aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rw-r--r--perllib/FixMyStreet/App/Controller/Photo.pm29
-rw-r--r--perllib/FixMyStreet/App/Controller/Report/New.pm18
-rw-r--r--t/app/controller/photo.t3
-rw-r--r--t/app/controller/report_import.t12
-rw-r--r--t/app/controller/report_new.t94
-rw-r--r--t/app/controller/report_new_open311.t4
-rw-r--r--templates/web/base/common_header_tags.html1
-rw-r--r--templates/web/base/js/translation_strings.html5
-rw-r--r--templates/web/base/report/new/fill_in_details_form.html49
-rw-r--r--templates/web/bromley/report/new/fill_in_details_form.html49
-rw-r--r--templates/web/fixmystreet.com/report/new/after_photo.html10
-rw-r--r--templates/web/oxfordshire/report/new/after_photo.html3
-rw-r--r--templates/web/zurich/report/new/fill_in_details_form.html49
-rw-r--r--web/cobrands/fixmystreet/fixmystreet.js75
-rw-r--r--web/cobrands/fixmystreet/images/cross-14px.pngbin0 -> 154 bytes
-rw-r--r--web/cobrands/fixmystreet/images/cross-14px.svg6
-rw-r--r--web/cobrands/fixmystreet/images/spinner-grey-eee.gifbin0 -> 35015 bytes
-rw-r--r--web/cobrands/fixmystreet/images/spinner-grey-eee.svg1
-rw-r--r--web/cobrands/sass/_base.scss1
-rw-r--r--web/cobrands/sass/_dropzone.scss198
-rwxr-xr-xweb/js/dropzone.min.js2
22 files changed, 493 insertions, 119 deletions
diff --git a/README.md b/README.md
index 81124d25c..27dd4334f 100644
--- a/README.md
+++ b/README.md
@@ -41,6 +41,8 @@ We've extracted all of the mobile apps from this repository into the
## Releases
* master (development)
+ - Front end improvements:
+ - Add multiple photo upload support, with new UI. #190
- Performance improvements:
- Reduce memory usage. #1285
- Bugfixes:
@@ -48,6 +50,7 @@ We've extracted all of the mobile apps from this repository into the
- Prevent SVG chevron being stretched in Firefox. #1256
- Better display/internationalisation of numbers. #1297
- Fix cobrand restriction of My/Nearby. #1289
+ - Don't have hover state on disabled buttons.
- Development improvements:
- Add generic static route handler. #1235
- Store reports summary data by cobrand. #1290
diff --git a/perllib/FixMyStreet/App/Controller/Photo.pm b/perllib/FixMyStreet/App/Controller/Photo.pm
index bc72f4bfb..e8025e0a1 100644
--- a/perllib/FixMyStreet/App/Controller/Photo.pm
+++ b/perllib/FixMyStreet/App/Controller/Photo.pm
@@ -69,7 +69,7 @@ sub index :LocalRegex('^(c/)?(\d+)(?:\.(\d+))?(?:\.(full|tn|fp))?\.jpeg$') {
$c->detach( 'no_photo' ) if $id =~ /\D/;
($item) = $c->cobrand->problems->search( {
id => $id,
- state => [ FixMyStreet::DB::Result::Problem->visible_states(), 'partial' ],
+ state => [ FixMyStreet::DB::Result::Problem->visible_states() ],
photo => { '!=', undef },
} );
}
@@ -150,6 +150,33 @@ sub _crop {
return $blobs[0];
}
+sub upload : Local {
+ my ( $self, $c ) = @_;
+ my @items = (
+ ( map {
+ /^photo/ ? # photo, photo1, photo2 etc.
+ ($c->req->upload($_)) : ()
+ } sort $c->req->upload),
+ );
+ my $photoset = FixMyStreet::App::Model::PhotoSet->new({
+ c => $c,
+ data_items => \@items,
+ });
+
+ my $fileid = $photoset->data;
+ my $out;
+ if ($c->stash->{photo_error} || !$fileid) {
+ $c->res->status(500);
+ $out = { error => $c->stash->{photo_error} || _('Unknown error') };
+ } else {
+ $out = { id => $fileid };
+ }
+
+ my $body = JSON->new->utf8(1)->encode($out);
+ $c->res->content_type('application/json; charset=utf-8');
+ $c->res->body($body);
+}
+
=head2 process_photo
Handle the photo - either checking and storing it after an upload or retrieving
diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm
index 246facbee..4632f450d 100644
--- a/perllib/FixMyStreet/App/Controller/Report/New.pm
+++ b/perllib/FixMyStreet/App/Controller/Report/New.pm
@@ -426,26 +426,21 @@ sub initialize_report : Private {
for (1) { # use as pseudo flow control
- # did we find a token
- last unless $partial;
-
# is it in the database
my $token =
$c->model("DB::Token")
- ->find( { scope => 'partial', token => $partial } ) #
+ ->find( { scope => 'partial', token => $partial } )
|| last;
# can we get an id from it?
- my $id = $token->data #
- || last;
+ my $id = $token->data || last;
# load the related problem
- $report = $c->cobrand->problems #
- ->search( { id => $id, state => 'partial' } ) #
+ $report = $c->cobrand->problems
+ ->search( { id => $id, state => 'partial' } )
->first;
if ($report) {
-
# log the problem creation user in to the site
$c->authenticate( { email => $report->user->email },
'no_password' );
@@ -453,9 +448,10 @@ sub initialize_report : Private {
# save the token to delete at the end
$c->stash->{partial_token} = $token if $report;
- }
- else {
+ # Stash the photo IDs for "already got" display
+ $c->stash->{upload_fileid} = $report->get_photoset($c)->data;
+ } else {
# no point keeping it if it is done.
$token->delete;
}
diff --git a/t/app/controller/photo.t b/t/app/controller/photo.t
index 6e61ebb32..39380e769 100644
--- a/t/app/controller/photo.t
+++ b/t/app/controller/photo.t
@@ -64,6 +64,9 @@ subtest "Check multiple upload worked" => sub {
);
ok $mech->success, 'Made request with multiple photo upload';
$mech->base_is('http://localhost/report/new');
+ $mech->content_like(
+ qr[(<img align="right" src="/photo/1cdd4329ceee2234bd4e89cb33b42061a0724687.temp.jpeg" alt="">\s*){3}],
+ 'Three uploaded pictures are all shown, safe');
$mech->content_contains(
'name="upload_fileid" value="1cdd4329ceee2234bd4e89cb33b42061a0724687,1cdd4329ceee2234bd4e89cb33b42061a0724687,1cdd4329ceee2234bd4e89cb33b42061a0724687"',
'Returned upload_fileid contains expected hash, 3 times');
diff --git a/t/app/controller/report_import.t b/t/app/controller/report_import.t
index 4d0f6e5d1..1d6695996 100644
--- a/t/app/controller/report_import.t
+++ b/t/app/controller/report_import.t
@@ -153,7 +153,9 @@ subtest "Submit a correct entry" => sub {
name => 'Test User',
title => 'Test report',
detail => 'This is a test report',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
phone => '',
may_show_name => '1',
category => '-- Pick a category --',
@@ -187,7 +189,9 @@ subtest "Submit a correct entry" => sub {
name => 'Test User',
title => 'Test report',
detail => 'This is a test report',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
phone => '',
may_show_name => '1',
category => '-- Pick a category --',
@@ -275,7 +279,9 @@ subtest "Submit a correct entry (with location)" => sub {
name => 'Test User ll',
title => 'Test report ll',
detail => 'This is a test report ll',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
phone => '',
may_show_name => '1',
category => '-- Pick a category --',
diff --git a/t/app/controller/report_new.t b/t/app/controller/report_new.t
index 3c05adfbd..4258a46a1 100644
--- a/t/app/controller/report_new.t
+++ b/t/app/controller/report_new.t
@@ -103,7 +103,9 @@ foreach my $test (
fields => {
title => '',
detail => '',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => '',
may_show_name => '1',
email => '',
@@ -127,7 +129,9 @@ foreach my $test (
fields => {
title => '',
detail => '',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => '',
may_show_name => '1',
email => '',
@@ -154,7 +158,9 @@ foreach my $test (
fields => {
title => '',
detail => '',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => '',
may_show_name => '1',
email => '',
@@ -178,7 +184,9 @@ foreach my $test (
fields => {
title => '',
detail => '',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => '',
may_show_name => undef,
email => '',
@@ -202,7 +210,9 @@ foreach my $test (
fields => {
title => '',
detail => '',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => 'Bob Jones',
may_show_name => undef,
email => '',
@@ -225,7 +235,9 @@ foreach my $test (
fields => {
title => '',
detail => '',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => 'Bob Jones',
may_show_name => '1',
email => '',
@@ -248,7 +260,9 @@ foreach my $test (
fields => {
title => "DOG SHIT\r\nON WALLS",
detail => "on this portakabin -\r\n\r\nmore of a portaloo HEH!!",
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => 'Bob Jones',
may_show_name => '1',
email => '',
@@ -271,7 +285,9 @@ foreach my $test (
fields => {
title => 'Test title',
detail => 'Test detail',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => 'DUDE',
may_show_name => '1',
email => '',
@@ -293,7 +309,9 @@ foreach my $test (
fields => {
title => 'Test title',
detail => 'Test detail',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => 'anonymous',
may_show_name => '1',
email => '',
@@ -315,7 +333,9 @@ foreach my $test (
fields => {
title => 'Test title',
detail => 'Test detail',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => 'Joe Smith',
may_show_name => '1',
email => 'not an email',
@@ -334,7 +354,9 @@ foreach my $test (
fields => {
title => " Test title ",
detail => " first line \n\n second\nline\n\n ",
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => '',
may_show_name => '1',
email => '',
@@ -359,7 +381,9 @@ foreach my $test (
fields => {
title => '',
detail => '',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => ' Bob Jones ',
may_show_name => '1',
email => ' BOB @ExAmplE.COM ',
@@ -381,7 +405,9 @@ foreach my $test (
fields => {
title => 'Title',
detail => 'Detail',
- photo => [ [ undef, 'bad.txt', Content => 'This is not a JPEG', Content_Type => 'text/plain' ], 1 ],
+ photo1 => [ [ undef, 'bad.txt', Content => 'This is not a JPEG', Content_Type => 'text/plain' ], 1 ],
+ photo2 => '',
+ photo3 => '',
name => 'Bob Jones',
may_show_name => '1',
email => 'bob@example.com',
@@ -392,7 +418,7 @@ foreach my $test (
remember_me => undef,
},
changes => {
- photo => '',
+ photo1 => '',
},
errors => [ "Please upload a JPEG image only" ],
},
@@ -402,7 +428,9 @@ foreach my $test (
fields => {
title => 'Title',
detail => 'Detail',
- photo => [ [ undef, 'fake.jpeg', Content => 'This is not a JPEG', Content_Type => 'image/jpeg' ], 1 ],
+ photo1 => [ [ undef, 'fake.jpeg', Content => 'This is not a JPEG', Content_Type => 'image/jpeg' ], 1 ],
+ photo2 => '',
+ photo3 => '',
name => 'Bob Jones',
may_show_name => '1',
email => 'bob@example.com',
@@ -413,7 +441,7 @@ foreach my $test (
remember_me => undef,
},
changes => {
- photo => '',
+ photo1 => '',
},
errors => [ "That image doesn't appear to have uploaded correctly (Please upload a JPEG image only ), please try again." ],
},
@@ -423,7 +451,9 @@ foreach my $test (
fields => {
title => '',
detail => 'Detail',
- photo => [ [ $sample_file, undef, Content_Type => 'application/octet-stream' ], 1 ],
+ photo1 => [ [ $sample_file, undef, Content_Type => 'application/octet-stream' ], 1 ],
+ photo2 => '',
+ photo3 => '',
name => 'Bob Jones',
may_show_name => '1',
email => 'bob@example.com',
@@ -434,7 +464,7 @@ foreach my $test (
remember_me => undef,
},
changes => {
- photo => '',
+ photo1 => '',
},
errors => [ "Please enter a subject" ],
},
@@ -534,7 +564,7 @@ foreach my $test (
with_fields => {
title => 'Test Report',
detail => 'Test report details.',
- photo => '',
+ photo1 => '',
name => 'Joe Bloggs',
may_show_name => '1',
email => 'test-1@example.com',
@@ -652,7 +682,7 @@ subtest "test password errors for a user who is signing in as they report" => su
with_fields => {
title => 'Test Report',
detail => 'Test report details.',
- photo => '',
+ photo1 => '',
email => 'test-2@example.com',
password_sign_in => 'secret1',
category => 'Street lighting',
@@ -704,7 +734,7 @@ subtest "test report creation for a user who is signing in as they report" => su
with_fields => {
title => 'Test Report',
detail => 'Test report details.',
- photo => '',
+ photo1 => '',
email => 'test-2@example.com',
password_sign_in => 'secret2',
category => 'Street lighting',
@@ -803,7 +833,9 @@ foreach my $test (
may_show_name => '1',
name => 'Test User',
phone => '01234 567 890',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
category => '-- Pick a category --',
},
"user's details prefilled"
@@ -814,7 +846,7 @@ foreach my $test (
with_fields => {
title => "Test Report at café",
detail => 'Test report details.',
- photo => '',
+ photo1 => '',
name => 'Joe Bloggs',
may_show_name => '1',
phone => '07903 123 456',
@@ -898,7 +930,7 @@ subtest "test report creation for a category that is non public" => sub {
with_fields => {
title => 'Test Report',
detail => 'Test report details.',
- photo => '',
+ photo1 => '',
email => 'test-2@example.com',
name => 'Joe Bloggs',
category => 'Street lighting',
@@ -1087,7 +1119,7 @@ for my $test (
my $submission_fields = {
title => "Test Report",
detail => 'Test report details.',
- photo => '',
+ photo1 => '',
email => 'firstlast@example.com',
may_show_name => '1',
phone => '07903 123 456',
@@ -1156,7 +1188,7 @@ subtest 'user title not reset if no user title in submission' => sub {
my $submission_fields = {
title => "Test Report",
detail => 'Test report details.',
- photo => '',
+ photo1 => '',
name => 'Has Title',
may_show_name => '1',
phone => '07903 123 456',
@@ -1250,7 +1282,7 @@ subtest "test Hart" => sub {
with_fields => {
title => 'Test Report',
detail => 'Test report details.',
- photo => '',
+ photo1 => '',
name => 'Joe Bloggs',
may_show_name => '1',
category => $test->{category},
@@ -1484,7 +1516,7 @@ subtest "unresponsive body handling works" => sub {
with_fields => {
title => "Test Report at café",
detail => 'Test report details.',
- photo => '',
+ photo1 => '',
name => 'Joe Bloggs',
email => $test_email,
may_show_name => '1',
@@ -1523,7 +1555,7 @@ subtest "unresponsive body handling works" => sub {
with_fields => {
title => "Test Report at café",
detail => 'Test report details.',
- photo => '',
+ photo1 => '',
name => 'Joe Bloggs',
email => $test_email,
may_show_name => '1',
@@ -1604,7 +1636,7 @@ subtest "extra google analytics code displayed on logged in problem creation" =>
with_fields => {
title => "Test Report at café",
detail => 'Test report details.',
- photo => '',
+ photo1 => '',
name => 'Joe Bloggs',
may_show_name => '1',
phone => '07903 123 456',
@@ -1646,7 +1678,7 @@ subtest "extra google analytics code displayed on email confirmation problem cre
my $submission_fields = {
title => "Test Report",
detail => 'Test report details.',
- photo => '',
+ photo1 => '',
email => 'firstlast@example.com',
name => 'Test User',
may_show_name => '1',
diff --git a/t/app/controller/report_new_open311.t b/t/app/controller/report_new_open311.t
index d3ca93f0e..b29642abe 100644
--- a/t/app/controller/report_new_open311.t
+++ b/t/app/controller/report_new_open311.t
@@ -45,7 +45,9 @@ foreach my $test (
fields => {
title => '',
detail => '',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => '',
may_show_name => '1',
email => '',
diff --git a/templates/web/base/common_header_tags.html b/templates/web/base/common_header_tags.html
index 0ad3ffb5f..1faf542d8 100644
--- a/templates/web/base/common_header_tags.html
+++ b/templates/web/base/common_header_tags.html
@@ -8,6 +8,7 @@
<script type="text/javascript" src="[% start %]/jslib/jquery-1.7.2.min.js"></script>
<script src="[% start %][% version('/js/jquery.validate.min.js') %]" type="text/javascript" charset="utf-8"></script>
+<script type="text/javascript" src="[% start %]/js/dropzone.min.js"></script>
<script type="text/javascript" src="[% start %][% version('/js/geo.min.js') %]"></script>
<script type="text/javascript" src="[% start %][% version('/js/fixmystreet.js') %]"></script>
diff --git a/templates/web/base/js/translation_strings.html b/templates/web/base/js/translation_strings.html
index 669055a1b..b97104f92 100644
--- a/templates/web/base/js/translation_strings.html
+++ b/templates/web/base/js/translation_strings.html
@@ -47,5 +47,10 @@
permalink: '[% loc('Permalink') | replace("'", "\\'") %]',
+ upload_max_files_exceeded: '[% loc ('Whoa there Testino! Three photos are enough.') | replace("'", "\\'") %]',
+ upload_default_message: '[% loc ('Drag and drop photos here or <u>click to upload</u>') | replace("'", "\\'") %]',
+ upload_cancel_confirmation: '[% loc ('Are you sure you want to cancel this upload?') | replace("'", "\\'") %]',
+ upload_invalid_file_type: '[% loc ('Please upload a JPEG image only') | replace("'", "\\'") %]',
+
report_problem_heading: '[% loc('Click map to report a problem') | replace("'", "\\'") %]'
};
diff --git a/templates/web/base/report/new/fill_in_details_form.html b/templates/web/base/report/new/fill_in_details_form.html
index 82b1097b7..5599c2059 100644
--- a/templates/web/base/report/new/fill_in_details_form.html
+++ b/templates/web/base/report/new/fill_in_details_form.html
@@ -48,6 +48,32 @@
[% END %]
<input type="text" value="[% report.title | html %]" name="title" id="form_title" placeholder="[% loc('What’s the issue, and where is it?') %]" required>
+ [% IF c.cobrand.allow_photo_upload %]
+ <input type="hidden" name="upload_fileid" value="[% upload_fileid %]">
+ <label for="form_photo">[% loc('Photo') %]</label>
+
+ [% IF field_errors.photo %]
+ <p class='form-error'>[% field_errors.photo %]</p>
+ [% END %]
+
+ <div id="form_photos">
+ [% IF upload_fileid %]
+ <script>
+ fixmystreet.uploaded_files = "[% upload_fileid %]".split(',');
+ </script>
+ <p>[% loc('You have already attached photos to this report. Note that you can attach a maximum of 3 to this report (if you try to upload more, the oldest will be removed).') %]</p>
+ [% FOREACH id IN upload_fileid.split(',') %]
+ <img align="right" src="/photo/[% id %].temp.jpeg" alt="">
+ [% END %]
+ [% END %]
+ <input type="file" name="photo1" id="form_photo">
+ <input type="file" name="photo2" id="form_photo2">
+ <input type="file" name="photo3" id="form_photo3">
+ </div>
+ [% END %]
+
+ [% TRY %][% PROCESS 'report/new/after_photo.html' %][% CATCH file %][% END %]
+
<label for="form_detail">[% loc('Description') %] [% INCLUDE 'report/public_label.html' %]</label>
[% IF field_errors.detail %]
<p class='form-error'>[% field_errors.detail %]</p>
@@ -62,29 +88,6 @@
[% TRY %][% PROCESS 'report/new/after_category.html' %][% CATCH file %][% END %]
- [% IF c.cobrand.allow_photo_upload %]
- <label for="form_photo">[% loc('Photo') %]</label>
- [% IF upload_fileid || report.photo %]
- [% IF upload_fileid %]
- <img align="right" src="/photo/[% upload_fileid %].temp.jpeg" alt="">
- <input type="hidden" name="upload_fileid" value="[% upload_fileid %]">
- [% END %]
-
- <p>[% loc('You have already attached a photo to this report, attaching another one will replace it.') %]</p>
-
- [% IF report.photo %]
- <img align="right" src="/photo/[% report.id %].jpeg">
- [% END %]
- [% END %]
-
- [% IF field_errors.photo %]
- <p class='form-error'>[% field_errors.photo %]</p>
- [% END %]
- <input type="file" name="photo" id="form_photo">
- [% END %]
-
- [% TRY %][% PROCESS 'report/new/after_photo.html' %][% CATCH file %][% END %]
-
[% IF c.user_exists %]
[% PROCESS "report/new/form_user_loggedin.html" %]
[% ELSE %]
diff --git a/templates/web/bromley/report/new/fill_in_details_form.html b/templates/web/bromley/report/new/fill_in_details_form.html
index 6bf077322..09e695278 100644
--- a/templates/web/bromley/report/new/fill_in_details_form.html
+++ b/templates/web/bromley/report/new/fill_in_details_form.html
@@ -48,6 +48,32 @@
[% END %]
<input type="text" value="[% report.title | html %]" name="title" id="form_title" placeholder="[% loc('Provide a title') %]" required>
+ [% IF c.cobrand.allow_photo_upload %]
+ <input type="hidden" name="upload_fileid" value="[% upload_fileid %]">
+ <label for="form_photo">[% loc('Photo') %]</label>
+
+ [% IF field_errors.photo %]
+ <p class='form-error'>[% field_errors.photo %]</p>
+ [% END %]
+
+ <div id="form_photos">
+ [% IF upload_fileid %]
+ <script>
+ fixmystreet.uploaded_files = "[% upload_fileid %]".split(',');
+ </script>
+ <p>[% loc('You have already attached photos to this report. Note that you can attach a maximum of 3 to this report (if you try to upload more, the oldest will be removed).') %]</p>
+ [% FOREACH id IN upload_fileid.split(',') %]
+ <img align="right" src="/photo/[% id %].temp.jpeg" alt="">
+ [% END %]
+ [% END %]
+ <input type="file" name="photo1" id="form_photo">
+ <input type="file" name="photo2" id="form_photo2">
+ <input type="file" name="photo3" id="form_photo3">
+ </div>
+ [% END %]
+
+ [% TRY %][% PROCESS 'report/new/after_photo.html' %][% CATCH file %][% END %]
+
<label for="form_detail">[% loc('Details') %]</label>
[% IF report.used_map %]
<p>
@@ -62,29 +88,6 @@
[% PROCESS "report/new/category_wrapper.html" %]
- [% IF c.cobrand.allow_photo_upload %]
- [% IF field_errors.photo %]
- <p class='form-error'>[% field_errors.photo %]</p>
- [% END %]
-
-
- [% IF upload_fileid || report.photo %]
- [% IF upload_fileid %]
- <img align="right" src="/photo/[% upload_fileid %].temp.jpeg" alt="">
- <input type="hidden" name="upload_fileid" value="[% upload_fileid %]">
- [% END %]
-
- <p>[% loc('You have already attached a photo to this report, attaching another one will replace it.') %]</p>
-
- [% IF report.photo %]
- <img align="right" src="/photo/[% report.id %].jpeg">
- [% END %]
- [% END %]
-
- <label for="form_photo">[% loc('Photo') %]</label>
- <input type="file" name="photo" id="form_photo">
- [% END %]
-
[% IF c.user_exists %]
<div class="form-box">
[% INCLUDE 'report/new/extra_name.html' %]
diff --git a/templates/web/fixmystreet.com/report/new/after_photo.html b/templates/web/fixmystreet.com/report/new/after_photo.html
new file mode 100644
index 000000000..987f6d124
--- /dev/null
+++ b/templates/web/fixmystreet.com/report/new/after_photo.html
@@ -0,0 +1,10 @@
+<div class="description_tips">
+ <h4>Tips for perfect photos:</h4>
+ <ul class="do">
+ <li>Show what the problem is</li>
+ <li>Show where it’s located</li>
+ </ul>
+ <ul class="dont">
+ <li>Avoid personal information and vehicle number plates</li>
+ </ul>
+</div> \ No newline at end of file
diff --git a/templates/web/oxfordshire/report/new/after_photo.html b/templates/web/oxfordshire/report/new/after_photo.html
deleted file mode 100644
index bd8b7076f..000000000
--- a/templates/web/oxfordshire/report/new/after_photo.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<p><small>Please be aware that you can only attach one picture so ensure that
-you provide a picture that clearly shows the location not just the fault.
-</small></p>
diff --git a/templates/web/zurich/report/new/fill_in_details_form.html b/templates/web/zurich/report/new/fill_in_details_form.html
index c8c567786..7a487f902 100644
--- a/templates/web/zurich/report/new/fill_in_details_form.html
+++ b/templates/web/zurich/report/new/fill_in_details_form.html
@@ -39,39 +39,42 @@
<p class='form-error'>[% field_errors.bodies %]</p>
[% END %]
- <label for="form_detail">[% loc('Details') %]</label>
- [% IF field_errors.detail %]
- <p class='form-error'>[% field_errors.detail %]</p>
- [% END %]
- <textarea rows="7" cols="26" name="detail" id="form_detail" placeholder="[% loc('Please fill in details of the problem.') %]" required>[% report.detail | html %]</textarea>
-
- [% PROCESS "report/new/category_wrapper.html" %]
-
- [% IF c.cobrand.allow_photo_upload %]
+ [% IF c.cobrand.allow_photo_upload %]
+ <input type="hidden" name="upload_fileid" value="[% upload_fileid %]">
<label for="form_photo">
[% loc('Photo') %]
[% loc('(Defect &amp; location of defect)') %]
</label>
- [% IF upload_fileid || report.photo %]
- [% IF upload_fileid %]
- <img align="right" src="/photo/[% upload_fileid %].temp.jpeg" alt="">
- <input type="hidden" name="upload_fileid" value="[% upload_fileid %]">
- [% END %]
- <p>[% loc('You have already attached photos to this report. Note that you can attach a maximum of 3 to this report (if you try to upload more, the oldest will be removed).') %]</p>
-
- [% IF report.photo %]
- <img align="right" src="/photo/[% report.id %].jpeg">
- [% END %]
- [% END %]
-
- [% IF field_errors.photo %]
- <p class='form-error'>[% field_errors.photo %]</p>
+ [% IF field_errors.photo %]
+ <p class='form-error'>[% field_errors.photo %]</p>
+ [% END %]
+
+ <div id="form_photos">
+ [% IF upload_fileid %]
+ <script>
+ fixmystreet.uploaded_files = "[% upload_fileid %]".split(',');
+ </script>
+ <p>[% loc('You have already attached photos to this report. Note that you can attach a maximum of 3 to this report (if you try to upload more, the oldest will be removed).') %]</p>
+ [% FOREACH id IN upload_fileid.split(',') %]
+ <img align="right" src="/photo/[% id %].temp.jpeg" alt="">
[% END %]
+ [% END %]
<input type="file" name="photo1" id="form_photo">
<input type="file" name="photo2" id="form_photo2">
<input type="file" name="photo3" id="form_photo3">
+ </div>
+ [% END %]
+
+ [% TRY %][% PROCESS 'report/new/after_photo.html' %][% CATCH file %][% END %]
+
+ <label for="form_detail">[% loc('Details') %]</label>
+ [% IF field_errors.detail %]
+ <p class='form-error'>[% field_errors.detail %]</p>
[% END %]
+ <textarea rows="7" cols="26" name="detail" id="form_detail" placeholder="[% loc('Please fill in details of the problem.') %]" required>[% report.detail | html %]</textarea>
+
+ [% PROCESS "report/new/category_wrapper.html" %]
<label for="form_email">[% loc('Your email') %]</label>
[% IF field_errors.email %]
diff --git a/web/cobrands/fixmystreet/fixmystreet.js b/web/cobrands/fixmystreet/fixmystreet.js
index 122488646..492f8b194 100644
--- a/web/cobrands/fixmystreet/fixmystreet.js
+++ b/web/cobrands/fixmystreet/fixmystreet.js
@@ -180,6 +180,81 @@ $(function(){
//move 'skip this step' link on mobile
$('.mobile #skip-this-step').addClass('chevron').wrap('<li>').parent().appendTo('#key-tools');
+ // Set up the Dropzone image uploader
+ if('Dropzone' in window){
+ Dropzone.autoDiscover = false;
+ }
+ if('Dropzone' in window && $('#form_photo').length){
+ var $originalLabel = $('[for="form_photo"]');
+ var $originalInput = $('#form_photos');
+ var $dropzone = $('<div>').addClass('dropzone');
+
+ $originalLabel.removeAttr('for');
+ $originalInput.hide();
+
+ $dropzone.insertAfter($originalInput);
+ var photodrop = new Dropzone($dropzone[0], {
+ url: '/photo/upload',
+ paramName: 'photo',
+ maxFiles: 3,
+ addRemoveLinks: true,
+ thumbnailHeight: 150,
+ thumbnailWidth: 150,
+ acceptedFiles: 'image/jpeg,image/pjpeg',
+ dictDefaultMessage: translation_strings.upload_default_message,
+ dictCancelUploadConfirmation: translation_strings.upload_cancel_confirmation,
+ dictInvalidFileType: translation_strings.upload_invalid_file_type,
+ dictMaxFilesExceeded: translation_strings.upload_max_files_exceeded,
+
+ fallback: function(){
+ $dropzone.remove();
+ $originalLabel.attr('for', 'form_photo');
+ $originalInput.show();
+ },
+ init: function(){
+ this.on("addedfile", function(file){
+ $('input[type=submit]').prop("disabled", true).removeClass('green-btn');
+ });
+ this.on("queuecomplete", function(){
+ $('input[type=submit]').removeAttr('disabled').addClass('green-btn');
+ });
+ this.on("success", function(file, xhrResponse) {
+ var ids = $('input[name=upload_fileid]').val().split(','),
+ id = (file.server_id = xhrResponse.id),
+ l = ids.push(id),
+ newstr = ids.join(',');
+ $('input[name=upload_fileid]').val(newstr);
+ });
+ this.on("error", function(file, errorMessage, xhrResponse){
+ });
+ this.on("removedfile", function(file){
+ var ids = $('input[name=upload_fileid]').val().split(','),
+ newstr = $.grep(ids, function(n){ return (n!=file.server_id); }).join(',');
+ $('input[name=upload_fileid]').val(newstr);
+ });
+ this.on("maxfilesexceeded", function(file){
+ this.removeFile(file);
+ var $message = $('<div class="dz-message dz-error-message">');
+ $message.text(translation_strings.upload_max_files_exceeded);
+ $message.prependTo(this.element);
+ setTimeout(function(){
+ $message.slideUp(250, function(){
+ $message.remove();
+ });
+ }, 2000);
+ });
+ }
+ });
+
+ $.each(fixmystreet.uploaded_files || [], function(i, f) {
+ var mockFile = { name: f, server_id: f };
+ photodrop.emit("addedfile", mockFile);
+ photodrop.createThumbnailFromUrl(mockFile, '/photo/' + f + '.temp.jpeg');
+ photodrop.emit("complete", mockFile);
+ photodrop.options.maxFiles -= 1;
+ });
+ }
+
/*
* Tabs
*/
diff --git a/web/cobrands/fixmystreet/images/cross-14px.png b/web/cobrands/fixmystreet/images/cross-14px.png
new file mode 100644
index 000000000..ead0b6913
--- /dev/null
+++ b/web/cobrands/fixmystreet/images/cross-14px.png
Binary files differ
diff --git a/web/cobrands/fixmystreet/images/cross-14px.svg b/web/cobrands/fixmystreet/images/cross-14px.svg
new file mode 100644
index 000000000..20c45ead2
--- /dev/null
+++ b/web/cobrands/fixmystreet/images/cross-14px.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg">
+ <g transform="translate(-5.000000, -5.000000)" fill="#FFFFFF">
+ <path d="M12.0007202,14.6137463 L16.3848133,19 L18.9985595,16.3862537 L14.6151867,12.0014405 L19,7.61590699 L16.3848133,5 L11.9992798,9.38553349 L7.61446651,5 L5.00072024,7.61374627 L9.38553349,11.9992798 L5,16.3848133 L7.61518675,19 L12.0007202,14.6137463 Z"></path>
+ </g>
+</svg> \ No newline at end of file
diff --git a/web/cobrands/fixmystreet/images/spinner-grey-eee.gif b/web/cobrands/fixmystreet/images/spinner-grey-eee.gif
new file mode 100644
index 000000000..a0bf05ae9
--- /dev/null
+++ b/web/cobrands/fixmystreet/images/spinner-grey-eee.gif
Binary files differ
diff --git a/web/cobrands/fixmystreet/images/spinner-grey-eee.svg b/web/cobrands/fixmystreet/images/spinner-grey-eee.svg
new file mode 100644
index 000000000..cfb63a489
--- /dev/null
+++ b/web/cobrands/fixmystreet/images/spinner-grey-eee.svg
@@ -0,0 +1 @@
+<svg width='100px' height='100px' xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" class="uil-default"><rect x="0" y="0" width="100" height="100" fill="none" class="bk"></rect><rect x='48' y='42.5' width='4' height='15' rx='2' ry='2' fill='#999999' transform='rotate(0 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0s' repeatCount='indefinite'/></rect><rect x='48' y='42.5' width='4' height='15' rx='2' ry='2' fill='#999999' transform='rotate(30 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.08333333333333333s' repeatCount='indefinite'/></rect><rect x='48' y='42.5' width='4' height='15' rx='2' ry='2' fill='#999999' transform='rotate(60 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.16666666666666666s' repeatCount='indefinite'/></rect><rect x='48' y='42.5' width='4' height='15' rx='2' ry='2' fill='#999999' transform='rotate(90 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.25s' repeatCount='indefinite'/></rect><rect x='48' y='42.5' width='4' height='15' rx='2' ry='2' fill='#999999' transform='rotate(120 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.3333333333333333s' repeatCount='indefinite'/></rect><rect x='48' y='42.5' width='4' height='15' rx='2' ry='2' fill='#999999' transform='rotate(150 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.4166666666666667s' repeatCount='indefinite'/></rect><rect x='48' y='42.5' width='4' height='15' rx='2' ry='2' fill='#999999' transform='rotate(180 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.5s' repeatCount='indefinite'/></rect><rect x='48' y='42.5' width='4' height='15' rx='2' ry='2' fill='#999999' transform='rotate(210 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.5833333333333334s' repeatCount='indefinite'/></rect><rect x='48' y='42.5' width='4' height='15' rx='2' ry='2' fill='#999999' transform='rotate(240 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.6666666666666666s' repeatCount='indefinite'/></rect><rect x='48' y='42.5' width='4' height='15' rx='2' ry='2' fill='#999999' transform='rotate(270 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.75s' repeatCount='indefinite'/></rect><rect x='48' y='42.5' width='4' height='15' rx='2' ry='2' fill='#999999' transform='rotate(300 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.8333333333333334s' repeatCount='indefinite'/></rect><rect x='48' y='42.5' width='4' height='15' rx='2' ry='2' fill='#999999' transform='rotate(330 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.9166666666666666s' repeatCount='indefinite'/></rect></svg> \ No newline at end of file
diff --git a/web/cobrands/sass/_base.scss b/web/cobrands/sass/_base.scss
index 0788a99ed..621eabd11 100644
--- a/web/cobrands/sass/_base.scss
+++ b/web/cobrands/sass/_base.scss
@@ -1755,3 +1755,4 @@ table.nicetable {
@import "_admin";
@import "_fixedthead";
+@import "_dropzone";
diff --git a/web/cobrands/sass/_dropzone.scss b/web/cobrands/sass/_dropzone.scss
new file mode 100644
index 000000000..90e53584d
--- /dev/null
+++ b/web/cobrands/sass/_dropzone.scss
@@ -0,0 +1,198 @@
+$dropzone-link-color: #0BA7D1; // match default `a` styling
+$dropzone-link-color--awakened: #0D7CCE; // match default `a:hover` styling
+$dropzone-border-color: #888; // match default form inputs
+$dropzone-border-color--awakened: $dropzone-link-color--awakened;
+$dropzone-border-color--full: #bf002a;
+$dropzone-border-radius: 0.25em; // match default form inputs
+$dropzone-background-color: #fff;
+$dropzone-background-color--awakened: mix($dropzone-link-color, $dropzone-background-color, 10%);
+$dropzone-background-color--full: mix($dropzone-border-color--full, $dropzone-background-color, 10%);
+
+.dropzone {
+ @include clearfix();
+ border: 0.125em solid $dropzone-border-color;
+ background-color: $dropzone-background-color;
+ border-radius: $dropzone-border-radius;
+ padding: 1.5em;
+ text-align: center;
+}
+
+.dz-clickable {
+ cursor: pointer;
+
+ * {
+ cursor: auto;
+ }
+
+ .dz-message,
+ .dz-message *,
+ .dz-remove,
+ .dz-cancel {
+ cursor: pointer;
+ }
+
+ .dz-message u {
+ color: $dropzone-link-color;
+ }
+}
+
+.dz-clickable:hover,
+.dz-drag-hover {
+ border-color: $dropzone-link-color--awakened;
+ background-color: $dropzone-background-color--awakened;
+
+ .dz-remove,
+ .dz-cancel {
+ border-color: $dropzone-background-color--awakened;
+ }
+
+ .dz-message u {
+ color: $dropzone-link-color--awakened;
+ }
+}
+
+.dz-max-files-reached {
+ cursor: auto;
+
+ &:hover {
+ border-color: $dropzone-border-color;
+ background-color: $dropzone-background-color;
+
+ .dz-remove,
+ .dz-cancel {
+ border-color: $dropzone-background-color;
+ }
+ }
+
+ &.dz-drag-hover {
+ border-color: $dropzone-border-color--full;
+ background-color: $dropzone-background-color--full;
+
+ .dz-remove,
+ .dz-cancel {
+ border-color: $dropzone-background-color--full;
+ }
+ }
+
+ .dz-message.dz-default {
+ display: none;
+ }
+
+ .dz-preview {
+ margin-top: 0;
+ }
+}
+
+.dz-message {
+ margin-bottom: 1.5em;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+}
+
+.dz-preview {
+ position: relative;
+ float: left;
+ width: 30%;
+ height: 0;
+ padding-bottom: 30%; // makes a square element
+ margin-right: 5%;
+
+ &:last-child {
+ margin-right: 0;
+ }
+}
+
+.dz-image {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+
+ border-radius: $dropzone-border-radius;
+ overflow: hidden; // crop child image to border radius, even before img src has loaded
+
+ img {
+ width: 100%;
+ height: 100%;
+ }
+}
+
+.dz-progress {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+
+ // http://loading.io/loader/?use=eyJzaXplIjo1MCwic3BlZWQiOjEsImNiayI6IiNlZWVlZWUiLCJjMSI6IiM5OTk5OTkiLCJjMiI6IjEyIiwiYzMiOiI0IiwiYzQiOiIxNSIsImM1IjoiMiIsImM2IjoiMjAiLCJ0eXBlIjoiZGVmYXVsdCJ9
+ background: #eee url(/cobrands/fixmystreet/images/spinner-grey-eee.gif) no-repeat center center;
+ background-image: url(/cobrands/fixmystreet/images/spinner-grey-eee.svg), none;
+ background-size: 100px;
+ border-radius: 0.3em;
+
+ .dz-complete & {
+ display: none;
+ }
+
+ .dz-upload {
+ background: rgba(0,0,0,0.2);
+ border-radius: $dropzone-border-radius;
+ height: 100%;
+ width: 0;
+ display: block;
+ }
+}
+
+.dz-error-message {
+ color: #881111;
+}
+
+.dz-remove,
+.dz-cancel {
+ display: block;
+ width: 1.5em;
+ height: 0;
+
+ padding-top: 1.5em;
+ overflow: hidden;
+
+ position: absolute;
+ top: -0.5em;
+ right: -0.5em;
+
+ border: 4px solid #fff;
+ border-radius: 100%;
+ background: #888 url(/cobrands/fixmystreet/images/cross-14px.png) no-repeat center center;
+ background-image: url(/cobrands/fixmystreet/images/cross-14px.svg), none;
+ background-size: 14px;
+
+ &:hover,
+ &:focus {
+ background-color: red;
+ }
+}
+
+// Deviously use pseudo-elements to preload a few images so they appear as soon as a file is picked
+.dz-message {
+ &:before {
+ content: "";
+ position: absolute;
+ background: transparent url(/cobrands/fixmystreet/images/spinner-grey-eee.gif) no-repeat 0 0;
+ background-image: url(/cobrands/fixmystreet/images/spinner-grey-eee.svg), none;
+ }
+
+ &:after {
+ content: "";
+ position: absolute;
+ background: transparent url(/cobrands/fixmystreet/images/cross-14px.png) no-repeat 0 0;
+ background-image: url(/cobrands/fixmystreet/images/cross-14px.svg), none;
+ }
+}
+
+// Don't really need these
+.dz-details, .dz-success-mark, .dz-error-mark {
+ display: none;
+}
diff --git a/web/js/dropzone.min.js b/web/js/dropzone.min.js
new file mode 100755
index 000000000..08cd734ce
--- /dev/null
+++ b/web/js/dropzone.min.js
@@ -0,0 +1,2 @@
+(function(){var a,b,c,d,e,f,g,h,i=[].slice,j={}.hasOwnProperty,k=function(a,b){function c(){this.constructor=a}for(var d in b)j.call(b,d)&&(a[d]=b[d]);return c.prototype=b.prototype,a.prototype=new c,a.__super__=b.prototype,a};g=function(){},b=function(){function a(){}return a.prototype.addEventListener=a.prototype.on,a.prototype.on=function(a,b){return this._callbacks=this._callbacks||{},this._callbacks[a]||(this._callbacks[a]=[]),this._callbacks[a].push(b),this},a.prototype.emit=function(){var a,b,c,d,e,f;if(d=arguments[0],a=2<=arguments.length?i.call(arguments,1):[],this._callbacks=this._callbacks||{},c=this._callbacks[d])for(e=0,f=c.length;f>e;e++)b=c[e],b.apply(this,a);return this},a.prototype.removeListener=a.prototype.off,a.prototype.removeAllListeners=a.prototype.off,a.prototype.removeEventListener=a.prototype.off,a.prototype.off=function(a,b){var c,d,e,f,g;if(!this._callbacks||0===arguments.length)return this._callbacks={},this;if(d=this._callbacks[a],!d)return this;if(1===arguments.length)return delete this._callbacks[a],this;for(e=f=0,g=d.length;g>f;e=++f)if(c=d[e],c===b){d.splice(e,1);break}return this},a}(),a=function(a){function c(a,b){var e,f,g;if(this.element=a,this.version=c.version,this.defaultOptions.previewTemplate=this.defaultOptions.previewTemplate.replace(/\n*/g,""),this.clickableElements=[],this.listeners=[],this.files=[],"string"==typeof this.element&&(this.element=document.querySelector(this.element)),!this.element||null==this.element.nodeType)throw new Error("Invalid dropzone element.");if(this.element.dropzone)throw new Error("Dropzone already attached.");if(c.instances.push(this),this.element.dropzone=this,e=null!=(g=c.optionsForElement(this.element))?g:{},this.options=d({},this.defaultOptions,e,null!=b?b:{}),this.options.forceFallback||!c.isBrowserSupported())return this.options.fallback.call(this);if(null==this.options.url&&(this.options.url=this.element.getAttribute("action")),!this.options.url)throw new Error("No URL provided.");if(this.options.acceptedFiles&&this.options.acceptedMimeTypes)throw new Error("You can't provide both 'acceptedFiles' and 'acceptedMimeTypes'. 'acceptedMimeTypes' is deprecated.");this.options.acceptedMimeTypes&&(this.options.acceptedFiles=this.options.acceptedMimeTypes,delete this.options.acceptedMimeTypes),this.options.method=this.options.method.toUpperCase(),(f=this.getExistingFallback())&&f.parentNode&&f.parentNode.removeChild(f),this.options.previewsContainer!==!1&&(this.previewsContainer=this.options.previewsContainer?c.getElement(this.options.previewsContainer,"previewsContainer"):this.element),this.options.clickable&&(this.clickableElements=this.options.clickable===!0?[this.element]:c.getElements(this.options.clickable,"clickable")),this.init()}var d,e;return k(c,a),c.prototype.Emitter=b,c.prototype.events=["drop","dragstart","dragend","dragenter","dragover","dragleave","addedfile","addedfiles","removedfile","thumbnail","error","errormultiple","processing","processingmultiple","uploadprogress","totaluploadprogress","sending","sendingmultiple","success","successmultiple","canceled","canceledmultiple","complete","completemultiple","reset","maxfilesexceeded","maxfilesreached","queuecomplete"],c.prototype.defaultOptions={url:null,method:"post",withCredentials:!1,parallelUploads:2,uploadMultiple:!1,maxFilesize:256,paramName:"file",createImageThumbnails:!0,maxThumbnailFilesize:10,thumbnailWidth:120,thumbnailHeight:120,filesizeBase:1e3,maxFiles:null,params:{},clickable:!0,ignoreHiddenFiles:!0,acceptedFiles:null,acceptedMimeTypes:null,autoProcessQueue:!0,autoQueue:!0,addRemoveLinks:!1,previewsContainer:null,hiddenInputContainer:"body",capture:null,dictDefaultMessage:"Drop files here to upload",dictFallbackMessage:"Your browser does not support drag'n'drop file uploads.",dictFallbackText:"Please use the fallback form below to upload your files like in the olden days.",dictFileTooBig:"File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.",dictInvalidFileType:"You can't upload files of this type.",dictResponseError:"Server responded with {{statusCode}} code.",dictCancelUpload:"Cancel upload",dictCancelUploadConfirmation:"Are you sure you want to cancel this upload?",dictRemoveFile:"Remove file",dictRemoveFileConfirmation:null,dictMaxFilesExceeded:"You can not upload any more files.",accept:function(a,b){return b()},init:function(){return g},forceFallback:!1,fallback:function(){var a,b,d,e,f,g;for(this.element.className=""+this.element.className+" dz-browser-not-supported",g=this.element.getElementsByTagName("div"),e=0,f=g.length;f>e;e++)a=g[e],/(^| )dz-message($| )/.test(a.className)&&(b=a,a.className="dz-message");return b||(b=c.createElement('<div class="dz-message"><span></span></div>'),this.element.appendChild(b)),d=b.getElementsByTagName("span")[0],d&&(null!=d.textContent?d.textContent=this.options.dictFallbackMessage:null!=d.innerText&&(d.innerText=this.options.dictFallbackMessage)),this.element.appendChild(this.getFallbackForm())},resize:function(a){var b,c,d;return b={srcX:0,srcY:0,srcWidth:a.width,srcHeight:a.height},c=a.width/a.height,b.optWidth=this.options.thumbnailWidth,b.optHeight=this.options.thumbnailHeight,null==b.optWidth&&null==b.optHeight?(b.optWidth=b.srcWidth,b.optHeight=b.srcHeight):null==b.optWidth?b.optWidth=c*b.optHeight:null==b.optHeight&&(b.optHeight=1/c*b.optWidth),d=b.optWidth/b.optHeight,a.height<b.optHeight||a.width<b.optWidth?(b.trgHeight=b.srcHeight,b.trgWidth=b.srcWidth):c>d?(b.srcHeight=a.height,b.srcWidth=b.srcHeight*d):(b.srcWidth=a.width,b.srcHeight=b.srcWidth/d),b.srcX=(a.width-b.srcWidth)/2,b.srcY=(a.height-b.srcHeight)/2,b},drop:function(){return this.element.classList.remove("dz-drag-hover")},dragstart:g,dragend:function(){return this.element.classList.remove("dz-drag-hover")},dragenter:function(){return this.element.classList.add("dz-drag-hover")},dragover:function(){return this.element.classList.add("dz-drag-hover")},dragleave:function(){return this.element.classList.remove("dz-drag-hover")},paste:g,reset:function(){return this.element.classList.remove("dz-started")},addedfile:function(a){var b,d,e,f,g,h,i,j,k,l,m,n,o;if(this.element===this.previewsContainer&&this.element.classList.add("dz-started"),this.previewsContainer){for(a.previewElement=c.createElement(this.options.previewTemplate.trim()),a.previewTemplate=a.previewElement,this.previewsContainer.appendChild(a.previewElement),l=a.previewElement.querySelectorAll("[data-dz-name]"),f=0,i=l.length;i>f;f++)b=l[f],b.textContent=a.name;for(m=a.previewElement.querySelectorAll("[data-dz-size]"),g=0,j=m.length;j>g;g++)b=m[g],b.innerHTML=this.filesize(a.size);for(this.options.addRemoveLinks&&(a._removeLink=c.createElement('<a class="dz-remove" href="javascript:undefined;" data-dz-remove>'+this.options.dictRemoveFile+"</a>"),a.previewElement.appendChild(a._removeLink)),d=function(b){return function(d){return d.preventDefault(),d.stopPropagation(),a.status===c.UPLOADING?c.confirm(b.options.dictCancelUploadConfirmation,function(){return b.removeFile(a)}):b.options.dictRemoveFileConfirmation?c.confirm(b.options.dictRemoveFileConfirmation,function(){return b.removeFile(a)}):b.removeFile(a)}}(this),n=a.previewElement.querySelectorAll("[data-dz-remove]"),o=[],h=0,k=n.length;k>h;h++)e=n[h],o.push(e.addEventListener("click",d));return o}},removedfile:function(a){var b;return a.previewElement&&null!=(b=a.previewElement)&&b.parentNode.removeChild(a.previewElement),this._updateMaxFilesReachedClass()},thumbnail:function(a,b){var c,d,e,f;if(a.previewElement){for(a.previewElement.classList.remove("dz-file-preview"),f=a.previewElement.querySelectorAll("[data-dz-thumbnail]"),d=0,e=f.length;e>d;d++)c=f[d],c.alt=a.name,c.src=b;return setTimeout(function(){return function(){return a.previewElement.classList.add("dz-image-preview")}}(this),1)}},error:function(a,b){var c,d,e,f,g;if(a.previewElement){for(a.previewElement.classList.add("dz-error"),"String"!=typeof b&&b.error&&(b=b.error),f=a.previewElement.querySelectorAll("[data-dz-errormessage]"),g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push(c.textContent=b);return g}},errormultiple:g,processing:function(a){return a.previewElement&&(a.previewElement.classList.add("dz-processing"),a._removeLink)?a._removeLink.textContent=this.options.dictCancelUpload:void 0},processingmultiple:g,uploadprogress:function(a,b){var c,d,e,f,g;if(a.previewElement){for(f=a.previewElement.querySelectorAll("[data-dz-uploadprogress]"),g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push("PROGRESS"===c.nodeName?c.value=b:c.style.width=""+b+"%");return g}},totaluploadprogress:g,sending:g,sendingmultiple:g,success:function(a){return a.previewElement?a.previewElement.classList.add("dz-success"):void 0},successmultiple:g,canceled:function(a){return this.emit("error",a,"Upload canceled.")},canceledmultiple:g,complete:function(a){return a._removeLink&&(a._removeLink.textContent=this.options.dictRemoveFile),a.previewElement?a.previewElement.classList.add("dz-complete"):void 0},completemultiple:g,maxfilesexceeded:g,maxfilesreached:g,queuecomplete:g,addedfiles:g,previewTemplate:'<div class="dz-preview dz-file-preview">\n <div class="dz-image"><img data-dz-thumbnail /></div>\n <div class="dz-details">\n <div class="dz-size"><span data-dz-size></span></div>\n <div class="dz-filename"><span data-dz-name></span></div>\n </div>\n <div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>\n <div class="dz-error-message"><span data-dz-errormessage></span></div>\n <div class="dz-success-mark">\n <svg width="54px" height="54px" viewBox="0 0 54 54" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">\n <title>Check</title>\n <defs></defs>\n <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">\n <path d="M23.5,31.8431458 L17.5852419,25.9283877 C16.0248253,24.3679711 13.4910294,24.366835 11.9289322,25.9289322 C10.3700136,27.4878508 10.3665912,30.0234455 11.9283877,31.5852419 L20.4147581,40.0716123 C20.5133999,40.1702541 20.6159315,40.2626649 20.7218615,40.3488435 C22.2835669,41.8725651 24.794234,41.8626202 26.3461564,40.3106978 L43.3106978,23.3461564 C44.8771021,21.7797521 44.8758057,19.2483887 43.3137085,17.6862915 C41.7547899,16.1273729 39.2176035,16.1255422 37.6538436,17.6893022 L23.5,31.8431458 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z" id="Oval-2" stroke-opacity="0.198794158" stroke="#747474" fill-opacity="0.816519475" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>\n </g>\n </svg>\n </div>\n <div class="dz-error-mark">\n <svg width="54px" height="54px" viewBox="0 0 54 54" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">\n <title>Error</title>\n <defs></defs>\n <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">\n <g id="Check-+-Oval-2" sketch:type="MSLayerGroup" stroke="#747474" stroke-opacity="0.198794158" fill="#FFFFFF" fill-opacity="0.816519475">\n <path d="M32.6568542,29 L38.3106978,23.3461564 C39.8771021,21.7797521 39.8758057,19.2483887 38.3137085,17.6862915 C36.7547899,16.1273729 34.2176035,16.1255422 32.6538436,17.6893022 L27,23.3431458 L21.3461564,17.6893022 C19.7823965,16.1255422 17.2452101,16.1273729 15.6862915,17.6862915 C14.1241943,19.2483887 14.1228979,21.7797521 15.6893022,23.3461564 L21.3431458,29 L15.6893022,34.6538436 C14.1228979,36.2202479 14.1241943,38.7516113 15.6862915,40.3137085 C17.2452101,41.8726271 19.7823965,41.8744578 21.3461564,40.3106978 L27,34.6568542 L32.6538436,40.3106978 C34.2176035,41.8744578 36.7547899,41.8726271 38.3137085,40.3137085 C39.8758057,38.7516113 39.8771021,36.2202479 38.3106978,34.6538436 L32.6568542,29 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z" id="Oval-2" sketch:type="MSShapeGroup"></path>\n </g>\n </g>\n </svg>\n </div>\n</div>'},d=function(){var a,b,c,d,e,f,g;for(d=arguments[0],c=2<=arguments.length?i.call(arguments,1):[],f=0,g=c.length;g>f;f++){b=c[f];for(a in b)e=b[a],d[a]=e}return d},c.prototype.getAcceptedFiles=function(){var a,b,c,d,e;for(d=this.files,e=[],b=0,c=d.length;c>b;b++)a=d[b],a.accepted&&e.push(a);return e},c.prototype.getRejectedFiles=function(){var a,b,c,d,e;for(d=this.files,e=[],b=0,c=d.length;c>b;b++)a=d[b],a.accepted||e.push(a);return e},c.prototype.getFilesWithStatus=function(a){var b,c,d,e,f;for(e=this.files,f=[],c=0,d=e.length;d>c;c++)b=e[c],b.status===a&&f.push(b);return f},c.prototype.getQueuedFiles=function(){return this.getFilesWithStatus(c.QUEUED)},c.prototype.getUploadingFiles=function(){return this.getFilesWithStatus(c.UPLOADING)},c.prototype.getAddedFiles=function(){return this.getFilesWithStatus(c.ADDED)},c.prototype.getActiveFiles=function(){var a,b,d,e,f;for(e=this.files,f=[],b=0,d=e.length;d>b;b++)a=e[b],(a.status===c.UPLOADING||a.status===c.QUEUED)&&f.push(a);return f},c.prototype.init=function(){var a,b,d,e,f,g,h;for("form"===this.element.tagName&&this.element.setAttribute("enctype","multipart/form-data"),this.element.classList.contains("dropzone")&&!this.element.querySelector(".dz-message")&&this.element.appendChild(c.createElement('<div class="dz-default dz-message"><span>'+this.options.dictDefaultMessage+"</span></div>")),this.clickableElements.length&&(d=function(a){return function(){return a.hiddenFileInput&&a.hiddenFileInput.parentNode.removeChild(a.hiddenFileInput),a.hiddenFileInput=document.createElement("input"),a.hiddenFileInput.setAttribute("type","file"),(null==a.options.maxFiles||a.options.maxFiles>1)&&a.hiddenFileInput.setAttribute("multiple","multiple"),a.hiddenFileInput.className="dz-hidden-input",null!=a.options.acceptedFiles&&a.hiddenFileInput.setAttribute("accept",a.options.acceptedFiles),null!=a.options.capture&&a.hiddenFileInput.setAttribute("capture",a.options.capture),a.hiddenFileInput.style.visibility="hidden",a.hiddenFileInput.style.position="absolute",a.hiddenFileInput.style.top="0",a.hiddenFileInput.style.left="0",a.hiddenFileInput.style.height="0",a.hiddenFileInput.style.width="0",document.querySelector(a.options.hiddenInputContainer).appendChild(a.hiddenFileInput),a.hiddenFileInput.addEventListener("change",function(){var b,c,e,f;if(c=a.hiddenFileInput.files,c.length)for(e=0,f=c.length;f>e;e++)b=c[e],a.addFile(b);return a.emit("addedfiles",c),d()})}}(this))(),this.URL=null!=(g=window.URL)?g:window.webkitURL,h=this.events,e=0,f=h.length;f>e;e++)a=h[e],this.on(a,this.options[a]);return this.on("uploadprogress",function(a){return function(){return a.updateTotalUploadProgress()}}(this)),this.on("removedfile",function(a){return function(){return a.updateTotalUploadProgress()}}(this)),this.on("canceled",function(a){return function(b){return a.emit("complete",b)}}(this)),this.on("complete",function(a){return function(){return 0===a.getAddedFiles().length&&0===a.getUploadingFiles().length&&0===a.getQueuedFiles().length?setTimeout(function(){return a.emit("queuecomplete")},0):void 0}}(this)),b=function(a){return a.stopPropagation(),a.preventDefault?a.preventDefault():a.returnValue=!1},this.listeners=[{element:this.element,events:{dragstart:function(a){return function(b){return a.emit("dragstart",b)}}(this),dragenter:function(a){return function(c){return b(c),a.emit("dragenter",c)}}(this),dragover:function(a){return function(c){var d;try{d=c.dataTransfer.effectAllowed}catch(e){}return c.dataTransfer.dropEffect="move"===d||"linkMove"===d?"move":"copy",b(c),a.emit("dragover",c)}}(this),dragleave:function(a){return function(b){return a.emit("dragleave",b)}}(this),drop:function(a){return function(c){return b(c),a.drop(c)}}(this),dragend:function(a){return function(b){return a.emit("dragend",b)}}(this)}}],this.clickableElements.forEach(function(a){return function(b){return a.listeners.push({element:b,events:{click:function(d){return(b!==a.element||d.target===a.element||c.elementInside(d.target,a.element.querySelector(".dz-message")))&&a.hiddenFileInput.click(),!0}}})}}(this)),this.enable(),this.options.init.call(this)},c.prototype.destroy=function(){var a;return this.disable(),this.removeAllFiles(!0),(null!=(a=this.hiddenFileInput)?a.parentNode:void 0)&&(this.hiddenFileInput.parentNode.removeChild(this.hiddenFileInput),this.hiddenFileInput=null),delete this.element.dropzone,c.instances.splice(c.instances.indexOf(this),1)},c.prototype.updateTotalUploadProgress=function(){var a,b,c,d,e,f,g,h;if(d=0,c=0,a=this.getActiveFiles(),a.length){for(h=this.getActiveFiles(),f=0,g=h.length;g>f;f++)b=h[f],d+=b.upload.bytesSent,c+=b.upload.total;e=100*d/c}else e=100;return this.emit("totaluploadprogress",e,c,d)},c.prototype._getParamName=function(a){return"function"==typeof this.options.paramName?this.options.paramName(a):""+this.options.paramName+(this.options.uploadMultiple?"["+a+"]":"")},c.prototype.getFallbackForm=function(){var a,b,d,e;return(a=this.getExistingFallback())?a:(d='<div class="dz-fallback">',this.options.dictFallbackText&&(d+="<p>"+this.options.dictFallbackText+"</p>"),d+='<input type="file" name="'+this._getParamName(0)+'" '+(this.options.uploadMultiple?'multiple="multiple"':void 0)+' /><input type="submit" value="Upload!"></div>',b=c.createElement(d),"FORM"!==this.element.tagName?(e=c.createElement('<form action="'+this.options.url+'" enctype="multipart/form-data" method="'+this.options.method+'"></form>'),e.appendChild(b)):(this.element.setAttribute("enctype","multipart/form-data"),this.element.setAttribute("method",this.options.method)),null!=e?e:b)},c.prototype.getExistingFallback=function(){var a,b,c,d,e,f;for(b=function(a){var b,c,d;for(c=0,d=a.length;d>c;c++)if(b=a[c],/(^| )fallback($| )/.test(b.className))return b},f=["div","form"],d=0,e=f.length;e>d;d++)if(c=f[d],a=b(this.element.getElementsByTagName(c)))return a},c.prototype.setupEventListeners=function(){var a,b,c,d,e,f,g;for(f=this.listeners,g=[],d=0,e=f.length;e>d;d++)a=f[d],g.push(function(){var d,e;d=a.events,e=[];for(b in d)c=d[b],e.push(a.element.addEventListener(b,c,!1));return e}());return g},c.prototype.removeEventListeners=function(){var a,b,c,d,e,f,g;for(f=this.listeners,g=[],d=0,e=f.length;e>d;d++)a=f[d],g.push(function(){var d,e;d=a.events,e=[];for(b in d)c=d[b],e.push(a.element.removeEventListener(b,c,!1));return e}());return g},c.prototype.disable=function(){var a,b,c,d,e;for(this.clickableElements.forEach(function(a){return a.classList.remove("dz-clickable")}),this.removeEventListeners(),d=this.files,e=[],b=0,c=d.length;c>b;b++)a=d[b],e.push(this.cancelUpload(a));return e},c.prototype.enable=function(){return this.clickableElements.forEach(function(a){return a.classList.add("dz-clickable")}),this.setupEventListeners()},c.prototype.filesize=function(a){var b,c,d,e,f,g,h,i;if(d=0,e="b",a>0){for(g=["TB","GB","MB","KB","b"],c=h=0,i=g.length;i>h;c=++h)if(f=g[c],b=Math.pow(this.options.filesizeBase,4-c)/10,a>=b){d=a/Math.pow(this.options.filesizeBase,4-c),e=f;break}d=Math.round(10*d)/10}return"<strong>"+d+"</strong> "+e},c.prototype._updateMaxFilesReachedClass=function(){return null!=this.options.maxFiles&&this.getAcceptedFiles().length>=this.options.maxFiles?(this.getAcceptedFiles().length===this.options.maxFiles&&this.emit("maxfilesreached",this.files),this.element.classList.add("dz-max-files-reached")):this.element.classList.remove("dz-max-files-reached")},c.prototype.drop=function(a){var b,c;a.dataTransfer&&(this.emit("drop",a),b=a.dataTransfer.files,this.emit("addedfiles",b),b.length&&(c=a.dataTransfer.items,c&&c.length&&null!=c[0].webkitGetAsEntry?this._addFilesFromItems(c):this.handleFiles(b)))},c.prototype.paste=function(a){var b,c;if(null!=(null!=a&&null!=(c=a.clipboardData)?c.items:void 0))return this.emit("paste",a),b=a.clipboardData.items,b.length?this._addFilesFromItems(b):void 0},c.prototype.handleFiles=function(a){var b,c,d,e;for(e=[],c=0,d=a.length;d>c;c++)b=a[c],e.push(this.addFile(b));return e},c.prototype._addFilesFromItems=function(a){var b,c,d,e,f;for(f=[],d=0,e=a.length;e>d;d++)c=a[d],f.push(null!=c.webkitGetAsEntry&&(b=c.webkitGetAsEntry())?b.isFile?this.addFile(c.getAsFile()):b.isDirectory?this._addFilesFromDirectory(b,b.name):void 0:null!=c.getAsFile?null==c.kind||"file"===c.kind?this.addFile(c.getAsFile()):void 0:void 0);return f},c.prototype._addFilesFromDirectory=function(a,b){var c,d;return c=a.createReader(),d=function(a){return function(c){var d,e,f;for(e=0,f=c.length;f>e;e++)d=c[e],d.isFile?d.file(function(c){return a.options.ignoreHiddenFiles&&"."===c.name.substring(0,1)?void 0:(c.fullPath=""+b+"/"+c.name,a.addFile(c))}):d.isDirectory&&a._addFilesFromDirectory(d,""+b+"/"+d.name)}}(this),c.readEntries(d,function(a){return"undefined"!=typeof console&&null!==console&&"function"==typeof console.log?console.log(a):void 0})},c.prototype.accept=function(a,b){return a.size>1024*this.options.maxFilesize*1024?b(this.options.dictFileTooBig.replace("{{filesize}}",Math.round(a.size/1024/10.24)/100).replace("{{maxFilesize}}",this.options.maxFilesize)):c.isValidFile(a,this.options.acceptedFiles)?null!=this.options.maxFiles&&this.getAcceptedFiles().length>=this.options.maxFiles?(b(this.options.dictMaxFilesExceeded.replace("{{maxFiles}}",this.options.maxFiles)),this.emit("maxfilesexceeded",a)):this.options.accept.call(this,a,b):b(this.options.dictInvalidFileType)},c.prototype.addFile=function(a){return a.upload={progress:0,total:a.size,bytesSent:0},this.files.push(a),a.status=c.ADDED,this.emit("addedfile",a),this._enqueueThumbnail(a),this.accept(a,function(b){return function(c){return c?(a.accepted=!1,b._errorProcessing([a],c)):(a.accepted=!0,b.options.autoQueue&&b.enqueueFile(a)),b._updateMaxFilesReachedClass()}}(this))},c.prototype.enqueueFiles=function(a){var b,c,d;for(c=0,d=a.length;d>c;c++)b=a[c],this.enqueueFile(b);return null},c.prototype.enqueueFile=function(a){if(a.status!==c.ADDED||a.accepted!==!0)throw new Error("This file can't be queued because it has already been processed or was rejected.");return a.status=c.QUEUED,this.options.autoProcessQueue?setTimeout(function(a){return function(){return a.processQueue()}}(this),0):void 0},c.prototype._thumbnailQueue=[],c.prototype._processingThumbnail=!1,c.prototype._enqueueThumbnail=function(a){return this.options.createImageThumbnails&&a.type.match(/image.*/)&&a.size<=1024*this.options.maxThumbnailFilesize*1024?(this._thumbnailQueue.push(a),setTimeout(function(a){return function(){return a._processThumbnailQueue()}}(this),0)):void 0},c.prototype._processThumbnailQueue=function(){return this._processingThumbnail||0===this._thumbnailQueue.length?void 0:(this._processingThumbnail=!0,this.createThumbnail(this._thumbnailQueue.shift(),function(a){return function(){return a._processingThumbnail=!1,a._processThumbnailQueue()}}(this)))},c.prototype.removeFile=function(a){return a.status===c.UPLOADING&&this.cancelUpload(a),this.files=h(this.files,a),this.emit("removedfile",a),0===this.files.length?this.emit("reset"):void 0},c.prototype.removeAllFiles=function(a){var b,d,e,f;for(null==a&&(a=!1),f=this.files.slice(),d=0,e=f.length;e>d;d++)b=f[d],(b.status!==c.UPLOADING||a)&&this.removeFile(b);return null},c.prototype.createThumbnail=function(a,b){var c;return c=new FileReader,c.onload=function(d){return function(){return"image/svg+xml"===a.type?(d.emit("thumbnail",a,c.result),void(null!=b&&b())):d.createThumbnailFromUrl(a,c.result,b)}}(this),c.readAsDataURL(a)},c.prototype.createThumbnailFromUrl=function(a,b,c,d){var e;return e=document.createElement("img"),d&&(e.crossOrigin=d),e.onload=function(b){return function(){var d,g,h,i,j,k,l,m;return a.width=e.width,a.height=e.height,h=b.options.resize.call(b,a),null==h.trgWidth&&(h.trgWidth=h.optWidth),null==h.trgHeight&&(h.trgHeight=h.optHeight),d=document.createElement("canvas"),g=d.getContext("2d"),d.width=h.trgWidth,d.height=h.trgHeight,f(g,e,null!=(j=h.srcX)?j:0,null!=(k=h.srcY)?k:0,h.srcWidth,h.srcHeight,null!=(l=h.trgX)?l:0,null!=(m=h.trgY)?m:0,h.trgWidth,h.trgHeight),i=d.toDataURL("image/png"),b.emit("thumbnail",a,i),null!=c?c():void 0}}(this),null!=c&&(e.onerror=c),e.src=b},c.prototype.processQueue=function(){var a,b,c,d;if(b=this.options.parallelUploads,c=this.getUploadingFiles().length,a=c,!(c>=b)&&(d=this.getQueuedFiles(),d.length>0)){if(this.options.uploadMultiple)return this.processFiles(d.slice(0,b-c));for(;b>a;){if(!d.length)return;this.processFile(d.shift()),a++}}},c.prototype.processFile=function(a){return this.processFiles([a])},c.prototype.processFiles=function(a){var b,d,e;for(d=0,e=a.length;e>d;d++)b=a[d],b.processing=!0,b.status=c.UPLOADING,this.emit("processing",b);return this.options.uploadMultiple&&this.emit("processingmultiple",a),this.uploadFiles(a)},c.prototype._getFilesWithXhr=function(a){var b,c;return c=function(){var c,d,e,f;for(e=this.files,f=[],c=0,d=e.length;d>c;c++)b=e[c],b.xhr===a&&f.push(b);return f}.call(this)},c.prototype.cancelUpload=function(a){var b,d,e,f,g,h,i;if(a.status===c.UPLOADING){for(d=this._getFilesWithXhr(a.xhr),e=0,g=d.length;g>e;e++)b=d[e],b.status=c.CANCELED;for(a.xhr.abort(),f=0,h=d.length;h>f;f++)b=d[f],this.emit("canceled",b);this.options.uploadMultiple&&this.emit("canceledmultiple",d)}else((i=a.status)===c.ADDED||i===c.QUEUED)&&(a.status=c.CANCELED,this.emit("canceled",a),this.options.uploadMultiple&&this.emit("canceledmultiple",[a]));return this.options.autoProcessQueue?this.processQueue():void 0},e=function(){var a,b;return b=arguments[0],a=2<=arguments.length?i.call(arguments,1):[],"function"==typeof b?b.apply(this,a):b},c.prototype.uploadFile=function(a){return this.uploadFiles([a])},c.prototype.uploadFiles=function(a){var b,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L;for(w=new XMLHttpRequest,x=0,B=a.length;B>x;x++)b=a[x],b.xhr=w;p=e(this.options.method,a),u=e(this.options.url,a),w.open(p,u,!0),w.withCredentials=!!this.options.withCredentials,s=null,g=function(c){return function(){var d,e,f;for(f=[],d=0,e=a.length;e>d;d++)b=a[d],f.push(c._errorProcessing(a,s||c.options.dictResponseError.replace("{{statusCode}}",w.status),w));return f}}(this),t=function(c){return function(d){var e,f,g,h,i,j,k,l,m;if(null!=d)for(f=100*d.loaded/d.total,g=0,j=a.length;j>g;g++)b=a[g],b.upload={progress:f,total:d.total,bytesSent:d.loaded};else{for(e=!0,f=100,h=0,k=a.length;k>h;h++)b=a[h],(100!==b.upload.progress||b.upload.bytesSent!==b.upload.total)&&(e=!1),b.upload.progress=f,b.upload.bytesSent=b.upload.total;if(e)return}for(m=[],i=0,l=a.length;l>i;i++)b=a[i],m.push(c.emit("uploadprogress",b,f,b.upload.bytesSent));return m}}(this),w.onload=function(b){return function(d){var e;if(a[0].status!==c.CANCELED&&4===w.readyState){if(s=w.responseText,w.getResponseHeader("content-type")&&~w.getResponseHeader("content-type").indexOf("application/json"))try{s=JSON.parse(s)}catch(f){d=f,s="Invalid JSON response from server."}return t(),200<=(e=w.status)&&300>e?b._finished(a,s,d):g()}}}(this),w.onerror=function(){return function(){return a[0].status!==c.CANCELED?g():void 0}}(this),r=null!=(G=w.upload)?G:w,r.onprogress=t,j={Accept:"application/json","Cache-Control":"no-cache","X-Requested-With":"XMLHttpRequest"},this.options.headers&&d(j,this.options.headers);for(h in j)i=j[h],i&&w.setRequestHeader(h,i);if(f=new FormData,this.options.params){H=this.options.params;for(o in H)v=H[o],f.append(o,v)}for(y=0,C=a.length;C>y;y++)b=a[y],this.emit("sending",b,w,f);if(this.options.uploadMultiple&&this.emit("sendingmultiple",a,w,f),"FORM"===this.element.tagName)for(I=this.element.querySelectorAll("input, textarea, select, button"),z=0,D=I.length;D>z;z++)if(l=I[z],m=l.getAttribute("name"),n=l.getAttribute("type"),"SELECT"===l.tagName&&l.hasAttribute("multiple"))for(J=l.options,A=0,E=J.length;E>A;A++)q=J[A],q.selected&&f.append(m,q.value);else(!n||"checkbox"!==(K=n.toLowerCase())&&"radio"!==K||l.checked)&&f.append(m,l.value);for(k=F=0,L=a.length-1;L>=0?L>=F:F>=L;k=L>=0?++F:--F)f.append(this._getParamName(k),a[k],a[k].name);return this.submitRequest(w,f,a)},c.prototype.submitRequest=function(a,b){return a.send(b)},c.prototype._finished=function(a,b,d){var e,f,g;for(f=0,g=a.length;g>f;f++)e=a[f],e.status=c.SUCCESS,this.emit("success",e,b,d),this.emit("complete",e);return this.options.uploadMultiple&&(this.emit("successmultiple",a,b,d),this.emit("completemultiple",a)),this.options.autoProcessQueue?this.processQueue():void 0},c.prototype._errorProcessing=function(a,b,d){var e,f,g;for(f=0,g=a.length;g>f;f++)e=a[f],e.status=c.ERROR,this.emit("error",e,b,d),this.emit("complete",e);return this.options.uploadMultiple&&(this.emit("errormultiple",a,b,d),this.emit("completemultiple",a)),this.options.autoProcessQueue?this.processQueue():void 0},c}(b),a.version="4.2.0",a.options={},a.optionsForElement=function(b){return b.getAttribute("id")?a.options[c(b.getAttribute("id"))]:void 0},a.instances=[],a.forElement=function(a){if("string"==typeof a&&(a=document.querySelector(a)),null==(null!=a?a.dropzone:void 0))throw new Error("No Dropzone found for given element. This is probably because you're trying to access it before Dropzone had the time to initialize. Use the `init` option to setup any additional observers on your Dropzone.");return a.dropzone},a.autoDiscover=!0,a.discover=function(){var b,c,d,e,f,g;for(document.querySelectorAll?d=document.querySelectorAll(".dropzone"):(d=[],b=function(a){var b,c,e,f;for(f=[],c=0,e=a.length;e>c;c++)b=a[c],f.push(/(^| )dropzone($| )/.test(b.className)?d.push(b):void 0);return f},b(document.getElementsByTagName("div")),b(document.getElementsByTagName("form"))),g=[],e=0,f=d.length;f>e;e++)c=d[e],g.push(a.optionsForElement(c)!==!1?new a(c):void 0);return g},a.blacklistedBrowsers=[/opera.*Macintosh.*version\/12/i],a.isBrowserSupported=function(){var b,c,d,e,f;if(b=!0,window.File&&window.FileReader&&window.FileList&&window.Blob&&window.FormData&&document.querySelector)if("classList"in document.createElement("a"))for(f=a.blacklistedBrowsers,d=0,e=f.length;e>d;d++)c=f[d],c.test(navigator.userAgent)&&(b=!1);else b=!1;else b=!1;return b},h=function(a,b){var c,d,e,f;for(f=[],d=0,e=a.length;e>d;d++)c=a[d],c!==b&&f.push(c);return f},c=function(a){return a.replace(/[\-_](\w)/g,function(a){return a.charAt(1).toUpperCase()})},a.createElement=function(a){var b;return b=document.createElement("div"),b.innerHTML=a,b.childNodes[0]},a.elementInside=function(a,b){if(a===b)return!0;for(;a=a.parentNode;)if(a===b)return!0;return!1},a.getElement=function(a,b){var c;if("string"==typeof a?c=document.querySelector(a):null!=a.nodeType&&(c=a),null==c)throw new Error("Invalid `"+b+"` option provided. Please provide a CSS selector or a plain HTML element.");return c},a.getElements=function(a,b){var c,d,e,f,g,h,i,j;if(a instanceof Array){e=[];try{for(f=0,h=a.length;h>f;f++)d=a[f],e.push(this.getElement(d,b))}catch(k){c=k,e=null}}else if("string"==typeof a)for(e=[],j=document.querySelectorAll(a),g=0,i=j.length;i>g;g++)d=j[g],e.push(d);else null!=a.nodeType&&(e=[a]);if(null==e||!e.length)throw new Error("Invalid `"+b+"` option provided. Please provide a CSS selector, a plain HTML element or a list of those.");return e},a.confirm=function(a,b,c){return window.confirm(a)?b():null!=c?c():void 0},a.isValidFile=function(a,b){var c,d,e,f,g;if(!b)return!0;for(b=b.split(","),d=a.type,c=d.replace(/\/.*$/,""),f=0,g=b.length;g>f;f++)if(e=b[f],e=e.trim(),"."===e.charAt(0)){if(-1!==a.name.toLowerCase().indexOf(e.toLowerCase(),a.name.length-e.length))return!0}else if(/\/\*$/.test(e)){if(c===e.replace(/\/.*$/,""))return!0}else if(d===e)return!0;return!1},"undefined"!=typeof jQuery&&null!==jQuery&&(jQuery.fn.dropzone=function(b){return this.each(function(){return new a(this,b)})}),"undefined"!=typeof module&&null!==module?module.exports=a:window.Dropzone=a,a.ADDED="added",a.QUEUED="queued",a.ACCEPTED=a.QUEUED,a.UPLOADING="uploading",a.PROCESSING=a.UPLOADING,a.CANCELED="canceled",a.ERROR="error",a.SUCCESS="success",e=function(a){var b,c,d,e,f,g,h,i,j,k;
+for(h=a.naturalWidth,g=a.naturalHeight,c=document.createElement("canvas"),c.width=1,c.height=g,d=c.getContext("2d"),d.drawImage(a,0,0),e=d.getImageData(0,0,1,g).data,k=0,f=g,i=g;i>k;)b=e[4*(i-1)+3],0===b?f=i:k=i,i=f+k>>1;return j=i/g,0===j?1:j},f=function(a,b,c,d,f,g,h,i,j,k){var l;return l=e(b),a.drawImage(b,c,d,f,g,h,i,j,k/l)},d=function(a,b){var c,d,e,f,g,h,i,j,k;if(e=!1,k=!0,d=a.document,j=d.documentElement,c=d.addEventListener?"addEventListener":"attachEvent",i=d.addEventListener?"removeEventListener":"detachEvent",h=d.addEventListener?"":"on",f=function(c){return"readystatechange"!==c.type||"complete"===d.readyState?(("load"===c.type?a:d)[i](h+c.type,f,!1),!e&&(e=!0)?b.call(a,c.type||c):void 0):void 0},g=function(){var a;try{j.doScroll("left")}catch(b){return a=b,void setTimeout(g,50)}return f("poll")},"complete"!==d.readyState){if(d.createEventObject&&j.doScroll){try{k=!a.frameElement}catch(l){}k&&g()}return d[c](h+"DOMContentLoaded",f,!1),d[c](h+"readystatechange",f,!1),a[c](h+"load",f,!1)}},a._autoDiscoverFunction=function(){return a.autoDiscover?a.discover():void 0},d(window,a._autoDiscoverFunction)}).call(this); \ No newline at end of file