diff --git a/js/components/whitelabel/prize/components/settings_container.js b/js/components/whitelabel/prize/components/settings_container.js
index 36321424..109da9ae 100644
--- a/js/components/whitelabel/prize/components/settings_container.js
+++ b/js/components/whitelabel/prize/components/settings_container.js
@@ -174,8 +174,16 @@ let PrizeJurySettings = React.createClass({
+
+ {member.email}
+
+
+ {member.status}
+
+
+ }
buttons={
);
diff --git a/js/components/ascribe_forms/property_collapsible.js b/js/components/ascribe_forms/property_collapsible.js
index ba6c0a1e..03ec404d 100644
--- a/js/components/ascribe_forms/property_collapsible.js
+++ b/js/components/ascribe_forms/property_collapsible.js
@@ -3,11 +3,9 @@
import React from 'react';
import ReactAddons from 'react/addons';
-import CollapsibleMixin from 'react-bootstrap/lib/CollapsibleMixin';
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger';
import Tooltip from 'react-bootstrap/lib/Tooltip';
-
-import classNames from 'classnames';
+import Panel from 'react-bootstrap/lib/Panel';
let PropertyCollapsile = React.createClass({
@@ -17,22 +15,12 @@ let PropertyCollapsile = React.createClass({
tooltip: React.PropTypes.string
},
- mixins: [CollapsibleMixin],
-
getInitialState() {
return {
show: false
};
},
- getCollapsibleDOMNode(){
- return React.findDOMNode(this.refs.panel);
- },
-
- getCollapsibleDimensionValue(){
- return React.findDOMNode(this.refs.panel).scrollHeight;
- },
-
handleFocus() {
this.refs.checkboxCollapsible.getDOMNode().checked = !this.refs.checkboxCollapsible.getDOMNode().checked;
this.setState({
@@ -85,11 +73,14 @@ let PropertyCollapsile = React.createClass({
{this.props.checkboxLabel}
-
+
+
{this.renderChildren()}
-
+
+
);
}
diff --git a/sass/ascribe_edition.scss b/sass/ascribe_edition.scss
index ee082a04..fe647e2d 100644
--- a/sass/ascribe_edition.scss
+++ b/sass/ascribe_edition.scss
@@ -16,33 +16,35 @@
margin-top: 20px;
}
.ascribe-edition-collapsible-wrapper > div > span {
- font-size: 1.2em;
- margin-right: .5em;
+ font-size: 1.2em;
+ margin-right: .5em;
}
.ascribe-edition-collapsible-wrapper > div > span:nth-child(2) {
- font-size: 0.9em;
+ font-size: 0.9em;
}
-.ascribe-edition-collapible-content {
- width:100%;
+.ascribe-edition-collapsible-content {
+ width:100%;
+ background: none;
+ border: none;
}
-.coa-file-wrapper{
- display: table;
- height: 200px;
- overflow: hidden;
- margin: 0 auto;
- width: 100%;
- padding: 1em;
+.coa-file-wrapper {
+ display: table;
+ height: 200px;
+ overflow: hidden;
+ margin: 0 auto;
+ width: 100%;
+ padding: 1em;
}
.coa-file {
- display: table-cell;
- vertical-align: middle;
- border: 1px solid #CCC;
- background-color: #F8F8F8;
+ display: table-cell;
+ vertical-align: middle;
+ border: 1px solid #CCC;
+ background-color: #F8F8F8;
}
.ascribe-button-list {
- margin-top: 1em;
+ margin-top: 1em;
}
\ No newline at end of file
diff --git a/sass/ascribe_theme.scss b/sass/ascribe_theme.scss
index 9eb92a30..da3c921f 100644
--- a/sass/ascribe_theme.scss
+++ b/sass/ascribe_theme.scss
@@ -2,4 +2,13 @@
.pager li a {
color: white;
+}
+
+.panel-default {
+ border: none;
+ box-shadow: none;
+}
+
+.panel-body {
+ padding:0;
}
\ No newline at end of file
From cde6118b8e3bf0f1a6fcb688a089d9dde37df8a7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Mon, 10 Aug 2015 14:57:06 +0200
Subject: [PATCH 039/397] panel styling
---
sass/ascribe_theme.scss | 1 +
1 file changed, 1 insertion(+)
diff --git a/sass/ascribe_theme.scss b/sass/ascribe_theme.scss
index da3c921f..e02b97c6 100644
--- a/sass/ascribe_theme.scss
+++ b/sass/ascribe_theme.scss
@@ -7,6 +7,7 @@
.panel-default {
border: none;
box-shadow: none;
+ margin-bottom: 0;
}
.panel-body {
From 3c752372759929b6ce82d78c0978c682b152127d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Mon, 10 Aug 2015 15:10:21 +0200
Subject: [PATCH 040/397] update refactor.md
---
docs/refactor-todo.md | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/docs/refactor-todo.md b/docs/refactor-todo.md
index 8554f001..f7a5917b 100644
--- a/docs/refactor-todo.md
+++ b/docs/refactor-todo.md
@@ -2,16 +2,18 @@
*This should be a living document. So if you have any ideas for refactoring stuff, then feel free to add them to this document*
-- Get rid of all Mixins. (making good progress there :))
- Make all standalone components independent from things like global utilities (GeneralUtils is maybe used in table for example)
-- Check if all polyfills are appropriately initialized and available: Compare to this
- Extract all standalone components to their own folder structure and write application independent tests (+ figure out how to do that in a productive way) (fetch lib especially)
-- Refactor forms to generic-declarative form component
- Check for mobile compatibility: Is site responsive anywhere?
queryParams of the piece_list_store should all be reflected in the url and not a single component each should manipulate the URL bar (refactor pagination, use actions and state)
- Refactor string-templating for api_urls
- Use classNames plugin instead of if-conditional-classes
+# Refactor DONE
+- Refactor forms to generic-declarative form component ✓
+- Get rid of all Mixins (inject head is fine) ✓
+- Check if all polyfills are appropriately initialized and available: Compare to this ✓
+
## React-S3-Fineuploader
- implementation should enable to define all important methods outside
- and: maybe create a utility class for all methods to avoid code duplication
From a27415eb864d8591533079367cb03b795f62443d Mon Sep 17 00:00:00 2001
From: diminator
Date: Mon, 10 Aug 2015 15:23:13 +0200
Subject: [PATCH 041/397] jury dashboard + rating WIP
---
.../components/ascribe_detail/piece_container.js | 13 +++++++++++++
package.json | 3 ++-
sass/main.scss | 6 ++++++
3 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js b/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js
index 8917e6d0..8782f6f0 100644
--- a/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js
+++ b/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js
@@ -14,6 +14,8 @@ import Property from '../../../../../components/ascribe_forms/property';
import InputTextAreaToggable from '../../../../../components/ascribe_forms/input_textarea_toggable';
import CollapsibleParagraph from '../../../../../components/ascribe_collapsible/collapsible_paragraph';
+import StarRating from 'react-star-rating';
+
/**
* This is the component that implements resource/data specific functionality
*/
@@ -70,6 +72,10 @@ let PrizePieceDetails = React.createClass({
propTypes: {
piece: React.PropTypes.object
},
+
+ onRatingClick(event, position, rating, caption, name) {
+ console.log(rating);
+ },
render() {
if (this.props.piece.prize
&& this.props.piece.prize.name
@@ -79,6 +85,13 @@ let PrizePieceDetails = React.createClass({
title="Prize Details"
show={true}
defaultExpanded={true}>
+
{Object.keys(this.props.piece.extra_data).map((data) => {
let label = data.replace('_', ' ');
diff --git a/package.json b/package.json
index 4fdf87fb..9d767930 100644
--- a/package.json
+++ b/package.json
@@ -84,7 +84,8 @@
"vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^1.1.0",
"watchify": "^3.1.2",
- "yargs": "^3.10.0"
+ "yargs": "^3.10.0",
+ "react-star-rating": "~1.3.2"
},
"jest": {
"scriptPreprocessor": "node_modules/babel-jest",
diff --git a/sass/main.scss b/sass/main.scss
index d2c05afa..c83379b3 100644
--- a/sass/main.scss
+++ b/sass/main.scss
@@ -6,6 +6,7 @@ $BASE_URL: '<%= BASE_URL %>';
@import 'ascribe_variables';
@import 'variables';
@import '../node_modules/bootstrap-sass/assets/stylesheets/bootstrap';
+@import '../node_modules/react-star-rating/dist/css/react-star-rating.min';
@import '../node_modules/react-datepicker/dist/react-datepicker';
@import 'glyphicons-social';
@import 'ascribe_theme';
@@ -381,4 +382,9 @@ hr {
> span {
font-size: 2em;
}
+}
+
+.rating-container .rating-stars {
+ width: 25px;
+ color: #000;
}
\ No newline at end of file
From 8ff2dea4dfb9ef900517c43cf0dfa06f932f136c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Mon, 10 Aug 2015 15:57:20 +0200
Subject: [PATCH 042/397] refactor: acl buttons message functionality
---
js/components/ascribe_buttons/acl_button.js | 87 +++------------------
js/utils/form_utils.js | 51 ++++++++++++
2 files changed, 62 insertions(+), 76 deletions(-)
create mode 100644 js/utils/form_utils.js
diff --git a/js/components/ascribe_buttons/acl_button.js b/js/components/ascribe_buttons/acl_button.js
index 5a924a0c..2f5bb7b0 100644
--- a/js/components/ascribe_buttons/acl_button.js
+++ b/js/components/ascribe_buttons/acl_button.js
@@ -13,9 +13,11 @@ import AppConstants from '../../constants/application_constants';
import GlobalNotificationModel from '../../models/global_notification_model';
import GlobalNotificationActions from '../../actions/global_notification_actions';
-import { getLangText } from '../../utils/lang_utils.js';
import ApiUrls from '../../constants/api_urls';
+import { getAclFormMessage } from '../../utils/form_utils';
+import { getLangText } from '../../utils/lang_utils';
+
let AclButton = React.createClass({
propTypes: {
action: React.PropTypes.oneOf(AppConstants.aclList).isRequired,
@@ -34,13 +36,16 @@ let AclButton = React.createClass({
},
actionProperties(){
+
+ let message = getAclFormMessage(this.props.action, this.getTitlesString(), this.props.currentUser.username);
+
if (this.props.action === 'acl_consign'){
return {
title: getLangText('Consign artwork'),
tooltip: getLangText('Have someone else sell the artwork'),
form: (
),
@@ -53,7 +58,7 @@ let AclButton = React.createClass({
tooltip: getLangText('Have the owner manage his sales again'),
form: (
),
@@ -65,7 +70,7 @@ let AclButton = React.createClass({
tooltip: getLangText('Transfer the ownership of the artwork'),
form: (
),
@@ -77,7 +82,7 @@ let AclButton = React.createClass({
title: getLangText('Loan artwork'),
tooltip: getLangText('Loan your artwork for a limited period of time'),
form: (
),
@@ -90,7 +95,7 @@ let AclButton = React.createClass({
tooltip: getLangText('Share the artwork'),
form: (
),
@@ -133,76 +138,6 @@ let AclButton = React.createClass({
}
},
-// plz move to transfer form
- getTransferMessage(){
- return (
- `${getLangText('Hi')},
-
-${getLangText('I transfer ownership of')}:
-${this.getTitlesString()} ${getLangText('to you')}.
-
-${getLangText('Truly yours')},
-${this.props.currentUser.username}
- `
- );
- },
-
- // plz move to transfer form
- getLoanMessage(){
- return (
- `${getLangText('Hi')},
-
-${getLangText('I loan')}:
-${this.getTitlesString()} ${getLangText('to you')}.
-
-${getLangText('Truly yours')},
-${this.props.currentUser.username}
- `
- );
- },
-
- // plz move to consign form
- getConsignMessage(){
- return (
- `${getLangText('Hi')},
-
-${getLangText('I consign')}:
-${this.getTitlesString()} ${getLangText('to you')}.
-
-${getLangText('Truly yours')},
-${this.props.currentUser.username}
- `
- );
- },
-
- // plz move to consign form
- getUnConsignMessage(){
- return (
- `${getLangText('Hi')},
-
-${getLangText('I un-consign')}:
-${this.getTitlesString()} ${getLangText('from you')}.
-
-${getLangText('Truly yours')},
-${this.props.currentUser.username}
- `
- );
- },
-
-// plz move to share form
- getShareMessage(){
- return (
- `${getLangText('Hi')},
-
-${getLangText('I am sharing')}:
-${this.getTitlesString()} ${getLangText('with you')}.
-
-${getLangText('Truly yours')},
-${this.props.currentUser.username}
- `
- );
- },
-
// Removes the acl_ prefix and converts to upper case
sanitizeAction() {
return this.props.action.split('acl_')[1].toUpperCase();
diff --git a/js/utils/form_utils.js b/js/utils/form_utils.js
new file mode 100644
index 00000000..3a8861cc
--- /dev/null
+++ b/js/utils/form_utils.js
@@ -0,0 +1,51 @@
+'use strict';
+
+import { getLangText } from './lang_utils';
+
+/**
+ * Generates a message for submitting a form
+ * @param {string} aclName Enum name of a acl
+ * @param {string} entities Already computed name of entities
+ * @param {string} senderName Name of the sender
+ * @return {string} Completed message
+ */
+export function getAclFormMessage(aclName, entities, senderName) {
+ let message = '';
+
+ message += getLangText('Hi');
+ message += ',\n\n';
+
+ if(aclName === 'acl_transfer') {
+ message += getLangText('I transfer ownership of');
+ } else if(aclName === 'acl_consign') {
+ message += getLangText('I consign');
+ } else if(aclName === 'acl_unconsign') {
+ message += getLangText('I un-consign');
+ } else if(aclName === 'acl_loan') {
+ message += getLangText('I loan');
+ } else if(aclName === 'acl_share') {
+ message += getLangText('I share');
+ } else {
+ throw new Error('Your specified aclName did not match a an acl class.');
+ }
+
+ message += ':\n';
+ message += entities;
+
+ if(aclName === 'acl_transfer' || aclName === 'acl_loan' || aclName === 'acl_consign') {
+ message += getLangText('to you');
+ } else if(aclName === 'acl_unconsign') {
+ message += getLangText('from you');
+ } else if(aclName === 'acl_share') {
+ message += getLangText('with you');
+ } else {
+ throw new Error('Your specified aclName did not match a an acl class.');
+ }
+
+ message += '\n\n';
+ message += getLangText('Truly yours,');
+ message += '\n';
+ message += senderName;
+
+ return message;
+}
\ No newline at end of file
From 36ca2004ffd732c90f05bf0b2f2e9235e000a0b1 Mon Sep 17 00:00:00 2001
From: diminator
Date: Mon, 10 Aug 2015 17:02:10 +0200
Subject: [PATCH 043/397] rating create and fetch
---
.../prize/actions/prize_rating_actions.js | 66 +++++++++++++++++++
.../ascribe_detail/piece_container.js | 36 ++++++++--
.../whitelabel/prize/constants/api_urls.js | 4 +-
.../prize/fetchers/prize_rating_fetcher.js | 20 ++++++
.../prize/stores/prize_rating_store.js | 23 +++++++
5 files changed, 144 insertions(+), 5 deletions(-)
create mode 100644 js/components/whitelabel/prize/actions/prize_rating_actions.js
create mode 100644 js/components/whitelabel/prize/fetchers/prize_rating_fetcher.js
create mode 100644 js/components/whitelabel/prize/stores/prize_rating_store.js
diff --git a/js/components/whitelabel/prize/actions/prize_rating_actions.js b/js/components/whitelabel/prize/actions/prize_rating_actions.js
new file mode 100644
index 00000000..536445f8
--- /dev/null
+++ b/js/components/whitelabel/prize/actions/prize_rating_actions.js
@@ -0,0 +1,66 @@
+'use strict';
+
+import alt from '../../../../alt';
+import Q from 'q';
+
+import PrizeRatingFetcher from '../fetchers/prize_rating_fetcher';
+
+class PrizeRatingActions {
+ constructor() {
+ this.generateActions(
+ 'updatePrizeRatings',
+ 'updatePrizeRating'
+ );
+ }
+
+ fetch() {
+ return Q.Promise((resolve, reject) => {
+ PrizeRatingFetcher
+ .fetch()
+ .then((res) => {
+ this.actions.updatePrizeRatings(res.ratings);
+ resolve(res);
+ })
+ .catch((err) => {
+ console.logGlobal(err);
+ reject(err);
+ });
+ });
+ }
+
+ fetchOne(pieceId) {
+ return Q.Promise((resolve, reject) => {
+ PrizeRatingFetcher
+ .fetchOne(pieceId)
+ .then((res) => {
+ this.actions.updatePrizeRating(res.rating.rating);
+ resolve(res);
+ })
+ .catch((err) => {
+ console.logGlobal(err);
+ reject(err);
+ });
+ });
+ }
+
+ createRating(pieceId, rating) {
+ return Q.Promise((resolve, reject) => {
+ PrizeRatingFetcher
+ .rate(pieceId, rating)
+ .then((res) => {
+ this.actions.updatePrizeRating(res.rating.rating);
+ resolve(res);
+ })
+ .catch((err) => {
+ console.logGlobal(err);
+ reject(err);
+ });
+ });
+ }
+
+ updateRating(rating) {
+ this.actions.updatePrizeRating(rating);
+ }
+}
+
+export default alt.createActions(PrizeRatingActions);
\ No newline at end of file
diff --git a/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js b/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js
index 8782f6f0..3a7c3144 100644
--- a/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js
+++ b/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js
@@ -2,9 +2,14 @@
import React from 'react';
+import StarRating from 'react-star-rating';
+
import PieceActions from '../../../../../actions/piece_actions';
import PieceStore from '../../../../../stores/piece_store';
+import PrizeRatingActions from '../../actions/prize_rating_actions';
+import PrizeRatingStore from '../../stores/prize_rating_store';
+
import Piece from '../../../../../components/ascribe_detail/piece';
import AppConstants from '../../../../../constants/application_constants';
@@ -14,8 +19,6 @@ import Property from '../../../../../components/ascribe_forms/property';
import InputTextAreaToggable from '../../../../../components/ascribe_forms/input_textarea_toggable';
import CollapsibleParagraph from '../../../../../components/ascribe_collapsible/collapsible_paragraph';
-import StarRating from 'react-star-rating';
-
/**
* This is the component that implements resource/data specific functionality
*/
@@ -73,9 +76,33 @@ let PrizePieceDetails = React.createClass({
piece: React.PropTypes.object
},
- onRatingClick(event, position, rating, caption, name) {
- console.log(rating);
+ getInitialState() {
+ return PrizeRatingStore.getState();
},
+
+ onChange(state) {
+ this.setState(state);
+ },
+
+ componentDidMount() {
+ PrizeRatingStore.listen(this.onChange);
+ PrizeRatingActions.fetchOne(this.props.piece.id);
+ },
+
+ componentWillUnmount() {
+ // Every time we're leaving the piece detail page,
+ // just reset the piece that is saved in the piece store
+ // as it will otherwise display wrong/old data once the user loads
+ // the piece detail a second time
+ PrizeRatingActions.updateRating({});
+ PrizeRatingStore.unlisten(this.onChange);
+ },
+
+ onRatingClick(event, args) {
+ event.preventDefault();
+ PrizeRatingActions.createRating(this.props.piece.id, args.rating);
+ },
+
render() {
if (this.props.piece.prize
&& this.props.piece.prize.name
@@ -90,6 +117,7 @@ let PrizePieceDetails = React.createClass({
caption=""
step={1}
size='lg'
+ rating={this.state.currentRating}
onRatingClick={this.onRatingClick}
ratingAmount={5} />
+ );
+ }
+});
+
+export default WalletApp;
diff --git a/js/components/whitelabel/wallet/routes.js b/js/components/whitelabel/wallet/routes.js
new file mode 100644
index 00000000..82cc458f
--- /dev/null
+++ b/js/components/whitelabel/wallet/routes.js
@@ -0,0 +1,41 @@
+'use strict';
+
+import React from 'react';
+import Router from 'react-router';
+
+import LoginContainer from './components/login_container';
+import LogoutContainer from '../../../components/logout_container';
+import SignupContainer from './components/signup_container';
+import PasswordResetContainer from '../../../components/password_reset_container';
+import WalletRegisterPiece from './components/wallet_register_piece';
+import PieceList from '../../piece_list';
+import PieceContainer from '../../ascribe_detail/piece_container';
+import EditionContainer from '../../ascribe_detail/edition_container';
+import SettingsContainer from './components/settings_container';
+
+import App from './app';
+import AppConstants from '../../../constants/application_constants';
+
+let Route = Router.Route;
+let baseUrl = AppConstants.baseUrl;
+
+
+function getRoutes() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+
+export default getRoutes;
\ No newline at end of file
diff --git a/js/constants/application_constants.js b/js/constants/application_constants.js
index 54d43299..acd2561a 100644
--- a/js/constants/application_constants.js
+++ b/js/constants/application_constants.js
@@ -52,7 +52,7 @@ let constants = {
'name': 'Cyland media art lab',
'logo': 'https://s3-us-west-2.amazonaws.com/ascribe0/whitelabel/cyland/logo.gif',
'permissions': ['register', 'edit', 'share', 'del_from_collection'],
- 'type': 'prize'
+ 'type': 'wallet'
}
],
'defaultDomain': {
From eb6e3cb20a7ead5deedade404017dabb326c15b7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Tue, 11 Aug 2015 14:47:28 +0200
Subject: [PATCH 049/397] finishing boilerplate for wallet app + prefixing
whitelabel specific files
---
js/app.js | 1 -
..._container.js => prize_piece_container.js} | 0
.../components/{hero.js => prize_hero.js} | 0
.../{landing.js => prize_landing.js} | 0
..._container.js => prize_login_container.js} | 0
.../{piece_list.js => prize_piece_list.js} | 0
...ister_piece.js => prize_register_piece.js} | 0
...ntainer.js => prize_settings_container.js} | 0
...container.js => prize_signup_container.js} | 0
.../{api_urls.js => prize_api_urls.js} | 6 +-
...ants.js => prize_application_constants.js} | 4 +-
.../whitelabel/prize/{app.js => prize_app.js} | 2 +-
.../prize/{routes.js => prize_routes.js} | 16 +++---
.../components/wallet_register_piece.js | 57 +++++++++++++++++++
.../wallet/constants/wallet_api_urls.js | 11 ++++
.../constants/wallet_application_constants.js | 9 +++
.../wallet/{app.js => wallet_app.js} | 0
.../wallet/{routes.js => wallet_routes.js} | 16 +++---
js/constants/api_urls.js | 7 ++-
js/routes.js | 5 +-
20 files changed, 109 insertions(+), 25 deletions(-)
rename js/components/whitelabel/prize/components/ascribe_detail/{piece_container.js => prize_piece_container.js} (100%)
rename js/components/whitelabel/prize/components/{hero.js => prize_hero.js} (100%)
rename js/components/whitelabel/prize/components/{landing.js => prize_landing.js} (100%)
rename js/components/whitelabel/prize/components/{login_container.js => prize_login_container.js} (100%)
rename js/components/whitelabel/prize/components/{piece_list.js => prize_piece_list.js} (100%)
rename js/components/whitelabel/prize/components/{register_piece.js => prize_register_piece.js} (100%)
rename js/components/whitelabel/prize/components/{settings_container.js => prize_settings_container.js} (100%)
rename js/components/whitelabel/prize/components/{signup_container.js => prize_signup_container.js} (100%)
rename js/components/whitelabel/prize/constants/{api_urls.js => prize_api_urls.js} (89%)
rename js/components/whitelabel/prize/constants/{application_prize_constants.js => prize_application_constants.js} (74%)
rename js/components/whitelabel/prize/{app.js => prize_app.js} (95%)
rename js/components/whitelabel/prize/{routes.js => prize_routes.js} (73%)
create mode 100644 js/components/whitelabel/wallet/components/wallet_register_piece.js
create mode 100644 js/components/whitelabel/wallet/constants/wallet_api_urls.js
create mode 100644 js/components/whitelabel/wallet/constants/wallet_application_constants.js
rename js/components/whitelabel/wallet/{app.js => wallet_app.js} (100%)
rename js/components/whitelabel/wallet/{routes.js => wallet_routes.js} (71%)
diff --git a/js/app.js b/js/app.js
index 81a8fb82..6115a0aa 100644
--- a/js/app.js
+++ b/js/app.js
@@ -44,7 +44,6 @@ requests.defaults({
});
-
class AppGateway {
start() {
diff --git a/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js b/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js
similarity index 100%
rename from js/components/whitelabel/prize/components/ascribe_detail/piece_container.js
rename to js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js
diff --git a/js/components/whitelabel/prize/components/hero.js b/js/components/whitelabel/prize/components/prize_hero.js
similarity index 100%
rename from js/components/whitelabel/prize/components/hero.js
rename to js/components/whitelabel/prize/components/prize_hero.js
diff --git a/js/components/whitelabel/prize/components/landing.js b/js/components/whitelabel/prize/components/prize_landing.js
similarity index 100%
rename from js/components/whitelabel/prize/components/landing.js
rename to js/components/whitelabel/prize/components/prize_landing.js
diff --git a/js/components/whitelabel/prize/components/login_container.js b/js/components/whitelabel/prize/components/prize_login_container.js
similarity index 100%
rename from js/components/whitelabel/prize/components/login_container.js
rename to js/components/whitelabel/prize/components/prize_login_container.js
diff --git a/js/components/whitelabel/prize/components/piece_list.js b/js/components/whitelabel/prize/components/prize_piece_list.js
similarity index 100%
rename from js/components/whitelabel/prize/components/piece_list.js
rename to js/components/whitelabel/prize/components/prize_piece_list.js
diff --git a/js/components/whitelabel/prize/components/register_piece.js b/js/components/whitelabel/prize/components/prize_register_piece.js
similarity index 100%
rename from js/components/whitelabel/prize/components/register_piece.js
rename to js/components/whitelabel/prize/components/prize_register_piece.js
diff --git a/js/components/whitelabel/prize/components/settings_container.js b/js/components/whitelabel/prize/components/prize_settings_container.js
similarity index 100%
rename from js/components/whitelabel/prize/components/settings_container.js
rename to js/components/whitelabel/prize/components/prize_settings_container.js
diff --git a/js/components/whitelabel/prize/components/signup_container.js b/js/components/whitelabel/prize/components/prize_signup_container.js
similarity index 100%
rename from js/components/whitelabel/prize/components/signup_container.js
rename to js/components/whitelabel/prize/components/prize_signup_container.js
diff --git a/js/components/whitelabel/prize/constants/api_urls.js b/js/components/whitelabel/prize/constants/prize_api_urls.js
similarity index 89%
rename from js/components/whitelabel/prize/constants/api_urls.js
rename to js/components/whitelabel/prize/constants/prize_api_urls.js
index 480e8d4f..8ef92daa 100644
--- a/js/components/whitelabel/prize/constants/api_urls.js
+++ b/js/components/whitelabel/prize/constants/prize_api_urls.js
@@ -1,8 +1,8 @@
'use strict';
-import AppPrizeConstants from './application_prize_constants';
+import AppPrizeConstants from './prize_application_constants';
-function getApiUrls(subdomain) {
+function getPrizeApiUrls(subdomain) {
return {
'pieces_list': AppPrizeConstants.prizeApiEndpoint + subdomain + '/pieces/',
'users_login': AppPrizeConstants.prizeApiEndpoint + subdomain + '/users/login/',
@@ -20,4 +20,4 @@ function getApiUrls(subdomain) {
};
}
-export default getApiUrls;
+export default getPrizeApiUrls;
diff --git a/js/components/whitelabel/prize/constants/application_prize_constants.js b/js/components/whitelabel/prize/constants/prize_application_constants.js
similarity index 74%
rename from js/components/whitelabel/prize/constants/application_prize_constants.js
rename to js/components/whitelabel/prize/constants/prize_application_constants.js
index 6026193b..9ba87a37 100644
--- a/js/components/whitelabel/prize/constants/application_prize_constants.js
+++ b/js/components/whitelabel/prize/constants/prize_application_constants.js
@@ -2,8 +2,8 @@
import AppConstants from '../../../../constants/application_constants';
-let constants = {
+let prizeConstants = {
prizeApiEndpoint: AppConstants.apiEndpoint + 'prizes/'
};
-export default constants;
\ No newline at end of file
+export default prizeConstants;
\ No newline at end of file
diff --git a/js/components/whitelabel/prize/app.js b/js/components/whitelabel/prize/prize_app.js
similarity index 95%
rename from js/components/whitelabel/prize/app.js
rename to js/components/whitelabel/prize/prize_app.js
index 8876aa8c..137c2cf4 100644
--- a/js/components/whitelabel/prize/app.js
+++ b/js/components/whitelabel/prize/prize_app.js
@@ -2,7 +2,7 @@
import React from 'react';
import Router from 'react-router';
-import Hero from './components/hero';
+import Hero from './components/prize_hero';
import Header from '../../header';
// import Footer from '../../footer';
import GlobalNotification from '../../global_notification';
diff --git a/js/components/whitelabel/prize/routes.js b/js/components/whitelabel/prize/prize_routes.js
similarity index 73%
rename from js/components/whitelabel/prize/routes.js
rename to js/components/whitelabel/prize/prize_routes.js
index 16e57e50..1384d26b 100644
--- a/js/components/whitelabel/prize/routes.js
+++ b/js/components/whitelabel/prize/prize_routes.js
@@ -3,18 +3,18 @@
import React from 'react';
import Router from 'react-router';
-import Landing from './components/landing';
-import LoginContainer from './components/login_container';
+import Landing from './components/prize_landing';
+import LoginContainer from './components/prize_login_container';
import LogoutContainer from '../../../components/logout_container';
-import SignupContainer from './components/signup_container';
+import SignupContainer from './components/prize_signup_container';
import PasswordResetContainer from '../../../components/password_reset_container';
-import PrizeRegisterPiece from './components/register_piece';
-import PrizePieceList from './components/piece_list';
-import PrizePieceContainer from './components/ascribe_detail/piece_container';
+import PrizeRegisterPiece from './components/prize_register_piece';
+import PrizePieceList from './components/prize_piece_list';
+import PrizePieceContainer from './components/ascribe_detail/prize_piece_container';
import EditionContainer from '../../ascribe_detail/edition_container';
-import SettingsContainer from './components/settings_container';
+import SettingsContainer from './components/prize_settings_container';
-import App from './app';
+import App from './prize_app';
import AppConstants from '../../../constants/application_constants';
let Route = Router.Route;
diff --git a/js/components/whitelabel/wallet/components/wallet_register_piece.js b/js/components/whitelabel/wallet/components/wallet_register_piece.js
new file mode 100644
index 00000000..6b4d88fa
--- /dev/null
+++ b/js/components/whitelabel/wallet/components/wallet_register_piece.js
@@ -0,0 +1,57 @@
+'use strict';
+
+import React from 'react';
+import RegisterPiece from '../../../register_piece';
+import Property from '../../../ascribe_forms/property';
+import InputTextAreaToggable from '../../../ascribe_forms/input_textarea_toggable';
+import InputCheckbox from '../../../ascribe_forms/input_checkbox';
+
+import { getLangText } from '../../../../utils/lang_utils';
+
+
+let WalletRegisterPiece = React.createClass({
+ render() {
+ return (
+
+
+
+
+
+
+
+
+
+
+ {' ' + getLangText('I agree to the Terms of Service the art price') + ' '}
+ (
+ {getLangText('read')}
+ )
+
+
+
+
+ );
+ }
+});
+
+export default WalletRegisterPiece;
diff --git a/js/components/whitelabel/wallet/constants/wallet_api_urls.js b/js/components/whitelabel/wallet/constants/wallet_api_urls.js
new file mode 100644
index 00000000..60ee8658
--- /dev/null
+++ b/js/components/whitelabel/wallet/constants/wallet_api_urls.js
@@ -0,0 +1,11 @@
+'use strict';
+
+import WalletAppConstants from './wallet_application_constants';
+
+function getPrizeApiUrls(subdomain) {
+ return {
+ 'pieces_list': WalletAppConstants.walletApiEndpoint + subdomain + '/pieces/'
+ };
+}
+
+export default getPrizeApiUrls;
\ No newline at end of file
diff --git a/js/components/whitelabel/wallet/constants/wallet_application_constants.js b/js/components/whitelabel/wallet/constants/wallet_application_constants.js
new file mode 100644
index 00000000..bc0d73fd
--- /dev/null
+++ b/js/components/whitelabel/wallet/constants/wallet_application_constants.js
@@ -0,0 +1,9 @@
+'use strict';
+
+import AppConstants from '../../../../constants/application_constants';
+
+let walletConstants = {
+ walletApiEndpoint: AppConstants.apiEndpoint + 'wallets/'
+};
+
+export default walletConstants;
\ No newline at end of file
diff --git a/js/components/whitelabel/wallet/app.js b/js/components/whitelabel/wallet/wallet_app.js
similarity index 100%
rename from js/components/whitelabel/wallet/app.js
rename to js/components/whitelabel/wallet/wallet_app.js
diff --git a/js/components/whitelabel/wallet/routes.js b/js/components/whitelabel/wallet/wallet_routes.js
similarity index 71%
rename from js/components/whitelabel/wallet/routes.js
rename to js/components/whitelabel/wallet/wallet_routes.js
index 82cc458f..3dc07c6d 100644
--- a/js/components/whitelabel/wallet/routes.js
+++ b/js/components/whitelabel/wallet/wallet_routes.js
@@ -3,17 +3,17 @@
import React from 'react';
import Router from 'react-router';
-import LoginContainer from './components/login_container';
+import LoginContainer from '../../../components/login_container';
import LogoutContainer from '../../../components/logout_container';
-import SignupContainer from './components/signup_container';
+import SignupContainer from '../../../components/signup_container';
import PasswordResetContainer from '../../../components/password_reset_container';
import WalletRegisterPiece from './components/wallet_register_piece';
-import PieceList from '../../piece_list';
-import PieceContainer from '../../ascribe_detail/piece_container';
-import EditionContainer from '../../ascribe_detail/edition_container';
-import SettingsContainer from './components/settings_container';
+import PieceList from '../../../components/piece_list';
+import PieceContainer from '../../../components/ascribe_detail/piece_container';
+import EditionContainer from '../../../components/ascribe_detail/edition_container';
+import SettingsContainer from '../../../components/settings_container';
-import App from './app';
+import WalletApp from './wallet_app';
import AppConstants from '../../../constants/application_constants';
let Route = Router.Route;
@@ -22,7 +22,7 @@ let baseUrl = AppConstants.baseUrl;
function getRoutes() {
return (
-
+
diff --git a/js/constants/api_urls.js b/js/constants/api_urls.js
index c11a5df2..f56879e5 100644
--- a/js/constants/api_urls.js
+++ b/js/constants/api_urls.js
@@ -1,7 +1,10 @@
'use strict';
import AppConstants from './application_constants';
-import getPrizeApiUrls from '../components/whitelabel/prize/constants/api_urls';
+
+import getPrizeApiUrls from '../components/whitelabel/prize/constants/prize_api_urls';
+import getWalletApiUrls from '../components/whitelabel/wallet/constants/wallet_api_urls';
+
import { update } from '../utils/general_utils';
@@ -62,6 +65,8 @@ export function updateApiUrls(type, subdomain) {
if (type === 'prize') {
newUrls = getPrizeApiUrls(subdomain);
+ } else if(type === 'wallet') {
+ newUrls = getWalletApiUrls(subdomain);
}
update(ApiUrls, newUrls);
}
diff --git a/js/routes.js b/js/routes.js
index f7ea2ea6..4ee71070 100644
--- a/js/routes.js
+++ b/js/routes.js
@@ -3,7 +3,8 @@
import React from 'react';
import Router from 'react-router';
-import getPrizeRoutes from './components/whitelabel/prize/routes';
+import getPrizeRoutes from './components/whitelabel/prize/prize_routes';
+import getWalletRoutes from './components/whitelabel/wallet/wallet_routes';
import getDefaultRoutes from './components/routes';
import PieceList from './components/piece_list';
@@ -47,6 +48,8 @@ function getRoutes(type) {
if (type === 'prize') {
routes = getPrizeRoutes(COMMON_ROUTES);
+ } else if(type === 'wallet') {
+ routes = getWalletRoutes(COMMON_ROUTES);
} else {
routes = getDefaultRoutes(COMMON_ROUTES);
}
From 22727c2703600114703b0e1ab9b95f1bcf7a4155 Mon Sep 17 00:00:00 2001
From: diminator
Date: Tue, 11 Aug 2015 17:12:12 +0200
Subject: [PATCH 050/397] refactored piece container and detail
---
.../collapsible_paragraph.js | 2 +-
.../ascribe_detail/detail_property.js | 10 +-
.../ascribe_detail/media_container.js | 28 +++-
js/components/ascribe_detail/piece.js | 147 ++---------------
.../ascribe_detail/piece_container.js | 152 ++++++++++++++++--
js/components/piece_list.js | 2 +-
.../accordion_list_item_prize.js | 75 ++++++---
.../ascribe_detail/piece_container.js | 85 ++++++++--
sass/main.scss | 4 +
9 files changed, 312 insertions(+), 193 deletions(-)
diff --git a/js/components/ascribe_collapsible/collapsible_paragraph.js b/js/components/ascribe_collapsible/collapsible_paragraph.js
index e04e82c2..8b3b3cf4 100644
--- a/js/components/ascribe_collapsible/collapsible_paragraph.js
+++ b/js/components/ascribe_collapsible/collapsible_paragraph.js
@@ -23,7 +23,7 @@ const CollapsibleParagraph = React.createClass({
getInitialState() {
return {
- expanded: false
+ expanded: this.props.defaultExpanded
};
},
diff --git a/js/components/ascribe_detail/detail_property.js b/js/components/ascribe_detail/detail_property.js
index f220fc98..991226f9 100644
--- a/js/components/ascribe_detail/detail_property.js
+++ b/js/components/ascribe_detail/detail_property.js
@@ -18,8 +18,8 @@ let DetailProperty = React.createClass({
getDefaultProps() {
return {
separator: ':',
- labelClassName: 'col-xs-3 col-sm-3 col-md-2 col-lg-2',
- valueClassName: 'col-xs-9 col-sm-9 col-md-10 col-lg-10'
+ labelClassName: 'col-xs-3 col-sm-3 col-md-2 col-lg-2 col-xs-height col-bottom ascribe-detail-property-label',
+ valueClassName: 'col-xs-9 col-sm-9 col-md-10 col-lg-10 col-xs-height col-bottom ascribe-detail-property-value'
};
},
@@ -52,11 +52,11 @@ let DetailProperty = React.createClass({
return (
-
- { this.props.label + this.props.separator}
+
+ { this.props.label } { this.props.separator}
{value}
diff --git a/js/components/ascribe_detail/media_container.js b/js/components/ascribe_detail/media_container.js
index 529817c3..6ac2f745 100644
--- a/js/components/ascribe_detail/media_container.js
+++ b/js/components/ascribe_detail/media_container.js
@@ -19,7 +19,33 @@ const EMBED_IFRAME_HEIGHT = {
let MediaContainer = React.createClass({
propTypes: {
- content: React.PropTypes.object
+ content: React.PropTypes.object,
+ refreshObject: React.PropTypes.func
+ },
+
+ getInitialState() {
+ return {timerId: null};
+ },
+
+ componentDidMount() {
+ if (!this.props.content.digital_work) {
+ return;
+ }
+ let isEncoding = this.props.content.digital_work.isEncoding;
+ if (this.props.content.digital_work.mime === 'video' && typeof isEncoding === 'number' && isEncoding !== 100 && !this.state.timerId) {
+ let timerId = window.setInterval(this.props.refreshObject, 10000);
+ this.setState({timerId: timerId});
+ }
+ },
+
+ componentWillUpdate() {
+ if (this.props.content.digital_work.isEncoding === 100) {
+ window.clearInterval(this.state.timerId);
+ }
+ },
+
+ componentWillUnmount() {
+ window.clearInterval(this.state.timerId);
},
render() {
diff --git a/js/components/ascribe_detail/piece.js b/js/components/ascribe_detail/piece.js
index 3fabb055..ed312f5f 100644
--- a/js/components/ascribe_detail/piece.js
+++ b/js/components/ascribe_detail/piece.js
@@ -1,38 +1,14 @@
'use strict';
import React from 'react';
-import Router from 'react-router';
import Row from 'react-bootstrap/lib/Row';
import Col from 'react-bootstrap/lib/Col';
-import DetailProperty from './detail_property';
-
-import UserActions from '../../actions/user_actions';
-import UserStore from '../../stores/user_store';
-
-import PieceListActions from '../../actions/piece_list_actions';
-import PieceListStore from '../../stores/piece_list_store';
-
-import EditionListActions from '../../actions/edition_list_actions';
-
import PieceActions from '../../actions/piece_actions';
import MediaContainer from './media_container';
-import EditionDetailProperty from './detail_property';
-
-import AclButtonList from './../ascribe_buttons/acl_button_list';
-import CreateEditionsForm from '../ascribe_forms/create_editions_form';
-import CreateEditionsButton from '../ascribe_buttons/create_editions_button';
-import DeleteButton from '../ascribe_buttons/delete_button';
-
-import GlobalNotificationModel from '../../models/global_notification_model';
-import GlobalNotificationActions from '../../actions/global_notification_actions';
-
-import { getLangText } from '../../utils/lang_utils';
-import { mergeOptions } from '../../utils/general_utils';
-
/**
* This is the component that implements display-specific functionality
@@ -40,97 +16,16 @@ import { mergeOptions } from '../../utils/general_utils';
let Piece = React.createClass({
propTypes: {
piece: React.PropTypes.object,
+ header: React.PropTypes.object,
+ subheader: React.PropTypes.object,
+ buttons: React.PropTypes.object,
loadPiece: React.PropTypes.func,
children: React.PropTypes.object
},
- mixins: [Router.Navigation],
- getInitialState() {
- return mergeOptions(
- UserStore.getState(),
- PieceListStore.getState(),
- {
- showCreateEditionsDialog: false
- }
- );
- },
-
- componentDidMount() {
- UserStore.listen(this.onChange);
- PieceListStore.listen(this.onChange);
- UserActions.fetchCurrentUser();
- },
-
- componentWillUnmount() {
- UserStore.unlisten(this.onChange);
- PieceListStore.unlisten(this.onChange);
- },
-
- onChange(state) {
- this.setState(state);
- },
-
- toggleCreateEditionsDialog() {
- this.setState({
- showCreateEditionsDialog: !this.state.showCreateEditionsDialog
- });
- },
-
- handleEditionCreationSuccess() {
- PieceActions.updateProperty({key: 'num_editions', value: 0});
- PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
- this.state.orderBy, this.state.orderAsc, this.state.filterBy);
- this.toggleCreateEditionsDialog();
- },
-
- handleDeleteSuccess(response) {
- PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
- this.state.orderBy, this.state.orderAsc, this.state.filterBy);
-
- // since we're deleting a piece, we just need to close
- // all editions dialogs and not reload them
- EditionListActions.closeAllEditionLists();
- EditionListActions.clearAllEditionSelections();
-
- let notification = new GlobalNotificationModel(response.notification, 'success');
- GlobalNotificationActions.appendGlobalNotification(notification);
-
- this.transitionTo('pieces');
- },
-
- getCreateEditionsDialog() {
- if(this.props.piece.num_editions < 1 && this.state.showCreateEditionsDialog) {
- return (
-
-
-
-
- );
- } else {
- return ();
- }
- },
-
- handlePollingSuccess(pieceId, numEditions) {
-
- // we need to refresh the num_editions property of the actual piece we're looking at
- PieceActions.updateProperty({
- key: 'num_editions',
- value: numEditions
- });
-
- // as well as its representation in the collection
- // btw.: It's not sufficient to just set num_editions to numEditions, since a single accordion
- // list item also uses the firstEdition property which we can only get from the server in that case.
- // Therefore we need to at least refetch the changed piece from the server or on our case simply all
- PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
- this.state.orderBy, this.state.orderAsc, this.state.filterBy);
-
- let notification = new GlobalNotificationModel('Editions successfully created', 'success', 10000);
- GlobalNotificationActions.appendGlobalNotification(notification);
+ updateObject() {
+ return PieceActions.fetchOne(this.props.piece.id);
},
render() {
@@ -138,38 +33,14 @@ let Piece = React.createClass({
+ {this.props.header}
+ {this.props.subheader}
+ {this.props.buttons}
-
-
-
-
-
- {this.getCreateEditionsDialog()}
{this.props.children}
diff --git a/js/components/ascribe_detail/piece_container.js b/js/components/ascribe_detail/piece_container.js
index 8e3a5750..8625f7a0 100644
--- a/js/components/ascribe_detail/piece_container.js
+++ b/js/components/ascribe_detail/piece_container.js
@@ -1,37 +1,59 @@
'use strict';
import React from 'react';
+import Router from 'react-router';
import PieceActions from '../../actions/piece_actions';
import PieceStore from '../../stores/piece_store';
+import PieceListActions from '../../actions/piece_list_actions';
+import PieceListStore from '../../stores/piece_list_store';
+
+import UserActions from '../../actions/user_actions';
+import UserStore from '../../stores/user_store';
+
+import EditionListActions from '../../actions/edition_list_actions';
+
import Piece from './piece';
import CollapsibleParagraph from './../ascribe_collapsible/collapsible_paragraph';
import FurtherDetails from './further_details';
+import DetailProperty from './detail_property';
+
+import AclButtonList from './../ascribe_buttons/acl_button_list';
+import CreateEditionsForm from '../ascribe_forms/create_editions_form';
+import CreateEditionsButton from '../ascribe_buttons/create_editions_button';
+import DeleteButton from '../ascribe_buttons/delete_button';
+
+import GlobalNotificationModel from '../../models/global_notification_model';
+import GlobalNotificationActions from '../../actions/global_notification_actions';
+
import AppConstants from '../../constants/application_constants';
+import { mergeOptions } from '../../utils/general_utils';
+import { getLangText } from '../../utils/lang_utils';
/**
* This is the component that implements resource/data specific functionality
*/
let PieceContainer = React.createClass({
- getInitialState() {
- return PieceStore.getState();
- },
- onChange(state) {
- this.setState(state);
- if (!state.piece.digital_work) {
- return;
- }
- let isEncoding = state.piece.digital_work.isEncoding;
- if (state.piece.digital_work.mime === 'video' && typeof isEncoding === 'number' && isEncoding !== 100 && !this.state.timerId) {
- let timerId = window.setInterval(() => PieceActions.fetchOne(this.props.params.pieceId), 10000);
- this.setState({timerId: timerId});
- }
+ mixins: [Router.Navigation],
+
+ getInitialState() {
+ return mergeOptions(
+ UserStore.getState(),
+ PieceListStore.getState(),
+ PieceStore.getState(),
+ {
+ showCreateEditionsDialog: false
+ }
+ );
},
componentDidMount() {
+ UserStore.listen(this.onChange);
+ PieceListStore.listen(this.onChange);
+ UserActions.fetchCurrentUser();
PieceStore.listen(this.onChange);
PieceActions.fetchOne(this.props.params.pieceId);
},
@@ -42,21 +64,121 @@ let PieceContainer = React.createClass({
// as it will otherwise display wrong/old data once the user loads
// the piece detail a second time
PieceActions.updatePiece({});
- window.clearInterval(this.state.timerId);
PieceStore.unlisten(this.onChange);
+ UserStore.unlisten(this.onChange);
+ PieceListStore.unlisten(this.onChange);
},
+ onChange(state) {
+ this.setState(state);
+ },
loadPiece() {
PieceActions.fetchOne(this.props.params.pieceId);
},
+
+ toggleCreateEditionsDialog() {
+ this.setState({
+ showCreateEditionsDialog: !this.state.showCreateEditionsDialog
+ });
+ },
+
+ handleEditionCreationSuccess() {
+ PieceActions.updateProperty({key: 'num_editions', value: 0});
+ PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
+ this.state.orderBy, this.state.orderAsc, this.state.filterBy);
+ this.toggleCreateEditionsDialog();
+ },
+
+ handleDeleteSuccess(response) {
+ PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
+ this.state.orderBy, this.state.orderAsc, this.state.filterBy);
+
+ // since we're deleting a piece, we just need to close
+ // all editions dialogs and not reload them
+ EditionListActions.closeAllEditionLists();
+ EditionListActions.clearAllEditionSelections();
+
+ let notification = new GlobalNotificationModel(response.notification, 'success');
+ GlobalNotificationActions.appendGlobalNotification(notification);
+
+ this.transitionTo('pieces');
+ },
+
+ getCreateEditionsDialog() {
+ if(this.state.piece.num_editions < 1 && this.state.showCreateEditionsDialog) {
+ return (
+
+
+
+
+ );
+ } else {
+ return ();
+ }
+ },
+
+ handlePollingSuccess(pieceId, numEditions) {
+
+ // we need to refresh the num_editions property of the actual piece we're looking at
+ PieceActions.updateProperty({
+ key: 'num_editions',
+ value: numEditions
+ });
+
+ // as well as its representation in the collection
+ // btw.: It's not sufficient to just set num_editions to numEditions, since a single accordion
+ // list item also uses the firstEdition property which we can only get from the server in that case.
+ // Therefore we need to at least refetch the changed piece from the server or on our case simply all
+ PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
+ this.state.orderBy, this.state.orderAsc, this.state.filterBy);
+
+ let notification = new GlobalNotificationModel('Editions successfully created', 'success', 10000);
+ GlobalNotificationActions.appendGlobalNotification(notification);
+ },
+
render() {
if('title' in this.state.piece) {
return (
+ loadPiece={this.loadPiece}
+ header={
+
);
}
});
-let FileUploader = React.createClass({
- propTypes: {
- pieceId: React.PropTypes.number,
- otherData: React.PropTypes.object,
- setIsUploadReady: React.PropTypes.func,
- submitKey: React.PropTypes.func,
- isReadyForFormSubmission: React.PropTypes.func,
- editable: React.PropTypes.bool
- },
- render() {
- // Essentially there a three cases important to the fileuploader
- //
- // 1. there is no other_data => do not show the fileuploader at all
- // 2. there is other_data, but user has no edit rights => show fileuploader but without action buttons
- // 3. both other_data and editable are defined or true => show fileuploade with all action buttons
- if (!this.props.editable && !this.props.otherData){
- return null;
- }
- return (
-
-
-
-
-
-
- );
- }
-});
export default FurtherDetails;
diff --git a/js/components/ascribe_detail/further_details_fileuploader.js b/js/components/ascribe_detail/further_details_fileuploader.js
new file mode 100644
index 00000000..5d9cd5fd
--- /dev/null
+++ b/js/components/ascribe_detail/further_details_fileuploader.js
@@ -0,0 +1,95 @@
+'use strict';
+
+import React from 'react';
+
+import Property from './../ascribe_forms/property';
+
+import ReactS3FineUploader from './../ascribe_uploader/react_s3_fine_uploader';
+
+import ApiUrls from '../../constants/api_urls';
+import AppConstants from '../../constants/application_constants';
+
+import { getCookie } from '../../utils/fetch_api_utils';
+
+let FurtherDetailsFileuploader = React.createClass({
+ propTypes: {
+ pieceId: React.PropTypes.number,
+ otherData: React.PropTypes.object,
+ setIsUploadReady: React.PropTypes.func,
+ submitKey: React.PropTypes.func,
+ isReadyForFormSubmission: React.PropTypes.func,
+ editable: React.PropTypes.bool,
+ multiple: React.PropTypes.bool
+ },
+
+ getDefaultProps() {
+ return {
+ multiple: false
+ };
+ },
+
+ render() {
+ // Essentially there a three cases important to the fileuploader
+ //
+ // 1. there is no other_data => do not show the fileuploader at all
+ // 2. there is other_data, but user has no edit rights => show fileuploader but without action buttons
+ // 3. both other_data and editable are defined or true => show fileuploade with all action buttons
+ if (!this.props.editable && !this.props.otherData){
+ return null;
+ }
+ return (
+
+
+
+ );
+ }
+});
+
+export default FurtherDetailsFileuploader;
\ No newline at end of file
diff --git a/js/components/ascribe_forms/form_loan.js b/js/components/ascribe_forms/form_loan.js
index f319c363..a96f12b9 100644
--- a/js/components/ascribe_forms/form_loan.js
+++ b/js/components/ascribe_forms/form_loan.js
@@ -2,6 +2,8 @@
import React from 'react';
+import classnames from 'classnames';
+
import Button from 'react-bootstrap/lib/Button';
import Form from './form';
@@ -20,12 +22,25 @@ import { getLangText } from '../../utils/lang_utils';
let LoanForm = React.createClass({
propTypes: {
+ fullform: React.PropTypes.bool,
+ email: React.PropTypes.string,
+ gallery: React.PropTypes.string,
+ startdate: React.PropTypes.string,
+ enddate: React.PropTypes.string,
+ showPersonalMessage: React.PropTypes.bool,
+
url: React.PropTypes.string,
id: React.PropTypes.object,
message: React.PropTypes.string,
handleSuccess: React.PropTypes.func
},
+ getDefaultProps() {
+ return {
+ fullform: false
+ };
+ },
+
getInitialState() {
return LoanContractStore.getState();
},
@@ -87,60 +102,87 @@ let LoanForm = React.createClass({
}
},
- render() {
+ getButtons() {
+ if(this.props.fullform) {
+ return (
+
+ {getLangText('Finish process')}
+
+ );
+ } else {
+ return (
+
+ {getLangText('Proceed to loan')}
+
+ }
+ spinner={
+
+
+
+ }>
+
+
+
+
+
+
+
+
+ );
+ } else {
+ return First register the piece.;
+ }
+ }
+});
+
+export default CylandAdditionalDataForm;
\ No newline at end of file
diff --git a/js/components/whitelabel/wallet/components/cyland/cyland_register_piece.js b/js/components/whitelabel/wallet/components/cyland/cyland_register_piece.js
index a1f76b6e..cb842df9 100644
--- a/js/components/whitelabel/wallet/components/cyland/cyland_register_piece.js
+++ b/js/components/whitelabel/wallet/components/cyland/cyland_register_piece.js
@@ -9,7 +9,6 @@ import Row from 'react-bootstrap/lib/Row';
import RegisterPieceForm from '../../../../ascribe_forms/form_register_piece';
import Property from '../../../../ascribe_forms/property';
-import InputTextAreaToggable from '../../../../ascribe_forms/input_textarea_toggable';
import InputCheckbox from '../../../../ascribe_forms/input_checkbox';
import PieceListStore from '../../../../../stores/piece_list_store';
@@ -18,36 +17,51 @@ import PieceListActions from '../../../../../actions/piece_list_actions';
import UserStore from '../../../../../stores/user_store';
import UserActions from '../../../../../actions/user_actions';
+import PieceStore from '../../../../../stores/piece_store';
+import PieceActions from '../../../../../actions/piece_actions';
+
import GlobalNotificationModel from '../../../../../models/global_notification_model';
import GlobalNotificationActions from '../../../../../actions/global_notification_actions';
+import CylandAdditionalDataForm from '../ascribe_forms/cyland_additional_data_form';
+
+import LoanForm from '../../../../ascribe_forms/form_loan';
+
import SlidesContainer from '../../../../ascribe_slides_container/slides_container';
+import ApiUrls from '../../../../../constants/api_urls';
+
import { getLangText } from '../../../../../utils/lang_utils';
-import { mergeOptions } from '../../../../../utils/general_utils';
+import { mergeOptions, dateToString } from '../../../../../utils/general_utils';
+import { getAclFormMessage } from '../../../../../utils/form_utils';
let CylandRegisterPiece = React.createClass({
+ mixins: [Router.Navigation],
+
getInitialState(){
return mergeOptions(
UserStore.getState(),
PieceListStore.getState(),
+ PieceStore.getState(),
{
selectedLicense: 0,
isFineUploaderActive: false
});
},
- mixins: [Router.Navigation],
-
componentDidMount() {
PieceListStore.listen(this.onChange);
UserStore.listen(this.onChange);
+ PieceStore.listen(this.onChange);
+
+ UserActions.fetchCurrentUser();
},
componentWillUnmount() {
PieceListStore.unlisten(this.onChange);
UserStore.unlisten(this.onChange);
+ PieceStore.unlisten(this.onChange);
},
onChange(state) {
@@ -61,9 +75,7 @@ let CylandRegisterPiece = React.createClass({
}
},
- handleSuccess(response){
- let notification = new GlobalNotificationModel(response.notification, 'success', 10000);
- GlobalNotificationActions.appendGlobalNotification(notification);
+ handleRegisterSuccess(response){
// once the user was able to register a piece successfully, we need to make sure to keep
// the piece list up to date
@@ -76,7 +88,16 @@ let CylandRegisterPiece = React.createClass({
this.state.filterBy
);
- this.transitionTo('piece', {pieceId: response.piece.id});
+ // also start loading the piece for the next step
+ if(response && response.piece) {
+ PieceActions.updatePiece(response.piece);
+ }
+
+ this.refs.slidesContainer.setSlideNum(1);
+ },
+
+ handleAdditionalDataSuccess() {
+ this.refs.slidesContainer.setSlideNum(2);
},
changeSlide() {
@@ -93,11 +114,14 @@ let CylandRegisterPiece = React.createClass({
},
render() {
+
+ let today = new Date();
+ let datetimeWhenWeAllWillBeFlyingCoolHoverboardsAndDinosaursWillLiveAgain = new Date();
+ datetimeWhenWeAllWillBeFlyingCoolHoverboardsAndDinosaursWillLiveAgain.setFullYear(3000);
+
return (
-
+
{' ' + getLangText('I agree to the Terms of Service the art price') + ' '}
- (
+ (
{getLangText('read')}
)
@@ -125,7 +149,28 @@ let CylandRegisterPiece = React.createClass({
- {/* next slide */}
+
+
+
+
+
+
+
+
+
+
+
+
);
diff --git a/js/utils/general_utils.js b/js/utils/general_utils.js
index 4dfda21d..85472fea 100644
--- a/js/utils/general_utils.js
+++ b/js/utils/general_utils.js
@@ -178,3 +178,25 @@ function _mergeOptions(obj1, obj2) {
export function escapeHTML(s) {
return document.createElement('div').appendChild(document.createTextNode(s)).parentNode.innerHTML;
}
+
+/**
+ * Converts a date object to a string.
+ * Taken from: http://stackoverflow.com/a/4929629/1263876
+ * @param {date} date a javascript date
+ * @return {string} a string, in format: DD-MM-YYY
+ */
+export function dateToString(date) {
+ var dd = date.getDate();
+ var mm = date.getMonth() + 1; //January is 0!
+ var yyyy = date.getFullYear();
+
+ if(dd < 10) {
+ dd = '0' + dd;
+ }
+
+ if(mm < 10) {
+ mm = '0' + mm;
+ }
+
+ return dd + '-' + mm + '-' + yyyy;
+}
\ No newline at end of file
From 1620437c86ace2a7615eb4bf89c03ce366c0fe05 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Wed, 12 Aug 2015 13:53:17 +0200
Subject: [PATCH 056/397] add defaultValue to inputdate
---
js/components/ascribe_forms/form_loan.js | 8 +++----
js/components/ascribe_forms/input_date.js | 9 +++++++-
.../cyland/cyland_register_piece.js | 14 +++++++-----
js/utils/general_utils.js | 22 -------------------
package.json | 1 +
5 files changed, 21 insertions(+), 33 deletions(-)
diff --git a/js/components/ascribe_forms/form_loan.js b/js/components/ascribe_forms/form_loan.js
index a96f12b9..fe6f1810 100644
--- a/js/components/ascribe_forms/form_loan.js
+++ b/js/components/ascribe_forms/form_loan.js
@@ -25,8 +25,8 @@ let LoanForm = React.createClass({
fullform: React.PropTypes.bool,
email: React.PropTypes.string,
gallery: React.PropTypes.string,
- startdate: React.PropTypes.string,
- enddate: React.PropTypes.string,
+ startdate: React.PropTypes.object,
+ enddate: React.PropTypes.object,
showPersonalMessage: React.PropTypes.bool,
url: React.PropTypes.string,
@@ -167,7 +167,7 @@ let LoanForm = React.createClass({
label={getLangText('Start date')}
hidden={!this.props.startdate}>
@@ -167,8 +169,8 @@ let CylandRegisterPiece = React.createClass({
url={ApiUrls.ownership_loans_pieces}
email="videoarchive@cyland.org"
gallery="Cyland Archive"
- startdate={dateToString(today)}
- enddate={dateToString(datetimeWhenWeAllWillBeFlyingCoolHoverboardsAndDinosaursWillLiveAgain)}/>
+ startdate={today}
+ enddate={datetimeWhenWeAllWillBeFlyingCoolHoverboardsAndDinosaursWillLiveAgain}/>
diff --git a/js/utils/general_utils.js b/js/utils/general_utils.js
index 85472fea..70c94a97 100644
--- a/js/utils/general_utils.js
+++ b/js/utils/general_utils.js
@@ -177,26 +177,4 @@ function _mergeOptions(obj1, obj2) {
*/
export function escapeHTML(s) {
return document.createElement('div').appendChild(document.createTextNode(s)).parentNode.innerHTML;
-}
-
-/**
- * Converts a date object to a string.
- * Taken from: http://stackoverflow.com/a/4929629/1263876
- * @param {date} date a javascript date
- * @return {string} a string, in format: DD-MM-YYY
- */
-export function dateToString(date) {
- var dd = date.getDate();
- var mm = date.getMonth() + 1; //January is 0!
- var yyyy = date.getFullYear();
-
- if(dd < 10) {
- dd = '0' + dd;
- }
-
- if(mm < 10) {
- mm = '0' + mm;
- }
-
- return dd + '-' + mm + '-' + yyyy;
}
\ No newline at end of file
diff --git a/package.json b/package.json
index ddf45059..8162df06 100644
--- a/package.json
+++ b/package.json
@@ -67,6 +67,7 @@
"isomorphic-fetch": "^2.0.2",
"jest-cli": "^0.4.0",
"lodash": "^3.9.3",
+ "moment": "^2.10.6",
"object-assign": "^2.0.0",
"q": "^1.4.1",
"raven-js": "^1.1.19",
From d3bf990ca5dd10928342c1bc4918aaf458fefb67 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Wed, 12 Aug 2015 14:40:44 +0200
Subject: [PATCH 057/397] adjust props
---
js/components/ascribe_forms/form_loan.js | 19 ++++++++++---------
.../cyland_additional_data_form.js | 3 +++
.../cyland/cyland_register_piece.js | 7 ++++---
3 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/js/components/ascribe_forms/form_loan.js b/js/components/ascribe_forms/form_loan.js
index fe6f1810..a0202e7f 100644
--- a/js/components/ascribe_forms/form_loan.js
+++ b/js/components/ascribe_forms/form_loan.js
@@ -22,7 +22,7 @@ import { getLangText } from '../../utils/lang_utils';
let LoanForm = React.createClass({
propTypes: {
- fullform: React.PropTypes.bool,
+ loanHeading: React.PropTypes.string,
email: React.PropTypes.string,
gallery: React.PropTypes.string,
startdate: React.PropTypes.object,
@@ -37,7 +37,8 @@ let LoanForm = React.createClass({
getDefaultProps() {
return {
- fullform: false
+ loanHeading: '',
+ showPersonalMessage: true
};
},
@@ -103,7 +104,7 @@ let LoanForm = React.createClass({
},
getButtons() {
- if(this.props.fullform) {
+ if(this.props.loanHeading) {
return (
From 0cf5815f42736d27187d7696c46884aa5b741510 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Wed, 12 Aug 2015 16:11:15 +0200
Subject: [PATCH 058/397] add functionality to make a forwarded process slide
container
---
js/components/ascribe_forms/form_loan.js | 2 +-
.../ascribe_slides_container/slides_container.js | 15 ++++++++++-----
js/components/header.js | 2 +-
js/components/register_piece.js | 16 +++++++---------
.../ascribe_forms/cyland_additional_data_form.js | 2 +-
.../components/cyland/cyland_register_piece.js | 6 ++++--
6 files changed, 24 insertions(+), 19 deletions(-)
diff --git a/js/components/ascribe_forms/form_loan.js b/js/components/ascribe_forms/form_loan.js
index a0202e7f..3fc6bd6e 100644
--- a/js/components/ascribe_forms/form_loan.js
+++ b/js/components/ascribe_forms/form_loan.js
@@ -140,7 +140,7 @@ let LoanForm = React.createClass({
}>
-
+
{this.props.loanHeading}
{getLangText('COLLECTION')};
- addNewWork = this.props.showAddWork ? + {getLangText('NEW WORK')} : null;
+ addNewWork = this.props.showAddWork ? + {getLangText('NEW WORK')} : null;
}
else {
account = {getLangText('LOGIN')};
diff --git a/js/components/register_piece.js b/js/components/register_piece.js
index 229592b0..78474f46 100644
--- a/js/components/register_piece.js
+++ b/js/components/register_piece.js
@@ -117,7 +117,8 @@ let RegisterPiece = React.createClass( {
}
},
- changeSlide() {
+ // basically redirects to the second slide (index: 1), when the user is not logged in
+ onLoggedOut() {
// only transition to the login store, if user is not logged in
// ergo the currentUser object is not properly defined
if(this.state.currentUser && !this.state.currentUser.email) {
@@ -125,11 +126,6 @@ let RegisterPiece = React.createClass( {
}
},
- // basically redirects to the second slide (index: 1), when the user is not logged in
- onLoggedOut() {
- this.refs.slidesContainer.setSlideNum(1);
- },
-
onLogin() {
// once the currentUser object from UserStore is defined (eventually the user was transitioned
// to the login form via the slider and successfully logged in), we can direct him back to the
@@ -141,10 +137,12 @@ let RegisterPiece = React.createClass( {
render() {
return (
-
+
+ );
+ }
+ return null;
+ },
+
// Since we need to give the slides a width, we need to call ReactAddons.addons.cloneWithProps
// Also, a key is nice to have!
renderChildren() {
@@ -151,15 +183,16 @@ let SlidesContainer = React.createClass({
+ {this.renderBreadCrumbs()}
-
- {this.renderChildren()}
-
+
+ {this.renderChildren()}
+
);
diff --git a/js/components/whitelabel/wallet/components/ascribe_forms/cyland_additional_data_form.js b/js/components/whitelabel/wallet/components/ascribe_forms/cyland_additional_data_form.js
index 33b3e4ca..0ae5e22a 100644
--- a/js/components/whitelabel/wallet/components/ascribe_forms/cyland_additional_data_form.js
+++ b/js/components/whitelabel/wallet/components/ascribe_forms/cyland_additional_data_form.js
@@ -80,14 +80,6 @@ let CylandAdditionalDataForm = React.createClass({
Provide supporting materials
-
+
);
} else {
diff --git a/js/components/whitelabel/wallet/components/cyland/cyland_register_piece.js b/js/components/whitelabel/wallet/components/cyland/cyland_register_piece.js
index 918db052..42c5e14e 100644
--- a/js/components/whitelabel/wallet/components/cyland/cyland_register_piece.js
+++ b/js/components/whitelabel/wallet/components/cyland/cyland_register_piece.js
@@ -102,6 +102,13 @@ let CylandRegisterPiece = React.createClass({
this.refs.slidesContainer.setSlideNum(2);
},
+ handleLoanSuccess(response) {
+ let notification = new GlobalNotificationModel(response.notification, 'success', 10000);
+ GlobalNotificationActions.appendGlobalNotification(notification);
+
+ this.transitionTo('piece', {pieceId: this.state.piece.id});
+ },
+
changeSlide() {
// only transition to the login store, if user is not logged in
// ergo the currentUser object is not properly defined
@@ -124,6 +131,7 @@ let CylandRegisterPiece = React.createClass({
return (
);
+ } else {
+ return null;
}
- return null;
},
// Since we need to give the slides a width, we need to call ReactAddons.addons.cloneWithProps
@@ -186,7 +202,7 @@ let SlidesContainer = React.createClass({
);
diff --git a/js/components/ascribe_slides_container/slides_container.js b/js/components/ascribe_slides_container/slides_container.js
index 95c5859f..56f1547f 100644
--- a/js/components/ascribe_slides_container/slides_container.js
+++ b/js/components/ascribe_slides_container/slides_container.js
@@ -21,15 +21,22 @@ let SlidesContainer = React.createClass({
// handle queryParameters
let queryParams = this.getQuery();
let slideNum = -1;
+ let startFrom = -1;
if(queryParams && 'slide_num' in queryParams) {
slideNum = parseInt(queryParams.slide_num, 10);
}
// if slide_num is not set, this will be done in componentDidMount
+ // the query param 'start_from' removes all slide children before the respective number
+ if(queryParams && 'start_from' in queryParams) {
+ startFrom = parseInt(queryParams.start_from, 10);
+ }
+
return {
+ slideNum,
+ startFrom,
containerWidth: 0,
- slideNum: slideNum,
historyLength: window.history.length
};
},
@@ -54,9 +61,23 @@ let SlidesContainer = React.createClass({
window.addEventListener('resize', this.handleContainerResize);
},
- componentDidUpdate() {
- // check if slide_num was defined, and if not then default to 0
+ componentWillReceiveProps() {
let queryParams = this.getQuery();
+
+ // also check if start_from was updated
+ // This applies for example when the user tries to submit a already existing piece
+ // (starting from slide 1 for example) and then clicking on + NEW WORK
+ if(queryParams && !('start_from' in queryParams)) {
+ this.setState({
+ startFrom: -1
+ });
+ }
+ },
+
+ componentDidUpdate() {
+ let queryParams = this.getQuery();
+
+ // check if slide_num was defined, and if not then default to 0
this.setSlideNum(queryParams.slide_num);
},
@@ -137,20 +158,34 @@ let SlidesContainer = React.createClass({
extractBreadcrumbs() {
let breadcrumbs = [];
- ReactAddons.Children.map(this.props.children, (child) => {
- breadcrumbs.push(child.props['data-slide-title']);
+ ReactAddons.Children.map(this.props.children, (child, i) => {
+ if(i >= this.state.startFrom) {
+ breadcrumbs.push(child.props['data-slide-title']);
+ }
});
return breadcrumbs;
},
+ customChildrenCount() {
+ let count = 0;
+ React.Children.forEach(this.props.children, (child, i) => {
+ if(i >= this.state.startFrom) {
+ count++;
+ }
+ });
+
+ return count;
+ },
+
renderBreadcrumbs() {
let breadcrumbs = this.extractBreadcrumbs();
- let numOfChildren = React.Children.count(this.props.children);
+ let numOfChildren = this.customChildrenCount();
// check if every child/slide has a title,
// otherwise do not display the breadcrumbs at all
- if(breadcrumbs.length === numOfChildren) {
+ // Also, if there is only one child, do not display the breadcrumbs
+ if(breadcrumbs.length === numOfChildren && breadcrumbs.length > 1 && numOfChildren > 1) {
let numSlides = breadcrumbs.length;
let columnWidth = Math.floor(12 / numSlides);
@@ -187,13 +222,21 @@ let SlidesContainer = React.createClass({
// Also, a key is nice to have!
renderChildren() {
return ReactAddons.Children.map(this.props.children, (child, i) => {
- return ReactAddons.addons.cloneWithProps(child, {
- className: 'ascribe-slide',
- style: {
- width: this.state.containerWidth
- },
- key: i
- });
+ // since the default parameter of startFrom is -1, we do not need to check
+ // if its actually present in the url bar, as it will just not match
+
+ if(i >= this.state.startFrom) {
+ return ReactAddons.addons.cloneWithProps(child, {
+ className: 'ascribe-slide',
+ style: {
+ width: this.state.containerWidth
+ },
+ key: i
+ });
+ } else {
+ // Abortions are bad mkay
+ return null;
+ }
});
},
diff --git a/js/components/piece_list.js b/js/components/piece_list.js
index eac6ca15..14554ea0 100644
--- a/js/components/piece_list.js
+++ b/js/components/piece_list.js
@@ -138,7 +138,7 @@ let PieceList = React.createClass({
this.transitionTo(this.getPathname(), {page: 1});
},
- applyOrderBy(orderBy, orderAsc) {
+ applyOrderBy(orderBy) {
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
orderBy, this.state.orderAsc, this.state.filterBy);
},
diff --git a/js/components/whitelabel/wallet/components/cyland/ascribe_buttons/cyland_submit_button.js b/js/components/whitelabel/wallet/components/cyland/ascribe_buttons/cyland_submit_button.js
index 8b9a53ef..a4c23e41 100644
--- a/js/components/whitelabel/wallet/components/cyland/ascribe_buttons/cyland_submit_button.js
+++ b/js/components/whitelabel/wallet/components/cyland/ascribe_buttons/cyland_submit_button.js
@@ -39,7 +39,11 @@ let CylandSubmitButton = React.createClass({
return (
{getLangText('Submit to Cyland')}
diff --git a/js/components/whitelabel/wallet/components/cyland/ascribe_detail/cyland_piece_container.js b/js/components/whitelabel/wallet/components/cyland/ascribe_detail/cyland_piece_container.js
index d22d8638..c8011fc7 100644
--- a/js/components/whitelabel/wallet/components/cyland/ascribe_detail/cyland_piece_container.js
+++ b/js/components/whitelabel/wallet/components/cyland/ascribe_detail/cyland_piece_container.js
@@ -20,11 +20,8 @@ import FurtherDetailsFileuploader from '../../../../../ascribe_detail/further_de
import DetailProperty from '../../../../../ascribe_detail/detail_property';
import { mergeOptions } from '../../../../../../utils/general_utils';
-import { getLangText } from '../../../../../../utils/lang_utils';
-/**
- * This is the component that implements resource/data specific functionality
- */
+
let CylandPieceContainer = React.createClass({
getInitialState() {
return mergeOptions(
@@ -106,10 +103,11 @@ let CylandPieceDetails = React.createClass({
show={true}
defaultExpanded={true}>
Date: Wed, 19 Aug 2015 16:03:59 +0200
Subject: [PATCH 090/397] Revert "form validation first cut"
Tim:
I reverted this commit because I want to keep if for later.
We decided to do so because we're of the opinion validation is not a pressing issue right now.
This reverts commit 8a814c287cd6dc85fbd63cb29518ac0e21aabfb3.
---
js/components/ascribe_forms/form.js | 41 ++-----------
.../ascribe_forms/form_register_piece.js | 58 ++++++-------------
js/components/ascribe_forms/input_checkbox.js | 27 ++++-----
js/components/ascribe_forms/property.js | 43 +++-----------
.../cyland/cyland_register_piece.js | 3 +-
5 files changed, 41 insertions(+), 131 deletions(-)
diff --git a/js/components/ascribe_forms/form.js b/js/components/ascribe_forms/form.js
index a9e267d9..2b956a7e 100644
--- a/js/components/ascribe_forms/form.js
+++ b/js/components/ascribe_forms/form.js
@@ -23,8 +23,8 @@ let Form = React.createClass({
handleSuccess: React.PropTypes.func,
getFormData: React.PropTypes.func,
children: React.PropTypes.oneOfType([
- React.PropTypes.arrayOf(React.PropTypes.element),
- React.PropTypes.element
+ React.PropTypes.object,
+ React.PropTypes.array
]),
className: React.PropTypes.string,
spinner: React.PropTypes.element,
@@ -165,43 +165,14 @@ let Form = React.createClass({
this.setState({errors: []});
},
- checkFormValidity() {
- let requiredProps = [];
-
- Object
- .keys(this.refs)
- .forEach((refName) => {
- if(this.refs[refName].props.required) {
- requiredProps.push(this.refs[refName]);
- }
- });
-
- let validProps = requiredProps.filter((property) => property.state.isValid);
-
- if(requiredProps.length === validProps.length) {
- return true;
- } else {
- return false;
- }
-
- },
-
getButtons() {
- let buttons = null;
- let isFormValid = this.checkFormValidity();
-
- if(this.state.submitted) {
+ if (this.state.submitted){
return this.props.spinner;
}
- if(this.props.buttons) {
-
- buttons = React.cloneElement(this.props.buttons, {
- disabled: !isFormValid
- });
-
- return buttons;
+ if (this.props.buttons){
+ return this.props.buttons;
}
-
+ let buttons = null;
if (this.state.edited){
buttons = (
diff --git a/js/components/ascribe_forms/form_register_piece.js b/js/components/ascribe_forms/form_register_piece.js
index ef25dd55..6545007c 100644
--- a/js/components/ascribe_forms/form_register_piece.js
+++ b/js/components/ascribe_forms/form_register_piece.js
@@ -27,10 +27,7 @@ let RegisterPieceForm = React.createClass({
isFineUploaderActive: React.PropTypes.bool,
isFineUploaderEditable: React.PropTypes.bool,
enableLocalHashing: React.PropTypes.bool,
- children: React.PropTypes.oneOfType([
- React.PropTypes.arrayOf(React.PropTypes.element),
- React.PropTypes.element
- ]),
+ children: React.PropTypes.element,
onLoggedOut: React.PropTypes.func
},
@@ -77,11 +74,16 @@ let RegisterPieceForm = React.createClass({
});
},
+ setIsUploadReady(isReady) {
+ this.setState({
+ isUploadReady: isReady
+ });
+ },
+
render() {
let currentUser = this.state.currentUser;
let enableLocalHashing = currentUser && currentUser.profile ? currentUser.profile.hash_locally : false;
enableLocalHashing = enableLocalHashing && this.props.enableLocalHashing;
-
return (
{this.props.headerMessage}
+ ignoreFocus={true}>
+ label={getLangText('Artist Name')}>
+ label={getLangText('Title')}>
+ label={getLangText('Year Created')}>
+ style={{paddingBottom: 0}}>
{' ' + getLangText('I agree to the Terms of Service of Cyland Archive') + ' '}
From 862cd7986c208ccf488e3771f6bf770c3fd9b897 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Wed, 19 Aug 2015 17:06:14 +0200
Subject: [PATCH 091/397] add lock/disabled functionality to form
---
js/components/ascribe_forms/form.js | 6 +++-
.../ascribe_forms/form_register_piece.js | 18 ++++++++++--
js/components/ascribe_forms/input_checkbox.js | 28 +++++++++++++++++--
js/components/ascribe_forms/property.js | 20 +++++++++----
sass/ascribe_settings.scss | 2 --
5 files changed, 62 insertions(+), 12 deletions(-)
diff --git a/js/components/ascribe_forms/form.js b/js/components/ascribe_forms/form.js
index 2b956a7e..eac91d42 100644
--- a/js/components/ascribe_forms/form.js
+++ b/js/components/ascribe_forms/form.js
@@ -33,6 +33,9 @@ let Form = React.createClass({
React.PropTypes.arrayOf(React.PropTypes.element)
]),
+ // Can be used to freeze the whole form
+ disabled: React.PropTypes.bool,
+
// You can use the form for inline requests, like the submit click on a button.
// For the form to then not display the error on top, you need to enable this option.
// It will make use of the GlobalNotification
@@ -203,7 +206,8 @@ let Form = React.createClass({
if (child) {
return ReactAddons.addons.cloneWithProps(child, {
handleChange: this.handleChangeChild,
- ref: child.props.name
+ ref: child.props.name,
+ editable: !this.props.disabled
});
}
});
diff --git a/js/components/ascribe_forms/form_register_piece.js b/js/components/ascribe_forms/form_register_piece.js
index 6545007c..a47ab00e 100644
--- a/js/components/ascribe_forms/form_register_piece.js
+++ b/js/components/ascribe_forms/form_register_piece.js
@@ -86,6 +86,7 @@ let RegisterPieceForm = React.createClass({
enableLocalHashing = enableLocalHashing && this.props.enableLocalHashing;
return (
@@ -83,7 +105,9 @@ let InputCheckbox = React.createClass({
onChange={this.onChange}
checked={this.state.value}
defaultChecked={this.props.defaultChecked}/>
-
+
{this.props.children}
diff --git a/js/components/ascribe_forms/property.js b/js/components/ascribe_forms/property.js
index 5a72270c..acb38234 100644
--- a/js/components/ascribe_forms/property.js
+++ b/js/components/ascribe_forms/property.js
@@ -6,6 +6,8 @@ import ReactAddons from 'react/addons';
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger';
import Tooltip from 'react-bootstrap/lib/Tooltip';
+import { mergeOptions } from '../../utils/general_utils';
+
let Property = React.createClass({
propTypes: {
hidden: React.PropTypes.bool,
@@ -167,9 +169,10 @@ let Property = React.createClass({
}
},
- renderChildren() {
+ renderChildren(style) {
return ReactAddons.Children.map(this.props.children, (child) => {
return ReactAddons.addons.cloneWithProps(child, {
+ style,
onChange: this.handleChange,
onFocus: this.handleFocus,
onBlur: this.handleBlur,
@@ -181,25 +184,32 @@ let Property = React.createClass({
render() {
let tooltip = ;
- if (this.props.tooltip){
+ let style = this.props.style ? mergeOptions({}, this.props.style) : {};
+
+ if(this.props.tooltip){
tooltip = (
{this.props.tooltip}
);
}
let footer = null;
- if (this.props.footer){
+ if(this.props.footer){
footer = (
+
);
} else {
return null;
@@ -251,9 +216,9 @@ let SlidesContainer = React.createClass({
// Also, a key is nice to have!
renderChildren() {
return ReactAddons.Children.map(this.props.children, (child, i) => {
+
// since the default parameter of startFrom is -1, we do not need to check
// if its actually present in the url bar, as it will just not match
-
if(i >= this.state.startFrom) {
return ReactAddons.addons.cloneWithProps(child, {
className: 'ascribe-slide',
@@ -266,6 +231,7 @@ let SlidesContainer = React.createClass({
// Abortions are bad mkay
return null;
}
+
});
},
diff --git a/js/components/ascribe_slides_container/slides_container_breadcrumbs.js b/js/components/ascribe_slides_container/slides_container_breadcrumbs.js
new file mode 100644
index 00000000..eb3e95f1
--- /dev/null
+++ b/js/components/ascribe_slides_container/slides_container_breadcrumbs.js
@@ -0,0 +1,78 @@
+'use strict';
+
+import React from 'react';
+
+import Col from 'react-bootstrap/lib/Col';
+
+
+// Note:
+//
+// If we ever need generic breadcrumbs component, we should refactor this
+let SlidesContainerBreadcrumbs = React.createClass({
+ propTypes: {
+ breadcrumbs: React.PropTypes.arrayOf(React.PropTypes.string).isRequired,
+
+ slideNum: React.PropTypes.number.isRequired,
+ numOfSlides: React.PropTypes.number.isRequired,
+
+ containerWidth: React.PropTypes.number.isRequired,
+
+ glyphiconClassNames: React.PropTypes.shape({
+ pending: React.PropTypes.string,
+ complete: React.PropTypes.string
+ })
+ },
+
+ getDefaultProps() {
+ return {
+ glyphiconClassNames: {
+ pending: 'glyphicon glyphicon-chevron-right',
+ complete: 'glyphicon glyphicon-lock'
+ }
+ };
+ },
+
+ render() {
+ let breadcrumbs = this.props.breadcrumbs;
+ let numSlides = breadcrumbs.length;
+ let columnWidth = Math.floor(12 / numSlides);
+
+ return (
+
+
+
+ {breadcrumbs.map((breadcrumb, i) => {
+
+ // Depending on the progress the user has already made, we display different
+ // glyphicons that can also be specified from the outside
+ let glyphiconClassName;
+
+ if(i >= this.props.slideNum) {
+ glyphiconClassName = this.props.glyphiconClassNames.pending;
+ } else {
+ glyphiconClassName = this.props.glyphiconClassNames.completed;
+ }
+
+ return (
+
diff --git a/js/components/ascribe_detail/further_details_fileuploader.js b/js/components/ascribe_detail/further_details_fileuploader.js
index 7c5525fd..064b6a77 100644
--- a/js/components/ascribe_detail/further_details_fileuploader.js
+++ b/js/components/ascribe_detail/further_details_fileuploader.js
@@ -33,8 +33,8 @@ let FurtherDetailsFileuploader = React.createClass({
//
// 1. there is no other_data => do not show the fileuploader at all
// 2. there is other_data, but user has no edit rights => show fileuploader but without action buttons
- // 3. both other_data and editable are defined or true => show fileuploade with all action buttons
- if (!this.props.editable && !this.props.otherData){
+ // 3. both other_data and editable are defined or true => show fileuploader with all action buttons
+ if (!this.props.editable && (!this.props.otherData || this.props.otherData.length == 0)){
return null;
}
let otherDataIds = this.props.otherData ? this.props.otherData.map((data)=>{return data.id; }).join() : null;
diff --git a/js/components/ascribe_detail/piece_container.js b/js/components/ascribe_detail/piece_container.js
index 7380ada7..1552a985 100644
--- a/js/components/ascribe_detail/piece_container.js
+++ b/js/components/ascribe_detail/piece_container.js
@@ -183,7 +183,7 @@ let PieceContainer = React.createClass({
title="Further Details"
show={this.state.piece.acl.acl_edit
|| Object.keys(this.state.piece.extra_data).length > 0
- || this.state.piece.other_data !== null}
+ || this.state.piece.other_data.length > 0}
defaultExpanded={true}>
);
} else {
- header = ;
+ header = ;
}
return (
From ffdb4847dbd50c5b3419094d54885d4460e9668f Mon Sep 17 00:00:00 2001
From: diminator
Date: Thu, 20 Aug 2015 14:01:02 +0200
Subject: [PATCH 100/397] piece bitcoin id
---
.../ascribe_detail/piece_container.js | 50 +++++++++++++++++++
.../ascribe_detail/prize_piece_container.js | 2 +-
2 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/js/components/ascribe_detail/piece_container.js b/js/components/ascribe_detail/piece_container.js
index 1552a985..2c36035b 100644
--- a/js/components/ascribe_detail/piece_container.js
+++ b/js/components/ascribe_detail/piece_container.js
@@ -28,6 +28,11 @@ import DeleteButton from '../ascribe_buttons/delete_button';
import GlobalNotificationModel from '../../models/global_notification_model';
import GlobalNotificationActions from '../../actions/global_notification_actions';
+import Form from '../ascribe_forms/form';
+import Property from '../ascribe_forms/property';
+import InputTextAreaToggable from '../ascribe_forms/input_textarea_toggable';
+
+import ApiUrls from '../../constants/api_urls';
import AppConstants from '../../constants/application_constants';
import { mergeOptions } from '../../utils/general_utils';
import { getLangText } from '../../utils/lang_utils';
@@ -159,6 +164,7 @@ let PieceContainer = React.createClass({
subheader={
Date: Mon, 24 Aug 2015 11:01:42 +0200
Subject: [PATCH 117/397] bug fix loadPiece
---
js/components/ascribe_detail/further_details_fileuploader.js | 1 -
js/components/ascribe_detail/piece_container.js | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/js/components/ascribe_detail/further_details_fileuploader.js b/js/components/ascribe_detail/further_details_fileuploader.js
index a6eea898..2b04a210 100644
--- a/js/components/ascribe_detail/further_details_fileuploader.js
+++ b/js/components/ascribe_detail/further_details_fileuploader.js
@@ -30,7 +30,6 @@ let FurtherDetailsFileuploader = React.createClass({
},
render() {
- console.log(this.props)
// Essentially there a three cases important to the fileuploader
//
// 1. there is no other_data => do not show the fileuploader at all
diff --git a/js/components/ascribe_detail/piece_container.js b/js/components/ascribe_detail/piece_container.js
index bb528a56..fe1a6c8a 100644
--- a/js/components/ascribe_detail/piece_container.js
+++ b/js/components/ascribe_detail/piece_container.js
@@ -160,7 +160,7 @@ let PieceContainer = React.createClass({
pieceOrEditions={ this.state.piece }
requestAction={this.state.piece.request_action}
requestUser={this.state.piece.user_registered}
- handleSuccess={this.showNotification}/>);
+ handleSuccess={this.loadPiece}/>);
}
else {
return (
From d05662b87926104ee326d9d9dd0aedaa025d3575 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Mon, 24 Aug 2015 11:22:44 +0200
Subject: [PATCH 118/397] fix PR issues
---
.../further_details_fileuploader.js | 2 +-
js/components/ascribe_forms/input_date.js | 3 ++
.../slides_container.js | 6 ++++
.../slides_container_breadcrumbs.js | 11 ++++--
.../ascribe_detail/prize_piece_container.js | 23 ++++++++----
.../prize/components/prize_landing.js | 22 ++++++------
.../prize/components/prize_login_container.js | 16 ++++++---
.../prize/components/prize_piece_list.js | 4 ++-
.../prize/components/prize_register_piece.js | 4 +--
.../components/prize_settings_container.js | 35 +++++++++++--------
.../components/prize_signup_container.js | 5 +--
.../ascribe_buttons/cyland_submit_button.js | 5 +++
.../ascribe_detail/cyland_piece_container.js | 4 +--
.../cyland_additional_data_form.js | 4 ++-
.../components/cyland/cyland_landing.js | 13 ++++---
.../cyland/cyland_register_piece.js | 12 ++++---
.../ikonotv_accordion_list_item.js | 28 ++++++++-------
.../ascribe_forms/ikonotv_contract_form.js | 14 +++++---
18 files changed, 136 insertions(+), 75 deletions(-)
diff --git a/js/components/ascribe_detail/further_details_fileuploader.js b/js/components/ascribe_detail/further_details_fileuploader.js
index 2b04a210..8c1023ba 100644
--- a/js/components/ascribe_detail/further_details_fileuploader.js
+++ b/js/components/ascribe_detail/further_details_fileuploader.js
@@ -32,7 +32,7 @@ let FurtherDetailsFileuploader = React.createClass({
render() {
// Essentially there a three cases important to the fileuploader
//
- // 1. there is no other_data => do not show the fileuploader at all
+ // 1. there is no other_data => do not show the fileuploader at all (where otherData is now an array)
// 2. there is other_data, but user has no edit rights => show fileuploader but without action buttons
// 3. both other_data and editable are defined or true => show fileuploader with all action buttons
if (!this.props.editable && (!this.props.otherData || this.props.otherData.length === 0)) {
diff --git a/js/components/ascribe_forms/input_date.js b/js/components/ascribe_forms/input_date.js
index 2e25fc00..f2df69b9 100644
--- a/js/components/ascribe_forms/input_date.js
+++ b/js/components/ascribe_forms/input_date.js
@@ -18,6 +18,9 @@ let InputDate = React.createClass({
};
},
+ // InputDate needs to support setting a defaultValue from outside.
+ // If this is the case, we need to call handleChange to propagate this
+ // to the outer Property
componentWillReceiveProps(nextProps) {
if(!this.state.value && !this.state.value_moment && nextProps.defaultValue) {
this.handleChange(this.props.defaultValue);
diff --git a/js/components/ascribe_slides_container/slides_container.js b/js/components/ascribe_slides_container/slides_container.js
index bdaef734..4ac4d57a 100644
--- a/js/components/ascribe_slides_container/slides_container.js
+++ b/js/components/ascribe_slides_container/slides_container.js
@@ -167,6 +167,8 @@ let SlidesContainer = React.createClass({
}
},
+ // breadcrumbs are defined as attributes of the slides.
+ // To extract them we have to read the DOM element's attributes
extractBreadcrumbs() {
let breadcrumbs = [];
@@ -179,6 +181,10 @@ let SlidesContainer = React.createClass({
return breadcrumbs;
},
+ // If startFrom is defined as a URL parameter, this can manipulate
+ // the number of children that are injected into the DOM.
+ // Therefore React.Children.count does not work anymore and we
+ // need to implement our own method.
customChildrenCount() {
let count = 0;
React.Children.forEach(this.props.children, (child, i) => {
diff --git a/js/components/ascribe_slides_container/slides_container_breadcrumbs.js b/js/components/ascribe_slides_container/slides_container_breadcrumbs.js
index eb3e95f1..6d361ca2 100644
--- a/js/components/ascribe_slides_container/slides_container_breadcrumbs.js
+++ b/js/components/ascribe_slides_container/slides_container_breadcrumbs.js
@@ -2,6 +2,8 @@
import React from 'react';
+import classnames from 'classnames';
+
import Col from 'react-bootstrap/lib/Col';
@@ -59,9 +61,14 @@ let SlidesContainerBreadcrumbs = React.createClass({
sm={columnWidth}
key={i}>
diff --git a/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js b/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js
index 6ce3a852..fd25190f 100644
--- a/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js
+++ b/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js
@@ -63,6 +63,8 @@ let PieceContainer = React.createClass({
UserStore.unlisten(this.onChange);
},
+ // This is done to update the container when the user clicks on the prev or next
+ // button to update the URL parameter (and therefore to switch pieces)
componentWillReceiveProps(nextProps) {
if(this.props.params.pieceId !== nextProps.params.pieceId) {
PieceActions.updatePiece({});
@@ -123,19 +125,20 @@ let NavigationHeader = React.createClass({
},
render() {
- if (this.props.currentUser && this.props.piece.navigation) {
+ if (this.props.currentUser && this.props.currentUser.email && this.props.piece && this.props.piece.navigation) {
let nav = this.props.piece.navigation;
+
return (
- Previous
+ {getLangText('Previous')}
- Next
+ {getLangText('Next')}
@@ -177,6 +180,10 @@ let PrizePieceRatings = React.createClass({
PieceListStore.unlisten(this.onChange);
},
+ // The StarRating component does not have a property that lets us set
+ // a default value at initialization. Since the ratingCache would otherwise on
+ // every mouseover be overridden, we need to set it ourselves initially to deal
+ // with the problem.
onChange(state) {
this.setState(state);
if (this.refs.rating) {
@@ -196,6 +203,7 @@ let PrizePieceRatings = React.createClass({
this.state.orderBy, this.state.orderAsc, this.state.filterBy)
);
},
+
render(){
if (this.props.currentUser && this.props.currentUser.is_jury) {
return (
@@ -234,7 +242,7 @@ let PersonalNote = React.createClass({
},
render() {
- if (this.props.currentUser.username && true || false) {
+ if (this.props.currentUser && this.props.currentUser.username) {
return (
@@ -267,12 +275,13 @@ let PrizePieceDetails = React.createClass({
},
render() {
- if (this.props.piece.prize
+ if (this.props.piece
+ && this.props.piece.prize
&& this.props.piece.prize.name
&& Object.keys(this.props.piece.extra_data).length !== 0){
return (
diff --git a/js/components/whitelabel/prize/components/prize_landing.js b/js/components/whitelabel/prize/components/prize_landing.js
index 75cdff79..c47f8088 100644
--- a/js/components/whitelabel/prize/components/prize_landing.js
+++ b/js/components/whitelabel/prize/components/prize_landing.js
@@ -13,7 +13,7 @@ import UserStore from '../../../../stores/user_store';
import UserActions from '../../../../actions/user_actions';
import { mergeOptions } from '../../../../utils/general_utils';
-
+import { getLangText } from '../../../../utils/lang_utils';
let Landing = React.createClass({
@@ -53,14 +53,14 @@ let Landing = React.createClass({
return (
- Sign up to submit
+ {getLangText('Sign up to submit')}
- or, already an ascribe user?
+ {getLangText('or, already an ascribe user?')}
);
diff --git a/js/components/whitelabel/wallet/components/cyland/ascribe_buttons/cyland_submit_button.js b/js/components/whitelabel/wallet/components/cyland/ascribe_buttons/cyland_submit_button.js
index ab7723ea..72ff595b 100644
--- a/js/components/whitelabel/wallet/components/cyland/ascribe_buttons/cyland_submit_button.js
+++ b/js/components/whitelabel/wallet/components/cyland/ascribe_buttons/cyland_submit_button.js
@@ -39,6 +39,11 @@ let CylandSubmitButton = React.createClass({
let piece = this.props.piece;
let startFrom = 1;
+ // In the Cyland register page a user has to complete three steps.
+ // Since every one of those steps is atomic a user should always be able to continue
+ // where he left of.
+ // This is why we start the process form slide 1/2 if the user has already finished
+ // it in another session.
if(piece && piece.extra_data && Object.keys(piece.extra_data).length > 0) {
startFrom = 2;
}
diff --git a/js/components/whitelabel/wallet/components/cyland/ascribe_detail/cyland_piece_container.js b/js/components/whitelabel/wallet/components/cyland/ascribe_detail/cyland_piece_container.js
index 2da39a72..e46d4886 100644
--- a/js/components/whitelabel/wallet/components/cyland/ascribe_detail/cyland_piece_container.js
+++ b/js/components/whitelabel/wallet/components/cyland/ascribe_detail/cyland_piece_container.js
@@ -114,10 +114,10 @@ let CylandPieceDetails = React.createClass({
},
render() {
- if (Object.keys(this.props.piece.extra_data).length !== 0){
+ if (this.props.piece && Object.keys(this.props.piece.extra_data).length !== 0){
return (
diff --git a/js/components/whitelabel/wallet/components/cyland/ascribe_forms/cyland_additional_data_form.js b/js/components/whitelabel/wallet/components/cyland/ascribe_forms/cyland_additional_data_form.js
index b97d568c..c8dd7f2c 100644
--- a/js/components/whitelabel/wallet/components/cyland/ascribe_forms/cyland_additional_data_form.js
+++ b/js/components/whitelabel/wallet/components/cyland/ascribe_forms/cyland_additional_data_form.js
@@ -95,7 +95,9 @@ let CylandAdditionalDataForm = React.createClass({
}>
-
Provide supporting materials
+
+ {getLangText('Provide supporting materials')}
+
- Submissions to Cyland Archive are powered by
+ {getLangText('Submissions to Cyland Archive are powered by')}
ascribe
@@ -67,18 +66,18 @@ let CylandLanding = React.createClass({
- Do you need an account?
+ {getLangText('Do you need an account?')}
- Sign up
+ {getLangText('Sign up')}
diff --git a/js/components/whitelabel/wallet/components/cyland/cyland_register_piece.js b/js/components/whitelabel/wallet/components/cyland/cyland_register_piece.js
index 489be043..8a092bdf 100644
--- a/js/components/whitelabel/wallet/components/cyland/cyland_register_piece.js
+++ b/js/components/whitelabel/wallet/components/cyland/cyland_register_piece.js
@@ -68,6 +68,10 @@ let CylandRegisterPiece = React.createClass({
let queryParams = this.getQuery();
+ // Since every step of this register process is atomic,
+ // we may need to enter the process at step 1 or 2.
+ // If this is the case, we'll need the piece number to complete submission.
+ // It is encoded in the URL as a queryParam and we're checking for it here.
if(queryParams && 'piece_id' in queryParams) {
PieceActions.fetchOne(queryParams.piece_id);
}
@@ -176,7 +180,7 @@ let CylandRegisterPiece = React.createClass({
pending: 'glyphicon glyphicon-chevron-right',
completed: 'glyphicon glyphicon-lock'
}}>
-
- Submit your rating
+ {getLangText('Submit your rating')}
);
@@ -144,25 +144,28 @@ let AccordionListItemPrize = React.createClass({
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
},
+ onSelectChange(){
+ PrizeRatingActions.toggleShortlist(this.props.content.id)
+ .then(
+ (res) => {
+ this.refreshPieceData();
+ return res;
+ })
+ .then(
+ (res) => {
+ this.handleShortlistSuccess(res.notification);
+ }
+ );
+
+ },
+
getPrizeBadge(){
if (this.state.currentUser && this.state.currentUser.is_judge) {
return (
{
- PrizeRatingActions.toggleShortlist(this.props.content.id)
- .then(
- (res) => {
- this.refreshPieceData();
- return res;
- })
- .then(
- (res) => {
- this.handleShortlistSuccess(res.notification);
- }
- );
- }}/>
+ onChange={this.onSelectChange}/>
);
}
@@ -170,6 +173,7 @@ let AccordionListItemPrize = React.createClass({
},
render() {
+ // Only show the artist name if you are the participant or if you are a judge and the piece is shortlisted
let artistName = ((this.state.currentUser.is_jury && !this.state.currentUser.is_judge) ||
(this.state.currentUser.is_judge && !this.props.content.selected )) ?
: this.props.content.artist_name;
diff --git a/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js b/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js
index f4bfc6d7..6daef7ea 100644
--- a/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js
+++ b/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js
@@ -106,9 +106,11 @@ let PieceContainer = React.createClass({
render() {
if('title' in this.state.piece) {
+ // Only show the artist name if you are the participant or if you are a judge and the piece is shortlisted
let artistName = ((this.state.currentUser.is_jury && !this.state.currentUser.is_judge) ||
(this.state.currentUser.is_judge && !this.state.piece.selected )) ?
: this.state.piece.artist_name;
+ // Only show the artist email if you are a judge and the piece is shortlisted
let artistEmail = (this.state.currentUser.is_judge && this.state.piece.selected ) ?
: null;
return (
@@ -277,32 +279,36 @@ let PrizePieceRatings = React.createClass({
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
},
+ onSelectChange() {
+ PrizeRatingActions.toggleShortlist(this.props.piece.id)
+ .then(
+ (res) => {
+ this.refreshPieceData();
+ return res;
+ })
+ .then(
+ (res) => {
+ this.handleShortlistSuccess(res.notification);
+ }
+ );
+ },
+
render(){
if (this.props.piece && this.props.currentUser && this.props.currentUser.is_judge && this.state.average) {
+ // Judge sees shortlisting, average and per-jury notes
return (
{
- PrizeRatingActions.toggleShortlist(this.props.piece.id)
- .then(
- (res) => {
- this.refreshPieceData();
- return res;
- })
- .then(
- (res) => {
- this.handleShortlistSuccess(res.notification);
- }
- ); }}>
+ onChange={this.onSelectChange}>
- Select for the prize
+ {getLangText('Select for the prize')}
@@ -313,7 +319,7 @@ let PrizePieceRatings = React.createClass({
@@ -356,6 +362,7 @@ let PrizePieceRatings = React.createClass({
);
}
else if (this.props.currentUser && this.props.currentUser.is_jury) {
+ // Jury can set rating and note
return (
Date: Thu, 27 Aug 2015 10:18:50 +0200
Subject: [PATCH 148/397] review comments
---
.../prize/components/ascribe_detail/prize_piece_container.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js b/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js
index 6daef7ea..b1a85ef8 100644
--- a/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js
+++ b/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js
@@ -365,7 +365,7 @@ let PrizePieceRatings = React.createClass({
// Jury can set rating and note
return (
+ );
+ }
+ return null;
+ }
+});
+
+export default ListRequestActions;
\ No newline at end of file
diff --git a/js/components/ascribe_table/table_item_acl_filtered.js b/js/components/ascribe_table/table_item_acl_filtered.js
index 9a684e36..c850ab59 100644
--- a/js/components/ascribe_table/table_item_acl_filtered.js
+++ b/js/components/ascribe_table/table_item_acl_filtered.js
@@ -11,10 +11,10 @@ let TableItemAclFiltered = React.createClass({
render() {
var availableAcls = ['acl_consign', 'acl_loan', 'acl_transfer', 'acl_view', 'acl_share', 'acl_unshare', 'acl_delete'];
- if (this.props.requestAction){
+ if (this.props.requestAction && this.props.requestAction.length > 0){
return (
- {this.props.requestAction + ' request pending'}
+ {this.props.requestAction[0].action + ' request pending'}
);
}
diff --git a/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js b/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js
index b1a85ef8..4b785fc2 100644
--- a/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js
+++ b/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js
@@ -29,7 +29,7 @@ import CollapsibleParagraph from '../../../../../components/ascribe_collapsible/
import InputCheckbox from '../../../../ascribe_forms/input_checkbox';
import LoanForm from '../../../../ascribe_forms/form_loan';
-import RequestActionForm from '../../../../ascribe_forms/form_request_action';
+import ListRequestActions from '../../../../ascribe_forms/list_form_request_actions';
import ModalWrapper from '../../../../ascribe_modal/modal_wrapper';
import GlobalNotificationModel from '../../../../../models/global_notification_model';
@@ -89,21 +89,6 @@ let PieceContainer = React.createClass({
this.setState(this.state);
},
- getActions(){
- if (this.state.piece &&
- this.state.piece.request_action &&
- this.state.piece.request_action.length > 0) {
- return (
- );
- }
- return null;
- },
-
render() {
if('title' in this.state.piece) {
// Only show the artist name if you are the participant or if you are a judge and the piece is shortlisted
@@ -112,7 +97,7 @@ let PieceContainer = React.createClass({
: this.state.piece.artist_name;
// Only show the artist email if you are a judge and the piece is shortlisted
let artistEmail = (this.state.currentUser.is_judge && this.state.piece.selected ) ?
- : null;
+ : null;
return (
{this.state.piece.title}
-
-
+
+
{artistEmail}
- {this.getActions()}
+
}
@@ -237,6 +226,11 @@ let PrizePieceRatings = React.createClass({
);
},
+ handleLoanRequestSuccess(message){
+ let notification = new GlobalNotificationModel(message, 'success', 4000);
+ GlobalNotificationActions.appendGlobalNotification(notification);
+ },
+
getLoanButton(){
let today = new Moment();
let endDate = new Moment();
@@ -245,15 +239,15 @@ let PrizePieceRatings = React.createClass({
- SEND LOAN REQUEST
+ {getLangText('SEND LOAN REQUEST')}
}
handleSuccess={this.handleLoanRequestSuccess}
title='REQUEST LOAN'>
);
},
- handleLoanRequestSuccess(){},
-
handleShortlistSuccess(message){
let notification = new GlobalNotificationModel(message, 'success', 2000);
GlobalNotificationActions.appendGlobalNotification(notification);
diff --git a/sass/ascribe_accordion_list.scss b/sass/ascribe_accordion_list.scss
index b040e877..1ef4bef9 100644
--- a/sass/ascribe_accordion_list.scss
+++ b/sass/ascribe_accordion_list.scss
@@ -152,11 +152,11 @@ span.ascribe-accordion-list-table-toggle {
}
}
-.request-action-batch {
+.request-action-badge {
position: absolute;
top: 0px;
right: 0px;
- color: #666;
+ color: $ascribe-color-green;
font-size: 1.2em;
padding: 0.3em;
}
diff --git a/sass/whitelabel/prize/rating.scss b/sass/whitelabel/prize/rating.scss
index 8ea7c8ba..dfbff05b 100644
--- a/sass/whitelabel/prize/rating.scss
+++ b/sass/whitelabel/prize/rating.scss
@@ -29,6 +29,6 @@
.rating-note {
color: #666;
font-style: italic;
- padding: 0.2em;
+ padding: 0.7em;
}
\ No newline at end of file
From 9d7a9bd028a10669533848244b4b7b33c37e8bf9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Thu, 27 Aug 2015 14:34:15 +0200
Subject: [PATCH 151/397] add router/navigation integration into whole project
---
js/components/ascribe_app.js | 7 +++---
js/components/header.js | 7 ------
js/components/nav_routes_links.js | 7 ++++--
js/components/routes.js | 25 -------------------
js/components/whitelabel/prize/prize_app.js | 8 +++++-
.../whitelabel/prize/prize_routes.js | 4 +--
.../whitelabel/wallet/wallet_routes.js | 14 +++++------
js/routes.js | 17 +++++++++----
8 files changed, 37 insertions(+), 52 deletions(-)
delete mode 100644 js/components/routes.js
diff --git a/js/components/ascribe_app.js b/js/components/ascribe_app.js
index b4a894a3..789399b0 100644
--- a/js/components/ascribe_app.js
+++ b/js/components/ascribe_app.js
@@ -6,15 +6,16 @@ import Header from '../components/header';
import Footer from '../components/footer';
import GlobalNotification from './global_notification';
-// let Link = Router.Link;
-let RouteHandler = Router.RouteHandler;
+import getRoutes from '../routes';
+let RouteHandler = Router.RouteHandler;
+
let AscribeApp = React.createClass({
render() {
return (
-
+
diff --git a/js/components/header.js b/js/components/header.js
index 6c2dfac8..4cd8e4b0 100644
--- a/js/components/header.js
+++ b/js/components/header.js
@@ -93,8 +93,6 @@ let Header = React.createClass({
render() {
let account = null;
let signup = null;
- let collection = null;
- let addNewWork = null;
if (this.state.currentUser.username){
account = (
@@ -103,9 +101,6 @@ let Header = React.createClass({
{getLangText('Log out')}
);
-
- collection = {getLangText('COLLECTION')};
- addNewWork = this.props.showAddWork ? + {getLangText('NEW WORK')} : null;
}
else {
account = {getLangText('LOGIN')};
@@ -126,8 +121,6 @@ let Header = React.createClass({
diff --git a/js/components/nav_routes_links.js b/js/components/nav_routes_links.js
index 0e03e0fe..9a266ba8 100644
--- a/js/components/nav_routes_links.js
+++ b/js/components/nav_routes_links.js
@@ -16,6 +16,9 @@ let NavRoutesLinks = React.createClass({
},
extractLinksFromRoutes(node, i) {
+ if(!node) {
+ return;
+ }
node = node.props;
@@ -35,11 +38,11 @@ let NavRoutesLinks = React.createClass({
// if the node's child is actually a node of level one (a child of a node), we're
// returning a DropdownButton matching MenuItemLink
return (
- {child.props.headerTitle}
+ {child.props.headerTitle}
);
} else if(i === 0) {
return (
- {child.props.headerTitle}
+ {child.props.headerTitle}
);
} else {
return null;
diff --git a/js/components/routes.js b/js/components/routes.js
deleted file mode 100644
index 8b230a5a..00000000
--- a/js/components/routes.js
+++ /dev/null
@@ -1,25 +0,0 @@
-'use strict';
-
-import React from 'react';
-import Router from 'react-router';
-
-import App from './ascribe_app';
-import AppConstants from '../constants/application_constants';
-
-let Route = Router.Route;
-let Redirect = Router.Redirect;
-let baseUrl = AppConstants.baseUrl;
-
-
-function getRoutes(commonRoutes) {
- return (
-
-
-
- {commonRoutes}
-
- );
-}
-
-
-export default getRoutes;
diff --git a/js/components/whitelabel/prize/prize_app.js b/js/components/whitelabel/prize/prize_app.js
index dec859fc..29763ab3 100644
--- a/js/components/whitelabel/prize/prize_app.js
+++ b/js/components/whitelabel/prize/prize_app.js
@@ -7,6 +7,8 @@ import Header from '../../header';
import Footer from '../../footer';
import GlobalNotification from '../../global_notification';
+import getRoutes from './prize_routes';
+
let RouteHandler = Router.RouteHandler;
let PrizeApp = React.createClass({
@@ -14,10 +16,14 @@ let PrizeApp = React.createClass({
render() {
let header = null;
+ let subdomain = window.location.host.split('.')[0];
+
+ let ROUTES = getRoutes(null, subdomain);
+
if (this.isActive('landing') || this.isActive('login') || this.isActive('signup')) {
header = ;
} else {
- header = ;
+ header = ;
}
return (
diff --git a/js/components/whitelabel/prize/prize_routes.js b/js/components/whitelabel/prize/prize_routes.js
index 1384d26b..a389cb83 100644
--- a/js/components/whitelabel/prize/prize_routes.js
+++ b/js/components/whitelabel/prize/prize_routes.js
@@ -29,8 +29,8 @@ function getRoutes() {
-
-
+
+
diff --git a/js/components/whitelabel/wallet/wallet_routes.js b/js/components/whitelabel/wallet/wallet_routes.js
index 941c5a9c..a315bf3d 100644
--- a/js/components/whitelabel/wallet/wallet_routes.js
+++ b/js/components/whitelabel/wallet/wallet_routes.js
@@ -41,8 +41,8 @@ let ROUTES = {
-
-
+
+
@@ -56,8 +56,8 @@ let ROUTES = {
-
-
+
+
@@ -70,9 +70,9 @@ let ROUTES = {
-
-
-
+
+
+
diff --git a/js/routes.js b/js/routes.js
index 65dfbaac..f76e4b45 100644
--- a/js/routes.js
+++ b/js/routes.js
@@ -5,7 +5,8 @@ import Router from 'react-router';
import getPrizeRoutes from './components/whitelabel/prize/prize_routes';
import getWalletRoutes from './components/whitelabel/wallet/wallet_routes';
-import getDefaultRoutes from './components/routes';
+
+import App from './components/ascribe_app';
import PieceList from './components/piece_list';
import PieceContainer from './components/ascribe_detail/piece_container';
@@ -23,19 +24,25 @@ import RegisterPiece from './components/register_piece';
import PrizesDashboard from './components/ascribe_prizes_dashboard/prizes_dashboard';
+import AppConstants from './constants/application_constants';
+
let Route = Router.Route;
+let Redirect = Router.Redirect;
+let baseUrl = AppConstants.baseUrl;
const COMMON_ROUTES = (
-
+
+
+
-
+
+
-
@@ -51,7 +58,7 @@ function getRoutes(type, subdomain) {
} else if(type === 'wallet') {
routes = getWalletRoutes(COMMON_ROUTES, subdomain);
} else {
- routes = getDefaultRoutes(COMMON_ROUTES);
+ routes = COMMON_ROUTES;
}
return routes;
From 64d23f82dffae7fdd92f2028c00810ba68f6cd7b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Thu, 27 Aug 2015 14:47:33 +0200
Subject: [PATCH 152/397] refactoring of the general architecture
---
.../components/ikonotv/ikonotv_landing.js | 13 +++
.../ikonotv/ikonotv_register_piece.js | 80 -------------------
.../whitelabel/wallet/wallet_routes.js | 7 +-
3 files changed, 17 insertions(+), 83 deletions(-)
create mode 100644 js/components/whitelabel/wallet/components/ikonotv/ikonotv_landing.js
delete mode 100644 js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_landing.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_landing.js
new file mode 100644
index 00000000..9893da0d
--- /dev/null
+++ b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_landing.js
@@ -0,0 +1,13 @@
+'use strict';
+
+import React from 'react';
+
+let IkonotvLanding = React.createClass({
+ render() {
+ return (
+ This is a landing page placeholder
+ );
+ }
+});
+
+export default IkonotvLanding;
\ No newline at end of file
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js
deleted file mode 100644
index 814b0f01..00000000
--- a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js
+++ /dev/null
@@ -1,80 +0,0 @@
-'use strict';
-
-import React from 'react';
-import Router from 'react-router';
-
-import WhitelabelActions from '../../../../../actions/whitelabel_actions';
-import WhitelabelStore from '../../../../../stores/whitelabel_store';
-
-import PieceListStore from '../../../../../stores/piece_list_store';
-import PieceListActions from '../../../../../actions/piece_list_actions';
-
-import UserStore from '../../../../../stores/user_store';
-import UserActions from '../../../../../actions/user_actions';
-
-import PieceStore from '../../../../../stores/piece_store';
-import PieceActions from '../../../../../actions/piece_actions';
-
-import ContractForm from './ascribe_forms/ikonotv_contract_form';
-import RegisterPieceForm from '../../../../../components/ascribe_forms/form_register_piece';
-import Property from '../../../../../components/ascribe_forms/property';
-import InputCheckbox from '../../../../../components/ascribe_forms/input_checkbox';
-
-import GlobalNotificationModel from '../../../../../models/global_notification_model';
-import GlobalNotificationActions from '../../../../../actions/global_notification_actions';
-
-import { getLangText } from '../../../../../utils/lang_utils';
-import { mergeOptions } from '../../../../../utils/general_utils';
-
-
-let IkonotvRegisterPiece = React.createClass({
-
- mixins: [Router.Navigation],
-
- getInitialState(){
- return mergeOptions(
- UserStore.getState(),
- WhitelabelStore.getState());
- },
-
- componentDidMount() {
- UserStore.listen(this.onChange);
- WhitelabelStore.listen(this.onChange);
- UserActions.fetchCurrentUser();
- WhitelabelActions.fetchWhitelabel();
- },
-
- componentWillUnmount() {
- UserStore.unlisten(this.onChange);
- WhitelabelStore.unlisten(this.onChange);
- },
-
- onChange(state) {
- this.setState(state);
- },
-
-
- render() {
- /* if (this.state.currentUser &&
- this.state.whitelabel &&
- this.state.whitelabel.user &&
- this.state.currentUser.email === this.state.whitelabel.user){
- return (
-
- );
- } */
- return (
-
-
-
- );
-
- }
-});
-
-
-export default IkonotvRegisterPiece;
diff --git a/js/components/whitelabel/wallet/wallet_routes.js b/js/components/whitelabel/wallet/wallet_routes.js
index a315bf3d..133d66ac 100644
--- a/js/components/whitelabel/wallet/wallet_routes.js
+++ b/js/components/whitelabel/wallet/wallet_routes.js
@@ -12,13 +12,14 @@ import PieceList from '../../../components/piece_list';
import PieceContainer from '../../../components/ascribe_detail/piece_container';
import EditionContainer from '../../../components/ascribe_detail/edition_container';
import SettingsContainer from '../../../components/settings_container';
+import RegisterPiece from '../../../components/register_piece';
-// specific components
import CylandLanding from './components/cyland/cyland_landing';
import CylandPieceContainer from './components/cyland/ascribe_detail/cyland_piece_container';
import CylandRegisterPiece from './components/cyland/cyland_register_piece';
import CylandPieceList from './components/cyland/cyland_piece_list';
+import IkonotvLanding from './components/ikonotv/ikonotv_landing';
import IkonotvPieceList from './components/ikonotv/ikonotv_piece_list';
import IkonotvRegisterPiece from './components/ikonotv/ikonotv_register_piece';
import IkonotvRequestLoan from './components/ikonotv/ikonotv_request_loan';
@@ -65,13 +66,13 @@ let ROUTES = {
),
'ikonotv': (
-
+
-
+
From 65148e24de68c91e1fe817d4d6fca0ebaa1c341a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Thu, 27 Aug 2015 14:56:49 +0200
Subject: [PATCH 153/397] remove contract form from ikonotv codebase and
integrate it into ascribe-core
---
.../contract_form.js} | 18 +++++++++---------
.../components/ikonotv/ikonotv_request_loan.js | 2 +-
.../whitelabel/wallet/wallet_routes.js | 1 -
3 files changed, 10 insertions(+), 11 deletions(-)
rename js/components/{whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_contract_form.js => ascribe_forms/contract_form.js} (86%)
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_contract_form.js b/js/components/ascribe_forms/contract_form.js
similarity index 86%
rename from js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_contract_form.js
rename to js/components/ascribe_forms/contract_form.js
index 2d56ac6f..91f1d487 100644
--- a/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_contract_form.js
+++ b/js/components/ascribe_forms/contract_form.js
@@ -2,20 +2,20 @@
import React from 'react';
-import Property from '../../../../../ascribe_forms/property';
+import Property from './property';
-import LoanContractListActions from '../../../../../../actions/loan_contract_list_actions';
-import LoanContractListStore from '../../../../../../stores/loan_contract_list_store';
+import LoanContractListActions from '../../actions/loan_contract_list_actions';
+import LoanContractListStore from '../../stores/loan_contract_list_store';
-import GlobalNotificationModel from '../../../../../../models/global_notification_model';
-import GlobalNotificationActions from '../../../../../../actions/global_notification_actions';
+import GlobalNotificationModel from '../../models/global_notification_model';
+import GlobalNotificationActions from '../../actions/global_notification_actions';
-import Form from '../../../../../ascribe_forms/form';
+import Form from './form';
-import ApiUrls from '../../../../../../constants/api_urls';
+import ApiUrls from '../../constants/api_urls';
-import { getLangText } from '../../../../../../utils/lang_utils';
-import { mergeOptions } from '../../../../../../utils/general_utils';
+import { getLangText } from '../../utils/lang_utils';
+import { mergeOptions } from '../../utils/general_utils';
let ContractForm = React.createClass({
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_request_loan.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_request_loan.js
index 78f8b3b4..e9c61f51 100644
--- a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_request_loan.js
+++ b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_request_loan.js
@@ -2,7 +2,7 @@
import React from 'react';
-import ContractForm from './ascribe_forms/ikonotv_contract_form';
+import ContractForm from '../../../../../components/ascribe_forms/contract_form';
let IkonotvRequestLoan = React.createClass({
diff --git a/js/components/whitelabel/wallet/wallet_routes.js b/js/components/whitelabel/wallet/wallet_routes.js
index 133d66ac..d5937710 100644
--- a/js/components/whitelabel/wallet/wallet_routes.js
+++ b/js/components/whitelabel/wallet/wallet_routes.js
@@ -21,7 +21,6 @@ import CylandPieceList from './components/cyland/cyland_piece_list';
import IkonotvLanding from './components/ikonotv/ikonotv_landing';
import IkonotvPieceList from './components/ikonotv/ikonotv_piece_list';
-import IkonotvRegisterPiece from './components/ikonotv/ikonotv_register_piece';
import IkonotvRequestLoan from './components/ikonotv/ikonotv_request_loan';
import CCRegisterPiece from './components/cc/cc_register_piece';
From 86efb66663404e335f27ff94da1df19154e5ce3d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Thu, 27 Aug 2015 17:33:51 +0200
Subject: [PATCH 154/397] add collapsible appendix to send contract form
---
js/components/ascribe_forms/contract_form.js | 24 ++++++++++---------
.../whitelabel/wallet/wallet_routes.js | 2 +-
2 files changed, 14 insertions(+), 12 deletions(-)
diff --git a/js/components/ascribe_forms/contract_form.js b/js/components/ascribe_forms/contract_form.js
index 91f1d487..5b811cf6 100644
--- a/js/components/ascribe_forms/contract_form.js
+++ b/js/components/ascribe_forms/contract_form.js
@@ -2,8 +2,6 @@
import React from 'react';
-import Property from './property';
-
import LoanContractListActions from '../../actions/loan_contract_list_actions';
import LoanContractListStore from '../../stores/loan_contract_list_store';
@@ -11,6 +9,9 @@ import GlobalNotificationModel from '../../models/global_notification_model';
import GlobalNotificationActions from '../../actions/global_notification_actions';
import Form from './form';
+import Property from './property';
+import PropertyCollapsible from './property_collapsible';
+import InputTextAreaToggable from './input_textarea_toggable';
import ApiUrls from '../../constants/api_urls';
@@ -96,7 +97,7 @@ let ContractForm = React.createClass({
buttons={
- {getLangText('SEND LOAN REQUEST')}
+ {getLangText('Send loan request')}
}
spinner={
@@ -104,7 +105,7 @@ let ContractForm = React.createClass({
}>
-
{getLangText('CONTRACT FORM')}
+
{getLangText('Contract form')}
{this.getContracts()}
-
-
-
+ checkboxLabel={getLangText('Add appendix to the contract')}>
+ {getLangText('Appendix')}
+
+
);
}
diff --git a/js/components/whitelabel/wallet/wallet_routes.js b/js/components/whitelabel/wallet/wallet_routes.js
index d5937710..6836ec66 100644
--- a/js/components/whitelabel/wallet/wallet_routes.js
+++ b/js/components/whitelabel/wallet/wallet_routes.js
@@ -70,7 +70,7 @@ let ROUTES = {
-
+
From 8e5c04140f1a09be10196c946ccebde6deaa59d7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Thu, 27 Aug 2015 18:11:47 +0200
Subject: [PATCH 155/397] add vendor prefixes for slide container
---
.../ascribe_slides_container/slides_container.js | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/js/components/ascribe_slides_container/slides_container.js b/js/components/ascribe_slides_container/slides_container.js
index 4ac4d57a..8b098ef6 100644
--- a/js/components/ascribe_slides_container/slides_container.js
+++ b/js/components/ascribe_slides_container/slides_container.js
@@ -241,6 +241,16 @@ let SlidesContainer = React.createClass({
},
render() {
+
+ let translateXValue = 'translateX(' + (-1) * this.state.containerWidth * this.state.slideNum + 'px)';
+
+ /*
+ According to the react documentation,
+ all browser vendor prefixes need to be upper cases in the beginning except for
+ the Microsoft one *bigfuckingsurprise*
+ https://facebook.github.io/react/tips/inline-styles.html
+ */
+
return (
{this.renderChildren()}
From 9a9aa68ca9ecd4774aa19a0f92026bfc28a75b9a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Fri, 28 Aug 2015 11:13:28 +0200
Subject: [PATCH 156/397] fix lazy evalutaion of loan form
---
js/components/ascribe_forms/form_loan.js | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/js/components/ascribe_forms/form_loan.js b/js/components/ascribe_forms/form_loan.js
index f9b866a3..276ff492 100644
--- a/js/components/ascribe_forms/form_loan.js
+++ b/js/components/ascribe_forms/form_loan.js
@@ -68,8 +68,12 @@ let LoanForm = React.createClass({
return this.props.id;
},
- handleOnBlur(event) {
- LoanContractActions.fetchLoanContract(event.target.value);
+ handleOnChange(event) {
+ let potentialEmail = event.target.value;
+
+ if(potentialEmail.match(/.*@.*/)) {
+ LoanContractActions.fetchLoanContract(potentialEmail);
+ }
},
getContractCheckbox() {
@@ -151,7 +155,7 @@ let LoanForm = React.createClass({
Date: Fri, 28 Aug 2015 12:11:29 +0200
Subject: [PATCH 157/397] add: Loan form for Ikonotv
---
.../ikonotv_accordion_list_item.js | 17 ++++----
.../ascribe_buttons/ikonotv_submit_button.js | 41 +++++++++++++++++--
.../wallet/constants/wallet_api_urls.js | 4 +-
.../whitelabel/wallet/wallet_routes.js | 5 ++-
4 files changed, 50 insertions(+), 17 deletions(-)
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_accordion_list/ikonotv_accordion_list_item.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_accordion_list/ikonotv_accordion_list_item.js
index 2be45ce3..ecab34fb 100644
--- a/js/components/whitelabel/wallet/components/ikonotv/ascribe_accordion_list/ikonotv_accordion_list_item.js
+++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_accordion_list/ikonotv_accordion_list_item.js
@@ -14,8 +14,11 @@ import GlobalNotificationModel from '../../../../../../models/global_notificatio
import GlobalNotificationActions from '../../../../../../actions/global_notification_actions';
import IkonotvSubmitButton from '../ascribe_buttons/ikonotv_submit_button';
+
import AclProxy from '../../../../../acl_proxy';
+import AclButton from '../../../../../ascribe_buttons/acl_button';
+
import { getLangText } from '../../../../../../utils/lang_utils';
import { mergeOptions } from '../../../../../../utils/general_utils';
@@ -61,16 +64,10 @@ let IkonotvAccordionListItem = React.createClass({
getSubmitButtons() {
return (
-
-
-
-
-
+
);
},
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_buttons/ikonotv_submit_button.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_buttons/ikonotv_submit_button.js
index d3f4c0e3..ae5ba094 100644
--- a/js/components/whitelabel/wallet/components/ikonotv/ascribe_buttons/ikonotv_submit_button.js
+++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_buttons/ikonotv_submit_button.js
@@ -1,10 +1,18 @@
'use strict';
import React from 'react';
+import Moment from 'moment';
import classNames from 'classnames';
import ModalWrapper from '../../../../../ascribe_modal/modal_wrapper';
+import LoanForm from '../../../../../ascribe_forms/form_loan';
+
+import Property from '../../../../../ascribe_forms/property';
+import InputCheckbox from '../../../../../ascribe_forms/input_checkbox';
+
+import ApiUrls from '../../../../../../constants/api_urls';
+
import { getLangText } from '../../../../../../utils/lang_utils';
let IkonotvSubmitButton = React.createClass({
@@ -24,16 +32,43 @@ let IkonotvSubmitButton = React.createClass({
},
render() {
+
+ let today = new Moment();
+ let enddate = new Moment();
+ enddate.add(1, 'years');
+
return (
-
+ title={getLangText('Loan to IkonoTV archive')}>
+
+
+
+
+ {' ' + getLangText('I agree to the Terms of Service of IkonoTV Archive') + ' '}
+ (
+ {getLangText('read')}
+ )
+
+
+
+
);
}
});
-export default IkonotvSubmitButton;
\ No newline at end of file
+export default IkonotvSubmitButton;
diff --git a/js/components/whitelabel/wallet/constants/wallet_api_urls.js b/js/components/whitelabel/wallet/constants/wallet_api_urls.js
index c1b101a1..22d4017e 100644
--- a/js/components/whitelabel/wallet/constants/wallet_api_urls.js
+++ b/js/components/whitelabel/wallet/constants/wallet_api_urls.js
@@ -13,8 +13,8 @@ function getWalletApiUrls(subdomain) {
}
else if (subdomain === 'ikonotv'){
return {
- 'pieces_list': walletConstants.walletApiEndpoint + subdomain + '/pieces/',
- 'piece': walletConstants.walletApiEndpoint + subdomain + '/pieces/${piece_id}/'
+ 'pieces_list': walletConstants.walletApiEndpoint + 'cyland' + '/pieces/',
+ 'piece': walletConstants.walletApiEndpoint + 'cyland' + '/pieces/${piece_id}/'
};
}
return {};
diff --git a/js/components/whitelabel/wallet/wallet_routes.js b/js/components/whitelabel/wallet/wallet_routes.js
index 6836ec66..9532299c 100644
--- a/js/components/whitelabel/wallet/wallet_routes.js
+++ b/js/components/whitelabel/wallet/wallet_routes.js
@@ -65,12 +65,13 @@ let ROUTES = {
),
'ikonotv': (
-
+
+
-
+
From 2c26aab8cc262803353d89d6da71d7280c63d206 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Fri, 28 Aug 2015 12:20:36 +0200
Subject: [PATCH 158/397] add exception for loaning a piece for ikonotv
---
js/components/ascribe_detail/piece_container.js | 5 ++++-
js/components/whitelabel/wallet/constants/wallet_api_urls.js | 4 ++--
js/components/whitelabel/wallet/wallet_routes.js | 2 +-
3 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/js/components/ascribe_detail/piece_container.js b/js/components/ascribe_detail/piece_container.js
index 3739a508..2c6da4a9 100644
--- a/js/components/ascribe_detail/piece_container.js
+++ b/js/components/ascribe_detail/piece_container.js
@@ -84,8 +84,11 @@ let PieceContainer = React.createClass({
IT SHOULD BE REMOVED AND REPLACED WITH A BETTER SOLUTION ASAP!
+ ALSO, WE ENABLED THE LOAN BUTTON FOR IKONOTV TO LET THEM LOAN ON A PIECE LEVEL
+
*/
- if(state && state.piece && state.piece.acl && typeof state.piece.acl.acl_loan !== 'undefined') {
+ let subdomain = window.location.host.split('.')[0];
+ if(subdomain !== 'ikonotv' && state && state.piece && state.piece.acl && typeof state.piece.acl.acl_loan !== 'undefined') {
let pieceState = mergeOptions({}, state.piece);
pieceState.acl.acl_loan = false;
diff --git a/js/components/whitelabel/wallet/constants/wallet_api_urls.js b/js/components/whitelabel/wallet/constants/wallet_api_urls.js
index 22d4017e..c1b101a1 100644
--- a/js/components/whitelabel/wallet/constants/wallet_api_urls.js
+++ b/js/components/whitelabel/wallet/constants/wallet_api_urls.js
@@ -13,8 +13,8 @@ function getWalletApiUrls(subdomain) {
}
else if (subdomain === 'ikonotv'){
return {
- 'pieces_list': walletConstants.walletApiEndpoint + 'cyland' + '/pieces/',
- 'piece': walletConstants.walletApiEndpoint + 'cyland' + '/pieces/${piece_id}/'
+ 'pieces_list': walletConstants.walletApiEndpoint + subdomain + '/pieces/',
+ 'piece': walletConstants.walletApiEndpoint + subdomain + '/pieces/${piece_id}/'
};
}
return {};
diff --git a/js/components/whitelabel/wallet/wallet_routes.js b/js/components/whitelabel/wallet/wallet_routes.js
index 9532299c..ec5b9787 100644
--- a/js/components/whitelabel/wallet/wallet_routes.js
+++ b/js/components/whitelabel/wallet/wallet_routes.js
@@ -74,7 +74,7 @@ let ROUTES = {
-
+
From e9d0311f589a5f96ecdf492419870af130fa31ab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Fri, 28 Aug 2015 12:33:00 +0200
Subject: [PATCH 159/397] custom ikonotv piece page
---
.../ascribe_detail/piece_container.js | 1 +
.../ikonotv_accordion_list_item.js | 2 +-
.../ascribe_buttons/ikonotv_submit_button.js | 2 +-
.../ascribe_detail/ikonotv_piece_container.js | 165 ++++++++++++++++++
.../whitelabel/wallet/wallet_routes.js | 4 +-
5 files changed, 170 insertions(+), 4 deletions(-)
create mode 100644 js/components/whitelabel/wallet/components/ikonotv/ascribe_detail/ikonotv_piece_container.js
diff --git a/js/components/ascribe_detail/piece_container.js b/js/components/ascribe_detail/piece_container.js
index 2c6da4a9..62fc9b11 100644
--- a/js/components/ascribe_detail/piece_container.js
+++ b/js/components/ascribe_detail/piece_container.js
@@ -205,6 +205,7 @@ let PieceContainer = React.createClass({
);
}
},
+
render() {
if('title' in this.state.piece) {
return (
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_accordion_list/ikonotv_accordion_list_item.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_accordion_list/ikonotv_accordion_list_item.js
index ecab34fb..8a4ed893 100644
--- a/js/components/whitelabel/wallet/components/ikonotv/ascribe_accordion_list/ikonotv_accordion_list_item.js
+++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_accordion_list/ikonotv_accordion_list_item.js
@@ -65,7 +65,7 @@ let IkonotvAccordionListItem = React.createClass({
getSubmitButtons() {
return (
);
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_buttons/ikonotv_submit_button.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_buttons/ikonotv_submit_button.js
index ae5ba094..a73871dd 100644
--- a/js/components/whitelabel/wallet/components/ikonotv/ascribe_buttons/ikonotv_submit_button.js
+++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_buttons/ikonotv_submit_button.js
@@ -25,7 +25,7 @@ let IkonotvSubmitButton = React.createClass({
getSubmitButton() {
return (
+ className={classNames('btn', 'btn-default', this.props.className)}>
{getLangText('Loan to IkonoTV')}
);
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_detail/ikonotv_piece_container.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_detail/ikonotv_piece_container.js
new file mode 100644
index 00000000..d88f42a5
--- /dev/null
+++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_detail/ikonotv_piece_container.js
@@ -0,0 +1,165 @@
+'use strict';
+
+import React from 'react';
+
+import PieceActions from '../../../../../../actions/piece_actions';
+import PieceStore from '../../../../../../stores/piece_store';
+import PieceListActions from '../../../../../../actions/piece_list_actions';
+import UserStore from '../../../../../../stores/user_store';
+
+import Piece from '../../../../../../components/ascribe_detail/piece';
+
+import ListRequestActions from '../../../../../ascribe_forms/list_form_request_actions';
+import AclButtonList from '../../../../../ascribe_buttons/acl_button_list';
+import DeleteButton from '../../../../../ascribe_buttons/delete_button';
+
+import CollapsibleParagraph from '../../../../../../components/ascribe_collapsible/collapsible_paragraph';
+
+import IkonotvSubmitButton from '../ascribe_buttons/ikonotv_submit_button';
+
+import HistoryIterator from '../../../../../ascribe_detail/history_iterator';
+
+import DetailProperty from '../../../../../ascribe_detail/detail_property';
+
+
+import GlobalNotificationModel from '../../../../../../models/global_notification_model';
+import GlobalNotificationActions from '../../../../../../actions/global_notification_actions';
+
+
+import AppConstants from '../../../../../../constants/application_constants';
+
+import { getLangText } from '../../../../../../utils/lang_utils';
+import { mergeOptions } from '../../../../../../utils/general_utils';
+
+
+let IkonotvPieceContainer = React.createClass({
+ getInitialState() {
+ return mergeOptions(
+ PieceStore.getState(),
+ UserStore.getState()
+ );
+ },
+
+ componentDidMount() {
+ PieceStore.listen(this.onChange);
+ PieceActions.fetchOne(this.props.params.pieceId);
+ UserStore.listen(this.onChange);
+ },
+
+ componentWillReceiveProps(nextProps) {
+ if(this.props.params.pieceId !== nextProps.params.pieceId) {
+ PieceActions.updatePiece({});
+ PieceActions.fetchOne(nextProps.params.pieceId);
+ }
+ },
+
+ componentWillUnmount() {
+ // Every time we're leaving the piece detail page,
+ // just reset the piece that is saved in the piece store
+ // as it will otherwise display wrong/old data once the user loads
+ // the piece detail a second time
+ PieceActions.updatePiece({});
+ PieceStore.unlisten(this.onChange);
+ UserStore.unlisten(this.onChange);
+ },
+
+ onChange(state) {
+ this.setState(state);
+ },
+
+ loadPiece() {
+ PieceActions.fetchOne(this.props.params.pieceId);
+ },
+
+ handleSubmitSuccess(response) {
+ PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
+ this.state.orderBy, this.state.orderAsc, this.state.filterBy);
+
+ let notification = new GlobalNotificationModel(response.notification, 'success', 10000);
+ GlobalNotificationActions.appendGlobalNotification(notification);
+ },
+
+ getActions(){
+ if (this.state.piece &&
+ this.state.piece.request_action &&
+ this.state.piece.request_action.length > 0) {
+ return (
+
+ );
+ }
+ else {
+
+ // This is just because we're inserting a custom acl_loan button
+ let availableAcls;
+
+ if(this.state.piece && this.state.piece.acl && typeof this.state.piece.acl.acl_loan !== 'undefined') {
+ // make a copy to not have side effects
+ availableAcls = mergeOptions({}, this.state.piece.acl);
+ availableAcls.acl_loan = false;
+ }
+
+ return (
+
+
+
+
+ );
+ }
+ },
+
+ render() {
+ if('title' in this.state.piece) {
+ return (
+
+
+
);
} else {
diff --git a/js/components/ascribe_uploader/file_drag_and_drop_preview_progress.js b/js/components/ascribe_uploader/file_drag_and_drop_preview_progress.js
new file mode 100644
index 00000000..2d99104f
--- /dev/null
+++ b/js/components/ascribe_uploader/file_drag_and_drop_preview_progress.js
@@ -0,0 +1,38 @@
+'use strict';
+
+import React from 'react';
+
+let FileDragAndDropPreviewProgress = React.createClass({
+ propTypes: {
+ files: React.PropTypes.array
+ },
+
+ calcOverallProgress() {
+ let overallProgress = 0;
+ let sizeOfAllFiles = 0;
+ let files = this.props.files.filter((file) => file.status !== 'deleted' || file.status !== 'canceled');
+ console.log(this.props.files.filter);
+
+ for(let i = 0; i < files.length; i++) {
+ sizeOfAllFiles += files[i].size;
+ }
+
+ for(let i = 0; i < files.length; i++) {
+ overallProgress += files[i].size / sizeOfAllFiles * files[i].progress;
+ }
+
+
+ return overallProgress.toFixed(2);
+ },
+
+ render() {
+ return (
+
+ Overall progress: {this.calcOverallProgress()}%
+
+ );
+ }
+});
+
+export default FileDragAndDropPreviewProgress;
\ No newline at end of file
diff --git a/js/components/ascribe_uploader/react_s3_fine_uploader.js b/js/components/ascribe_uploader/react_s3_fine_uploader.js
index 8ecaf40b..31b1590a 100644
--- a/js/components/ascribe_uploader/react_s3_fine_uploader.js
+++ b/js/components/ascribe_uploader/react_s3_fine_uploader.js
@@ -461,7 +461,6 @@ var ReactS3FineUploader = React.createClass({
},
onProgress(id, name, uploadedBytes, totalBytes) {
-
let newState = React.addons.update(this.state, {
filesToUpload: { [id]: {
progress: { $set: (uploadedBytes / totalBytes) * 100} }
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_accordion_list/ikonotv_accordion_list_item.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_accordion_list/ikonotv_accordion_list_item.js
index c0a239cb..b716914a 100644
--- a/js/components/whitelabel/wallet/components/ikonotv/ascribe_accordion_list/ikonotv_accordion_list_item.js
+++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_accordion_list/ikonotv_accordion_list_item.js
@@ -1,7 +1,6 @@
'use strict';
import React from 'react';
-import Router from 'react-router';
import AccordionListItemPiece from '../../../../../ascribe_accordion_list/accordion_list_item_piece';
@@ -17,8 +16,6 @@ import IkonotvSubmitButton from '../ascribe_buttons/ikonotv_submit_button';
import AclProxy from '../../../../../acl_proxy';
-import AclButton from '../../../../../ascribe_buttons/acl_button';
-
import { getLangText } from '../../../../../../utils/lang_utils';
import { mergeOptions } from '../../../../../../utils/general_utils';
diff --git a/js/components/whitelabel/wallet/wallet_routes.js b/js/components/whitelabel/wallet/wallet_routes.js
index 40f092d6..62c1d255 100644
--- a/js/components/whitelabel/wallet/wallet_routes.js
+++ b/js/components/whitelabel/wallet/wallet_routes.js
@@ -71,7 +71,7 @@ let ROUTES = {
-
+
diff --git a/js/third_party/ga.js b/js/third_party/ga.js
index 52832623..f95450cb 100644
--- a/js/third_party/ga.js
+++ b/js/third_party/ga.js
@@ -3,7 +3,6 @@
import alt from '../alt';
import EventActions from '../actions/event_actions';
-
class GoogleAnalyticsHandler {
constructor() {
this.bindActions(EventActions);
diff --git a/sass/ascribe_uploader.scss b/sass/ascribe_uploader.scss
index 2aab021a..e3b5d1c1 100644
--- a/sass/ascribe_uploader.scss
+++ b/sass/ascribe_uploader.scss
@@ -29,6 +29,14 @@
}
}
+.file-drag-and-drop-preview-iterator {
+ text-align: right;
+
+ > div:first-child {
+ text-align: center;
+ }
+}
+
.file-drag-and-drop .file-drag-and-drop-dialog > p:first-child {
font-size: 1.5em !important;
From bb6deb3f688530c6862030d18bba5a5a96f1123c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Fri, 4 Sep 2015 15:13:38 +0200
Subject: [PATCH 215/397] refactor setStatus method of fineuploader
---
.../react_s3_fine_uploader.js | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/js/components/ascribe_uploader/react_s3_fine_uploader.js b/js/components/ascribe_uploader/react_s3_fine_uploader.js
index 31b1590a..9736c0bd 100644
--- a/js/components/ascribe_uploader/react_s3_fine_uploader.js
+++ b/js/components/ascribe_uploader/react_s3_fine_uploader.js
@@ -439,7 +439,6 @@ var ReactS3FineUploader = React.createClass({
},
onCancel(id) {
-
// when a upload is canceled, we need to update this components file array
this.setStatusOfFile(id, 'canceled');
@@ -766,22 +765,18 @@ var ReactS3FineUploader = React.createClass({
},
setStatusOfFile(fileId, status) {
- // also, sync files from state with the ones from fineuploader
- let filesToUpload = JSON.parse(JSON.stringify(this.state.filesToUpload));
+ let changeSet = {};
- filesToUpload[fileId].status = status;
-
- // is status is set to deleted or canceled, we also need to reset the progress
- // back to zero
if(status === 'deleted' || status === 'canceled') {
- filesToUpload[fileId].progress = 0;
+ changeSet.progress = { $set: 0 };
}
- // set state
- let newState = React.addons.update(this.state, {
- filesToUpload: { $set: filesToUpload }
- });
+ changeSet.status = { $set: status };
+ let newState = React.addons.update(this.state, {
+ filesToUpload: { [fileId]: changeSet}
+ });
+
this.setState(newState);
},
From bf6b5e00a63a412df085bb296ec775608376eb99 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Fri, 4 Sep 2015 16:39:57 +0200
Subject: [PATCH 216/397] update fineuploader
---
.../vendor/s3.fine-uploader.js | 195 ++++++++++++------
.../vendor/s3.fine-uploader.min.js | 16 +-
2 files changed, 135 insertions(+), 76 deletions(-)
diff --git a/js/components/ascribe_uploader/vendor/s3.fine-uploader.js b/js/components/ascribe_uploader/vendor/s3.fine-uploader.js
index e0f096df..5b90cf5a 100644
--- a/js/components/ascribe_uploader/vendor/s3.fine-uploader.js
+++ b/js/components/ascribe_uploader/vendor/s3.fine-uploader.js
@@ -3,7 +3,7 @@
*
* Copyright 2015, Widen Enterprises, Inc. info@fineuploader.com
*
-* Version: 5.2.2
+* Version: 5.3.0
*
* Homepage: http://fineuploader.com
*
@@ -894,7 +894,7 @@ var qq = function(element) {
}());
/*global qq */
-qq.version = "5.2.2";
+qq.version = "5.3.0";
/* globals qq */
qq.supportedFeatures = (function() {
@@ -1928,6 +1928,10 @@ qq.status = {
this._endpointStore.set(endpoint, id);
},
+ setForm: function(elementOrId) {
+ this._updateFormSupportAndParams(elementOrId);
+ },
+
setItemLimit: function(newItemLimit) {
this._currentItemLimit = newItemLimit;
},
@@ -1945,16 +1949,11 @@ qq.status = {
},
uploadStoredFiles: function() {
- var idToUpload;
-
if (this._storedIds.length === 0) {
this._itemError("noFilesError");
}
else {
- while (this._storedIds.length) {
- idToUpload = this._storedIds.shift();
- this._uploadFile(idToUpload);
- }
+ this._uploadStoredFiles();
}
}
};
@@ -2038,10 +2037,11 @@ qq.status = {
});
},
- _createStore: function(initialValue, readOnlyValues) {
+ _createStore: function(initialValue, _readOnlyValues_) {
var store = {},
catchall = initialValue,
perIdReadOnlyValues = {},
+ readOnlyValues = _readOnlyValues_,
copy = function(orig) {
if (qq.isObject(orig)) {
return qq.extend({}, orig);
@@ -2095,8 +2095,20 @@ qq.status = {
addReadOnly: function(id, values) {
// Only applicable to Object stores
if (qq.isObject(store)) {
- perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};
- qq.extend(perIdReadOnlyValues[id], values);
+ // If null ID, apply readonly values to all files
+ if (id === null) {
+ if (qq.isFunction(values)) {
+ readOnlyValues = values;
+ }
+ else {
+ readOnlyValues = readOnlyValues || {};
+ qq.extend(readOnlyValues, values);
+ }
+ }
+ else {
+ perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {};
+ qq.extend(perIdReadOnlyValues[id], values);
+ }
}
},
@@ -2882,7 +2894,7 @@ qq.status = {
_onBeforeManualRetry: function(id) {
var itemLimit = this._currentItemLimit,
fileName;
- console.log(this._handler.isValid(id));
+
if (this._preventRetries[id]) {
this.log("Retries are forbidden for id " + id, "warn");
return false;
@@ -3005,13 +3017,14 @@ qq.status = {
this._onSubmit.apply(this, arguments);
this._uploadData.setStatus(id, qq.status.SUBMITTED);
this._onSubmitted.apply(this, arguments);
- this._options.callbacks.onSubmitted.apply(this, arguments);
if (this._options.autoUpload) {
+ this._options.callbacks.onSubmitted.apply(this, arguments);
this._uploadFile(id);
}
else {
this._storeForLater(id);
+ this._options.callbacks.onSubmitted.apply(this, arguments);
}
},
@@ -3238,6 +3251,23 @@ qq.status = {
}
},
+ _updateFormSupportAndParams: function(formElementOrId) {
+ this._options.form.element = formElementOrId;
+
+ this._formSupport = qq.FormSupport && new qq.FormSupport(
+ this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this)
+ );
+
+ if (this._formSupport && this._formSupport.attachedToForm) {
+ this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject);
+
+ this._options.autoUpload = this._formSupport.newAutoUpload;
+ if (this._formSupport.newEndpoint) {
+ this.setEndpoint(this._formSupport.newEndpoint);
+ }
+ }
+ },
+
_upload: function(id, params, endpoint) {
var name = this.getName(id);
@@ -3264,6 +3294,25 @@ qq.status = {
}
},
+ _uploadStoredFiles: function() {
+ var idToUpload, stillSubmitting,
+ self = this;
+
+ while (this._storedIds.length) {
+ idToUpload = this._storedIds.shift();
+ this._uploadFile(idToUpload);
+ }
+
+ // If we are still waiting for some files to clear validation, attempt to upload these again in a bit
+ stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length;
+ if (stillSubmitting) {
+ qq.log("Still waiting for " + stillSubmitting + " files to clear submit queue. Will re-parse stored IDs array shortly.");
+ setTimeout(function() {
+ self._uploadStoredFiles();
+ }, 1000);
+ }
+ },
+
/**
* Performs some internal validation checks on an item, defined in the `validation` option.
*
@@ -5271,6 +5320,7 @@ qq.XhrUploadHandler = function(spec) {
*/
getResumableFilesData: function() {
var resumableFilesData = [];
+
handler._iterateResumeRecords(function(key, uploadData) {
handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining);
@@ -5461,7 +5511,7 @@ qq.XhrUploadHandler = function(spec) {
_iterateResumeRecords: function(callback) {
if (resumeEnabled) {
qq.each(localStorage, function(key, item) {
- if (key.indexOf(qq.format("qq{}resume-", namespace)) === 0) {
+ if (key.indexOf(qq.format("qq{}resume", namespace)) === 0) {
var uploadData = JSON.parse(item);
callback(key, uploadData);
}
@@ -5728,7 +5778,9 @@ qq.WindowReceiveMessage = function(o) {
},
getItemByFileId: function(id) {
- return this._templating.getFileContainer(id);
+ if (!this._templating.isHiddenForever(id)) {
+ return this._templating.getFileContainer(id);
+ }
},
reset: function() {
@@ -6238,11 +6290,6 @@ qq.WindowReceiveMessage = function(o) {
dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled,
record;
- // If we don't want this file to appear in the UI, skip all of this UI-related logic.
- if (dontDisplay) {
- return;
- }
-
if (this._options.display.prependFiles) {
if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) {
prependIndex = this._filesInBatchAddedToUi - 1;
@@ -6274,7 +6321,7 @@ qq.WindowReceiveMessage = function(o) {
}
}
- this._templating.addFile(id, this._options.formatFileName(name), prependData);
+ this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay);
if (canned) {
this._thumbnailUrls[id] && this._templating.updateThumbnail(id, this._thumbnailUrls[id], true);
@@ -6638,6 +6685,7 @@ qq.Templating = function(spec) {
HIDE_DROPZONE_ATTR = "qq-hide-dropzone",
DROPZPONE_TEXT_ATTR = "qq-drop-area-text",
IN_PROGRESS_CLASS = "qq-in-progress",
+ HIDDEN_FOREVER_CLASS = "qq-hidden-forever",
isCancelDisabled = false,
generatedThumbnails = 0,
thumbnailQueueMonitorRunning = false,
@@ -7273,7 +7321,7 @@ qq.Templating = function(spec) {
isCancelDisabled = true;
},
- addFile: function(id, name, prependInfo) {
+ addFile: function(id, name, prependInfo, hideForever) {
var fileEl = qq.toElement(templateHtml.fileTemplate),
fileNameEl = getTemplateEl(fileEl, selectorClasses.file),
uploaderEl = getTemplateEl(container, selectorClasses.uploader),
@@ -7296,30 +7344,36 @@ qq.Templating = function(spec) {
fileList.appendChild(fileEl);
}
- hide(getProgress(id));
- hide(getSize(id));
- hide(getDelete(id));
- hide(getRetry(id));
- hide(getPause(id));
- hide(getContinue(id));
-
- if (isCancelDisabled) {
- this.hideCancel(id);
+ if (hideForever) {
+ fileEl.style.display = "none";
+ qq(fileEl).addClass(HIDDEN_FOREVER_CLASS);
}
+ else {
+ hide(getProgress(id));
+ hide(getSize(id));
+ hide(getDelete(id));
+ hide(getRetry(id));
+ hide(getPause(id));
+ hide(getContinue(id));
- thumb = getThumbnail(id);
- if (thumb && !thumb.src) {
- cachedWaitingForThumbnailImg.then(function(waitingImg) {
- thumb.src = waitingImg.src;
- if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {
- qq(thumb).css({
- maxHeight: waitingImg.style.maxHeight,
- maxWidth: waitingImg.style.maxWidth
- });
- }
+ if (isCancelDisabled) {
+ this.hideCancel(id);
+ }
- show(thumb);
- });
+ thumb = getThumbnail(id);
+ if (thumb && !thumb.src) {
+ cachedWaitingForThumbnailImg.then(function(waitingImg) {
+ thumb.src = waitingImg.src;
+ if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) {
+ qq(thumb).css({
+ maxHeight: waitingImg.style.maxHeight,
+ maxWidth: waitingImg.style.maxWidth
+ });
+ }
+
+ show(thumb);
+ });
+ }
}
},
@@ -7413,6 +7467,10 @@ qq.Templating = function(spec) {
icon && qq(icon).addClass(options.classes.editable);
},
+ isHiddenForever: function(id) {
+ return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS);
+ },
+
hideEditIcon: function(id) {
var icon = getEditIcon(id);
@@ -7572,13 +7630,17 @@ qq.Templating = function(spec) {
},
generatePreview: function(id, optFileOrBlob) {
- thumbGenerationQueue.push({id: id, optFileOrBlob: optFileOrBlob});
- !thumbnailQueueMonitorRunning && generateNextQueuedPreview();
+ if (!this.isHiddenForever(id)) {
+ thumbGenerationQueue.push({id: id, optFileOrBlob: optFileOrBlob});
+ !thumbnailQueueMonitorRunning && generateNextQueuedPreview();
+ }
},
updateThumbnail: function(id, thumbnailUrl, showWaitingImg) {
- thumbGenerationQueue.push({update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});
- !thumbnailQueueMonitorRunning && generateNextQueuedPreview();
+ if (!this.isHiddenForever(id)) {
+ thumbGenerationQueue.push({update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg});
+ !thumbnailQueueMonitorRunning && generateNextQueuedPreview();
+ }
},
hasDialog: function(type) {
@@ -9489,12 +9551,6 @@ qq.s3.XhrUploadHandler = function(spec, proxy) {
result.success,
function failure(reason, xhr) {
- console.logGlobal(reason + 'in chunked.combine', false, {
- uploadId,
- etagMap,
- result
- });
-
result.failure(upload.done(id, xhr).response, xhr);
}
);
@@ -12335,7 +12391,7 @@ qq.Scaler = function(spec, log) {
"use strict";
var self = this,
- includeReference = spec.sendOriginal,
+ includeOriginal = spec.sendOriginal,
orient = spec.orient,
defaultType = spec.defaultType,
defaultQuality = spec.defaultQuality / 100,
@@ -12385,16 +12441,18 @@ qq.Scaler = function(spec, log) {
});
});
- includeReference && records.push({
+ records.push({
uuid: originalFileUuid,
name: originalFileName,
- blob: originalBlob
+ size: originalBlob.size,
+ blob: includeOriginal ? originalBlob : null
});
}
else {
records.push({
uuid: originalFileUuid,
name: originalFileName,
+ size: originalBlob.size,
blob: originalBlob
});
}
@@ -12413,19 +12471,17 @@ qq.Scaler = function(spec, log) {
proxyGroupId = qq.getUniqueId();
qq.each(self.getFileRecords(uuid, name, file), function(idx, record) {
- var relatedBlob = file,
- relatedSize = size,
+ var blobSize = record.size,
id;
if (record.blob instanceof qq.BlobProxy) {
- relatedBlob = record.blob;
- relatedSize = -1;
+ blobSize = -1;
}
id = uploadData.addFile({
uuid: record.uuid,
name: record.name,
- size: relatedSize,
+ size: blobSize,
batchId: batchId,
proxyGroupId: proxyGroupId
});
@@ -12437,10 +12493,13 @@ qq.Scaler = function(spec, log) {
originalId = id;
}
- addFileToHandler(id, relatedBlob);
-
- fileList.push({id: id, file: relatedBlob});
-
+ if (record.blob) {
+ addFileToHandler(id, record.blob);
+ fileList.push({id: id, file: record.blob});
+ }
+ else {
+ uploadData.setStatus(id, qq.status.REJECTED);
+ }
});
// If we are potentially uploading an original file and some scaled versions,
@@ -12453,8 +12512,8 @@ qq.Scaler = function(spec, log) {
qqparentsize: uploadData.retrieve({id: originalId}).size
};
- // Make SURE the UUID for each scaled image is sent with the upload request,
- // to be consistent (since we need to ensure it is sent for the original file as well).
+ // Make sure the UUID for each scaled image is sent with the upload request,
+ // to be consistent (since we may need to ensure it is sent for the original file as well).
params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid;
uploadData.setParentId(scaledId, originalId);
@@ -14411,4 +14470,4 @@ code.google.com/p/crypto-js/wiki/License
C.HmacSHA1 = Hasher._createHmacHelper(SHA1);
}());
-/*! 2015-06-09 */
+/*! 2015-08-26 */
diff --git a/js/components/ascribe_uploader/vendor/s3.fine-uploader.min.js b/js/components/ascribe_uploader/vendor/s3.fine-uploader.min.js
index ef244d9e..620fcafc 100644
--- a/js/components/ascribe_uploader/vendor/s3.fine-uploader.min.js
+++ b/js/components/ascribe_uploader/vendor/s3.fine-uploader.min.js
@@ -3,7 +3,7 @@
*
* Copyright 2015, Widen Enterprises, Inc. info@fineuploader.com
*
-* Version: 5.2.2
+* Version: 5.3.0
*
* Homepage: http://fineuploader.com
*
@@ -13,10 +13,10 @@
*/
-var qq=function(a){"use strict";return{hide:function(){return a.style.display="none",this},attach:function(b,c){return a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent&&a.attachEvent("on"+b,c),function(){qq(a).detach(b,c)}},detach:function(b,c){return a.removeEventListener?a.removeEventListener(b,c,!1):a.attachEvent&&a.detachEvent("on"+b,c),this},contains:function(b){return b?a===b?!0:a.contains?a.contains(b):!!(8&b.compareDocumentPosition(a)):!1},insertBefore:function(b){return b.parentNode.insertBefore(a,b),this},remove:function(){return a.parentNode.removeChild(a),this},css:function(b){if(null==a.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=b.opacity&&"string"!=typeof a.style.opacity&&"undefined"!=typeof a.filters&&(b.filter="alpha(opacity="+Math.round(100*b.opacity)+")"),qq.extend(a.style,b),this},hasClass:function(b,c){var d=new RegExp("(^| )"+b+"( |$)");return d.test(a.className)||!(!c||!d.test(a.parentNode.className))},addClass:function(b){return qq(a).hasClass(b)||(a.className+=" "+b),this},removeClass:function(b){var c=new RegExp("(^| )"+b+"( |$)");return a.className=a.className.replace(c," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(b){var c,d=[];return a.querySelectorAll?a.querySelectorAll("."+b):(c=a.getElementsByTagName("*"),qq.each(c,function(a,c){qq(c).hasClass(b)&&d.push(c)}),d)},children:function(){for(var b=[],c=a.firstChild;c;)1===c.nodeType&&b.push(c),c=c.nextSibling;return b},setText:function(b){return a.innerText=b,a.textContent=b,this},clearText:function(){return qq(a).setText("")},hasAttribute:function(b){var c;return a.hasAttribute?a.hasAttribute(b)?null==/^false$/i.exec(a.getAttribute(b)):!1:(c=a[b],void 0===c?!1:null==/^false$/i.exec(c))}}};!function(){"use strict";qq.canvasToBlob=function(a,b,c){return qq.dataUriToBlob(a.toDataURL(b,c))},qq.dataUriToBlob=function(a){var b,c,d,e,f=function(a,b){var c=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,d=c&&new c;return d?(d.append(a),d.getBlob(b)):new Blob([a],{type:b})};return c=a.split(",")[0].indexOf("base64")>=0?atob(a.split(",")[1]):decodeURI(a.split(",")[1]),e=a.split(",")[0].split(":")[1].split(";")[0],b=new ArrayBuffer(c.length),d=new Uint8Array(b),qq.each(c,function(a,b){d[a]=b.charCodeAt(0)}),f(b,e)},qq.log=function(a,b){window.console&&(b&&"info"!==b?window.console[b]?window.console[b](a):window.console.log("<"+b+"> "+a):window.console.log(a))},qq.isObject=function(a){return a&&!a.nodeType&&"[object Object]"===Object.prototype.toString.call(a)},qq.isFunction=function(a){return"function"==typeof a},qq.isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)||a&&window.ArrayBuffer&&a.buffer&&a.buffer.constructor===ArrayBuffer},qq.isItemList=function(a){return"[object DataTransferItemList]"===Object.prototype.toString.call(a)},qq.isNodeList=function(a){return"[object NodeList]"===Object.prototype.toString.call(a)||a.item&&a.namedItem},qq.isString=function(a){return"[object String]"===Object.prototype.toString.call(a)},qq.trimStr=function(a){return String.prototype.trim?a.trim():a.replace(/^\s+|\s+$/g,"")},qq.format=function(a){var b=Array.prototype.slice.call(arguments,1),c=a,d=c.indexOf("{}");return qq.each(b,function(a,b){var e=c.substring(0,d),f=c.substring(d+2);return c=e+b+f,d=c.indexOf("{}",d+b.length),0>d?!1:void 0}),c},qq.isFile=function(a){return window.File&&"[object File]"===Object.prototype.toString.call(a)},qq.isFileList=function(a){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(a)},qq.isFileOrInput=function(a){return qq.isFile(a)||qq.isInput(a)},qq.isInput=function(a,b){var c=function(a){var c=a.toLowerCase();return b?"file"!==c:"file"===c};return window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(a)&&a.type&&c(a.type)?!0:a.tagName&&"input"===a.tagName.toLowerCase()&&a.type&&c(a.type)?!0:!1},qq.isBlob=function(a){return window.Blob&&"[object Blob]"===Object.prototype.toString.call(a)?!0:void 0},qq.isXhrUploadSupported=function(){var a=document.createElement("input");return a.type="file",void 0!==a.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&"undefined"!=typeof qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(a){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(a){return a.items&&a.items.length>0&&a.items[0].webkitGetAsEntry},qq.isFileChunkingSupported=function(){return!qq.androidStock()&&qq.isXhrUploadSupported()&&(void 0!==File.prototype.slice||void 0!==File.prototype.webkitSlice||void 0!==File.prototype.mozSlice)},qq.sliceBlob=function(a,b,c){var d=a.slice||a.mozSlice||a.webkitSlice;return d.call(a,b,c)},qq.arrayBufferToHex=function(a){var b="",c=new Uint8Array(a);return qq.each(c,function(a,c){var d=c.toString(16);d.length<2&&(d="0"+d),b+=d}),b},qq.readBlobToHex=function(a,b,c){var d=qq.sliceBlob(a,b,b+c),e=new FileReader,f=new qq.Promise;return e.onload=function(){f.success(qq.arrayBufferToHex(e.result))},e.onerror=f.failure,e.readAsArrayBuffer(d),f},qq.extend=function(a,b,c){return qq.each(b,function(b,d){c&&qq.isObject(d)?(void 0===a[b]&&(a[b]={}),qq.extend(a[b],d,!0)):a[b]=d}),a},qq.override=function(a,b){var c={},d=b(c);return qq.each(d,function(b,d){void 0!==a[b]&&(c[b]=a[b]),a[b]=d}),a},qq.indexOf=function(a,b,c){if(a.indexOf)return a.indexOf(b,c);c=c||0;var d=a.length;for(0>c&&(c+=d);d>c;c+=1)if(a.hasOwnProperty(c)&&a[c]===b)return c;return-1},qq.getUniqueId=function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=0|16*Math.random(),c="x"==a?b:8|3&b;return c.toString(16)})},qq.ie=function(){return-1!==navigator.userAgent.indexOf("MSIE")||-1!==navigator.userAgent.indexOf("Trident")},qq.ie7=function(){return-1!==navigator.userAgent.indexOf("MSIE 7")},qq.ie8=function(){return-1!==navigator.userAgent.indexOf("MSIE 8")},qq.ie10=function(){return-1!==navigator.userAgent.indexOf("MSIE 10")},qq.ie11=function(){return qq.ie()&&-1!==navigator.userAgent.indexOf("rv:11")},qq.safari=function(){return void 0!==navigator.vendor&&-1!==navigator.vendor.indexOf("Apple")},qq.chrome=function(){return void 0!==navigator.vendor&&-1!==navigator.vendor.indexOf("Google")},qq.opera=function(){return void 0!==navigator.vendor&&-1!==navigator.vendor.indexOf("Opera")},qq.firefox=function(){return!qq.ie11()&&-1!==navigator.userAgent.indexOf("Mozilla")&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return-1!==navigator.userAgent.toLowerCase().indexOf("android")},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&-1!==navigator.userAgent.indexOf(" OS 6_")},qq.ios7=function(){return qq.ios()&&-1!==navigator.userAgent.indexOf(" OS 7_")},qq.ios8=function(){return qq.ios()&&-1!==navigator.userAgent.indexOf(" OS 8_")},qq.ios800=function(){return qq.ios()&&-1!==navigator.userAgent.indexOf(" OS 8_0 ")},qq.ios=function(){return-1!==navigator.userAgent.indexOf("iPad")||-1!==navigator.userAgent.indexOf("iPod")||-1!==navigator.userAgent.indexOf("iPhone")},qq.iosChrome=function(){return qq.ios()&&-1!==navigator.userAgent.indexOf("CriOS")},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&-1!==navigator.userAgent.indexOf("Safari")},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1},qq.toElement=function(){var a=document.createElement("div");return function(b){a.innerHTML=b;var c=a.firstChild;return a.removeChild(c),c}}(),qq.each=function(a,b){var c,d;if(a)if(window.Storage&&a.constructor===window.Storage)for(c=0;c0?a.substr(b,a.length-b):void 0},qq.getFilename=function(a){return qq.isInput(a)?a.value.replace(/.*(\/|\\)/,""):qq.isFile(a)&&null!==a.fileName&&void 0!==a.fileName?a.fileName:a.name},qq.DisposeSupport=function(){var a=[];return{dispose:function(){var b;do b=a.shift(),b&&b();while(b)},attach:function(){var a=arguments;this.addDisposer(qq(a[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(b){a.push(b)}}}}(),function(){"use strict";qq.Error=function(a){this.message="[Fine Uploader "+qq.version+"] "+a},qq.Error.prototype=new Error}(),qq.version="5.2.2",qq.supportedFeatures=function(){"use strict";function a(){var a,b=!0;try{a=document.createElement("input"),a.type="file",qq(a).hide(),a.disabled&&(b=!1)}catch(c){b=!1}return b}function b(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function c(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function d(){if(window.XMLHttpRequest){var a=qq.createXhrInstance();return void 0!==a.withCredentials}return!1}function e(){return void 0!==window.XDomainRequest}function f(){return d()?!0:e()}function g(){return void 0!==document.createElement("input").webkitdirectory}function h(){try{return!!window.localStorage}catch(a){return!1}}function i(){var a=document.createElement("span");return("draggable"in a||"ondragstart"in a&&"ondrop"in a)&&!qq.android()&&!qq.ios()}var j,k,l,m,n,o,p,q,r,s,t,u,v,w,x;return j=a(),m=j&&qq.isXhrUploadSupported(),k=m&&!qq.androidStock(),l=m&&i(),n=l&&b(),o=m&&qq.isFileChunkingSupported(),p=m&&o&&h(),q=m&&c(),r=j&&(void 0!==window.postMessage||m),t=d(),s=e(),u=f(),v=g(),w=m&&void 0!==window.FileReader,x=function(){return m?!qq.androidStock()&&!qq.iosChrome():!1}(),{ajaxUploading:m,blobUploading:k,canDetermineSize:m,chunking:o,deleteFileCors:u,deleteFileCorsXdr:s,deleteFileCorsXhr:t,dialogElement:!!window.HTMLDialogElement,fileDrop:l,folderDrop:n,folderSelection:v,imagePreviews:w,imageValidation:w,itemSizeValidation:m,pause:o,progressBar:x,resume:p,scaling:w&&k,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:j,uploadCors:r,uploadCustomHeaders:m,uploadNonMultipart:m,uploadViaPaste:q}}(),qq.isGenericPromise=function(a){"use strict";return!!(a&&a.then&&qq.isFunction(a.then))},qq.Promise=function(){"use strict";var a,b,c=[],d=[],e=[],f=0;qq.extend(this,{then:function(e,g){return 0===f?(e&&c.push(e),g&&d.push(g)):-1===f?g&&g.apply(null,b):e&&e.apply(null,a),this},done:function(c){return 0===f?e.push(c):c.apply(null,void 0===b?a:b),this},success:function(){return f=1,a=arguments,c.length&&qq.each(c,function(b,c){c.apply(null,a)}),e.length&&qq.each(e,function(b,c){c.apply(null,a)}),this},failure:function(){return f=-1,b=arguments,d.length&&qq.each(d,function(a,c){c.apply(null,b)}),e.length&&qq.each(e,function(a,c){c.apply(null,b)}),this}})},qq.BlobProxy=function(a,b){"use strict";qq.extend(this,{referenceBlob:a,create:function(){return b(a)}})},qq.UploadButton=function(a){"use strict";function b(){var a=document.createElement("input");return a.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,d),a.setAttribute("title","file input"),e.setMultiple(g.multiple,a),g.folders&&qq.supportedFeatures.folderSelection&&a.setAttribute("webkitdirectory",""),g.acceptFiles&&a.setAttribute("accept",g.acceptFiles),a.setAttribute("type","file"),a.setAttribute("name",g.name),qq(a).css({position:"absolute",right:0,top:0,fontFamily:"Arial",fontSize:qq.ie()&&!qq.ie8()?"3500px":"118px",margin:0,padding:0,cursor:"pointer",opacity:0}),!qq.ie7()&&qq(a).css({height:"100%"}),g.element.appendChild(a),f.attach(a,"change",function(){g.onChange(a)}),f.attach(a,"mouseover",function(){qq(g.element).addClass(g.hoverClass)}),f.attach(a,"mouseout",function(){qq(g.element).removeClass(g.hoverClass)}),f.attach(a,"focus",function(){qq(g.element).addClass(g.focusClass)}),f.attach(a,"blur",function(){qq(g.element).removeClass(g.focusClass)}),a}var c,d,e=this,f=new qq.DisposeSupport,g={element:null,multiple:!1,acceptFiles:null,folders:!1,name:"qqfile",onChange:function(){},ios8BrowserCrashWorkaround:!1,hoverClass:"qq-upload-button-hover",focusClass:"qq-upload-button-focus"};qq.extend(g,a),d=qq.getUniqueId(),qq(g.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return c},getButtonId:function(){return d},setMultiple:function(a,b){var c=b||this.getInput();g.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?c.setAttribute("multiple",""):a?c.setAttribute("multiple",""):c.removeAttribute("multiple")},setAcceptFiles:function(a){a!==g.acceptFiles&&c.setAttribute("accept",a)},reset:function(){c.parentNode&&qq(c).remove(),qq(g.element).removeClass(g.focusClass),c=null,c=b()}}),c=b()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(a){"use strict";function b(a){if(qq.isArray(a)){var b=[];return qq.each(a,function(a,c){b.push(e[c])}),b}return e[a]}function c(a){if(qq.isArray(a)){var b=[];return qq.each(a,function(a,c){b.push(e[f[c]])}),b}return e[f[a]]}function d(a){var b=[],c=[].concat(a);return qq.each(c,function(a,c){var d=g[c];void 0!==d&&qq.each(d,function(a,c){b.push(e[c])})}),b}var e=[],f={},g={},h={},i={};qq.extend(this,{addFile:function(b){var c=b.status||qq.status.SUBMITTING,d=e.push({name:b.name,originalName:b.name,uuid:b.uuid,size:null==b.size?-1:b.size,status:c})-1;return b.batchId&&(e[d].batchId=b.batchId,void 0===i[b.batchId]&&(i[b.batchId]=[]),i[b.batchId].push(d)),b.proxyGroupId&&(e[d].proxyGroupId=b.proxyGroupId,void 0===h[b.proxyGroupId]&&(h[b.proxyGroupId]=[]),h[b.proxyGroupId].push(d)),e[d].id=d,f[b.uuid]=d,void 0===g[c]&&(g[c]=[]),g[c].push(d),a.onStatusChange(d,null,c),d},retrieve:function(a){return qq.isObject(a)&&e.length?void 0!==a.id?b(a.id):void 0!==a.uuid?c(a.uuid):a.status?d(a.status):void 0:qq.extend([],e,!0)},reset:function(){e=[],f={},g={},i={}},setStatus:function(b,c){var d=e[b].status,f=qq.indexOf(g[d],b);g[d].splice(f,1),e[b].status=c,void 0===g[c]&&(g[c]=[]),g[c].push(b),a.onStatusChange(b,d,c)},uuidChanged:function(a,b){var c=e[a].uuid;e[a].uuid=b,f[b]=a,delete f[c]},updateName:function(a,b){e[a].name=b},updateSize:function(a,b){e[a].size=b},setParentId:function(a,b){e[a].parentId=b},getIdsInProxyGroup:function(a){var b=e[a].proxyGroupId;return b?h[b]:[]},getIdsInBatch:function(a){var b=e[a].batchId;return i[b]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_RETRYING:"retrying upload",UPLOAD_SUCCESSFUL:"upload successful",UPLOAD_FAILED:"upload failed",DELETE_FAILED:"delete failed",DELETING:"deleting",DELETED:"deleted"},function(){"use strict";qq.basePublicApi={addBlobs:function(a,b,c){this.addFiles(a,b,c)},addFiles:function(a,b,c){this._maybeHandleIos8SafariWorkaround();var d=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,e=qq.bind(function(a){this._handleNewFile({blob:a,name:this._options.blobs.defaultName},d,l)},this),f=qq.bind(function(a){this._handleNewFile(a,d,l)},this),g=qq.bind(function(a){var b=qq.canvasToBlob(a);this._handleNewFile({blob:b,name:this._options.blobs.defaultName+".png"},d,l)},this),h=qq.bind(function(a){var b=a.quality&&a.quality/100,c=qq.canvasToBlob(a.canvas,a.type,b);this._handleNewFile({blob:c,name:a.name},d,l)},this),i=qq.bind(function(a){if(qq.isInput(a)&&qq.supportedFeatures.ajaxUploading){var b=Array.prototype.slice.call(a.files),c=this;qq.each(b,function(a,b){c._handleNewFile(b,d,l)})}else this._handleNewFile(a,d,l)},this),j=function(){qq.isFileList(a)&&(a=Array.prototype.slice.call(a)),a=[].concat(a)},k=this,l=[];this._currentBatchId=d,a&&(j(),qq.each(a,function(a,b){qq.isFileOrInput(b)?i(b):qq.isBlob(b)?e(b):qq.isObject(b)?b.blob&&b.name?f(b):b.canvas&&b.name&&h(b):b.tagName&&"canvas"===b.tagName.toLowerCase()?g(b):k.log(b+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+l.length+" files."),this._prepareItemsForUpload(l,b,c))},cancel:function(a){this._handler.cancel(a)},cancelAll:function(){var a=[],b=this;qq.extend(a,this._storedIds),qq.each(a,function(a,c){b.cancel(c)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(a){var b=this._uploadData.retrieve({id:a});return qq.supportedFeatures.pause&&this._options.chunking.enabled?b.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",a,this.getName(a))),this._uploadFile(a),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",a,this.getName(a)),"error"),!1):!1},deleteFile:function(a){return this._onSubmitDelete(a)},doesExist:function(a){return this._handler.isValid(a)},drawThumbnail:function(a,b,c,d){var e,f,g=new qq.Promise;return this._imageGenerator?(e=this._thumbnailUrls[a],f={scale:c>0,maxSize:c>0?c:null},!d&&qq.supportedFeatures.imagePreviews&&(e=this.getFile(a)),null==e?g.failure({container:b,error:"File or URL not found."}):this._imageGenerator.generate(e,b,f).then(function(a){g.success(a)},function(a,b){g.failure({container:a,error:b||"Problem generating thumbnail"})})):g.failure({container:b,error:"Missing image generator module"}),g},getButton:function(a){return this._getButton(this._buttonIdsForFileIds[a])},getEndpoint:function(a){return this._endpointStore.get(a)},getFile:function(a){return this._handler.getFile(a)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(a){return this._uploadData.retrieve({id:a}).name},getParentId:function(a){var b=this.getUploads({id:a}),c=null;return b&&void 0!==b.parentId&&(c=b.parentId),c},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(a){return this._uploadData.retrieve({id:a}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var a=this._currentItemLimit;return a>0?a-this._netUploadedOrQueued:null},getUploads:function(a){return this._uploadData.retrieve(a)},getUuid:function(a){return this._uploadData.retrieve({id:a}).uuid},log:function(a,b){!this._options.debug||b&&"info"!==b?b&&"info"!==b&&qq.log("[Fine Uploader "+qq.version+"] "+a,b):qq.log("[Fine Uploader "+qq.version+"] "+a)},pauseUpload:function(a){var b=this._uploadData.retrieve({id:a});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],b.status)>=0){if(this._handler.pause(a))return this._uploadData.setStatus(a,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",a,this.getName(a)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",a,this.getName(a)),"error");return!1},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(a,b){b.reset()}),this._paramsStore.reset(),this._endpointStore.reset(),this._netUploadedOrQueued=0,this._netUploaded=0,this._uploadData.reset(),this._buttonIdsForFileIds=[],this._pasteHandler&&this._pasteHandler.reset(),this._options.session.refreshOnReset&&this._refreshSessionData(),this._succeededSinceLastAllComplete=[],this._failedSinceLastAllComplete=[],this._totalProgress&&this._totalProgress.reset()},retry:function(a){return this._manualRetry(a)},scaleImage:function(a,b){var c=this;return qq.Scaler.prototype.scaleImage(a,b,{log:qq.bind(c.log,c),getFile:qq.bind(c.getFile,c),uploadData:c._uploadData})},setCustomHeaders:function(a,b){this._customHeadersStore.set(a,b)},setDeleteFileCustomHeaders:function(a,b){this._deleteFileCustomHeadersStore.set(a,b)},setDeleteFileEndpoint:function(a,b){this._deleteFileEndpointStore.set(a,b)},setDeleteFileParams:function(a,b){this._deleteFileParamsStore.set(a,b)},setEndpoint:function(a,b){this._endpointStore.set(a,b)},setItemLimit:function(a){this._currentItemLimit=a},setName:function(a,b){this._uploadData.updateName(a,b)},setParams:function(a,b){this._paramsStore.set(a,b)},setUuid:function(a,b){return this._uploadData.uuidChanged(a,b)},uploadStoredFiles:function(){var a;if(0===this._storedIds.length)this._itemError("noFilesError");else for(;this._storedIds.length;)a=this._storedIds.shift(),this._uploadFile(a)}},qq.basePrivateApi={_addCannedFile:function(a){var b=this._uploadData.addFile({uuid:a.uuid,name:a.name,size:a.size,status:qq.status.UPLOAD_SUCCESSFUL});return a.deleteFileEndpoint&&this.setDeleteFileEndpoint(a.deleteFileEndpoint,b),a.deleteFileParams&&this.setDeleteFileParams(a.deleteFileParams,b),a.thumbnailUrl&&(this._thumbnailUrls[b]=a.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,b},_annotateWithButtonId:function(a,b){qq.isFile(a)&&(a.qqButtonId=this._getButtonId(b))},_batchError:function(a){this._options.callbacks.onError(null,null,a,void 0)},_createDeleteHandler:function(){var a=this;return new qq.DeleteFileAjaxRequester({method:this._options.deleteFile.method.toUpperCase(),maxConnections:this._options.maxConnections,uuidParamName:this._options.request.uuidName,customHeaders:this._deleteFileCustomHeadersStore,paramsStore:this._deleteFileParamsStore,endpointStore:this._deleteFileEndpointStore,cors:this._options.cors,log:qq.bind(a.log,a),onDelete:function(b){a._onDelete(b),a._options.callbacks.onDelete(b)},onDeleteComplete:function(b,c,d){a._onDeleteComplete(b,c,d),a._options.callbacks.onDeleteComplete(b,c,d)}})},_createPasteHandler:function(){var a=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(a.log,a),pasteReceived:function(b){a._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(a._options.callbacks.onPasteReceived,a,b),onSuccess:qq.bind(a._handlePasteSuccess,a,b),identifier:"pasted image"})}}})},_createStore:function(a,b){var c={},d=a,e={},f=function(a){return qq.isObject(a)?qq.extend({},a):a},g=function(){return qq.isFunction(b)?b():b},h=function(a,c){b&&qq.isObject(c)&&qq.extend(c,g()),e[a]&&qq.extend(c,e[a])};return{set:function(a,b){null==b?(c={},d=f(a)):c[b]=f(a)},get:function(a){var b;return b=null!=a&&c[a]?c[a]:f(d),h(a,b),f(b)},addReadOnly:function(a,b){qq.isObject(c)&&(e[a]=e[a]||{},qq.extend(e[a],b))},remove:function(a){return delete c[a]},reset:function(){c={},e={},d=a}}},_createUploadDataTracker:function(){var a=this;return new qq.UploadData({getName:function(b){return a.getName(b)},getUuid:function(b){return a.getUuid(b)},getSize:function(b){return a.getSize(b)},onStatusChange:function(b,c,d){a._onUploadStatusChange(b,c,d),a._options.callbacks.onStatusChange(b,c,d),a._maybeAllComplete(b,d),a._totalProgress&&setTimeout(function(){a._totalProgress.onStatusChange(b,c,d)},0)}})},_createUploadButton:function(a){function b(){return qq.supportedFeatures.ajaxUploading?d._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&d._isAllowedExtension(f,".mov")?!1:void 0===a.multiple?d._options.multiple:a.multiple:!1}var c,d=this,e=a.accept||this._options.validation.acceptFiles,f=a.allowedExtensions||this._options.validation.allowedExtensions;return c=new qq.UploadButton({element:a.element,folders:a.folders,name:this._options.request.inputName,multiple:b(),acceptFiles:e,onChange:function(a){d._onInputChange(a)},hoverClass:this._options.classes.buttonHover,focusClass:this._options.classes.buttonFocus,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash}),this._disposeSupport.addDisposer(function(){c.dispose()}),d._buttons.push(c),c},_createUploadHandler:function(a,b){var c=this,d={},e={debug:this._options.debug,maxConnections:this._options.maxConnections,cors:this._options.cors,paramsStore:this._paramsStore,endpointStore:this._endpointStore,chunking:this._options.chunking,resume:this._options.resume,blobs:this._options.blobs,log:qq.bind(c.log,c),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(a,b,e,f){0>e||0>f||(d[a]?(d[a].loaded!==e||d[a].total!==f)&&(c._onProgress(a,b,e,f),c._options.callbacks.onProgress(a,b,e,f)):(c._onProgress(a,b,e,f),c._options.callbacks.onProgress(a,b,e,f)),d[a]={loaded:e,total:f})},onComplete:function(a,b,e,f){delete d[a];var g,h=c.getUploads({id:a}).status;h!==qq.status.UPLOAD_SUCCESSFUL&&h!==qq.status.UPLOAD_FAILED&&(g=c._onComplete(a,b,e,f),g instanceof qq.Promise?g.done(function(){c._options.callbacks.onComplete(a,b,e,f)}):c._options.callbacks.onComplete(a,b,e,f))},onCancel:function(a,b,d){var e=new qq.Promise;return c._handleCheckedCallback({name:"onCancel",callback:qq.bind(c._options.callbacks.onCancel,c,a,b),onFailure:e.failure,onSuccess:function(){d.then(function(){c._onCancel(a,b)}),e.success()},identifier:a}),e},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(a,b){c._onUpload(a,b),c._options.callbacks.onUpload(a,b)},onUploadChunk:function(a,b,d){c._onUploadChunk(a,d),c._options.callbacks.onUploadChunk(a,b,d)},onUploadChunkSuccess:function(){c._options.callbacks.onUploadChunkSuccess.apply(c,arguments)},onResume:function(a,b,d){return c._options.callbacks.onResume(a,b,d)},onAutoRetry:function(){return c._onAutoRetry.apply(c,arguments)},onUuidChanged:function(a,b){c.log("Server requested UUID change from '"+c.getUuid(a)+"' to '"+b+"'"),c.setUuid(a,b)},getName:qq.bind(c.getName,c),getUuid:qq.bind(c.getUuid,c),getSize:qq.bind(c.getSize,c),setSize:qq.bind(c._setSize,c),getDataByUuid:function(a){return c.getUploads({uuid:a})},isQueued:function(a){var b=c.getUploads({id:a}).status;return b===qq.status.QUEUED||b===qq.status.SUBMITTED||b===qq.status.UPLOAD_RETRYING||b===qq.status.PAUSED},getIdsInProxyGroup:c._uploadData.getIdsInProxyGroup,getIdsInBatch:c._uploadData.getIdsInBatch};return qq.each(this._options.request,function(a,b){e[a]=b}),e.customHeaders=this._customHeadersStore,a&&qq.each(a,function(a,b){e[a]=b}),new qq.UploadHandlerController(e,b)},_fileOrBlobRejected:function(a){this._netUploadedOrQueued--,this._uploadData.setStatus(a,qq.status.REJECTED)},_formatSize:function(a){var b=-1;do a/=1e3,b++;while(a>999);return Math.max(a,.1).toFixed(1)+this._options.text.sizeSymbols[b]},_generateExtraButtonSpecs:function(){var a=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(b,c){var d=c.multiple,e=qq.extend({},a._options.validation,!0),f=qq.extend({},c);void 0===d&&(d=a._options.multiple),f.validation&&qq.extend(e,c.validation,!0),qq.extend(f,{multiple:d,validation:e},!0),a._initExtraButton(f)})},_getButton:function(a){var b=this._extraButtonSpecs[a];return b?b.element:a===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(a){var b,c,d=a;if(d instanceof qq.BlobProxy&&(d=d.referenceBlob),d&&!qq.isBlob(d)){if(qq.isFile(d))return d.qqButtonId;if("input"===d.tagName.toLowerCase()&&"file"===d.type.toLowerCase())return d.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(b=d.getElementsByTagName("input"),qq.each(b,function(a,b){return"file"===b.getAttribute("type")?(c=b,!1):void 0}),c)return c.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getNotFinished:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED,qq.status.SUBMITTING,qq.status.SUBMITTED,qq.status.PAUSED]}).length},_getValidationBase:function(a){var b=this._extraButtonSpecs[a];return b?b.validation:this._options.validation},_getValidationDescriptor:function(a){return a.file instanceof qq.BlobProxy?{name:qq.getFilename(a.file.referenceBlob),size:a.file.referenceBlob.size}:{name:this.getUploads({id:a.id}).name,size:this.getUploads({id:a.id}).size}},_getValidationDescriptors:function(a){var b=this,c=[];return qq.each(a,function(a,d){c.push(b._getValidationDescriptor(d))}),c},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var a="image/*;capture=camera",b=this._options.camera.button,c=b?this._getButtonId(b):this._defaultButtonId,d=this._options;c&&c!==this._defaultButtonId&&(d=this._extraButtonSpecs[c]),d.multiple=!1,null===d.validation.acceptFiles?d.validation.acceptFiles=a:d.validation.acceptFiles+=","+a,qq.each(this._buttons,function(a,b){return b.getButtonId()===c?(b.setMultiple(d.multiple),b.setAcceptFiles(d.acceptFiles),!1):void 0})}},_handleCheckedCallback:function(a){var b=this,c=a.callback();return qq.isGenericPromise(c)?(this.log(a.name+" - waiting for "+a.name+" promise to be fulfilled for "+a.identifier),c.then(function(c){b.log(a.name+" promise success for "+a.identifier),a.onSuccess(c)},function(){a.onFailure?(b.log(a.name+" promise failure for "+a.identifier),a.onFailure()):b.log(a.name+" promise failure for "+a.identifier)})):(c!==!1?a.onSuccess(c):a.onFailure?(this.log(a.name+" - return value was 'false' for "+a.identifier+". Invoking failure callback."),a.onFailure()):this.log(a.name+" - return value was 'false' for "+a.identifier+". Will not proceed."),c)},_handleNewFile:function(a,b,c){var d=this,e=qq.getUniqueId(),f=-1,g=qq.getFilename(a),h=a.blob||a,i=this._customNewFileHandler?this._customNewFileHandler:qq.bind(d._handleNewFileGeneric,d);!qq.isInput(h)&&h.size>=0&&(f=h.size),i(h,g,e,f,c,b,this._options.request.uuidName,{uploadData:d._uploadData,paramsStore:d._paramsStore,addFileToHandler:function(a,b){d._handler.add(a,b),d._netUploadedOrQueued++,d._trackButton(a)}})},_handleNewFileGeneric:function(a,b,c,d,e,f){var g=this._uploadData.addFile({uuid:c,name:b,size:d,batchId:f});this._handler.add(g,a),this._trackButton(g),this._netUploadedOrQueued++,e.push({id:g,file:a})},_handlePasteSuccess:function(a,b){var c=a.type.split("/")[1],d=b;null==d&&(d=this._options.paste.defaultName),d+="."+c,this.addFiles({name:d,blob:a})},_initExtraButton:function(a){var b=this._createUploadButton({element:a.element,multiple:a.multiple,accept:a.validation.acceptFiles,folders:a.folders,allowedExtensions:a.validation.allowedExtensions});this._extraButtonSpecs[b.getButtonId()]=a},_initFormSupportAndParams:function(){this._formSupport=qq.FormSupport&&new qq.FormSupport(this._options.form,qq.bind(this.uploadStoredFiles,this),qq.bind(this.log,this)),this._formSupport&&this._formSupport.attachedToForm?(this._paramsStore=this._createStore(this._options.request.params,this._formSupport.getFormInputsAsObject),this._options.autoUpload=this._formSupport.newAutoUpload,this._formSupport.newEndpoint&&(this._options.request.endpoint=this._formSupport.newEndpoint)):this._paramsStore=this._createStore(this._options.request.params)
-},_isDeletePossible:function(){return qq.DeleteFileAjaxRequester&&this._options.deleteFile.enabled?this._options.cors.expected?qq.supportedFeatures.deleteFileCorsXhr?!0:qq.supportedFeatures.deleteFileCorsXdr&&this._options.cors.allowXdr?!0:!1:!0:!1},_isAllowedExtension:function(a,b){var c=!1;return a.length?(qq.each(a,function(a,d){if(qq.isString(d)){var e=new RegExp("\\."+d+"$","i");if(null!=b.match(e))return c=!0,!1}}),c):!0},_itemError:function(a,b,c){function d(a,b){g=g.replace(a,b)}var e,f,g=this._options.messages[a],h=[],i=[].concat(b),j=i[0],k=this._getButtonId(c),l=this._getValidationBase(k);return qq.each(l.allowedExtensions,function(a,b){qq.isString(b)&&h.push(b)}),e=h.join(", ").toLowerCase(),d("{file}",this._options.formatFileName(j)),d("{extensions}",e),d("{sizeLimit}",this._formatSize(l.sizeLimit)),d("{minSizeLimit}",this._formatSize(l.minSizeLimit)),f=g.match(/(\{\w+\})/g),null!==f&&qq.each(f,function(a,b){d(b,i[a])}),this._options.callbacks.onError(null,j,g,void 0),g},_manualRetry:function(a,b){return this._onBeforeManualRetry(a)?(this._netUploadedOrQueued++,this._uploadData.setStatus(a,qq.status.UPLOAD_RETRYING),b?b(a):this._handler.retry(a),!0):void 0},_maybeAllComplete:function(a,b){var c=this,d=this._getNotFinished();b===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(a):b===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(a),0===d&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){c._onAllComplete(c._succeededSinceLastAllComplete,c._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var a=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(a._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(a,b,c,d){if(!c.success)if(d&&200!==d.status&&!c.error)this._options.callbacks.onError(a,b,"XHR returned response code "+d.status,d);else{var e=c.error?c.error:this._options.text.defaultResponseError;this._options.callbacks.onError(a,b,e,d)}},_maybeProcessNextItemAfterOnValidateCallback:function(a,b,c,d,e){var f=this;if(b.length>c)if(a||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var a=f._getValidationDescriptor(b[c]),g=f._getButtonId(b[c].file),h=f._getButton(g);f._handleCheckedCallback({name:"onValidate",callback:qq.bind(f._options.callbacks.onValidate,f,a,h),onSuccess:qq.bind(f._onValidateCallbackSuccess,f,b,c,d,e),onFailure:qq.bind(f._onValidateCallbackFailure,f,b,c,d,e),identifier:"Item '"+a.name+"', size: "+a.size})},0);else if(!a)for(;c0&&this._netUploadedOrQueued+1>c?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+b+"' (id: "+a+")..."),!0)):(this.log("'"+a+"' is not a valid file ID","error"),!1)},_onCancel:function(a){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[a]);var b=qq.indexOf(this._storedIds,a);!this._options.autoUpload&&b>=0&&this._storedIds.splice(b,1),this._uploadData.setStatus(a,qq.status.CANCELED)},_onComplete:function(a,b,c,d){return c.success?(c.thumbnailUrl&&(this._thumbnailUrls[a]=c.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(a,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(a,qq.status.UPLOAD_FAILED),c[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[a]=!0)),this._maybeParseAndSendUploadError(a,b,c,d),c.success?!0:!1},_onDelete:function(a){this._uploadData.setStatus(a,qq.status.DELETING)},_onDeleteComplete:function(a,b,c){var d=this.getName(a);c?(this._uploadData.setStatus(a,qq.status.DELETE_FAILED),this.log("Delete request for '"+d+"' has failed.","error"),void 0===b.withCredentials?this._options.callbacks.onError(a,d,"Delete request failed",b):this._options.callbacks.onError(a,d,"Delete request failed with response code "+b.status,b)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(a),this._uploadData.setStatus(a,qq.status.DELETED),this.log("Delete request for '"+d+"' has succeeded."))},_onInputChange:function(a){var b;if(qq.supportedFeatures.ajaxUploading){for(b=0;b0&&this.addFiles(a);qq.each(this._buttons,function(a,b){b.reset()})},_onProgress:function(a,b,c,d){this._totalProgress&&this._totalProgress.onIndividualProgress(a,c,d)},_onSubmit:function(){},_onSubmitCallbackSuccess:function(a){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(a,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.callbacks.onSubmitted.apply(this,arguments),this._options.autoUpload?this._uploadFile(a):this._storeForLater(a)},_onSubmitDelete:function(a,b,c){var d,e=this.getUuid(a);return b&&(d=qq.bind(b,this,a,e,c)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,a),onSuccess:d||qq.bind(this._deleteHandler.sendDelete,this,a,e,c),identifier:a}),!0):(this.log("Delete request ignored for ID "+a+", delete feature is disabled or request not possible "+"due to CORS on a user agent that does not support pre-flighting.","warn"),!1)},_onSubmitted:function(){},_onTotalProgress:function(a,b){this._options.callbacks.onTotalProgress(a,b)},_onUploadPrep:function(){},_onUpload:function(a){this._uploadData.setStatus(a,qq.status.UPLOADING)},_onUploadChunk:function(){},_onUploadStatusChange:function(a,b,c){c===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[a])},_onValidateBatchCallbackFailure:function(a){var b=this;qq.each(a,function(a,c){b._fileOrBlobRejected(c.id)})},_onValidateBatchCallbackSuccess:function(a,b,c,d,e){var f,g=this._currentItemLimit,h=this._netUploadedOrQueued;0===g||g>=h?b.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,a[0],e),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,b,0,c,d),onFailure:qq.bind(this._onValidateCallbackFailure,this,b,0,c,d),identifier:"Item '"+b[0].file.name+"', size: "+b[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(b),f=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,h).replace(/\{itemLimit\}/g,g),this._batchError(f))},_onValidateCallbackFailure:function(a,b,c,d){var e=b+1;this._fileOrBlobRejected(a[b].id,a[b].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,a,e,c,d)},_onValidateCallbackSuccess:function(a,b,c,d){var e=this,f=b+1,g=this._getValidationDescriptor(a[b]);this._validateFileOrBlobData(a[b],g).then(function(){e._upload(a[b].id,c,d),e._maybeProcessNextItemAfterOnValidateCallback(!0,a,f,c,d)},function(){e._maybeProcessNextItemAfterOnValidateCallback(!1,a,f,c,d)})},_prepareItemsForUpload:function(a,b,c){if(0===a.length)return this._itemError("noFilesError"),void 0;var d=this._getValidationDescriptors(a),e=this._getButtonId(a[0].file),f=this._getButton(e);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,d,f),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,d,a,b,c,f),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,a),identifier:"batch validation"})},_preventLeaveInProgress:function(){var a=this;this._disposeSupport.attach(window,"beforeunload",function(b){return a.getInProgress()?(b=b||window.event,b.returnValue=a._options.messages.onLeave,a._options.messages.onLeave):void 0})},_refreshSessionData:function(){var a=this,b=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(b,this._options.cors),b.log=qq.bind(this.log,this),b.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(b)),setTimeout(function(){a._session.refresh().then(function(b,c){a._options.callbacks.onSessionRequestComplete(b,!0,c)},function(b,c){a._options.callbacks.onSessionRequestComplete(b,!1,c)})},0))},_setSize:function(a,b){this._uploadData.updateSize(a,b),this._totalProgress&&this._totalProgress.onNewSize(a)},_shouldAutoRetry:function(a){var b=this._uploadData.retrieve({id:a});return!this._preventRetries[a]&&this._options.retry.enableAuto&&b.status!==qq.status.PAUSED&&(void 0===this._autoRetries[a]&&(this._autoRetries[a]=0),this._autoRetries[a]0&&h.sizeLimit&&f>h.sizeLimit?(this._itemError("sizeError",e,d),i.failure()):f>0&&f=0}function c(){var a=!1;return qq.each(a,function(b,c){return qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],c)<0?(a=!0,!1):void 0}),a}function d(a){return w.cors.expected&&void 0===a.withCredentials}function e(){var a;return(window.XMLHttpRequest||window.ActiveXObject)&&(a=qq.createXhrInstance(),void 0===a.withCredentials&&(a=new XDomainRequest)),a}function f(a,b){var c=v[a].xhr;return c||(c=b?b:w.cors.expected?e():qq.createXhrInstance(),v[a].xhr=c),c}function g(a){var b,c=qq.indexOf(u,a),d=w.maxConnections;delete v[a],u.splice(c,1),u.length>=d&&d>c&&(b=u[d-1],j(b))}function h(a,b){var c=f(a),e=w.method,h=b===!0;g(a),h?s(e+" request for "+a+" has failed","error"):d(c)||q(c.status)||(h=!0,s(e+" request for "+a+" has failed - response code "+c.status,"error")),w.onComplete(a,c,h)}function i(a){var b,c=v[a].additionalParams,d=w.mandatedParams;return w.paramsStore.get&&(b=w.paramsStore.get(a)),c&&qq.each(c,function(a,c){b=b||{},b[a]=c}),d&&qq.each(d,function(a,c){b=b||{},b[a]=c}),b}function j(a,b){var c,e=f(a,b),g=w.method,h=i(a),j=v[a].payload;return w.onSend(a),c=k(a,h),d(e)?(e.onload=n(a),e.onerror=o(a)):e.onreadystatechange=l(a),m(a),e.open(g,c,!0),w.cors.expected&&w.cors.sendCredentials&&!d(e)&&(e.withCredentials=!0),p(a),s("Sending "+g+" request for "+a),j?e.send(j):t||!h?e.send():h&&w.contentType&&w.contentType.toLowerCase().indexOf("application/x-www-form-urlencoded")>=0?e.send(qq.obj2url(h,"")):h&&w.contentType&&w.contentType.toLowerCase().indexOf("application/json")>=0?e.send(JSON.stringify(h)):e.send(h),e}function k(a,b){var c=w.endpointStore.get(a),d=v[a].addToPath;return void 0!=d&&(c+="/"+d),t&&b?qq.obj2url(b,c):c}function l(a){return function(){4===f(a).readyState&&h(a)}}function m(a){var b=w.onProgress;b&&(f(a).upload.onprogress=function(c){c.lengthComputable&&b(a,c.loaded,c.total)})}function n(a){return function(){h(a)}}function o(a){return function(){h(a,!0)}}function p(a){var e=f(a),g=w.customHeaders,h=v[a].additionalHeaders||{},i=w.method,j={};d(e)||(w.acceptHeader&&e.setRequestHeader("Accept",w.acceptHeader),w.allowXRequestedWithAndCacheControl&&(w.cors.expected&&b()&&!c(g)||(e.setRequestHeader("X-Requested-With","XMLHttpRequest"),e.setRequestHeader("Cache-Control","no-cache"))),!w.contentType||"POST"!==i&&"PUT"!==i||e.setRequestHeader("Content-Type",w.contentType),qq.extend(j,qq.isFunction(g)?g(a):g),qq.extend(j,h),qq.each(j,function(a,b){e.setRequestHeader(a,b)}))}function q(a){return qq.indexOf(w.successfulResponseCodes[w.method],a)>=0}function r(a,b,c,d,e,f){v[a]={addToPath:c,additionalParams:d,additionalHeaders:e,payload:f};var g=u.push(a);return g<=w.maxConnections?j(a,b):void 0}var s,t,u=[],v={},w={acceptHeader:null,validMethods:["PATCH","POST","PUT"],method:"POST",contentType:"application/x-www-form-urlencoded",maxConnections:3,customHeaders:{},endpointStore:{},paramsStore:{},mandatedParams:{},allowXRequestedWithAndCacheControl:!0,successfulResponseCodes:{DELETE:[200,202,204],PATCH:[200,201,202,203,204],POST:[200,201,202,203,204],PUT:[200,201,202,203,204],GET:[200]},cors:{expected:!1,sendCredentials:!1},log:function(){},onSend:function(){},onComplete:function(){},onProgress:null};if(qq.extend(w,a),s=w.log,qq.indexOf(w.validMethods,w.method)<0)throw new Error("'"+w.method+"' is not a supported method for this type of request!");t="GET"===w.method||"DELETE"===w.method,qq.extend(this,{initTransport:function(a){var b,c,d,e,f;return{withPath:function(a){return b=a,this},withParams:function(a){return c=a,this},withHeaders:function(a){return d=a,this},withPayload:function(a){return e=a,this},withCacheBuster:function(){return f=!0,this},send:function(g){return f&&qq.indexOf(["GET","DELETE"],w.method)>=0&&(c.qqtimestamp=(new Date).getTime()),r(a,g,b,c,d,e)}}},canceled:function(a){g(a)}})},qq.UploadHandler=function(a){"use strict";var b=a.proxy,c={},d=b.onCancel,e=b.getName;qq.extend(this,{add:function(a,b){c[a]=b,c[a].temp={}},cancel:function(a){var b=this,f=new qq.Promise,g=d(a,e(a),f);g.then(function(){b.isValid(a)&&(c[a].canceled=!0,b.expunge(a)),f.success()})},expunge:function(a){delete c[a]},getThirdPartyFileId:function(a){return c[a].key},isValid:function(a){return void 0!==c[a]},reset:function(){c={}},_getFileState:function(a){return c[a]},_setThirdPartyFileId:function(a,b){c[a].key=b},_wasCanceled:function(a){return!!c[a].canceled}})},qq.UploadHandlerController=function(a,b){"use strict";var c,d,e,f=this,g=!1,h=!1,i={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(){},onProgress:function(){},onComplete:function(){},onCancel:function(){},onUploadPrep:function(){},onUpload:function(){},onUploadChunk:function(){},onUploadChunkSuccess:function(){},onAutoRetry:function(){},onResume:function(){},onUuidChanged:function(){},getName:function(){},setSize:function(){},isQueued:function(){},getIdsInProxyGroup:function(){},getIdsInBatch:function(){}},j={done:function(a,b,c,d){var f=e._getChunkData(a,b);e._getFileState(a).attemptingResume=!1,delete e._getFileState(a).temp.chunkProgress[b],e._getFileState(a).loaded+=f.size,i.onUploadChunkSuccess(a,e._getChunkDataForCallback(f),c,d)},finalize:function(a){var b=i.getSize(a),c=i.getName(a);d("All chunks have been uploaded for "+a+" - finalizing...."),e.finalizeChunks(a).then(function(f,g){d("Finalize successful for "+a);var h=m.normalizeResponse(f,!0);i.onProgress(a,c,b,b),e._maybeDeletePersistedChunkData(a),m.cleanup(a,h,g)},function(b,e){var f=m.normalizeResponse(b,!1);d("Problem finalizing chunks for file ID "+a+" - "+f.error,"error"),f.reset&&j.reset(a),i.onAutoRetry(a,c,f,e)||m.cleanup(a,f,e)})},hasMoreParts:function(a){return!!e._getFileState(a).chunking.remaining.length},nextPart:function(a){var b=e._getFileState(a).chunking.remaining.shift();return b>=e._getTotalChunks(a)&&(b=null),b},reset:function(a){d("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+a,"error"),e._maybeDeletePersistedChunkData(a),e.reevaluateChunking(a),e._getFileState(a).loaded=0},sendNext:function(a){var b=i.getSize(a),c=i.getName(a),f=j.nextPart(a),g=e._getChunkData(a,f),l=e._getFileState(a).attemptingResume,n=e._getFileState(a).chunking.inProgress||[];null==e._getFileState(a).loaded&&(e._getFileState(a).loaded=0),l&&i.onResume(a,c,g)===!1&&(j.reset(a),f=j.nextPart(a),g=e._getChunkData(a,f),l=!1),null==f&&0===n.length?j.finalize(a):(d("Sending chunked upload request for item "+a+": bytes "+(g.start+1)+"-"+g.end+" of "+b),i.onUploadChunk(a,c,e._getChunkDataForCallback(g)),n.push(f),e._getFileState(a).chunking.inProgress=n,h&&k.open(a,f),h&&k.available()&&e._getFileState(a).chunking.remaining.length&&j.sendNext(a),e.uploadChunk(a,f,l).then(function(b,c){d("Chunked upload request succeeded for "+a+", chunk "+f),e.clearCachedChunk(a,f);var g=e._getFileState(a).chunking.inProgress||[],h=m.normalizeResponse(b,!0),i=qq.indexOf(g,f);d(qq.format("Chunk {} for file {} uploaded successfully.",f,a)),j.done(a,f,h,c),i>=0&&g.splice(i,1),e._maybePersistChunkedState(a),j.hasMoreParts(a)||0!==g.length?j.hasMoreParts(a)&&j.sendNext(a):j.finalize(a)},function(b,g){d("Chunked upload request failed for "+a+", chunk "+f),e.clearCachedChunk(a,f);var l,n=m.normalizeResponse(b,!1);n.reset?j.reset(a):(l=qq.indexOf(e._getFileState(a).chunking.inProgress,f),l>=0&&(e._getFileState(a).chunking.inProgress.splice(l,1),e._getFileState(a).chunking.remaining.unshift(f))),e._getFileState(a).temp.ignoreFailure||(h&&(e._getFileState(a).temp.ignoreFailure=!0,qq.each(e._getXhrs(a),function(a,b){b.abort()}),e.moveInProgressToRemaining(a),k.free(a,!0)),i.onAutoRetry(a,c,n,g)||m.cleanup(a,n,g))}).done(function(){e.clearXhr(a,f)}))}},k={_open:[],_openChunks:{},_waiting:[],available:function(){var a=i.maxConnections,b=0,c=0;return qq.each(k._openChunks,function(a,d){b++,c+=d.length}),a-(k._open.length-b+c)},free:function(a,b){var c,f=!b,g=qq.indexOf(k._waiting,a),h=qq.indexOf(k._open,a);delete k._openChunks[a],m.getProxyOrBlob(a)instanceof qq.BlobProxy&&(d("Generated blob upload has ended for "+a+", disposing generated blob."),delete e._getFileState(a).file),g>=0?k._waiting.splice(g,1):f&&h>=0&&(k._open.splice(h,1),c=k._waiting.shift(),c>=0&&(k._open.push(c),m.start(c)))},getWaitingOrConnected:function(){var a=[];return qq.each(k._openChunks,function(b,c){c&&c.length&&a.push(parseInt(b))}),qq.each(k._open,function(b,c){k._openChunks[c]||a.push(parseInt(c))}),a=a.concat(k._waiting)},isUsingConnection:function(a){return qq.indexOf(k._open,a)>=0},open:function(a,b){return null==b&&k._waiting.push(a),k.available()?(null==b?(k._waiting.pop(),k._open.push(a)):function(){var c=k._openChunks[a]||[];c.push(b),k._openChunks[a]=c}(),!0):!1},reset:function(){k._waiting=[],k._open=[]}},l={send:function(a,b){e._getFileState(a).loaded=0,d("Sending simple upload request for "+a),e.uploadFile(a).then(function(c,e){d("Simple upload request succeeded for "+a);var f=m.normalizeResponse(c,!0),g=i.getSize(a);i.onProgress(a,b,g,g),m.maybeNewUuid(a,f),m.cleanup(a,f,e)},function(c,e){d("Simple upload request failed for "+a);var f=m.normalizeResponse(c,!1);i.onAutoRetry(a,b,f,e)||m.cleanup(a,f,e)})}},m={cancel:function(a){d("Cancelling "+a),i.paramsStore.remove(a),k.free(a)},cleanup:function(a,b,c){var d=i.getName(a);i.onComplete(a,d,b,c),e._getFileState(a)&&e._clearXhrs&&e._clearXhrs(a),k.free(a)},getProxyOrBlob:function(a){return e.getProxy&&e.getProxy(a)||e.getFile&&e.getFile(a)},initHandler:function(){var a=b?qq[b]:qq.traditional,c=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";e=new a[c+"UploadHandler"](i,{getDataByUuid:i.getDataByUuid,getName:i.getName,getSize:i.getSize,getUuid:i.getUuid,log:d,onCancel:i.onCancel,onProgress:i.onProgress,onUuidChanged:i.onUuidChanged}),e._removeExpiredChunkingRecords&&e._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(a){return i.isQueued(a)},maybeDefer:function(a,b){return b&&!e.getFile(a)&&b instanceof qq.BlobProxy?(i.onUploadPrep(a),d("Attempting to generate a blob on-demand for "+a),b.create().then(function(b){d("Generated an on-demand blob for "+a),e.updateBlob(a,b),i.setSize(a,b.size),e.reevaluateChunking(a),m.maybeSendDeferredFiles(a)},function(b){var e={};b&&(e.error=b),d(qq.format("Failed to generate blob for ID {}. Error message: {}.",a,b),"error"),i.onComplete(a,i.getName(a),qq.extend(e,c),null),m.maybeSendDeferredFiles(a),k.free(a)}),!1):m.maybeSendDeferredFiles(a)},maybeSendDeferredFiles:function(a){var b=i.getIdsInProxyGroup(a),c=!1;return b&&b.length?(d("Maybe ready to upload proxy group file "+a),qq.each(b,function(b,d){if(m.isDeferredEligibleForUpload(d)&&e.getFile(d))c=d===a,m.now(d);else if(m.isDeferredEligibleForUpload(d))return!1})):(c=!0,m.now(a)),c},maybeNewUuid:function(a,b){void 0!==b.newUuid&&i.onUuidChanged(a,b.newUuid)},normalizeResponse:function(a,b){var c=a;return qq.isObject(a)||(c={},qq.isString(a)&&!b&&(c.error=a)),c.success=b,c},now:function(a){var b=i.getName(a);if(!f.isValid(a))throw new qq.Error(a+" is not a valid file ID to upload!");i.onUpload(a,b),g&&e._shouldChunkThisFile(a)?j.sendNext(a):l.send(a,b)},start:function(a){var b=m.getProxyOrBlob(a);return b?m.maybeDefer(a,b):(m.now(a),!0)}};qq.extend(this,{add:function(){e.add.apply(this,arguments)},upload:function(a){return k.open(a)?m.start(a):!1},retry:function(a){return h&&(e._getFileState(a).temp.ignoreFailure=!1),k.isUsingConnection(a)?m.start(a):f.upload(a)},cancel:function(a){var b=e.cancel(a);qq.isGenericPromise(b)?b.then(function(){m.cancel(a)}):b!==!1&&m.cancel(a)},cancelAll:function(){var a,b=k.getWaitingOrConnected();if(b.length)for(a=b.length-1;a>=0;a--)f.cancel(b[a]);k.reset()},getFile:function(a){return e.getProxy&&e.getProxy(a)?e.getProxy(a).referenceBlob:e.getFile&&e.getFile(a)},isProxied:function(a){return!(!e.getProxy||!e.getProxy(a))},getInput:function(a){return e.getInput?e.getInput(a):void 0},reset:function(){d("Resetting upload handler"),f.cancelAll(),k.reset(),e.reset()},expunge:function(a){return f.isValid(a)?e.expunge(a):void 0},isValid:function(a){return e.isValid(a)},getResumableFilesData:function(){return e.getResumableFilesData?e.getResumableFilesData():[]},getThirdPartyFileId:function(a){return f.isValid(a)?e.getThirdPartyFileId(a):void 0},pause:function(a){return f.isResumable(a)&&e.pause&&f.isValid(a)&&e.pause(a)?(k.free(a),e.moveInProgressToRemaining(a),!0):!1},isResumable:function(a){return!!e.isResumable&&e.isResumable(a)}}),qq.extend(i,a),d=i.log,g=i.chunking.enabled&&qq.supportedFeatures.chunking,h=g&&i.chunking.concurrent.enabled,c=function(){var a={};return a[i.preventRetryParam]=!0,a}(),m.initHandler()},qq.FormUploadHandler=function(a){"use strict";function b(a){delete k[a],m&&(clearTimeout(l[a]),delete l[a],q.stopReceivingMessages(a));var b=document.getElementById(g._getIframeName(a));b&&(b.setAttribute("src","javascript:false;"),qq(b).remove())}function c(a){return a.split("_")[0]}function d(a){var b=qq.toElement("");return b.setAttribute("id",a),b.style.display="none",document.body.appendChild(b),b}function e(a,b){var d=a.id,e=c(d),f=o(e);j[f]=b,k[e]=qq(a).attach("load",function(){g.getInput(e)&&(p("Received iframe load event for CORS upload request (iframe name "+d+")"),l[d]=setTimeout(function(){var a="No valid message received from loaded iframe for iframe name "+d;p(a,"error"),b({error:a})},1e3))}),q.receiveMessage(d,function(a){p("Received the following window message: '"+a+"'");var b,e=(c(d),g._parseJsonResponse(a)),f=e.uuid;f&&j[f]?(p("Handling response for iframe name "+d),clearTimeout(l[d]),delete l[d],g._detachLoadEvent(d),b=j[f],delete j[f],q.stopReceivingMessages(d),b(e)):f||p("'"+a+"' does not contain a UUID - ignoring.")})}var f=a.options,g=this,h=a.proxy,i=qq.getUniqueId(),j={},k={},l={},m=f.isCors,n=f.inputName,o=h.getUuid,p=h.log,q=new qq.WindowReceiveMessage({log:p});qq.extend(this,new qq.UploadHandler(a)),qq.override(this,function(a){return{add:function(b,c){a.add(b,{input:c}),c.setAttribute("name",n),c.parentNode&&qq(c).remove()},expunge:function(c){b(c),a.expunge(c)},isValid:function(b){return a.isValid(b)&&void 0!==g._getFileState(b).input}}}),qq.extend(this,{getInput:function(a){return g._getFileState(a).input},_attachLoadEvent:function(a,b){var c;m?e(a,b):k[a.id]=qq(a).attach("load",function(){if(p("Received response for "+a.id),a.parentNode){try{if(a.contentDocument&&a.contentDocument.body&&"false"==a.contentDocument.body.innerHTML)return}catch(d){p("Error when attempting to access iframe during handling of upload response ("+d.message+")","error"),c={success:!1}}b(c)}})},_createIframe:function(a){var b=g._getIframeName(a);return d(b)},_detachLoadEvent:function(a){void 0!==k[a]&&(k[a](),delete k[a])},_getIframeName:function(a){return a+"_"+i},_initFormForUpload:function(a){var b=a.method,c=a.endpoint,d=a.params,e=a.paramsInBody,f=a.targetName,g=qq.toElement("
"),h=c;return e?qq.obj2Inputs(d,g):h=qq.obj2url(d,c),g.setAttribute("action",h),g.setAttribute("target",f),g.style.display="none",document.body.appendChild(g),g
-},_parseJsonResponse:function(a){var b={};try{b=qq.parseJson(a)}catch(c){p("Error when attempting to parse iframe upload response ("+c.message+")","error")}return b}})},qq.XhrUploadHandler=function(a){"use strict";function b(a){qq.each(c._getXhrs(a),function(b,d){var e=c._getAjaxRequester(a,b);d.onreadystatechange=null,d.upload.onprogress=null,d.abort(),e&&e.canceled&&e.canceled(a)})}var c=this,d=a.options.namespace,e=a.proxy,f=a.options.chunking,g=a.options.resume,h=f&&a.options.chunking.enabled&&qq.supportedFeatures.chunking,i=g&&a.options.resume.enabled&&h&&qq.supportedFeatures.resume,j=e.getName,k=e.getSize,l=e.getUuid,m=e.getEndpoint,n=e.getDataByUuid,o=e.onUuidChanged,p=e.onProgress,q=e.log;qq.extend(this,new qq.UploadHandler(a)),qq.override(this,function(a){return{add:function(b,d){if(qq.isFile(d)||qq.isBlob(d))a.add(b,{file:d});else{if(!(d instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");a.add(b,{proxy:d})}c._initTempState(b),i&&c._maybePrepareForResume(b)},expunge:function(d){b(d),c._maybeDeletePersistedChunkData(d),c._clearXhrs(d),a.expunge(d)}}}),qq.extend(this,{clearCachedChunk:function(a,b){delete c._getFileState(a).temp.cachedChunks[b]},clearXhr:function(a,b){var d=c._getFileState(a).temp;d.xhrs&&delete d.xhrs[b],d.ajaxRequesters&&delete d.ajaxRequesters[b]},finalizeChunks:function(a,b){var d=c._getTotalChunks(a)-1,e=c._getXhr(a,d);return b?(new qq.Promise).success(b(e),e):(new qq.Promise).success({},e)},getFile:function(a){return c.isValid(a)&&c._getFileState(a).file},getProxy:function(a){return c.isValid(a)&&c._getFileState(a).proxy},getResumableFilesData:function(){var a=[];return c._iterateResumeRecords(function(b,d){c.moveInProgressToRemaining(null,d.chunking.inProgress,d.chunking.remaining);var e={name:d.name,remaining:d.chunking.remaining,size:d.size,uuid:d.uuid};d.key&&(e.key=d.key),a.push(e)}),a},isResumable:function(a){return!!f&&c.isValid(a)&&!c._getFileState(a).notResumable},moveInProgressToRemaining:function(a,b,d){var e=b||c._getFileState(a).chunking.inProgress,f=d||c._getFileState(a).chunking.remaining;e&&(e.reverse(),qq.each(e,function(a,b){f.unshift(b)}),e.length=0)},pause:function(a){return c.isValid(a)?(q(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",a,j(a))),c._getFileState(a).paused=!0,b(a),!0):void 0},reevaluateChunking:function(a){if(f&&c.isValid(a)){var b,d,e=c._getFileState(a);if(delete e.chunking,e.chunking={},b=c._getTotalChunks(a),b>1||f.mandatory){for(e.chunking.enabled=!0,e.chunking.parts=b,e.chunking.remaining=[],d=0;b>d;d++)e.chunking.remaining.push(d);c._initTempState(a)}else e.chunking.enabled=!1}},updateBlob:function(a,b){c.isValid(a)&&(c._getFileState(a).file=b)},_clearXhrs:function(a){var b=c._getFileState(a).temp;qq.each(b.ajaxRequesters,function(a){delete b.ajaxRequesters[a]}),qq.each(b.xhrs,function(a){delete b.xhrs[a]})},_createXhr:function(a,b){return c._registerXhr(a,b,qq.createXhrInstance())},_getAjaxRequester:function(a,b){var d=null==b?-1:b;return c._getFileState(a).temp.ajaxRequesters[d]},_getChunkData:function(a,b){var d=f.partSize,e=k(a),g=c.getFile(a),h=d*b,i=h+d>=e?e:h+d,j=c._getTotalChunks(a),l=this._getFileState(a).temp.cachedChunks,m=l[b]||qq.sliceBlob(g,h,i);return l[b]=m,{part:b,start:h,end:i,count:j,blob:m,size:i-h}},_getChunkDataForCallback:function(a){return{partIndex:a.part,startByte:a.start+1,endByte:a.end,totalParts:a.count}},_getLocalStorageId:function(a){var b="5.0",c=j(a),e=k(a),g=f.partSize,h=m(a);return qq.format("qq{}resume{}-{}-{}-{}-{}",d,b,c,e,g,h)},_getMimeType:function(a){return c.getFile(a).type},_getPersistableData:function(a){return c._getFileState(a).chunking},_getTotalChunks:function(a){if(f){var b=k(a),c=f.partSize;return Math.ceil(b/c)}},_getXhr:function(a,b){var d=null==b?-1:b;return c._getFileState(a).temp.xhrs[d]},_getXhrs:function(a){return c._getFileState(a).temp.xhrs},_iterateResumeRecords:function(a){i&&qq.each(localStorage,function(b,c){if(0===b.indexOf(qq.format("qq{}resume-",d))){var e=JSON.parse(c);a(b,e)}})},_initTempState:function(a){c._getFileState(a).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(a){c._getFileState(a).notResumable=!0},_maybeDeletePersistedChunkData:function(a){var b;return i&&c.isResumable(a)&&(b=c._getLocalStorageId(a),b&&localStorage.getItem(b))?(localStorage.removeItem(b),!0):!1},_maybePrepareForResume:function(a){var b,d,e=c._getFileState(a);i&&void 0===e.key&&(b=c._getLocalStorageId(a),d=localStorage.getItem(b),d&&(d=JSON.parse(d),n(d.uuid)?c._markNotResumable(a):(q(qq.format("Identified file with ID {} and name of {} as resumable.",a,j(a))),o(a,d.uuid),e.key=d.key,e.chunking=d.chunking,e.loaded=d.loaded,e.attemptingResume=!0,c.moveInProgressToRemaining(a))))},_maybePersistChunkedState:function(a){var b,d,e=c._getFileState(a);if(i&&c.isResumable(a)){b=c._getLocalStorageId(a),d={name:j(a),size:k(a),uuid:l(a),key:e.key,chunking:e.chunking,loaded:e.loaded,lastUpdated:Date.now()};try{localStorage.setItem(b,JSON.stringify(d))}catch(f){q(qq.format("Unable to save resume data for '{}' due to error: '{}'.",a,f.toString()),"warn")}}},_registerProgressHandler:function(a,b,d){var e=c._getXhr(a,b),f=j(a),g={simple:function(b,c){var d=k(a);b===c?p(a,f,d,d):p(a,f,b>=d?d-1:b,d)},chunked:function(e,g){var h=c._getFileState(a).temp.chunkProgress,i=c._getFileState(a).loaded,j=e,l=g,m=k(a),n=j-(l-d),o=i;h[b]=n,qq.each(h,function(a,b){o+=b}),p(a,f,o,m)}};e.upload.onprogress=function(a){if(a.lengthComputable){var b=null==d?"simple":"chunked";g[b](a.loaded,a.total)}}},_registerXhr:function(a,b,d,e){var f=null==b?-1:b,g=c._getFileState(a).temp;return g.xhrs=g.xhrs||{},g.ajaxRequesters=g.ajaxRequesters||{},g.xhrs[f]=d,e&&(g.ajaxRequesters[f]=e),d},_removeExpiredChunkingRecords:function(){var a=g.recordsExpireIn;c._iterateResumeRecords(function(b,c){var d=new Date(c.lastUpdated);d.setDate(d.getDate()+a),d.getTime()<=Date.now()&&(q("Removing expired resume record with key "+b),localStorage.removeItem(b))})},_shouldChunkThisFile:function(a){var b=c._getFileState(a);return b.chunking||c.reevaluateChunking(a),b.chunking.enabled}})},qq.WindowReceiveMessage=function(a){"use strict";var b={log:function(){}},c={};qq.extend(b,a),qq.extend(this,{receiveMessage:function(a,b){var d=function(a){b(a.data)};window.postMessage?c[a]=qq(window).attach("message",d):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(a){if(window.postMessage){var b=c[a];b&&b()}}})},function(){"use strict";qq.uiPublicApi={clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(a){this._dnd&&this._dnd.setupExtraDropzone(a)},removeExtraDropzone:function(a){return this._dnd?this._dnd.removeDropzone(a):void 0},getItemByFileId:function(a){return this._templating.getFileContainer(a)},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()}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(a,b){var c=this._options.formatFileName(b);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(a,c)},pauseUpload:function(a){var b=this._parent.prototype.pauseUpload.apply(this,arguments);return b&&this._templating.uploadPaused(a),b},continueUpload:function(a){var b=this._parent.prototype.continueUpload.apply(this,arguments);return b&&this._templating.uploadContinued(a),b},getId:function(a){return this._templating.getFileId(a)},getDropTarget:function(a){var b=this.getFile(a);return b.qqDropTarget}},qq.uiPrivateApi={_getButton:function(a){var b=this._parent.prototype._getButton.apply(this,arguments);return b||a===this._defaultButtonId&&(b=this._templating.getButton()),b},_removeFileItem:function(a){this._templating.removeFile(a)},_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 a=this,b=this._options.dragAndDrop.extraDropzones,c=this._templating,d=c.getDropZone();return d&&b.push(d),new qq.DragAndDrop({dropZoneElements:b,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){c.showDropProcessing()},processingDroppedFilesComplete:function(b,d){c.hideDropProcessing(),qq.each(b,function(a,b){b.qqDropTarget=d}),b.length&&a.addFiles(b,null,null)},dropError:function(b,c){a._itemError(b,c)},dropLog:function(b,c){a.log(b,c)}}})},_bindFileButtonsClickEvent:function(){var a=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(b,c){a.log(b,c)},onDeleteFile:function(b){a.deleteFile(b)},onCancel:function(b){a.cancel(b)},onRetry:function(b){qq(a._templating.getFileContainer(b)).removeClass(a._classes.retryable),a._templating.hideRetry(b),a.retry(b)},onPause:function(b){a.pauseUpload(b)},onContinue:function(b){a.continueUpload(b)},onGetName:function(b){return a.getName(b)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var a=this,b=this._templating;return{templating:b,log:function(b,c){a.log(b,c)},onGetUploadStatus:function(b){return a.getUploads({id:b}).status},onGetName:function(b){return a.getName(b)},onSetName:function(b,c){a.setName(b,c)},onEditingStatusChange:function(a,c){var d=qq(b.getEditInput(a)),e=qq(b.getFileContainer(a));c?(d.addClass("qq-editing"),b.hideFilename(a),b.hideEditIcon(a)):(d.removeClass("qq-editing"),b.showFilename(a),b.showEditIcon(a)),e.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(a,b,c){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(a)&&c!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(a),this._templating.hideEditIcon(a)),c===qq.status.UPLOAD_RETRYING?(this._templating.setStatusText(a),qq(this._templating.getFileContainer(a)).removeClass(this._classes.retrying)):c===qq.status.UPLOAD_FAILED&&this._templating.hidePause(a)},_bindFilenameInputFocusInEvent:function(){var a=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(a)},_bindFilenameInputFocusEvent:function(){var a=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(a)},_bindFilenameClickEvent:function(){var a=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(a)},_storeForLater:function(a){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(a)},_onAllComplete:function(){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(a,b){var c=this.getFile(a);c&&c.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(a,{qqpath:c.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(a,b)},_onSubmitted:function(a){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(a),this._templating.showEditIcon(a),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(a)))},_onProgress:function(a,b,c,d){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(a,c,d),100===Math.round(100*(c/d))?(this._templating.hideCancel(a),this._templating.hidePause(a),this._templating.hideProgress(a),this._templating.setStatusText(a,this._options.text.waitingForResponse),this._displayFileSize(a)):this._displayFileSize(a,c,d)},_onTotalProgress:function(a,b){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(a,b)},_onComplete:function(a,b,c){function d(b){g&&(f.setStatusText(a),qq(g).removeClass(h._classes.retrying),f.hideProgress(a),h.getUploads({id:a}).status!==qq.status.UPLOAD_FAILED&&f.hideCancel(a),f.hideSpinner(a),b.success?h._markFileAsSuccessful(a):(qq(g).addClass(h._classes.fail),f.showCancel(a),f.isRetryPossible()&&!h._preventRetries[a]&&(qq(g).addClass(h._classes.retryable),f.showRetry(a)),h._controlFailureTextDisplay(a,b)))}var e=this._parent.prototype._onComplete.apply(this,arguments),f=this._templating,g=f.getFileContainer(a),h=this;return e instanceof qq.Promise?e.done(function(a){d(a)}):d(c),e},_markFileAsSuccessful:function(a){var b=this._templating;this._isDeletePossible()&&b.showDeleteButton(a),qq(b.getFileContainer(a)).addClass(this._classes.success),this._maybeUpdateThumbnail(a)},_onUploadPrep:function(a){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(a)},_onUpload:function(a){var b=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(a),b},_onUploadChunk:function(a,b){this._parent.prototype._onUploadChunk.apply(this,arguments),b.partIndex>0&&this._handler.isResumable(a)&&this._templating.allowPause(a)},_onCancel:function(a){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(a),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(a){var b,c,d;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(a),this._options.retry.showAutoRetryNote&&(b=this._autoRetries[a],c=this._options.retry.maxAutoAttempts,d=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,b),d=d.replace(/\{maxAuto\}/g,c),this._templating.setStatusText(a,d),qq(this._templating.getFileContainer(a)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(a){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(a),qq(this._templating.getFileContainer(a)).removeClass(this._classes.fail),this._templating.setStatusText(a),this._templating.showSpinner(a),this._showCancelLink(a),!0):(qq(this._templating.getFileContainer(a)).addClass(this._classes.retryable),this._templating.showRetry(a),!1)},_onSubmitDelete:function(a){var b=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,a,b)},_onSubmitDeleteSuccess:function(){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(a,b,c){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(a),c?(this._templating.setStatusText(a,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(a)):this._removeFileItem(a)},_sendDeleteRequest:function(a){this._templating.hideDeleteButton(a),this._templating.showSpinner(a),this._templating.setStatusText(a,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(a){var b,c=this.getName(a),d=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,c),e=(this.getUuid(a),arguments),f=this;b=this._options.showConfirm(d),qq.isGenericPromise(b)?b.then(function(){f._sendDeleteRequest.apply(f,e)}):b!==!1&&f._sendDeleteRequest.apply(f,e)},_addToList:function(a,b,c){var d,e,f=0,g=this._handler.isProxied(a)&&this._options.scaling.hideScaled;g||(this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(f=this._filesInBatchAddedToUi-1),d={index:f}),c||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(e=this.getUploads({id:a}),this._handledProxyGroup=this._handledProxyGroup||e.proxyGroupId,e.proxyGroupId===this._handledProxyGroup&&e.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),this._templating.addFile(a,this._options.formatFileName(b),d),c?this._thumbnailUrls[a]&&this._templating.updateThumbnail(a,this._thumbnailUrls[a],!0):this._templating.generatePreview(a,this.getFile(a)),this._filesInBatchAddedToUi+=1,(c||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(a))},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(a,b,c){var d=this.getSize(a),e=this._formatSize(d);d>=0&&(void 0!==b&&void 0!==c&&(e=this._formatProgress(b,c)),this._templating.updateSize(a,e))},_formatProgress:function(a,b){function c(a,b){d=d.replace(a,b)}var d=this._options.text.formatProgress;return c("{percent}",Math.round(100*(a/b))),c("{total_size}",this._formatSize(b)),d},_controlFailureTextDisplay:function(a,b){var c,d,e;c=this._options.failedUploadTextDisplay.mode,d=this._options.failedUploadTextDisplay.responseProperty,"custom"===c?(e=b[d],e||(e=this._options.text.failUpload),this._templating.setStatusText(a,e),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(a,e)):"default"===c?this._templating.setStatusText(a,this._options.text.failUpload):"none"!==c&&this.log("failedUploadTextDisplay.mode value of '"+c+"' is not valid","warn")},_showTooltip:function(a,b){this._templating.getFileContainer(a).title=b},_showCancelLink:function(a){(!this._options.disableCancelForFormUploads||qq.supportedFeatures.ajaxUploading)&&this._templating.showCancel(a)},_itemError:function(){var a=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(a)},_batchError:function(a){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(a)},_setupPastePrompt:function(){var a=this;this._options.callbacks.onPasteReceived=function(){var b=a._options.paste.namePromptMessage,c=a._options.paste.defaultName;return a._options.showPrompt(b,c)}},_fileOrBlobRejected:function(){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(a){this._totalFilesInBatch=a.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(a){var b=this._thumbnailUrls[a],c=this.getUploads({id:a}).status;c===qq.status.DELETED||!b&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(a,b)},_addCannedFile:function(){var a=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(a,this.getName(a),!0),this._templating.hideSpinner(a),this._templating.hideCancel(a),this._markFileAsSuccessful(a),a},_setSize:function(a,b){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(a,this._formatSize(b))}}}(),qq.FineUploader=function(a,b){"use strict";var c=this;this._parent=b?qq[b].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:{maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(a){return c._templating.hasDialog("alert")?c._templating.showDialog("alert",a):(setTimeout(function(){window.alert(a)},0),void 0)},showConfirm:function(a){return c._templating.hasDialog("confirm")?c._templating.showDialog("confirm",a):window.confirm(a)},showPrompt:function(a,b){return c._templating.hasDialog("prompt")?c._templating.showDialog("prompt",a,b):window.prompt(a,b)}},!0),qq.extend(this._options,a,!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()}).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(a){"use strict";var b,c,d,e,f,g,h,i,j="qq-file-id",k="qq-file-id-",l="qq-max-size",m="qq-server-scale",n="qq-hide-dropzone",o="qq-drop-area-text",p="qq-in-progress",q=!1,r=0,s=!1,t=[],u=-1,v={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"}},w={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={},y=new qq.Promise,z=new qq.Promise,A=function(){var a=v.placeholders.thumbnailNotAvailable,c=v.placeholders.waitingForThumbnail,d={maxSize:u,scale:i};h&&(a?v.imageGenerator.generate(a,new Image,d).then(function(a){y.success(a)},function(){y.failure(),b("Problem loading 'not available' placeholder image at "+a,"error")}):y.failure(),c?v.imageGenerator.generate(c,new Image,d).then(function(a){z.success(a)},function(){z.failure(),b("Problem loading 'waiting for thumbnail' placeholder image at "+c,"error")}):z.failure())},B=function(a){var b=new qq.Promise;return z.then(function(c){U(c,a),a.src?b.success():(a.src=c.src,a.onload=function(){a.onload=null,_(a),b.success()})},function(){T(a),b.success()}),b},C=function(a,c,d){var e=S(a);return b("Generating new thumbnail for "+a),c.qqThumbnailId=a,v.imageGenerator.generate(c,e,d).then(function(){r++,_(e),x[a].success()},function(){x[a].failure(),v.placeholders.waitUntilUpdate||V(a,e)})},D=function(){if(t.length){s=!0;var a=t.shift();a.update?Z(a):Y(a)}else s=!1},E=function(a){return R(K(a),w.cancel)},F=function(a){return R(K(a),w.continueButton)},G=function(a){return R(f,w[a+"Dialog"])},H=function(a){return R(K(a),w.deleteButton)},I=function(){return R(f,w.dropProcessing)},J=function(a){return R(K(a),w.editNameIcon)},K=function(a){return qq(g).getByClass(k+a)[0]},L=function(a){return R(K(a),w.file)},M=function(a){return R(K(a),w.pause)},N=function(a){return null==a?R(f,w.totalProgressBarContainer)||R(f,w.totalProgressBar):R(K(a),w.progressBarContainer)||R(K(a),w.progressBar)},O=function(a){return R(K(a),w.retry)},P=function(a){return R(K(a),w.size)},Q=function(a){return R(K(a),w.spinner)},R=function(a,b){return a&&qq(a).getByClass(b)[0]},S=function(a){return h&&R(K(a),w.thumbnail)},T=function(a){a&&qq(a).addClass(v.classes.hide)},U=function(a,b){var c=a.style.maxWidth,d=a.style.maxHeight;d&&c&&!b.style.maxWidth&&!b.style.maxHeight&&qq(b).css({maxWidth:c,maxHeight:d})},V=function(a,b){var c=x[a]||(new qq.Promise).failure(),d=new qq.Promise;return y.then(function(a){c.then(function(){d.success()},function(){U(a,b),b.onload=function(){b.onload=null,d.success()},b.src=a.src,_(b)})}),d},W=function(){var a,e,f,g,j,k,p,q,r,s,t;if(b("Parsing template"),null==v.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(v.templateIdOrEl)){if(a=document.getElementById(v.templateIdOrEl),null===a)throw new Error(qq.format("Cannot find template script at ID '{}'!",v.templateIdOrEl));e=a.innerHTML}else{if(void 0===v.templateIdOrEl.innerHTML)throw new Error("You have specified an invalid value for the template option! It must be an ID or an Element.");e=v.templateIdOrEl.innerHTML}if(e=qq.trimStr(e),g=document.createElement("div"),g.appendChild(qq.toElement(e)),t=qq(g).getByClass(w.uploader)[0],v.button&&(k=qq(g).getByClass(w.button)[0],k&&qq(k).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(r=qq(g).getByClass(w.dropProcessing)[0],r&&qq(r).remove()),p=qq(g).getByClass(w.drop)[0],p&&!qq.DragAndDrop&&(b("DnD module unavailable.","info"),qq(p).remove()),qq.supportedFeatures.fileDrop?qq(t).hasAttribute(o)&&p&&(s=qq(p).getByClass(w.dropText)[0],s&&qq(s).remove()):(t.removeAttribute(o),p&&qq(p).hasAttribute(n)&&qq(p).css({display:"none"})),q=qq(g).getByClass(w.thumbnail)[0],h?q&&(u=parseInt(q.getAttribute(l)),u=u>0?u:null,i=qq(q).hasAttribute(m)):q&&qq(q).remove(),h=h&&q,c=qq(g).getByClass(w.editFilenameInput).length>0,d=qq(g).getByClass(w.retry).length>0,f=qq(g).getByClass(w.list)[0],null==f)throw new Error("Could not find the file list container in the template!");return j=f.innerHTML,f.innerHTML="",g.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),b("Template parsing complete"),{template:qq.trimStr(g.innerHTML),fileTemplate:qq.trimStr(j)}},X=function(a,b){var c=g,d=c.firstChild;b>0&&(d=qq(c).children()[b].nextSibling),c.insertBefore(a,d)},Y=function(a){var b=a.id,c=a.optFileOrBlob,d=c&&c.qqThumbnailId,e=S(b),f={maxSize:u,scale:!0,orient:!0};qq.supportedFeatures.imagePreviews?e?v.limits.maxThumbs&&v.limits.maxThumbs<=r?(V(b,e),D()):B(e).done(function(){x[b]=new qq.Promise,x[b].done(function(){setTimeout(D,v.limits.timeBetweenThumbs)}),null!=d?ab(b,d):C(b,c,f)}):D():e&&(B(e),D())},Z=function(a){var b=a.id,c=a.thumbnailUrl,d=a.showWaitingImg,e=S(b),f={maxSize:u,scale:i};if(e)if(c){if(!(v.limits.maxThumbs&&v.limits.maxThumbs<=r))return d&&B(e),v.imageGenerator.generate(c,e,f).then(function(){_(e),r++,setTimeout(D,v.limits.timeBetweenThumbs)},function(){V(b,e),setTimeout(D,v.limits.timeBetweenThumbs)});V(b,e),D()}else V(b,e),D()},$=function(a,b){var c=N(a),d=null==a?w.totalProgressBar:w.progressBar;c&&!qq(c).hasClass(d)&&(c=qq(c).getByClass(d)[0]),c&&(qq(c).css({width:b+"%"}),c.setAttribute("aria-valuenow",b))},_=function(a){a&&qq(a).removeClass(v.classes.hide)},ab=function(a,c){var d=S(a),e=S(c);b(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",a,c,c)),x[c].then(function(){r++,x[a].success(),b(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",c,a)),d.src=e.src,_(d)},function(){x[a].failure(),v.placeholders.waitUntilUpdate||V(a,d)})};qq.extend(v,a),b=v.log,qq.supportedFeatures.imagePreviews||(v.limits.timeBetweenThumbs=0,v.limits.maxThumbs=0),f=v.containerEl,h=void 0!==v.imageGenerator,e=W(),A(),qq.extend(this,{render:function(){b("Rendering template in DOM."),r=0,f.innerHTML=e.template,T(I()),this.hideTotalProgress(),g=v.fileContainerEl||R(f,w.list),b("Template rendering complete")},renderFailure:function(a){var b=qq.toElement(a);f.innerHTML="",f.appendChild(b)},reset:function(){this.render()},clearFiles:function(){g.innerHTML=""},disableCancel:function(){q=!0},addFile:function(a,b,c){var d,h=qq.toElement(e.fileTemplate),i=R(h,w.file),l=R(f,w.uploader);qq(h).addClass(k+a),l.removeAttribute(o),i&&(qq(i).setText(b),i.setAttribute("title",b)),h.setAttribute(j,a),c?X(h,c.index):g.appendChild(h),T(N(a)),T(P(a)),T(H(a)),T(O(a)),T(M(a)),T(F(a)),q&&this.hideCancel(a),d=S(a),d&&!d.src&&z.then(function(a){d.src=a.src,a.style.maxHeight&&a.style.maxWidth&&qq(d).css({maxHeight:a.style.maxHeight,maxWidth:a.style.maxWidth}),_(d)})},removeFile:function(a){qq(K(a)).remove()},getFileId:function(a){var b=a;if(b){for(;null==b.getAttribute(j);)b=b.parentNode;return parseInt(b.getAttribute(j))}},getFileList:function(){return g},markFilenameEditable:function(a){var b=L(a);b&&qq(b).addClass(v.classes.editable)},updateFilename:function(a,b){var c=L(a);c&&(qq(c).setText(b),c.setAttribute("title",b))},hideFilename:function(a){T(L(a))},showFilename:function(a){_(L(a))},isFileName:function(a){return qq(a).hasClass(w.file)},getButton:function(){return v.button||R(f,w.button)},hideDropProcessing:function(){T(I())},showDropProcessing:function(){_(I())},getDropZone:function(){return R(f,w.drop)},isEditFilenamePossible:function(){return c},hideRetry:function(a){T(O(a))},isRetryPossible:function(){return d},showRetry:function(a){_(O(a))},getFileContainer:function(a){return K(a)},showEditIcon:function(a){var b=J(a);b&&qq(b).addClass(v.classes.editable)},hideEditIcon:function(a){var b=J(a);b&&qq(b).removeClass(v.classes.editable)},isEditIcon:function(a){return qq(a).hasClass(w.editNameIcon,!0)},getEditInput:function(a){return R(K(a),w.editFilenameInput)},isEditInput:function(a){return qq(a).hasClass(w.editFilenameInput,!0)},updateProgress:function(a,b,c){var d,e=N(a);e&&c>0&&(d=Math.round(100*(b/c)),100===d?T(e):_(e),$(a,d))
-},updateTotalProgress:function(a,b){this.updateProgress(null,a,b)},hideProgress:function(a){var b=N(a);b&&T(b)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(a){$(a,0),this.hideTotalProgress(a)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(a){if(!q){var b=E(a);b&&qq(b).removeClass(v.classes.hide)}},hideCancel:function(a){T(E(a))},isCancel:function(a){return qq(a).hasClass(w.cancel,!0)},allowPause:function(a){_(M(a)),T(F(a))},uploadPaused:function(a){this.setStatusText(a,v.text.paused),this.allowContinueButton(a),T(Q(a))},hidePause:function(a){T(M(a))},isPause:function(a){return qq(a).hasClass(w.pause,!0)},isContinueButton:function(a){return qq(a).hasClass(w.continueButton,!0)},allowContinueButton:function(a){_(F(a)),T(M(a))},uploadContinued:function(a){this.setStatusText(a,""),this.allowPause(a),_(Q(a))},showDeleteButton:function(a){_(H(a))},hideDeleteButton:function(a){T(H(a))},isDeleteButton:function(a){return qq(a).hasClass(w.deleteButton,!0)},isRetry:function(a){return qq(a).hasClass(w.retry,!0)},updateSize:function(a,b){var c=P(a);c&&(_(c),qq(c).setText(b))},setStatusText:function(a,b){var c=R(K(a),w.statusText);c&&(null==b?qq(c).clearText():qq(c).setText(b))},hideSpinner:function(a){qq(K(a)).removeClass(p),T(Q(a))},showSpinner:function(a){qq(K(a)).addClass(p),_(Q(a))},generatePreview:function(a,b){t.push({id:a,optFileOrBlob:b}),!s&&D()},updateThumbnail:function(a,b,c){t.push({update:!0,id:a,thumbnailUrl:b,showWaitingImg:c}),!s&&D()},hasDialog:function(a){return qq.supportedFeatures.dialogElement&&!!G(a)},showDialog:function(a,b,c){var d=G(a),e=R(d,w.dialogMessage),f=d.getElementsByTagName("INPUT")[0],g=R(d,w.dialogCancelButton),h=R(d,w.dialogOkButton),i=new qq.Promise,j=function(){g.removeEventListener("click",k),h&&h.removeEventListener("click",l),i.failure()},k=function(){g.removeEventListener("click",k),d.close()},l=function(){d.removeEventListener("close",j),h.removeEventListener("click",l),d.close(),i.success(f&&f.value)};return d.addEventListener("close",j),g.addEventListener("click",k),h&&h.addEventListener("click",l),f&&(f.value=c),e.textContent=b,d.showModal(),i}})},qq.s3=qq.s3||{},qq.s3.util=qq.s3.util||function(){"use strict";return{AWS_PARAM_PREFIX:"x-amz-meta-",SESSION_TOKEN_PARAM_NAME:"x-amz-security-token",REDUCED_REDUNDANCY_PARAM_NAME:"x-amz-storage-class",REDUCED_REDUNDANCY_PARAM_VALUE:"REDUCED_REDUNDANCY",SERVER_SIDE_ENCRYPTION_PARAM_NAME:"x-amz-server-side-encryption",SERVER_SIDE_ENCRYPTION_PARAM_VALUE:"AES256",getBucket:function(a){var b,c=[/^(?:https?:\/\/)?([a-z0-9.\-_]+)\.s3(?:-[a-z0-9\-]+)?\.amazonaws\.com/i,/^(?:https?:\/\/)?s3(?:-[a-z0-9\-]+)?\.amazonaws\.com\/([a-z0-9.\-_]+)/i,/^(?:https?:\/\/)?([a-z0-9.\-_]+)/i];return qq.each(c,function(c,d){var e=d.exec(a);return e?(b=e[1],!1):void 0}),b},getPolicy:function(a){var b={},c=[],d=a.bucket,e=a.key,f=a.acl,g=a.type,h=new Date,i=a.expectedStatus,j=a.sessionToken,k=a.params,l=qq.s3.util.getSuccessRedirectAbsoluteUrl(a.successRedirectUrl),m=a.minFileSize,n=a.maxFileSize,o=a.reducedRedundancy,p=a.serverSideEncryption;return b.expiration=qq.s3.util.getPolicyExpirationDate(h),c.push({acl:f}),c.push({bucket:d}),g&&c.push({"Content-Type":g}),i&&c.push({success_action_status:i.toString()}),l&&c.push({success_action_redirect:l}),o&&(c.push({}),c[c.length-1][qq.s3.util.REDUCED_REDUNDANCY_PARAM_NAME]=qq.s3.util.REDUCED_REDUNDANCY_PARAM_VALUE),j&&(c.push({}),c[c.length-1][qq.s3.util.SESSION_TOKEN_PARAM_NAME]=j),p&&(c.push({}),c[c.length-1][qq.s3.util.SERVER_SIDE_ENCRYPTION_PARAM_NAME]=qq.s3.util.SERVER_SIDE_ENCRYPTION_PARAM_VALUE),c.push({key:e}),qq.each(k,function(a,b){var d=qq.s3.util.AWS_PARAM_PREFIX+a,e={};e[d]=encodeURIComponent(b),c.push(e)}),b.conditions=c,qq.s3.util.enforceSizeLimits(b,m,n),b},refreshPolicyCredentials:function(a,b){var c=!1;qq.each(a.conditions,function(a,d){qq.each(d,function(a){a===qq.s3.util.SESSION_TOKEN_PARAM_NAME&&(d[a]=b,c=!0)})}),c||(a.conditions.push({}),a.conditions[a.conditions.length-1][qq.s3.util.SESSION_TOKEN_PARAM_NAME]=b)},generateAwsParams:function(a,b){var c={},d=a.params,e=new qq.Promise,f=qq.s3.util.getPolicy(a),g=a.sessionToken,h=a.type,i=a.key,j=a.accessKey,k=a.acl,l=a.expectedStatus,m=qq.s3.util.getSuccessRedirectAbsoluteUrl(a.successRedirectUrl),n=a.reducedRedundancy,o=a.serverSideEncryption,p=a.log;return c.key=i,c.AWSAccessKeyId=j,h&&(c["Content-Type"]=h),l&&(c.success_action_status=l),m&&(c.success_action_redirect=m),n&&(c[qq.s3.util.REDUCED_REDUNDANCY_PARAM_NAME]=qq.s3.util.REDUCED_REDUNDANCY_PARAM_VALUE),o&&(c[qq.s3.util.SERVER_SIDE_ENCRYPTION_PARAM_NAME]=qq.s3.util.SERVER_SIDE_ENCRYPTION_PARAM_VALUE),g&&(c[qq.s3.util.SESSION_TOKEN_PARAM_NAME]=g),c.acl=k,qq.each(d,function(a,b){var d=qq.s3.util.AWS_PARAM_PREFIX+a;c[d]=encodeURIComponent(b)}),b(f).then(function(a,b,d){c.policy=a.policy,c.signature=a.signature,b&&(c.AWSAccessKeyId=b),d&&(c[qq.s3.util.SESSION_TOKEN_PARAM_NAME]=d),e.success(c)},function(a){a=a||"Can't continue further with request to S3 as we did not receive a valid signature and policy from the server.",p("Policy signing failed. "+a,"error"),e.failure(a)}),e},enforceSizeLimits:function(a,b,c){var d=0>b?0:b,e=0>=c?9007199254740992:c;(b>0||c>0)&&a.conditions.push(["content-length-range",d.toString(),e.toString()])},getPolicyExpirationDate:function(a){if(a.setMinutes(a.getMinutes()+5),Date.prototype.toISOString)return a.toISOString();var b=function(a){var b=String(a);return 1===b.length&&(b="0"+b),b};return a.getUTCFullYear()+"-"+b(a.getUTCMonth()+1)+"-"+b(a.getUTCDate())+"T"+b(a.getUTCHours())+":"+b(a.getUTCMinutes())+":"+b(a.getUTCSeconds())+"."+String((a.getUTCMilliseconds()/1e3).toFixed(3)).slice(2,5)+"Z"},parseIframeResponse:function(a){var b=a.contentDocument||a.contentWindow.document,c=b.location.search,d=/bucket=(.+)&key=(.+)&etag=(.+)/.exec(c);return d?{bucket:d[1],key:d[2],etag:d[3].replace(/%22/g,"")}:void 0},getSuccessRedirectAbsoluteUrl:function(a){if(a){var b,c=document.createElement("div");return qq.ie7()?(c.innerHTML="",b=c.firstChild,b.href):(b=document.createElement("a"),b.href=a,b.href=b.href,b.href)}},encodeQueryStringParam:function(a){var b=encodeURIComponent(a);return b=b.replace(/[!'()]/g,escape),b=b.replace(/\*/g,"%2A"),b.replace(/%20/g,"+")}}}(),function(){"use strict";qq.nonTraditionalBasePublicApi={setUploadSuccessParams:function(a,b){this._uploadSuccessParamsStore.set(a,b)},setUploadSuccessEndpoint:function(a,b){this._uploadSuccessEndpointStore.set(a,b)}},qq.nonTraditionalBasePrivateApi={_onComplete:function(a,b,c,d){var e,f,g=c.success?!0:!1,h=this,i=arguments,j=this._uploadSuccessEndpointStore.get(a),k=this._options.uploadSuccess.customHeaders,l=this._options.uploadSuccess.method,m=this._options.cors,n=new qq.Promise,o=this._uploadSuccessParamsStore.get(a),p=this._paramsStore.get(a),q=function(b){delete h._failedSuccessRequestCallbacks[a],qq.extend(c,b),qq.FineUploaderBasic.prototype._onComplete.apply(h,i),n.success(b)},r=function(f){var g=e;qq.extend(c,f),c&&c.reset&&(g=null),g?h._failedSuccessRequestCallbacks[a]=g:delete h._failedSuccessRequestCallbacks[a],h._onAutoRetry(a,b,c,d,g)||(qq.FineUploaderBasic.prototype._onComplete.apply(h,i),n.failure(f))};return g&&j?(f=new qq.UploadSuccessAjaxRequester({endpoint:j,method:l,customHeaders:k,cors:m,log:qq.bind(this.log,this)}),qq.extend(o,h._getEndpointSpecificParams(a,c,d),!0),p&&qq.extend(o,p,!0),e=qq.bind(function(){f.sendSuccessRequest(a,o).then(q,r)},h),e(),n):qq.FineUploaderBasic.prototype._onComplete.apply(this,arguments)},_manualRetry:function(a){var b=this._failedSuccessRequestCallbacks[a];return qq.FineUploaderBasic.prototype._manualRetry.call(this,a,b)}}}(),function(){"use strict";qq.s3.FineUploaderBasic=function(a){var b={request:{accessKey:null},objectProperties:{acl:"private",bucket:qq.bind(function(a){return qq.s3.util.getBucket(this.getEndpoint(a))},this),key:"uuid",reducedRedundancy:!1,serverSideEncryption:!1},credentials:{accessKey:null,secretKey:null,expiration:null,sessionToken:null},signature:{endpoint:null,customHeaders:{}},uploadSuccess:{endpoint:null,method:"POST",params:{},customHeaders:{}},iframeSupport:{localBlankPagePath:null},chunking:{partSize:5242880},cors:{allowXdr:!0},callbacks:{onCredentialsExpired:function(){}}};qq.extend(b,a,!0),this.setCredentials(b.credentials,!0)||(this._currentCredentials.accessKey=b.request.accessKey),this._aclStore=this._createStore(b.objectProperties.acl),qq.FineUploaderBasic.call(this,b),this._uploadSuccessParamsStore=this._createStore(this._options.uploadSuccess.params),this._uploadSuccessEndpointStore=this._createStore(this._options.uploadSuccess.endpoint),this._failedSuccessRequestCallbacks={},this._cannedKeys={},this._cannedBuckets={},this._buckets={}},qq.extend(qq.s3.FineUploaderBasic.prototype,qq.basePublicApi),qq.extend(qq.s3.FineUploaderBasic.prototype,qq.basePrivateApi),qq.extend(qq.s3.FineUploaderBasic.prototype,qq.nonTraditionalBasePublicApi),qq.extend(qq.s3.FineUploaderBasic.prototype,qq.nonTraditionalBasePrivateApi),qq.extend(qq.s3.FineUploaderBasic.prototype,{getBucket:function(a){return null==this._cannedBuckets[a]?this._buckets[a]:this._cannedBuckets[a]},getKey:function(a){return null==this._cannedKeys[a]?this._handler.getThirdPartyFileId(a):this._cannedKeys[a]},reset:function(){qq.FineUploaderBasic.prototype.reset.call(this),this._failedSuccessRequestCallbacks=[],this._buckets={}},setCredentials:function(a,b){if(a&&a.secretKey){if(!a.accessKey)throw new qq.Error("Invalid credentials: no accessKey");if(!a.expiration)throw new qq.Error("Invalid credentials: no expiration");return this._currentCredentials=qq.extend({},a),qq.isString(a.expiration)&&(this._currentCredentials.expiration=new Date(a.expiration)),!0}if(!b)throw new qq.Error("Invalid credentials parameter!");this._currentCredentials={}},setAcl:function(a,b){this._aclStore.set(a,b)},_createUploadHandler:function(){var a=this,b={aclStore:this._aclStore,getBucket:qq.bind(this._determineBucket,this),getKeyName:qq.bind(this._determineKeyName,this),iframeSupport:this._options.iframeSupport,objectProperties:this._options.objectProperties,signature:this._options.signature,validation:{minSizeLimit:this._options.validation.minSizeLimit,maxSizeLimit:this._options.validation.sizeLimit}};return qq.override(this._endpointStore,function(a){return{get:function(b){var c=a.get(b);return c.indexOf("http")<0?"http://"+c:c}}}),qq.override(this._paramsStore,function(a){return{get:function(b){var c=a.get(b),d={};return qq.each(c,function(a,b){d[a.toLowerCase()]=qq.isFunction(b)?b():b}),d}}}),b.signature.credentialsProvider={get:function(){return a._currentCredentials},onExpired:function(){var b=new qq.Promise,c=a._options.callbacks.onCredentialsExpired();return qq.isGenericPromise(c)?c.then(function(c){try{a.setCredentials(c),b.success()}catch(d){a.log("Invalid credentials returned from onCredentialsExpired callback! ("+d.message+")","error"),b.failure("onCredentialsExpired did not return valid credentials.")}},function(c){a.log("onCredentialsExpired callback indicated failure! ("+c+")","error"),b.failure("onCredentialsExpired callback failed.")}):(a.log("onCredentialsExpired callback did not return a promise!","error"),b.failure("Unexpected return value for onCredentialsExpired.")),b}},qq.FineUploaderBasic.prototype._createUploadHandler.call(this,b,"s3")},_determineBucket:function(a){var b=this._options.objectProperties.bucket,c=new qq.Promise,d=this;return qq.isFunction(b)?(b=b(a),qq.isGenericPromise(b)?c=b:c.success(b)):qq.isString(b)&&c.success(b),c.then(function(b){d._buckets[a]=b},function(b){qq.log("Problem determining bucket for ID "+a+" ("+b+")","error")}),c},_determineKeyName:function(a,b){var c=new qq.Promise,d=this._options.objectProperties.key,e=qq.getExtension(b),f=c.failure,g=function(a,b){var d=a;void 0!==b&&(d+="."+b),c.success(d)};switch(d){case"uuid":g(this.getUuid(a),e);break;case"filename":g(b);break;default:qq.isFunction(d)?this._handleKeynameFunction(d,a,g,f):(this.log(d+" is not a valid value for the s3.keyname option!","error"),f())}return c},_handleKeynameFunction:function(a,b,c,d){var e=this,f=function(a){c(a)},g=function(a){e.log(qq.format("Failed to retrieve key name for {}. Reason: {}",b,a||"null"),"error"),d(a)},h=a.call(this,b);qq.isGenericPromise(h)?h.then(f,g):null==h?g():f(h)},_getEndpointSpecificParams:function(a,b,c){var d={key:this.getKey(a),uuid:this.getUuid(a),name:this.getName(a),bucket:this.getBucket(a)};return c&&c.getResponseHeader("ETag")?d.etag=c.getResponseHeader("ETag"):b.etag&&(d.etag=b.etag),d},_onSubmitDelete:function(a,b){var c={key:this.getKey(a),bucket:this.getBucket(a)};return qq.FineUploaderBasic.prototype._onSubmitDelete.call(this,a,b,c)},_addCannedFile:function(a){var b;if(null==a.s3Key)throw new qq.Error("Did not find s3Key property in server session response. This is required!");return b=qq.FineUploaderBasic.prototype._addCannedFile.apply(this,arguments),this._cannedKeys[b]=a.s3Key,this._cannedBuckets[b]=a.s3Bucket,b}})}(),qq.s3.RequestSigner=function(a){"use strict";function b(a,b,c){var d,e,f=b.responseText,g=j[a],h=g.promise;if(delete j[a],f)try{e=qq.parseJson(f)}catch(i){k.log("Error attempting to parse signature response: "+i,"error")}e&&e.invalid?(c=!0,d="Invalid policy document or request headers!"):e?k.expectingPolicy&&!e.policy?(c=!0,d="Response does not include the base64 encoded policy!"):e.signature||(c=!0,d="Response does not include the signature!"):(c=!0,d="Received an empty or invalid response from the server!"),c?(d&&k.log(d,"error"),h.failure(d)):h.success(e)}function c(a,b,c,d,e,f,g){var h,j="POST",k=[],l="";switch(a){case i.REQUEST_TYPE.MULTIPART_ABORT:j="DELETE",h=qq.format("uploadId={}",f);break;case i.REQUEST_TYPE.MULTIPART_INITIATE:h="uploads";break;case i.REQUEST_TYPE.MULTIPART_COMPLETE:h=qq.format("uploadId={}",f);break;case i.REQUEST_TYPE.MULTIPART_UPLOAD:j="PUT",h=qq.format("partNumber={}&uploadId={}",g,f)}return h=c+"?"+h,qq.each(e,function(a){k.push(a)}),k.sort(),qq.each(k,function(a,b){l+=b+":"+e[b]+"\n"}),{toSign:qq.format("{}\n\n{}\n\n{}/{}/{}",j,d||"",l||"\n",b,h),endOfUrl:h}}function d(a,b,c,d){var g;a.signatureConstructor?(d&&(g=a.signatureConstructor.getHeaders(),g[qq.s3.util.SESSION_TOKEN_PARAM_NAME]=d,a.signatureConstructor.withHeaders(g)),f(a.signatureConstructor.getToSign().stringToSign,b)):(d&&qq.s3.util.refreshPolicyCredentials(a,d),e(a,b,c,d))}function e(a,b,c,d){var e=JSON.stringify(a),f=CryptoJS.enc.Utf8.parse(e),g=CryptoJS.enc.Base64.stringify(f),i=CryptoJS.HmacSHA1(g,h.get().secretKey),j=CryptoJS.enc.Base64.stringify(i);b.success({policy:g,signature:j},c,d)}function f(a,b){var c=CryptoJS.enc.Utf8.parse(a),d=CryptoJS.HmacSHA1(c,h.get().secretKey),e=CryptoJS.enc.Base64.stringify(d);b.success({signature:e})}var g,h,i=this,j={},k={expectingPolicy:!1,method:"POST",signatureSpec:{credentialsProvider:{},endpoint:null,customHeaders:{}},maxConnections:3,paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(){}};qq.extend(k,a,!0),h=k.signatureSpec.credentialsProvider,g=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",method:k.method,contentType:"application/json; charset=utf-8",endpointStore:{get:function(){return k.signatureSpec.endpoint}},paramsStore:k.paramsStore,maxConnections:k.maxConnections,customHeaders:k.signatureSpec.customHeaders,log:k.log,onComplete:b,cors:k.cors})),qq.extend(this,{getSignature:function(a,b){var c=b,e=new qq.Promise;return h.get().secretKey&&window.CryptoJS?h.get().expiration.getTime()>Date.now()?d(b,e):h.onExpired().then(function(){d(b,e,h.get().accessKey,h.get().sessionToken)},function(){k.log("Attempt to update expired credentials apparently failed! Unable to sign request. ","error"),e.failure("Unable to sign request - expired credentials.")}):(k.log("Submitting S3 signature request for "+a),c.signatureConstructor&&(c={headers:c.signatureConstructor.getToSign().stringToSign}),g.initTransport(a).withParams(c).send(),j[a]={promise:e}),e},constructStringToSign:function(a,b,d){var e,f,g,i,j={};return{withHeaders:function(a){return j=a,this},withUploadId:function(a){return e=a,this},withContentType:function(a){return f=a,this},withPartNum:function(a){return g=a,this},getToSign:function(){var k=h.get().sessionToken;return j["x-amz-date"]=(new Date).toUTCString(),k&&(j[qq.s3.util.SESSION_TOKEN_PARAM_NAME]=k),i=c(a,b,d,f,j,e,g),{headers:function(){return f&&(j["Content-Type"]=f),j}(),endOfUrl:i.endOfUrl,stringToSign:i.toSign}},getHeaders:function(){return qq.extend({},j)},getEndOfUrl:function(){return i&&i.endOfUrl}}}})},qq.s3.RequestSigner.prototype.REQUEST_TYPE={MULTIPART_INITIATE:"multipart_initiate",MULTIPART_COMPLETE:"multipart_complete",MULTIPART_ABORT:"multipart_abort",MULTIPART_UPLOAD:"multipart_upload"},qq.UploadSuccessAjaxRequester=function(a){"use strict";function b(a,b,c){var f,g=d[a],h=b.responseText,i={success:!0},j={success:!1};delete d[a],e.log(qq.format("Received the following response body to an upload success request for id {}: {}",a,h));try{f=qq.parseJson(h),c||f&&(f.error||f.success===!1)?(e.log("Upload success request was rejected by the server.","error"),g.failure(qq.extend(f,j))):(e.log("Upload success was acknowledged by the server."),g.success(qq.extend(f,i)))}catch(k){c?(e.log(qq.format("Your server indicated failure in its upload success request response for id {}!",a),"error"),g.failure(j)):(e.log("Upload success was acknowledged by the server."),g.success(i))}}var c,d=[],e={method:"POST",endpoint:null,maxConnections:3,customHeaders:{},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(){}};qq.extend(e,a),c=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",method:e.method,endpointStore:{get:function(){return e.endpoint}},paramsStore:e.paramsStore,maxConnections:e.maxConnections,customHeaders:e.customHeaders,log:e.log,onComplete:b,cors:e.cors})),qq.extend(this,{sendSuccessRequest:function(a,b){var f=new qq.Promise;return e.log("Submitting upload success request/notification for "+a),c.initTransport(a).withParams(b).send(),d[a]=f,f}})},qq.s3.InitiateMultipartAjaxRequester=function(a){"use strict";function b(a){var b,c=g.getBucket(a),d={},f=new qq.Promise,h=g.getKey(a);return d["x-amz-acl"]=g.aclStore.get(a),g.reducedRedundancy&&(d[qq.s3.util.REDUCED_REDUNDANCY_PARAM_NAME]=qq.s3.util.REDUCED_REDUNDANCY_PARAM_VALUE),g.serverSideEncryption&&(d[qq.s3.util.SERVER_SIDE_ENCRYPTION_PARAM_NAME]=qq.s3.util.SERVER_SIDE_ENCRYPTION_PARAM_VALUE),d[qq.s3.util.AWS_PARAM_PREFIX+g.filenameParam]=encodeURIComponent(g.getName(a)),qq.each(g.paramsStore.get(a),function(a,b){d[qq.s3.util.AWS_PARAM_PREFIX+a]=encodeURIComponent(b)}),b=e.constructStringToSign(e.REQUEST_TYPE.MULTIPART_INITIATE,c,h).withContentType(g.getContentType(a)).withHeaders(d),e.getSignature(a,{signatureConstructor:b}).then(function(a){d=b.getHeaders(),d.Authorization="AWS "+g.signatureSpec.credentialsProvider.get().accessKey+":"+a.signature,f.success(d,b.getEndOfUrl())},f.failure),f}function c(a,b,c){var d,e,h,i,j,k=f[a],l=new DOMParser,m=l.parseFromString(b.responseText,"application/xml");delete f[a],c?(j=b.status,e=m.getElementsByTagName("Message"),e.length>0&&(i=e[0].textContent)):(d=m.getElementsByTagName("UploadId"),d.length>0?h=d[0].textContent:i="Upload ID missing from request"),void 0===h?(i?g.log(qq.format("Specific problem detected initiating multipart upload request for {}: '{}'.",a,i),"error"):g.log(qq.format("Unexplained error with initiate multipart upload request for {}. Status code {}.",a,j),"error"),k.failure("Problem initiating upload request.",b)):(g.log(qq.format("Initiate multipart upload request successful for {}. Upload ID is {}",a,h)),k.success(h,b))}var d,e,f={},g={filenameParam:"qqfilename",method:"POST",endpointStore:null,paramsStore:null,signatureSpec:null,aclStore:null,reducedRedundancy:!1,serverSideEncryption:!1,maxConnections:3,getContentType:function(){},getBucket:function(){},getKey:function(){},getName:function(){},log:function(){}};qq.extend(g,a),e=new qq.s3.RequestSigner({signatureSpec:g.signatureSpec,cors:g.cors,log:g.log}),d=qq.extend(this,new qq.AjaxRequester({method:g.method,contentType:null,endpointStore:g.endpointStore,maxConnections:g.maxConnections,allowXRequestedWithAndCacheControl:!1,log:g.log,onComplete:c,successfulResponseCodes:{POST:[200]}})),qq.extend(this,{send:function(a){var c=new qq.Promise;return b(a).then(function(b,e){g.log("Submitting S3 initiate multipart upload request for "+a),f[a]=c,d.initTransport(a).withPath(e).withHeaders(b).send()},c.failure),c}})},qq.s3.CompleteMultipartAjaxRequester=function(a){"use strict";function b(a,b){var c={},d=new qq.Promise,e=h.getBucket(a),g=f.constructStringToSign(f.REQUEST_TYPE.MULTIPART_COMPLETE,e,h.getKey(a)).withUploadId(b).withContentType("application/xml; charset=UTF-8");return f.getSignature(a,{signatureConstructor:g}).then(function(a){c=g.getHeaders(),c.Authorization="AWS "+h.signatureSpec.credentialsProvider.get().accessKey+":"+a.signature,d.success(c,g.getEndOfUrl())},d.failure),d}function c(a,b,c){var d=g[a],e=new DOMParser,f=h.getBucket(a),i=(h.getKey(a),e.parseFromString(b.responseText,"application/xml")),j=i.getElementsByTagName("Bucket"),k=i.getElementsByTagName("Key");delete g[a],h.log(qq.format("Complete response status {}, body = {}",b.status,b.responseText)),c?h.log(qq.format("Complete Multipart Upload request for {} failed with status {}.",a,b.status),"error"):j.length&&k.length?j[0].textContent!==f&&(c=!0,h.log(qq.format("Wrong bucket in response to Complete Multipart Upload request for {}.",a),"error")):(c=!0,h.log(qq.format("Missing bucket and/or key in response to Complete Multipart Upload request for {}.",a),"error")),c?d.failure("Problem combining the file parts!",b):d.success({},b)}function d(a){var b=document.implementation.createDocument(null,"CompleteMultipartUpload",null);return a.sort(function(a,b){return a.part-b.part}),qq.each(a,function(a,c){var d=c.part,e=c.etag,f=b.createElement("Part"),g=b.createElement("PartNumber"),h=b.createTextNode(d),i=b.createTextNode(e),j=b.createElement("ETag");j.appendChild(i),g.appendChild(h),f.appendChild(g),f.appendChild(j),qq(b).children()[0].appendChild(f)}),(new XMLSerializer).serializeToString(b)}var e,f,g={},h={method:"POST",contentType:"text/xml",endpointStore:null,signatureSpec:null,maxConnections:3,getBucket:function(){},getKey:function(){},log:function(){}};qq.extend(h,a),f=new qq.s3.RequestSigner({signatureSpec:h.signatureSpec,cors:h.cors,log:h.log}),e=qq.extend(this,new qq.AjaxRequester({method:h.method,contentType:"application/xml; charset=UTF-8",endpointStore:h.endpointStore,maxConnections:h.maxConnections,allowXRequestedWithAndCacheControl:!1,log:h.log,onComplete:c,successfulResponseCodes:{POST:[200]}})),qq.extend(this,{send:function(a,c,f){var i=new qq.Promise;return b(a,c).then(function(b,c){var j=d(f);h.log("Submitting S3 complete multipart upload request for "+a),g[a]=i,delete b["Content-Type"],e.initTransport(a).withPath(c).withHeaders(b).withPayload(j).send()},i.failure),i}})},qq.s3.AbortMultipartAjaxRequester=function(a){"use strict";function b(a,b){var c={},d=new qq.Promise,g=(f.endpointStore.get(a),f.getBucket(a)),h=e.constructStringToSign(e.REQUEST_TYPE.MULTIPART_ABORT,g,f.getKey(a)).withUploadId(b);return e.getSignature(a,{signatureConstructor:h}).then(function(a){c=h.getHeaders(),c.Authorization="AWS "+f.signatureSpec.credentialsProvider.get().accessKey+":"+a.signature,d.success(c,h.getEndOfUrl())},d.failure),d}function c(a,b,c){var d,e=new DOMParser,g=e.parseFromString(b.responseText,"application/xml"),h=g.getElementsByTagName("Error");f.log(qq.format("Abort response status {}, body = {}",b.status,b.responseText)),c?f.log(qq.format("Abort Multipart Upload request for {} failed with status {}.",a,b.status),"error"):h.length?(c=!0,d=g.getElementsByTagName("Message")[0].textContent,f.log(qq.format("Failed to Abort Multipart Upload request for {}. Error: {}",a,d),"error")):f.log(qq.format("Abort MPU request succeeded for file ID {}.",a))}var d,e,f={method:"DELETE",endpointStore:null,signatureSpec:null,maxConnections:3,getBucket:function(){},getKey:function(){},log:function(){}};qq.extend(f,a),e=new qq.s3.RequestSigner({signatureSpec:f.signatureSpec,cors:f.cors,log:f.log}),d=qq.extend(this,new qq.AjaxRequester({validMethods:["DELETE"],method:f.method,contentType:null,endpointStore:f.endpointStore,maxConnections:f.maxConnections,allowXRequestedWithAndCacheControl:!1,log:f.log,onComplete:c,successfulResponseCodes:{DELETE:[204]}})),qq.extend(this,{send:function(a,c){b(a,c).then(function(b,c){f.log("Submitting S3 Abort multipart upload request for "+a),d.initTransport(a).withPath(c).withHeaders(b).send()})}})},qq.s3.XhrUploadHandler=function(a,b){"use strict";var c=b.getName,d=b.log,e=200,f=a.getBucket,g=a.getKeyName,h=a.filenameParam,i=a.paramsStore,j=a.endpointStore,k=a.aclStore,l=a.objectProperties.reducedRedundancy,m=a.objectProperties.serverSideEncryption,n=a.validation,o=a.signature,p=this,q=a.signature.credentialsProvider,r={combine:function(a){var b=p._getPersistableData(a).uploadId,c=p._getPersistableData(a).etags,d=new qq.Promise;return s.completeMultipart.send(a,b,c).then(d.success,function(b,c){d.failure(u.done(a,c).response,c)}),d},done:function(a,b,c){var d,e=u.response.parse(a,b);e.success&&(d=b.getResponseHeader("ETag"),p._getPersistableData(a).etags||(p._getPersistableData(a).etags=[]),p._getPersistableData(a).etags.push({part:c+1,etag:d}))},initHeaders:function(b,c){var d={},e=(a.endpointStore.get(b),u.bucket.getName(b)),f=u.key.urlSafe(b),g=new qq.Promise,h=s.restSignature.constructStringToSign(s.restSignature.REQUEST_TYPE.MULTIPART_UPLOAD,e,f).withPartNum(c+1).withUploadId(p._getPersistableData(b).uploadId);return s.restSignature.getSignature(b+"."+c,{signatureConstructor:h}).then(function(a){d=h.getHeaders(),d.Authorization="AWS "+q.get().accessKey+":"+a.signature,g.success(d,h.getEndOfUrl())},g.failure),g},put:function(b,c){var d=p._createXhr(b,c),e=p._getChunkData(b,c),f=a.endpointStore.get(b),g=new qq.Promise;return r.initHeaders(b,c).then(function(a,h){var i=f+"/"+h;p._registerProgressHandler(b,c,e.size),u.track(b,d,c).then(g.success,g.failure),d.open("PUT",i,!0),qq.each(a,function(a,b){d.setRequestHeader(a,b)}),d.send(e.blob)},function(){g.failure({error:"Problem signing the chunk!"},d)}),g},send:function(a,b){var c=new qq.Promise;return r.setup(a).then(function(){r.put(a,b).then(c.success,c.failure)},function(a,b){c.failure({error:a},b)}),c},setup:function(a){var b=new qq.Promise,c=p._getPersistableData(a).uploadId,d=new qq.Promise;return c?c instanceof qq.Promise?c.then(function(a){b.success(a)}):b.success(c):(p._getPersistableData(a).uploadId=d,s.initiateMultipart.send(a).then(function(c){p._getPersistableData(a).uploadId=c,d.success(c),b.success(c)},function(c){p._getPersistableData(a).uploadId=null,b.failure(c),d.failure(c)})),b}},s={abortMultipart:new qq.s3.AbortMultipartAjaxRequester({endpointStore:j,signatureSpec:o,cors:a.cors,log:d,getBucket:function(a){return u.bucket.getName(a)},getKey:function(a){return u.key.urlSafe(a)}}),completeMultipart:new qq.s3.CompleteMultipartAjaxRequester({endpointStore:j,signatureSpec:o,cors:a.cors,log:d,getBucket:function(a){return u.bucket.getName(a)},getKey:function(a){return u.key.urlSafe(a)}}),initiateMultipart:new qq.s3.InitiateMultipartAjaxRequester({filenameParam:h,endpointStore:j,paramsStore:i,signatureSpec:o,aclStore:k,reducedRedundancy:l,serverSideEncryption:m,cors:a.cors,log:d,getContentType:function(a){return p._getMimeType(a)},getBucket:function(a){return u.bucket.getName(a)},getKey:function(a){return u.key.urlSafe(a)},getName:function(a){return c(a)}}),policySignature:new qq.s3.RequestSigner({expectingPolicy:!0,signatureSpec:o,cors:a.cors,log:d}),restSignature:new qq.s3.RequestSigner({signatureSpec:o,cors:a.cors,log:d})},t={initParams:function(a){var b=i.get(a);return b[h]=c(a),qq.s3.util.generateAwsParams({endpoint:j.get(a),params:b,type:p._getMimeType(a),bucket:u.bucket.getName(a),key:p.getThirdPartyFileId(a),accessKey:q.get().accessKey,sessionToken:q.get().sessionToken,acl:k.get(a),expectedStatus:e,minFileSize:n.minSizeLimit,maxFileSize:n.maxSizeLimit,reducedRedundancy:l,serverSideEncryption:m,log:d},qq.bind(s.policySignature.getSignature,this,a))},send:function(a){var b=new qq.Promise,c=p._createXhr(a),e=p.getFile(a);return p._registerProgressHandler(a),u.track(a,c).then(b.success,b.failure),t.setup(a,c,e).then(function(b){d("Sending upload request for "+a),c.send(b)},b.failure),b},setup:function(a,b,c){var d=new FormData,e=j.get(a),f=e,g=new qq.Promise;return t.initParams(a).then(function(a){b.open("POST",f,!0),qq.obj2FormData(a,d),d.append("file",c),g.success(d)},function(a){g.failure({error:a})}),g}},u={bucket:{promise:function(a){var b=new qq.Promise,c=p._getFileState(a).bucket;return c?b.success(c):f(a).then(function(c){p._getFileState(a).bucket=c,b.success(c)},b.failure),b},getName:function(a){return p._getFileState(a).bucket}},done:function(a,b){var c=u.response.parse(a,b),e=c.success!==!0;return e&&u.response.shouldReset(c.code)&&(d("This is an unrecoverable error, we must restart the upload entirely on the next retry attempt.","error"),c.reset=!0),{success:!e,response:c}},key:{promise:function(a){var b=new qq.Promise,d=p.getThirdPartyFileId(a);return null==d?(p._setThirdPartyFileId(a,b),g(a,c(a)).then(function(c){p._setThirdPartyFileId(a,c),b.success(c)},function(c){p._setThirdPartyFileId(a,null),b.failure(c)})):qq.isGenericPromise(d)?d.then(b.success,b.failure):b.success(d),b},urlSafe:function(a){return encodeURIComponent(p.getThirdPartyFileId(a))}},response:{parse:function(a,b){var c,f={};try{d(qq.format("Received response status {} with body: {}",b.status,b.responseText)),b.status===e?f.success=!0:(c=u.response.parseError(b.responseText),c&&(f.error=c.message,f.code=c.code))}catch(g){d("Error when attempting to parse xhr response text ("+g.message+")","error")}return f},parseError:function(a){var b,c,d=new DOMParser,e=d.parseFromString(a,"application/xml"),f=e.getElementsByTagName("Error"),g={};return f.length?(b=e.getElementsByTagName("Code"),c=e.getElementsByTagName("Message"),c.length&&(g.message=c[0].textContent),b.length&&(g.code=b[0].textContent),g):void 0},shouldReset:function(a){return"EntityTooSmall"===a||"InvalidPart"===a||"InvalidPartOrder"===a||"NoSuchUpload"===a}},start:function(a,b){var c=new qq.Promise;return u.key.promise(a).then(function(){u.bucket.promise(a).then(function(){null==b?t.send(a).then(c.success,c.failure):r.send(a,b).then(c.success,c.failure)})},function(a){c.failure({error:a})}),c},track:function(a,b,c){var d=new qq.Promise;return b.onreadystatechange=function(){if(4===b.readyState){var e;null==c?(e=u.done(a,b),d[e.success?"success":"failure"](e.response,b)):(r.done(a,b,c),e=u.done(a,b),d[e.success?"success":"failure"](e.response,b))}},d}};qq.extend(this,{uploadChunk:u.start,uploadFile:u.start}),qq.extend(this,new qq.XhrUploadHandler({options:qq.extend({namespace:"s3"},a),proxy:qq.extend({getEndpoint:a.endpointStore.get},b)})),qq.override(this,function(a){return{expunge:function(b){var c=p._getPersistableData(b)&&p._getPersistableData(b).uploadId,d=p._maybeDeletePersistedChunkData(b);void 0!==c&&d&&s.abortMultipart.send(b,c),a.expunge(b)},finalizeChunks:function(a){return r.combine(a)},_getLocalStorageId:function(b){var c=a._getLocalStorageId(b),d=u.bucket.getName(b);return c+"-"+d}}})},qq.s3.FormUploadHandler=function(a,b){"use strict";function c(b,c){var d,e,f,g=a.endpointStore.get(b),i=qq.s3.util.getBucket(g);try{if(d=c.contentDocument||c.contentWindow.document,e=d.body.innerHTML,f=qq.s3.util.parseIframeResponse(c),f.bucket===i&&f.key===qq.s3.util.encodeQueryStringParam(h.getThirdPartyFileId(b)))return!0;l("Response from AWS included an unexpected bucket or key name.","error")}catch(j){l("Error when attempting to parse form upload response ("+j.message+")","error")}return!1}function d(a){var b=p.get(a);return b[o]=j(a),qq.s3.util.generateAwsParams({endpoint:q.get(a),params:b,bucket:h._getFileState(a).bucket,key:h.getThirdPartyFileId(a),accessKey:x.get().accessKey,sessionToken:x.get().sessionToken,acl:r.get(a),minFileSize:u.minSizeLimit,maxFileSize:u.maxSizeLimit,successRedirectUrl:w,reducedRedundancy:s,serverSideEncryption:t,log:l},qq.bind(y.getSignature,this,a))
-}function e(b,c){var e=new qq.Promise,f="POST",i=a.endpointStore.get(b),k=j(b);return d(b).then(function(a){var b=h._initFormForUpload({method:f,endpoint:i,params:a,paramsInBody:!0,targetName:c.name});e.success(b)},function(a){e.failure(a),g(b,c,k,{error:a})}),e}function f(a){var b=h._createIframe(a),d=h.getInput(a),f=new qq.Promise;return e(a,b).then(function(e){e.appendChild(d),h._attachLoadEvent(b,function(d){l("iframe loaded"),d?d.success===!1&&(l("Amazon likely rejected the upload request","error"),f.failure(d)):(d={},d.success=c(a,b),d.success===!1?(l("A success response was received by Amazon, but it was invalid in some way.","error"),f.failure(d)):(qq.extend(d,qq.s3.util.parseIframeResponse(b)),f.success(d))),g(a,b)}),l("Sending upload request for "+a),e.submit(),qq(e).remove()},f.failure),f}function g(a,b){h._detachLoadEvent(a),b&&qq(b).remove()}var h=this,i=b.onUuidChanged,j=b.getName,k=b.getUuid,l=b.log,m=a.getBucket,n=a.getKeyName,o=a.filenameParam,p=a.paramsStore,q=a.endpointStore,r=a.aclStore,s=a.objectProperties.reducedRedundancy,t=a.objectProperties.serverSideEncryption,u=a.validation,v=a.signature,w=a.iframeSupport.localBlankPagePath,x=a.signature.credentialsProvider,y=new qq.s3.RequestSigner({signatureSpec:v,cors:a.cors,log:l});if(void 0===w)throw new Error("successRedirectEndpoint MUST be defined if you intend to use browsers that do not support the File API!");qq.extend(this,new qq.FormUploadHandler({options:{isCors:!1,inputName:"file"},proxy:{onCancel:a.onCancel,onUuidChanged:i,getName:j,getUuid:k,log:l}})),qq.extend(this,{uploadFile:function(a){var b=j(a),c=new qq.Promise;return h.getThirdPartyFileId(a)?h._getFileState(a).bucket?f(a).then(c.success,c.failure):m(a).then(function(b){h._getFileState(a).bucket=b,f(a).then(c.success,c.failure)}):n(a,b).then(function(b){m(a).then(function(d){h._getFileState(a).bucket=d,h._setThirdPartyFileId(a,b),f(a).then(c.success,c.failure)},function(a){c.failure({error:a})})},function(a){c.failure({error:a})}),c}})},function(){"use strict";qq.s3.FineUploader=function(a){var b={failedUploadTextDisplay:{mode:"custom"}};qq.extend(b,a,!0),qq.FineUploader.call(this,b,"s3"),qq.supportedFeatures.ajaxUploading||void 0!==b.iframeSupport.localBlankPagePath||(this._options.element.innerHTML="
You MUST set the localBlankPagePath property of the iframeSupport option since this browser does not support the File API!
")},qq.extend(qq.s3.FineUploader.prototype,qq.s3.FineUploaderBasic.prototype),qq.extend(qq.s3.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.s3.FineUploader.prototype,qq.uiPrivateApi)}(),qq.PasteSupport=function(a){"use strict";function b(a){return a.type&&0===a.type.indexOf("image/")}function c(){f=qq(e.targetElement).attach("paste",function(a){var c=a.clipboardData;c&&qq.each(c.items,function(a,c){if(b(c)){var d=c.getAsFile();e.callbacks.pasteReceived(d)}})})}function d(){f&&f()}var e,f;e={targetElement:null,callbacks:{log:function(){},pasteReceived:function(){}}},qq.extend(e,a),c(),qq.extend(this,{reset:function(){d()}})},qq.DragAndDrop=function(a){"use strict";function b(a,b){var c=Array.prototype.slice.call(a);j.callbacks.dropLog("Grabbed "+a.length+" dropped files."),b.dropDisabled(!1),j.callbacks.processingDroppedFilesComplete(c,b.getElement())}function c(a){var b=new qq.Promise;return a.isFile?a.file(function(c){var d=a.name,e=a.fullPath,f=e.indexOf(d);e=e.substr(0,f),"/"===e.charAt(0)&&(e=e.substr(1)),c.qqPath=e,n.push(c),b.success()},function(c){j.callbacks.dropLog("Problem parsing '"+a.fullPath+"'. FileError code "+c.code+".","error"),b.failure()}):a.isDirectory&&d(a).then(function(a){var d=a.length;qq.each(a,function(a,e){c(e).done(function(){d-=1,0===d&&b.success()})}),a.length||b.success()},function(c){j.callbacks.dropLog("Problem parsing '"+a.fullPath+"'. FileError code "+c.code+".","error"),b.failure()}),b}function d(a,b,c,e){var f=e||new qq.Promise,g=b||a.createReader();return g.readEntries(function(b){var e=c?c.concat(b):b;b.length?setTimeout(function(){d(a,g,e,f)},0):f.success(e)},f.failure),f}function e(a,b){var d=[],e=new qq.Promise;return j.callbacks.processingDroppedFiles(),b.dropDisabled(!0),a.files.length>1&&!j.allowMultipleItems?(j.callbacks.processingDroppedFilesComplete([]),j.callbacks.dropError("tooManyFilesError",""),b.dropDisabled(!1),e.failure()):(n=[],qq.isFolderDropSupported(a)?qq.each(a.items,function(a,b){var f=b.webkitGetAsEntry();f&&(f.isFile?n.push(b.getAsFile()):d.push(c(f).done(function(){d.pop(),0===d.length&&e.success()})))}):n=a.files,0===d.length&&e.success()),e}function f(a){var c=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:k,element:a,onEnter:function(b){qq(a).addClass(j.classes.dropActive),b.stopPropagation()},onLeaveNotDescendants:function(){qq(a).removeClass(j.classes.dropActive)},onDrop:function(a){e(a.dataTransfer,c).then(function(){b(n,c)},function(){j.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return o.addDisposer(function(){c.dispose()}),qq(a).hasAttribute(l)&&qq(a).hide(),m.push(c),c}function g(a){var b;return qq.each(a.dataTransfer.types,function(a,c){return"Files"===c?(b=!0,!1):void 0}),b}function h(a){return qq.firefox()?!a.relatedTarget:qq.safari()?a.x<0||a.y<0:0===a.x&&0===a.y}function i(){var a=j.dropZoneElements,b=function(){setTimeout(function(){qq.each(a,function(a,b){qq(b).hasAttribute(l)&&qq(b).hide(),qq(b).removeClass(j.classes.dropActive)})},10)};qq.each(a,function(b,c){var d=f(c);a.length&&qq.supportedFeatures.fileDrop&&o.attach(document,"dragenter",function(b){!d.dropDisabled()&&g(b)&&qq.each(a,function(a,b){b instanceof HTMLElement&&qq(b).hasAttribute(l)&&qq(b).css({display:"block"})})})}),o.attach(document,"dragleave",function(a){h(a)&&b()}),o.attach(qq(document).children()[0],"mouseenter",function(){b()}),o.attach(document,"drop",function(a){a.preventDefault(),b()}),o.attach(document,k,b)}var j,k="qq-hidezones",l="qq-hide-dropzone",m=[],n=[],o=new qq.DisposeSupport;j={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(j,a,!0),i(),qq.extend(this,{setupExtraDropzone:function(a){j.dropZoneElements.push(a),f(a)},removeDropzone:function(a){var b,c=j.dropZoneElements;for(b in c)if(c[b]===a)return c.splice(b,1)},dispose:function(){o.dispose(),qq.each(m,function(a,b){b.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(){},dropError:function(a,b){qq.log("Drag & drop error code '"+a+" with these specifics: '"+b+"'","error")},dropLog:function(a,b){qq.log(a,b)}}},qq.UploadDropZone=function(a){"use strict";function b(){return qq.safari()||qq.firefox()&&qq.windows()}function c(){k||(b?l.attach(document,"dragover",function(a){a.preventDefault()}):l.attach(document,"dragover",function(a){a.dataTransfer&&(a.dataTransfer.dropEffect="none",a.preventDefault())}),k=!0)}function d(a){if(!qq.supportedFeatures.fileDrop)return!1;var b,c=a.dataTransfer,d=qq.safari();return b=qq.ie()&&qq.supportedFeatures.fileDrop?!0:"none"!==c.effectAllowed,c&&b&&(c.files||!d&&c.types.contains&&c.types.contains("Files"))}function e(a){return void 0!==a&&(j=a),j}function f(){function a(){b=document.createEvent("Event"),b.initEvent(h.HIDE_ZONES_EVENT_NAME,!0,!0)}var b;if(window.CustomEvent)try{b=new CustomEvent(h.HIDE_ZONES_EVENT_NAME)}catch(c){a()}else a();document.dispatchEvent(b)}function g(){l.attach(i,"dragover",function(a){if(d(a)){var b=qq.ie()&&qq.supportedFeatures.fileDrop?null:a.dataTransfer.effectAllowed;a.dataTransfer.dropEffect="move"===b||"linkMove"===b?"move":"copy",a.stopPropagation(),a.preventDefault()}}),l.attach(i,"dragenter",function(a){if(!e()){if(!d(a))return;h.onEnter(a)}}),l.attach(i,"dragleave",function(a){if(d(a)){h.onLeave(a);var b=document.elementFromPoint(a.clientX,a.clientY);qq(this).contains(b)||h.onLeaveNotDescendants(a)}}),l.attach(i,"drop",function(a){if(!e()){if(!d(a))return;a.preventDefault(),a.stopPropagation(),h.onDrop(a),f()}})}var h,i,j,k,l=new qq.DisposeSupport;h={element:null,onEnter:function(){},onLeave:function(){},onLeaveNotDescendants:function(){},onDrop:function(){}},qq.extend(h,a),i=h.element,c(),g(),qq.extend(this,{dropDisabled:function(a){return e(a)},dispose:function(){l.dispose()},getElement:function(){return i}})},qq.DeleteFileAjaxRequester=function(a){"use strict";function b(){return"POST"===d.method.toUpperCase()?{_method:"DELETE"}:{}}var c,d={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(){},onDelete:function(){},onDeleteComplete:function(){}};qq.extend(d,a),c=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:d.method,endpointStore:d.endpointStore,paramsStore:d.paramsStore,mandatedParams:b(),maxConnections:d.maxConnections,customHeaders:function(a){return d.customHeaders.get(a)},log:d.log,onSend:d.onDelete,onComplete:d.onDeleteComplete,cors:d.cors})),qq.extend(this,{sendDelete:function(a,b,e){var f=e||{};d.log("Submitting delete file request for "+a),"DELETE"===d.method?c.initTransport(a).withPath(b).withParams(f).send():(f[d.uuidParamName]=b,c.initTransport(a).withParams(f).send())}})},function(){function a(a){var b,c=a.naturalWidth,d=a.naturalHeight,e=document.createElement("canvas");return c*d>1048576?(e.width=e.height=1,b=e.getContext("2d"),b.drawImage(a,-c+1,0),0===b.getImageData(0,0,1,1).data[3]):!1}function b(a,b,c){var d,e,f,g,h=document.createElement("canvas"),i=0,j=c,k=c;for(h.width=1,h.height=c,d=h.getContext("2d"),d.drawImage(a,0,0),e=d.getImageData(0,0,1,c).data;k>i;)f=e[4*(k-1)+3],0===f?j=k:i=k,k=j+i>>1;return g=k/c,0===g?1:g}function c(a,b,c){var d=document.createElement("canvas"),f=b.mime||"image/jpeg";return e(a,d,b,c),d.toDataURL(f,b.quality||.8)}function d(a){var b=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");return a.origHeight*a.origWidth>b?{newHeight:Math.round(Math.sqrt(b*(a.origHeight/a.origWidth))),newWidth:Math.round(Math.sqrt(b*(a.origWidth/a.origHeight)))}:void 0}function e(c,e,g,h){var i,j=c.naturalWidth,k=c.naturalHeight,l=g.width,m=g.height,n=e.getContext("2d");n.save(),qq.supportedFeatures.unlimitedScaledImageSize||(i=d({origWidth:l,origHeight:m}),i&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",l,m,i.newWidth,i.newHeight),"warn"),l=i.newWidth,m=i.newHeight)),f(e,l,m,g.orientation),qq.ios()?function(){a(c)&&(j/=2,k/=2);var d,e,f,g=1024,i=document.createElement("canvas"),o=h?b(c,j,k):1,p=Math.ceil(g*l/j),q=Math.ceil(g*m/k/o),r=0,s=0;for(i.width=i.height=g,d=i.getContext("2d");k>r;){for(e=0,f=0;j>e;)d.clearRect(0,0,g,g),d.drawImage(c,-e,-r),n.drawImage(i,0,0,g,g,f,s,p,q),e+=g,f+=p;r+=g,s+=q}n.restore(),i=d=null}():n.drawImage(c,0,0,l,m),e.qqImageRendered&&e.qqImageRendered()}function f(a,b,c,d){switch(d){case 5:case 6:case 7:case 8:a.width=c,a.height=b;break;default:a.width=b,a.height=c}var e=a.getContext("2d");switch(d){case 2:e.translate(b,0),e.scale(-1,1);break;case 3:e.translate(b,c),e.rotate(Math.PI);break;case 4:e.translate(0,c),e.scale(1,-1);break;case 5:e.rotate(.5*Math.PI),e.scale(1,-1);break;case 6:e.rotate(.5*Math.PI),e.translate(0,-c);break;case 7:e.rotate(.5*Math.PI),e.translate(b,-c),e.scale(-1,1);break;case 8:e.rotate(-.5*Math.PI),e.translate(-b,0)}}function g(a,b){var c=this;window.Blob&&a instanceof Blob&&function(){var b=new Image,d=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;if(!d)throw Error("No createObjectURL function found to create blob url");b.src=d.createObjectURL(a),c.blob=a,a=b}(),a.naturalWidth||a.naturalHeight||(a.onload=function(){var a=c.imageLoadListeners;a&&(c.imageLoadListeners=null,setTimeout(function(){for(var b=0,c=a.length;c>b;b++)a[b]()},0))},a.onerror=b,this.imageLoadListeners=[]),this.srcImage=a}g.prototype.render=function(a,b){b=b||{};var d,f=this,g=this.srcImage.naturalWidth,h=this.srcImage.naturalHeight,i=b.width,j=b.height,k=b.maxWidth,l=b.maxHeight,m=!this.blob||"image/jpeg"===this.blob.type,n=a.tagName.toLowerCase();return this.imageLoadListeners?(this.imageLoadListeners.push(function(){f.render(a,b)}),void 0):(i&&!j?j=h*i/g<<0:j&&!i?i=g*j/h<<0:(i=g,j=h),k&&i>k&&(i=k,j=h*i/g<<0),l&&j>l&&(j=l,i=g*j/h<<0),d={width:i,height:j},qq.each(b,function(a,b){d[a]=b}),"img"===n?function(){var b=a.src;a.src=c(f.srcImage,d,m),b===a.src&&a.onload()}():"canvas"===n&&e(this.srcImage,a,d,m),"function"==typeof this.onrender&&this.onrender(a),void 0)},qq.MegaPixImage=g}(),qq.ImageGenerator=function(a){"use strict";function b(a){return"img"===a.tagName.toLowerCase()}function c(a){return"canvas"===a.tagName.toLowerCase()}function d(){return void 0!==(new Image).crossOrigin}function e(){var a=document.createElement("canvas");return a.getContext&&a.getContext("2d")}function f(a){var b=a.split("/"),c=b[b.length-1],d=qq.getExtension(c);switch(d=d&&d.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 g(a){var b,c,d,e=document.createElement("a");return e.href=a,b=e.protocol,d=e.port,c=e.hostname,b.toLowerCase()!==window.location.protocol.toLowerCase()?!0:c.toLowerCase()!==window.location.hostname.toLowerCase()?!0:d===window.location.port||qq.ie()?!1:!0}function h(b,c){b.onload=function(){b.onload=null,b.onerror=null,c.success(b)},b.onerror=function(){b.onload=null,b.onerror=null,a("Problem drawing thumbnail!","error"),c.failure(b,"Problem drawing thumbnail!")}}function i(a,b){a.qqImageRendered=function(){b.success(a)}}function j(d,e){var f=b(d)||c(d);return b(d)?h(d,e):c(d)?i(d,e):(e.failure(d),a(qq.format("Element container of type {} is not supported!",d.tagName),"error")),f}function k(b,c,d){var e=new qq.Promise,f=new qq.Identify(b,a),g=d.maxSize,h=null==d.orient?!0:d.orient,i=function(){c.onerror=null,c.onload=null,a("Could not render preview, file may be too large!","error"),e.failure(c,"Browser cannot render image!")};return f.isPreviewable().then(function(d){var f={parse:function(){return(new qq.Promise).success()}},k=h?new qq.Exif(b,a):f,l=new qq.MegaPixImage(b,i);j(c,e)&&k.parse().then(function(a){var b=a&&a.Orientation;l.render(c,{maxWidth:g,maxHeight:g,orientation:b,mime:d})},function(b){a(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",b)),l.render(c,{maxWidth:g,maxHeight:g,mime:d})})},function(){a("Not previewable"),e.failure(c,"Not previewable")}),e}function l(a,b,c,d){var e=new Image,h=new qq.Promise;j(e,h),g(a)&&(e.crossOrigin="anonymous"),e.src=a,h.then(function(){j(b,c);var g=new qq.MegaPixImage(e);g.render(b,{maxWidth:d,maxHeight:d,mime:f(a)})},c.failure)}function m(a,b,c,d){j(b,c),qq(b).css({maxWidth:d+"px",maxHeight:d+"px"}),b.src=a}function n(a,f,h){var i=new qq.Promise,k=h.scale,n=k?h.maxSize:null;return k&&b(f)?e()?g(a)&&!d()?m(a,f,i,n):l(a,f,i,n):m(a,f,i,n):c(f)?l(a,f,i,n):j(f,i)&&(f.src=a),i}qq.extend(this,{generate:function(b,c,d){return qq.isString(b)?(a("Attempting to update thumbnail based on server response."),n(b,c,d||{})):(a("Attempting to draw client-side image preview."),k(b,c,d||{}))}})},qq.Exif=function(a,b){"use strict";function c(a){for(var b=0,c=0;a.length>0;)b+=parseInt(a.substring(0,2),16)*Math.pow(2,c),a=a.substring(2,a.length),c+=8;return b}function d(b,c){var e=b,f=c;return void 0===e&&(e=2,f=new qq.Promise),qq.readBlobToHex(a,e,4).then(function(a){var b,c=/^ffe([0-9])/.exec(a);c?"1"!==c[1]?(b=parseInt(a.slice(4,8),16),d(e+b+2,f)):f.success(e):f.failure("No EXIF header to be found!")}),f}function e(){var b=new qq.Promise;return qq.readBlobToHex(a,0,6).then(function(a){0!==a.indexOf("ffd8")?b.failure("Not a valid JPEG!"):d().then(function(a){b.success(a)},function(a){b.failure(a)})}),b}function f(b){var c=new qq.Promise;return qq.readBlobToHex(a,b+10,2).then(function(a){c.success("4949"===a)}),c}function g(b,d){var e=new qq.Promise;return qq.readBlobToHex(a,b+18,2).then(function(a){return d?e.success(c(a)):(e.success(parseInt(a,16)),void 0)}),e}function h(b,c){var d=b+20,e=12*c;return qq.readBlobToHex(a,d,e)}function i(a){for(var b=[],c=0;c+24<=a.length;)b.push(a.slice(c,c+24)),c+=24;return b}function j(a,b){var d=16,e=qq.extend([],k),f={};return qq.each(b,function(b,g){var h,i,j,k=g.slice(0,4),m=a?c(k):parseInt(k,16),n=e.indexOf(m);return n>=0&&(i=l[m].name,j=l[m].bytes,h=g.slice(d,d+2*j),f[i]=a?c(h):parseInt(h,16),e.splice(n,1)),0===e.length?!1:void 0}),f}var k=[274],l={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var c=new qq.Promise,d=function(a){b(qq.format("EXIF header parse failed: '{}' ",a)),c.failure(a)};return e().then(function(e){b(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===a.name?"blob":a.name)),f(e).then(function(a){b(qq.format("EXIF Byte order is {} endian",a?"little":"big")),g(e,a).then(function(f){b(qq.format("Found {} APP1 directory entries",f)),h(e,f).then(function(d){var e=i(d),f=j(a,e);b("Successfully parsed some EXIF tags"),c.success(f)},d)},d)},d)},d),c}})},qq.Identify=function(a,b){"use strict";function c(a,b){var c=!1,d=[].concat(a);return qq.each(d,function(a,d){return 0===b.indexOf(d)?(c=!0,!1):void 0}),c}qq.extend(this,{isPreviewable:function(){var d=this,e=new qq.Promise,f=!1,g=void 0===a.name?"blob":a.name;return b(qq.format("Attempting to determine if {} can be rendered in this browser",g)),b("First pass: check type attribute of blob object."),this.isPreviewableSync()?(b("Second pass: check for magic bytes in file header."),qq.readBlobToHex(a,0,4).then(function(a){qq.each(d.PREVIEWABLE_MIME_TYPES,function(b,d){return c(d,a)?(("image/tiff"!==b||qq.supportedFeatures.tiffPreviews)&&(f=!0,e.success(b)),!1):void 0}),b(qq.format("'{}' is {} able to be rendered in this browser",g,f?"":"NOT")),f||e.failure()},function(){b("Error reading file w/ name '"+g+"'. Not able to be rendered in this browser."),e.failure()})):e.failure(),e},isPreviewableSync:function(){var c=a.type,d=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),c)>=0,e=!1,f=void 0===a.name?"blob":a.name;return d&&(e="image/tiff"===c?qq.supportedFeatures.tiffPreviews:!0),!e&&b(f+" is not previewable in this browser per the blob's type attr"),e}})},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(a,b){"use strict";function c(a){var b=!1;return qq.each(a,function(a,c){return c>0?(b=!0,!1):void 0}),b}function d(){var c=new qq.Promise;return new qq.Identify(a,b).isPreviewable().then(function(){var d=new Image,e=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;e?(d.onerror=function(){b("Cannot determine dimensions for image. May be too large.","error"),c.failure()},d.onload=function(){c.success({width:this.width,height:this.height})},d.src=e.createObjectURL(a)):(b("No createObjectURL function available to generate image URL!","error"),c.failure())},c.failure),c}function e(a,b){var c;return qq.each(a,function(a,d){if(d>0){var e=/(max|min)(Width|Height)/.exec(a),f=e[2].charAt(0).toLowerCase()+e[2].slice(1),g=b[f];switch(e[1]){case"min":if(d>g)return c=a,!1;break;case"max":if(g>d)return c=a,!1}}}),c}this.validate=function(a){var f=new qq.Promise;return b("Attempting to validate image."),c(a)?d().then(function(b){var c=e(a,b);c?f.failure(c):f.success()},f.success):f.success(),f}},qq.Session=function(a){"use strict";function b(a){return qq.isArray(a)?!0:(d.log("Session response is not an array.","error"),void 0)}function c(a,c,e,f){var g=!1;c=c&&b(a),c&&qq.each(a,function(a,b){if(null==b.uuid)g=!0,d.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",a),"error");else if(null==b.name)g=!0,d.log(qq.format("Session response item {} did not include a valid name - ignoring.",a),"error");else try{return d.addFileRecord(b),!0}catch(c){g=!0,d.log(c.message,"error")}return!1}),f[c&&!g?"success":"failure"](a,e)}var d={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(){},log:function(){}};qq.extend(d,a,!0),this.refresh=function(){var a=new qq.Promise,b=function(b,d,e){c(b,d,e,a)},e=qq.extend({},d),f=new qq.SessionAjaxRequester(qq.extend(e,{onComplete:b}));return f.queryServer(),a}},qq.SessionAjaxRequester=function(a){"use strict";function b(a,b,c){var e=null;if(null!=b.responseText)try{e=qq.parseJson(b.responseText)}catch(f){d.log("Problem parsing session response: "+f.message,"error"),c=!0}d.onComplete(e,!c,b)}var c,d={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(){},log:function(){}};qq.extend(d,a),c=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return d.endpoint}},customHeaders:d.customHeaders,log:d.log,onComplete:b,cors:d.cors})),qq.extend(this,{queryServer:function(){var a=qq.extend({},d.params);d.log("Session query request."),c.initTransport("sessionRefresh").withParams(a).withCacheBuster().send()}})},qq.FormSupport=function(a,b,c){"use strict";function d(a){a.getAttribute("action")&&(h.newEndpoint=a.getAttribute("action"))}function e(a,b){return!a.checkValidity||a.checkValidity()?!0:(c("Form did not pass validation checks - will not upload.","error"),b(),void 0)}function f(a){var c=a.submit;qq(a).attach("submit",function(d){d=d||window.event,d.preventDefault?d.preventDefault():d.returnValue=!1,e(a,c)&&b()}),a.submit=function(){e(a,c)&&b()}}function g(a){return a&&(qq.isString(a)&&(a=document.getElementById(a)),a&&(c("Attaching to form element."),d(a),i&&f(a))),a}var h=this,i=a.interceptSubmit,j=a.element,k=a.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:k,attachedToForm:!1,getFormInputsAsObject:function(){return null==j?null:h._form2Obj(j)}}),j=g(j),this.attachedToForm=!!j},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(a){"use strict";var b={},c=function(a){var b=["button","image","reset","submit"];return qq.indexOf(b,a.toLowerCase())<0},d=function(a){return qq.indexOf(["checkbox","radio"],a.toLowerCase())>=0},e=function(a){return d(a.type)&&!a.checked?!0:a.disabled&&"hidden"!==a.type.toLowerCase()},f=function(a){var b=null;return qq.each(qq(a).children(),function(a,c){return"option"===c.tagName.toLowerCase()&&c.selected?(b=c.value,!1):void 0}),b};return qq.each(a.elements,function(a,d){if(!qq.isInput(d,!0)&&"textarea"!==d.tagName.toLowerCase()||!c(d.type)||e(d)){if("select"===d.tagName.toLowerCase()&&!e(d)){var g=f(d);null!==g&&(b[d.name]=g)}}else b[d.name]=d.value}),b}}),qq.Scaler=function(a,b){"use strict";var c=a.sendOriginal,d=a.orient,e=a.defaultType,f=a.defaultQuality/100,g=a.failureText,h=a.includeExif,i=this._getSortedSizes(a.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&i.length>0,getFileRecords:function(a,j,k){var l=this,m=[],n=k.blob?k.blob:k,o=new qq.Identify(n,b);return o.isPreviewableSync()?(qq.each(i,function(a,c){var i=l._determineOutputType({defaultType:e,requestedType:c.type,refType:n.type});m.push({uuid:qq.getUniqueId(),name:l._getName(j,{name:c.name,type:i,refType:n.type}),blob:new qq.BlobProxy(n,qq.bind(l._generateScaledImage,l,{maxSize:c.maxSize,orient:d,type:i,quality:f,failedText:g,includeExif:h,log:b}))})}),c&&m.push({uuid:a,name:j,blob:n})):m.push({uuid:a,name:j,blob:n}),m},handleNewFile:function(a,b,c,d,e,f,g,h){var i=this,j=(a.qqButtonId||a.blob&&a.blob.qqButtonId,[]),k=null,l=h.addFileToHandler,m=h.uploadData,n=h.paramsStore,o=qq.getUniqueId();qq.each(i.getFileRecords(c,b,a),function(b,c){var g,h=a,i=d;c.blob instanceof qq.BlobProxy&&(h=c.blob,i=-1),g=m.addFile({uuid:c.uuid,name:c.name,size:i,batchId:f,proxyGroupId:o}),c.blob instanceof qq.BlobProxy?j.push(g):k=g,l(g,h),e.push({id:g,file:h})}),null!==k&&(qq.each(j,function(a,b){var c={qqparentuuid:m.retrieve({id:k}).uuid,qqparentsize:m.retrieve({id:k}).size};c[g]=m.retrieve({id:b}).uuid,m.setParentId(b,k),n.addReadOnly(b,c)}),j.length&&function(){var a={};a[g]=m.retrieve({id:k}).uuid,n.addReadOnly(k,a)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(a,b,c){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var d=new qq.Promise,e=c.log,f=c.getFile(a),g=c.uploadData.retrieve({id:a}),h=g&&g.name,i=g&&g.uuid,j={sendOriginal:!1,orient:b.orient,defaultType:b.type||null,defaultQuality:b.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:b.maxSize}]},k=new qq.Scaler(j,e);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&f?qq.bind(function(){var b=k.getFileRecords(i,h,f)[0];b&&b.blob instanceof qq.BlobProxy?b.blob.create().then(d.success,d.failure):(e(a+" is not a scalable image!","error"),d.failure())},this)():(d.failure(),e("Could not generate requested scaled image for "+a+". "+"Scaling is either not possible in this browser, or the file could not be located.","error")),d},_determineOutputType:function(a){"use strict";var b=a.requestedType,c=a.defaultType,d=a.refType;return c||b?b?qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),b)>=0?"image/tiff"===b?qq.supportedFeatures.tiffPreviews?b:c:b:c:c:"image/jpeg"!==d?"image/png":d},_getName:function(a,b){"use strict";var c=a.lastIndexOf("."),d=b.type||"image/png",e=b.refType,f="",g=qq.getExtension(a),h="";return b.name&&b.name.trim().length&&(h=" ("+b.name+")"),c>=0?(f=a.substr(0,c),e!==d&&(g=d.split("/")[1]),f+=h+"."+g):f=a+h,f},_getSortedSizes:function(a){"use strict";return a=qq.extend([],a),a.sort(function(a,b){return a.maxSize>b.maxSize?1:a.maxSize=0?atob(a.split(",")[1]):decodeURI(a.split(",")[1]),c=a.split(",")[0].split(":")[1].split(";")[0],d=new ArrayBuffer(b.length),e=new Uint8Array(d),qq.each(b,function(a,b){e[a]=b.charCodeAt(0)}),this._createBlob(d,c)},_createBlob:function(a,b){"use strict";var c=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,d=c&&new c;return d?(d.append(a),d.getBlob(b)):new Blob([a],{type:b})}});var ExifRestorer=function(){var a={};return a.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",a.encode64=function(a){var b,c,d,e,f,g="",h="",i="",j=0;do b=a[j++],c=a[j++],h=a[j++],d=b>>2,e=(3&b)<<4|c>>4,f=(15&c)<<2|h>>6,i=63&h,isNaN(c)?f=i=64:isNaN(h)&&(i=64),g=g+this.KEY_STR.charAt(d)+this.KEY_STR.charAt(e)+this.KEY_STR.charAt(f)+this.KEY_STR.charAt(i),b=c=h="",d=e=f=i="";while(ja.length)break}return c},a.decode64=function(a){var b,c,d,e,f,g="",h="",i=0,j=[],k=/[^A-Za-z0-9\+\/\=]/g;if(k.exec(a))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");do d=this.KEY_STR.indexOf(a.charAt(i++)),e=this.KEY_STR.indexOf(a.charAt(i++)),f=this.KEY_STR.indexOf(a.charAt(i++)),h=this.KEY_STR.indexOf(a.charAt(i++)),b=d<<2|e>>4,c=(15&e)<<4|f>>2,g=(3&f)<<6|h,j.push(b),64!=f&&j.push(c),64!=h&&j.push(g),b=c=g="",d=e=f=h="";while(i=0?(c=!1,!1):void 0}),c},j=function(a){m(a,-1,-1),delete c[a]},k=function(a,b,c){(0===b.length||i(b,c))&&(h(e,e),this.reset())},l=function(a){var d=b(a);d>0&&(m(a,0,d),c[a]={loaded:0,total:d})},m=function(a,b,f){var g=c[a]?c[a].loaded:0,i=c[a]?c[a].total:0;-1===b&&-1===f?(d-=g,e-=i):(b&&(d+=b-g),f&&(e+=f-i)),h(d,e)};qq.extend(this,{onAllComplete:k,onStatusChange:function(a,b,c){c===qq.status.CANCELED||c===qq.status.REJECTED?j(a):c===qq.status.SUBMITTING&&l(a)},onIndividualProgress:function(a,b,d){m(a,b,d),c[a]={loaded:b,total:d}},onNewSize:function(a){l(a)},reset:function(){c={},d=0,e=0}})},qq.UiEventHandler=function(a,b){"use strict";function c(a){d.attach(a,e.eventType,function(a){a=a||window.event;var b=a.target||a.srcElement;e.onHandled(b,a)})}var d=new qq.DisposeSupport,e={eventType:"click",attachTo:null,onHandled:function(){}};qq.extend(this,{addHandler:function(a){c(a)},dispose:function(){d.dispose()}}),qq.extend(b,{getFileIdFromItem:function(a){return a.qqFileId},getDisposeSupport:function(){return d}}),qq.extend(e,a),e.attachTo&&c(e.attachTo)},qq.FileButtonsClickHandler=function(a){"use strict";function b(a,b){qq.each(e,function(c,e){var f,g=c.charAt(0).toUpperCase()+c.slice(1);return d.templating["is"+g](a)?(f=d.templating.getFileId(a),qq.preventDefault(b),d.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",d.onGetName(f),f)),e(f),!1):void 0})}var c={},d={templating:null,log:function(){},onDeleteFile:function(){},onCancel:function(){},onRetry:function(){},onPause:function(){},onContinue:function(){},onGetName:function(){}},e={cancel:function(a){d.onCancel(a)},retry:function(a){d.onRetry(a)},deleteButton:function(a){d.onDeleteFile(a)},pause:function(a){d.onPause(a)},continueButton:function(a){d.onContinue(a)}};qq.extend(d,a),d.eventType="click",d.onHandled=b,d.attachTo=d.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(d,c))},qq.FilenameClickHandler=function(a){"use strict";function b(a,b){if(d.templating.isFileName(a)||d.templating.isEditIcon(a)){var e=d.templating.getFileId(a),f=d.onGetUploadStatus(e);f===qq.status.SUBMITTED&&(d.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",d.onGetName(e),e)),qq.preventDefault(b),c.handleFilenameEdit(e,a,!0))}}var c={},d={templating:null,log:function(){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(){},onGetName:function(){}};qq.extend(d,a),d.eventType="click",d.onHandled=b,qq.extend(this,new qq.FilenameEditHandler(d,c))
-},qq.FilenameInputFocusInHandler=function(a,b){"use strict";function c(a){if(d.templating.isEditInput(a)){var c=d.templating.getFileId(a),e=d.onGetUploadStatus(c);e===qq.status.SUBMITTED&&(d.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",d.onGetName(c),c)),b.handleFilenameEdit(c,a))}}var d={templating:null,onGetUploadStatus:function(){},log:function(){}};b||(b={}),d.eventType="focusin",d.onHandled=c,qq.extend(d,a),qq.extend(this,new qq.FilenameEditHandler(d,b))},qq.FilenameInputFocusHandler=function(a){"use strict";a.eventType="focus",a.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(a,{}))},qq.FilenameEditHandler=function(a,b){"use strict";function c(a){var b=h.onGetName(a),c=b.lastIndexOf(".");return c>0&&(b=b.substr(0,c)),b}function d(a){var b=h.onGetName(a);return qq.getExtension(b)}function e(a,b){var c,e=a.value;void 0!==e&&qq.trimStr(e).length>0&&(c=d(b),void 0!==c&&(e=e+"."+c),h.onSetName(b,e)),h.onEditingStatusChange(b,!1)}function f(a,c){b.getDisposeSupport().attach(a,"blur",function(){e(a,c)})}function g(a,c){b.getDisposeSupport().attach(a,"keyup",function(b){var d=b.keyCode||b.which;13===d&&e(a,c)})}var h={templating:null,log:function(){},onGetUploadStatus:function(){},onGetName:function(){},onSetName:function(){},onEditingStatusChange:function(){}};qq.extend(h,a),h.attachTo=h.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(h,b)),qq.extend(b,{handleFilenameEdit:function(a,b,d){var e=h.templating.getEditInput(a);h.onEditingStatusChange(a,!0),e.value=c(a),d&&e.focus(),f(e,a),g(e,a)}})};var CryptoJS=CryptoJS||function(a,b){var c={},d=c.lib={},e=d.Base=function(){function a(){}return{extend:function(b){a.prototype=this;var c=new a;return b&&c.mixIn(b),c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)}),c.init.prototype=c,c.$super=this,c},create:function(){var a=this.extend();return a.init.apply(a,arguments),a},init:function(){},mixIn:function(a){for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}}}(),f=d.WordArray=e.extend({init:function(a,c){a=this.words=a||[],this.sigBytes=c!=b?c:4*a.length},toString:function(a){return(a||h).stringify(this)},concat:function(a){var b=this.words,c=a.words,d=this.sigBytes,e=a.sigBytes;if(this.clamp(),d%4)for(var f=0;e>f;f++){var g=255&c[f>>>2]>>>24-8*(f%4);b[d+f>>>2]|=g<<24-8*((d+f)%4)}else if(c.length>65535)for(var f=0;e>f;f+=4)b[d+f>>>2]=c[f>>>2];else b.push.apply(b,c);return this.sigBytes+=e,this},clamp:function(){var b=this.words,c=this.sigBytes;b[c>>>2]&=4294967295<<32-8*(c%4),b.length=a.ceil(c/4)},clone:function(){var a=e.clone.call(this);return a.words=this.words.slice(0),a},random:function(b){for(var c=[],d=0;b>d;d+=4)c.push(0|4294967296*a.random());return new f.init(c,b)}}),g=c.enc={},h=g.Hex={stringify:function(a){for(var b=a.words,c=a.sigBytes,d=[],e=0;c>e;e++){var f=255&b[e>>>2]>>>24-8*(e%4);d.push((f>>>4).toString(16)),d.push((15&f).toString(16))}return d.join("")},parse:function(a){for(var b=a.length,c=[],d=0;b>d;d+=2)c[d>>>3]|=parseInt(a.substr(d,2),16)<<24-4*(d%8);return new f.init(c,b/2)}},i=g.Latin1={stringify:function(a){for(var b=a.words,c=a.sigBytes,d=[],e=0;c>e;e++){var f=255&b[e>>>2]>>>24-8*(e%4);d.push(String.fromCharCode(f))}return d.join("")},parse:function(a){for(var b=a.length,c=[],d=0;b>d;d++)c[d>>>2]|=(255&a.charCodeAt(d))<<24-8*(d%4);return new f.init(c,b)}},j=g.Utf8={stringify:function(a){try{return decodeURIComponent(escape(i.stringify(a)))}catch(b){throw new Error("Malformed UTF-8 data")}},parse:function(a){return i.parse(unescape(encodeURIComponent(a)))}},k=d.BufferedBlockAlgorithm=e.extend({reset:function(){this._data=new f.init,this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=j.parse(a)),this._data.concat(a),this._nDataBytes+=a.sigBytes},_process:function(b){var c=this._data,d=c.words,e=c.sigBytes,g=this.blockSize,h=4*g,i=e/h;i=b?a.ceil(i):a.max((0|i)-this._minBufferSize,0);var j=i*g,k=a.min(4*j,e);if(j){for(var l=0;j>l;l+=g)this._doProcessBlock(d,l);var m=d.splice(0,j);c.sigBytes-=k}return new f.init(m,k)},clone:function(){var a=e.clone.call(this);return a._data=this._data.clone(),a},_minBufferSize:0});d.Hasher=k.extend({cfg:e.extend(),init:function(a){this.cfg=this.cfg.extend(a),this.reset()},reset:function(){k.reset.call(this),this._doReset()},update:function(a){return this._append(a),this._process(),this},finalize:function(a){a&&this._append(a);var b=this._doFinalize();return b},blockSize:16,_createHelper:function(a){return function(b,c){return new a.init(c).finalize(b)}},_createHmacHelper:function(a){return function(b,c){return new l.HMAC.init(a,c).finalize(b)}}});var l=c.algo={};return c}(Math);!function(){var a=CryptoJS,b=a.lib,c=b.WordArray,d=a.enc;d.Base64={stringify:function(a){var b=a.words,c=a.sigBytes,d=this._map;a.clamp();for(var e=[],f=0;c>f;f+=3)for(var g=255&b[f>>>2]>>>24-8*(f%4),h=255&b[f+1>>>2]>>>24-8*((f+1)%4),i=255&b[f+2>>>2]>>>24-8*((f+2)%4),j=g<<16|h<<8|i,k=0;4>k&&c>f+.75*k;k++)e.push(d.charAt(63&j>>>6*(3-k)));var l=d.charAt(64);if(l)for(;e.length%4;)e.push(l);return e.join("")},parse:function(a){var b=a.length,d=this._map,e=d.charAt(64);if(e){var f=a.indexOf(e);-1!=f&&(b=f)}for(var g=[],h=0,i=0;b>i;i++)if(i%4){var j=d.indexOf(a.charAt(i-1))<<2*(i%4),k=d.indexOf(a.charAt(i))>>>6-2*(i%4);g[h>>>2]|=(j|k)<<24-8*(h%4),h++}return c.create(g,h)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}}(),function(){var a=CryptoJS,b=a.lib,c=b.Base,d=a.enc,e=d.Utf8,f=a.algo;f.HMAC=c.extend({init:function(a,b){a=this._hasher=new a.init,"string"==typeof b&&(b=e.parse(b));var c=a.blockSize,d=4*c;b.sigBytes>d&&(b=a.finalize(b)),b.clamp();for(var f=this._oKey=b.clone(),g=this._iKey=b.clone(),h=f.words,i=g.words,j=0;c>j;j++)h[j]^=1549556828,i[j]^=909522486;f.sigBytes=g.sigBytes=d,this.reset()},reset:function(){var a=this._hasher;a.reset(),a.update(this._iKey)},update:function(a){return this._hasher.update(a),this},finalize:function(a){var b=this._hasher,c=b.finalize(a);b.reset();var d=b.finalize(this._oKey.clone().concat(c));return d}})}(),function(){var a=CryptoJS,b=a.lib,c=b.WordArray,d=b.Hasher,e=a.algo,f=[],g=e.SHA1=d.extend({_doReset:function(){this._hash=new c.init([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(a,b){for(var c=this._hash.words,d=c[0],e=c[1],g=c[2],h=c[3],i=c[4],j=0;80>j;j++){if(16>j)f[j]=0|a[b+j];else{var k=f[j-3]^f[j-8]^f[j-14]^f[j-16];f[j]=k<<1|k>>>31}var l=(d<<5|d>>>27)+i+f[j];l+=20>j?(e&g|~e&h)+1518500249:40>j?(e^g^h)+1859775393:60>j?(e&g|e&h|g&h)-1894007588:(e^g^h)-899497514,i=h,h=g,g=e<<30|e>>>2,e=d,d=l}c[0]=0|c[0]+d,c[1]=0|c[1]+e,c[2]=0|c[2]+g,c[3]=0|c[3]+h,c[4]=0|c[4]+i},_doFinalize:function(){var a=this._data,b=a.words,c=8*this._nDataBytes,d=8*a.sigBytes;return b[d>>>5]|=128<<24-d%32,b[(d+64>>>9<<4)+14]=Math.floor(c/4294967296),b[(d+64>>>9<<4)+15]=c,a.sigBytes=4*b.length,this._process(),this._hash},clone:function(){var a=d.clone.call(this);return a._hash=this._hash.clone(),a}});a.SHA1=d._createHelper(g),a.HmacSHA1=d._createHmacHelper(g)}();
-/*! 2015-06-09 */
+var qq=function(a){"use strict";return{hide:function(){return a.style.display="none",this},attach:function(b,c){return a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent&&a.attachEvent("on"+b,c),function(){qq(a).detach(b,c)}},detach:function(b,c){return a.removeEventListener?a.removeEventListener(b,c,!1):a.attachEvent&&a.detachEvent("on"+b,c),this},contains:function(b){return b?a===b?!0:a.contains?a.contains(b):!!(8&b.compareDocumentPosition(a)):!1},insertBefore:function(b){return b.parentNode.insertBefore(a,b),this},remove:function(){return a.parentNode.removeChild(a),this},css:function(b){if(null==a.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=b.opacity&&"string"!=typeof a.style.opacity&&"undefined"!=typeof a.filters&&(b.filter="alpha(opacity="+Math.round(100*b.opacity)+")"),qq.extend(a.style,b),this},hasClass:function(b,c){var d=new RegExp("(^| )"+b+"( |$)");return d.test(a.className)||!(!c||!d.test(a.parentNode.className))},addClass:function(b){return qq(a).hasClass(b)||(a.className+=" "+b),this},removeClass:function(b){var c=new RegExp("(^| )"+b+"( |$)");return a.className=a.className.replace(c," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(b){var c,d=[];return a.querySelectorAll?a.querySelectorAll("."+b):(c=a.getElementsByTagName("*"),qq.each(c,function(a,c){qq(c).hasClass(b)&&d.push(c)}),d)},children:function(){for(var b=[],c=a.firstChild;c;)1===c.nodeType&&b.push(c),c=c.nextSibling;return b},setText:function(b){return a.innerText=b,a.textContent=b,this},clearText:function(){return qq(a).setText("")},hasAttribute:function(b){var c;return a.hasAttribute?a.hasAttribute(b)?null==/^false$/i.exec(a.getAttribute(b)):!1:(c=a[b],void 0===c?!1:null==/^false$/i.exec(c))}}};!function(){"use strict";qq.canvasToBlob=function(a,b,c){return qq.dataUriToBlob(a.toDataURL(b,c))},qq.dataUriToBlob=function(a){var b,c,d,e,f=function(a,b){var c=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,d=c&&new c;return d?(d.append(a),d.getBlob(b)):new Blob([a],{type:b})};return c=a.split(",")[0].indexOf("base64")>=0?atob(a.split(",")[1]):decodeURI(a.split(",")[1]),e=a.split(",")[0].split(":")[1].split(";")[0],b=new ArrayBuffer(c.length),d=new Uint8Array(b),qq.each(c,function(a,b){d[a]=b.charCodeAt(0)}),f(b,e)},qq.log=function(a,b){window.console&&(b&&"info"!==b?window.console[b]?window.console[b](a):window.console.log("<"+b+"> "+a):window.console.log(a))},qq.isObject=function(a){return a&&!a.nodeType&&"[object Object]"===Object.prototype.toString.call(a)},qq.isFunction=function(a){return"function"==typeof a},qq.isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)||a&&window.ArrayBuffer&&a.buffer&&a.buffer.constructor===ArrayBuffer},qq.isItemList=function(a){return"[object DataTransferItemList]"===Object.prototype.toString.call(a)},qq.isNodeList=function(a){return"[object NodeList]"===Object.prototype.toString.call(a)||a.item&&a.namedItem},qq.isString=function(a){return"[object String]"===Object.prototype.toString.call(a)},qq.trimStr=function(a){return String.prototype.trim?a.trim():a.replace(/^\s+|\s+$/g,"")},qq.format=function(a){var b=Array.prototype.slice.call(arguments,1),c=a,d=c.indexOf("{}");return qq.each(b,function(a,b){var e=c.substring(0,d),f=c.substring(d+2);return c=e+b+f,d=c.indexOf("{}",d+b.length),0>d?!1:void 0}),c},qq.isFile=function(a){return window.File&&"[object File]"===Object.prototype.toString.call(a)},qq.isFileList=function(a){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(a)},qq.isFileOrInput=function(a){return qq.isFile(a)||qq.isInput(a)},qq.isInput=function(a,b){var c=function(a){var c=a.toLowerCase();return b?"file"!==c:"file"===c};return window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(a)&&a.type&&c(a.type)?!0:a.tagName&&"input"===a.tagName.toLowerCase()&&a.type&&c(a.type)?!0:!1},qq.isBlob=function(a){return window.Blob&&"[object Blob]"===Object.prototype.toString.call(a)?!0:void 0},qq.isXhrUploadSupported=function(){var a=document.createElement("input");return a.type="file",void 0!==a.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&"undefined"!=typeof qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(a){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(a){return a.items&&a.items.length>0&&a.items[0].webkitGetAsEntry},qq.isFileChunkingSupported=function(){return!qq.androidStock()&&qq.isXhrUploadSupported()&&(void 0!==File.prototype.slice||void 0!==File.prototype.webkitSlice||void 0!==File.prototype.mozSlice)},qq.sliceBlob=function(a,b,c){var d=a.slice||a.mozSlice||a.webkitSlice;return d.call(a,b,c)},qq.arrayBufferToHex=function(a){var b="",c=new Uint8Array(a);return qq.each(c,function(a,c){var d=c.toString(16);d.length<2&&(d="0"+d),b+=d}),b},qq.readBlobToHex=function(a,b,c){var d=qq.sliceBlob(a,b,b+c),e=new FileReader,f=new qq.Promise;return e.onload=function(){f.success(qq.arrayBufferToHex(e.result))},e.onerror=f.failure,e.readAsArrayBuffer(d),f},qq.extend=function(a,b,c){return qq.each(b,function(b,d){c&&qq.isObject(d)?(void 0===a[b]&&(a[b]={}),qq.extend(a[b],d,!0)):a[b]=d}),a},qq.override=function(a,b){var c={},d=b(c);return qq.each(d,function(b,d){void 0!==a[b]&&(c[b]=a[b]),a[b]=d}),a},qq.indexOf=function(a,b,c){if(a.indexOf)return a.indexOf(b,c);c=c||0;var d=a.length;for(0>c&&(c+=d);d>c;c+=1)if(a.hasOwnProperty(c)&&a[c]===b)return c;return-1},qq.getUniqueId=function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=0|16*Math.random(),c="x"==a?b:8|3&b;return c.toString(16)})},qq.ie=function(){return-1!==navigator.userAgent.indexOf("MSIE")||-1!==navigator.userAgent.indexOf("Trident")},qq.ie7=function(){return-1!==navigator.userAgent.indexOf("MSIE 7")},qq.ie8=function(){return-1!==navigator.userAgent.indexOf("MSIE 8")},qq.ie10=function(){return-1!==navigator.userAgent.indexOf("MSIE 10")},qq.ie11=function(){return qq.ie()&&-1!==navigator.userAgent.indexOf("rv:11")},qq.safari=function(){return void 0!==navigator.vendor&&-1!==navigator.vendor.indexOf("Apple")},qq.chrome=function(){return void 0!==navigator.vendor&&-1!==navigator.vendor.indexOf("Google")},qq.opera=function(){return void 0!==navigator.vendor&&-1!==navigator.vendor.indexOf("Opera")},qq.firefox=function(){return!qq.ie11()&&-1!==navigator.userAgent.indexOf("Mozilla")&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return-1!==navigator.userAgent.toLowerCase().indexOf("android")},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&-1!==navigator.userAgent.indexOf(" OS 6_")},qq.ios7=function(){return qq.ios()&&-1!==navigator.userAgent.indexOf(" OS 7_")},qq.ios8=function(){return qq.ios()&&-1!==navigator.userAgent.indexOf(" OS 8_")},qq.ios800=function(){return qq.ios()&&-1!==navigator.userAgent.indexOf(" OS 8_0 ")},qq.ios=function(){return-1!==navigator.userAgent.indexOf("iPad")||-1!==navigator.userAgent.indexOf("iPod")||-1!==navigator.userAgent.indexOf("iPhone")},qq.iosChrome=function(){return qq.ios()&&-1!==navigator.userAgent.indexOf("CriOS")},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&-1!==navigator.userAgent.indexOf("Safari")},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1},qq.toElement=function(){var a=document.createElement("div");return function(b){a.innerHTML=b;var c=a.firstChild;return a.removeChild(c),c}}(),qq.each=function(a,b){var c,d;if(a)if(window.Storage&&a.constructor===window.Storage)for(c=0;c0?a.substr(b,a.length-b):void 0},qq.getFilename=function(a){return qq.isInput(a)?a.value.replace(/.*(\/|\\)/,""):qq.isFile(a)&&null!==a.fileName&&void 0!==a.fileName?a.fileName:a.name},qq.DisposeSupport=function(){var a=[];return{dispose:function(){var b;do b=a.shift(),b&&b();while(b)},attach:function(){var a=arguments;this.addDisposer(qq(a[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(b){a.push(b)}}}}(),function(){"use strict";qq.Error=function(a){this.message="[Fine Uploader "+qq.version+"] "+a},qq.Error.prototype=new Error}(),qq.version="5.3.0",qq.supportedFeatures=function(){"use strict";function a(){var a,b=!0;try{a=document.createElement("input"),a.type="file",qq(a).hide(),a.disabled&&(b=!1)}catch(c){b=!1}return b}function b(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function c(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function d(){if(window.XMLHttpRequest){var a=qq.createXhrInstance();return void 0!==a.withCredentials}return!1}function e(){return void 0!==window.XDomainRequest}function f(){return d()?!0:e()}function g(){return void 0!==document.createElement("input").webkitdirectory}function h(){try{return!!window.localStorage}catch(a){return!1}}function i(){var a=document.createElement("span");return("draggable"in a||"ondragstart"in a&&"ondrop"in a)&&!qq.android()&&!qq.ios()}var j,k,l,m,n,o,p,q,r,s,t,u,v,w,x;return j=a(),m=j&&qq.isXhrUploadSupported(),k=m&&!qq.androidStock(),l=m&&i(),n=l&&b(),o=m&&qq.isFileChunkingSupported(),p=m&&o&&h(),q=m&&c(),r=j&&(void 0!==window.postMessage||m),t=d(),s=e(),u=f(),v=g(),w=m&&void 0!==window.FileReader,x=function(){return m?!qq.androidStock()&&!qq.iosChrome():!1}(),{ajaxUploading:m,blobUploading:k,canDetermineSize:m,chunking:o,deleteFileCors:u,deleteFileCorsXdr:s,deleteFileCorsXhr:t,dialogElement:!!window.HTMLDialogElement,fileDrop:l,folderDrop:n,folderSelection:v,imagePreviews:w,imageValidation:w,itemSizeValidation:m,pause:o,progressBar:x,resume:p,scaling:w&&k,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:j,uploadCors:r,uploadCustomHeaders:m,uploadNonMultipart:m,uploadViaPaste:q}}(),qq.isGenericPromise=function(a){"use strict";return!!(a&&a.then&&qq.isFunction(a.then))},qq.Promise=function(){"use strict";var a,b,c=[],d=[],e=[],f=0;qq.extend(this,{then:function(e,g){return 0===f?(e&&c.push(e),g&&d.push(g)):-1===f?g&&g.apply(null,b):e&&e.apply(null,a),this},done:function(c){return 0===f?e.push(c):c.apply(null,void 0===b?a:b),this},success:function(){return f=1,a=arguments,c.length&&qq.each(c,function(b,c){c.apply(null,a)}),e.length&&qq.each(e,function(b,c){c.apply(null,a)}),this},failure:function(){return f=-1,b=arguments,d.length&&qq.each(d,function(a,c){c.apply(null,b)}),e.length&&qq.each(e,function(a,c){c.apply(null,b)}),this}})},qq.BlobProxy=function(a,b){"use strict";qq.extend(this,{referenceBlob:a,create:function(){return b(a)}})},qq.UploadButton=function(a){"use strict";function b(){var a=document.createElement("input");return a.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,d),a.setAttribute("title","file input"),e.setMultiple(g.multiple,a),g.folders&&qq.supportedFeatures.folderSelection&&a.setAttribute("webkitdirectory",""),g.acceptFiles&&a.setAttribute("accept",g.acceptFiles),a.setAttribute("type","file"),a.setAttribute("name",g.name),qq(a).css({position:"absolute",right:0,top:0,fontFamily:"Arial",fontSize:qq.ie()&&!qq.ie8()?"3500px":"118px",margin:0,padding:0,cursor:"pointer",opacity:0}),!qq.ie7()&&qq(a).css({height:"100%"}),g.element.appendChild(a),f.attach(a,"change",function(){g.onChange(a)}),f.attach(a,"mouseover",function(){qq(g.element).addClass(g.hoverClass)}),f.attach(a,"mouseout",function(){qq(g.element).removeClass(g.hoverClass)}),f.attach(a,"focus",function(){qq(g.element).addClass(g.focusClass)}),f.attach(a,"blur",function(){qq(g.element).removeClass(g.focusClass)}),a}var c,d,e=this,f=new qq.DisposeSupport,g={element:null,multiple:!1,acceptFiles:null,folders:!1,name:"qqfile",onChange:function(){},ios8BrowserCrashWorkaround:!1,hoverClass:"qq-upload-button-hover",focusClass:"qq-upload-button-focus"};qq.extend(g,a),d=qq.getUniqueId(),qq(g.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return c},getButtonId:function(){return d},setMultiple:function(a,b){var c=b||this.getInput();g.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?c.setAttribute("multiple",""):a?c.setAttribute("multiple",""):c.removeAttribute("multiple")},setAcceptFiles:function(a){a!==g.acceptFiles&&c.setAttribute("accept",a)},reset:function(){c.parentNode&&qq(c).remove(),qq(g.element).removeClass(g.focusClass),c=null,c=b()}}),c=b()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(a){"use strict";function b(a){if(qq.isArray(a)){var b=[];return qq.each(a,function(a,c){b.push(e[c])}),b}return e[a]}function c(a){if(qq.isArray(a)){var b=[];return qq.each(a,function(a,c){b.push(e[f[c]])}),b}return e[f[a]]}function d(a){var b=[],c=[].concat(a);return qq.each(c,function(a,c){var d=g[c];void 0!==d&&qq.each(d,function(a,c){b.push(e[c])})}),b}var e=[],f={},g={},h={},i={};qq.extend(this,{addFile:function(b){var c=b.status||qq.status.SUBMITTING,d=e.push({name:b.name,originalName:b.name,uuid:b.uuid,size:null==b.size?-1:b.size,status:c})-1;return b.batchId&&(e[d].batchId=b.batchId,void 0===i[b.batchId]&&(i[b.batchId]=[]),i[b.batchId].push(d)),b.proxyGroupId&&(e[d].proxyGroupId=b.proxyGroupId,void 0===h[b.proxyGroupId]&&(h[b.proxyGroupId]=[]),h[b.proxyGroupId].push(d)),e[d].id=d,f[b.uuid]=d,void 0===g[c]&&(g[c]=[]),g[c].push(d),a.onStatusChange(d,null,c),d},retrieve:function(a){return qq.isObject(a)&&e.length?void 0!==a.id?b(a.id):void 0!==a.uuid?c(a.uuid):a.status?d(a.status):void 0:qq.extend([],e,!0)},reset:function(){e=[],f={},g={},i={}},setStatus:function(b,c){var d=e[b].status,f=qq.indexOf(g[d],b);g[d].splice(f,1),e[b].status=c,void 0===g[c]&&(g[c]=[]),g[c].push(b),a.onStatusChange(b,d,c)},uuidChanged:function(a,b){var c=e[a].uuid;e[a].uuid=b,f[b]=a,delete f[c]},updateName:function(a,b){e[a].name=b},updateSize:function(a,b){e[a].size=b},setParentId:function(a,b){e[a].parentId=b},getIdsInProxyGroup:function(a){var b=e[a].proxyGroupId;return b?h[b]:[]},getIdsInBatch:function(a){var b=e[a].batchId;return i[b]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_RETRYING:"retrying upload",UPLOAD_SUCCESSFUL:"upload successful",UPLOAD_FAILED:"upload failed",DELETE_FAILED:"delete failed",DELETING:"deleting",DELETED:"deleted"},function(){"use strict";qq.basePublicApi={addBlobs:function(a,b,c){this.addFiles(a,b,c)},addFiles:function(a,b,c){this._maybeHandleIos8SafariWorkaround();var d=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,e=qq.bind(function(a){this._handleNewFile({blob:a,name:this._options.blobs.defaultName},d,l)},this),f=qq.bind(function(a){this._handleNewFile(a,d,l)},this),g=qq.bind(function(a){var b=qq.canvasToBlob(a);this._handleNewFile({blob:b,name:this._options.blobs.defaultName+".png"},d,l)},this),h=qq.bind(function(a){var b=a.quality&&a.quality/100,c=qq.canvasToBlob(a.canvas,a.type,b);this._handleNewFile({blob:c,name:a.name},d,l)},this),i=qq.bind(function(a){if(qq.isInput(a)&&qq.supportedFeatures.ajaxUploading){var b=Array.prototype.slice.call(a.files),c=this;qq.each(b,function(a,b){c._handleNewFile(b,d,l)})}else this._handleNewFile(a,d,l)},this),j=function(){qq.isFileList(a)&&(a=Array.prototype.slice.call(a)),a=[].concat(a)},k=this,l=[];this._currentBatchId=d,a&&(j(),qq.each(a,function(a,b){qq.isFileOrInput(b)?i(b):qq.isBlob(b)?e(b):qq.isObject(b)?b.blob&&b.name?f(b):b.canvas&&b.name&&h(b):b.tagName&&"canvas"===b.tagName.toLowerCase()?g(b):k.log(b+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+l.length+" files."),this._prepareItemsForUpload(l,b,c))},cancel:function(a){this._handler.cancel(a)},cancelAll:function(){var a=[],b=this;qq.extend(a,this._storedIds),qq.each(a,function(a,c){b.cancel(c)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(a){var b=this._uploadData.retrieve({id:a});return qq.supportedFeatures.pause&&this._options.chunking.enabled?b.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",a,this.getName(a))),this._uploadFile(a),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",a,this.getName(a)),"error"),!1):!1},deleteFile:function(a){return this._onSubmitDelete(a)},doesExist:function(a){return this._handler.isValid(a)},drawThumbnail:function(a,b,c,d){var e,f,g=new qq.Promise;return this._imageGenerator?(e=this._thumbnailUrls[a],f={scale:c>0,maxSize:c>0?c:null},!d&&qq.supportedFeatures.imagePreviews&&(e=this.getFile(a)),null==e?g.failure({container:b,error:"File or URL not found."}):this._imageGenerator.generate(e,b,f).then(function(a){g.success(a)},function(a,b){g.failure({container:a,error:b||"Problem generating thumbnail"})})):g.failure({container:b,error:"Missing image generator module"}),g},getButton:function(a){return this._getButton(this._buttonIdsForFileIds[a])},getEndpoint:function(a){return this._endpointStore.get(a)},getFile:function(a){return this._handler.getFile(a)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(a){return this._uploadData.retrieve({id:a}).name},getParentId:function(a){var b=this.getUploads({id:a}),c=null;return b&&void 0!==b.parentId&&(c=b.parentId),c},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(a){return this._uploadData.retrieve({id:a}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var a=this._currentItemLimit;return a>0?a-this._netUploadedOrQueued:null},getUploads:function(a){return this._uploadData.retrieve(a)},getUuid:function(a){return this._uploadData.retrieve({id:a}).uuid},log:function(a,b){!this._options.debug||b&&"info"!==b?b&&"info"!==b&&qq.log("[Fine Uploader "+qq.version+"] "+a,b):qq.log("[Fine Uploader "+qq.version+"] "+a)},pauseUpload:function(a){var b=this._uploadData.retrieve({id:a});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],b.status)>=0){if(this._handler.pause(a))return this._uploadData.setStatus(a,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",a,this.getName(a)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",a,this.getName(a)),"error");return!1},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(a,b){b.reset()}),this._paramsStore.reset(),this._endpointStore.reset(),this._netUploadedOrQueued=0,this._netUploaded=0,this._uploadData.reset(),this._buttonIdsForFileIds=[],this._pasteHandler&&this._pasteHandler.reset(),this._options.session.refreshOnReset&&this._refreshSessionData(),this._succeededSinceLastAllComplete=[],this._failedSinceLastAllComplete=[],this._totalProgress&&this._totalProgress.reset()},retry:function(a){return this._manualRetry(a)},scaleImage:function(a,b){var c=this;return qq.Scaler.prototype.scaleImage(a,b,{log:qq.bind(c.log,c),getFile:qq.bind(c.getFile,c),uploadData:c._uploadData})},setCustomHeaders:function(a,b){this._customHeadersStore.set(a,b)},setDeleteFileCustomHeaders:function(a,b){this._deleteFileCustomHeadersStore.set(a,b)},setDeleteFileEndpoint:function(a,b){this._deleteFileEndpointStore.set(a,b)},setDeleteFileParams:function(a,b){this._deleteFileParamsStore.set(a,b)},setEndpoint:function(a,b){this._endpointStore.set(a,b)},setForm:function(a){this._updateFormSupportAndParams(a)},setItemLimit:function(a){this._currentItemLimit=a},setName:function(a,b){this._uploadData.updateName(a,b)},setParams:function(a,b){this._paramsStore.set(a,b)},setUuid:function(a,b){return this._uploadData.uuidChanged(a,b)},uploadStoredFiles:function(){0===this._storedIds.length?this._itemError("noFilesError"):this._uploadStoredFiles()}},qq.basePrivateApi={_addCannedFile:function(a){var b=this._uploadData.addFile({uuid:a.uuid,name:a.name,size:a.size,status:qq.status.UPLOAD_SUCCESSFUL});return a.deleteFileEndpoint&&this.setDeleteFileEndpoint(a.deleteFileEndpoint,b),a.deleteFileParams&&this.setDeleteFileParams(a.deleteFileParams,b),a.thumbnailUrl&&(this._thumbnailUrls[b]=a.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,b},_annotateWithButtonId:function(a,b){qq.isFile(a)&&(a.qqButtonId=this._getButtonId(b))},_batchError:function(a){this._options.callbacks.onError(null,null,a,void 0)},_createDeleteHandler:function(){var a=this;return new qq.DeleteFileAjaxRequester({method:this._options.deleteFile.method.toUpperCase(),maxConnections:this._options.maxConnections,uuidParamName:this._options.request.uuidName,customHeaders:this._deleteFileCustomHeadersStore,paramsStore:this._deleteFileParamsStore,endpointStore:this._deleteFileEndpointStore,cors:this._options.cors,log:qq.bind(a.log,a),onDelete:function(b){a._onDelete(b),a._options.callbacks.onDelete(b)},onDeleteComplete:function(b,c,d){a._onDeleteComplete(b,c,d),a._options.callbacks.onDeleteComplete(b,c,d)}})},_createPasteHandler:function(){var a=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(a.log,a),pasteReceived:function(b){a._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(a._options.callbacks.onPasteReceived,a,b),onSuccess:qq.bind(a._handlePasteSuccess,a,b),identifier:"pasted image"})}}})},_createStore:function(a,b){var c={},d=a,e={},f=b,g=function(a){return qq.isObject(a)?qq.extend({},a):a},h=function(){return qq.isFunction(f)?f():f},i=function(a,b){f&&qq.isObject(b)&&qq.extend(b,h()),e[a]&&qq.extend(b,e[a])};return{set:function(a,b){null==b?(c={},d=g(a)):c[b]=g(a)},get:function(a){var b;return b=null!=a&&c[a]?c[a]:g(d),i(a,b),g(b)},addReadOnly:function(a,b){qq.isObject(c)&&(null===a?qq.isFunction(b)?f=b:(f=f||{},qq.extend(f,b)):(e[a]=e[a]||{},qq.extend(e[a],b)))},remove:function(a){return delete c[a]},reset:function(){c={},e={},d=a}}},_createUploadDataTracker:function(){var a=this;return new qq.UploadData({getName:function(b){return a.getName(b)},getUuid:function(b){return a.getUuid(b)},getSize:function(b){return a.getSize(b)},onStatusChange:function(b,c,d){a._onUploadStatusChange(b,c,d),a._options.callbacks.onStatusChange(b,c,d),a._maybeAllComplete(b,d),a._totalProgress&&setTimeout(function(){a._totalProgress.onStatusChange(b,c,d)},0)}})},_createUploadButton:function(a){function b(){return qq.supportedFeatures.ajaxUploading?d._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&d._isAllowedExtension(f,".mov")?!1:void 0===a.multiple?d._options.multiple:a.multiple:!1}var c,d=this,e=a.accept||this._options.validation.acceptFiles,f=a.allowedExtensions||this._options.validation.allowedExtensions;return c=new qq.UploadButton({element:a.element,folders:a.folders,name:this._options.request.inputName,multiple:b(),acceptFiles:e,onChange:function(a){d._onInputChange(a)},hoverClass:this._options.classes.buttonHover,focusClass:this._options.classes.buttonFocus,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash}),this._disposeSupport.addDisposer(function(){c.dispose()}),d._buttons.push(c),c},_createUploadHandler:function(a,b){var c=this,d={},e={debug:this._options.debug,maxConnections:this._options.maxConnections,cors:this._options.cors,paramsStore:this._paramsStore,endpointStore:this._endpointStore,chunking:this._options.chunking,resume:this._options.resume,blobs:this._options.blobs,log:qq.bind(c.log,c),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(a,b,e,f){0>e||0>f||(d[a]?(d[a].loaded!==e||d[a].total!==f)&&(c._onProgress(a,b,e,f),c._options.callbacks.onProgress(a,b,e,f)):(c._onProgress(a,b,e,f),c._options.callbacks.onProgress(a,b,e,f)),d[a]={loaded:e,total:f})},onComplete:function(a,b,e,f){delete d[a];var g,h=c.getUploads({id:a}).status;h!==qq.status.UPLOAD_SUCCESSFUL&&h!==qq.status.UPLOAD_FAILED&&(g=c._onComplete(a,b,e,f),g instanceof qq.Promise?g.done(function(){c._options.callbacks.onComplete(a,b,e,f)}):c._options.callbacks.onComplete(a,b,e,f))},onCancel:function(a,b,d){var e=new qq.Promise;return c._handleCheckedCallback({name:"onCancel",callback:qq.bind(c._options.callbacks.onCancel,c,a,b),onFailure:e.failure,onSuccess:function(){d.then(function(){c._onCancel(a,b)}),e.success()},identifier:a}),e},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(a,b){c._onUpload(a,b),c._options.callbacks.onUpload(a,b)},onUploadChunk:function(a,b,d){c._onUploadChunk(a,d),c._options.callbacks.onUploadChunk(a,b,d)},onUploadChunkSuccess:function(){c._options.callbacks.onUploadChunkSuccess.apply(c,arguments)},onResume:function(a,b,d){return c._options.callbacks.onResume(a,b,d)},onAutoRetry:function(){return c._onAutoRetry.apply(c,arguments)},onUuidChanged:function(a,b){c.log("Server requested UUID change from '"+c.getUuid(a)+"' to '"+b+"'"),c.setUuid(a,b)},getName:qq.bind(c.getName,c),getUuid:qq.bind(c.getUuid,c),getSize:qq.bind(c.getSize,c),setSize:qq.bind(c._setSize,c),getDataByUuid:function(a){return c.getUploads({uuid:a})},isQueued:function(a){var b=c.getUploads({id:a}).status;return b===qq.status.QUEUED||b===qq.status.SUBMITTED||b===qq.status.UPLOAD_RETRYING||b===qq.status.PAUSED},getIdsInProxyGroup:c._uploadData.getIdsInProxyGroup,getIdsInBatch:c._uploadData.getIdsInBatch};return qq.each(this._options.request,function(a,b){e[a]=b}),e.customHeaders=this._customHeadersStore,a&&qq.each(a,function(a,b){e[a]=b}),new qq.UploadHandlerController(e,b)},_fileOrBlobRejected:function(a){this._netUploadedOrQueued--,this._uploadData.setStatus(a,qq.status.REJECTED)},_formatSize:function(a){var b=-1;do a/=1e3,b++;while(a>999);return Math.max(a,.1).toFixed(1)+this._options.text.sizeSymbols[b]},_generateExtraButtonSpecs:function(){var a=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(b,c){var d=c.multiple,e=qq.extend({},a._options.validation,!0),f=qq.extend({},c);void 0===d&&(d=a._options.multiple),f.validation&&qq.extend(e,c.validation,!0),qq.extend(f,{multiple:d,validation:e},!0),a._initExtraButton(f)})},_getButton:function(a){var b=this._extraButtonSpecs[a];return b?b.element:a===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(a){var b,c,d=a;if(d instanceof qq.BlobProxy&&(d=d.referenceBlob),d&&!qq.isBlob(d)){if(qq.isFile(d))return d.qqButtonId;if("input"===d.tagName.toLowerCase()&&"file"===d.type.toLowerCase())return d.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(b=d.getElementsByTagName("input"),qq.each(b,function(a,b){return"file"===b.getAttribute("type")?(c=b,!1):void 0}),c)return c.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getNotFinished:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED,qq.status.SUBMITTING,qq.status.SUBMITTED,qq.status.PAUSED]}).length},_getValidationBase:function(a){var b=this._extraButtonSpecs[a];return b?b.validation:this._options.validation},_getValidationDescriptor:function(a){return a.file instanceof qq.BlobProxy?{name:qq.getFilename(a.file.referenceBlob),size:a.file.referenceBlob.size}:{name:this.getUploads({id:a.id}).name,size:this.getUploads({id:a.id}).size}},_getValidationDescriptors:function(a){var b=this,c=[];return qq.each(a,function(a,d){c.push(b._getValidationDescriptor(d))}),c},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var a="image/*;capture=camera",b=this._options.camera.button,c=b?this._getButtonId(b):this._defaultButtonId,d=this._options;c&&c!==this._defaultButtonId&&(d=this._extraButtonSpecs[c]),d.multiple=!1,null===d.validation.acceptFiles?d.validation.acceptFiles=a:d.validation.acceptFiles+=","+a,qq.each(this._buttons,function(a,b){return b.getButtonId()===c?(b.setMultiple(d.multiple),b.setAcceptFiles(d.acceptFiles),!1):void 0})}},_handleCheckedCallback:function(a){var b=this,c=a.callback();return qq.isGenericPromise(c)?(this.log(a.name+" - waiting for "+a.name+" promise to be fulfilled for "+a.identifier),c.then(function(c){b.log(a.name+" promise success for "+a.identifier),a.onSuccess(c)},function(){a.onFailure?(b.log(a.name+" promise failure for "+a.identifier),a.onFailure()):b.log(a.name+" promise failure for "+a.identifier)})):(c!==!1?a.onSuccess(c):a.onFailure?(this.log(a.name+" - return value was 'false' for "+a.identifier+". Invoking failure callback."),a.onFailure()):this.log(a.name+" - return value was 'false' for "+a.identifier+". Will not proceed."),c)},_handleNewFile:function(a,b,c){var d=this,e=qq.getUniqueId(),f=-1,g=qq.getFilename(a),h=a.blob||a,i=this._customNewFileHandler?this._customNewFileHandler:qq.bind(d._handleNewFileGeneric,d);!qq.isInput(h)&&h.size>=0&&(f=h.size),i(h,g,e,f,c,b,this._options.request.uuidName,{uploadData:d._uploadData,paramsStore:d._paramsStore,addFileToHandler:function(a,b){d._handler.add(a,b),d._netUploadedOrQueued++,d._trackButton(a)}})},_handleNewFileGeneric:function(a,b,c,d,e,f){var g=this._uploadData.addFile({uuid:c,name:b,size:d,batchId:f});this._handler.add(g,a),this._trackButton(g),this._netUploadedOrQueued++,e.push({id:g,file:a})},_handlePasteSuccess:function(a,b){var c=a.type.split("/")[1],d=b;null==d&&(d=this._options.paste.defaultName),d+="."+c,this.addFiles({name:d,blob:a})},_initExtraButton:function(a){var b=this._createUploadButton({element:a.element,multiple:a.multiple,accept:a.validation.acceptFiles,folders:a.folders,allowedExtensions:a.validation.allowedExtensions});this._extraButtonSpecs[b.getButtonId()]=a},_initFormSupportAndParams:function(){this._formSupport=qq.FormSupport&&new qq.FormSupport(this._options.form,qq.bind(this.uploadStoredFiles,this),qq.bind(this.log,this)),this._formSupport&&this._formSupport.attachedToForm?(this._paramsStore=this._createStore(this._options.request.params,this._formSupport.getFormInputsAsObject),this._options.autoUpload=this._formSupport.newAutoUpload,this._formSupport.newEndpoint&&(this._options.request.endpoint=this._formSupport.newEndpoint)):this._paramsStore=this._createStore(this._options.request.params)
+},_isDeletePossible:function(){return qq.DeleteFileAjaxRequester&&this._options.deleteFile.enabled?this._options.cors.expected?qq.supportedFeatures.deleteFileCorsXhr?!0:qq.supportedFeatures.deleteFileCorsXdr&&this._options.cors.allowXdr?!0:!1:!0:!1},_isAllowedExtension:function(a,b){var c=!1;return a.length?(qq.each(a,function(a,d){if(qq.isString(d)){var e=new RegExp("\\."+d+"$","i");if(null!=b.match(e))return c=!0,!1}}),c):!0},_itemError:function(a,b,c){function d(a,b){g=g.replace(a,b)}var e,f,g=this._options.messages[a],h=[],i=[].concat(b),j=i[0],k=this._getButtonId(c),l=this._getValidationBase(k);return qq.each(l.allowedExtensions,function(a,b){qq.isString(b)&&h.push(b)}),e=h.join(", ").toLowerCase(),d("{file}",this._options.formatFileName(j)),d("{extensions}",e),d("{sizeLimit}",this._formatSize(l.sizeLimit)),d("{minSizeLimit}",this._formatSize(l.minSizeLimit)),f=g.match(/(\{\w+\})/g),null!==f&&qq.each(f,function(a,b){d(b,i[a])}),this._options.callbacks.onError(null,j,g,void 0),g},_manualRetry:function(a,b){return this._onBeforeManualRetry(a)?(this._netUploadedOrQueued++,this._uploadData.setStatus(a,qq.status.UPLOAD_RETRYING),b?b(a):this._handler.retry(a),!0):void 0},_maybeAllComplete:function(a,b){var c=this,d=this._getNotFinished();b===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(a):b===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(a),0===d&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){c._onAllComplete(c._succeededSinceLastAllComplete,c._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var a=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(a._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(a,b,c,d){if(!c.success)if(d&&200!==d.status&&!c.error)this._options.callbacks.onError(a,b,"XHR returned response code "+d.status,d);else{var e=c.error?c.error:this._options.text.defaultResponseError;this._options.callbacks.onError(a,b,e,d)}},_maybeProcessNextItemAfterOnValidateCallback:function(a,b,c,d,e){var f=this;if(b.length>c)if(a||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var a=f._getValidationDescriptor(b[c]),g=f._getButtonId(b[c].file),h=f._getButton(g);f._handleCheckedCallback({name:"onValidate",callback:qq.bind(f._options.callbacks.onValidate,f,a,h),onSuccess:qq.bind(f._onValidateCallbackSuccess,f,b,c,d,e),onFailure:qq.bind(f._onValidateCallbackFailure,f,b,c,d,e),identifier:"Item '"+a.name+"', size: "+a.size})},0);else if(!a)for(;c0&&this._netUploadedOrQueued+1>c?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+b+"' (id: "+a+")..."),!0)):(this.log("'"+a+"' is not a valid file ID","error"),!1)},_onCancel:function(a){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[a]);var b=qq.indexOf(this._storedIds,a);!this._options.autoUpload&&b>=0&&this._storedIds.splice(b,1),this._uploadData.setStatus(a,qq.status.CANCELED)},_onComplete:function(a,b,c,d){return c.success?(c.thumbnailUrl&&(this._thumbnailUrls[a]=c.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(a,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(a,qq.status.UPLOAD_FAILED),c[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[a]=!0)),this._maybeParseAndSendUploadError(a,b,c,d),c.success?!0:!1},_onDelete:function(a){this._uploadData.setStatus(a,qq.status.DELETING)},_onDeleteComplete:function(a,b,c){var d=this.getName(a);c?(this._uploadData.setStatus(a,qq.status.DELETE_FAILED),this.log("Delete request for '"+d+"' has failed.","error"),void 0===b.withCredentials?this._options.callbacks.onError(a,d,"Delete request failed",b):this._options.callbacks.onError(a,d,"Delete request failed with response code "+b.status,b)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(a),this._uploadData.setStatus(a,qq.status.DELETED),this.log("Delete request for '"+d+"' has succeeded."))},_onInputChange:function(a){var b;if(qq.supportedFeatures.ajaxUploading){for(b=0;b0&&this.addFiles(a);qq.each(this._buttons,function(a,b){b.reset()})},_onProgress:function(a,b,c,d){this._totalProgress&&this._totalProgress.onIndividualProgress(a,c,d)},_onSubmit:function(){},_onSubmitCallbackSuccess:function(a){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(a,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.autoUpload?(this._options.callbacks.onSubmitted.apply(this,arguments),this._uploadFile(a)):(this._storeForLater(a),this._options.callbacks.onSubmitted.apply(this,arguments))},_onSubmitDelete:function(a,b,c){var d,e=this.getUuid(a);return b&&(d=qq.bind(b,this,a,e,c)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,a),onSuccess:d||qq.bind(this._deleteHandler.sendDelete,this,a,e,c),identifier:a}),!0):(this.log("Delete request ignored for ID "+a+", delete feature is disabled or request not possible "+"due to CORS on a user agent that does not support pre-flighting.","warn"),!1)},_onSubmitted:function(){},_onTotalProgress:function(a,b){this._options.callbacks.onTotalProgress(a,b)},_onUploadPrep:function(){},_onUpload:function(a){this._uploadData.setStatus(a,qq.status.UPLOADING)},_onUploadChunk:function(){},_onUploadStatusChange:function(a,b,c){c===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[a])},_onValidateBatchCallbackFailure:function(a){var b=this;qq.each(a,function(a,c){b._fileOrBlobRejected(c.id)})},_onValidateBatchCallbackSuccess:function(a,b,c,d,e){var f,g=this._currentItemLimit,h=this._netUploadedOrQueued;0===g||g>=h?b.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,a[0],e),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,b,0,c,d),onFailure:qq.bind(this._onValidateCallbackFailure,this,b,0,c,d),identifier:"Item '"+b[0].file.name+"', size: "+b[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(b),f=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,h).replace(/\{itemLimit\}/g,g),this._batchError(f))},_onValidateCallbackFailure:function(a,b,c,d){var e=b+1;this._fileOrBlobRejected(a[b].id,a[b].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,a,e,c,d)},_onValidateCallbackSuccess:function(a,b,c,d){var e=this,f=b+1,g=this._getValidationDescriptor(a[b]);this._validateFileOrBlobData(a[b],g).then(function(){e._upload(a[b].id,c,d),e._maybeProcessNextItemAfterOnValidateCallback(!0,a,f,c,d)},function(){e._maybeProcessNextItemAfterOnValidateCallback(!1,a,f,c,d)})},_prepareItemsForUpload:function(a,b,c){if(0===a.length)return this._itemError("noFilesError"),void 0;var d=this._getValidationDescriptors(a),e=this._getButtonId(a[0].file),f=this._getButton(e);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,d,f),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,d,a,b,c,f),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,a),identifier:"batch validation"})},_preventLeaveInProgress:function(){var a=this;this._disposeSupport.attach(window,"beforeunload",function(b){return a.getInProgress()?(b=b||window.event,b.returnValue=a._options.messages.onLeave,a._options.messages.onLeave):void 0})},_refreshSessionData:function(){var a=this,b=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(b,this._options.cors),b.log=qq.bind(this.log,this),b.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(b)),setTimeout(function(){a._session.refresh().then(function(b,c){a._options.callbacks.onSessionRequestComplete(b,!0,c)},function(b,c){a._options.callbacks.onSessionRequestComplete(b,!1,c)})},0))},_setSize:function(a,b){this._uploadData.updateSize(a,b),this._totalProgress&&this._totalProgress.onNewSize(a)},_shouldAutoRetry:function(a){var b=this._uploadData.retrieve({id:a});return!this._preventRetries[a]&&this._options.retry.enableAuto&&b.status!==qq.status.PAUSED&&(void 0===this._autoRetries[a]&&(this._autoRetries[a]=0),this._autoRetries[a]0&&h.sizeLimit&&f>h.sizeLimit?(this._itemError("sizeError",e,d),i.failure()):f>0&&f=0}function c(){var a=!1;return qq.each(a,function(b,c){return qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],c)<0?(a=!0,!1):void 0}),a}function d(a){return w.cors.expected&&void 0===a.withCredentials}function e(){var a;return(window.XMLHttpRequest||window.ActiveXObject)&&(a=qq.createXhrInstance(),void 0===a.withCredentials&&(a=new XDomainRequest)),a}function f(a,b){var c=v[a].xhr;return c||(c=b?b:w.cors.expected?e():qq.createXhrInstance(),v[a].xhr=c),c}function g(a){var b,c=qq.indexOf(u,a),d=w.maxConnections;delete v[a],u.splice(c,1),u.length>=d&&d>c&&(b=u[d-1],j(b))}function h(a,b){var c=f(a),e=w.method,h=b===!0;g(a),h?s(e+" request for "+a+" has failed","error"):d(c)||q(c.status)||(h=!0,s(e+" request for "+a+" has failed - response code "+c.status,"error")),w.onComplete(a,c,h)}function i(a){var b,c=v[a].additionalParams,d=w.mandatedParams;return w.paramsStore.get&&(b=w.paramsStore.get(a)),c&&qq.each(c,function(a,c){b=b||{},b[a]=c}),d&&qq.each(d,function(a,c){b=b||{},b[a]=c}),b}function j(a,b){var c,e=f(a,b),g=w.method,h=i(a),j=v[a].payload;return w.onSend(a),c=k(a,h),d(e)?(e.onload=n(a),e.onerror=o(a)):e.onreadystatechange=l(a),m(a),e.open(g,c,!0),w.cors.expected&&w.cors.sendCredentials&&!d(e)&&(e.withCredentials=!0),p(a),s("Sending "+g+" request for "+a),j?e.send(j):t||!h?e.send():h&&w.contentType&&w.contentType.toLowerCase().indexOf("application/x-www-form-urlencoded")>=0?e.send(qq.obj2url(h,"")):h&&w.contentType&&w.contentType.toLowerCase().indexOf("application/json")>=0?e.send(JSON.stringify(h)):e.send(h),e}function k(a,b){var c=w.endpointStore.get(a),d=v[a].addToPath;return void 0!=d&&(c+="/"+d),t&&b?qq.obj2url(b,c):c}function l(a){return function(){4===f(a).readyState&&h(a)}}function m(a){var b=w.onProgress;b&&(f(a).upload.onprogress=function(c){c.lengthComputable&&b(a,c.loaded,c.total)})}function n(a){return function(){h(a)}}function o(a){return function(){h(a,!0)}}function p(a){var e=f(a),g=w.customHeaders,h=v[a].additionalHeaders||{},i=w.method,j={};d(e)||(w.acceptHeader&&e.setRequestHeader("Accept",w.acceptHeader),w.allowXRequestedWithAndCacheControl&&(w.cors.expected&&b()&&!c(g)||(e.setRequestHeader("X-Requested-With","XMLHttpRequest"),e.setRequestHeader("Cache-Control","no-cache"))),!w.contentType||"POST"!==i&&"PUT"!==i||e.setRequestHeader("Content-Type",w.contentType),qq.extend(j,qq.isFunction(g)?g(a):g),qq.extend(j,h),qq.each(j,function(a,b){e.setRequestHeader(a,b)}))}function q(a){return qq.indexOf(w.successfulResponseCodes[w.method],a)>=0}function r(a,b,c,d,e,f){v[a]={addToPath:c,additionalParams:d,additionalHeaders:e,payload:f};var g=u.push(a);return g<=w.maxConnections?j(a,b):void 0}var s,t,u=[],v={},w={acceptHeader:null,validMethods:["PATCH","POST","PUT"],method:"POST",contentType:"application/x-www-form-urlencoded",maxConnections:3,customHeaders:{},endpointStore:{},paramsStore:{},mandatedParams:{},allowXRequestedWithAndCacheControl:!0,successfulResponseCodes:{DELETE:[200,202,204],PATCH:[200,201,202,203,204],POST:[200,201,202,203,204],PUT:[200,201,202,203,204],GET:[200]},cors:{expected:!1,sendCredentials:!1},log:function(){},onSend:function(){},onComplete:function(){},onProgress:null};if(qq.extend(w,a),s=w.log,qq.indexOf(w.validMethods,w.method)<0)throw new Error("'"+w.method+"' is not a supported method for this type of request!");t="GET"===w.method||"DELETE"===w.method,qq.extend(this,{initTransport:function(a){var b,c,d,e,f;return{withPath:function(a){return b=a,this},withParams:function(a){return c=a,this},withHeaders:function(a){return d=a,this},withPayload:function(a){return e=a,this},withCacheBuster:function(){return f=!0,this},send:function(g){return f&&qq.indexOf(["GET","DELETE"],w.method)>=0&&(c.qqtimestamp=(new Date).getTime()),r(a,g,b,c,d,e)}}},canceled:function(a){g(a)}})},qq.UploadHandler=function(a){"use strict";var b=a.proxy,c={},d=b.onCancel,e=b.getName;qq.extend(this,{add:function(a,b){c[a]=b,c[a].temp={}},cancel:function(a){var b=this,f=new qq.Promise,g=d(a,e(a),f);g.then(function(){b.isValid(a)&&(c[a].canceled=!0,b.expunge(a)),f.success()})},expunge:function(a){delete c[a]},getThirdPartyFileId:function(a){return c[a].key},isValid:function(a){return void 0!==c[a]},reset:function(){c={}},_getFileState:function(a){return c[a]},_setThirdPartyFileId:function(a,b){c[a].key=b},_wasCanceled:function(a){return!!c[a].canceled}})},qq.UploadHandlerController=function(a,b){"use strict";var c,d,e,f=this,g=!1,h=!1,i={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(){},onProgress:function(){},onComplete:function(){},onCancel:function(){},onUploadPrep:function(){},onUpload:function(){},onUploadChunk:function(){},onUploadChunkSuccess:function(){},onAutoRetry:function(){},onResume:function(){},onUuidChanged:function(){},getName:function(){},setSize:function(){},isQueued:function(){},getIdsInProxyGroup:function(){},getIdsInBatch:function(){}},j={done:function(a,b,c,d){var f=e._getChunkData(a,b);e._getFileState(a).attemptingResume=!1,delete e._getFileState(a).temp.chunkProgress[b],e._getFileState(a).loaded+=f.size,i.onUploadChunkSuccess(a,e._getChunkDataForCallback(f),c,d)},finalize:function(a){var b=i.getSize(a),c=i.getName(a);d("All chunks have been uploaded for "+a+" - finalizing...."),e.finalizeChunks(a).then(function(f,g){d("Finalize successful for "+a);var h=m.normalizeResponse(f,!0);i.onProgress(a,c,b,b),e._maybeDeletePersistedChunkData(a),m.cleanup(a,h,g)},function(b,e){var f=m.normalizeResponse(b,!1);d("Problem finalizing chunks for file ID "+a+" - "+f.error,"error"),f.reset&&j.reset(a),i.onAutoRetry(a,c,f,e)||m.cleanup(a,f,e)})},hasMoreParts:function(a){return!!e._getFileState(a).chunking.remaining.length},nextPart:function(a){var b=e._getFileState(a).chunking.remaining.shift();return b>=e._getTotalChunks(a)&&(b=null),b},reset:function(a){d("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+a,"error"),e._maybeDeletePersistedChunkData(a),e.reevaluateChunking(a),e._getFileState(a).loaded=0},sendNext:function(a){var b=i.getSize(a),c=i.getName(a),f=j.nextPart(a),g=e._getChunkData(a,f),l=e._getFileState(a).attemptingResume,n=e._getFileState(a).chunking.inProgress||[];null==e._getFileState(a).loaded&&(e._getFileState(a).loaded=0),l&&i.onResume(a,c,g)===!1&&(j.reset(a),f=j.nextPart(a),g=e._getChunkData(a,f),l=!1),null==f&&0===n.length?j.finalize(a):(d("Sending chunked upload request for item "+a+": bytes "+(g.start+1)+"-"+g.end+" of "+b),i.onUploadChunk(a,c,e._getChunkDataForCallback(g)),n.push(f),e._getFileState(a).chunking.inProgress=n,h&&k.open(a,f),h&&k.available()&&e._getFileState(a).chunking.remaining.length&&j.sendNext(a),e.uploadChunk(a,f,l).then(function(b,c){d("Chunked upload request succeeded for "+a+", chunk "+f),e.clearCachedChunk(a,f);var g=e._getFileState(a).chunking.inProgress||[],h=m.normalizeResponse(b,!0),i=qq.indexOf(g,f);d(qq.format("Chunk {} for file {} uploaded successfully.",f,a)),j.done(a,f,h,c),i>=0&&g.splice(i,1),e._maybePersistChunkedState(a),j.hasMoreParts(a)||0!==g.length?j.hasMoreParts(a)&&j.sendNext(a):j.finalize(a)},function(b,g){d("Chunked upload request failed for "+a+", chunk "+f),e.clearCachedChunk(a,f);var l,n=m.normalizeResponse(b,!1);n.reset?j.reset(a):(l=qq.indexOf(e._getFileState(a).chunking.inProgress,f),l>=0&&(e._getFileState(a).chunking.inProgress.splice(l,1),e._getFileState(a).chunking.remaining.unshift(f))),e._getFileState(a).temp.ignoreFailure||(h&&(e._getFileState(a).temp.ignoreFailure=!0,qq.each(e._getXhrs(a),function(a,b){b.abort()}),e.moveInProgressToRemaining(a),k.free(a,!0)),i.onAutoRetry(a,c,n,g)||m.cleanup(a,n,g))}).done(function(){e.clearXhr(a,f)}))}},k={_open:[],_openChunks:{},_waiting:[],available:function(){var a=i.maxConnections,b=0,c=0;return qq.each(k._openChunks,function(a,d){b++,c+=d.length}),a-(k._open.length-b+c)},free:function(a,b){var c,f=!b,g=qq.indexOf(k._waiting,a),h=qq.indexOf(k._open,a);delete k._openChunks[a],m.getProxyOrBlob(a)instanceof qq.BlobProxy&&(d("Generated blob upload has ended for "+a+", disposing generated blob."),delete e._getFileState(a).file),g>=0?k._waiting.splice(g,1):f&&h>=0&&(k._open.splice(h,1),c=k._waiting.shift(),c>=0&&(k._open.push(c),m.start(c)))},getWaitingOrConnected:function(){var a=[];return qq.each(k._openChunks,function(b,c){c&&c.length&&a.push(parseInt(b))}),qq.each(k._open,function(b,c){k._openChunks[c]||a.push(parseInt(c))}),a=a.concat(k._waiting)},isUsingConnection:function(a){return qq.indexOf(k._open,a)>=0},open:function(a,b){return null==b&&k._waiting.push(a),k.available()?(null==b?(k._waiting.pop(),k._open.push(a)):function(){var c=k._openChunks[a]||[];c.push(b),k._openChunks[a]=c}(),!0):!1},reset:function(){k._waiting=[],k._open=[]}},l={send:function(a,b){e._getFileState(a).loaded=0,d("Sending simple upload request for "+a),e.uploadFile(a).then(function(c,e){d("Simple upload request succeeded for "+a);var f=m.normalizeResponse(c,!0),g=i.getSize(a);i.onProgress(a,b,g,g),m.maybeNewUuid(a,f),m.cleanup(a,f,e)},function(c,e){d("Simple upload request failed for "+a);var f=m.normalizeResponse(c,!1);i.onAutoRetry(a,b,f,e)||m.cleanup(a,f,e)})}},m={cancel:function(a){d("Cancelling "+a),i.paramsStore.remove(a),k.free(a)},cleanup:function(a,b,c){var d=i.getName(a);i.onComplete(a,d,b,c),e._getFileState(a)&&e._clearXhrs&&e._clearXhrs(a),k.free(a)},getProxyOrBlob:function(a){return e.getProxy&&e.getProxy(a)||e.getFile&&e.getFile(a)},initHandler:function(){var a=b?qq[b]:qq.traditional,c=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";e=new a[c+"UploadHandler"](i,{getDataByUuid:i.getDataByUuid,getName:i.getName,getSize:i.getSize,getUuid:i.getUuid,log:d,onCancel:i.onCancel,onProgress:i.onProgress,onUuidChanged:i.onUuidChanged}),e._removeExpiredChunkingRecords&&e._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(a){return i.isQueued(a)},maybeDefer:function(a,b){return b&&!e.getFile(a)&&b instanceof qq.BlobProxy?(i.onUploadPrep(a),d("Attempting to generate a blob on-demand for "+a),b.create().then(function(b){d("Generated an on-demand blob for "+a),e.updateBlob(a,b),i.setSize(a,b.size),e.reevaluateChunking(a),m.maybeSendDeferredFiles(a)},function(b){var e={};b&&(e.error=b),d(qq.format("Failed to generate blob for ID {}. Error message: {}.",a,b),"error"),i.onComplete(a,i.getName(a),qq.extend(e,c),null),m.maybeSendDeferredFiles(a),k.free(a)}),!1):m.maybeSendDeferredFiles(a)},maybeSendDeferredFiles:function(a){var b=i.getIdsInProxyGroup(a),c=!1;return b&&b.length?(d("Maybe ready to upload proxy group file "+a),qq.each(b,function(b,d){if(m.isDeferredEligibleForUpload(d)&&e.getFile(d))c=d===a,m.now(d);else if(m.isDeferredEligibleForUpload(d))return!1})):(c=!0,m.now(a)),c},maybeNewUuid:function(a,b){void 0!==b.newUuid&&i.onUuidChanged(a,b.newUuid)},normalizeResponse:function(a,b){var c=a;return qq.isObject(a)||(c={},qq.isString(a)&&!b&&(c.error=a)),c.success=b,c},now:function(a){var b=i.getName(a);if(!f.isValid(a))throw new qq.Error(a+" is not a valid file ID to upload!");i.onUpload(a,b),g&&e._shouldChunkThisFile(a)?j.sendNext(a):l.send(a,b)},start:function(a){var b=m.getProxyOrBlob(a);return b?m.maybeDefer(a,b):(m.now(a),!0)}};qq.extend(this,{add:function(){e.add.apply(this,arguments)},upload:function(a){return k.open(a)?m.start(a):!1},retry:function(a){return h&&(e._getFileState(a).temp.ignoreFailure=!1),k.isUsingConnection(a)?m.start(a):f.upload(a)},cancel:function(a){var b=e.cancel(a);qq.isGenericPromise(b)?b.then(function(){m.cancel(a)}):b!==!1&&m.cancel(a)},cancelAll:function(){var a,b=k.getWaitingOrConnected();if(b.length)for(a=b.length-1;a>=0;a--)f.cancel(b[a]);k.reset()},getFile:function(a){return e.getProxy&&e.getProxy(a)?e.getProxy(a).referenceBlob:e.getFile&&e.getFile(a)},isProxied:function(a){return!(!e.getProxy||!e.getProxy(a))},getInput:function(a){return e.getInput?e.getInput(a):void 0},reset:function(){d("Resetting upload handler"),f.cancelAll(),k.reset(),e.reset()},expunge:function(a){return f.isValid(a)?e.expunge(a):void 0},isValid:function(a){return e.isValid(a)},getResumableFilesData:function(){return e.getResumableFilesData?e.getResumableFilesData():[]},getThirdPartyFileId:function(a){return f.isValid(a)?e.getThirdPartyFileId(a):void 0},pause:function(a){return f.isResumable(a)&&e.pause&&f.isValid(a)&&e.pause(a)?(k.free(a),e.moveInProgressToRemaining(a),!0):!1},isResumable:function(a){return!!e.isResumable&&e.isResumable(a)}}),qq.extend(i,a),d=i.log,g=i.chunking.enabled&&qq.supportedFeatures.chunking,h=g&&i.chunking.concurrent.enabled,c=function(){var a={};return a[i.preventRetryParam]=!0,a}(),m.initHandler()},qq.FormUploadHandler=function(a){"use strict";function b(a){delete k[a],m&&(clearTimeout(l[a]),delete l[a],q.stopReceivingMessages(a));var b=document.getElementById(g._getIframeName(a));b&&(b.setAttribute("src","javascript:false;"),qq(b).remove())}function c(a){return a.split("_")[0]}function d(a){var b=qq.toElement("");return b.setAttribute("id",a),b.style.display="none",document.body.appendChild(b),b}function e(a,b){var d=a.id,e=c(d),f=o(e);j[f]=b,k[e]=qq(a).attach("load",function(){g.getInput(e)&&(p("Received iframe load event for CORS upload request (iframe name "+d+")"),l[d]=setTimeout(function(){var a="No valid message received from loaded iframe for iframe name "+d;p(a,"error"),b({error:a})},1e3))}),q.receiveMessage(d,function(a){p("Received the following window message: '"+a+"'");var b,e=(c(d),g._parseJsonResponse(a)),f=e.uuid;f&&j[f]?(p("Handling response for iframe name "+d),clearTimeout(l[d]),delete l[d],g._detachLoadEvent(d),b=j[f],delete j[f],q.stopReceivingMessages(d),b(e)):f||p("'"+a+"' does not contain a UUID - ignoring.")})}var f=a.options,g=this,h=a.proxy,i=qq.getUniqueId(),j={},k={},l={},m=f.isCors,n=f.inputName,o=h.getUuid,p=h.log,q=new qq.WindowReceiveMessage({log:p});qq.extend(this,new qq.UploadHandler(a)),qq.override(this,function(a){return{add:function(b,c){a.add(b,{input:c}),c.setAttribute("name",n),c.parentNode&&qq(c).remove()},expunge:function(c){b(c),a.expunge(c)},isValid:function(b){return a.isValid(b)&&void 0!==g._getFileState(b).input}}}),qq.extend(this,{getInput:function(a){return g._getFileState(a).input
+},_attachLoadEvent:function(a,b){var c;m?e(a,b):k[a.id]=qq(a).attach("load",function(){if(p("Received response for "+a.id),a.parentNode){try{if(a.contentDocument&&a.contentDocument.body&&"false"==a.contentDocument.body.innerHTML)return}catch(d){p("Error when attempting to access iframe during handling of upload response ("+d.message+")","error"),c={success:!1}}b(c)}})},_createIframe:function(a){var b=g._getIframeName(a);return d(b)},_detachLoadEvent:function(a){void 0!==k[a]&&(k[a](),delete k[a])},_getIframeName:function(a){return a+"_"+i},_initFormForUpload:function(a){var b=a.method,c=a.endpoint,d=a.params,e=a.paramsInBody,f=a.targetName,g=qq.toElement("
"),h=c;return e?qq.obj2Inputs(d,g):h=qq.obj2url(d,c),g.setAttribute("action",h),g.setAttribute("target",f),g.style.display="none",document.body.appendChild(g),g},_parseJsonResponse:function(a){var b={};try{b=qq.parseJson(a)}catch(c){p("Error when attempting to parse iframe upload response ("+c.message+")","error")}return b}})},qq.XhrUploadHandler=function(a){"use strict";function b(a){qq.each(c._getXhrs(a),function(b,d){var e=c._getAjaxRequester(a,b);d.onreadystatechange=null,d.upload.onprogress=null,d.abort(),e&&e.canceled&&e.canceled(a)})}var c=this,d=a.options.namespace,e=a.proxy,f=a.options.chunking,g=a.options.resume,h=f&&a.options.chunking.enabled&&qq.supportedFeatures.chunking,i=g&&a.options.resume.enabled&&h&&qq.supportedFeatures.resume,j=e.getName,k=e.getSize,l=e.getUuid,m=e.getEndpoint,n=e.getDataByUuid,o=e.onUuidChanged,p=e.onProgress,q=e.log;qq.extend(this,new qq.UploadHandler(a)),qq.override(this,function(a){return{add:function(b,d){if(qq.isFile(d)||qq.isBlob(d))a.add(b,{file:d});else{if(!(d instanceof qq.BlobProxy))throw new Error("Passed obj is not a File, Blob, or proxy");a.add(b,{proxy:d})}c._initTempState(b),i&&c._maybePrepareForResume(b)},expunge:function(d){b(d),c._maybeDeletePersistedChunkData(d),c._clearXhrs(d),a.expunge(d)}}}),qq.extend(this,{clearCachedChunk:function(a,b){delete c._getFileState(a).temp.cachedChunks[b]},clearXhr:function(a,b){var d=c._getFileState(a).temp;d.xhrs&&delete d.xhrs[b],d.ajaxRequesters&&delete d.ajaxRequesters[b]},finalizeChunks:function(a,b){var d=c._getTotalChunks(a)-1,e=c._getXhr(a,d);return b?(new qq.Promise).success(b(e),e):(new qq.Promise).success({},e)},getFile:function(a){return c.isValid(a)&&c._getFileState(a).file},getProxy:function(a){return c.isValid(a)&&c._getFileState(a).proxy},getResumableFilesData:function(){var a=[];return c._iterateResumeRecords(function(b,d){c.moveInProgressToRemaining(null,d.chunking.inProgress,d.chunking.remaining);var e={name:d.name,remaining:d.chunking.remaining,size:d.size,uuid:d.uuid};d.key&&(e.key=d.key),a.push(e)}),a},isResumable:function(a){return!!f&&c.isValid(a)&&!c._getFileState(a).notResumable},moveInProgressToRemaining:function(a,b,d){var e=b||c._getFileState(a).chunking.inProgress,f=d||c._getFileState(a).chunking.remaining;e&&(e.reverse(),qq.each(e,function(a,b){f.unshift(b)}),e.length=0)},pause:function(a){return c.isValid(a)?(q(qq.format("Aborting XHR upload for {} '{}' due to pause instruction.",a,j(a))),c._getFileState(a).paused=!0,b(a),!0):void 0},reevaluateChunking:function(a){if(f&&c.isValid(a)){var b,d,e=c._getFileState(a);if(delete e.chunking,e.chunking={},b=c._getTotalChunks(a),b>1||f.mandatory){for(e.chunking.enabled=!0,e.chunking.parts=b,e.chunking.remaining=[],d=0;b>d;d++)e.chunking.remaining.push(d);c._initTempState(a)}else e.chunking.enabled=!1}},updateBlob:function(a,b){c.isValid(a)&&(c._getFileState(a).file=b)},_clearXhrs:function(a){var b=c._getFileState(a).temp;qq.each(b.ajaxRequesters,function(a){delete b.ajaxRequesters[a]}),qq.each(b.xhrs,function(a){delete b.xhrs[a]})},_createXhr:function(a,b){return c._registerXhr(a,b,qq.createXhrInstance())},_getAjaxRequester:function(a,b){var d=null==b?-1:b;return c._getFileState(a).temp.ajaxRequesters[d]},_getChunkData:function(a,b){var d=f.partSize,e=k(a),g=c.getFile(a),h=d*b,i=h+d>=e?e:h+d,j=c._getTotalChunks(a),l=this._getFileState(a).temp.cachedChunks,m=l[b]||qq.sliceBlob(g,h,i);return l[b]=m,{part:b,start:h,end:i,count:j,blob:m,size:i-h}},_getChunkDataForCallback:function(a){return{partIndex:a.part,startByte:a.start+1,endByte:a.end,totalParts:a.count}},_getLocalStorageId:function(a){var b="5.0",c=j(a),e=k(a),g=f.partSize,h=m(a);return qq.format("qq{}resume{}-{}-{}-{}-{}",d,b,c,e,g,h)},_getMimeType:function(a){return c.getFile(a).type},_getPersistableData:function(a){return c._getFileState(a).chunking},_getTotalChunks:function(a){if(f){var b=k(a),c=f.partSize;return Math.ceil(b/c)}},_getXhr:function(a,b){var d=null==b?-1:b;return c._getFileState(a).temp.xhrs[d]},_getXhrs:function(a){return c._getFileState(a).temp.xhrs},_iterateResumeRecords:function(a){i&&qq.each(localStorage,function(b,c){if(0===b.indexOf(qq.format("qq{}resume",d))){var e=JSON.parse(c);a(b,e)}})},_initTempState:function(a){c._getFileState(a).temp={ajaxRequesters:{},chunkProgress:{},xhrs:{},cachedChunks:{}}},_markNotResumable:function(a){c._getFileState(a).notResumable=!0},_maybeDeletePersistedChunkData:function(a){var b;return i&&c.isResumable(a)&&(b=c._getLocalStorageId(a),b&&localStorage.getItem(b))?(localStorage.removeItem(b),!0):!1},_maybePrepareForResume:function(a){var b,d,e=c._getFileState(a);i&&void 0===e.key&&(b=c._getLocalStorageId(a),d=localStorage.getItem(b),d&&(d=JSON.parse(d),n(d.uuid)?c._markNotResumable(a):(q(qq.format("Identified file with ID {} and name of {} as resumable.",a,j(a))),o(a,d.uuid),e.key=d.key,e.chunking=d.chunking,e.loaded=d.loaded,e.attemptingResume=!0,c.moveInProgressToRemaining(a))))},_maybePersistChunkedState:function(a){var b,d,e=c._getFileState(a);if(i&&c.isResumable(a)){b=c._getLocalStorageId(a),d={name:j(a),size:k(a),uuid:l(a),key:e.key,chunking:e.chunking,loaded:e.loaded,lastUpdated:Date.now()};try{localStorage.setItem(b,JSON.stringify(d))}catch(f){q(qq.format("Unable to save resume data for '{}' due to error: '{}'.",a,f.toString()),"warn")}}},_registerProgressHandler:function(a,b,d){var e=c._getXhr(a,b),f=j(a),g={simple:function(b,c){var d=k(a);b===c?p(a,f,d,d):p(a,f,b>=d?d-1:b,d)},chunked:function(e,g){var h=c._getFileState(a).temp.chunkProgress,i=c._getFileState(a).loaded,j=e,l=g,m=k(a),n=j-(l-d),o=i;h[b]=n,qq.each(h,function(a,b){o+=b}),p(a,f,o,m)}};e.upload.onprogress=function(a){if(a.lengthComputable){var b=null==d?"simple":"chunked";g[b](a.loaded,a.total)}}},_registerXhr:function(a,b,d,e){var f=null==b?-1:b,g=c._getFileState(a).temp;return g.xhrs=g.xhrs||{},g.ajaxRequesters=g.ajaxRequesters||{},g.xhrs[f]=d,e&&(g.ajaxRequesters[f]=e),d},_removeExpiredChunkingRecords:function(){var a=g.recordsExpireIn;c._iterateResumeRecords(function(b,c){var d=new Date(c.lastUpdated);d.setDate(d.getDate()+a),d.getTime()<=Date.now()&&(q("Removing expired resume record with key "+b),localStorage.removeItem(b))})},_shouldChunkThisFile:function(a){var b=c._getFileState(a);return b.chunking||c.reevaluateChunking(a),b.chunking.enabled}})},qq.WindowReceiveMessage=function(a){"use strict";var b={log:function(){}},c={};qq.extend(b,a),qq.extend(this,{receiveMessage:function(a,b){var d=function(a){b(a.data)};window.postMessage?c[a]=qq(window).attach("message",d):log("iframe message passing not supported in this browser!","error")},stopReceivingMessages:function(a){if(window.postMessage){var b=c[a];b&&b()}}})},function(){"use strict";qq.uiPublicApi={clearStoredFiles:function(){this._parent.prototype.clearStoredFiles.apply(this,arguments),this._templating.clearFiles()},addExtraDropzone:function(a){this._dnd&&this._dnd.setupExtraDropzone(a)},removeExtraDropzone:function(a){return this._dnd?this._dnd.removeDropzone(a):void 0},getItemByFileId:function(a){return this._templating.isHiddenForever(a)?void 0:this._templating.getFileContainer(a)},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()}).getButtonId()),this._dnd&&(this._dnd.dispose(),this._dnd=this._setupDragAndDrop()),this._totalFilesInBatch=0,this._filesInBatchAddedToUi=0,this._setupClickAndEditEventHandlers()},setName:function(a,b){var c=this._options.formatFileName(b);this._parent.prototype.setName.apply(this,arguments),this._templating.updateFilename(a,c)},pauseUpload:function(a){var b=this._parent.prototype.pauseUpload.apply(this,arguments);return b&&this._templating.uploadPaused(a),b},continueUpload:function(a){var b=this._parent.prototype.continueUpload.apply(this,arguments);return b&&this._templating.uploadContinued(a),b},getId:function(a){return this._templating.getFileId(a)},getDropTarget:function(a){var b=this.getFile(a);return b.qqDropTarget}},qq.uiPrivateApi={_getButton:function(a){var b=this._parent.prototype._getButton.apply(this,arguments);return b||a===this._defaultButtonId&&(b=this._templating.getButton()),b},_removeFileItem:function(a){this._templating.removeFile(a)},_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 a=this,b=this._options.dragAndDrop.extraDropzones,c=this._templating,d=c.getDropZone();return d&&b.push(d),new qq.DragAndDrop({dropZoneElements:b,allowMultipleItems:this._options.multiple,classes:{dropActive:this._options.classes.dropActive},callbacks:{processingDroppedFiles:function(){c.showDropProcessing()},processingDroppedFilesComplete:function(b,d){c.hideDropProcessing(),qq.each(b,function(a,b){b.qqDropTarget=d}),b.length&&a.addFiles(b,null,null)},dropError:function(b,c){a._itemError(b,c)},dropLog:function(b,c){a.log(b,c)}}})},_bindFileButtonsClickEvent:function(){var a=this;return new qq.FileButtonsClickHandler({templating:this._templating,log:function(b,c){a.log(b,c)},onDeleteFile:function(b){a.deleteFile(b)},onCancel:function(b){a.cancel(b)},onRetry:function(b){qq(a._templating.getFileContainer(b)).removeClass(a._classes.retryable),a._templating.hideRetry(b),a.retry(b)},onPause:function(b){a.pauseUpload(b)},onContinue:function(b){a.continueUpload(b)},onGetName:function(b){return a.getName(b)}})},_isEditFilenameEnabled:function(){return this._templating.isEditFilenamePossible()&&!this._options.autoUpload&&qq.FilenameClickHandler&&qq.FilenameInputFocusHandler&&qq.FilenameInputFocusHandler},_filenameEditHandler:function(){var a=this,b=this._templating;return{templating:b,log:function(b,c){a.log(b,c)},onGetUploadStatus:function(b){return a.getUploads({id:b}).status},onGetName:function(b){return a.getName(b)},onSetName:function(b,c){a.setName(b,c)},onEditingStatusChange:function(a,c){var d=qq(b.getEditInput(a)),e=qq(b.getFileContainer(a));c?(d.addClass("qq-editing"),b.hideFilename(a),b.hideEditIcon(a)):(d.removeClass("qq-editing"),b.showFilename(a),b.showEditIcon(a)),e.addClass("qq-temp").removeClass("qq-temp")}}},_onUploadStatusChange:function(a,b,c){this._parent.prototype._onUploadStatusChange.apply(this,arguments),this._isEditFilenameEnabled()&&this._templating.getFileContainer(a)&&c!==qq.status.SUBMITTED&&(this._templating.markFilenameEditable(a),this._templating.hideEditIcon(a)),c===qq.status.UPLOAD_RETRYING?(this._templating.setStatusText(a),qq(this._templating.getFileContainer(a)).removeClass(this._classes.retrying)):c===qq.status.UPLOAD_FAILED&&this._templating.hidePause(a)},_bindFilenameInputFocusInEvent:function(){var a=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusInHandler(a)},_bindFilenameInputFocusEvent:function(){var a=qq.extend({},this._filenameEditHandler());return new qq.FilenameInputFocusHandler(a)},_bindFilenameClickEvent:function(){var a=qq.extend({},this._filenameEditHandler());return new qq.FilenameClickHandler(a)},_storeForLater:function(a){this._parent.prototype._storeForLater.apply(this,arguments),this._templating.hideSpinner(a)},_onAllComplete:function(){this._parent.prototype._onAllComplete.apply(this,arguments),this._templating.resetTotalProgress()},_onSubmit:function(a,b){var c=this.getFile(a);c&&c.qqPath&&this._options.dragAndDrop.reportDirectoryPaths&&this._paramsStore.addReadOnly(a,{qqpath:c.qqPath}),this._parent.prototype._onSubmit.apply(this,arguments),this._addToList(a,b)},_onSubmitted:function(a){this._isEditFilenameEnabled()&&(this._templating.markFilenameEditable(a),this._templating.showEditIcon(a),this._focusinEventSupported||this._filenameInputFocusHandler.addHandler(this._templating.getEditInput(a)))},_onProgress:function(a,b,c,d){this._parent.prototype._onProgress.apply(this,arguments),this._templating.updateProgress(a,c,d),100===Math.round(100*(c/d))?(this._templating.hideCancel(a),this._templating.hidePause(a),this._templating.hideProgress(a),this._templating.setStatusText(a,this._options.text.waitingForResponse),this._displayFileSize(a)):this._displayFileSize(a,c,d)},_onTotalProgress:function(a,b){this._parent.prototype._onTotalProgress.apply(this,arguments),this._templating.updateTotalProgress(a,b)},_onComplete:function(a,b,c){function d(b){g&&(f.setStatusText(a),qq(g).removeClass(h._classes.retrying),f.hideProgress(a),h.getUploads({id:a}).status!==qq.status.UPLOAD_FAILED&&f.hideCancel(a),f.hideSpinner(a),b.success?h._markFileAsSuccessful(a):(qq(g).addClass(h._classes.fail),f.showCancel(a),f.isRetryPossible()&&!h._preventRetries[a]&&(qq(g).addClass(h._classes.retryable),f.showRetry(a)),h._controlFailureTextDisplay(a,b)))}var e=this._parent.prototype._onComplete.apply(this,arguments),f=this._templating,g=f.getFileContainer(a),h=this;return e instanceof qq.Promise?e.done(function(a){d(a)}):d(c),e},_markFileAsSuccessful:function(a){var b=this._templating;this._isDeletePossible()&&b.showDeleteButton(a),qq(b.getFileContainer(a)).addClass(this._classes.success),this._maybeUpdateThumbnail(a)},_onUploadPrep:function(a){this._parent.prototype._onUploadPrep.apply(this,arguments),this._templating.showSpinner(a)},_onUpload:function(a){var b=this._parent.prototype._onUpload.apply(this,arguments);return this._templating.showSpinner(a),b},_onUploadChunk:function(a,b){this._parent.prototype._onUploadChunk.apply(this,arguments),b.partIndex>0&&this._handler.isResumable(a)&&this._templating.allowPause(a)},_onCancel:function(a){this._parent.prototype._onCancel.apply(this,arguments),this._removeFileItem(a),0===this._getNotFinished()&&this._templating.resetTotalProgress()},_onBeforeAutoRetry:function(a){var b,c,d;this._parent.prototype._onBeforeAutoRetry.apply(this,arguments),this._showCancelLink(a),this._options.retry.showAutoRetryNote&&(b=this._autoRetries[a],c=this._options.retry.maxAutoAttempts,d=this._options.retry.autoRetryNote.replace(/\{retryNum\}/g,b),d=d.replace(/\{maxAuto\}/g,c),this._templating.setStatusText(a,d),qq(this._templating.getFileContainer(a)).addClass(this._classes.retrying))},_onBeforeManualRetry:function(a){return this._parent.prototype._onBeforeManualRetry.apply(this,arguments)?(this._templating.resetProgress(a),qq(this._templating.getFileContainer(a)).removeClass(this._classes.fail),this._templating.setStatusText(a),this._templating.showSpinner(a),this._showCancelLink(a),!0):(qq(this._templating.getFileContainer(a)).addClass(this._classes.retryable),this._templating.showRetry(a),!1)},_onSubmitDelete:function(a){var b=qq.bind(this._onSubmitDeleteSuccess,this);this._parent.prototype._onSubmitDelete.call(this,a,b)},_onSubmitDeleteSuccess:function(){this._options.deleteFile.forceConfirm?this._showDeleteConfirm.apply(this,arguments):this._sendDeleteRequest.apply(this,arguments)},_onDeleteComplete:function(a,b,c){this._parent.prototype._onDeleteComplete.apply(this,arguments),this._templating.hideSpinner(a),c?(this._templating.setStatusText(a,this._options.deleteFile.deletingFailedText),this._templating.showDeleteButton(a)):this._removeFileItem(a)},_sendDeleteRequest:function(a){this._templating.hideDeleteButton(a),this._templating.showSpinner(a),this._templating.setStatusText(a,this._options.deleteFile.deletingStatusText),this._deleteHandler.sendDelete.apply(this,arguments)},_showDeleteConfirm:function(a){var b,c=this.getName(a),d=this._options.deleteFile.confirmMessage.replace(/\{filename\}/g,c),e=(this.getUuid(a),arguments),f=this;b=this._options.showConfirm(d),qq.isGenericPromise(b)?b.then(function(){f._sendDeleteRequest.apply(f,e)}):b!==!1&&f._sendDeleteRequest.apply(f,e)},_addToList:function(a,b,c){var d,e,f=0,g=this._handler.isProxied(a)&&this._options.scaling.hideScaled;this._options.display.prependFiles&&(this._totalFilesInBatch>1&&this._filesInBatchAddedToUi>0&&(f=this._filesInBatchAddedToUi-1),d={index:f}),c||(this._options.disableCancelForFormUploads&&!qq.supportedFeatures.ajaxUploading&&this._templating.disableCancel(),this._options.multiple||(e=this.getUploads({id:a}),this._handledProxyGroup=this._handledProxyGroup||e.proxyGroupId,e.proxyGroupId===this._handledProxyGroup&&e.proxyGroupId||(this._handler.cancelAll(),this._clearList(),this._handledProxyGroup=null))),this._templating.addFile(a,this._options.formatFileName(b),d,g),c?this._thumbnailUrls[a]&&this._templating.updateThumbnail(a,this._thumbnailUrls[a],!0):this._templating.generatePreview(a,this.getFile(a)),this._filesInBatchAddedToUi+=1,(c||this._options.display.fileSizeOnSubmit&&qq.supportedFeatures.ajaxUploading)&&this._displayFileSize(a)},_clearList:function(){this._templating.clearFiles(),this.clearStoredFiles()},_displayFileSize:function(a,b,c){var d=this.getSize(a),e=this._formatSize(d);d>=0&&(void 0!==b&&void 0!==c&&(e=this._formatProgress(b,c)),this._templating.updateSize(a,e))},_formatProgress:function(a,b){function c(a,b){d=d.replace(a,b)}var d=this._options.text.formatProgress;return c("{percent}",Math.round(100*(a/b))),c("{total_size}",this._formatSize(b)),d},_controlFailureTextDisplay:function(a,b){var c,d,e;c=this._options.failedUploadTextDisplay.mode,d=this._options.failedUploadTextDisplay.responseProperty,"custom"===c?(e=b[d],e||(e=this._options.text.failUpload),this._templating.setStatusText(a,e),this._options.failedUploadTextDisplay.enableTooltip&&this._showTooltip(a,e)):"default"===c?this._templating.setStatusText(a,this._options.text.failUpload):"none"!==c&&this.log("failedUploadTextDisplay.mode value of '"+c+"' is not valid","warn")},_showTooltip:function(a,b){this._templating.getFileContainer(a).title=b},_showCancelLink:function(a){(!this._options.disableCancelForFormUploads||qq.supportedFeatures.ajaxUploading)&&this._templating.showCancel(a)},_itemError:function(){var a=this._parent.prototype._itemError.apply(this,arguments);this._options.showMessage(a)},_batchError:function(a){this._parent.prototype._batchError.apply(this,arguments),this._options.showMessage(a)},_setupPastePrompt:function(){var a=this;this._options.callbacks.onPasteReceived=function(){var b=a._options.paste.namePromptMessage,c=a._options.paste.defaultName;return a._options.showPrompt(b,c)}},_fileOrBlobRejected:function(){this._totalFilesInBatch-=1,this._parent.prototype._fileOrBlobRejected.apply(this,arguments)},_prepareItemsForUpload:function(a){this._totalFilesInBatch=a.length,this._filesInBatchAddedToUi=0,this._parent.prototype._prepareItemsForUpload.apply(this,arguments)},_maybeUpdateThumbnail:function(a){var b=this._thumbnailUrls[a],c=this.getUploads({id:a}).status;c===qq.status.DELETED||!b&&!this._options.thumbnails.placeholders.waitUntilResponse&&qq.supportedFeatures.imagePreviews||this._templating.updateThumbnail(a,b)},_addCannedFile:function(){var a=this._parent.prototype._addCannedFile.apply(this,arguments);return this._addToList(a,this.getName(a),!0),this._templating.hideSpinner(a),this._templating.hideCancel(a),this._markFileAsSuccessful(a),a},_setSize:function(a,b){this._parent.prototype._setSize.apply(this,arguments),this._templating.updateSize(a,this._formatSize(b))}}}(),qq.FineUploader=function(a,b){"use strict";var c=this;this._parent=b?qq[b].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:{maxCount:0,placeholders:{waitUntilResponse:!1,notAvailablePath:null,waitingPath:null},timeBetweenThumbs:750},scaling:{hideScaled:!1},showMessage:function(a){return c._templating.hasDialog("alert")?c._templating.showDialog("alert",a):(setTimeout(function(){window.alert(a)},0),void 0)},showConfirm:function(a){return c._templating.hasDialog("confirm")?c._templating.showDialog("confirm",a):window.confirm(a)},showPrompt:function(a,b){return c._templating.hasDialog("prompt")?c._templating.showDialog("prompt",a,b):window.prompt(a,b)}},!0),qq.extend(this._options,a,!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()}).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(a){"use strict";var b,c,d,e,f,g,h,i,j="qq-file-id",k="qq-file-id-",l="qq-max-size",m="qq-server-scale",n="qq-hide-dropzone",o="qq-drop-area-text",p="qq-in-progress",q="qq-hidden-forever",r=!1,s=0,t=!1,u=[],v=-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"}},x={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"},y={},z=new qq.Promise,A=new qq.Promise,B=function(){var a=w.placeholders.thumbnailNotAvailable,c=w.placeholders.waitingForThumbnail,d={maxSize:v,scale:i};h&&(a?w.imageGenerator.generate(a,new Image,d).then(function(a){z.success(a)},function(){z.failure(),b("Problem loading 'not available' placeholder image at "+a,"error")}):z.failure(),c?w.imageGenerator.generate(c,new Image,d).then(function(a){A.success(a)},function(){A.failure(),b("Problem loading 'waiting for thumbnail' placeholder image at "+c,"error")}):A.failure())},C=function(a){var b=new qq.Promise;return A.then(function(c){V(c,a),a.src?b.success():(a.src=c.src,a.onload=function(){a.onload=null,ab(a),b.success()})},function(){U(a),b.success()}),b},D=function(a,c,d){var e=T(a);return b("Generating new thumbnail for "+a),c.qqThumbnailId=a,w.imageGenerator.generate(c,e,d).then(function(){s++,ab(e),y[a].success()},function(){y[a].failure(),w.placeholders.waitUntilUpdate||W(a,e)})},E=function(){if(u.length){t=!0;var a=u.shift();a.update?$(a):Z(a)}else t=!1},F=function(a){return S(L(a),x.cancel)},G=function(a){return S(L(a),x.continueButton)},H=function(a){return S(f,x[a+"Dialog"])},I=function(a){return S(L(a),x.deleteButton)},J=function(){return S(f,x.dropProcessing)},K=function(a){return S(L(a),x.editNameIcon)},L=function(a){return qq(g).getByClass(k+a)[0]},M=function(a){return S(L(a),x.file)},N=function(a){return S(L(a),x.pause)},O=function(a){return null==a?S(f,x.totalProgressBarContainer)||S(f,x.totalProgressBar):S(L(a),x.progressBarContainer)||S(L(a),x.progressBar)},P=function(a){return S(L(a),x.retry)},Q=function(a){return S(L(a),x.size)},R=function(a){return S(L(a),x.spinner)},S=function(a,b){return a&&qq(a).getByClass(b)[0]},T=function(a){return h&&S(L(a),x.thumbnail)},U=function(a){a&&qq(a).addClass(w.classes.hide)},V=function(a,b){var c=a.style.maxWidth,d=a.style.maxHeight;d&&c&&!b.style.maxWidth&&!b.style.maxHeight&&qq(b).css({maxWidth:c,maxHeight:d})},W=function(a,b){var c=y[a]||(new qq.Promise).failure(),d=new qq.Promise;return z.then(function(a){c.then(function(){d.success()},function(){V(a,b),b.onload=function(){b.onload=null,d.success()},b.src=a.src,ab(b)})}),d},X=function(){var a,e,f,g,j,k,p,q,r,s,t;if(b("Parsing template"),null==w.templateIdOrEl)throw new Error("You MUST specify either a template element or ID!");if(qq.isString(w.templateIdOrEl)){if(a=document.getElementById(w.templateIdOrEl),null===a)throw new Error(qq.format("Cannot find template script at ID '{}'!",w.templateIdOrEl));e=a.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.");e=w.templateIdOrEl.innerHTML}if(e=qq.trimStr(e),g=document.createElement("div"),g.appendChild(qq.toElement(e)),t=qq(g).getByClass(x.uploader)[0],w.button&&(k=qq(g).getByClass(x.button)[0],k&&qq(k).remove()),qq.DragAndDrop&&qq.supportedFeatures.fileDrop||(r=qq(g).getByClass(x.dropProcessing)[0],r&&qq(r).remove()),p=qq(g).getByClass(x.drop)[0],p&&!qq.DragAndDrop&&(b("DnD module unavailable.","info"),qq(p).remove()),qq.supportedFeatures.fileDrop?qq(t).hasAttribute(o)&&p&&(s=qq(p).getByClass(x.dropText)[0],s&&qq(s).remove()):(t.removeAttribute(o),p&&qq(p).hasAttribute(n)&&qq(p).css({display:"none"})),q=qq(g).getByClass(x.thumbnail)[0],h?q&&(v=parseInt(q.getAttribute(l)),v=v>0?v:null,i=qq(q).hasAttribute(m)):q&&qq(q).remove(),h=h&&q,c=qq(g).getByClass(x.editFilenameInput).length>0,d=qq(g).getByClass(x.retry).length>0,f=qq(g).getByClass(x.list)[0],null==f)throw new Error("Could not find the file list container in the template!");return j=f.innerHTML,f.innerHTML="",g.getElementsByTagName("DIALOG").length&&document.createElement("dialog"),b("Template parsing complete"),{template:qq.trimStr(g.innerHTML),fileTemplate:qq.trimStr(j)}},Y=function(a,b){var c=g,d=c.firstChild;b>0&&(d=qq(c).children()[b].nextSibling),c.insertBefore(a,d)},Z=function(a){var b=a.id,c=a.optFileOrBlob,d=c&&c.qqThumbnailId,e=T(b),f={maxSize:v,scale:!0,orient:!0};qq.supportedFeatures.imagePreviews?e?w.limits.maxThumbs&&w.limits.maxThumbs<=s?(W(b,e),E()):C(e).done(function(){y[b]=new qq.Promise,y[b].done(function(){setTimeout(E,w.limits.timeBetweenThumbs)}),null!=d?bb(b,d):D(b,c,f)}):E():e&&(C(e),E())},$=function(a){var b=a.id,c=a.thumbnailUrl,d=a.showWaitingImg,e=T(b),f={maxSize:v,scale:i};if(e)if(c){if(!(w.limits.maxThumbs&&w.limits.maxThumbs<=s))return d&&C(e),w.imageGenerator.generate(c,e,f).then(function(){ab(e),s++,setTimeout(E,w.limits.timeBetweenThumbs)},function(){W(b,e),setTimeout(E,w.limits.timeBetweenThumbs)});W(b,e),E()}else W(b,e),E()},_=function(a,b){var c=O(a),d=null==a?x.totalProgressBar:x.progressBar;c&&!qq(c).hasClass(d)&&(c=qq(c).getByClass(d)[0]),c&&(qq(c).css({width:b+"%"}),c.setAttribute("aria-valuenow",b))},ab=function(a){a&&qq(a).removeClass(w.classes.hide)},bb=function(a,c){var d=T(a),e=T(c);b(qq.format("ID {} is the same file as ID {}. Will use generated thumbnail from ID {} instead.",a,c,c)),y[c].then(function(){s++,y[a].success(),b(qq.format("Now using previously generated thumbnail created for ID {} on ID {}.",c,a)),d.src=e.src,ab(d)},function(){y[a].failure(),w.placeholders.waitUntilUpdate||W(a,d)})};qq.extend(w,a),b=w.log,qq.supportedFeatures.imagePreviews||(w.limits.timeBetweenThumbs=0,w.limits.maxThumbs=0),f=w.containerEl,h=void 0!==w.imageGenerator,e=X(),B(),qq.extend(this,{render:function(){b("Rendering template in DOM."),s=0,f.innerHTML=e.template,U(J()),this.hideTotalProgress(),g=w.fileContainerEl||S(f,x.list),b("Template rendering complete")},renderFailure:function(a){var b=qq.toElement(a);f.innerHTML="",f.appendChild(b)},reset:function(){this.render()},clearFiles:function(){g.innerHTML=""},disableCancel:function(){r=!0},addFile:function(a,b,c,d){var h,i=qq.toElement(e.fileTemplate),l=S(i,x.file),m=S(f,x.uploader);qq(i).addClass(k+a),m.removeAttribute(o),l&&(qq(l).setText(b),l.setAttribute("title",b)),i.setAttribute(j,a),c?Y(i,c.index):g.appendChild(i),d?(i.style.display="none",qq(i).addClass(q)):(U(O(a)),U(Q(a)),U(I(a)),U(P(a)),U(N(a)),U(G(a)),r&&this.hideCancel(a),h=T(a),h&&!h.src&&A.then(function(a){h.src=a.src,a.style.maxHeight&&a.style.maxWidth&&qq(h).css({maxHeight:a.style.maxHeight,maxWidth:a.style.maxWidth}),ab(h)}))},removeFile:function(a){qq(L(a)).remove()},getFileId:function(a){var b=a;if(b){for(;null==b.getAttribute(j);)b=b.parentNode;return parseInt(b.getAttribute(j))}},getFileList:function(){return g},markFilenameEditable:function(a){var b=M(a);b&&qq(b).addClass(w.classes.editable)
+},updateFilename:function(a,b){var c=M(a);c&&(qq(c).setText(b),c.setAttribute("title",b))},hideFilename:function(a){U(M(a))},showFilename:function(a){ab(M(a))},isFileName:function(a){return qq(a).hasClass(x.file)},getButton:function(){return w.button||S(f,x.button)},hideDropProcessing:function(){U(J())},showDropProcessing:function(){ab(J())},getDropZone:function(){return S(f,x.drop)},isEditFilenamePossible:function(){return c},hideRetry:function(a){U(P(a))},isRetryPossible:function(){return d},showRetry:function(a){ab(P(a))},getFileContainer:function(a){return L(a)},showEditIcon:function(a){var b=K(a);b&&qq(b).addClass(w.classes.editable)},isHiddenForever:function(a){return qq(L(a)).hasClass(q)},hideEditIcon:function(a){var b=K(a);b&&qq(b).removeClass(w.classes.editable)},isEditIcon:function(a){return qq(a).hasClass(x.editNameIcon,!0)},getEditInput:function(a){return S(L(a),x.editFilenameInput)},isEditInput:function(a){return qq(a).hasClass(x.editFilenameInput,!0)},updateProgress:function(a,b,c){var d,e=O(a);e&&c>0&&(d=Math.round(100*(b/c)),100===d?U(e):ab(e),_(a,d))},updateTotalProgress:function(a,b){this.updateProgress(null,a,b)},hideProgress:function(a){var b=O(a);b&&U(b)},hideTotalProgress:function(){this.hideProgress()},resetProgress:function(a){_(a,0),this.hideTotalProgress(a)},resetTotalProgress:function(){this.resetProgress()},showCancel:function(a){if(!r){var b=F(a);b&&qq(b).removeClass(w.classes.hide)}},hideCancel:function(a){U(F(a))},isCancel:function(a){return qq(a).hasClass(x.cancel,!0)},allowPause:function(a){ab(N(a)),U(G(a))},uploadPaused:function(a){this.setStatusText(a,w.text.paused),this.allowContinueButton(a),U(R(a))},hidePause:function(a){U(N(a))},isPause:function(a){return qq(a).hasClass(x.pause,!0)},isContinueButton:function(a){return qq(a).hasClass(x.continueButton,!0)},allowContinueButton:function(a){ab(G(a)),U(N(a))},uploadContinued:function(a){this.setStatusText(a,""),this.allowPause(a),ab(R(a))},showDeleteButton:function(a){ab(I(a))},hideDeleteButton:function(a){U(I(a))},isDeleteButton:function(a){return qq(a).hasClass(x.deleteButton,!0)},isRetry:function(a){return qq(a).hasClass(x.retry,!0)},updateSize:function(a,b){var c=Q(a);c&&(ab(c),qq(c).setText(b))},setStatusText:function(a,b){var c=S(L(a),x.statusText);c&&(null==b?qq(c).clearText():qq(c).setText(b))},hideSpinner:function(a){qq(L(a)).removeClass(p),U(R(a))},showSpinner:function(a){qq(L(a)).addClass(p),ab(R(a))},generatePreview:function(a,b){this.isHiddenForever(a)||(u.push({id:a,optFileOrBlob:b}),!t&&E())},updateThumbnail:function(a,b,c){this.isHiddenForever(a)||(u.push({update:!0,id:a,thumbnailUrl:b,showWaitingImg:c}),!t&&E())},hasDialog:function(a){return qq.supportedFeatures.dialogElement&&!!H(a)},showDialog:function(a,b,c){var d=H(a),e=S(d,x.dialogMessage),f=d.getElementsByTagName("INPUT")[0],g=S(d,x.dialogCancelButton),h=S(d,x.dialogOkButton),i=new qq.Promise,j=function(){g.removeEventListener("click",k),h&&h.removeEventListener("click",l),i.failure()},k=function(){g.removeEventListener("click",k),d.close()},l=function(){d.removeEventListener("close",j),h.removeEventListener("click",l),d.close(),i.success(f&&f.value)};return d.addEventListener("close",j),g.addEventListener("click",k),h&&h.addEventListener("click",l),f&&(f.value=c),e.textContent=b,d.showModal(),i}})},qq.s3=qq.s3||{},qq.s3.util=qq.s3.util||function(){"use strict";return{AWS_PARAM_PREFIX:"x-amz-meta-",SESSION_TOKEN_PARAM_NAME:"x-amz-security-token",REDUCED_REDUNDANCY_PARAM_NAME:"x-amz-storage-class",REDUCED_REDUNDANCY_PARAM_VALUE:"REDUCED_REDUNDANCY",SERVER_SIDE_ENCRYPTION_PARAM_NAME:"x-amz-server-side-encryption",SERVER_SIDE_ENCRYPTION_PARAM_VALUE:"AES256",getBucket:function(a){var b,c=[/^(?:https?:\/\/)?([a-z0-9.\-_]+)\.s3(?:-[a-z0-9\-]+)?\.amazonaws\.com/i,/^(?:https?:\/\/)?s3(?:-[a-z0-9\-]+)?\.amazonaws\.com\/([a-z0-9.\-_]+)/i,/^(?:https?:\/\/)?([a-z0-9.\-_]+)/i];return qq.each(c,function(c,d){var e=d.exec(a);return e?(b=e[1],!1):void 0}),b},getPolicy:function(a){var b={},c=[],d=a.bucket,e=a.key,f=a.acl,g=a.type,h=new Date,i=a.expectedStatus,j=a.sessionToken,k=a.params,l=qq.s3.util.getSuccessRedirectAbsoluteUrl(a.successRedirectUrl),m=a.minFileSize,n=a.maxFileSize,o=a.reducedRedundancy,p=a.serverSideEncryption;return b.expiration=qq.s3.util.getPolicyExpirationDate(h),c.push({acl:f}),c.push({bucket:d}),g&&c.push({"Content-Type":g}),i&&c.push({success_action_status:i.toString()}),l&&c.push({success_action_redirect:l}),o&&(c.push({}),c[c.length-1][qq.s3.util.REDUCED_REDUNDANCY_PARAM_NAME]=qq.s3.util.REDUCED_REDUNDANCY_PARAM_VALUE),j&&(c.push({}),c[c.length-1][qq.s3.util.SESSION_TOKEN_PARAM_NAME]=j),p&&(c.push({}),c[c.length-1][qq.s3.util.SERVER_SIDE_ENCRYPTION_PARAM_NAME]=qq.s3.util.SERVER_SIDE_ENCRYPTION_PARAM_VALUE),c.push({key:e}),qq.each(k,function(a,b){var d=qq.s3.util.AWS_PARAM_PREFIX+a,e={};e[d]=encodeURIComponent(b),c.push(e)}),b.conditions=c,qq.s3.util.enforceSizeLimits(b,m,n),b},refreshPolicyCredentials:function(a,b){var c=!1;qq.each(a.conditions,function(a,d){qq.each(d,function(a){a===qq.s3.util.SESSION_TOKEN_PARAM_NAME&&(d[a]=b,c=!0)})}),c||(a.conditions.push({}),a.conditions[a.conditions.length-1][qq.s3.util.SESSION_TOKEN_PARAM_NAME]=b)},generateAwsParams:function(a,b){var c={},d=a.params,e=new qq.Promise,f=qq.s3.util.getPolicy(a),g=a.sessionToken,h=a.type,i=a.key,j=a.accessKey,k=a.acl,l=a.expectedStatus,m=qq.s3.util.getSuccessRedirectAbsoluteUrl(a.successRedirectUrl),n=a.reducedRedundancy,o=a.serverSideEncryption,p=a.log;return c.key=i,c.AWSAccessKeyId=j,h&&(c["Content-Type"]=h),l&&(c.success_action_status=l),m&&(c.success_action_redirect=m),n&&(c[qq.s3.util.REDUCED_REDUNDANCY_PARAM_NAME]=qq.s3.util.REDUCED_REDUNDANCY_PARAM_VALUE),o&&(c[qq.s3.util.SERVER_SIDE_ENCRYPTION_PARAM_NAME]=qq.s3.util.SERVER_SIDE_ENCRYPTION_PARAM_VALUE),g&&(c[qq.s3.util.SESSION_TOKEN_PARAM_NAME]=g),c.acl=k,qq.each(d,function(a,b){var d=qq.s3.util.AWS_PARAM_PREFIX+a;c[d]=encodeURIComponent(b)}),b(f).then(function(a,b,d){c.policy=a.policy,c.signature=a.signature,b&&(c.AWSAccessKeyId=b),d&&(c[qq.s3.util.SESSION_TOKEN_PARAM_NAME]=d),e.success(c)},function(a){a=a||"Can't continue further with request to S3 as we did not receive a valid signature and policy from the server.",p("Policy signing failed. "+a,"error"),e.failure(a)}),e},enforceSizeLimits:function(a,b,c){var d=0>b?0:b,e=0>=c?9007199254740992:c;(b>0||c>0)&&a.conditions.push(["content-length-range",d.toString(),e.toString()])},getPolicyExpirationDate:function(a){if(a.setMinutes(a.getMinutes()+5),Date.prototype.toISOString)return a.toISOString();var b=function(a){var b=String(a);return 1===b.length&&(b="0"+b),b};return a.getUTCFullYear()+"-"+b(a.getUTCMonth()+1)+"-"+b(a.getUTCDate())+"T"+b(a.getUTCHours())+":"+b(a.getUTCMinutes())+":"+b(a.getUTCSeconds())+"."+String((a.getUTCMilliseconds()/1e3).toFixed(3)).slice(2,5)+"Z"},parseIframeResponse:function(a){var b=a.contentDocument||a.contentWindow.document,c=b.location.search,d=/bucket=(.+)&key=(.+)&etag=(.+)/.exec(c);return d?{bucket:d[1],key:d[2],etag:d[3].replace(/%22/g,"")}:void 0},getSuccessRedirectAbsoluteUrl:function(a){if(a){var b,c=document.createElement("div");return qq.ie7()?(c.innerHTML="",b=c.firstChild,b.href):(b=document.createElement("a"),b.href=a,b.href=b.href,b.href)}},encodeQueryStringParam:function(a){var b=encodeURIComponent(a);return b=b.replace(/[!'()]/g,escape),b=b.replace(/\*/g,"%2A"),b.replace(/%20/g,"+")}}}(),function(){"use strict";qq.nonTraditionalBasePublicApi={setUploadSuccessParams:function(a,b){this._uploadSuccessParamsStore.set(a,b)},setUploadSuccessEndpoint:function(a,b){this._uploadSuccessEndpointStore.set(a,b)}},qq.nonTraditionalBasePrivateApi={_onComplete:function(a,b,c,d){var e,f,g=c.success?!0:!1,h=this,i=arguments,j=this._uploadSuccessEndpointStore.get(a),k=this._options.uploadSuccess.customHeaders,l=this._options.uploadSuccess.method,m=this._options.cors,n=new qq.Promise,o=this._uploadSuccessParamsStore.get(a),p=this._paramsStore.get(a),q=function(b){delete h._failedSuccessRequestCallbacks[a],qq.extend(c,b),qq.FineUploaderBasic.prototype._onComplete.apply(h,i),n.success(b)},r=function(f){var g=e;qq.extend(c,f),c&&c.reset&&(g=null),g?h._failedSuccessRequestCallbacks[a]=g:delete h._failedSuccessRequestCallbacks[a],h._onAutoRetry(a,b,c,d,g)||(qq.FineUploaderBasic.prototype._onComplete.apply(h,i),n.failure(f))};return g&&j?(f=new qq.UploadSuccessAjaxRequester({endpoint:j,method:l,customHeaders:k,cors:m,log:qq.bind(this.log,this)}),qq.extend(o,h._getEndpointSpecificParams(a,c,d),!0),p&&qq.extend(o,p,!0),e=qq.bind(function(){f.sendSuccessRequest(a,o).then(q,r)},h),e(),n):qq.FineUploaderBasic.prototype._onComplete.apply(this,arguments)},_manualRetry:function(a){var b=this._failedSuccessRequestCallbacks[a];return qq.FineUploaderBasic.prototype._manualRetry.call(this,a,b)}}}(),function(){"use strict";qq.s3.FineUploaderBasic=function(a){var b={request:{accessKey:null},objectProperties:{acl:"private",bucket:qq.bind(function(a){return qq.s3.util.getBucket(this.getEndpoint(a))},this),key:"uuid",reducedRedundancy:!1,serverSideEncryption:!1},credentials:{accessKey:null,secretKey:null,expiration:null,sessionToken:null},signature:{endpoint:null,customHeaders:{}},uploadSuccess:{endpoint:null,method:"POST",params:{},customHeaders:{}},iframeSupport:{localBlankPagePath:null},chunking:{partSize:5242880},cors:{allowXdr:!0},callbacks:{onCredentialsExpired:function(){}}};qq.extend(b,a,!0),this.setCredentials(b.credentials,!0)||(this._currentCredentials.accessKey=b.request.accessKey),this._aclStore=this._createStore(b.objectProperties.acl),qq.FineUploaderBasic.call(this,b),this._uploadSuccessParamsStore=this._createStore(this._options.uploadSuccess.params),this._uploadSuccessEndpointStore=this._createStore(this._options.uploadSuccess.endpoint),this._failedSuccessRequestCallbacks={},this._cannedKeys={},this._cannedBuckets={},this._buckets={}},qq.extend(qq.s3.FineUploaderBasic.prototype,qq.basePublicApi),qq.extend(qq.s3.FineUploaderBasic.prototype,qq.basePrivateApi),qq.extend(qq.s3.FineUploaderBasic.prototype,qq.nonTraditionalBasePublicApi),qq.extend(qq.s3.FineUploaderBasic.prototype,qq.nonTraditionalBasePrivateApi),qq.extend(qq.s3.FineUploaderBasic.prototype,{getBucket:function(a){return null==this._cannedBuckets[a]?this._buckets[a]:this._cannedBuckets[a]},getKey:function(a){return null==this._cannedKeys[a]?this._handler.getThirdPartyFileId(a):this._cannedKeys[a]},reset:function(){qq.FineUploaderBasic.prototype.reset.call(this),this._failedSuccessRequestCallbacks=[],this._buckets={}},setCredentials:function(a,b){if(a&&a.secretKey){if(!a.accessKey)throw new qq.Error("Invalid credentials: no accessKey");if(!a.expiration)throw new qq.Error("Invalid credentials: no expiration");return this._currentCredentials=qq.extend({},a),qq.isString(a.expiration)&&(this._currentCredentials.expiration=new Date(a.expiration)),!0}if(!b)throw new qq.Error("Invalid credentials parameter!");this._currentCredentials={}},setAcl:function(a,b){this._aclStore.set(a,b)},_createUploadHandler:function(){var a=this,b={aclStore:this._aclStore,getBucket:qq.bind(this._determineBucket,this),getKeyName:qq.bind(this._determineKeyName,this),iframeSupport:this._options.iframeSupport,objectProperties:this._options.objectProperties,signature:this._options.signature,validation:{minSizeLimit:this._options.validation.minSizeLimit,maxSizeLimit:this._options.validation.sizeLimit}};return qq.override(this._endpointStore,function(a){return{get:function(b){var c=a.get(b);return c.indexOf("http")<0?"http://"+c:c}}}),qq.override(this._paramsStore,function(a){return{get:function(b){var c=a.get(b),d={};return qq.each(c,function(a,b){d[a.toLowerCase()]=qq.isFunction(b)?b():b}),d}}}),b.signature.credentialsProvider={get:function(){return a._currentCredentials},onExpired:function(){var b=new qq.Promise,c=a._options.callbacks.onCredentialsExpired();return qq.isGenericPromise(c)?c.then(function(c){try{a.setCredentials(c),b.success()}catch(d){a.log("Invalid credentials returned from onCredentialsExpired callback! ("+d.message+")","error"),b.failure("onCredentialsExpired did not return valid credentials.")}},function(c){a.log("onCredentialsExpired callback indicated failure! ("+c+")","error"),b.failure("onCredentialsExpired callback failed.")}):(a.log("onCredentialsExpired callback did not return a promise!","error"),b.failure("Unexpected return value for onCredentialsExpired.")),b}},qq.FineUploaderBasic.prototype._createUploadHandler.call(this,b,"s3")},_determineBucket:function(a){var b=this._options.objectProperties.bucket,c=new qq.Promise,d=this;return qq.isFunction(b)?(b=b(a),qq.isGenericPromise(b)?c=b:c.success(b)):qq.isString(b)&&c.success(b),c.then(function(b){d._buckets[a]=b},function(b){qq.log("Problem determining bucket for ID "+a+" ("+b+")","error")}),c},_determineKeyName:function(a,b){var c=new qq.Promise,d=this._options.objectProperties.key,e=qq.getExtension(b),f=c.failure,g=function(a,b){var d=a;void 0!==b&&(d+="."+b),c.success(d)};switch(d){case"uuid":g(this.getUuid(a),e);break;case"filename":g(b);break;default:qq.isFunction(d)?this._handleKeynameFunction(d,a,g,f):(this.log(d+" is not a valid value for the s3.keyname option!","error"),f())}return c},_handleKeynameFunction:function(a,b,c,d){var e=this,f=function(a){c(a)},g=function(a){e.log(qq.format("Failed to retrieve key name for {}. Reason: {}",b,a||"null"),"error"),d(a)},h=a.call(this,b);qq.isGenericPromise(h)?h.then(f,g):null==h?g():f(h)},_getEndpointSpecificParams:function(a,b,c){var d={key:this.getKey(a),uuid:this.getUuid(a),name:this.getName(a),bucket:this.getBucket(a)};return c&&c.getResponseHeader("ETag")?d.etag=c.getResponseHeader("ETag"):b.etag&&(d.etag=b.etag),d},_onSubmitDelete:function(a,b){var c={key:this.getKey(a),bucket:this.getBucket(a)};return qq.FineUploaderBasic.prototype._onSubmitDelete.call(this,a,b,c)},_addCannedFile:function(a){var b;if(null==a.s3Key)throw new qq.Error("Did not find s3Key property in server session response. This is required!");return b=qq.FineUploaderBasic.prototype._addCannedFile.apply(this,arguments),this._cannedKeys[b]=a.s3Key,this._cannedBuckets[b]=a.s3Bucket,b}})}(),qq.s3.RequestSigner=function(a){"use strict";function b(a,b,c){var d,e,f=b.responseText,g=j[a],h=g.promise;if(delete j[a],f)try{e=qq.parseJson(f)}catch(i){k.log("Error attempting to parse signature response: "+i,"error")}e&&e.invalid?(c=!0,d="Invalid policy document or request headers!"):e?k.expectingPolicy&&!e.policy?(c=!0,d="Response does not include the base64 encoded policy!"):e.signature||(c=!0,d="Response does not include the signature!"):(c=!0,d="Received an empty or invalid response from the server!"),c?(d&&k.log(d,"error"),h.failure(d)):h.success(e)}function c(a,b,c,d,e,f,g){var h,j="POST",k=[],l="";switch(a){case i.REQUEST_TYPE.MULTIPART_ABORT:j="DELETE",h=qq.format("uploadId={}",f);break;case i.REQUEST_TYPE.MULTIPART_INITIATE:h="uploads";break;case i.REQUEST_TYPE.MULTIPART_COMPLETE:h=qq.format("uploadId={}",f);break;case i.REQUEST_TYPE.MULTIPART_UPLOAD:j="PUT",h=qq.format("partNumber={}&uploadId={}",g,f)}return h=c+"?"+h,qq.each(e,function(a){k.push(a)}),k.sort(),qq.each(k,function(a,b){l+=b+":"+e[b]+"\n"}),{toSign:qq.format("{}\n\n{}\n\n{}/{}/{}",j,d||"",l||"\n",b,h),endOfUrl:h}}function d(a,b,c,d){var g;a.signatureConstructor?(d&&(g=a.signatureConstructor.getHeaders(),g[qq.s3.util.SESSION_TOKEN_PARAM_NAME]=d,a.signatureConstructor.withHeaders(g)),f(a.signatureConstructor.getToSign().stringToSign,b)):(d&&qq.s3.util.refreshPolicyCredentials(a,d),e(a,b,c,d))}function e(a,b,c,d){var e=JSON.stringify(a),f=CryptoJS.enc.Utf8.parse(e),g=CryptoJS.enc.Base64.stringify(f),i=CryptoJS.HmacSHA1(g,h.get().secretKey),j=CryptoJS.enc.Base64.stringify(i);b.success({policy:g,signature:j},c,d)}function f(a,b){var c=CryptoJS.enc.Utf8.parse(a),d=CryptoJS.HmacSHA1(c,h.get().secretKey),e=CryptoJS.enc.Base64.stringify(d);b.success({signature:e})}var g,h,i=this,j={},k={expectingPolicy:!1,method:"POST",signatureSpec:{credentialsProvider:{},endpoint:null,customHeaders:{}},maxConnections:3,paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(){}};qq.extend(k,a,!0),h=k.signatureSpec.credentialsProvider,g=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",method:k.method,contentType:"application/json; charset=utf-8",endpointStore:{get:function(){return k.signatureSpec.endpoint}},paramsStore:k.paramsStore,maxConnections:k.maxConnections,customHeaders:k.signatureSpec.customHeaders,log:k.log,onComplete:b,cors:k.cors})),qq.extend(this,{getSignature:function(a,b){var c=b,e=new qq.Promise;return h.get().secretKey&&window.CryptoJS?h.get().expiration.getTime()>Date.now()?d(b,e):h.onExpired().then(function(){d(b,e,h.get().accessKey,h.get().sessionToken)},function(){k.log("Attempt to update expired credentials apparently failed! Unable to sign request. ","error"),e.failure("Unable to sign request - expired credentials.")}):(k.log("Submitting S3 signature request for "+a),c.signatureConstructor&&(c={headers:c.signatureConstructor.getToSign().stringToSign}),g.initTransport(a).withParams(c).send(),j[a]={promise:e}),e},constructStringToSign:function(a,b,d){var e,f,g,i,j={};return{withHeaders:function(a){return j=a,this},withUploadId:function(a){return e=a,this},withContentType:function(a){return f=a,this},withPartNum:function(a){return g=a,this},getToSign:function(){var k=h.get().sessionToken;return j["x-amz-date"]=(new Date).toUTCString(),k&&(j[qq.s3.util.SESSION_TOKEN_PARAM_NAME]=k),i=c(a,b,d,f,j,e,g),{headers:function(){return f&&(j["Content-Type"]=f),j}(),endOfUrl:i.endOfUrl,stringToSign:i.toSign}},getHeaders:function(){return qq.extend({},j)},getEndOfUrl:function(){return i&&i.endOfUrl}}}})},qq.s3.RequestSigner.prototype.REQUEST_TYPE={MULTIPART_INITIATE:"multipart_initiate",MULTIPART_COMPLETE:"multipart_complete",MULTIPART_ABORT:"multipart_abort",MULTIPART_UPLOAD:"multipart_upload"},qq.UploadSuccessAjaxRequester=function(a){"use strict";function b(a,b,c){var f,g=d[a],h=b.responseText,i={success:!0},j={success:!1};delete d[a],e.log(qq.format("Received the following response body to an upload success request for id {}: {}",a,h));try{f=qq.parseJson(h),c||f&&(f.error||f.success===!1)?(e.log("Upload success request was rejected by the server.","error"),g.failure(qq.extend(f,j))):(e.log("Upload success was acknowledged by the server."),g.success(qq.extend(f,i)))}catch(k){c?(e.log(qq.format("Your server indicated failure in its upload success request response for id {}!",a),"error"),g.failure(j)):(e.log("Upload success was acknowledged by the server."),g.success(i))}}var c,d=[],e={method:"POST",endpoint:null,maxConnections:3,customHeaders:{},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(){}};qq.extend(e,a),c=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",method:e.method,endpointStore:{get:function(){return e.endpoint}},paramsStore:e.paramsStore,maxConnections:e.maxConnections,customHeaders:e.customHeaders,log:e.log,onComplete:b,cors:e.cors})),qq.extend(this,{sendSuccessRequest:function(a,b){var f=new qq.Promise;return e.log("Submitting upload success request/notification for "+a),c.initTransport(a).withParams(b).send(),d[a]=f,f}})},qq.s3.InitiateMultipartAjaxRequester=function(a){"use strict";function b(a){var b,c=g.getBucket(a),d={},f=new qq.Promise,h=g.getKey(a);return d["x-amz-acl"]=g.aclStore.get(a),g.reducedRedundancy&&(d[qq.s3.util.REDUCED_REDUNDANCY_PARAM_NAME]=qq.s3.util.REDUCED_REDUNDANCY_PARAM_VALUE),g.serverSideEncryption&&(d[qq.s3.util.SERVER_SIDE_ENCRYPTION_PARAM_NAME]=qq.s3.util.SERVER_SIDE_ENCRYPTION_PARAM_VALUE),d[qq.s3.util.AWS_PARAM_PREFIX+g.filenameParam]=encodeURIComponent(g.getName(a)),qq.each(g.paramsStore.get(a),function(a,b){d[qq.s3.util.AWS_PARAM_PREFIX+a]=encodeURIComponent(b)}),b=e.constructStringToSign(e.REQUEST_TYPE.MULTIPART_INITIATE,c,h).withContentType(g.getContentType(a)).withHeaders(d),e.getSignature(a,{signatureConstructor:b}).then(function(a){d=b.getHeaders(),d.Authorization="AWS "+g.signatureSpec.credentialsProvider.get().accessKey+":"+a.signature,f.success(d,b.getEndOfUrl())},f.failure),f}function c(a,b,c){var d,e,h,i,j,k=f[a],l=new DOMParser,m=l.parseFromString(b.responseText,"application/xml");delete f[a],c?(j=b.status,e=m.getElementsByTagName("Message"),e.length>0&&(i=e[0].textContent)):(d=m.getElementsByTagName("UploadId"),d.length>0?h=d[0].textContent:i="Upload ID missing from request"),void 0===h?(i?g.log(qq.format("Specific problem detected initiating multipart upload request for {}: '{}'.",a,i),"error"):g.log(qq.format("Unexplained error with initiate multipart upload request for {}. Status code {}.",a,j),"error"),k.failure("Problem initiating upload request.",b)):(g.log(qq.format("Initiate multipart upload request successful for {}. Upload ID is {}",a,h)),k.success(h,b))}var d,e,f={},g={filenameParam:"qqfilename",method:"POST",endpointStore:null,paramsStore:null,signatureSpec:null,aclStore:null,reducedRedundancy:!1,serverSideEncryption:!1,maxConnections:3,getContentType:function(){},getBucket:function(){},getKey:function(){},getName:function(){},log:function(){}};qq.extend(g,a),e=new qq.s3.RequestSigner({signatureSpec:g.signatureSpec,cors:g.cors,log:g.log}),d=qq.extend(this,new qq.AjaxRequester({method:g.method,contentType:null,endpointStore:g.endpointStore,maxConnections:g.maxConnections,allowXRequestedWithAndCacheControl:!1,log:g.log,onComplete:c,successfulResponseCodes:{POST:[200]}})),qq.extend(this,{send:function(a){var c=new qq.Promise;return b(a).then(function(b,e){g.log("Submitting S3 initiate multipart upload request for "+a),f[a]=c,d.initTransport(a).withPath(e).withHeaders(b).send()},c.failure),c}})},qq.s3.CompleteMultipartAjaxRequester=function(a){"use strict";function b(a,b){var c={},d=new qq.Promise,e=h.getBucket(a),g=f.constructStringToSign(f.REQUEST_TYPE.MULTIPART_COMPLETE,e,h.getKey(a)).withUploadId(b).withContentType("application/xml; charset=UTF-8");return f.getSignature(a,{signatureConstructor:g}).then(function(a){c=g.getHeaders(),c.Authorization="AWS "+h.signatureSpec.credentialsProvider.get().accessKey+":"+a.signature,d.success(c,g.getEndOfUrl())},d.failure),d}function c(a,b,c){var d=g[a],e=new DOMParser,f=h.getBucket(a),i=(h.getKey(a),e.parseFromString(b.responseText,"application/xml")),j=i.getElementsByTagName("Bucket"),k=i.getElementsByTagName("Key");delete g[a],h.log(qq.format("Complete response status {}, body = {}",b.status,b.responseText)),c?h.log(qq.format("Complete Multipart Upload request for {} failed with status {}.",a,b.status),"error"):j.length&&k.length?j[0].textContent!==f&&(c=!0,h.log(qq.format("Wrong bucket in response to Complete Multipart Upload request for {}.",a),"error")):(c=!0,h.log(qq.format("Missing bucket and/or key in response to Complete Multipart Upload request for {}.",a),"error")),c?d.failure("Problem combining the file parts!",b):d.success({},b)}function d(a){var b=document.implementation.createDocument(null,"CompleteMultipartUpload",null);return a.sort(function(a,b){return a.part-b.part}),qq.each(a,function(a,c){var d=c.part,e=c.etag,f=b.createElement("Part"),g=b.createElement("PartNumber"),h=b.createTextNode(d),i=b.createTextNode(e),j=b.createElement("ETag");j.appendChild(i),g.appendChild(h),f.appendChild(g),f.appendChild(j),qq(b).children()[0].appendChild(f)}),(new XMLSerializer).serializeToString(b)}var e,f,g={},h={method:"POST",contentType:"text/xml",endpointStore:null,signatureSpec:null,maxConnections:3,getBucket:function(){},getKey:function(){},log:function(){}};qq.extend(h,a),f=new qq.s3.RequestSigner({signatureSpec:h.signatureSpec,cors:h.cors,log:h.log}),e=qq.extend(this,new qq.AjaxRequester({method:h.method,contentType:"application/xml; charset=UTF-8",endpointStore:h.endpointStore,maxConnections:h.maxConnections,allowXRequestedWithAndCacheControl:!1,log:h.log,onComplete:c,successfulResponseCodes:{POST:[200]}})),qq.extend(this,{send:function(a,c,f){var i=new qq.Promise;return b(a,c).then(function(b,c){var j=d(f);h.log("Submitting S3 complete multipart upload request for "+a),g[a]=i,delete b["Content-Type"],e.initTransport(a).withPath(c).withHeaders(b).withPayload(j).send()},i.failure),i}})},qq.s3.AbortMultipartAjaxRequester=function(a){"use strict";function b(a,b){var c={},d=new qq.Promise,g=(f.endpointStore.get(a),f.getBucket(a)),h=e.constructStringToSign(e.REQUEST_TYPE.MULTIPART_ABORT,g,f.getKey(a)).withUploadId(b);return e.getSignature(a,{signatureConstructor:h}).then(function(a){c=h.getHeaders(),c.Authorization="AWS "+f.signatureSpec.credentialsProvider.get().accessKey+":"+a.signature,d.success(c,h.getEndOfUrl())},d.failure),d}function c(a,b,c){var d,e=new DOMParser,g=e.parseFromString(b.responseText,"application/xml"),h=g.getElementsByTagName("Error");f.log(qq.format("Abort response status {}, body = {}",b.status,b.responseText)),c?f.log(qq.format("Abort Multipart Upload request for {} failed with status {}.",a,b.status),"error"):h.length?(c=!0,d=g.getElementsByTagName("Message")[0].textContent,f.log(qq.format("Failed to Abort Multipart Upload request for {}. Error: {}",a,d),"error")):f.log(qq.format("Abort MPU request succeeded for file ID {}.",a))}var d,e,f={method:"DELETE",endpointStore:null,signatureSpec:null,maxConnections:3,getBucket:function(){},getKey:function(){},log:function(){}};qq.extend(f,a),e=new qq.s3.RequestSigner({signatureSpec:f.signatureSpec,cors:f.cors,log:f.log}),d=qq.extend(this,new qq.AjaxRequester({validMethods:["DELETE"],method:f.method,contentType:null,endpointStore:f.endpointStore,maxConnections:f.maxConnections,allowXRequestedWithAndCacheControl:!1,log:f.log,onComplete:c,successfulResponseCodes:{DELETE:[204]}})),qq.extend(this,{send:function(a,c){b(a,c).then(function(b,c){f.log("Submitting S3 Abort multipart upload request for "+a),d.initTransport(a).withPath(c).withHeaders(b).send()})}})},qq.s3.XhrUploadHandler=function(a,b){"use strict";var c=b.getName,d=b.log,e=200,f=a.getBucket,g=a.getKeyName,h=a.filenameParam,i=a.paramsStore,j=a.endpointStore,k=a.aclStore,l=a.objectProperties.reducedRedundancy,m=a.objectProperties.serverSideEncryption,n=a.validation,o=a.signature,p=this,q=a.signature.credentialsProvider,r={combine:function(a){var b=p._getPersistableData(a).uploadId,c=p._getPersistableData(a).etags,d=new qq.Promise;return s.completeMultipart.send(a,b,c).then(d.success,function(b,c){d.failure(u.done(a,c).response,c)}),d},done:function(a,b,c){var d,e=u.response.parse(a,b);e.success&&(d=b.getResponseHeader("ETag"),p._getPersistableData(a).etags||(p._getPersistableData(a).etags=[]),p._getPersistableData(a).etags.push({part:c+1,etag:d}))},initHeaders:function(b,c){var d={},e=(a.endpointStore.get(b),u.bucket.getName(b)),f=u.key.urlSafe(b),g=new qq.Promise,h=s.restSignature.constructStringToSign(s.restSignature.REQUEST_TYPE.MULTIPART_UPLOAD,e,f).withPartNum(c+1).withUploadId(p._getPersistableData(b).uploadId);return s.restSignature.getSignature(b+"."+c,{signatureConstructor:h}).then(function(a){d=h.getHeaders(),d.Authorization="AWS "+q.get().accessKey+":"+a.signature,g.success(d,h.getEndOfUrl())},g.failure),g},put:function(b,c){var d=p._createXhr(b,c),e=p._getChunkData(b,c),f=a.endpointStore.get(b),g=new qq.Promise;return r.initHeaders(b,c).then(function(a,h){var i=f+"/"+h;p._registerProgressHandler(b,c,e.size),u.track(b,d,c).then(g.success,g.failure),d.open("PUT",i,!0),qq.each(a,function(a,b){d.setRequestHeader(a,b)}),d.send(e.blob)},function(){g.failure({error:"Problem signing the chunk!"},d)}),g},send:function(a,b){var c=new qq.Promise;return r.setup(a).then(function(){r.put(a,b).then(c.success,c.failure)},function(a,b){c.failure({error:a},b)}),c},setup:function(a){var b=new qq.Promise,c=p._getPersistableData(a).uploadId,d=new qq.Promise;return c?c instanceof qq.Promise?c.then(function(a){b.success(a)}):b.success(c):(p._getPersistableData(a).uploadId=d,s.initiateMultipart.send(a).then(function(c){p._getPersistableData(a).uploadId=c,d.success(c),b.success(c)},function(c){p._getPersistableData(a).uploadId=null,b.failure(c),d.failure(c)})),b}},s={abortMultipart:new qq.s3.AbortMultipartAjaxRequester({endpointStore:j,signatureSpec:o,cors:a.cors,log:d,getBucket:function(a){return u.bucket.getName(a)},getKey:function(a){return u.key.urlSafe(a)}}),completeMultipart:new qq.s3.CompleteMultipartAjaxRequester({endpointStore:j,signatureSpec:o,cors:a.cors,log:d,getBucket:function(a){return u.bucket.getName(a)},getKey:function(a){return u.key.urlSafe(a)}}),initiateMultipart:new qq.s3.InitiateMultipartAjaxRequester({filenameParam:h,endpointStore:j,paramsStore:i,signatureSpec:o,aclStore:k,reducedRedundancy:l,serverSideEncryption:m,cors:a.cors,log:d,getContentType:function(a){return p._getMimeType(a)},getBucket:function(a){return u.bucket.getName(a)},getKey:function(a){return u.key.urlSafe(a)},getName:function(a){return c(a)}}),policySignature:new qq.s3.RequestSigner({expectingPolicy:!0,signatureSpec:o,cors:a.cors,log:d}),restSignature:new qq.s3.RequestSigner({signatureSpec:o,cors:a.cors,log:d})},t={initParams:function(a){var b=i.get(a);return b[h]=c(a),qq.s3.util.generateAwsParams({endpoint:j.get(a),params:b,type:p._getMimeType(a),bucket:u.bucket.getName(a),key:p.getThirdPartyFileId(a),accessKey:q.get().accessKey,sessionToken:q.get().sessionToken,acl:k.get(a),expectedStatus:e,minFileSize:n.minSizeLimit,maxFileSize:n.maxSizeLimit,reducedRedundancy:l,serverSideEncryption:m,log:d},qq.bind(s.policySignature.getSignature,this,a))},send:function(a){var b=new qq.Promise,c=p._createXhr(a),e=p.getFile(a);return p._registerProgressHandler(a),u.track(a,c).then(b.success,b.failure),t.setup(a,c,e).then(function(b){d("Sending upload request for "+a),c.send(b)},b.failure),b},setup:function(a,b,c){var d=new FormData,e=j.get(a),f=e,g=new qq.Promise;return t.initParams(a).then(function(a){b.open("POST",f,!0),qq.obj2FormData(a,d),d.append("file",c),g.success(d)},function(a){g.failure({error:a})}),g}},u={bucket:{promise:function(a){var b=new qq.Promise,c=p._getFileState(a).bucket;return c?b.success(c):f(a).then(function(c){p._getFileState(a).bucket=c,b.success(c)},b.failure),b},getName:function(a){return p._getFileState(a).bucket}},done:function(a,b){var c=u.response.parse(a,b),e=c.success!==!0;return e&&u.response.shouldReset(c.code)&&(d("This is an unrecoverable error, we must restart the upload entirely on the next retry attempt.","error"),c.reset=!0),{success:!e,response:c}},key:{promise:function(a){var b=new qq.Promise,d=p.getThirdPartyFileId(a);return null==d?(p._setThirdPartyFileId(a,b),g(a,c(a)).then(function(c){p._setThirdPartyFileId(a,c),b.success(c)},function(c){p._setThirdPartyFileId(a,null),b.failure(c)})):qq.isGenericPromise(d)?d.then(b.success,b.failure):b.success(d),b},urlSafe:function(a){return encodeURIComponent(p.getThirdPartyFileId(a))}},response:{parse:function(a,b){var c,f={};try{d(qq.format("Received response status {} with body: {}",b.status,b.responseText)),b.status===e?f.success=!0:(c=u.response.parseError(b.responseText),c&&(f.error=c.message,f.code=c.code))}catch(g){d("Error when attempting to parse xhr response text ("+g.message+")","error")}return f},parseError:function(a){var b,c,d=new DOMParser,e=d.parseFromString(a,"application/xml"),f=e.getElementsByTagName("Error"),g={};return f.length?(b=e.getElementsByTagName("Code"),c=e.getElementsByTagName("Message"),c.length&&(g.message=c[0].textContent),b.length&&(g.code=b[0].textContent),g):void 0},shouldReset:function(a){return"EntityTooSmall"===a||"InvalidPart"===a||"InvalidPartOrder"===a||"NoSuchUpload"===a}},start:function(a,b){var c=new qq.Promise;return u.key.promise(a).then(function(){u.bucket.promise(a).then(function(){null==b?t.send(a).then(c.success,c.failure):r.send(a,b).then(c.success,c.failure)})},function(a){c.failure({error:a})}),c},track:function(a,b,c){var d=new qq.Promise;return b.onreadystatechange=function(){if(4===b.readyState){var e;null==c?(e=u.done(a,b),d[e.success?"success":"failure"](e.response,b)):(r.done(a,b,c),e=u.done(a,b),d[e.success?"success":"failure"](e.response,b))
+}},d}};qq.extend(this,{uploadChunk:u.start,uploadFile:u.start}),qq.extend(this,new qq.XhrUploadHandler({options:qq.extend({namespace:"s3"},a),proxy:qq.extend({getEndpoint:a.endpointStore.get},b)})),qq.override(this,function(a){return{expunge:function(b){var c=p._getPersistableData(b)&&p._getPersistableData(b).uploadId,d=p._maybeDeletePersistedChunkData(b);void 0!==c&&d&&s.abortMultipart.send(b,c),a.expunge(b)},finalizeChunks:function(a){return r.combine(a)},_getLocalStorageId:function(b){var c=a._getLocalStorageId(b),d=u.bucket.getName(b);return c+"-"+d}}})},qq.s3.FormUploadHandler=function(a,b){"use strict";function c(b,c){var d,e,f,g=a.endpointStore.get(b),i=qq.s3.util.getBucket(g);try{if(d=c.contentDocument||c.contentWindow.document,e=d.body.innerHTML,f=qq.s3.util.parseIframeResponse(c),f.bucket===i&&f.key===qq.s3.util.encodeQueryStringParam(h.getThirdPartyFileId(b)))return!0;l("Response from AWS included an unexpected bucket or key name.","error")}catch(j){l("Error when attempting to parse form upload response ("+j.message+")","error")}return!1}function d(a){var b=p.get(a);return b[o]=j(a),qq.s3.util.generateAwsParams({endpoint:q.get(a),params:b,bucket:h._getFileState(a).bucket,key:h.getThirdPartyFileId(a),accessKey:x.get().accessKey,sessionToken:x.get().sessionToken,acl:r.get(a),minFileSize:u.minSizeLimit,maxFileSize:u.maxSizeLimit,successRedirectUrl:w,reducedRedundancy:s,serverSideEncryption:t,log:l},qq.bind(y.getSignature,this,a))}function e(b,c){var e=new qq.Promise,f="POST",i=a.endpointStore.get(b),k=j(b);return d(b).then(function(a){var b=h._initFormForUpload({method:f,endpoint:i,params:a,paramsInBody:!0,targetName:c.name});e.success(b)},function(a){e.failure(a),g(b,c,k,{error:a})}),e}function f(a){var b=h._createIframe(a),d=h.getInput(a),f=new qq.Promise;return e(a,b).then(function(e){e.appendChild(d),h._attachLoadEvent(b,function(d){l("iframe loaded"),d?d.success===!1&&(l("Amazon likely rejected the upload request","error"),f.failure(d)):(d={},d.success=c(a,b),d.success===!1?(l("A success response was received by Amazon, but it was invalid in some way.","error"),f.failure(d)):(qq.extend(d,qq.s3.util.parseIframeResponse(b)),f.success(d))),g(a,b)}),l("Sending upload request for "+a),e.submit(),qq(e).remove()},f.failure),f}function g(a,b){h._detachLoadEvent(a),b&&qq(b).remove()}var h=this,i=b.onUuidChanged,j=b.getName,k=b.getUuid,l=b.log,m=a.getBucket,n=a.getKeyName,o=a.filenameParam,p=a.paramsStore,q=a.endpointStore,r=a.aclStore,s=a.objectProperties.reducedRedundancy,t=a.objectProperties.serverSideEncryption,u=a.validation,v=a.signature,w=a.iframeSupport.localBlankPagePath,x=a.signature.credentialsProvider,y=new qq.s3.RequestSigner({signatureSpec:v,cors:a.cors,log:l});if(void 0===w)throw new Error("successRedirectEndpoint MUST be defined if you intend to use browsers that do not support the File API!");qq.extend(this,new qq.FormUploadHandler({options:{isCors:!1,inputName:"file"},proxy:{onCancel:a.onCancel,onUuidChanged:i,getName:j,getUuid:k,log:l}})),qq.extend(this,{uploadFile:function(a){var b=j(a),c=new qq.Promise;return h.getThirdPartyFileId(a)?h._getFileState(a).bucket?f(a).then(c.success,c.failure):m(a).then(function(b){h._getFileState(a).bucket=b,f(a).then(c.success,c.failure)}):n(a,b).then(function(b){m(a).then(function(d){h._getFileState(a).bucket=d,h._setThirdPartyFileId(a,b),f(a).then(c.success,c.failure)},function(a){c.failure({error:a})})},function(a){c.failure({error:a})}),c}})},function(){"use strict";qq.s3.FineUploader=function(a){var b={failedUploadTextDisplay:{mode:"custom"}};qq.extend(b,a,!0),qq.FineUploader.call(this,b,"s3"),qq.supportedFeatures.ajaxUploading||void 0!==b.iframeSupport.localBlankPagePath||(this._options.element.innerHTML="
You MUST set the localBlankPagePath property of the iframeSupport option since this browser does not support the File API!
")},qq.extend(qq.s3.FineUploader.prototype,qq.s3.FineUploaderBasic.prototype),qq.extend(qq.s3.FineUploader.prototype,qq.uiPublicApi),qq.extend(qq.s3.FineUploader.prototype,qq.uiPrivateApi)}(),qq.PasteSupport=function(a){"use strict";function b(a){return a.type&&0===a.type.indexOf("image/")}function c(){f=qq(e.targetElement).attach("paste",function(a){var c=a.clipboardData;c&&qq.each(c.items,function(a,c){if(b(c)){var d=c.getAsFile();e.callbacks.pasteReceived(d)}})})}function d(){f&&f()}var e,f;e={targetElement:null,callbacks:{log:function(){},pasteReceived:function(){}}},qq.extend(e,a),c(),qq.extend(this,{reset:function(){d()}})},qq.DragAndDrop=function(a){"use strict";function b(a,b){var c=Array.prototype.slice.call(a);j.callbacks.dropLog("Grabbed "+a.length+" dropped files."),b.dropDisabled(!1),j.callbacks.processingDroppedFilesComplete(c,b.getElement())}function c(a){var b=new qq.Promise;return a.isFile?a.file(function(c){var d=a.name,e=a.fullPath,f=e.indexOf(d);e=e.substr(0,f),"/"===e.charAt(0)&&(e=e.substr(1)),c.qqPath=e,n.push(c),b.success()},function(c){j.callbacks.dropLog("Problem parsing '"+a.fullPath+"'. FileError code "+c.code+".","error"),b.failure()}):a.isDirectory&&d(a).then(function(a){var d=a.length;qq.each(a,function(a,e){c(e).done(function(){d-=1,0===d&&b.success()})}),a.length||b.success()},function(c){j.callbacks.dropLog("Problem parsing '"+a.fullPath+"'. FileError code "+c.code+".","error"),b.failure()}),b}function d(a,b,c,e){var f=e||new qq.Promise,g=b||a.createReader();return g.readEntries(function(b){var e=c?c.concat(b):b;b.length?setTimeout(function(){d(a,g,e,f)},0):f.success(e)},f.failure),f}function e(a,b){var d=[],e=new qq.Promise;return j.callbacks.processingDroppedFiles(),b.dropDisabled(!0),a.files.length>1&&!j.allowMultipleItems?(j.callbacks.processingDroppedFilesComplete([]),j.callbacks.dropError("tooManyFilesError",""),b.dropDisabled(!1),e.failure()):(n=[],qq.isFolderDropSupported(a)?qq.each(a.items,function(a,b){var f=b.webkitGetAsEntry();f&&(f.isFile?n.push(b.getAsFile()):d.push(c(f).done(function(){d.pop(),0===d.length&&e.success()})))}):n=a.files,0===d.length&&e.success()),e}function f(a){var c=new qq.UploadDropZone({HIDE_ZONES_EVENT_NAME:k,element:a,onEnter:function(b){qq(a).addClass(j.classes.dropActive),b.stopPropagation()},onLeaveNotDescendants:function(){qq(a).removeClass(j.classes.dropActive)},onDrop:function(a){e(a.dataTransfer,c).then(function(){b(n,c)},function(){j.callbacks.dropLog("Drop event DataTransfer parsing failed. No files will be uploaded.","error")})}});return o.addDisposer(function(){c.dispose()}),qq(a).hasAttribute(l)&&qq(a).hide(),m.push(c),c}function g(a){var b;return qq.each(a.dataTransfer.types,function(a,c){return"Files"===c?(b=!0,!1):void 0}),b}function h(a){return qq.firefox()?!a.relatedTarget:qq.safari()?a.x<0||a.y<0:0===a.x&&0===a.y}function i(){var a=j.dropZoneElements,b=function(){setTimeout(function(){qq.each(a,function(a,b){qq(b).hasAttribute(l)&&qq(b).hide(),qq(b).removeClass(j.classes.dropActive)})},10)};qq.each(a,function(b,c){var d=f(c);a.length&&qq.supportedFeatures.fileDrop&&o.attach(document,"dragenter",function(b){!d.dropDisabled()&&g(b)&&qq.each(a,function(a,b){b instanceof HTMLElement&&qq(b).hasAttribute(l)&&qq(b).css({display:"block"})})})}),o.attach(document,"dragleave",function(a){h(a)&&b()}),o.attach(qq(document).children()[0],"mouseenter",function(){b()}),o.attach(document,"drop",function(a){a.preventDefault(),b()}),o.attach(document,k,b)}var j,k="qq-hidezones",l="qq-hide-dropzone",m=[],n=[],o=new qq.DisposeSupport;j={dropZoneElements:[],allowMultipleItems:!0,classes:{dropActive:null},callbacks:new qq.DragAndDrop.callbacks},qq.extend(j,a,!0),i(),qq.extend(this,{setupExtraDropzone:function(a){j.dropZoneElements.push(a),f(a)},removeDropzone:function(a){var b,c=j.dropZoneElements;for(b in c)if(c[b]===a)return c.splice(b,1)},dispose:function(){o.dispose(),qq.each(m,function(a,b){b.dispose()})}})},qq.DragAndDrop.callbacks=function(){"use strict";return{processingDroppedFiles:function(){},processingDroppedFilesComplete:function(){},dropError:function(a,b){qq.log("Drag & drop error code '"+a+" with these specifics: '"+b+"'","error")},dropLog:function(a,b){qq.log(a,b)}}},qq.UploadDropZone=function(a){"use strict";function b(){return qq.safari()||qq.firefox()&&qq.windows()}function c(){k||(b?l.attach(document,"dragover",function(a){a.preventDefault()}):l.attach(document,"dragover",function(a){a.dataTransfer&&(a.dataTransfer.dropEffect="none",a.preventDefault())}),k=!0)}function d(a){if(!qq.supportedFeatures.fileDrop)return!1;var b,c=a.dataTransfer,d=qq.safari();return b=qq.ie()&&qq.supportedFeatures.fileDrop?!0:"none"!==c.effectAllowed,c&&b&&(c.files||!d&&c.types.contains&&c.types.contains("Files"))}function e(a){return void 0!==a&&(j=a),j}function f(){function a(){b=document.createEvent("Event"),b.initEvent(h.HIDE_ZONES_EVENT_NAME,!0,!0)}var b;if(window.CustomEvent)try{b=new CustomEvent(h.HIDE_ZONES_EVENT_NAME)}catch(c){a()}else a();document.dispatchEvent(b)}function g(){l.attach(i,"dragover",function(a){if(d(a)){var b=qq.ie()&&qq.supportedFeatures.fileDrop?null:a.dataTransfer.effectAllowed;a.dataTransfer.dropEffect="move"===b||"linkMove"===b?"move":"copy",a.stopPropagation(),a.preventDefault()}}),l.attach(i,"dragenter",function(a){if(!e()){if(!d(a))return;h.onEnter(a)}}),l.attach(i,"dragleave",function(a){if(d(a)){h.onLeave(a);var b=document.elementFromPoint(a.clientX,a.clientY);qq(this).contains(b)||h.onLeaveNotDescendants(a)}}),l.attach(i,"drop",function(a){if(!e()){if(!d(a))return;a.preventDefault(),a.stopPropagation(),h.onDrop(a),f()}})}var h,i,j,k,l=new qq.DisposeSupport;h={element:null,onEnter:function(){},onLeave:function(){},onLeaveNotDescendants:function(){},onDrop:function(){}},qq.extend(h,a),i=h.element,c(),g(),qq.extend(this,{dropDisabled:function(a){return e(a)},dispose:function(){l.dispose()},getElement:function(){return i}})},qq.DeleteFileAjaxRequester=function(a){"use strict";function b(){return"POST"===d.method.toUpperCase()?{_method:"DELETE"}:{}}var c,d={method:"DELETE",uuidParamName:"qquuid",endpointStore:{},maxConnections:3,customHeaders:function(){return{}},paramsStore:{},cors:{expected:!1,sendCredentials:!1},log:function(){},onDelete:function(){},onDeleteComplete:function(){}};qq.extend(d,a),c=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["POST","DELETE"],method:d.method,endpointStore:d.endpointStore,paramsStore:d.paramsStore,mandatedParams:b(),maxConnections:d.maxConnections,customHeaders:function(a){return d.customHeaders.get(a)},log:d.log,onSend:d.onDelete,onComplete:d.onDeleteComplete,cors:d.cors})),qq.extend(this,{sendDelete:function(a,b,e){var f=e||{};d.log("Submitting delete file request for "+a),"DELETE"===d.method?c.initTransport(a).withPath(b).withParams(f).send():(f[d.uuidParamName]=b,c.initTransport(a).withParams(f).send())}})},function(){function a(a){var b,c=a.naturalWidth,d=a.naturalHeight,e=document.createElement("canvas");return c*d>1048576?(e.width=e.height=1,b=e.getContext("2d"),b.drawImage(a,-c+1,0),0===b.getImageData(0,0,1,1).data[3]):!1}function b(a,b,c){var d,e,f,g,h=document.createElement("canvas"),i=0,j=c,k=c;for(h.width=1,h.height=c,d=h.getContext("2d"),d.drawImage(a,0,0),e=d.getImageData(0,0,1,c).data;k>i;)f=e[4*(k-1)+3],0===f?j=k:i=k,k=j+i>>1;return g=k/c,0===g?1:g}function c(a,b,c){var d=document.createElement("canvas"),f=b.mime||"image/jpeg";return e(a,d,b,c),d.toDataURL(f,b.quality||.8)}function d(a){var b=5241e3;if(!qq.ios())throw new qq.Error("Downsampled dimensions can only be reliably calculated for iOS!");return a.origHeight*a.origWidth>b?{newHeight:Math.round(Math.sqrt(b*(a.origHeight/a.origWidth))),newWidth:Math.round(Math.sqrt(b*(a.origWidth/a.origHeight)))}:void 0}function e(c,e,g,h){var i,j=c.naturalWidth,k=c.naturalHeight,l=g.width,m=g.height,n=e.getContext("2d");n.save(),qq.supportedFeatures.unlimitedScaledImageSize||(i=d({origWidth:l,origHeight:m}),i&&(qq.log(qq.format("Had to reduce dimensions due to device limitations from {}w / {}h to {}w / {}h",l,m,i.newWidth,i.newHeight),"warn"),l=i.newWidth,m=i.newHeight)),f(e,l,m,g.orientation),qq.ios()?function(){a(c)&&(j/=2,k/=2);var d,e,f,g=1024,i=document.createElement("canvas"),o=h?b(c,j,k):1,p=Math.ceil(g*l/j),q=Math.ceil(g*m/k/o),r=0,s=0;for(i.width=i.height=g,d=i.getContext("2d");k>r;){for(e=0,f=0;j>e;)d.clearRect(0,0,g,g),d.drawImage(c,-e,-r),n.drawImage(i,0,0,g,g,f,s,p,q),e+=g,f+=p;r+=g,s+=q}n.restore(),i=d=null}():n.drawImage(c,0,0,l,m),e.qqImageRendered&&e.qqImageRendered()}function f(a,b,c,d){switch(d){case 5:case 6:case 7:case 8:a.width=c,a.height=b;break;default:a.width=b,a.height=c}var e=a.getContext("2d");switch(d){case 2:e.translate(b,0),e.scale(-1,1);break;case 3:e.translate(b,c),e.rotate(Math.PI);break;case 4:e.translate(0,c),e.scale(1,-1);break;case 5:e.rotate(.5*Math.PI),e.scale(1,-1);break;case 6:e.rotate(.5*Math.PI),e.translate(0,-c);break;case 7:e.rotate(.5*Math.PI),e.translate(b,-c),e.scale(-1,1);break;case 8:e.rotate(-.5*Math.PI),e.translate(-b,0)}}function g(a,b){var c=this;window.Blob&&a instanceof Blob&&function(){var b=new Image,d=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;if(!d)throw Error("No createObjectURL function found to create blob url");b.src=d.createObjectURL(a),c.blob=a,a=b}(),a.naturalWidth||a.naturalHeight||(a.onload=function(){var a=c.imageLoadListeners;a&&(c.imageLoadListeners=null,setTimeout(function(){for(var b=0,c=a.length;c>b;b++)a[b]()},0))},a.onerror=b,this.imageLoadListeners=[]),this.srcImage=a}g.prototype.render=function(a,b){b=b||{};var d,f=this,g=this.srcImage.naturalWidth,h=this.srcImage.naturalHeight,i=b.width,j=b.height,k=b.maxWidth,l=b.maxHeight,m=!this.blob||"image/jpeg"===this.blob.type,n=a.tagName.toLowerCase();return this.imageLoadListeners?(this.imageLoadListeners.push(function(){f.render(a,b)}),void 0):(i&&!j?j=h*i/g<<0:j&&!i?i=g*j/h<<0:(i=g,j=h),k&&i>k&&(i=k,j=h*i/g<<0),l&&j>l&&(j=l,i=g*j/h<<0),d={width:i,height:j},qq.each(b,function(a,b){d[a]=b}),"img"===n?function(){var b=a.src;a.src=c(f.srcImage,d,m),b===a.src&&a.onload()}():"canvas"===n&&e(this.srcImage,a,d,m),"function"==typeof this.onrender&&this.onrender(a),void 0)},qq.MegaPixImage=g}(),qq.ImageGenerator=function(a){"use strict";function b(a){return"img"===a.tagName.toLowerCase()}function c(a){return"canvas"===a.tagName.toLowerCase()}function d(){return void 0!==(new Image).crossOrigin}function e(){var a=document.createElement("canvas");return a.getContext&&a.getContext("2d")}function f(a){var b=a.split("/"),c=b[b.length-1],d=qq.getExtension(c);switch(d=d&&d.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 g(a){var b,c,d,e=document.createElement("a");return e.href=a,b=e.protocol,d=e.port,c=e.hostname,b.toLowerCase()!==window.location.protocol.toLowerCase()?!0:c.toLowerCase()!==window.location.hostname.toLowerCase()?!0:d===window.location.port||qq.ie()?!1:!0}function h(b,c){b.onload=function(){b.onload=null,b.onerror=null,c.success(b)},b.onerror=function(){b.onload=null,b.onerror=null,a("Problem drawing thumbnail!","error"),c.failure(b,"Problem drawing thumbnail!")}}function i(a,b){a.qqImageRendered=function(){b.success(a)}}function j(d,e){var f=b(d)||c(d);return b(d)?h(d,e):c(d)?i(d,e):(e.failure(d),a(qq.format("Element container of type {} is not supported!",d.tagName),"error")),f}function k(b,c,d){var e=new qq.Promise,f=new qq.Identify(b,a),g=d.maxSize,h=null==d.orient?!0:d.orient,i=function(){c.onerror=null,c.onload=null,a("Could not render preview, file may be too large!","error"),e.failure(c,"Browser cannot render image!")};return f.isPreviewable().then(function(d){var f={parse:function(){return(new qq.Promise).success()}},k=h?new qq.Exif(b,a):f,l=new qq.MegaPixImage(b,i);j(c,e)&&k.parse().then(function(a){var b=a&&a.Orientation;l.render(c,{maxWidth:g,maxHeight:g,orientation:b,mime:d})},function(b){a(qq.format("EXIF data could not be parsed ({}). Assuming orientation = 1.",b)),l.render(c,{maxWidth:g,maxHeight:g,mime:d})})},function(){a("Not previewable"),e.failure(c,"Not previewable")}),e}function l(a,b,c,d){var e=new Image,h=new qq.Promise;j(e,h),g(a)&&(e.crossOrigin="anonymous"),e.src=a,h.then(function(){j(b,c);var g=new qq.MegaPixImage(e);g.render(b,{maxWidth:d,maxHeight:d,mime:f(a)})},c.failure)}function m(a,b,c,d){j(b,c),qq(b).css({maxWidth:d+"px",maxHeight:d+"px"}),b.src=a}function n(a,f,h){var i=new qq.Promise,k=h.scale,n=k?h.maxSize:null;return k&&b(f)?e()?g(a)&&!d()?m(a,f,i,n):l(a,f,i,n):m(a,f,i,n):c(f)?l(a,f,i,n):j(f,i)&&(f.src=a),i}qq.extend(this,{generate:function(b,c,d){return qq.isString(b)?(a("Attempting to update thumbnail based on server response."),n(b,c,d||{})):(a("Attempting to draw client-side image preview."),k(b,c,d||{}))}})},qq.Exif=function(a,b){"use strict";function c(a){for(var b=0,c=0;a.length>0;)b+=parseInt(a.substring(0,2),16)*Math.pow(2,c),a=a.substring(2,a.length),c+=8;return b}function d(b,c){var e=b,f=c;return void 0===e&&(e=2,f=new qq.Promise),qq.readBlobToHex(a,e,4).then(function(a){var b,c=/^ffe([0-9])/.exec(a);c?"1"!==c[1]?(b=parseInt(a.slice(4,8),16),d(e+b+2,f)):f.success(e):f.failure("No EXIF header to be found!")}),f}function e(){var b=new qq.Promise;return qq.readBlobToHex(a,0,6).then(function(a){0!==a.indexOf("ffd8")?b.failure("Not a valid JPEG!"):d().then(function(a){b.success(a)},function(a){b.failure(a)})}),b}function f(b){var c=new qq.Promise;return qq.readBlobToHex(a,b+10,2).then(function(a){c.success("4949"===a)}),c}function g(b,d){var e=new qq.Promise;return qq.readBlobToHex(a,b+18,2).then(function(a){return d?e.success(c(a)):(e.success(parseInt(a,16)),void 0)}),e}function h(b,c){var d=b+20,e=12*c;return qq.readBlobToHex(a,d,e)}function i(a){for(var b=[],c=0;c+24<=a.length;)b.push(a.slice(c,c+24)),c+=24;return b}function j(a,b){var d=16,e=qq.extend([],k),f={};return qq.each(b,function(b,g){var h,i,j,k=g.slice(0,4),m=a?c(k):parseInt(k,16),n=e.indexOf(m);return n>=0&&(i=l[m].name,j=l[m].bytes,h=g.slice(d,d+2*j),f[i]=a?c(h):parseInt(h,16),e.splice(n,1)),0===e.length?!1:void 0}),f}var k=[274],l={274:{name:"Orientation",bytes:2}};qq.extend(this,{parse:function(){var c=new qq.Promise,d=function(a){b(qq.format("EXIF header parse failed: '{}' ",a)),c.failure(a)};return e().then(function(e){b(qq.format("Moving forward with EXIF header parsing for '{}'",void 0===a.name?"blob":a.name)),f(e).then(function(a){b(qq.format("EXIF Byte order is {} endian",a?"little":"big")),g(e,a).then(function(f){b(qq.format("Found {} APP1 directory entries",f)),h(e,f).then(function(d){var e=i(d),f=j(a,e);b("Successfully parsed some EXIF tags"),c.success(f)},d)},d)},d)},d),c}})},qq.Identify=function(a,b){"use strict";function c(a,b){var c=!1,d=[].concat(a);return qq.each(d,function(a,d){return 0===b.indexOf(d)?(c=!0,!1):void 0}),c}qq.extend(this,{isPreviewable:function(){var d=this,e=new qq.Promise,f=!1,g=void 0===a.name?"blob":a.name;return b(qq.format("Attempting to determine if {} can be rendered in this browser",g)),b("First pass: check type attribute of blob object."),this.isPreviewableSync()?(b("Second pass: check for magic bytes in file header."),qq.readBlobToHex(a,0,4).then(function(a){qq.each(d.PREVIEWABLE_MIME_TYPES,function(b,d){return c(d,a)?(("image/tiff"!==b||qq.supportedFeatures.tiffPreviews)&&(f=!0,e.success(b)),!1):void 0}),b(qq.format("'{}' is {} able to be rendered in this browser",g,f?"":"NOT")),f||e.failure()},function(){b("Error reading file w/ name '"+g+"'. Not able to be rendered in this browser."),e.failure()})):e.failure(),e},isPreviewableSync:function(){var c=a.type,d=qq.indexOf(Object.keys(this.PREVIEWABLE_MIME_TYPES),c)>=0,e=!1,f=void 0===a.name?"blob":a.name;return d&&(e="image/tiff"===c?qq.supportedFeatures.tiffPreviews:!0),!e&&b(f+" is not previewable in this browser per the blob's type attr"),e}})},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(a,b){"use strict";function c(a){var b=!1;return qq.each(a,function(a,c){return c>0?(b=!0,!1):void 0}),b}function d(){var c=new qq.Promise;return new qq.Identify(a,b).isPreviewable().then(function(){var d=new Image,e=window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL&&window.webkitURL.createObjectURL?window.webkitURL:null;e?(d.onerror=function(){b("Cannot determine dimensions for image. May be too large.","error"),c.failure()},d.onload=function(){c.success({width:this.width,height:this.height})},d.src=e.createObjectURL(a)):(b("No createObjectURL function available to generate image URL!","error"),c.failure())},c.failure),c}function e(a,b){var c;return qq.each(a,function(a,d){if(d>0){var e=/(max|min)(Width|Height)/.exec(a),f=e[2].charAt(0).toLowerCase()+e[2].slice(1),g=b[f];switch(e[1]){case"min":if(d>g)return c=a,!1;break;case"max":if(g>d)return c=a,!1}}}),c}this.validate=function(a){var f=new qq.Promise;return b("Attempting to validate image."),c(a)?d().then(function(b){var c=e(a,b);c?f.failure(c):f.success()},f.success):f.success(),f}},qq.Session=function(a){"use strict";function b(a){return qq.isArray(a)?!0:(d.log("Session response is not an array.","error"),void 0)}function c(a,c,e,f){var g=!1;c=c&&b(a),c&&qq.each(a,function(a,b){if(null==b.uuid)g=!0,d.log(qq.format("Session response item {} did not include a valid UUID - ignoring.",a),"error");else if(null==b.name)g=!0,d.log(qq.format("Session response item {} did not include a valid name - ignoring.",a),"error");else try{return d.addFileRecord(b),!0}catch(c){g=!0,d.log(c.message,"error")}return!1}),f[c&&!g?"success":"failure"](a,e)}var d={endpoint:null,params:{},customHeaders:{},cors:{},addFileRecord:function(){},log:function(){}};qq.extend(d,a,!0),this.refresh=function(){var a=new qq.Promise,b=function(b,d,e){c(b,d,e,a)},e=qq.extend({},d),f=new qq.SessionAjaxRequester(qq.extend(e,{onComplete:b}));return f.queryServer(),a}},qq.SessionAjaxRequester=function(a){"use strict";function b(a,b,c){var e=null;if(null!=b.responseText)try{e=qq.parseJson(b.responseText)}catch(f){d.log("Problem parsing session response: "+f.message,"error"),c=!0}d.onComplete(e,!c,b)}var c,d={endpoint:null,customHeaders:{},params:{},cors:{expected:!1,sendCredentials:!1},onComplete:function(){},log:function(){}};qq.extend(d,a),c=qq.extend(this,new qq.AjaxRequester({acceptHeader:"application/json",validMethods:["GET"],method:"GET",endpointStore:{get:function(){return d.endpoint}},customHeaders:d.customHeaders,log:d.log,onComplete:b,cors:d.cors})),qq.extend(this,{queryServer:function(){var a=qq.extend({},d.params);d.log("Session query request."),c.initTransport("sessionRefresh").withParams(a).withCacheBuster().send()}})},qq.FormSupport=function(a,b,c){"use strict";function d(a){a.getAttribute("action")&&(h.newEndpoint=a.getAttribute("action"))}function e(a,b){return!a.checkValidity||a.checkValidity()?!0:(c("Form did not pass validation checks - will not upload.","error"),b(),void 0)}function f(a){var c=a.submit;qq(a).attach("submit",function(d){d=d||window.event,d.preventDefault?d.preventDefault():d.returnValue=!1,e(a,c)&&b()}),a.submit=function(){e(a,c)&&b()}}function g(a){return a&&(qq.isString(a)&&(a=document.getElementById(a)),a&&(c("Attaching to form element."),d(a),i&&f(a))),a}var h=this,i=a.interceptSubmit,j=a.element,k=a.autoUpload;qq.extend(this,{newEndpoint:null,newAutoUpload:k,attachedToForm:!1,getFormInputsAsObject:function(){return null==j?null:h._form2Obj(j)}}),j=g(j),this.attachedToForm=!!j},qq.extend(qq.FormSupport.prototype,{_form2Obj:function(a){"use strict";var b={},c=function(a){var b=["button","image","reset","submit"];return qq.indexOf(b,a.toLowerCase())<0},d=function(a){return qq.indexOf(["checkbox","radio"],a.toLowerCase())>=0},e=function(a){return d(a.type)&&!a.checked?!0:a.disabled&&"hidden"!==a.type.toLowerCase()},f=function(a){var b=null;return qq.each(qq(a).children(),function(a,c){return"option"===c.tagName.toLowerCase()&&c.selected?(b=c.value,!1):void 0}),b};return qq.each(a.elements,function(a,d){if(!qq.isInput(d,!0)&&"textarea"!==d.tagName.toLowerCase()||!c(d.type)||e(d)){if("select"===d.tagName.toLowerCase()&&!e(d)){var g=f(d);null!==g&&(b[d.name]=g)}}else b[d.name]=d.value}),b}}),qq.Scaler=function(a,b){"use strict";var c=a.sendOriginal,d=a.orient,e=a.defaultType,f=a.defaultQuality/100,g=a.failureText,h=a.includeExif,i=this._getSortedSizes(a.sizes);qq.extend(this,{enabled:qq.supportedFeatures.scaling&&i.length>0,getFileRecords:function(a,j,k){var l=this,m=[],n=k.blob?k.blob:k,o=new qq.Identify(n,b);return o.isPreviewableSync()?(qq.each(i,function(a,c){var i=l._determineOutputType({defaultType:e,requestedType:c.type,refType:n.type});m.push({uuid:qq.getUniqueId(),name:l._getName(j,{name:c.name,type:i,refType:n.type}),blob:new qq.BlobProxy(n,qq.bind(l._generateScaledImage,l,{maxSize:c.maxSize,orient:d,type:i,quality:f,failedText:g,includeExif:h,log:b}))})}),m.push({uuid:a,name:j,size:n.size,blob:c?n:null})):m.push({uuid:a,name:j,size:n.size,blob:n}),m},handleNewFile:function(a,b,c,d,e,f,g,h){var i=this,j=(a.qqButtonId||a.blob&&a.blob.qqButtonId,[]),k=null,l=h.addFileToHandler,m=h.uploadData,n=h.paramsStore,o=qq.getUniqueId();qq.each(i.getFileRecords(c,b,a),function(a,b){var c,d=b.size;b.blob instanceof qq.BlobProxy&&(d=-1),c=m.addFile({uuid:b.uuid,name:b.name,size:d,batchId:f,proxyGroupId:o}),b.blob instanceof qq.BlobProxy?j.push(c):k=c,b.blob?(l(c,b.blob),e.push({id:c,file:b.blob})):m.setStatus(c,qq.status.REJECTED)}),null!==k&&(qq.each(j,function(a,b){var c={qqparentuuid:m.retrieve({id:k}).uuid,qqparentsize:m.retrieve({id:k}).size};c[g]=m.retrieve({id:b}).uuid,m.setParentId(b,k),n.addReadOnly(b,c)}),j.length&&function(){var a={};a[g]=m.retrieve({id:k}).uuid,n.addReadOnly(k,a)}())}})},qq.extend(qq.Scaler.prototype,{scaleImage:function(a,b,c){"use strict";if(!qq.supportedFeatures.scaling)throw new qq.Error("Scaling is not supported in this browser!");var d=new qq.Promise,e=c.log,f=c.getFile(a),g=c.uploadData.retrieve({id:a}),h=g&&g.name,i=g&&g.uuid,j={sendOriginal:!1,orient:b.orient,defaultType:b.type||null,defaultQuality:b.quality,failedToScaleText:"Unable to scale",sizes:[{name:"",maxSize:b.maxSize}]},k=new qq.Scaler(j,e);return qq.Scaler&&qq.supportedFeatures.imagePreviews&&f?qq.bind(function(){var b=k.getFileRecords(i,h,f)[0];b&&b.blob instanceof qq.BlobProxy?b.blob.create().then(d.success,d.failure):(e(a+" is not a scalable image!","error"),d.failure())},this)():(d.failure(),e("Could not generate requested scaled image for "+a+". "+"Scaling is either not possible in this browser, or the file could not be located.","error")),d},_determineOutputType:function(a){"use strict";var b=a.requestedType,c=a.defaultType,d=a.refType;return c||b?b?qq.indexOf(Object.keys(qq.Identify.prototype.PREVIEWABLE_MIME_TYPES),b)>=0?"image/tiff"===b?qq.supportedFeatures.tiffPreviews?b:c:b:c:c:"image/jpeg"!==d?"image/png":d},_getName:function(a,b){"use strict";var c=a.lastIndexOf("."),d=b.type||"image/png",e=b.refType,f="",g=qq.getExtension(a),h="";return b.name&&b.name.trim().length&&(h=" ("+b.name+")"),c>=0?(f=a.substr(0,c),e!==d&&(g=d.split("/")[1]),f+=h+"."+g):f=a+h,f},_getSortedSizes:function(a){"use strict";return a=qq.extend([],a),a.sort(function(a,b){return a.maxSize>b.maxSize?1:a.maxSize=0?atob(a.split(",")[1]):decodeURI(a.split(",")[1]),c=a.split(",")[0].split(":")[1].split(";")[0],d=new ArrayBuffer(b.length),e=new Uint8Array(d),qq.each(b,function(a,b){e[a]=b.charCodeAt(0)}),this._createBlob(d,c)},_createBlob:function(a,b){"use strict";var c=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,d=c&&new c;return d?(d.append(a),d.getBlob(b)):new Blob([a],{type:b})}});var ExifRestorer=function(){var a={};return a.KEY_STR="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",a.encode64=function(a){var b,c,d,e,f,g="",h="",i="",j=0;do b=a[j++],c=a[j++],h=a[j++],d=b>>2,e=(3&b)<<4|c>>4,f=(15&c)<<2|h>>6,i=63&h,isNaN(c)?f=i=64:isNaN(h)&&(i=64),g=g+this.KEY_STR.charAt(d)+this.KEY_STR.charAt(e)+this.KEY_STR.charAt(f)+this.KEY_STR.charAt(i),b=c=h="",d=e=f=i="";while(ja.length)break}return c},a.decode64=function(a){var b,c,d,e,f,g="",h="",i=0,j=[],k=/[^A-Za-z0-9\+\/\=]/g;if(k.exec(a))throw new Error("There were invalid base64 characters in the input text. Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='");a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");do d=this.KEY_STR.indexOf(a.charAt(i++)),e=this.KEY_STR.indexOf(a.charAt(i++)),f=this.KEY_STR.indexOf(a.charAt(i++)),h=this.KEY_STR.indexOf(a.charAt(i++)),b=d<<2|e>>4,c=(15&e)<<4|f>>2,g=(3&f)<<6|h,j.push(b),64!=f&&j.push(c),64!=h&&j.push(g),b=c=g="",d=e=f=h="";while(i=0?(c=!1,!1):void 0}),c},j=function(a){m(a,-1,-1),delete c[a]},k=function(a,b,c){(0===b.length||i(b,c))&&(h(e,e),this.reset())},l=function(a){var d=b(a);d>0&&(m(a,0,d),c[a]={loaded:0,total:d})},m=function(a,b,f){var g=c[a]?c[a].loaded:0,i=c[a]?c[a].total:0;-1===b&&-1===f?(d-=g,e-=i):(b&&(d+=b-g),f&&(e+=f-i)),h(d,e)};qq.extend(this,{onAllComplete:k,onStatusChange:function(a,b,c){c===qq.status.CANCELED||c===qq.status.REJECTED?j(a):c===qq.status.SUBMITTING&&l(a)},onIndividualProgress:function(a,b,d){m(a,b,d),c[a]={loaded:b,total:d}},onNewSize:function(a){l(a)},reset:function(){c={},d=0,e=0}})},qq.UiEventHandler=function(a,b){"use strict";function c(a){d.attach(a,e.eventType,function(a){a=a||window.event;var b=a.target||a.srcElement;e.onHandled(b,a)})}var d=new qq.DisposeSupport,e={eventType:"click",attachTo:null,onHandled:function(){}};qq.extend(this,{addHandler:function(a){c(a)},dispose:function(){d.dispose()}}),qq.extend(b,{getFileIdFromItem:function(a){return a.qqFileId
+},getDisposeSupport:function(){return d}}),qq.extend(e,a),e.attachTo&&c(e.attachTo)},qq.FileButtonsClickHandler=function(a){"use strict";function b(a,b){qq.each(e,function(c,e){var f,g=c.charAt(0).toUpperCase()+c.slice(1);return d.templating["is"+g](a)?(f=d.templating.getFileId(a),qq.preventDefault(b),d.log(qq.format("Detected valid file button click event on file '{}', ID: {}.",d.onGetName(f),f)),e(f),!1):void 0})}var c={},d={templating:null,log:function(){},onDeleteFile:function(){},onCancel:function(){},onRetry:function(){},onPause:function(){},onContinue:function(){},onGetName:function(){}},e={cancel:function(a){d.onCancel(a)},retry:function(a){d.onRetry(a)},deleteButton:function(a){d.onDeleteFile(a)},pause:function(a){d.onPause(a)},continueButton:function(a){d.onContinue(a)}};qq.extend(d,a),d.eventType="click",d.onHandled=b,d.attachTo=d.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(d,c))},qq.FilenameClickHandler=function(a){"use strict";function b(a,b){if(d.templating.isFileName(a)||d.templating.isEditIcon(a)){var e=d.templating.getFileId(a),f=d.onGetUploadStatus(e);f===qq.status.SUBMITTED&&(d.log(qq.format("Detected valid filename click event on file '{}', ID: {}.",d.onGetName(e),e)),qq.preventDefault(b),c.handleFilenameEdit(e,a,!0))}}var c={},d={templating:null,log:function(){},classes:{file:"qq-upload-file",editNameIcon:"qq-edit-filename-icon"},onGetUploadStatus:function(){},onGetName:function(){}};qq.extend(d,a),d.eventType="click",d.onHandled=b,qq.extend(this,new qq.FilenameEditHandler(d,c))},qq.FilenameInputFocusInHandler=function(a,b){"use strict";function c(a){if(d.templating.isEditInput(a)){var c=d.templating.getFileId(a),e=d.onGetUploadStatus(c);e===qq.status.SUBMITTED&&(d.log(qq.format("Detected valid filename input focus event on file '{}', ID: {}.",d.onGetName(c),c)),b.handleFilenameEdit(c,a))}}var d={templating:null,onGetUploadStatus:function(){},log:function(){}};b||(b={}),d.eventType="focusin",d.onHandled=c,qq.extend(d,a),qq.extend(this,new qq.FilenameEditHandler(d,b))},qq.FilenameInputFocusHandler=function(a){"use strict";a.eventType="focus",a.attachTo=null,qq.extend(this,new qq.FilenameInputFocusInHandler(a,{}))},qq.FilenameEditHandler=function(a,b){"use strict";function c(a){var b=h.onGetName(a),c=b.lastIndexOf(".");return c>0&&(b=b.substr(0,c)),b}function d(a){var b=h.onGetName(a);return qq.getExtension(b)}function e(a,b){var c,e=a.value;void 0!==e&&qq.trimStr(e).length>0&&(c=d(b),void 0!==c&&(e=e+"."+c),h.onSetName(b,e)),h.onEditingStatusChange(b,!1)}function f(a,c){b.getDisposeSupport().attach(a,"blur",function(){e(a,c)})}function g(a,c){b.getDisposeSupport().attach(a,"keyup",function(b){var d=b.keyCode||b.which;13===d&&e(a,c)})}var h={templating:null,log:function(){},onGetUploadStatus:function(){},onGetName:function(){},onSetName:function(){},onEditingStatusChange:function(){}};qq.extend(h,a),h.attachTo=h.templating.getFileList(),qq.extend(this,new qq.UiEventHandler(h,b)),qq.extend(b,{handleFilenameEdit:function(a,b,d){var e=h.templating.getEditInput(a);h.onEditingStatusChange(a,!0),e.value=c(a),d&&e.focus(),f(e,a),g(e,a)}})};var CryptoJS=CryptoJS||function(a,b){var c={},d=c.lib={},e=d.Base=function(){function a(){}return{extend:function(b){a.prototype=this;var c=new a;return b&&c.mixIn(b),c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)}),c.init.prototype=c,c.$super=this,c},create:function(){var a=this.extend();return a.init.apply(a,arguments),a},init:function(){},mixIn:function(a){for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}}}(),f=d.WordArray=e.extend({init:function(a,c){a=this.words=a||[],this.sigBytes=c!=b?c:4*a.length},toString:function(a){return(a||h).stringify(this)},concat:function(a){var b=this.words,c=a.words,d=this.sigBytes,e=a.sigBytes;if(this.clamp(),d%4)for(var f=0;e>f;f++){var g=255&c[f>>>2]>>>24-8*(f%4);b[d+f>>>2]|=g<<24-8*((d+f)%4)}else if(c.length>65535)for(var f=0;e>f;f+=4)b[d+f>>>2]=c[f>>>2];else b.push.apply(b,c);return this.sigBytes+=e,this},clamp:function(){var b=this.words,c=this.sigBytes;b[c>>>2]&=4294967295<<32-8*(c%4),b.length=a.ceil(c/4)},clone:function(){var a=e.clone.call(this);return a.words=this.words.slice(0),a},random:function(b){for(var c=[],d=0;b>d;d+=4)c.push(0|4294967296*a.random());return new f.init(c,b)}}),g=c.enc={},h=g.Hex={stringify:function(a){for(var b=a.words,c=a.sigBytes,d=[],e=0;c>e;e++){var f=255&b[e>>>2]>>>24-8*(e%4);d.push((f>>>4).toString(16)),d.push((15&f).toString(16))}return d.join("")},parse:function(a){for(var b=a.length,c=[],d=0;b>d;d+=2)c[d>>>3]|=parseInt(a.substr(d,2),16)<<24-4*(d%8);return new f.init(c,b/2)}},i=g.Latin1={stringify:function(a){for(var b=a.words,c=a.sigBytes,d=[],e=0;c>e;e++){var f=255&b[e>>>2]>>>24-8*(e%4);d.push(String.fromCharCode(f))}return d.join("")},parse:function(a){for(var b=a.length,c=[],d=0;b>d;d++)c[d>>>2]|=(255&a.charCodeAt(d))<<24-8*(d%4);return new f.init(c,b)}},j=g.Utf8={stringify:function(a){try{return decodeURIComponent(escape(i.stringify(a)))}catch(b){throw new Error("Malformed UTF-8 data")}},parse:function(a){return i.parse(unescape(encodeURIComponent(a)))}},k=d.BufferedBlockAlgorithm=e.extend({reset:function(){this._data=new f.init,this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=j.parse(a)),this._data.concat(a),this._nDataBytes+=a.sigBytes},_process:function(b){var c=this._data,d=c.words,e=c.sigBytes,g=this.blockSize,h=4*g,i=e/h;i=b?a.ceil(i):a.max((0|i)-this._minBufferSize,0);var j=i*g,k=a.min(4*j,e);if(j){for(var l=0;j>l;l+=g)this._doProcessBlock(d,l);var m=d.splice(0,j);c.sigBytes-=k}return new f.init(m,k)},clone:function(){var a=e.clone.call(this);return a._data=this._data.clone(),a},_minBufferSize:0});d.Hasher=k.extend({cfg:e.extend(),init:function(a){this.cfg=this.cfg.extend(a),this.reset()},reset:function(){k.reset.call(this),this._doReset()},update:function(a){return this._append(a),this._process(),this},finalize:function(a){a&&this._append(a);var b=this._doFinalize();return b},blockSize:16,_createHelper:function(a){return function(b,c){return new a.init(c).finalize(b)}},_createHmacHelper:function(a){return function(b,c){return new l.HMAC.init(a,c).finalize(b)}}});var l=c.algo={};return c}(Math);!function(){var a=CryptoJS,b=a.lib,c=b.WordArray,d=a.enc;d.Base64={stringify:function(a){var b=a.words,c=a.sigBytes,d=this._map;a.clamp();for(var e=[],f=0;c>f;f+=3)for(var g=255&b[f>>>2]>>>24-8*(f%4),h=255&b[f+1>>>2]>>>24-8*((f+1)%4),i=255&b[f+2>>>2]>>>24-8*((f+2)%4),j=g<<16|h<<8|i,k=0;4>k&&c>f+.75*k;k++)e.push(d.charAt(63&j>>>6*(3-k)));var l=d.charAt(64);if(l)for(;e.length%4;)e.push(l);return e.join("")},parse:function(a){var b=a.length,d=this._map,e=d.charAt(64);if(e){var f=a.indexOf(e);-1!=f&&(b=f)}for(var g=[],h=0,i=0;b>i;i++)if(i%4){var j=d.indexOf(a.charAt(i-1))<<2*(i%4),k=d.indexOf(a.charAt(i))>>>6-2*(i%4);g[h>>>2]|=(j|k)<<24-8*(h%4),h++}return c.create(g,h)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}}(),function(){var a=CryptoJS,b=a.lib,c=b.Base,d=a.enc,e=d.Utf8,f=a.algo;f.HMAC=c.extend({init:function(a,b){a=this._hasher=new a.init,"string"==typeof b&&(b=e.parse(b));var c=a.blockSize,d=4*c;b.sigBytes>d&&(b=a.finalize(b)),b.clamp();for(var f=this._oKey=b.clone(),g=this._iKey=b.clone(),h=f.words,i=g.words,j=0;c>j;j++)h[j]^=1549556828,i[j]^=909522486;f.sigBytes=g.sigBytes=d,this.reset()},reset:function(){var a=this._hasher;a.reset(),a.update(this._iKey)},update:function(a){return this._hasher.update(a),this},finalize:function(a){var b=this._hasher,c=b.finalize(a);b.reset();var d=b.finalize(this._oKey.clone().concat(c));return d}})}(),function(){var a=CryptoJS,b=a.lib,c=b.WordArray,d=b.Hasher,e=a.algo,f=[],g=e.SHA1=d.extend({_doReset:function(){this._hash=new c.init([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(a,b){for(var c=this._hash.words,d=c[0],e=c[1],g=c[2],h=c[3],i=c[4],j=0;80>j;j++){if(16>j)f[j]=0|a[b+j];else{var k=f[j-3]^f[j-8]^f[j-14]^f[j-16];f[j]=k<<1|k>>>31}var l=(d<<5|d>>>27)+i+f[j];l+=20>j?(e&g|~e&h)+1518500249:40>j?(e^g^h)+1859775393:60>j?(e&g|e&h|g&h)-1894007588:(e^g^h)-899497514,i=h,h=g,g=e<<30|e>>>2,e=d,d=l}c[0]=0|c[0]+d,c[1]=0|c[1]+e,c[2]=0|c[2]+g,c[3]=0|c[3]+h,c[4]=0|c[4]+i},_doFinalize:function(){var a=this._data,b=a.words,c=8*this._nDataBytes,d=8*a.sigBytes;return b[d>>>5]|=128<<24-d%32,b[(d+64>>>9<<4)+14]=Math.floor(c/4294967296),b[(d+64>>>9<<4)+15]=c,a.sigBytes=4*b.length,this._process(),this._hash},clone:function(){var a=d.clone.call(this);return a._hash=this._hash.clone(),a}});a.SHA1=d._createHelper(g),a.HmacSHA1=d._createHmacHelper(g)}();
+/*! 2015-08-26 */
From 1611a750365d4654d09ccb86eca6a5f95a1865e5 Mon Sep 17 00:00:00 2001
From: diminator
Date: Fri, 4 Sep 2015 16:48:00 +0200
Subject: [PATCH 217/397] Merge remote-tracking branch
'remotes/origin/AD-858-contract-history' into
AD-883-show-notificationsrequests-on-col
Conflicts:
ownership/serializers.py
---
.../wallet/components/ikonotv/ikonotv_contract_notifications.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js
index 636948d6..5e30d370 100644
--- a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js
+++ b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js
@@ -39,7 +39,7 @@ let IkonotvContractNotifications = React.createClass({
);
} else {
diff --git a/js/components/ascribe_uploader/file_drag_and_drop_preview_progress.js b/js/components/ascribe_uploader/file_drag_and_drop_preview_progress.js
index 0974142a..ef6d0e12 100644
--- a/js/components/ascribe_uploader/file_drag_and_drop_preview_progress.js
+++ b/js/components/ascribe_uploader/file_drag_and_drop_preview_progress.js
@@ -22,23 +22,28 @@ let FileDragAndDropPreviewProgress = React.createClass({
overallProgress += files[i].size / sizeOfAllFiles * files[i].progress;
}
-
return overallProgress;
},
render() {
let overallProgress = this.calcOverallProgress();
+ let style = {
+ visibility: 'hidden'
+ };
if(overallProgress !== 0) {
- return (
-
- );
- } else {
- return null;
+ style.visibility = 'visible';
}
+
+ console.log(overallProgress, style);
+
+ return (
+
+ );
}
});
diff --git a/sass/ascribe_uploader.scss b/sass/ascribe_uploader.scss
index e3b5d1c1..df08a27e 100644
--- a/sass/ascribe_uploader.scss
+++ b/sass/ascribe_uploader.scss
@@ -10,7 +10,6 @@
cursor: default !important;
- padding: 1.5em 0 1.5em 0;
}
.inactive-dropzone {
@@ -30,6 +29,7 @@
}
.file-drag-and-drop-preview-iterator {
+ margin: 2.5em 0 0 0;
text-align: right;
> div:first-child {
@@ -37,6 +37,18 @@
}
}
+.file-drag-and-drop-preview-iterator-spacing {
+ margin-bottom: 1em;
+}
+
+.file-drag-and-drop-dialog {
+ margin: 1.5em 0 1.5em 0;
+}
+
+.file-drag-and-drop-hashing-dialog {
+ margin: 1.5em 0 0 0;
+}
+
.file-drag-and-drop .file-drag-and-drop-dialog > p:first-child {
font-size: 1.5em !important;
From 2cc42841189f788e2113478aaf7077f151f946f0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Wed, 9 Sep 2015 16:22:20 +0200
Subject: [PATCH 245/397] minor cleanup
---
.../ascribe_uploader/file_drag_and_drop_preview_progress.js | 2 --
js/components/ascribe_uploader/react_s3_fine_uploader.js | 2 +-
2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/js/components/ascribe_uploader/file_drag_and_drop_preview_progress.js b/js/components/ascribe_uploader/file_drag_and_drop_preview_progress.js
index ef6d0e12..b3579825 100644
--- a/js/components/ascribe_uploader/file_drag_and_drop_preview_progress.js
+++ b/js/components/ascribe_uploader/file_drag_and_drop_preview_progress.js
@@ -35,8 +35,6 @@ let FileDragAndDropPreviewProgress = React.createClass({
style.visibility = 'visible';
}
- console.log(overallProgress, style);
-
return (
Date: Wed, 9 Sep 2015 16:32:08 +0200
Subject: [PATCH 246/397] only show progress bar if files are greater than 10MB
---
.../file_drag_and_drop_preview_progress.js | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/js/components/ascribe_uploader/file_drag_and_drop_preview_progress.js b/js/components/ascribe_uploader/file_drag_and_drop_preview_progress.js
index b3579825..62be49ae 100644
--- a/js/components/ascribe_uploader/file_drag_and_drop_preview_progress.js
+++ b/js/components/ascribe_uploader/file_drag_and_drop_preview_progress.js
@@ -25,13 +25,27 @@ let FileDragAndDropPreviewProgress = React.createClass({
return overallProgress;
},
+ calcOverallFileSize() {
+ let overallFileSize = 0;
+ let files = this.props.files.filter((file) => file.status !== 'deleted' && file.status !== 'canceled' && file.status !== 'online');
+
+ for(let i = 0; i < files.length; i++) {
+ overallFileSize += files[i].size;
+ }
+
+ return overallFileSize;
+ },
+
render() {
let overallProgress = this.calcOverallProgress();
+ let overallFileSize = this.calcOverallFileSize();
let style = {
visibility: 'hidden'
};
- if(overallProgress !== 0) {
+ // only visible if overallProgress is over zero
+ // or the overallFileSize is greater than 10MB
+ if(overallProgress !== 0 && overallFileSize > 10000000) {
style.visibility = 'visible';
}
From 2ba27d3847cbdbc815e3e39f758e03792b9803fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Wed, 9 Sep 2015 17:21:55 +0200
Subject: [PATCH 247/397] add documentation for exception
---
.../react_s3_fine_uploader.js | 34 +++++++++++++++----
1 file changed, 27 insertions(+), 7 deletions(-)
diff --git a/js/components/ascribe_uploader/react_s3_fine_uploader.js b/js/components/ascribe_uploader/react_s3_fine_uploader.js
index e41284aa..6ae7dabd 100644
--- a/js/components/ascribe_uploader/react_s3_fine_uploader.js
+++ b/js/components/ascribe_uploader/react_s3_fine_uploader.js
@@ -497,13 +497,11 @@ var ReactS3FineUploader = React.createClass({
onDeleteComplete(id, xhr, isError) {
if(isError) {
- let notification = new GlobalNotificationModel(getLangText('Couldn\'t delete file'), 'danger', 10000);
+ this.setStatusOfFile(id, 'online');
+
+ let notification = new GlobalNotificationModel(getLangText('There was an error deleting your file.'), 'danger', 10000);
GlobalNotificationActions.appendGlobalNotification(notification);
} else {
-
- // To hide the file in this component, we need to set it's status to "deleted"
- this.setStatusOfFile(id, 'deleted');
-
let notification = new GlobalNotificationModel(getLangText('File deleted'), 'success', 5000);
GlobalNotificationActions.appendGlobalNotification(notification);
}
@@ -525,6 +523,13 @@ var ReactS3FineUploader = React.createClass({
},
handleDeleteFile(fileId) {
+ // We set the files state to 'deleted' immediately, so that the user is not confused with
+ // the unresponsiveness of the UI
+ //
+ // If there is an error during the deletion, we will just change the status back to 'online'
+ // and display an error message
+ this.setStatusOfFile(fileId, 'deleted');
+
// In some instances (when the file was already uploaded and is just displayed to the user
// - for example in the loan contract or additional files dialog)
// fineuploader does not register an id on the file (we do, don't be confused by this!).
@@ -542,8 +547,6 @@ var ReactS3FineUploader = React.createClass({
// promise
} else {
let fileToDelete = this.state.filesToUpload[fileId];
- fileToDelete.status = 'deleted';
-
S3Fetcher
.deleteFile(fileToDelete.s3Key, fileToDelete.s3Bucket)
.then(() => this.onDeleteComplete(fileToDelete.id, null, false))
@@ -731,6 +734,7 @@ var ReactS3FineUploader = React.createClass({
synchronizeFileLists(files) {
let oldFiles = this.state.filesToUpload;
let oldAndNewFiles = this.state.uploader.getUploads();
+
// Add fineuploader specific information to new files
for(let i = 0; i < oldAndNewFiles.length; i++) {
for(let j = 0; j < files.length; j++) {
@@ -745,6 +749,22 @@ var ReactS3FineUploader = React.createClass({
// and re-add fineuploader specific information for old files as well
for(let i = 0; i < oldAndNewFiles.length; i++) {
for(let j = 0; j < oldFiles.length; j++) {
+
+ // EXCEPTION:
+ //
+ // Files do not necessarily come from the user's hard drive but can also be fetched
+ // from Amazon S3. This is handled in onSessionRequestComplete.
+ //
+ // If the user deletes one of those files, then fineuploader will still keep it in his
+ // files array but with key, progress undefined and size === -1 but
+ // status === 'upload successful'.
+ // This poses a problem as we depend on the amount of files that have
+ // status === 'upload successful', therefore once the file is synced,
+ // we need to tag its status as 'deleted' (which basically happens here)
+ if(oldAndNewFiles[i].size === -1 && (!oldAndNewFiles[i].progress || oldAndNewFiles[i].progress === 0)) {
+ oldAndNewFiles[i].status = 'deleted';
+ }
+
if(oldAndNewFiles[i].originalName === oldFiles[j].name) {
oldAndNewFiles[i].progress = oldFiles[j].progress;
oldAndNewFiles[i].type = oldFiles[j].type;
From 3307e282e4e1e2fcf2efa0a076b813888fad5f1c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Wed, 9 Sep 2015 17:27:23 +0200
Subject: [PATCH 248/397] remove header title
---
js/components/whitelabel/wallet/wallet_routes.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/js/components/whitelabel/wallet/wallet_routes.js b/js/components/whitelabel/wallet/wallet_routes.js
index 62c1d255..40f092d6 100644
--- a/js/components/whitelabel/wallet/wallet_routes.js
+++ b/js/components/whitelabel/wallet/wallet_routes.js
@@ -71,7 +71,7 @@ let ROUTES = {
-
+
From 1c5b0c7172e5674ed773ffd06c5c619c332ac5b5 Mon Sep 17 00:00:00 2001
From: diminator
Date: Wed, 9 Sep 2015 19:29:58 +0200
Subject: [PATCH 249/397] only one agreement pending agreement notifications
per subdomain (only by whitelabel owner)
---
.../ascribe_forms/form_contract_agreement.js | 1 +
.../ascribe_forms/form_create_contract.js | 8 +++---
js/components/ascribe_forms/property.js | 6 ++--
.../ikonotv/ikonotv_contract_notifications.js | 28 +++++++++++++------
js/utils/requests.js | 4 +--
5 files changed, 30 insertions(+), 17 deletions(-)
diff --git a/js/components/ascribe_forms/form_contract_agreement.js b/js/components/ascribe_forms/form_contract_agreement.js
index 9aad8827..0c20383c 100644
--- a/js/components/ascribe_forms/form_contract_agreement.js
+++ b/js/components/ascribe_forms/form_contract_agreement.js
@@ -54,6 +54,7 @@ let ContractAgreementForm = React.createClass({
let notification = 'Contract agreement send';
notification = new GlobalNotificationModel(notification, 'success', 10000);
GlobalNotificationActions.appendGlobalNotification(notification);
+ this.refs.form.reset();
},
getFormData(){
diff --git a/js/components/ascribe_forms/form_create_contract.js b/js/components/ascribe_forms/form_create_contract.js
index ee26adfc..9cf97db7 100644
--- a/js/components/ascribe_forms/form_create_contract.js
+++ b/js/components/ascribe_forms/form_create_contract.js
@@ -53,15 +53,14 @@ let CreateContractForm = React.createClass({
ContractListActions.fetchContractList({is_active: 'True'});
let notification = new GlobalNotificationModel(getLangText('Contract %s successfully created', response.name), 'success', 5000);
GlobalNotificationActions.appendGlobalNotification(notification);
- //
- //// also refresh contract lists for the rest of the contract settings page
- //ContractListActions.fetchContractList();
+ this.refs.form.reset();
},
render() {
return (
diff --git a/js/components/ascribe_forms/property.js b/js/components/ascribe_forms/property.js
index cfc4c4d9..90aa0490 100644
--- a/js/components/ascribe_forms/property.js
+++ b/js/components/ascribe_forms/property.js
@@ -90,8 +90,10 @@ let Property = React.createClass({
// maybe do reset by reload instead of front end state?
this.setState({value: this.state.initialValue});
- // resets the value of a custom react component input
- this.refs.input.state.value = this.state.initialValue;
+ if (this.refs.input.state && this.refs.input.state.value) {
+ // resets the value of a custom react component input
+ this.refs.input.state.value = this.state.initialValue;
+ }
// resets the value of a plain HTML5 input
this.refs.input.getDOMNode().value = this.state.initialValue;
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js
index e7e2d851..6a63657c 100644
--- a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js
+++ b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js
@@ -53,7 +53,7 @@ let IkonotvContractNotifications = React.createClass({
this.setState(state);
},
- displayContract(){
+ getContract(){
let notifications = this.state.contractAgreementListNotifications[0];
let blob = notifications.contract_agreement.contract.blob;
if (blob.mime === 'pdf') {
@@ -62,7 +62,7 @@ let IkonotvContractNotifications = React.createClass({
From b5e5102ea4260c9d966ed411efa56a83572b3e34 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Thu, 10 Sep 2015 14:00:59 +0200
Subject: [PATCH 256/397] replace in keyword with dot notation checking
---
.../ascribe_detail/edition_container.js | 2 +-
.../ascribe_detail/piece_container.js | 2 +-
js/components/ascribe_forms/form.js | 23 ++++++++++---------
js/components/ascribe_forms/property.js | 12 ++++++----
.../slides_container.js | 11 ++++++---
.../ascribe_detail/prize_piece_container.js | 11 ++++++++-
.../ascribe_detail/cyland_piece_container.js | 2 +-
.../cyland/cyland_register_piece.js | 3 +++
.../ascribe_detail/ikonotv_piece_container.js | 2 +-
9 files changed, 45 insertions(+), 23 deletions(-)
diff --git a/js/components/ascribe_detail/edition_container.js b/js/components/ascribe_detail/edition_container.js
index 15086434..2194123d 100644
--- a/js/components/ascribe_detail/edition_container.js
+++ b/js/components/ascribe_detail/edition_container.js
@@ -50,7 +50,7 @@ let EditionContainer = React.createClass({
},
render() {
- if('title' in this.state.edition) {
+ if(this.state.edition && this.state.edition.title) {
return (
this[this.props.method](), 100);
} else {
throw new Error('This HTTP method is not supported by form.js (' + this.props.method + ')');
@@ -109,11 +109,11 @@ let Form = React.createClass({
getFormData() {
let data = {};
- for (let ref in this.refs){
+ for(let ref in this.refs){
data[this.refs[ref].props.name] = this.refs[ref].state.value;
}
- if (this.props.getFormData){
+ if (this.props.getFormData && typeof this.props.getFormData === 'function'){
data = mergeOptionsWithDuplicates(data, this.props.getFormData());
}
@@ -125,11 +125,12 @@ let Form = React.createClass({
},
handleSuccess(response){
- if ('handleSuccess' in this.props){
+ if(this.props.handleSuccess && typeof this.props.handleSuccess === 'function') {
this.props.handleSuccess(response);
}
- for (var ref in this.refs){
- if ('handleSuccess' in this.refs[ref]){
+
+ for(let ref in this.refs) {
+ if(this.refs[ref] && this.refs[ref].handleSuccess && typeof this.refs[ref].handleSuccess === 'function'){
this.refs[ref].handleSuccess();
}
}
@@ -141,7 +142,7 @@ let Form = React.createClass({
handleError(err){
if (err.json) {
- for (var input in err.json.errors){
+ for (let input in err.json.errors){
if (this.refs && this.refs[input] && this.refs[input].state) {
this.refs[input].setErrors(err.json.errors[input]);
} else {
@@ -171,8 +172,8 @@ let Form = React.createClass({
},
clearErrors(){
- for (var ref in this.refs){
- if ('clearErrors' in this.refs[ref]){
+ for(let ref in this.refs){
+ if (this.refs[ref] && this.refs[ref].clearErrors && typeof this.refs[ref].clearErrors === 'function'){
this.refs[ref].clearErrors();
}
}
@@ -221,7 +222,7 @@ let Form = React.createClass({
},
renderChildren() {
- return ReactAddons.Children.map(this.props.children, (child, i) => {
+ return ReactAddons.Children.map(this.props.children, (child) => {
if (child) {
return ReactAddons.addons.cloneWithProps(child, {
handleChange: this.handleChangeChild,
diff --git a/js/components/ascribe_forms/property.js b/js/components/ascribe_forms/property.js
index de88e1a0..61c5c96e 100644
--- a/js/components/ascribe_forms/property.js
+++ b/js/components/ascribe_forms/property.js
@@ -29,8 +29,11 @@ let Property = React.createClass({
handleChange: React.PropTypes.func,
ignoreFocus: React.PropTypes.bool,
className: React.PropTypes.string,
+
onClick: React.PropTypes.func,
onChange: React.PropTypes.func,
+ onBlur: React.PropTypes.func,
+
children: React.PropTypes.oneOfType([
React.PropTypes.arrayOf(React.PropTypes.element),
React.PropTypes.element
@@ -109,7 +112,7 @@ let Property = React.createClass({
handleChange(event) {
this.props.handleChange(event);
- if ('onChange' in this.props) {
+ if (this.props.onChange && typeof this.props.onChange === 'function') {
this.props.onChange(event);
}
@@ -125,7 +128,7 @@ let Property = React.createClass({
// if onClick is defined from the outside,
// just call it
- if(this.props.onClick) {
+ if(this.props.onClick && typeof this.props.onClick === 'function') {
this.props.onClick();
}
@@ -140,7 +143,7 @@ let Property = React.createClass({
isFocused: false
});
- if(this.props.onBlur) {
+ if(this.props.onBlur && typeof this.props.onBlur === 'function') {
this.props.onBlur(event);
}
},
@@ -198,6 +201,7 @@ let Property = React.createClass({
},
render() {
+ let footer = null;
let tooltip = ;
let style = this.props.style ? mergeOptions({}, this.props.style) : {};
@@ -207,7 +211,7 @@ let Property = React.createClass({
{this.props.tooltip}
);
}
- let footer = null;
+
if(this.props.footer){
footer = (
diff --git a/js/components/ascribe_slides_container/slides_container.js b/js/components/ascribe_slides_container/slides_container.js
index 8b800377..c78478f1 100644
--- a/js/components/ascribe_slides_container/slides_container.js
+++ b/js/components/ascribe_slides_container/slides_container.js
@@ -4,13 +4,12 @@ import React from 'react';
import Router from 'react-router';
import ReactAddons from 'react/addons';
-import Col from 'react-bootstrap/lib/Col';
-
import SlidesContainerBreadcrumbs from './slides_container_breadcrumbs';
let State = Router.State;
let Navigation = Router.Navigation;
+
let SlidesContainer = React.createClass({
propTypes: {
children: React.PropTypes.arrayOf(React.PropTypes.element),
@@ -30,12 +29,15 @@ let SlidesContainer = React.createClass({
let slideNum = -1;
let startFrom = -1;
- if(queryParams && 'slide_num' in queryParams) {
+ // We can actually need to check if slide_num is present as a key in queryParams.
+ // We do not really care about its value though...
+ if(queryParams && 'slide_num' in queryParams.slide_num) {
slideNum = parseInt(queryParams.slide_num, 10);
}
// if slide_num is not set, this will be done in componentDidMount
// the query param 'start_from' removes all slide children before the respective number
+ // Also, we use the 'in' keyword for the same reason as above in 'slide_num'
if(queryParams && 'start_from' in queryParams) {
startFrom = parseInt(queryParams.start_from, 10);
}
@@ -51,6 +53,9 @@ let SlidesContainer = React.createClass({
componentDidMount() {
// check if slide_num was defined, and if not then default to 0
let queryParams = this.getQuery();
+
+ // We use 'in' to check if the key is present in the user's browser url bar,
+ // we do not really care about its value at this point
if(!('slide_num' in queryParams)) {
// we're first requiring all the other possible queryParams and then set
diff --git a/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js b/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js
index 4b785fc2..822557db 100644
--- a/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js
+++ b/js/components/whitelabel/prize/components/ascribe_detail/prize_piece_container.js
@@ -90,14 +90,23 @@ let PieceContainer = React.createClass({
},
render() {
- if('title' in this.state.piece) {
+ if(this.state.piece && this.state.piece.title) {
+ /*
+
+ This really needs a refactor!
+
+ - Tim
+
+ */
// Only show the artist name if you are the participant or if you are a judge and the piece is shortlisted
let artistName = ((this.state.currentUser.is_jury && !this.state.currentUser.is_judge) ||
(this.state.currentUser.is_judge && !this.state.piece.selected )) ?
: this.state.piece.artist_name;
+
// Only show the artist email if you are a judge and the piece is shortlisted
let artistEmail = (this.state.currentUser.is_judge && this.state.piece.selected ) ?
: null;
+
return (
Date: Thu, 10 Sep 2015 15:47:27 +0200
Subject: [PATCH 257/397] add download button to contract list
---
.../ascribe_settings/contract_settings.js | 28 +++++++++++++------
1 file changed, 20 insertions(+), 8 deletions(-)
diff --git a/js/components/ascribe_settings/contract_settings.js b/js/components/ascribe_settings/contract_settings.js
index 278c4c1b..06584a8d 100644
--- a/js/components/ascribe_settings/contract_settings.js
+++ b/js/components/ascribe_settings/contract_settings.js
@@ -105,6 +105,12 @@ let ContractSettings = React.createClass({
UPDATE
+
+ DOWNLOAD
+
@@ -129,19 +135,25 @@ let ContractSettings = React.createClass({
content={contract.name}
buttons={
- {getLangText('choose files to upload')}
+ {getLangText('choose %s to upload', this.props.fileClassToUpload.plural)}
);
} else {
- let dialog = queryParams.method === 'hash' ? getLangText('choose a file to hash') : getLangText('choose a file to upload');
+ let dialog = queryParams.method === 'hash' ? getLangText('choose a %s to hash', this.props.fileClassToUpload.singular) : getLangText('choose a file to upload');
return (
-
{getLangText('Drag a file here')}
+
{getLangText('Drag a %s here', this.props.fileClassToUpload.singular)}
);
} else {
+ let accept = '';
+
+ /**
+ * Fineuploader allows to specify the file extensions that are allowed to upload.
+ * For our self defined input, we can reuse those declarations to restrict which files
+ * the user can pick from his hard drive.
+ */
+ if(validation && validation.allowedExtensions.length > 0) {
+ // add a dot in front of the extension
+ let prefixedAllowedExtensions = validation.allowedExtensions.map((ext) => '.' + ext);
+
+ // generate a comma separated list to add them to the DOM element
+ // See: http://stackoverflow.com/questions/4328947/limit-file-format-when-using-input-type-file
+ accept = prefixedAllowedExtensions.join(', ');
+ }
+
return (
);
} else {
- let accept = '';
-
- /**
- * Fineuploader allows to specify the file extensions that are allowed to upload.
- * For our self defined input, we can reuse those declarations to restrict which files
- * the user can pick from his hard drive.
- */
- if(validation && validation.allowedExtensions && validation.allowedExtensions.length > 0) {
- // add a dot in front of the extension
- let prefixedAllowedExtensions = validation.allowedExtensions.map((ext) => '.' + ext);
-
- // generate a comma separated list to add them to the DOM element
- // See: http://stackoverflow.com/questions/4328947/limit-file-format-when-using-input-type-file
- accept = prefixedAllowedExtensions.join(', ');
- }
-
return (
+ accept={allowedExtensions}/>
);
}
diff --git a/js/components/ascribe_uploader/ascribe_upload_button/upload_button.js b/js/components/ascribe_uploader/ascribe_upload_button/upload_button.js
new file mode 100644
index 00000000..a3fa985c
--- /dev/null
+++ b/js/components/ascribe_uploader/ascribe_upload_button/upload_button.js
@@ -0,0 +1,114 @@
+'use strict';
+
+import React from 'react';
+
+import { displayValidProgressFilesFilter } from '../react_s3_fine_uploader_utils';
+
+let UploadButton = React.createClass({
+ propTypes: {
+ onDragStart: React.PropTypes.func,
+ onDrop: React.PropTypes.func.isRequired,
+ onDrag: React.PropTypes.func,
+ onDragEnter: React.PropTypes.func,
+ onLeave: React.PropTypes.func,
+ onDragLeave: React.PropTypes.func,
+ onDragOver: React.PropTypes.func,
+ onDragEnd: React.PropTypes.func,
+ onInactive: React.PropTypes.func,
+ filesToUpload: React.PropTypes.array,
+ handleDeleteFile: React.PropTypes.func,
+ handleCancelFile: React.PropTypes.func,
+ handlePauseFile: React.PropTypes.func,
+ handleResumeFile: React.PropTypes.func,
+ multiple: React.PropTypes.bool,
+
+
+ // For simplification purposes we're just going to use this prop as a
+ // label for the upload button
+ fileClassToUpload: React.PropTypes.shape({
+ singular: React.PropTypes.string,
+ plural: React.PropTypes.string
+ }),
+
+ allowedExtensions: React.PropTypes.string
+ },
+
+ handleDrop(event) {
+ event.preventDefault();
+ event.stopPropagation();
+ let files = event.target.files;
+
+ if(typeof this.props.onDrop === 'function' && files) {
+ this.props.onDrop(files);
+ }
+
+ },
+
+ getUploadingFiles() {
+ return this.props.filesToUpload.filter((file) => file.status === 'uploading');
+ },
+
+ handleOnClick() {
+ let uploadingFiles = this.getUploadingFiles();
+
+ // We only want the button to be clickable if there are no files currently uploading
+ if(uploadingFiles.length === 0) {
+ // Firefox only recognizes the simulated mouse click if bubbles is set to true,
+ // but since Google Chrome propagates the event much further than needed, we
+ // need to stop propagation as soon as the event is created
+ var evt = new MouseEvent('click', {
+ view: window,
+ bubbles: true,
+ cancelable: true
+ });
+
+ evt.stopPropagation();
+ this.refs.fileinput.getDOMNode().dispatchEvent(evt);
+ }
+ },
+
+ getButtonLabel() {
+ let { filesToUpload, fileClassToUpload } = this.props;
+
+ // filter invalid files that might have been deleted or canceled...
+ filesToUpload = filesToUpload.filter(displayValidProgressFilesFilter);
+
+ // Depending on wether there is an upload going on or not we
+ // display the progress
+ if(filesToUpload.length > 0) {
+ return 'Upload progress: ' + Math.ceil(filesToUpload[0].progress) + '%';
+ } else {
+ return fileClassToUpload.singular;
+ }
+ },
+
+ render() {
+ let {
+ multiple,
+ fileClassToUpload,
+ allowedExtensions
+ } = this.props;
+
+ return (
+
+ {this.getButtonLabel()}
+
+
+ );
+ }
+});
+
+export default UploadButton;
\ No newline at end of file
diff --git a/js/components/ascribe_uploader/react_s3_fine_uploader.js b/js/components/ascribe_uploader/react_s3_fine_uploader.js
index 8ba53444..05709ad2 100644
--- a/js/components/ascribe_uploader/react_s3_fine_uploader.js
+++ b/js/components/ascribe_uploader/react_s3_fine_uploader.js
@@ -16,7 +16,7 @@ import AppConstants from '../../constants/application_constants';
import { computeHashOfFile } from '../../utils/file_utils';
-import { displayValidFilesFilter } from './react_s3_fine_uploader_utils';
+import { displayValidFilesFilter, transformAllowedExtensionsToInputAcceptProp } from './react_s3_fine_uploader_utils';
import { getCookie } from '../../utils/fetch_api_utils';
import { getLangText } from '../../utils/lang_utils';
@@ -125,7 +125,10 @@ let ReactS3FineUploader = React.createClass({
// Uploading functionality of react fineuploader is disconnected from its UI
// layer, which means that literally every (properly adjusted) react element
// can handle the UI handling.
- fileInputElement: React.PropTypes.func
+ fileInputElement: React.PropTypes.oneOfType([
+ React.PropTypes.func,
+ React.PropTypes.element
+ ])
},
mixins: [Router.State],
@@ -838,6 +841,16 @@ let ReactS3FineUploader = React.createClass({
},
+ getAllowedExtensions() {
+ let { validation } = this.props;
+
+ if(validation && validation.allowedExtensions && validation.allowedExtensions.length > 0) {
+ return transformAllowedExtensionsToInputAcceptProp(validation.allowedExtensions);
+ } else {
+ return null;
+ }
+ },
+
render() {
let {
multiple,
@@ -868,7 +881,7 @@ let ReactS3FineUploader = React.createClass({
hashingProgress: this.state.hashingProgress,
enableLocalHashing: enableLocalHashing,
fileClassToUpload: fileClassToUpload,
- validation: validation
+ allowedExtensions: this.getAllowedExtensions()
});
}
diff --git a/js/components/ascribe_uploader/react_s3_fine_uploader_utils.js b/js/components/ascribe_uploader/react_s3_fine_uploader_utils.js
index 92d5c2ba..cd1dbce2 100644
--- a/js/components/ascribe_uploader/react_s3_fine_uploader_utils.js
+++ b/js/components/ascribe_uploader/react_s3_fine_uploader_utils.js
@@ -52,3 +52,22 @@ export function displayValidProgressFilesFilter(file) {
return file.status !== 'deleted' && file.status !== 'canceled' && file.status !== 'online';
}
+
+/**
+ * Fineuploader allows to specify the file extensions that are allowed to upload.
+ * For our self defined input, we can reuse those declarations to restrict which files
+ * the user can pick from his hard drive.
+ *
+ * Takes an array of file extensions (['pdf', 'png', ...]) and transforms them into a string
+ * that can be passed into an html5 input via its 'accept' prop.
+ * @param {array} allowedExtensions Array of strings without a dot prefixed
+ * @return {string} Joined string (comma-separated) of the passed-in array
+ */
+export function transformAllowedExtensionsToInputAcceptProp(allowedExtensions) {
+ // add a dot in front of the extension
+ let prefixedAllowedExtensions = allowedExtensions.map((ext) => '.' + ext);
+
+ // generate a comma separated list to add them to the DOM element
+ // See: http://stackoverflow.com/questions/4328947/limit-file-format-when-using-input-type-file
+ return prefixedAllowedExtensions.join(', ');
+}
diff --git a/sass/ascribe_uploader.scss b/sass/ascribe_uploader.scss
index 6e9eebd9..331b6b00 100644
--- a/sass/ascribe_uploader.scss
+++ b/sass/ascribe_uploader.scss
@@ -9,6 +9,7 @@
text-align: center;
vertical-align: middle;
cursor: default !important;
+ padding: 1.5em 0 1.5em 0;
.file-drag-and-drop-dialog > p:first-child {
font-size: 1.5em !important;
From 2656bdac14703fed6b151d09bc84436de0641c7b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Tue, 15 Sep 2015 17:18:38 +0200
Subject: [PATCH 286/397] correct query parameters for contract list request
---
js/components/ascribe_forms/form_contract_agreement.js | 2 +-
js/components/ascribe_forms/form_create_contract.js | 2 +-
js/components/ascribe_settings/contract_settings.js | 6 +++---
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/js/components/ascribe_forms/form_contract_agreement.js b/js/components/ascribe_forms/form_contract_agreement.js
index 887b99db..fb6793e6 100644
--- a/js/components/ascribe_forms/form_contract_agreement.js
+++ b/js/components/ascribe_forms/form_contract_agreement.js
@@ -35,7 +35,7 @@ let ContractAgreementForm = React.createClass({
componentDidMount() {
ContractListStore.listen(this.onChange);
- ContractListActions.fetchContractList({is_active: true});
+ ContractListActions.fetchContractList(true);
},
componentWillUnmount() {
diff --git a/js/components/ascribe_forms/form_create_contract.js b/js/components/ascribe_forms/form_create_contract.js
index b275df03..d3d14966 100644
--- a/js/components/ascribe_forms/form_create_contract.js
+++ b/js/components/ascribe_forms/form_create_contract.js
@@ -50,7 +50,7 @@ let CreateContractForm = React.createClass({
},
handleCreateSuccess(response) {
- ContractListActions.fetchContractList({is_active: true});
+ ContractListActions.fetchContractList(true);
let notification = new GlobalNotificationModel(getLangText('Contract %s successfully created', response.name), 'success', 5000);
GlobalNotificationActions.appendGlobalNotification(notification);
this.refs.form.reset();
diff --git a/js/components/ascribe_settings/contract_settings.js b/js/components/ascribe_settings/contract_settings.js
index b79f77f1..0db6133e 100644
--- a/js/components/ascribe_settings/contract_settings.js
+++ b/js/components/ascribe_settings/contract_settings.js
@@ -26,7 +26,7 @@ let ContractSettings = React.createClass({
componentDidMount() {
ContractListStore.listen(this.onChange);
- ContractListActions.fetchContractList({is_active: true});
+ ContractListActions.fetchContractList(true);
},
componentWillUnmount() {
@@ -42,7 +42,7 @@ let ContractSettings = React.createClass({
contract.is_public = true;
ContractListActions.changeContract(contract)
.then(() => {
- ContractListActions.fetchContractList({is_active: true});
+ ContractListActions.fetchContractList(true);
let notification = getLangText('Contract %s is now public', contract.name);
notification = new GlobalNotificationModel(notification, 'success', 4000);
GlobalNotificationActions.appendGlobalNotification(notification);
@@ -58,7 +58,7 @@ let ContractSettings = React.createClass({
return () => {
ContractListActions.removeContract(contract.id)
.then((response) => {
- ContractListActions.fetchContractList({is_active: true});
+ ContractListActions.fetchContractList(true);
let notification = new GlobalNotificationModel(response.notification, 'success', 4000);
GlobalNotificationActions.appendGlobalNotification(notification);
})
From 17cb2223c2358a28782d8277e57117748eea514d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Wed, 16 Sep 2015 09:47:22 +0200
Subject: [PATCH 287/397] finalize contract update button
---
js/actions/contract_list_actions.js | 2 +-
.../ascribe_settings/contract_settings.js | 26 ++------------
.../contract_settings_update_button.js | 36 ++++++++++++++++---
.../ascribe_upload_button/upload_button.js | 5 +--
js/fetchers/ownership_fetcher.js | 2 +-
5 files changed, 38 insertions(+), 33 deletions(-)
diff --git a/js/actions/contract_list_actions.js b/js/actions/contract_list_actions.js
index a856fb2b..5b874caf 100644
--- a/js/actions/contract_list_actions.js
+++ b/js/actions/contract_list_actions.js
@@ -30,7 +30,7 @@ class ContractListActions {
changeContract(contract){
return Q.Promise((resolve, reject) => {
- OwnershipFetcher.makeContractPublic(contract)
+ OwnershipFetcher.changeContract(contract)
.then((res) => {
resolve(res);
})
diff --git a/js/components/ascribe_settings/contract_settings.js b/js/components/ascribe_settings/contract_settings.js
index 00b37b78..278c0f52 100644
--- a/js/components/ascribe_settings/contract_settings.js
+++ b/js/components/ascribe_settings/contract_settings.js
@@ -39,23 +39,6 @@ let ContractSettings = React.createClass({
this.setState(state);
},
- makeContractPublic(contract) {
- return () => {
- contract.is_public = true;
- ContractListActions.changeContract(contract)
- .then(() => {
- ContractListActions.fetchContractList(true);
- let notification = getLangText('Contract %s is now public', contract.name);
- notification = new GlobalNotificationModel(notification, 'success', 4000);
- GlobalNotificationActions.appendGlobalNotification(notification);
- })
- .catch((err) => {
- let notification = new GlobalNotificationModel(err, 'danger', 10000);
- GlobalNotificationActions.appendGlobalNotification(notification);
- });
- };
- },
-
removeContract(contract) {
return () => {
ContractListActions.removeContract(contract.id)
@@ -113,7 +96,7 @@ let ContractSettings = React.createClass({
content={contract.name}
buttons={
);
}
});
diff --git a/js/components/ascribe_forms/form_copyright_association.js b/js/components/ascribe_forms/form_copyright_association.js
new file mode 100644
index 00000000..451afb97
--- /dev/null
+++ b/js/components/ascribe_forms/form_copyright_association.js
@@ -0,0 +1,75 @@
+'use strict';
+
+import React from 'react';
+
+import GlobalNotificationModel from '../../models/global_notification_model';
+import GlobalNotificationActions from '../../actions/global_notification_actions';
+
+import Form from './form';
+import Property from './property';
+
+import apiUrls from '../../constants/api_urls';
+import appConstants from '../../constants/application_constants';
+
+import { getLangText } from '../../utils/lang_utils';
+
+let CopyrightAssociationForm = React.createClass({
+ propTypes: {
+ currentUser: React.PropTypes.object
+ },
+
+ handleSubmitSuccess(){
+ let notification = getLangText('Copyright association updated');
+ notification = new GlobalNotificationModel(notification, 'success', 10000);
+ GlobalNotificationActions.appendGlobalNotification(notification);
+ },
+
+ getProfileFormData(){
+ if (this.props.currentUser && this.props.currentUser.email){
+ return {email: this.props.currentUser.email};
+ }
+ return null;
+ },
+
+ render() {
+ let selectedState = -1;
+ if (this.props.currentUser
+ && this.props.currentUser.profile
+ && this.props.currentUser.profile.copyright_association) {
+ selectedState = appConstants.copyrightAssociations.indexOf(this.props.currentUser.profile.copyright_association);
+ }
+ return (
+
+
+
+
+
+
+ );
+ }
+});
+
+export default CopyrightAssociationForm;
\ No newline at end of file
diff --git a/js/components/ascribe_forms/form_loan.js b/js/components/ascribe_forms/form_loan.js
index dacbae77..a1c31330 100644
--- a/js/components/ascribe_forms/form_loan.js
+++ b/js/components/ascribe_forms/form_loan.js
@@ -61,7 +61,7 @@ let LoanForm = React.createClass({
// however, it can also be that at the time the component is mounting,
// the email is not defined (because it's asynchronously fetched from the server).
// Then we need to update it as soon as it is included into LoanForm's props.
- if(nextProps && nextProps.email) {
+ if(nextProps && nextProps.email && this.props.email !== nextProps.email) {
this.getContractAgreementsOrCreatePublic(nextProps.email);
}
},
@@ -75,16 +75,19 @@ let LoanForm = React.createClass({
},
getContractAgreementsOrCreatePublic(email){
- ContractAgreementListActions.flushContractAgreementList();
- if (email) {
- ContractAgreementListActions.fetchAvailableContractAgreementList(email).then(
- (contractAgreementList) => {
- if (!contractAgreementList) {
- ContractAgreementListActions.createContractAgreementFromPublicContract(email);
+ /* a more complex defer (with promises) otherwise we dispatch while an action is being dispatched) */
+ window.setTimeout(() => {
+ ContractAgreementListActions.flushContractAgreementList();
+
+ if (email) {
+ ContractAgreementListActions.fetchAvailableContractAgreementList(email).then(
+ (contractAgreementList) => {
+ if (!contractAgreementList) {
+ ContractAgreementListActions.createContractAgreementFromPublicContract(email);
+ }
}
- }
- );
- }
+ );
+ }}, 0);
},
getFormData(){
diff --git a/js/components/ascribe_settings/account_settings.js b/js/components/ascribe_settings/account_settings.js
index b4d46b2d..93a419c2 100644
--- a/js/components/ascribe_settings/account_settings.js
+++ b/js/components/ascribe_settings/account_settings.js
@@ -13,6 +13,8 @@ import Property from '../ascribe_forms/property';
import InputCheckbox from '../ascribe_forms/input_checkbox';
import CollapsibleParagraph from '../ascribe_collapsible/collapsible_paragraph';
+import CopyrightAssociationForm from '../ascribe_forms/form_copyright_association';
+
import ApiUrls from '../../constants/api_urls';
import AppConstants from '../../constants/application_constants';
@@ -117,6 +119,7 @@ let AccountSettings = React.createClass({
show={true}
defaultExpanded={true}>
{content}
+
{profile}
{/*
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_additional_data_form.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_additional_data_form.js
index 6a2f8cc5..6f249c7b 100644
--- a/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_additional_data_form.js
+++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_additional_data_form.js
@@ -7,7 +7,7 @@ import Property from '../../../../../ascribe_forms/property';
import InputTextAreaToggable from '../../../../../ascribe_forms/input_textarea_toggable';
-import FurtherDetailsFileuploader from '../../../../../ascribe_detail/further_details_fileuploader';
+//import FurtherDetailsFileuploader from '../../../../../ascribe_detail/further_details_fileuploader';
import ApiUrls from '../../../../../../constants/api_urls';
import AppConstants from '../../../../../../constants/application_constants';
@@ -15,7 +15,7 @@ import AppConstants from '../../../../../../constants/application_constants';
import requests from '../../../../../../utils/requests';
import { getLangText } from '../../../../../../utils/lang_utils';
-import { formSubmissionValidation } from '../../../../../ascribe_uploader/react_s3_fine_uploader_utils';
+//import { formSubmissionValidation } from '../../../../../ascribe_uploader/react_s3_fine_uploader_utils';
let IkonotvAdditionalDataForm = React.createClass({
@@ -110,15 +110,6 @@ let IkonotvAdditionalDataForm = React.createClass({
placeholder={getLangText('Enter a conceptual overview...')}
required="required"/>
-
);
} else {
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js
index 6a63657c..beffe23a 100644
--- a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js
+++ b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_contract_notifications.js
@@ -6,17 +6,18 @@ import Router from 'react-router';
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
import Button from 'react-bootstrap/lib/Button';
-import Form from '../../../../ascribe_forms/form';
-import Property from '../../../../ascribe_forms/property';
-import InputCheckbox from '../../../../ascribe_forms/input_checkbox';
-
import NotificationActions from '../../../../../actions/notification_actions';
import NotificationStore from '../../../../../stores/notification_store';
+
+import UserStore from '../../../../../stores/user_store';
+
import WhitelabelStore from '../../../../../stores/whitelabel_store';
import GlobalNotificationModel from '../../../../../models/global_notification_model';
import GlobalNotificationActions from '../../../../../actions/global_notification_actions';
+import CopyrightAssociationForm from '../../../../ascribe_forms/form_copyright_association';
+
import apiUrls from '../../../../../constants/api_urls';
import requests from '../../../../../utils/requests';
@@ -32,12 +33,14 @@ let IkonotvContractNotifications = React.createClass({
getInitialState() {
return mergeOptions(
NotificationStore.getState(),
+ UserStore.getState(),
WhitelabelStore.getState()
);
},
componentDidMount() {
NotificationStore.listen(this.onChange);
+ UserStore.listen(this.onChange);
WhitelabelStore.listen(this.onChange);
if (this.state.contractAgreementListNotifications === null){
NotificationActions.fetchContractAgreementListNotifications();
@@ -88,7 +91,8 @@ let IkonotvContractNotifications = React.createClass({
let notifications = this.state.contractAgreementListNotifications[0];
let appendix = notifications.contract_agreement.appendix;
if (appendix) {
- return (
+ return (
+
{getLangText('Appendix')}
{appendix.default}
@@ -99,6 +103,13 @@ let IkonotvContractNotifications = React.createClass({
return null;
},
+ handleConfirm() {
+ let contractAgreement = this.state.contractAgreementListNotifications[0].contract_agreement;
+ requests.put(apiUrls.ownership_contract_agreements_confirm, {contract_agreement_id: contractAgreement.id}).then(
+ () => this.handleConfirmSuccess()
+ );
+ },
+
handleConfirmSuccess() {
let notification = new GlobalNotificationModel(getLangText('You have accepted the conditions'), 'success', 10000);
GlobalNotificationActions.appendGlobalNotification(notification);
@@ -118,11 +129,29 @@ let IkonotvContractNotifications = React.createClass({
this.transitionTo('pieces');
},
+ getCopyrightAssociationForm(){
+ if (this.state.currentUser && this.state.currentUser.profile
+ && this.state.currentUser.profile.copyright_association){
+ return null;
+ }
+ return (
+
+
{getLangText('Are you a member of any copyright societies?')}
+ As an entirely digital broadcasting and licensing company we’re always keen to properly handle the content that artists, museums, and archives consign to us. The main concern with art online is the risk it will be misused. Thanks to our partnership with ascribe.io, we can address that issue in a way that is faster and more efficient for our users.
+ Using ascribe means we can do away with paper contracts and replace them with an online-only version. Partnering with ascribe also means we can encrypt digital work once it is uploaded. This revolutionary service will allow you to keep track of your works and share without worry.
+
+
+
+
+ NEW SUBSCRIPTION SERVICE
+
+
+ IkonoTV has developed an app that provides playlists on demand—soon to be available on all online devices and SmartTVs. The app is a paid service; in view of the interest in distributing this service in public spaces (hospitals, airports, hotels, etc.), we can now offer the possibility of a share in revenue to compensate for the artist’s work.
+
+
+
+
+ THE RAPID GROWTH OF IkonoTV
+
+
+ In October 2014, our first app was installed on Amazon Fire TV. During the first month it was downloaded 200 times, and jumped to 5,000 by the second month. Today, we’re well over the 175,000 mark, making us the number one app in our category in the US, Canada, UK and Germany.
+
+
+
+
+ FULL TRANSPARENCY
+
+
+ We expect a similar success with each SmartTV brand. For us, this marks the beginning of a new way to offer hassle-free licensing to visual artists—and we’re very proud to be an integral part of this virtual market. In the future, should we plan anything not directly mentioned in the contract, we will always make sure to secure the artist’s approval first. ikonoTV was developed to serve art and artists, and for this reason it’s of the utmost importance to us to respect this relationship. Thanks to you, we now look forward to our next big step.
+
diff --git a/js/components/piece_list.js b/js/components/piece_list.js
index 71304a63..c7cab0f4 100644
--- a/js/components/piece_list.js
+++ b/js/components/piece_list.js
@@ -15,6 +15,8 @@ import AccordionListItemTableEditions from './ascribe_accordion_list/accordion_l
import Pagination from './ascribe_pagination/pagination';
+import PieceListFilterDisplay from './piece_list_filter_display';
+
import GlobalAction from './global_action';
import PieceListBulkModal from './ascribe_piece_list_bulk_modal/piece_list_bulk_modal';
import PieceListToolbar from './ascribe_piece_list_toolbar/piece_list_toolbar';
@@ -22,6 +24,8 @@ import PieceListToolbar from './ascribe_piece_list_toolbar/piece_list_toolbar';
import AppConstants from '../constants/application_constants';
import { mergeOptions } from '../utils/general_utils';
+import { getLangText } from '../utils/lang_utils';
+
let PieceList = React.createClass({
propTypes: {
@@ -149,9 +153,6 @@ let PieceList = React.createClass({
let loadingElement = ();
let AccordionListItemType = this.props.accordionListItemType;
- //
-
-
return (
+ filter.split('acl_')[1]).join(', ');
+
+ // there are acls, like acl_create_editions that still have underscores in them,
+ // therefore we need to replace all underscores with spaces
+ return filterText.replace(/_/g, ' ');
+ },
+
+ render() {
+ let { filterBy } = this.props;
+
+ // do not show the FilterDisplay if there are no filters applied
+ if(filterBy && Object.keys(filterBy).length === 0) {
+ return null;
+ } else {
+ return (
+
+
+ {this.getFilterText()}
+
+
+
+ );
+ }
+ }
+});
+
+export default PieceListFilterDisplay;
\ No newline at end of file
diff --git a/sass/ascribe_accordion_list.scss b/sass/ascribe_accordion_list.scss
index 6412a598..86a519b5 100644
--- a/sass/ascribe_accordion_list.scss
+++ b/sass/ascribe_accordion_list.scss
@@ -5,6 +5,10 @@ $ascribe-accordion-list-item-height: 8em;
padding-right: 15px;
}
+.ascribe-accordion-list-placeholder {
+ margin-top: 1em;
+}
+
.ascribe-accordion-list-item {
background-color: white;
border: 1px solid black;
diff --git a/sass/main.scss b/sass/main.scss
index 5f5c0f23..39ea78bd 100644
--- a/sass/main.scss
+++ b/sass/main.scss
@@ -487,3 +487,23 @@ hr {
.ascribe-progress-bar-xs {
height: 12px;
}
+
+
+.ascribe-piece-list-filter-display {
+ padding-left: 0;
+ padding-right: 0;
+
+ > span {
+ font-size: 1.1em;
+ font-weight: 600;
+ color: #616161;
+
+ padding-left: .3em;
+ }
+
+ > hr {
+ margin-top: .15em;
+ margin-bottom: .1em;
+ border-color: #ccc;
+ }
+}
\ No newline at end of file
From 5c2ec3ffb0f2b558ca8f6a9d55303908e6d7e116 Mon Sep 17 00:00:00 2001
From: diminator
Date: Wed, 16 Sep 2015 23:27:38 +0200
Subject: [PATCH 297/397] bug fix signup query landing page redirect ikono:
user acl proxy on submit button ikono: further details + slides
---
js/components/ascribe_forms/form_loan.js | 6 +-
js/components/ascribe_forms/form_signup.js | 1 -
.../slides_container.js | 4 +-
js/components/signup_container.js | 9 +
.../ikonotv_accordion_list_item.js | 14 +-
.../ascribe_detail/ikonotv_piece_container.js | 137 +++++++--------
...form.js => ikonotv_artist_details_form.js} | 44 +++--
.../ikonotv_artwork_details_form.js | 164 ++++++++++++++++++
.../ikonotv/ikonotv_contract_notifications.js | 4 +-
.../components/ikonotv/ikonotv_landing.js | 31 ++--
.../ikonotv/ikonotv_register_piece.js | 128 ++++++++++----
js/components/whitelabel/wallet/wallet_app.js | 2 +-
12 files changed, 395 insertions(+), 149 deletions(-)
rename js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/{ikonotv_additional_data_form.js => ikonotv_artist_details_form.js} (64%)
create mode 100644 js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artwork_details_form.js
diff --git a/js/components/ascribe_forms/form_loan.js b/js/components/ascribe_forms/form_loan.js
index a1c31330..0c60fd7b 100644
--- a/js/components/ascribe_forms/form_loan.js
+++ b/js/components/ascribe_forms/form_loan.js
@@ -35,6 +35,7 @@ let LoanForm = React.createClass({
url: React.PropTypes.string,
id: React.PropTypes.object,
message: React.PropTypes.string,
+ createPublicContractAgreement: React.PropTypes.bool,
handleSuccess: React.PropTypes.func
},
@@ -44,7 +45,8 @@ let LoanForm = React.createClass({
showPersonalMessage: true,
showEndDate: true,
showStartDate: true,
- showPassword: true
+ showPassword: true,
+ createPublicContractAgreement: true
};
},
@@ -82,7 +84,7 @@ let LoanForm = React.createClass({
if (email) {
ContractAgreementListActions.fetchAvailableContractAgreementList(email).then(
(contractAgreementList) => {
- if (!contractAgreementList) {
+ if (!contractAgreementList && this.props.createPublicContractAgreement) {
ContractAgreementListActions.createContractAgreementFromPublicContract(email);
}
}
diff --git a/js/components/ascribe_forms/form_signup.js b/js/components/ascribe_forms/form_signup.js
index 8b4e4cf7..928afe38 100644
--- a/js/components/ascribe_forms/form_signup.js
+++ b/js/components/ascribe_forms/form_signup.js
@@ -67,7 +67,6 @@ let SignupForm = React.createClass({
},
getFormData() {
- console.log(this.getQuery());
if (this.getQuery().token){
return {token: this.getQuery().token};
}
diff --git a/js/components/ascribe_slides_container/slides_container.js b/js/components/ascribe_slides_container/slides_container.js
index 84dff61c..53092a38 100644
--- a/js/components/ascribe_slides_container/slides_container.js
+++ b/js/components/ascribe_slides_container/slides_container.js
@@ -178,7 +178,7 @@ let SlidesContainer = React.createClass({
let breadcrumbs = [];
ReactAddons.Children.map(this.props.children, (child, i) => {
- if(i >= this.state.startFrom && child.props['data-slide-title']) {
+ if(child && i >= this.state.startFrom && child.props['data-slide-title']) {
breadcrumbs.push(child.props['data-slide-title']);
}
});
@@ -229,7 +229,7 @@ let SlidesContainer = React.createClass({
// since the default parameter of startFrom is -1, we do not need to check
// if its actually present in the url bar, as it will just not match
- if(i >= this.state.startFrom) {
+ if(child && i >= this.state.startFrom) {
return ReactAddons.addons.cloneWithProps(child, {
className: 'ascribe-slide',
style: {
diff --git a/js/components/signup_container.js b/js/components/signup_container.js
index 46813b59..856e4af2 100644
--- a/js/components/signup_container.js
+++ b/js/components/signup_container.js
@@ -1,8 +1,12 @@
'use strict';
import React from 'react';
+import Router from 'react-router';
import SignupForm from './ascribe_forms/form_signup';
+import { getLangText } from '../utils/lang_utils';
+
+let Link = Router.Link;
let SignupContainer = React.createClass({
getInitialState() {
@@ -33,7 +37,12 @@ let SignupContainer = React.createClass({
return (
+
+ {getLangText('Already an ascribe user')}? {getLangText('Log in')}...
+ {getLangText('Forgot my password')}? {getLangText('Rescue me')}...
+
);
From 0819724a10a57895526bffc4a0eea2e6a5ec22d0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Mon, 21 Sep 2015 10:57:10 +0200
Subject: [PATCH 325/397] probably fix dispatch.dispatch error + showing wrong
piece data bug
---
js/actions/contract_agreement_list_actions.js | 3 ++-
js/components/ascribe_forms/input_textarea_toggable.js | 4 ++++
js/components/ascribe_settings/account_settings.js | 4 ++--
.../wallet/components/ikonotv/ikonotv_register_piece.js | 4 ++++
4 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/js/actions/contract_agreement_list_actions.js b/js/actions/contract_agreement_list_actions.js
index 93bc35ac..fe089f24 100644
--- a/js/actions/contract_agreement_list_actions.js
+++ b/js/actions/contract_agreement_list_actions.js
@@ -15,8 +15,9 @@ class ContractAgreementListActions {
}
fetchContractAgreementList(issuer, accepted, pending) {
+ this.actions.updateContractAgreementList(null);
+
return Q.Promise((resolve, reject) => {
- this.actions.updateContractAgreementList(null);
OwnershipFetcher.fetchContractAgreementList(issuer, accepted, pending)
.then((contractAgreementList) => {
if (contractAgreementList.count > 0) {
diff --git a/js/components/ascribe_forms/input_textarea_toggable.js b/js/components/ascribe_forms/input_textarea_toggable.js
index e6da5282..39ef36fc 100644
--- a/js/components/ascribe_forms/input_textarea_toggable.js
+++ b/js/components/ascribe_forms/input_textarea_toggable.js
@@ -20,6 +20,8 @@ let InputTextAreaToggable = React.createClass({
},
componentDidUpdate(prevProps, prevState) {
+ // if the components state value was changed during an update, we want to refresh it
+ // in this component as well as in the parent Property
if(this.state.value !== prevState.value) {
this.handleChange({
target: {
@@ -28,6 +30,8 @@ let InputTextAreaToggable = React.createClass({
});
}
+ // Otherwise, if state wasn't defined beforehand and defaultValue is defined from the outside
+ // we set it as the component's state and update Property by calling handleChange
if(!this.state.value && this.props.defaultValue) {
this.handleChange({
target: {
diff --git a/js/components/ascribe_settings/account_settings.js b/js/components/ascribe_settings/account_settings.js
index aa50d719..7c769c22 100644
--- a/js/components/ascribe_settings/account_settings.js
+++ b/js/components/ascribe_settings/account_settings.js
@@ -19,8 +19,8 @@ import { getLangText } from '../../utils/lang_utils';
let AccountSettings = React.createClass({
propTypes: {
- currentUser: React.PropTypes.object.required,
- loadUser: React.PropTypes.func.required
+ currentUser: React.PropTypes.object.isRequired,
+ loadUser: React.PropTypes.func.isRequired
},
handleSuccess(){
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js
index 76880304..98d8a8e7 100644
--- a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js
+++ b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js
@@ -57,6 +57,10 @@ let IkonotvRegisterPiece = React.createClass({
PieceStore.listen(this.onChange);
UserActions.fetchCurrentUser();
+ // Before we load the new piece, we reset the piece store to delete old data that we do
+ // not want to display to the user.
+ PieceActions.updatePiece({});
+
let queryParams = this.getQuery();
// Since every step of this register process is atomic,
From 92f543490e8a3650e9490ccf020757131587a8aa Mon Sep 17 00:00:00 2001
From: diminator
Date: Mon, 21 Sep 2015 11:26:36 +0200
Subject: [PATCH 326/397] buttonlink style
---
.../components/ikonotv/ascribe_buttons/ikonotv_submit_button.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_buttons/ikonotv_submit_button.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_buttons/ikonotv_submit_button.js
index 7f1723cd..523f9fe2 100644
--- a/js/components/whitelabel/wallet/components/ikonotv/ascribe_buttons/ikonotv_submit_button.js
+++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_buttons/ikonotv_submit_button.js
@@ -40,7 +40,7 @@ let IkonotvSubmitButton = React.createClass({
'start_from': startFrom,
'piece_id': piece.id
}}
- className={classNames('btn', 'btn-default', this.props.className)}>
+ className={classNames('ascribe-margin-1px', this.props.className)}>
{getLangText('Loan to IkonoTV')}
);
From c00e003aeb4454842be98aa712b5b1a551268898 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Mon, 21 Sep 2015 12:05:42 +0200
Subject: [PATCH 327/397] refactor input textarea to use disabled instead of
editable
---
js/components/ascribe_detail/note.js | 9 ++++---
js/components/ascribe_forms/form_consign.js | 4 ++--
.../ascribe_forms/form_contract_agreement.js | 4 +++-
js/components/ascribe_forms/form_loan.js | 2 +-
.../ascribe_forms/form_piece_extradata.js | 7 +++---
.../ascribe_forms/form_register_piece.js | 2 +-
.../ascribe_forms/form_share_email.js | 4 ++--
.../ascribe_forms/form_submit_to_prize.js | 8 +++----
js/components/ascribe_forms/form_transfer.js | 4 ++--
js/components/ascribe_forms/form_unconsign.js | 4 ++--
.../ascribe_forms/form_unconsign_request.js | 4 ++--
.../ascribe_forms/input_fineuploader.js | 10 ++++----
.../ascribe_forms/input_textarea_toggable.js | 4 ++--
js/components/coa_verify_container.js | 5 ++--
.../ascribe_detail/prize_piece_container.js | 4 ++--
.../prize/components/prize_register_piece.js | 8 +++----
.../ascribe_detail/cyland_piece_container.js | 4 ++--
.../cyland_additional_data_form.js | 9 ++-----
.../ascribe_detail/ikonotv_piece_container.js | 8 +++----
.../ikonotv_artist_details_form.js | 16 ++++---------
.../ikonotv_artwork_details_form.js | 24 +++++--------------
21 files changed, 61 insertions(+), 83 deletions(-)
diff --git a/js/components/ascribe_detail/note.js b/js/components/ascribe_detail/note.js
index 0f32e5da..b377ff5c 100644
--- a/js/components/ascribe_detail/note.js
+++ b/js/components/ascribe_detail/note.js
@@ -44,14 +44,13 @@ let Note = React.createClass({
+ handleSuccess={this.showNotification}
+ disabled={!this.props.editable}>
+ label={this.props.label}>
@@ -63,4 +62,4 @@ let Note = React.createClass({
}
});
-export default Note
\ No newline at end of file
+export default Note;
\ No newline at end of file
diff --git a/js/components/ascribe_forms/form_consign.js b/js/components/ascribe_forms/form_consign.js
index 6f85adc2..de4a4788 100644
--- a/js/components/ascribe_forms/form_consign.js
+++ b/js/components/ascribe_forms/form_consign.js
@@ -56,10 +56,10 @@ let ConsignForm = React.createClass({
+ editable={true}
+ overrideForm={true}>
diff --git a/js/components/ascribe_forms/form_contract_agreement.js b/js/components/ascribe_forms/form_contract_agreement.js
index 94ab26d0..85ed6b6a 100644
--- a/js/components/ascribe_forms/form_contract_agreement.js
+++ b/js/components/ascribe_forms/form_contract_agreement.js
@@ -129,9 +129,11 @@ let ContractAgreementForm = React.createClass({
name='appendix'
checkboxLabel={getLangText('Add appendix to the contract')}>
{getLangText('Appendix')}
+ {/* We're using disabled on a form here as PropertyCollapsible currently
+ does not support the disabled + overrideForm functionality */}
+ );
+ }
}
});
From b0b44718da9e844c0eae8b44303bd302b6f3ab1e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Tue, 22 Sep 2015 10:29:23 +0200
Subject: [PATCH 341/397] Changes to landing page text according to Elisabeth
---
.../whitelabel/wallet/components/ikonotv/ikonotv_landing.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_landing.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_landing.js
index 7184c605..e991233a 100644
--- a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_landing.js
+++ b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_landing.js
@@ -76,7 +76,7 @@ let IkonotvLanding = React.createClass({
NEW SUBSCRIPTION SERVICE
- IkonoTV has developed an app that provides playlists on demand—soon to be available on all online devices and SmartTVs. The app is a paid service; in view of the interest in distributing this service in public spaces (hospitals, airports, hotels, etc.), we can now offer the possibility of a share in revenue to compensate for the artist’s work.
+ IkonoTV has developed an app that provides playlists on demand—soon to be available on all online devices and SmartTVs. We can now offer the possibility of a share in revenue to compensate for the artist’s work.
@@ -84,7 +84,7 @@ let IkonotvLanding = React.createClass({
THE RAPID GROWTH OF IkonoTV
- In October 2014, our first app was installed on Amazon Fire TV. During the first month it was downloaded 200 times, and jumped to 5,000 by the second month. Today, we’re well over the 175,000 mark, making us the number one app in our category in the US, Canada, UK and Germany.
+ In October 2014, our first app was installed on Amazon Fire TV. During the first month it was downloaded 200 times, and jumped to 5,000 by the second month. Today, we’re well over the 285,000 mark, making us the number one app in our category in the US, Canada, UK and Germany.
{this.getContract()}
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js
index 91a62b3b..b946d984 100644
--- a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js
+++ b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_register_piece.js
@@ -259,8 +259,8 @@ let IkonotvRegisterPiece = React.createClass({
- {this.getSlideArtistDetails()}
{this.getSlideArtworkDetails()}
+ {this.getSlideArtistDetails()}
{this.getSlideLoan()}
);
diff --git a/sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss b/sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss
index 4e0ba619..df1cf39c 100644
--- a/sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss
+++ b/sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss
@@ -221,7 +221,7 @@ $ikono--logo: 'https://s3-us-west-2.amazonaws.com/ascribe0/whitelabel/ikonotv/ik
margin-bottom: 2em;
> h1 {
- font-size: 9em;
+ font-size: 7em;
font-weight: bold;
margin-top: 10px;
From 31ffc4262a8d458429912427b89966211bdfaea1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Tue, 22 Sep 2015 11:41:10 +0200
Subject: [PATCH 343/397] change text in signup form
---
js/components/ascribe_forms/form_signup.js | 2 +-
js/constants/languages.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/js/components/ascribe_forms/form_signup.js b/js/components/ascribe_forms/form_signup.js
index 67097b42..bcc38007 100644
--- a/js/components/ascribe_forms/form_signup.js
+++ b/js/components/ascribe_forms/form_signup.js
@@ -127,7 +127,7 @@ let SignupForm = React.createClass({
style={{paddingBottom: 0}}>
- {' ' + getLangText('I agree to the Terms of Service') + ' '}
+ {' ' + getLangText('I agree to the Terms of Service of ascribe') + ' '}
(
{getLangText('read')}
)
diff --git a/js/constants/languages.js b/js/constants/languages.js
index db29166f..4a40d9a4 100644
--- a/js/constants/languages.js
+++ b/js/constants/languages.js
@@ -207,7 +207,7 @@ const languages = {
'Specify editions': 'Specify editions',
'Editions': 'Editions',
'Create editions': 'Create editions',
- 'I agree to the Terms of Service': 'I agree to the Terms of Service',
+ 'I agree to the Terms of Service of ascribe': 'I agree to the Terms of Service of ascribe',
'read': 'read',
'If your email address exists in our database, you will receive a password recovery link in a few minutes.': 'If your email address exists in our database, you will receive a password recovery link in a few minutes.',
'REGISTREE': 'REGISTREE',
From a8c436c40b3e47362dca0fee9dbed642dbbe87fc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Tue, 22 Sep 2015 11:56:30 +0200
Subject: [PATCH 344/397] Change detail text in loan process
---
.../ikonotv/ascribe_forms/ikonotv_artist_details_form.js | 2 +-
.../ikonotv/ascribe_forms/ikonotv_artwork_details_form.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artist_details_form.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artist_details_form.js
index d198c7dd..fadeec59 100644
--- a/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artist_details_form.js
+++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_forms/ikonotv_artist_details_form.js
@@ -119,7 +119,7 @@ let IkonotvArtistDetailsForm = React.createClass({
+ placeholder={getLangText('Sizes in centimeters. Durations in minutes.')}/>
Date: Tue, 22 Sep 2015 12:20:14 +0200
Subject: [PATCH 345/397] filter in frontend
---
.../components/ikonotv/ikonotv_piece_list.js | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_piece_list.js b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_piece_list.js
index 33478fbf..053d21b3 100644
--- a/js/components/whitelabel/wallet/components/ikonotv/ikonotv_piece_list.js
+++ b/js/components/whitelabel/wallet/components/ikonotv/ikonotv_piece_list.js
@@ -37,11 +37,17 @@ let IkonotvPieceList = React.createClass({
accordionListItemType={IkonotvAccordionListItem}
filterParams={[{
label: getLangText('Show works I have'),
- items: [{
- key: 'acl_loaned',
- label: getLangText('loaned to IkonoTV')
- }]
- }]}/>
+ items: [
+ {
+ key: 'submitted',
+ label: getLangText('submitted')
+ },
+ {
+ key: 'accepted',
+ label: getLangText('loaned')
+ }
+ ]
+ }]}/>
);
}
From 878a716262daebcc03bab2f1e8bec77fd9dd0860 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Tue, 22 Sep 2015 13:20:55 +0200
Subject: [PATCH 346/397] Remove 'learn more' from contract form
---
js/components/ascribe_forms/form_contract_agreement.js | 10 +---------
.../ascribe_forms/ikonotv_artwork_details_form.js | 2 +-
2 files changed, 2 insertions(+), 10 deletions(-)
diff --git a/js/components/ascribe_forms/form_contract_agreement.js b/js/components/ascribe_forms/form_contract_agreement.js
index 85ed6b6a..ddb261c4 100644
--- a/js/components/ascribe_forms/form_contract_agreement.js
+++ b/js/components/ascribe_forms/form_contract_agreement.js
@@ -68,15 +68,7 @@ let ContractAgreementForm = React.createClass({
- {getLangText('Learn more')}
-
- }>
+ onChange={this.onContractChange}>
Date: Tue, 22 Sep 2015 13:37:31 +0200
Subject: [PATCH 347/397] Increase robustness by excluding meta data for pieces
that have been loaned before actual launch
---
.../ascribe_detail/ikonotv_piece_container.js | 41 +++++++++++++------
1 file changed, 28 insertions(+), 13 deletions(-)
diff --git a/js/components/whitelabel/wallet/components/ikonotv/ascribe_detail/ikonotv_piece_container.js b/js/components/whitelabel/wallet/components/ikonotv/ascribe_detail/ikonotv_piece_container.js
index 0803961b..4d3b3dbe 100644
--- a/js/components/whitelabel/wallet/components/ikonotv/ascribe_detail/ikonotv_piece_container.js
+++ b/js/components/whitelabel/wallet/components/ikonotv/ascribe_detail/ikonotv_piece_container.js
@@ -65,6 +65,33 @@ let IkonotvPieceContainer = React.createClass({
},
render() {
+ let furtherDetails = (
+
+ {getLangText('This piece has been loaned before we started to collect further details.')}
+
+ );
+
+ if(this.state.piece.extra_data && Object.keys(this.state.piece.extra_data).length > 0 && this.state.piece.acl) {
+ furtherDetails = (
+
+
+
+
+ );
+ }
+
if(this.state.piece && this.state.piece.title) {
return (
-
-
-
-
+ {furtherDetails}
);
}
From c7321359c95fa315be7eae53cf8850f461c550f1 Mon Sep 17 00:00:00 2001
From: vrde
Date: Tue, 22 Sep 2015 13:37:31 +0200
Subject: [PATCH 348/397] Add style for notification
---
sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss b/sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss
index c25517e1..62b1690d 100644
--- a/sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss
+++ b/sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss
@@ -380,3 +380,9 @@ $ikono--logo: 'https://s3-us-west-2.amazonaws.com/ascribe0/whitelabel/ikonotv/ik
border-color: $ikono--button-color;
}
}
+
+
+// notifications
+.client--ikonotv .ascribe-global-notification-success {
+ background-color: $ikono--button-color;
+}
From d4f637aa8ae4a66a61b3ed9972439e6fb1e448af Mon Sep 17 00:00:00 2001
From: vrde
Date: Tue, 22 Sep 2015 13:44:19 +0200
Subject: [PATCH 349/397] Add color for disabled buttons
---
.../wallet/ikonotv/ikonotv_landing.scss | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss b/sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss
index c25517e1..50e24cd2 100644
--- a/sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss
+++ b/sass/whitelabel/wallet/ikonotv/ikonotv_landing.scss
@@ -290,6 +290,31 @@ $ikono--logo: 'https://s3-us-west-2.amazonaws.com/ascribe0/whitelabel/ikonotv/ik
}
}
+// disabled buttons
+.client--ikonotv {
+ .btn-default.disabled,
+ .btn-default.disabled:hover,
+ .btn-default.disabled:focus,
+ .btn-default.disabled.focus,
+ .btn-default.disabled:active,
+ .btn-default.disabled.active,
+ .btn-default[disabled],
+ .btn-default[disabled]:hover,
+ .btn-default[disabled]:focus,
+ .btn-default[disabled].focus,
+ .btn-default[disabled]:active,
+ .btn-default[disabled].active,
+ fieldset[disabled] .btn-default,
+ fieldset[disabled] .btn-default:hover,
+ fieldset[disabled] .btn-default:focus,
+ fieldset[disabled] .btn-default.focus,
+ fieldset[disabled] .btn-default:active,
+ fieldset[disabled] .btn-default.active {
+ background-color: darken($ikono--button-color, 20%);
+ border-color: darken($ikono--button-color, 20%);
+ }
+}
+
// buttons!
// thought of the day:
// "every great atrocity is the result of people just following orders"
From 33b8e51aee0dbae7be13b63cfdf4b44350fb4d6d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?=
Date: Tue, 22 Sep 2015 14:13:04 +0200
Subject: [PATCH 350/397] Fix react warning for select inputs
---
.../ascribe_forms/form_contract_agreement.js | 2 +-
.../form_copyright_association.js | 25 +++++++++++--------
2 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/js/components/ascribe_forms/form_contract_agreement.js b/js/components/ascribe_forms/form_contract_agreement.js
index ddb261c4..6d47d8e0 100644
--- a/js/components/ascribe_forms/form_contract_agreement.js
+++ b/js/components/ascribe_forms/form_contract_agreement.js
@@ -134,7 +134,7 @@ let ContractAgreementForm = React.createClass({
return (
- {getLangText('No private contracts found, please go to the ')}
+ {getLangText('No contracts uploaded yet, please go to the ')}
{getLangText('settings page')}
{getLangText(' and create them.')}
diff --git a/js/components/ascribe_forms/form_copyright_association.js b/js/components/ascribe_forms/form_copyright_association.js
index 53c7245f..da14e76d 100644
--- a/js/components/ascribe_forms/form_copyright_association.js
+++ b/js/components/ascribe_forms/form_copyright_association.js
@@ -29,12 +29,15 @@ let CopyrightAssociationForm = React.createClass({
},
render() {
- let selectedState = -1;
- if (this.props.currentUser
- && this.props.currentUser.profile
+ let selectedState;
+ let selectDefaultValue = ' -- ' + getLangText('select an association') + ' -- ';
+
+ if (this.props.currentUser && this.props.currentUser.profile
&& this.props.currentUser.profile.copyright_association) {
selectedState = AppConstants.copyrightAssociations.indexOf(this.props.currentUser.profile.copyright_association);
+ selectedState = selectedState !== -1 ? AppConstants.copyrightAssociations[selectedState] : selectDefaultValue;
}
+
if (this.props.currentUser && this.props.currentUser.email){
return (
-
+
+
{appendix.default}
+
);
}
}
@@ -214,7 +230,7 @@ let LoanForm = React.createClass({
name='loanee'
label={getLangText('Loanee Email')}
editable={!this.props.email}
- onBlur={this.handleOnChange}
+ onChange={this.handleOnChange}
overrideForm={!!this.props.email}>
+ {this.getContractCheckbox()}
+ {this.getAppendix()}
- {this.getContractCheckbox()}
- {this.getAppendix()}
{this.props.children}
);
diff --git a/js/components/ascribe_forms/input_checkbox.js b/js/components/ascribe_forms/input_checkbox.js
index 275b2374..38885441 100644
--- a/js/components/ascribe_forms/input_checkbox.js
+++ b/js/components/ascribe_forms/input_checkbox.js
@@ -25,7 +25,10 @@ let InputCheckbox = React.createClass({
// provided by Property
disabled: React.PropTypes.bool,
- onChange: React.PropTypes.func
+ onChange: React.PropTypes.func,
+
+ // can be used to style the component from the outside
+ style: React.PropTypes.object
},
// As HTML inputs, we're setting the default value for an input to checked === false
@@ -98,6 +101,7 @@ let InputCheckbox = React.createClass({
return (
-
-