WP Photo Album Plus - Version 7.2.03.006

Version Description

= 7.2.02 =

  • This version addresses various bug fixes and feature requests.

= 7.2.01 =

  • This version addresses various bug fixes and feature requests.

= 7.2.00 =

  • This version addresses various bug fixes and feature requests.

= 7.1.11 =

  • This version addresses various bug fixes and feature requests.

= 7.1.10 =

  • This version addresses various bug fixes and feature requests.

= 7.1.09 =

  • This version addresses various bug fixes and feature requests.

= 7.1.08 =

  • This version addresses various bug fixes and feature requests.

= 7.1.07 =

  • This version addresses various bug fixes and feature requests.

= 7.1.06 =

  • This version addresses various bug fixes and feature requests.

= 7.1.05 =

  • This version addresses various security issues.
  • This version addresses various bug fixes.

= 7.1.04 =

  • This version addresses various bug fixes.

= 7.1.03 =

  • This version addresses various security issues.
  • This version addresses various bug fixes.

= 7.1.02 =

  • This version addresses various security issues.
  • This version addresses various bug fixes and feature requests.

= 7.1.01 =

  • This version addresses various bug fixes and feature requests.

= 7.1.00 =

  • This version addresses various bug fixes and feature requests.
  • The Photo Album -> Upload Photos and Import Photos admin pages have been substantially improved. Read the changelog for details.

= 7.0.11 =

  • This version addresses various bug fixes and feature requests.

= 7.0.11 =

  • This version addresses various bug fixes

= 7.0.10 =

  • This version addresses various bug fixes

= 7.0.09 =

  • This version addresses various security issues.
  • This version addresses various bug fixes and feature requests.

= 7.0.08 =

  • This version addresses various security issues.
  • This version addresses various bug fixes

= 7.0.07 =

  • This version addresses various security issues.
  • This version addresses various bug fixes

= 7.0.06 =

  • This version addresses various bug fixes
  • This version addresses various security issues.

= 7.0.05 =

  • This version addresses various minor bug fixes and feature requests.
  • This version addresses various security issues.

= 7.0.04 =

  • This version addresses various bug fixes
  • This version addresses various security issues.

= 7.0.03 =

  • This version addresses various minor bug fixes and feature requests.

= 7.0.02 =

  • This version addresses various bug fixes
  • This version addresses various security issues.

= 7.0.01 =

  • This version addresses various minor bug fixes and feature requests.

= 7.0.00 =

  • Shortcode generators for Gutenberg added.
  • This version addresses various minor bug fixes and feature requests.
  • This version addresses various security issues.
  • To prevent spamming and give the users the opportunity to decide when they want us to email them, the mailing system has been revised. Configure Table IX-M to enable various mailing lists, and use the WPPA+ Notify widget for full user flexibility.

= 6.9.21 =

  • This version addresses various bug fixes
  • This version addresses various security issues.

= 6.9.20 =

  • This version addresses various bug fixes

= 6.9.19 =

  • This version addresses various minor bug fixes

= 6.9.18 =

  • This version addresses various minor bug fixes

= 6.9.17 =

  • This version addresses various minor bug fixes and feature requests.
  • This version addresses various security issues.

= 6.9.16 =

  • This version addresses various minor bug fixes and feature requests.
  • This version addresses various security issues.

= 6.9.15 =

  • This version addresses various minor bug fixes and feature requests.
  • This version addresses various security issues.

= 6.9.14 =

  • This version addresses various minor bug fixes and feature requests.
  • This version addresses various security issues.

= 6.9.13 =

  • Security release.

= 6.9.12 =

  • This version addresses various minor bug fixes and performance improvements.

= 6.9.11 =

  • This version addresses various minor bug fixes and performance improvements.

= 6.9.10 =

  • This version addresses various minor bug fixes and performance improvements.

= 6.9.09 =

  • Panorama support phase III.

= 6.9.08 =

  • This version addresses various minor bug fixes and feature requests.
  • Panorama support phase II.

= 6.9.07 =

  • This version addresses various minor bug fixes and feature requests.
  • Panorama support phase I.

= 6.9.06 =

  • This version addresses various minor bug fixes and feature requests.

= 6.9.05 =

  • This version addresses various minor bug fixes and feature requests.

= 6.9.04 =

  • This version addresses various minor bug fixes and feature requests.
  • Local CDN functionality has been added.

= 6.9.03 =

  • This version addresses various minor bug fixes and feature requests.

= 6.9.02 =

  • This version addresses various minor bug fixes and feature requests.

= 6.9.01 =

  • This version addresses various minor bug fixes and feature requests.

= 6.9.00 =

  • This version includes the code for the privacy policy requirements.

= 6.8.09

  • This version addresses various bug fixes and code edits.

= 6.8.08 =

  • This version addresses various minor bug fixes and feature requests.
  • This version offers substantial performance improvements when the box in Table IV-A13: Defer Javascript is ticked. This setting is now recommended and set ticked as the default.
  • For more info on performance improvements and compatibility with optimizers: see the changelog.txt

= 6.8.07 =

  • This version addresses various minor bug fixes and enhancements, and a new widget: Statistics.

= 6.8.06 =

  • This version addresses various minor bug fixes and improved cache handling.

= 6.8.05 =

  • This version addresses various minor bug fixes and feture requests.

= 6.8.04 =

  • This version addresses various display issues and a few fixes of bugs that seldom affected the plugins behaviour.
Download this release

Release Info

Developer opajaap
Plugin Icon wp plugin WP Photo Album Plus
Version 7.2.03.006
Comparing to
See all releases

Code changes from version 7.2.02.005 to 7.2.03.006

changelog.txt CHANGED
@@ -1,5 +1,16 @@
1
  WP Photo Album Plus Changelog
2
 
 
 
 
 
 
 
 
 
 
 
 
3
  = 7.2.02 =
4
 
5
  * Added cover type Grid with images only.
1
  WP Photo Album Plus Changelog
2
 
3
+ = 7.2.03 =
4
+
5
+ * Added crop functionality to imageMagick commands on the photo admin pages.
6
+ * Changed the algorithm for extended duplicate removal in search operations.
7
+ * Added a checkbox on the photo admin page to lock the thumbnail, so, if ticked,
8
+ the thumbnail file will not be remade when requested individually or in bulk procedures.
9
+ * Simplified (speeded up) and improved security while updating on the photo admin page.
10
+ * Improved reloading photo images after being visually modified on the photo admin page (without reloading the entire page).
11
+ * Fixed a spourious issue where the album timestamp was empty, causing php warnings.
12
+ * Any attempt to show previous or next on a lightbox single image showed the loading spinner. Fixed.
13
+
14
  = 7.2.02 =
15
 
16
  * Added cover type Grid with images only.
js/wppa-admin-scripts.js CHANGED
@@ -1,7 +1,7 @@
1
  /* admin-scripts.js */
2
  /* Package: wp-photo-album-plus
3
  /*
4
- /* Version 7.0.09
5
  /* Various js routines used in admin pages
6
  */
7
 
@@ -11,6 +11,7 @@ var wppa_update = 'Update';
11
  var wppaImageDirectory;
12
  var wppaAjaxUrl;
13
  var wppaUploadToThisAlbum = 'Upload to this album';
 
14
 
15
  // Init at dom ready
16
  jQuery( document ).ready(function() {
@@ -95,7 +96,7 @@ function wppaReUpload( event, photo, expectedName ) {
95
  }
96
  switch ( ArrValues[1] ) {
97
  case '0': // No error
98
- jQuery('#photostatus-'+photo).html(ArrValues[2]);
99
  button.value = 'Upload';
100
  jQuery( '#re-up-'+photo ).css( 'display', 'none' );
101
  break;
@@ -103,7 +104,7 @@ function wppaReUpload( event, photo, expectedName ) {
103
  document.getElementById('photoitem-'+photo).innerHTML = '<span style="color:red">'+ArrValues[2]+'</span>';
104
  break;
105
  default: // Any error
106
- document.getElementById('photostatus-'+photo).innerHTML = '<span style="color:red">'+ArrValues[2]+' ('+ArrValues[1]+')</span>';
107
  button.value = 'Error occured';
108
  button.style.color = 'red';
109
  break;
@@ -1029,13 +1030,13 @@ function wppaAjaxDeletePhoto(photo, bef, aft) {
1029
  xmlhttp.onreadystatechange=function() {
1030
  switch (xmlhttp.readyState) {
1031
  case 1:
1032
- document.getElementById('photostatus-'+photo).innerHTML = 'server connection established';
1033
  break;
1034
  case 2:
1035
- document.getElementById('photostatus-'+photo).innerHTML = 'request received';
1036
  break;
1037
  case 3:
1038
- document.getElementById('photostatus-'+photo).innerHTML = 'processing request';
1039
  break;
1040
  case 4:
1041
  if ( xmlhttp.status == 200 ) {
@@ -1052,7 +1053,7 @@ function wppaAjaxDeletePhoto(photo, bef, aft) {
1052
  alert('The server returned unexpected output:\n'+ArrValues[0]);
1053
  }
1054
 
1055
- if ( ArrValues[1] == 0 ) document.getElementById('photostatus-'+photo).innerHTML = ArrValues[2]; // Error
1056
  else {
1057
  document.getElementById('photoitem-'+photo).innerHTML = before+ArrValues[2]+after; // OK
1058
  wppaProcessFull(ArrValues[3], ArrValues[4]);
@@ -1085,13 +1086,13 @@ function wppaAjaxUndeletePhoto(photo) {
1085
  xmlhttp.onreadystatechange=function() {
1086
  switch (xmlhttp.readyState) {
1087
  case 1:
1088
- document.getElementById('photostatus-'+photo).innerHTML = 'server connection established';
1089
  break;
1090
  case 2:
1091
- document.getElementById('photostatus-'+photo).innerHTML = 'request received';
1092
  break;
1093
  case 3:
1094
- document.getElementById('photostatus-'+photo).innerHTML = 'processing request';
1095
  break;
1096
  case 4:
1097
  if ( xmlhttp.status == 200 ) {
@@ -1108,7 +1109,7 @@ function wppaAjaxUndeletePhoto(photo) {
1108
  alert('The server returned unexpected output:\n'+ArrValues[0]);
1109
  }
1110
 
1111
- if ( ArrValues[1] == 0 ) document.getElementById('photostatus-'+photo).innerHTML = ArrValues[2]; // Error
1112
  else {
1113
  document.getElementById('photoitem-'+photo).innerHTML = '<div style="padding-left:5px;" >' + ArrValues[2] + '</div>'; // OK
1114
  }
@@ -1153,10 +1154,10 @@ function wppaAjaxApplyWatermark(photo, file, pos) {
1153
  }
1154
  switch (ArrValues[1]) {
1155
  case '0': // No error
1156
- document.getElementById('photostatus-'+photo).innerHTML = ArrValues[2];
1157
  break;
1158
  default:
1159
- document.getElementById('photostatus-'+photo).innerHTML = '<span style="color:red">'+ArrValues[2]+'</span>';
1160
  }
1161
  // Hide spinner
1162
  jQuery('#wppa-water-spin-'+photo).css({visibility:'hidden'});
@@ -1164,136 +1165,23 @@ function wppaAjaxApplyWatermark(photo, file, pos) {
1164
  wppaFeAjaxLog('out');
1165
  }
1166
  else { // status != 200
1167
- document.getElementById('photostatus-'+photo).innerHTML = '<span style="color:red;" >Comm error '+xmlhttp.status+': '+xmlhttp.statusText+'</span>';
1168
  }
1169
  }
1170
  }
1171
  }
1172
 
1173
- var wppaAjaxPhotoCount = new Array();
1174
- var wppaPhotoUpdateMatrix = new Array();
1175
-
1176
- // Update photo
1177
- //
1178
- // @1: integer photo id
1179
- // @2: string action slug
1180
- // @3: elem ( this or getElementById() from caller ) OR a random number.
1181
- // The number must be different in successive calls to trigger subsequent actions.
1182
- // If the number is the same as before, no change is assumed.
1183
- // @4: bool: indicating if page reload needed after action.
1184
- // @5: An alphameric id for the photo ( required for TynyMce )
1185
- function wppaAjaxUpdatePhoto( photo, actionslug, elem, refresh, photoAlfaid ) {
1186
-
1187
- // Indexes in update matrix
1188
- var phoidx = 0;
1189
- var slgidx = 1;
1190
- var ovlidx = 2;
1191
- var nvlidx = 3;
1192
- var bsyidx = 4;
1193
- var refidx = 5;
1194
-
1195
- // For tynyMce
1196
- var isTmce = false;
1197
- if ( photoAlfaid ) {
1198
- isTmce = jQuery( "#wppaphotodesc"+photoAlfaid+":visible" ).length == 0;
1199
- jQuery( "#wppaphotodesc" + photoAlfaid + "-html" ).click();
1200
- if ( isTmce ) jQuery( "#wppaphotodesc" + photoAlfaid + "-tmce" ).click();
1201
- }
1202
-
1203
- // Init
1204
- var count = wppaPhotoUpdateMatrix.length;
1205
- var i = 0;
1206
- var found = false;
1207
- var index = -1;
1208
-
1209
- // See if we did this slug for this photo already
1210
- while ( i < count ) {
1211
- if ( wppaPhotoUpdateMatrix[i][phoidx] == photo && wppaPhotoUpdateMatrix[i][slgidx] == actionslug ) {
1212
- found = true;
1213
- index = i;
1214
- }
1215
- i++;
1216
- }
1217
-
1218
- // Not done this yet, create new entry in array
1219
- if ( ! found ) {
1220
- var oldval = 'undefined';
1221
- var newval = false;
1222
- var busy = false;
1223
- wppaPhotoUpdateMatrix[count] = [photo, actionslug, oldval, newval, busy, refresh];
1224
- index = count;
1225
- }
1226
-
1227
- // Updatearray
1228
- wppaPhotoUpdateMatrix[index][nvlidx] = ( typeof( elem ) == 'number' ? elem : elem.value );
1229
- wppaPhotoUpdateMatrix[index][refidx] = refresh;
1230
-
1231
- // Run the monitor
1232
- wppaAjaxUpdatePhotoMonitor();
1233
- }
1234
-
1235
- function wppaAjaxUpdateDelphoto( photo, actionslug, elem ) {
1236
- wppaAjaxUpdatePhoto( photo, 'del' + actionslug, elem );
1237
- }
1238
-
1239
- // This monitor keeps track of running ajax requests
1240
- // If many chars are typed quickly ( busy flag true ) updating will be skipped
1241
- // until the running ajax request ends. A new request will catch up the rest of the data mods.
1242
- function wppaAjaxUpdatePhotoMonitor() {
1243
-
1244
- // Indexes in update matrix
1245
- var phoidx = 0; // photo id
1246
- var slgidx = 1; // action slug
1247
- var ovlidx = 2; // old value
1248
- var nvlidx = 3; // new value
1249
- var bsyidx = 4; // busy flag
1250
- var refidx = 5; // refresh flag
1251
-
1252
- // Init
1253
- var count = wppaPhotoUpdateMatrix.length;
1254
- var i = 0;
1255
-
1256
- // Find the entries in the matrix for the photo/slug cominations where the new value is unequal to the old value,
1257
- // where this combi is not busy ( operation in progress ).
1258
- // For such matrix entries: set busy flag and start an ajax action
1259
- while ( i < count ) {
1260
-
1261
- if ( ( wppaPhotoUpdateMatrix[i][ovlidx] != wppaPhotoUpdateMatrix[i][nvlidx] ) && ! wppaPhotoUpdateMatrix[i][bsyidx] ) {
1262
-
1263
- // Set busy
1264
- wppaPhotoUpdateMatrix[i][bsyidx] = true;
1265
-
1266
- // Start ajax
1267
- _wppaAjaxUpdatePhoto( wppaPhotoUpdateMatrix[i][phoidx], wppaPhotoUpdateMatrix[i][slgidx], wppaPhotoUpdateMatrix[i][nvlidx], wppaPhotoUpdateMatrix[i][refidx] );
1268
- }
1269
- i++;
1270
- }
1271
- }
1272
-
1273
- // Do the actual ajax update request
1274
- function _wppaAjaxUpdatePhoto( photo, actionslug, value, refresh, bef, aft ) {
1275
 
1276
  if ( ! bef ) bef = '';
1277
  if ( ! aft ) aft = '';
1278
 
1279
- // Indexes in update matrix
1280
- var phoidx = 0; // photo id
1281
- var slgidx = 1; // action slug
1282
- var ovlidx = 2; // old value
1283
- var nvlidx = 3; // new value
1284
- var bsyidx = 4; // busy flag
1285
- var refidx = 5; // refresh flag
1286
-
1287
  // On Front-end edit photo classic style, there is a button: Update and exit.
1288
  // Set it to the desired state
1289
  wppaFeAjaxLog('in');
1290
 
1291
- // Increment total number of ajax actions pending for this photo
1292
- if ( ! wppaAjaxPhotoCount[photo] ) wppaAjaxPhotoCount[photo] = 0;
1293
- wppaAjaxPhotoCount[photo]++;
1294
-
1295
  // Open ajax object
1296
-
1297
  jQuery.ajax( { url: wppaAjaxUrl,
1298
  data: 'action=wppa&wppa-action=update-photo' +
1299
  '&photo-id=' + photo +
@@ -1306,12 +1194,10 @@ function _wppaAjaxUpdatePhoto( photo, actionslug, value, refresh, bef, aft ) {
1306
  beforeSend: function( xhr ) {
1307
 
1308
  // Show spinner
1309
- if ( actionslug == 'description' ) {
1310
- jQuery('#wppa-photo-spin-'+photo).css( { visibility: 'visible' } );
1311
- }
1312
 
1313
  // Update status
1314
- jQuery( '#photostatus-' + photo ).html( 'Working, please wait... (' + wppaAjaxPhotoCount[photo] + ')');
1315
 
1316
  },
1317
  success: function( result, status, xhr ) {
@@ -1320,67 +1206,78 @@ function _wppaAjaxUpdatePhoto( photo, actionslug, value, refresh, bef, aft ) {
1320
  var str = wppaTrim( result );
1321
  var ArrValues = str.split("||");
1322
 
1323
- // One pending less
1324
- wppaAjaxPhotoCount[photo]--;
1325
-
1326
  // Any strange results returned?
1327
  if ( ArrValues[0] != '' ) {
1328
  alert( 'The server returned unexpected output:\n' + ArrValues[0] );
1329
  }
1330
 
1331
- // Update status field
1332
  switch ( ArrValues[1] ) {
1333
- case '0': // No error
1334
-
1335
- // Udate status
1336
- if ( wppaAjaxPhotoCount[photo] == 0 ) {
1337
- jQuery('#photostatus-'+photo).html( ArrValues[2] );
1338
- }
1339
- else {
1340
- jQuery('#photostatus-'+photo).html( 'Working, please wait... (' + wppaAjaxPhotoCount[photo] + ')' );
1341
- }
1342
-
1343
- // Increment photo version no
1344
- if ( ArrValues[3] ) {
1345
- var href = jQuery( '#fs-a-' + photo ).attr( 'href' );
1346
- var arr = href.split( '=' );
1347
-
1348
- arr[1] = parseInt( arr[1] ) + 1;
1349
- jQuery( '#fs-a-' + photo ).attr( 'href', arr[0] + '=' + arr[1] );
1350
- jQuery( '#fs-img-' + photo ).attr( 'src', arr[0] + '=' + arr[1] );
1351
- }
1352
 
1353
- // Increment thumbnail version
1354
- if ( ArrValues[4] ) {
1355
- var src = jQuery( '#tnp-' + photo ).attr( 'src' );
1356
- var arr = src.split( '=' );
1357
- arr[1] = parseInt( arr[1] ) + 1;
1358
- jQuery( '#tnp-' + photo ).attr( 'src', arr[0] + '=' + arr[1] );
1359
- }
1360
 
1361
- // Update Magic stack
1362
- if ( typeof( ArrValues[5] ) != 'undefined' ) {
1363
- jQuery( '#imstack-' + photo ).html( ArrValues[5] );
1364
- if ( ArrValues[5].length > 0 ) {
1365
- jQuery( '#imstackbutton-' + photo ).css( 'display', '' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1366
  }
1367
- else {
1368
- jQuery( '#imstackbutton-' + photo ).css( 'display', 'none' );
1369
- }
1370
- }
1371
-
1372
- // Update display file sizes
1373
- if ( typeof( ArrValues[6] ) != 'undefined' ) {
1374
- jQuery( '#dispfileinfo-' + photo ).html( ArrValues[6] );
1375
  }
1376
 
1377
  break;
1378
- case '99': // Photo is gone
1379
- jQuery( '#photoitem-' + photo ).html( bef+'<span style="color:red">' + ArrValues[2] + '</span>'+aft );
1380
- break;
1381
- default: // Any error
1382
- jQuery( '#photostatus-' + photo ).html( '<span style="color:red">' + ArrValues[2] + ' (' + ArrValues[1] + ')</span>' );
1383
- break;
1384
  }
1385
 
1386
  // Hide spinner
@@ -1388,48 +1285,17 @@ function _wppaAjaxUpdatePhoto( photo, actionslug, value, refresh, bef, aft ) {
1388
  jQuery('#wppa-photo-spin-'+photo).css( { visibility:'hidden' } );
1389
  }
1390
 
1391
- // Find index in matrix
1392
- var i = 0;
1393
- var index = -1;
1394
- count = wppaPhotoUpdateMatrix.length;
1395
- while ( i < count ) {
1396
- if ( wppaPhotoUpdateMatrix[i][0] == photo && wppaPhotoUpdateMatrix[i][1] == actionslug ) {
1397
- index = i;
1398
- }
1399
- i++;
1400
- }
1401
-
1402
- // Update matrix if not from bulk edit
1403
- if ( wppaPhotoUpdateMatrix[index] ) {
1404
- wppaPhotoUpdateMatrix[index][2] = ( value ? value : 0 );
1405
- wppaPhotoUpdateMatrix[index][4] = false; // no more busy
1406
- wppaPhotoUpdateMatrix[index][5] = false; // reset refresh
1407
- }
1408
-
1409
  // Front-end button
1410
  wppaFeAjaxLog('out');
1411
 
1412
- // check for more
1413
- wppaAjaxUpdatePhotoMonitor();
1414
-
1415
- // Refresh only if no error
1416
- if ( refresh && ArrValues[1] == '0' ) {
1417
- jQuery( '#photostatus-' + photo ).after( '<span style="color:blue;font-weight:bold;"> Reloading...</span>' );
1418
- jQuery( '#wppa-photo-spin-' + photo ).css( { visibility: 'visible' } );
1419
- setTimeout( function() { wppaReload( '#photo_'+photo ) }, 1000 );
1420
- return;
1421
- }
1422
  },
1423
  error: function( xhr, status, error ) {
1424
 
1425
- // One pending less
1426
- wppaAjaxPhotoCount[photo]--;
1427
-
1428
  // Update status
1429
- jQuery( '#photostatus-' + photo ).html( '<span style="color:red;" >Comm error ' + status + '</span>' );
1430
 
1431
  // Log error
1432
- wppaConsoleLog( '_wppaAjaxUpdatePhoto failed. Error = ' + error + ', status = ' + status, 'force' );
1433
  },
1434
  complete: function( xhr, status, newurl ) {
1435
  jQuery( '#wppa-admin-spinner' ).css( 'display', 'none' );
@@ -1707,16 +1573,16 @@ function wppaAjaxUpdateCommentStatus( photo, id, value ) {
1707
  }
1708
  switch (ArrValues[1]) {
1709
  case '0': // No error
1710
- jQuery('#photostatus-'+photo).html(ArrValues[2]);
1711
  break;
1712
  default: // Error
1713
- jQuery('#photostatus-'+photo).html('<span style="color:red">'+ArrValues[2]+'</span>');
1714
  break;
1715
  }
1716
  jQuery('#wppa-comment-spin-'+id).css('visibility', 'hidden');
1717
  }
1718
  else { // status != 200
1719
- jQuery('#photostatus-'+photo).html('<span style="color:red;" >Comm error '+xmlhttp.status+': '+xmlhttp.statusText+'</span>');
1720
  }
1721
  }
1722
  }
1
  /* admin-scripts.js */
2
  /* Package: wp-photo-album-plus
3
  /*
4
+ /* Version 7.2.03
5
  /* Various js routines used in admin pages
6
  */
7
 
11
  var wppaImageDirectory;
12
  var wppaAjaxUrl;
13
  var wppaUploadToThisAlbum = 'Upload to this album';
14
+ var wppaCropper = [];
15
 
16
  // Init at dom ready
17
  jQuery( document ).ready(function() {
96
  }
97
  switch ( ArrValues[1] ) {
98
  case '0': // No error
99
+ jQuery('#remark-'+photo).html(ArrValues[2]);
100
  button.value = 'Upload';
101
  jQuery( '#re-up-'+photo ).css( 'display', 'none' );
102
  break;
104
  document.getElementById('photoitem-'+photo).innerHTML = '<span style="color:red">'+ArrValues[2]+'</span>';
105
  break;
106
  default: // Any error
107
+ document.getElementById('remark-'+photo).innerHTML = '<span style="color:red">'+ArrValues[2]+' ('+ArrValues[1]+')</span>';
108
  button.value = 'Error occured';
109
  button.style.color = 'red';
110
  break;
1030
  xmlhttp.onreadystatechange=function() {
1031
  switch (xmlhttp.readyState) {
1032
  case 1:
1033
+ document.getElementById('remark-'+photo).innerHTML = 'server connection established';
1034
  break;
1035
  case 2:
1036
+ document.getElementById('remark-'+photo).innerHTML = 'request received';
1037
  break;
1038
  case 3:
1039
+ document.getElementById('remark-'+photo).innerHTML = 'processing request';
1040
  break;
1041
  case 4:
1042
  if ( xmlhttp.status == 200 ) {
1053
  alert('The server returned unexpected output:\n'+ArrValues[0]);
1054
  }
1055
 
1056
+ if ( ArrValues[1] == 0 ) document.getElementById('remark-'+photo).innerHTML = ArrValues[2]; // Error
1057
  else {
1058
  document.getElementById('photoitem-'+photo).innerHTML = before+ArrValues[2]+after; // OK
1059
  wppaProcessFull(ArrValues[3], ArrValues[4]);
1086
  xmlhttp.onreadystatechange=function() {
1087
  switch (xmlhttp.readyState) {
1088
  case 1:
1089
+ document.getElementById('remark-'+photo).innerHTML = 'server connection established';
1090
  break;
1091
  case 2:
1092
+ document.getElementById('remark-'+photo).innerHTML = 'request received';
1093
  break;
1094
  case 3:
1095
+ document.getElementById('remark-'+photo).innerHTML = 'processing request';
1096
  break;
1097
  case 4:
1098
  if ( xmlhttp.status == 200 ) {
1109
  alert('The server returned unexpected output:\n'+ArrValues[0]);
1110
  }
1111
 
1112
+ if ( ArrValues[1] == 0 ) document.getElementById('remark-'+photo).innerHTML = ArrValues[2]; // Error
1113
  else {
1114
  document.getElementById('photoitem-'+photo).innerHTML = '<div style="padding-left:5px;" >' + ArrValues[2] + '</div>'; // OK
1115
  }
1154
  }
1155
  switch (ArrValues[1]) {
1156
  case '0': // No error
1157
+ document.getElementById('remark-'+photo).innerHTML = ArrValues[2];
1158
  break;
1159
  default:
1160
+ document.getElementById('remark-'+photo).innerHTML = '<span style="color:red">'+ArrValues[2]+'</span>';
1161
  }
1162
  // Hide spinner
1163
  jQuery('#wppa-water-spin-'+photo).css({visibility:'hidden'});
1165
  wppaFeAjaxLog('out');
1166
  }
1167
  else { // status != 200
1168
+ document.getElementById('remark-'+photo).innerHTML = '<span style="color:red;" >Comm error '+xmlhttp.status+': '+xmlhttp.statusText+'</span>';
1169
  }
1170
  }
1171
  }
1172
  }
1173
 
1174
+ // Do the ajax update photo request
1175
+ function wppaAjaxUpdatePhoto( photo, actionslug, value, reload, bef, aft ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1176
 
1177
  if ( ! bef ) bef = '';
1178
  if ( ! aft ) aft = '';
1179
 
 
 
 
 
 
 
 
 
1180
  // On Front-end edit photo classic style, there is a button: Update and exit.
1181
  // Set it to the desired state
1182
  wppaFeAjaxLog('in');
1183
 
 
 
 
 
1184
  // Open ajax object
 
1185
  jQuery.ajax( { url: wppaAjaxUrl,
1186
  data: 'action=wppa&wppa-action=update-photo' +
1187
  '&photo-id=' + photo +
1194
  beforeSend: function( xhr ) {
1195
 
1196
  // Show spinner
1197
+ jQuery('#wppa-photo-spin-'+photo).css( { visibility: 'visible' } );
 
 
1198
 
1199
  // Update status
1200
+ jQuery( '#remark-' + photo ).html( 'Working, please wait...' );
1201
 
1202
  },
1203
  success: function( result, status, xhr ) {
1206
  var str = wppaTrim( result );
1207
  var ArrValues = str.split("||");
1208
 
 
 
 
1209
  // Any strange results returned?
1210
  if ( ArrValues[0] != '' ) {
1211
  alert( 'The server returned unexpected output:\n' + ArrValues[0] );
1212
  }
1213
 
1214
+ // Switch on error code
1215
  switch ( ArrValues[1] ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1216
 
1217
+ case '99': // Photo is gone
1218
+ jQuery( '#photoitem-' + photo ).html( bef+'<span style="color:red">' + ArrValues[2] + '</span>'+aft );
1219
+ break;
 
 
 
 
1220
 
1221
+ default: // No or recoverable error
1222
+
1223
+ // Extract update felds
1224
+ var updates = JSON.parse( ArrValues[2] );
1225
+ var fieldName;
1226
+ var fieldValue;
1227
+
1228
+ for ( fieldName in updates ) {
1229
+ fieldValue = updates[fieldName];
1230
+
1231
+ switch ( fieldName ) {
1232
+
1233
+ case 'remark':
1234
+ var text;
1235
+ fieldValue = fieldValue.replace(/&lt;/g,'<');
1236
+ fieldValue = fieldValue.replace(/&gt;/g,'>');
1237
+ fieldValue = fieldValue.replace(/\\/g,'');
1238
+
1239
+ if ( ArrValues[1] != "0" ) { // error
1240
+ text = '<span style="color:red;" >' + fieldValue + '</span>';
1241
+ }
1242
+ else { // no error
1243
+ text = '<span style="color:green;" >' + fieldValue + '</span>';
1244
+ }
1245
+ jQuery( "#remark-" + photo ).html( text );
1246
+ break;
1247
+
1248
+ case 'photourl':
1249
+ if ( wppaCropper[photo] ) {
1250
+ var c = wppaCropper[photo];
1251
+ c.replace(fieldValue);
1252
+ }
1253
+ else {
1254
+ jQuery( "#photourl-" + photo ).attr('src', fieldValue);
1255
+ }
1256
+ jQuery( "#thumba-" + photo ).attr('href', fieldValue);
1257
+ break;
1258
+
1259
+ case 'thumburl':
1260
+ jQuery( "#thumburl-" + photo ).attr('src', fieldValue);
1261
+ break;
1262
+
1263
+ case 'magickstack':
1264
+ jQuery( "#magickstack-" + photo ).html( fieldValue );
1265
+ if ( fieldValue.length > 0 ) {
1266
+ jQuery( '#imstackbutton-' + photo ).css( 'display', 'inline' );
1267
+ }
1268
+ else {
1269
+ jQuery( '#imstackbutton-' + photo ).css( 'display', 'none' );
1270
+ }
1271
+ break;
1272
+
1273
+ default:
1274
+ jQuery( "#" + fieldName + "-" + photo ).html( fieldValue );
1275
+ break;
1276
  }
 
 
 
 
 
 
 
 
1277
  }
1278
 
1279
  break;
1280
+
 
 
 
 
 
1281
  }
1282
 
1283
  // Hide spinner
1285
  jQuery('#wppa-photo-spin-'+photo).css( { visibility:'hidden' } );
1286
  }
1287
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1288
  // Front-end button
1289
  wppaFeAjaxLog('out');
1290
 
 
 
 
 
 
 
 
 
 
 
1291
  },
1292
  error: function( xhr, status, error ) {
1293
 
 
 
 
1294
  // Update status
1295
+ jQuery( '#remark-' + photo ).html( '<span style="color:red;" >Comm error ' + status + '</span>' );
1296
 
1297
  // Log error
1298
+ wppaConsoleLog( 'wppaAjaxUpdatePhoto failed. Error = ' + error + ', status = ' + status, 'force' );
1299
  },
1300
  complete: function( xhr, status, newurl ) {
1301
  jQuery( '#wppa-admin-spinner' ).css( 'display', 'none' );
1573
  }
1574
  switch (ArrValues[1]) {
1575
  case '0': // No error
1576
+ jQuery('#remark-'+photo).html(ArrValues[2]);
1577
  break;
1578
  default: // Error
1579
+ jQuery('#remark-'+photo).html('<span style="color:red">'+ArrValues[2]+'</span>');
1580
  break;
1581
  }
1582
  jQuery('#wppa-comment-spin-'+id).css('visibility', 'hidden');
1583
  }
1584
  else { // status != 200
1585
+ jQuery('#remark-'+photo).html('<span style="color:red;" >Comm error '+xmlhttp.status+': '+xmlhttp.statusText+'</span>');
1586
  }
1587
  }
1588
  }
js/wppa-admin-scripts.min.js CHANGED
@@ -1 +1 @@
1
- var wppaImageDirectory,wppaAjaxUrl,wppa_moveup_url="#",wppa_import="Import",wppa_update="Update",wppaUploadToThisAlbum="Upload to this album";function checkjQueryRev(e,t,p){var a=parseFloat(jQuery.fn.jquery);t.checked&&a<p&&(alert(e+"\nThe version of your jQuery library: "+a+" is too low for this feature. It requires version "+p),t.checked="")}function wppaReUpload(e,t,p){document.getElementById("wppa-re-up-form-"+t);var a=document.getElementById("wppa-re-up-file-"+t),o=document.getElementById("wppa-re-up-butn-"+t);e.preventDefault();var n=a.files[0];if(n.type.match("image.*")){if(0==p.length)alert("Filename will be set to "+n.name);else if(n.name!=p&&!confirm("Filename is different.\nIf you continue, the filename will not be updated!.\n\nContinue?"))return void jQuery("#re-up-"+t).css("display","none");o.value="Uploading...",o.style.color="black";var i=new FormData;i.append("photo",n,n.name);var s=new XMLHttpRequest,l="?action=wppa&wppa-action=update-photo&photo-id="+t+"&item=file&wppa-nonce="+document.getElementById("photo-nonce-"+t).value;s.open("POST",wppaAjaxUrl+l,!0),s.onload=function(){if(200===s.status){var e=wppaTrim(s.responseText).split("||");switch(""!=e[0]&&alert("The server returned unexpected output:\n"+e[0]),e[1]){case"0":jQuery("#photostatus-"+t).html(e[2]),o.value="Upload",jQuery("#re-up-"+t).css("display","none");break;case"99":document.getElementById("photoitem-"+t).innerHTML='<span style="color:red">'+e[2]+"</span>";break;default:document.getElementById("photostatus-"+t).innerHTML='<span style="color:red">'+e[2]+" ("+e[1]+")</span>",o.value="Error occured",o.style.color="red"}}else alert("An error occurred!")},s.send(i)}else alert("File is not an image file!")}function wppaInitSettings(){wppaCheckBreadcrumb(),wppaCheckFullHalign(),wppaCheckUseThumbOpacity(),wppaCheckUseCoverOpacity(),wppaCheckThumbType(),wppaCheckThumbLink(),wppaCheckTopTenLink(),wppaCheckFeaTenLink(),wppaCheckLasTenLink(),wppaCheckThumbnailWLink(),wppaCheckCommentLink(),wppaCheckXphotoLink(),wppaCheckMphotoLink(),wppaCheckSphotoLink(),wppaCheckSlidePhotoLink(),wppaCheckSlideOnlyLink(),wppaCheckAlbumWidgetLink(),wppaCheckSlideLink(),wppaCheckCoverImg(),wppaCheckPotdLink(),wppaCheckTagLink(),wppaCheckRating(),wppaCheckComments(),wppaCheckCustom(),wppaCheckResize(),wppaCheckNumbar(),wppaCheckWatermark(),wppaCheckPopup(),wppaCheckGravatar(),wppaCheckUserUpload(),wppaCheckAjax(),wppaCheckFotomoto(),wppaCheckLinkPageErr("sphoto"),wppaCheckLinkPageErr("mphoto"),wppaCheckLinkPageErr("xphoto"),wppaCheckLinkPageErr("topten_widget"),wppaCheckLinkPageErr("slideonly_widget"),wppaCheckLinkPageErr("potd"),wppaCheckLinkPageErr("comment_widget"),wppaCheckLinkPageErr("thumbnail_widget"),wppaCheckLinkPageErr("lasten_widget"),wppaCheckLinkPageErr("album_widget"),wppaCheckLinkPageErr("tagcloud"),wppaCheckLinkPageErr("multitag"),wppaCheckLinkPageErr("super_view"),wppaCheckSplitNamedesc(),wppaCheckShares(),wppaCheckCoverType(),wppaCheckNewpag(),wppaCheckCDN(),wppaCheckAutoPage(),wppaCheckGps(),wppaCheckFontPreview(),wppaCheckCheck("wppa_enable_video","wppa-video"),wppaCheckCheck("wppa_custom_fields","custfields"),wppaCheckCheck("wppa_album_custom_fields","albumcustfields"),wppaCheckCheck("wppa_new_mod_label_is_text","nmtxt"),wppaCheckCheck("wppa_coverphoto_responsive","cvpr"),wppaCheckSmWidgetLink();var e=new Array("O","I","II","III","IV","V","VI","VII","VIII","IX","X","XI","XII"),t=new Array("A","B","C","D","E","F","G","H","I","J","K","L","M");for(table=1;table<13;table++){var p=wppa_getCookie("table_"+table);for("on"==p?wppaShowTable(table):wppaHideTable(table),subtab=0;subtab<13;subtab++)"on"==(p=wppa_getCookie("table_"+e[table-1]+"-"+t[subtab]))&&wppaToggleSubTable(e[table-1],t[subtab]);wppaToggleSubTable(e[table-1],"Z")}}function wppaQuickSel(){var e=new Array("O","I","II","III","IV","V","VI","VII","VIII","IX","X","XI","XII"),t=new Array("A","B","C","D","E","F","G","H","I","J","K","Z");for(table=1;table<13;table++)for(table<13?wppaShowTable(table):wppaHideTable(table),wppa_tablecookieoff(table),subtab=0;subtab<12;subtab++){cookie=wppa_getCookie("table_"+e[table-1]+"-"+t[subtab]),"on"==cookie&&wppaToggleSubTable(e[table-1],t[subtab]);var p=jQuery(".wppa-"+e[table-1]+"-"+t[subtab]);0<p.length&&(p.removeClass("wppa-none"),wppaSubTabOn[e[table-1]+"-"+t[subtab]]=!1,wppa_tablecookieoff(e[table-1]+"-"+t[subtab]))}if(tag1=jQuery("#wppa-quick-selbox-1").val(),tag2=jQuery("#wppa-quick-selbox-2").val(),"-"==tag1&&"-"==tag2)for(jQuery("._wppatag-").addClass("wppa-none"),table=1;table<13;table++)wppaHideTable(table);else"-"!=tag1&&jQuery("._wppatag-"+tag1).addClass("wppa-none"),"-"!=tag2&&jQuery("._wppatag-"+tag2).addClass("wppa-none")}function wppaToggleTable(e){"none"==jQuery("#wppa_table_"+e).css("display")?(jQuery("#wppa_table_"+e).css("display","inline"),wppa_tablecookieon(e)):(jQuery("#wppa_table_"+e).css("display","none"),wppa_tablecookieoff(e))}jQuery(document).ready(function(){jQuery(window).on("DOMContentLoaded load resize scroll",wppaMakeLazyVisible),wppaMakeLazyVisible()});var wppaSubTabOn=new Array;function wppaToggleSubTable(e,t){wppaSubTabOn[e+"-"+t]?(jQuery(".wppa-"+e+"-"+t).addClass("wppa-none"),jQuery(".wppa-"+e+"-"+t+"-help").css("display","none"),wppaSubTabOn[e+"-"+t]=!1,wppa_tablecookieoff(e+"-"+t)):(jQuery(".wppa-"+e+"-"+t).removeClass("wppa-none"),jQuery(".wppa-"+e+"-"+t+"-h").css("display",""),wppaSubTabOn[e+"-"+t]=!0,wppa_tablecookieon(e+"-"+t))}function wppaHideTable(e){jQuery("#wppa_table_"+e).css("display","none"),jQuery("#wppa_tableHide-"+e).css("display","none"),jQuery("#wppa_tableShow-"+e).css("display","inline"),wppa_tablecookieoff(e)}function wppaShowTable(e){jQuery("#wppa_table_"+e).css("display","block"),jQuery("#wppa_tableHide-"+e).css("display","inline"),jQuery("#wppa_tableShow-"+e).css("display","none"),wppa_tablecookieon(e)}var _wppaRefreshAfter=!1;function wppaRefreshAfter(){_wppaRefreshAfter=!0}function wppaFollow(e,t){jQuery("#"+e).prop("checked")?jQuery("."+t).css("display",""):jQuery("."+t).css("display","none")}function wppaCheckCheck(e,t){var p=e.substring(5);document.getElementById(p).checked?(jQuery("."+t).css("display",""),jQuery(".-"+t).css("display","none")):(jQuery("."+t).css("display","none"),jQuery(".-"+t).css("display",""))}function wppaCheckSlideVideoControls(){"none"!=document.getElementById("slideshow_linktype").value&&alert("Warning! \nYou can not have video controls on a videoslide when there is a link on the slide.\nThe videoslide will not show controls and will also not autoplay")}function wppaCheckFotomoto(){document.getElementById("fotomoto_on").checked?jQuery(".wppa_fotomoto").css("display",""):jQuery(".wppa_fotomoto").css("display","none")}function wppaCheckFontPreview(){var e=document.getElementById("textual_watermark_font").value,t=document.getElementById("textual_watermark_type").value,p=wppaFontDirectory+"wmf"+e+"-"+t+".png",a=wppaFontDirectory+"wmf"+t+"-"+e+".png";jQuery("#wm-font-preview").attr("src",p),jQuery("#wm-type-preview").attr("src",a)}function wppaCheckWidgetMethod(){var e,t;if("4"==document.getElementById("wppa-wm").value){document.getElementById("wppa-wp").style.visibility="visible";var p=jQuery("#wppa-wp").val();"day-of-week"==p||"day-of-month"==p||"day-of-year"==p?jQuery(".wppa-order").css("visibility",""):jQuery(".wppa-order").css("visibility","hidden")}else document.getElementById("wppa-wp").style.visibility="hidden",jQuery(".wppa-order").css("visibility","hidden");if("1"==document.getElementById("wppa-wm").value)for(e=document.getElementsByName("wppa-widget-photo"),t=0;t<e.length;)e[t].style.visibility="visible",t++;else for(e=document.getElementsByName("wppa-widget-photo"),t=0;t<e.length;)e[t].style.visibility="hidden",t++}function wppaCheckFullHalign(){var e=document.getElementById("fullsize").value,t=document.getElementById("colwidth").value,p=document.getElementById("fullvalign").value;e!=t&&"default"!=p?jQuery(".wppa_ha").css("display",""):jQuery(".wppa_ha").css("display","none"),"auto"==t?jQuery(".wppa_init_resp_width").css("display",""):jQuery(".wppa_init_resp_width").css("display","none")}function wppaCheckCDN(){var e=document.getElementById("cdn_service").value;"cloudinary"==e||"cloudinarymaintenance"==e?jQuery(".cloudinary").css("display",""):jQuery(".cloudinary").css("display","none")}function wppaCheckGps(){"wppa-plus-embedded"==document.getElementById("gpx_implementation").value?(jQuery(".wppa_gpx_native").css("display",""),jQuery(".wppa_gpx_plugin").css("display","none")):(jQuery(".wppa_gpx_native").css("display","none"),jQuery(".wppa_gpx_plugin").css("display",""))}function wppaCheckThumbType(){var e=document.getElementById("thumbtype").value;"default"==e&&(jQuery(".tt_normal").css("display",""),jQuery(".tt_ascovers").css("display","none"),jQuery(".tt_always").css("display",""),wppaCheckUseThumbOpacity()),"ascovers"!=e&&"ascovers-mcr"!=e||(jQuery(".tt_normal").css("display","none"),jQuery(".tt_ascovers").css("display",""),jQuery(".tt_always").css("display","")),"masonry"==e&&(jQuery(".tt_normal").css("display","none"),jQuery(".tt_ascovers").css("display","none"),jQuery(".tt_always").css("display",""),jQuery(".tt_masonry").css("display",""))}function wppaCheckAutoPage(){document.getElementById("auto_page").checked?jQuery(".autopage").css("display",""):jQuery(".autopage").css("display","none")}function wppaCheckUseThumbOpacity(){document.getElementById("use_thumb_opacity").checked?(jQuery(".thumb_opacity").css("color","#333"),jQuery(".thumb_opacity_html").css("visibility","visible")):(jQuery(".thumb_opacity").css("color","#999"),jQuery(".thumb_opacity_html").css("visibility","hidden"))}function wppaCheckUseCoverOpacity(){document.getElementById("use_cover_opacity").checked?(jQuery(".cover_opacity").css("color","#333"),jQuery(".cover_opacity_html").css("visibility","visible")):(jQuery(".cover_opacity").css("color","#999"),jQuery(".cover_opacity_html").css("visibility","hidden"))}function wppaCheckBreadcrumb(){var e=document.getElementById("show_bread_posts").checked,t=document.getElementById("show_bread_pages").checked;if(e||t){jQuery(".wppa_bc").css("display",""),jQuery(".wppa_bc_html").css("display","");var p=document.getElementById("bc_separator").value;"txt"==p?(jQuery(".wppa_bc_txt").css("display",""),jQuery(".wppa_bc_url").css("display","none"),jQuery(".wppa_bc_txt_html").css("display",""),jQuery(".wppa_bc_url_html").css("display","none")):"url"==p?(jQuery(".wppa_bc_txt").css("display","none"),jQuery(".wppa_bc_url").css("display",""),jQuery(".wppa_bc_txt_html").css("display","none"),jQuery(".wppa_bc_url_html").css("display","")):(jQuery(".wppa_bc_txt").css("display","none"),jQuery(".wppa_bc_url").css("display","none"))}else jQuery(".wppa_bc").css("display","none"),jQuery(".wppa_bc_txt").css("display","none"),jQuery(".wppa_bc_url").css("display","none")}function wppaCheckRating(){document.getElementById("rating_on").checked?(jQuery(".wppa_rating").css("color","#333"),jQuery(".wppa_rating_html").css("visibility","visible"),jQuery(".wppa_rating_").css("display","")):(jQuery(".wppa_rating").css("color","#999"),jQuery(".wppa_rating_html").css("visibility","hidden"),jQuery(".wppa_rating_").css("display","none"))}function wppaCheckComments(){document.getElementById("show_comments").checked?(jQuery(".wppa_comment").css("color","#333"),jQuery(".wppa_comment_html").css("visibility","visible"),jQuery(".wppa_comment_").css("display","")):(jQuery(".wppa_comment").css("color","#999"),jQuery(".wppa_comment_html").css("visibility","hidden"),jQuery(".wppa_comment_").css("display","none"))}function wppaCheckAjax(){document.getElementById("allow_ajax").checked?jQuery(".wppa_allow_ajax_").css("display",""):jQuery(".wppa_allow_ajax_").css("display","none")}function wppaCheckShares(){document.getElementById("share_on").checked||document.getElementById("share_on_widget").checked||document.getElementById("share_on_lightbox").checked||document.getElementById("share_on_thumbs").checked||document.getElementById("share_on_mphoto").checked?jQuery(".wppa_share").css("display",""):jQuery(".wppa_share").css("display","none")}function wppaCheckCoverType(){var e=document.getElementById("cover_type").value;document.getElementById("coverphoto_pos").value;"imagefactory"==e||"imagefactory-mcr"==e?jQuery(".wppa_imgfact_").css("display",""):jQuery(".wppa_imgfact_").css("display","none")}function wppaCheckNewpag(){document.getElementById("newpag_create").checked?jQuery(".wppa_newpag").css("display",""):jQuery(".wppa_newpag").css("display","none")}function wppaCheckCustom(){document.getElementById("custom_on").checked?(jQuery(".wppa_custom").css("color","#333"),jQuery(".wppa_custom_html").css("visibility","visible"),jQuery(".wppa_custom_").css("display","")):(jQuery(".wppa_custom").css("color","#999"),jQuery(".wppa_custom_html").css("visibility","hidden"),jQuery(".wppa_custom_").css("display","none"))}function wppaCheckWidgetLink(){"-1"==document.getElementById("wlp").value?(jQuery(".wppa_wlu").css("display",""),jQuery(".wppa_wlt").css("visibility","hidden")):(jQuery(".wppa_wlu").css("display","none"),jQuery(".wppa_wlt").css("visibility","visible"))}function wppaCheckSmWidgetLink(){"home"==document.getElementById("widget_sm_linktype").value?jQuery(".wppa_smrp").css("visibility","hidden"):jQuery(".wppa_smrp").css("visibility","")}function wppaCheckThumbLink(){var e=document.getElementById("thumb_linktype").value;"none"==e||"file"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_tlp").css("visibility","hidden"):jQuery(".wppa_tlp").css("visibility","visible"),"none"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_tlb").css("visibility","hidden"):jQuery(".wppa_tlb").css("visibility","visible")}function wppaCheckTopTenLink(){var e=document.getElementById("topten_widget_linktype").value;"none"==e||"file"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_ttlp").css("visibility","hidden"):jQuery(".wppa_ttlp").css("visibility","visible"),"none"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_ttlb").css("visibility","hidden"):jQuery(".wppa_ttlb").css("visibility","visible")}function wppaCheckFeaTenLink(){var e=document.getElementById("featen_widget_linktype").value;"none"==e||"file"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_ftlp").css("visibility","hidden"):jQuery(".wppa_ftlp").css("visibility","visible"),"none"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_ftlb").css("visibility","hidden"):jQuery(".wppa_ftlb").css("visibility","visible")}function wppaCheckLasTenLink(){var e=document.getElementById("lasten_widget_linktype").value;"none"==e||"file"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_ltlp").css("visibility","hidden"):jQuery(".wppa_ltlp").css("visibility","visible"),"none"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_ltlb").css("visibility","hidden"):jQuery(".wppa_ltlb").css("visibility","visible")}function wppaCheckThumbnailWLink(){var e=document.getElementById("thumbnail_widget_linktype").value;"none"==e||"file"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_tnlp").css("visibility","hidden"):jQuery(".wppa_tnlp").css("visibility","visible"),"none"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_tnlb").css("visibility","hidden"):jQuery(".wppa_tnlb").css("visibility","visible")}function wppaCheckCommentLink(){var e=document.getElementById("comment_widget_linktype").value;"none"==e||"file"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_cmlp").css("visibility","hidden"):jQuery(".wppa_cmlp").css("visibility","visible"),"none"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_cmlb").css("visibility","hidden"):jQuery(".wppa_cmlb").css("visibility","visible")}function wppaCheckSlideOnlyLink(){var e=document.getElementById("slideonly_widget_linktype").value;"none"==e||"file"==e||"widget"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_solp").css("visibility","hidden"):jQuery(".wppa_solp").css("visibility","visible"),"none"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_solb").css("visibility","hidden"):jQuery(".wppa_solb").css("visibility","visible")}function wppaCheckAlbumWidgetLink(){var e=document.getElementById("album_widget_linktype").value;"lightbox"==e?jQuery(".wppa_awlp").css("visibility","hidden"):jQuery(".wppa_awlp").css("visibility","visible"),"lightbox"==e?jQuery(".wppa_awlb").css("visibility","hidden"):jQuery(".wppa_awlb").css("visibility","visible")}function wppaCheckSlideLink(){var e=document.getElementById("slideshow_linktype").value;"none"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_sslb").css("visibility","hidden"):jQuery(".wppa_sslb").css("visibility","visible")}function wppaCheckCoverImg(){var e=document.getElementById("coverimg_linktype").value;"none"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_covimgbl").css("visibility","hidden"):jQuery(".wppa_covimgbl").css("visibility","visible")}function wppaCheckPotdLink(){var e=document.getElementById("potd_linktype").value;"none"==e||"lightbox"==e||"file"==e||"custom"==e?jQuery(".wppa_potdlp").css("visibility","hidden"):jQuery(".wppa_potdlp").css("visibility","visible"),"none"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_potdlb").css("visibility","hidden"):jQuery(".wppa_potdlb").css("visibility","visible")}function wppaCheckTagLink(){document.getElementById("tagcloud_linktype").value}function wppaCheckMTagLink(){document.getElementById("multitag_linktype").value}function wppaCheckXphotoLink(){var e=document.getElementById("xphoto_linktype").value;"none"==e||"file"==e||"lightbox"==e?jQuery(".wppa_xlp").css("visibility","hidden"):jQuery(".wppa_xlp").css("visibility","visible"),"none"==e||"lightbox"==e?jQuery(".wppa_xlb").css("visibility","hidden"):jQuery(".wppa_xlb").css("visibility","visible")}function wppaCheckMphotoLink(){var e=document.getElementById("mphoto_linktype").value;"none"==e||"file"==e||"lightbox"==e?jQuery(".wppa_mlp").css("visibility","hidden"):jQuery(".wppa_mlp").css("visibility","visible"),"none"==e||"lightbox"==e?jQuery(".wppa_mlb").css("visibility","hidden"):jQuery(".wppa_mlb").css("visibility","visible")}function wppaCheckSphotoLink(){var e=document.getElementById("sphoto_linktype").value;"none"==e||"file"==e||"lightbox"==e?jQuery(".wppa_slp").css("visibility","hidden"):jQuery(".wppa_slp").css("visibility","visible"),"none"==e||"lightbox"==e?jQuery(".wppa_slb").css("visibility","hidden"):jQuery(".wppa_slb").css("visibility","visible")}function wppaCheckSlidePhotoLink(){var e=document.getElementById("slideshow_linktype").value;"none"==e||"file"==e||"lightbox"==e||"lightboxsingle"==e||"fullpopup"==e?jQuery(".wppa_sslp").css("visibility","hidden"):jQuery(".wppa_sslp").css("visibility","visible"),"none"==e||"lightbox"==e||"lightboxsingle"==e||"fullpopup"==e?jQuery(".wppa_sslb").css("visibility","hidden"):jQuery(".wppa_sslb").css("visibility","visible")}function wppaCheckResize(){document.getElementById("resize_on_upload").checked?jQuery(".re_up").css("display",""):jQuery(".re_up").css("display","none")}function wppaCheckNumbar(){document.getElementById("show_slideshownumbar").checked?jQuery(".wppa_numbar").css("display",""):jQuery(".wppa_numbar").css("display","none")}function wppaCheckWatermark(){document.getElementById("watermark_on").checked?jQuery(".wppa_watermark").css("display",""):jQuery(".wppa_watermark").css("display","none")}function wppaCheckPopup(){document.getElementById("use_thumb_popup").checked?jQuery(".wppa_popup").css("display",""):jQuery(".wppa_popup").css("display","none")}function wppaCheckGravatar(){document.getElementById("comment_gravatar")&&("url"==document.getElementById("comment_gravatar").value?jQuery(".wppa_grav").css("display",""):jQuery(".wppa_grav").css("display","none"))}function wppaCheckUserUpload(){document.getElementById("user_upload_on").checked?jQuery(".wppa_feup").css("display",""):jQuery(".wppa_feup").css("display","none")}function wppaCheckSplitNamedesc(){document.getElementById("split_namedesc").checked?(jQuery(".swap_namedesc").css("display","none"),jQuery(".hide_empty").css("display","")):(jQuery(".swap_namedesc").css("display",""),jQuery(".hide_empty").css("display","none"))}function wppa_tablecookieon(e){wppa_setCookie("table_"+e,"on","365")}function wppa_tablecookieoff(e){wppa_setCookie("table_"+e,"off","365")}function wppaCookieCheckbox(e,t){e.checked?wppa_setCookie(t,"on","365"):wppa_setCookie(t,"off","365")}function wppa_move_up(e){document.location=wppa_moveup_url+e+"&wppa-nonce="+document.getElementById("wppa-nonce").value}function checkColor(e){var t=e.substr(5),p=jQuery("#"+t).val();jQuery("#colorbox-"+t).css("background-color",p)}function checkAll(e,t){var p=document.getElementById(e);p&&(p.checked?jQuery(t).prop("checked","checked"):jQuery(t).prop("checked",""))}function impUpd(e,t){e.checked?(jQuery(t).prop("value",wppa_update),jQuery(".hideifupdate").css("display","none")):(jQuery(t).prop("value",wppa_import),jQuery(".hideifupdate").css("display",""))}function wppaAjaxDeletePhoto(t,e,p){var a="",o="";a=e||'<div style="padding-left:5px;" >',p?o=p:aftrer="</div>",wppaFeAjaxLog("in");var n=wppaGetXmlHttp(),i=wppaAjaxUrl+"?action=wppa&wppa-action=delete-photo&photo-id="+t;i+="&wppa-nonce="+document.getElementById("photo-nonce-"+t).value,n.open("GET",i,!0),n.send(),n.onreadystatechange=function(){switch(n.readyState){case 1:document.getElementById("photostatus-"+t).innerHTML="server connection established";break;case 2:document.getElementById("photostatus-"+t).innerHTML="request received";break;case 3:document.getElementById("photostatus-"+t).innerHTML="processing request";break;case 4:if(200==n.status){var e=wppaTrim(n.responseText).split("||");"ER"==e[0]?(e[3]&&alert(e[3]),jQuery("#wppa-delete-"+t).css("text-decoration","line-through")):""!=e[0]&&alert("The server returned unexpected output:\n"+e[0]),0==e[1]?document.getElementById("photostatus-"+t).innerHTML=e[2]:(document.getElementById("photoitem-"+t).innerHTML=a+e[2]+o,wppaProcessFull(e[3],e[4])),jQuery(window).trigger("scroll"),wppaFeAjaxLog("out")}else document.getElementById("photoitem-"+t).innerHTML=a+'<span style="color:red;" >Comm error '+n.status+": "+n.statusText+"</span>"+o}}}function wppaAjaxUndeletePhoto(t){wppaFeAjaxLog("in");var p=wppaGetXmlHttp(),e=wppaAjaxUrl+"?action=wppa&wppa-action=undelete-photo&photo-id="+t;e+="&wppa-nonce="+document.getElementById("photo-nonce-"+t).value,p.open("GET",e,!0),p.send(),p.onreadystatechange=function(){switch(p.readyState){case 1:document.getElementById("photostatus-"+t).innerHTML="server connection established";break;case 2:document.getElementById("photostatus-"+t).innerHTML="request received";break;case 3:document.getElementById("photostatus-"+t).innerHTML="processing request";break;case 4:if(200==p.status){var e=wppaTrim(p.responseText).split("||");"ER"==e[0]?(e[3]&&alert(e[3]),jQuery("#wppa-delete-"+t).css("text-decoration","line-through")):""!=e[0]&&alert("The server returned unexpected output:\n"+e[0]),0==e[1]?document.getElementById("photostatus-"+t).innerHTML=e[2]:document.getElementById("photoitem-"+t).innerHTML='<div style="padding-left:5px;" >'+e[2]+"</div>",wppaFeAjaxLog("out")}else document.getElementById("photoitem-"+t).innerHTML=before+'<span style="color:red;" >Comm error '+p.status+": "+p.statusText+"</span>"+after}}}function wppaAjaxApplyWatermark(t,e,p){wppaFeAjaxLog("in");var a=wppaGetXmlHttp();jQuery("#wppa-water-spin-"+t).css({visibility:"visible"});var o="action=wppa&wppa-action=watermark-photo&photo-id="+t;o+="&wppa-nonce="+document.getElementById("photo-nonce-"+t).value,e&&(o+="&wppa-watermark-file="+e),p&&(o+="&wppa-watermark-pos="+p),a.open("POST",wppaAjaxUrl,!0),a.setRequestHeader("Content-type","application/x-www-form-urlencoded"),a.send(o),a.onreadystatechange=function(){if(4==a.readyState)if(200==a.status){var e=wppaTrim(a.responseText).split("||");switch(""!=e[0]&&alert("The server returned unexpected output:\n"+e[0]),e[1]){case"0":document.getElementById("photostatus-"+t).innerHTML=e[2];break;default:document.getElementById("photostatus-"+t).innerHTML='<span style="color:red">'+e[2]+"</span>"}jQuery("#wppa-water-spin-"+t).css({visibility:"hidden"}),wppaFeAjaxLog("out")}else document.getElementById("photostatus-"+t).innerHTML='<span style="color:red;" >Comm error '+a.status+": "+a.statusText+"</span>"}}var wppaAjaxPhotoCount=new Array,wppaPhotoUpdateMatrix=new Array;function wppaAjaxUpdatePhoto(e,t,p,a,o){var n=!1;o&&(n=0==jQuery("#wppaphotodesc"+o+":visible").length,jQuery("#wppaphotodesc"+o+"-html").click(),n&&jQuery("#wppaphotodesc"+o+"-tmce").click());for(var i=wppaPhotoUpdateMatrix.length,s=0,l=!1,r=-1;s<i;)wppaPhotoUpdateMatrix[s][0]==e&&wppaPhotoUpdateMatrix[s][1]==t&&(l=!0,r=s),s++;if(!l){wppaPhotoUpdateMatrix[i]=[e,t,"undefined",!1,!1,a],r=i}wppaPhotoUpdateMatrix[r][3]="number"==typeof p?p:p.value,wppaPhotoUpdateMatrix[r][5]=a,wppaAjaxUpdatePhotoMonitor()}function wppaAjaxUpdateDelphoto(e,t,p){wppaAjaxUpdatePhoto(e,"del"+t,p)}function wppaAjaxUpdatePhotoMonitor(){for(var e=wppaPhotoUpdateMatrix.length,t=0;t<e;)wppaPhotoUpdateMatrix[t][2]==wppaPhotoUpdateMatrix[t][3]||wppaPhotoUpdateMatrix[t][4]||(wppaPhotoUpdateMatrix[t][4]=!0,_wppaAjaxUpdatePhoto(wppaPhotoUpdateMatrix[t][0],wppaPhotoUpdateMatrix[t][1],wppaPhotoUpdateMatrix[t][3],wppaPhotoUpdateMatrix[t][5])),t++}function _wppaAjaxUpdatePhoto(s,l,r,u,c,d){c||(c=""),d||(d="");wppaFeAjaxLog("in"),wppaAjaxPhotoCount[s]||(wppaAjaxPhotoCount[s]=0),wppaAjaxPhotoCount[s]++,jQuery.ajax({url:wppaAjaxUrl,data:"action=wppa&wppa-action=update-photo&photo-id="+s+"&item="+l+"&wppa-nonce="+document.getElementById("photo-nonce-"+s).value+"&value="+wppaEncode(r),async:!0,type:"POST",timeout:6e4,beforeSend:function(e){"description"==l&&jQuery("#wppa-photo-spin-"+s).css({visibility:"visible"}),jQuery("#photostatus-"+s).html("Working, please wait... ("+wppaAjaxPhotoCount[s]+")")},success:function(e,t,p){var a=wppaTrim(e).split("||");switch(wppaAjaxPhotoCount[s]--,""!=a[0]&&alert("The server returned unexpected output:\n"+a[0]),a[1]){case"0":var o;if(0==wppaAjaxPhotoCount[s]?jQuery("#photostatus-"+s).html(a[2]):jQuery("#photostatus-"+s).html("Working, please wait... ("+wppaAjaxPhotoCount[s]+")"),a[3])(o=jQuery("#fs-a-"+s).attr("href").split("="))[1]=parseInt(o[1])+1,jQuery("#fs-a-"+s).attr("href",o[0]+"="+o[1]),jQuery("#fs-img-"+s).attr("src",o[0]+"="+o[1]);if(a[4])(o=jQuery("#tnp-"+s).attr("src").split("="))[1]=parseInt(o[1])+1,jQuery("#tnp-"+s).attr("src",o[0]+"="+o[1]);void 0!==a[5]&&(jQuery("#imstack-"+s).html(a[5]),0<a[5].length?jQuery("#imstackbutton-"+s).css("display",""):jQuery("#imstackbutton-"+s).css("display","none")),void 0!==a[6]&&jQuery("#dispfileinfo-"+s).html(a[6]);break;case"99":jQuery("#photoitem-"+s).html(c+'<span style="color:red">'+a[2]+"</span>"+d);break;default:jQuery("#photostatus-"+s).html('<span style="color:red">'+a[2]+" ("+a[1]+")</span>")}"description"==l&&jQuery("#wppa-photo-spin-"+s).css({visibility:"hidden"});var n=0,i=-1;for(count=wppaPhotoUpdateMatrix.length;n<count;)wppaPhotoUpdateMatrix[n][0]==s&&wppaPhotoUpdateMatrix[n][1]==l&&(i=n),n++;if(wppaPhotoUpdateMatrix[i]&&(wppaPhotoUpdateMatrix[i][2]=r||0,wppaPhotoUpdateMatrix[i][4]=!1,wppaPhotoUpdateMatrix[i][5]=!1),wppaFeAjaxLog("out"),wppaAjaxUpdatePhotoMonitor(),u&&"0"==a[1])return jQuery("#photostatus-"+s).after('<span style="color:blue;font-weight:bold;"> Reloading...</span>'),jQuery("#wppa-photo-spin-"+s).css({visibility:"visible"}),void setTimeout(function(){wppaReload("#photo_"+s)},1e3)},error:function(e,t,p){wppaAjaxPhotoCount[s]--,jQuery("#photostatus-"+s).html('<span style="color:red;" >Comm error '+t+"</span>"),wppaConsoleLog("_wppaAjaxUpdatePhoto failed. Error = "+p+", status = "+t,"force")},complete:function(e,t,p){jQuery("#wppa-admin-spinner").css("display","none"),jQuery(window).trigger("scroll")}})}function wppaChangeScheduleAlbum(e,t){jQuery(t).prop("checked")?jQuery(".wppa-datetime-"+e).css("display","inline"):(jQuery(".wppa-datetime-"+e).css("display","none"),wppaAjaxUpdateAlbum(e,"scheduledtm",document.getElementById("wppa-dummy")))}_wppaRefreshAfter=!1;var wppaAjaxAlbumCount=0,wppaAlbumUpdateMatrix=new Array;function wppaAjaxUpdateAlbum(e,t,p,a){var o=0==jQuery("#wppaalbumdesc:visible").length;jQuery("#wppaalbumdesc-html").click();for(var n=wppaAlbumUpdateMatrix.length,i=0,s=!1,l=-1;i<n;)wppaAlbumUpdateMatrix[i][0]==e&&wppaAlbumUpdateMatrix[i][1]==t&&(s=!0,l=i),i++;if(!s){wppaAlbumUpdateMatrix[n]=[e,t,"undefined",!1,!1,a],l=n}wppaAlbumUpdateMatrix[l][3]="number"==typeof p?p:p.value,wppaAlbumUpdateMatrix[l][5]=a,wppaAjaxUpdateAlbumMonitor(o)}function wppaAjaxUpdateAlbumMonitor(e){for(var t=wppaAlbumUpdateMatrix.length,p=0;p<t;)wppaAlbumUpdateMatrix[p][2]==wppaAlbumUpdateMatrix[p][3]||wppaAlbumUpdateMatrix[p][4]||(wppaAlbumUpdateMatrix[p][4]=!0,_wppaAjaxUpdateAlbum(wppaAlbumUpdateMatrix[p][0],wppaAlbumUpdateMatrix[p][1],wppaAlbumUpdateMatrix[p][3],e,wppaAlbumUpdateMatrix[p][5])),p++;e&&jQuery("#wppaalbumdesc-tmce").click()}function _wppaAjaxUpdateAlbum(s,l,r,u,c){wppaAjaxAlbumCount++;jQuery.ajax({url:wppaAjaxUrl,data:"action=wppa&wppa-action=update-album&album-id="+s+"&item="+l+"&wppa-nonce="+document.getElementById("album-nonce-"+s).value+"&value="+wppaEncode(r),async:!0,type:"POST",timeout:6e4,beforeSend:function(e){"description"==l&&jQuery("#wppa-album-spin").css({visibility:"visible"}),jQuery("#albumstatus-"+s).html("Working, please wait... ("+wppaAjaxAlbumCount+")")},success:function(e,t,p){var a=wppaTrim(e).split("||");switch(wppaAjaxAlbumCount--,""!=a[0]&&alert("The server returned unexpected output:\n"+a[0]),a[1]){case"0":0==wppaAjaxAlbumCount?jQuery("#albumstatus-"+s).html(a[2]):jQuery("#albumstatus-"+s).html("Working, please wait... ("+wppaAjaxAlbumCount+")");break;default:jQuery("#albumstatus-"+s).html='<span style="color:red">'+a[2]+" ("+a[1]+")</span>"}if(void 0!==a[3]&&wppaProcessFull(a[3],a[4]),c&&"0"==a[1])return jQuery("#albumstatus-"+s).after('<span style="color:blue;font-weight:bold;"> Reloading...</span>'),jQuery("#wppa-admin-spinner").fadeIn(),void setTimeout(function(){wppaReload()},100);"description"==l&&jQuery("#wppa-album-spin").css({visibility:"hidden"});for(var o=0,n=-1,i=wppaAlbumUpdateMatrix.length;o<i;)wppaAlbumUpdateMatrix[o][0]==s&&wppaAlbumUpdateMatrix[o][1]==l&&(n=o),o++;wppaAlbumUpdateMatrix[n][2]=r||0,wppaAlbumUpdateMatrix[n][4]=!1,wppaAlbumUpdateMatrix[n][5]=!1,wppaAjaxUpdateAlbumMonitor(u)},error:function(e,t,p){wppaAjaxAlbumCount--,jQuery("#albumstatus-"+s).html('<span style="color:red;" >Comm error '+t+"</span>"),wppaConsoleLog("_wppaAjaxUpdateAlbum failed. Error = "+p+", status = "+t,"force")},complete:function(e,t,p){}})}function wppaProcessFull(e,t){"full"==e&&(jQuery("#full").css("display",""),jQuery("#notfull").css("display","none")),"notfull"==e&&(jQuery("#full").css("display","none"),0<t?jQuery("#notfull").attr("value",wppaUploadToThisAlbum+" (max "+t+")"):jQuery("#notfull").attr("value",wppaUploadToThisAlbum),jQuery("#notfull").css("display",""))}function wppaAjaxUpdateCommentStatus(t,p,e){var a=wppaGetXmlHttp(),o=wppaAjaxUrl+"?action=wppa&wppa-action=update-comment-status&wppa-photo-id="+t+"&wppa-comment-id="+p+"&wppa-comment-status="+e+"&wppa-nonce="+document.getElementById("photo-nonce-"+t).value;a.onreadystatechange=function(){if(4==a.readyState)if(200==a.status){var e=wppaTrim(a.responseText).split("||");switch(""!=e[0]&&alert("The server returned unexpected output:\n"+e[0]),e[1]){case"0":jQuery("#photostatus-"+t).html(e[2]);break;default:jQuery("#photostatus-"+t).html('<span style="color:red">'+e[2]+"</span>")}jQuery("#wppa-comment-spin-"+p).css("visibility","hidden")}else jQuery("#photostatus-"+t).html('<span style="color:red;" >Comm error '+a.status+": "+a.statusText+"</span>")},a.open("GET",o,!0),a.send()}function wppaAjaxUpdateOptionCheckBox(t,e){var p=wppaGetXmlHttp(),a=wppaAjaxUrl+"?action=wppa&wppa-action=update-option&wppa-option="+t;a+="&wppa-nonce="+document.getElementById("wppa-nonce").value,e.checked?a+="&value=yes":a+="&value=no",p.onreadystatechange=function(){switch(p.readyState){case 1:case 2:case 3:jQuery("#img_"+t).attr("src",wppaImageDirectory+"spinner.gif");break;case 4:var e=wppaTrim(p.responseText).split("||");if(""!=e[0]&&alert("The server returned unexpected output:\n"+e[0]),404!=p.status)switch(e[1]){case"0":jQuery("#img_"+t).attr("src",wppaImageDirectory+"tick.png"),jQuery("#img_"+t).attr("title",e[2]),e[3]&&alert(e[3]),_wppaRefreshAfter&&(_wppaRefreshAfter=!1,document.location.reload(!0));break;default:jQuery("#img_"+t).attr("src",wppaImageDirectory+"cross.png"),jQuery("#img_"+t).attr("title","Error #"+e[1]+", message: "+e[2]+", status: "+p.status),e[3]&&alert(e[3]),_wppaRefreshAfter&&(_wppaRefreshAfter=!1,document.location.reload(!0))}else jQuery("#img_"+t).attr("src",wppaImageDirectory+"cross.png"),jQuery("#img_"+t).attr("title","Communication error, status = "+p.status);wppaCheckInconsistencies()}},p.open("GET",a,!0),p.send()}var wppaAlwaysContinue=100;function wppaMaintenanceProc(o,e,i){if(i);else if(!e&&"yes"==document.getElementById(o+"_continue").value)return document.getElementById(o+"_continue").value="no",document.getElementById(o+"_button").value="Start!",void(0<jQuery("#"+o+"_togo").html()&&(jQuery("#"+o+"_status").html("Pausing..."),jQuery("#"+o+"_button").css("display","none")));i||(document.getElementById(o+"_continue").value="yes",document.getElementById(o+"_button").value="Stop!",""==jQuery("#"+o+"_status").html()&&jQuery("#"+o+"_status").html("Wait...")),jQuery.ajax({url:wppaAjaxUrl,data:"action=wppa&wppa-action=maintenance&slug="+o+"&wppa-nonce="+jQuery("#wppa-nonce").val()+(i?"&wppa-cron":""),async:!0,type:"POST",timeout:3e5,beforeSend:function(e){},success:function(e,t,p){var a=e.split("||"),o=a[1],n=!1;return o?(10<a[0].length&&(alert("An error occurred:\n"+a[0]),n=!0),jQuery("#"+o+"_status").html(a[2]),jQuery("#"+o+"_togo").html(a[3]),jQuery("#"+o+"_button").css("display",""),n||"0"==a[3]?"reload"==a[4]?(alert("This page will now be reloaded to finish the operation. Please stay tuned..."),void wppaReload()):void setTimeout("wppaMaintenanceProc('"+o+"', false)",20):void("yes"!=document.getElementById(o+"_continue").value?i||jQuery("#"+o+"_status").html("Pending"):setTimeout("wppaMaintenanceProc('"+o+"', true)",20))):(alert("The server returned unexpected output:\n"+e+"\nIf the current procedure has a Skip One button, press it before retrying. Reloading page..."),void wppaReload())},error:function(e,t,p){wppaConsoleLog("wppaMaintenanceProc failed. Slug = "+o+", Error = "+p+", status = "+t,"force"),jQuery("#"+o+"_status").html("Server error #"+(11-wppaAlwaysContinue));var a=!1;--wppaAlwaysContinue<1&&(a=confirm("10 Server errors happened.\nDo you want to continue?"))&&(wppaAlwaysContinue=100),(a||0<wppaAlwaysContinue)&&("wppa_remake"==o&&wppaAjaxUpdateOptionValue("wppa_remake_skip_one",0),"wppa_regen_thumbs"==o&&wppaAjaxUpdateOptionValue("wppa_regen_thumbs_skip_one",0),"wppa_create_o1_files"==o&&wppaAjaxUpdateOptionValue("wppa_create_o1_files_skip_one",0),setTimeout("wppaMaintenanceProc('"+o+"', true)",2e3))},complete:function(e,t,p){}})}function wppaAjaxPopupWindow(e){switch(e){case"wppa_list_index":"Search index table";break;case"wppa_list_errorlog":"WPPA+ Error log";break;case"wppa_list_rating":"Recent ratings";break;case"wppa_list_session":"Active sessions";break;case"wppa_list_comments":"Recent comments"}var t=.9*wppaWindowWidth(),p=wppaGetXmlHttp(),a=wppaAjaxUrl,o="action=wppa&wppa-action=maintenancepopup&slug="+e;if(o+="&wppa-nonce="+document.getElementById("wppa-nonce").value,p.open("POST",a,!1),p.setRequestHeader("Content-type","application/x-www-form-urlencoded"),p.send(o),4==p.readyState&&200==p.status){var n=wppaEntityDecode(p.responseText).split("|"),i=n[0];n[0]="";var s=n.join("|").substring(1),l={modal:!0,resizable:!0,width:t,show:{effect:"fadeIn",duration:800},closeText:wppaCloseText};jQuery("#wppa-modal-container").html(s).dialog(l).dialog("open"),jQuery(".ui-dialog").css({boxShadow:"0px 0px 5px 5px #aaaaaa",padding:"8px",backgroundColor:"#cccccc",boxSizing:"content-box",zIndex:"9999"}),jQuery(".ui-dialog-titlebar").css({lineHeight:"0px",height:"24px"}),jQuery(".ui-dialog-title").html("<h2>"+i+"</h2>"),jQuery(".ui-button").css({position:"absolute",top:"12px",right:"12px"}),jQuery(".ui-button").attr("title",wppaCloseText)}}function wppaAjaxUpdateOptionValue(r,e,t){var p="action=wppa&wppa-action=update-option&wppa-option="+wppaEncode(r)+"&wppa-nonce="+document.getElementById("wppa-nonce").value;0!=e&&(p+="number"==typeof e?"&value="+e:t?"&value="+wppaGetSelectionEnumByClass("."+r,","):"&value="+wppaEncode(e.value)),jQuery.ajax({url:wppaAjaxUrl,data:p,async:!0,type:"POST",timeout:1e5,beforeSend:function(e){jQuery("#img_"+r.replace("#","H")).attr("src",wppaImageDirectory+"spinner.gif")},success:function(e,t,p){var a=wppaTrim(e).split("||");if(""!=a[0])alert("The server returned unexpected output:\n"+a[0]);else{switch(a[1]){case"0":jQuery("#img_"+r.replace("#","H")).attr("src",wppaImageDirectory+"tick.png"),a[3]&&alert(a[3]),_wppaRefreshAfter&&(_wppaRefreshAfter=!1,document.location.reload(!0));break;default:jQuery("#img_"+r.replace("#","H")).attr("src",wppaImageDirectory+"cross.png"),a[3]&&alert(a[3])}if(jQuery("#img_"+r.replace("#","H")).attr("title",a[2]),a[4])for(var o,n,i,s=a[4].split(";"),l=0;l<s.length;)o=s[l].split(":"),n=jQuery("#"+o[0]).html(),i=o[1],""!=n&&""==i&&(i='<input type="button" class="button-secundary" style="border-radius:3px;font-size:11px;height:18px;margin: 0 4px;padding:0px;color:red;background-color:pink;" onclick="document.location.reload(true)" value="Reload" />'),jQuery("#"+o[0]).html(i),l++}},error:function(e){jQuery("#img_"+r.replace("#","H")).attr("src",wppaImageDirectory+"cross.png"),document.getElementById("img_"+r).title="Communication error"},complete:function(e){wppaCheckInconsistencies(),"spinner_shape"!=r&&"icon_corner_style"!=r||(wppaAjaxGetSpinnerHtml("normal","wppa-spin-pre-1"),wppaAjaxGetSpinnerHtml("lightbox","wppa-spin-pre-2")),"svg_color"!=r&&"svg_bg_color"!=r||wppaAjaxGetSpinnerHtml("normal","wppa-spin-pre-1"),"ovl_svg_color"!=r&&"ovl_svg_bg_color"!=r||wppaAjaxGetSpinnerHtml("lightbox","wppa-spin-pre-2")}})}function wppaEncode(e){var t;if(void 0!==e){if("number"==typeof e)return e;var p=(t=(t=e.replace(/#/g,"||HASH||")).replace(/&/g,"||AMP||")).split("+"),a=0;for(t="";a<p.length;)t+=p[a],++a<p.length&&(t+="||PLUS||");return t}}function wppaCheckInconsistencies(){jQuery("#use_thumb_popup").prop("checked")&&"lightbox"==jQuery("#thumb_linktype").val()?jQuery(".popup-lightbox-err").css("display",""):jQuery(".popup-lightbox-err").css("display","none")}function wppaGetXmlHttp(){return window.XMLHttpRequest?xmlhttp=new XMLHttpRequest:xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"),xmlhttp}function wppaPhotoStatusChange(e){if(jQuery("#psdesc-"+e).css({display:"none"}),jQuery("#status-"+e)){if(elm=document.getElementById("status-"+e),"pending"!=elm.value&&"scheduled"!=elm.value||jQuery("#photoitem-"+e).css({backgroundColor:"#ffebe8",borderColor:"#cc0000"}),"publish"==elm.value&&jQuery("#photoitem-"+e).css({backgroundColor:"#ffffe0",borderColor:"#e6db55"}),"featured"==elm.value){jQuery("#photoitem-"+e).css({backgroundColor:"#e0ffe0",borderColor:"#55ee55"});var t=document.getElementById("pname-"+e).value.split(".");if(1<t.length)for(var p=0;p<t.length;)"jpg"!=t[p]&&"JPG"!=t[p]||jQuery("#psdesc-"+e).css({display:""}),p++}"gold"==elm.value&&jQuery("#photoitem-"+e).css({backgroundColor:"#eeeecc",borderColor:"#ddddbb"}),"silver"==elm.value&&jQuery("#photoitem-"+e).css({backgroundColor:"#ffffff",borderColor:"#eeeeee"}),"bronze"==elm.value&&jQuery("#photoitem-"+e).css({backgroundColor:"#ddddbb",borderColor:"#ccccaa"}),"scheduled"==elm.value?jQuery(".wppa-datetime-"+e).css("display",""):jQuery(".wppa-datetime-"+e).css("display","none"),jQuery("#scheduledel-"+e).prop("checked")?jQuery(".wppa-del-datetime-"+e).css("display",""):jQuery(".wppa-del-datetime-"+e).css("display","none")}}function wppaSetComBgCol(e){"approved"==jQuery("#com-stat-"+e).val()?jQuery("#com-tr-"+e).css({backgroundColor:"#ffffe0"}):jQuery("#com-tr-"+e).css({backgroundColor:"#ffebe8"})}function wppaCheckLinkPageErr(e){var t="nil";document.getElementById(e+"_linktype")&&(t=document.getElementById(e+"_linktype").value),"0"!=document.getElementById(e+"_linkpage").value||"nil"!=t&&"photo"!=t&&"single"!=t&&"album"!=t&&"content"!=t&&"slide"!=t&&"plainpage"!=t?jQuery("#"+e+"-err").css({display:"none"}):jQuery("#"+e+"-err").css({display:""})}function wppaAddCat(e,t){wppaAddTag(e,t)}function wppaAddTag(e,t){var p=document.getElementById(t);e&&(p.value?p.value+=","+e:p.value=e,"-clear-"==e&&(p.value=""))}function wppaRefresh(e){var t=new String(document.location).split("#")[0]+"#"+e;document.location=t}function wppaReload(e){e?(url=document.location.href.split("#"),document.location.href=url[0]+e,setTimeout(function(){document.location.reload(!0)},10)):document.location.reload(!0)}var wppaFeCount=0;function wppaFeAjaxLog(e){"in"==e&&(0==wppaFeCount&&jQuery("#wppa-fe-exit").css("display","none"),wppaFeCount++,jQuery("#wppa-fe-count").html(wppaFeCount)),"out"==e&&(1==wppaFeCount&&(jQuery("#wppa-fe-count").html(""),jQuery("#wppa-fe-exit").css("display","inline"),wppaFeCount--),1<wppaFeCount&&(wppaFeCount--,jQuery("#wppa-fe-count").html(wppaFeCount)))}function wppaArrayToEnum(e,t){temp=e.sort(function(e,t){return e-t});for(var p,a="",o=-1,n=-2,i=0,s=!1,l=0;l<e.length;)0!=(p=e[l].valueOf())&&(i=o,p==++i?s=!0:s?(a+=o==n?t+o+t+p:t+t+o+t+p,s=!1):a+=t+p,s||(n=p,n++),o=p),l++;for(s&&(a+=".."+o);"."==a.substr(0,1);)a=a.substr(1);for(;a.substr(0,1)==t;)a=a.substr(1);return a}function wppaGetSelEnumToId(e,t){p=jQuery("."+e);var a=[];for(i=0,j=0;i<p.length;)p[i].selected&&(a[j]=p[i].value,j++),i++;jQuery("#"+t).val(wppaArrayToEnum(a,"."))}function wppaGetSelectionEnumByClass(e,t){var p,a=[],o=0,n=0;for(t||(t="."),p=jQuery(e),n=o=0;o<p.length;)p[o].selected&&(a[n]=p[o].value,n++),o++;return wppaArrayToEnum(a,t)}function wppaEditSearch(e,t){var p=jQuery("#"+t).val();0==p.length?alert("Please enter searchstring"):document.location.href=e+"&wppa-searchstring="+p}function wppaEditTrash(e){document.location.href=e}function wppaExportDbTable(a){jQuery.ajax({url:wppaAjaxUrl,data:"action=wppa&wppa-action=export-table&table="+a,async:!0,type:"GET",timeout:1e5,beforeSend:function(e){jQuery("#"+a+"-spin").css("display","inline")},success:function(e,t,p){var a=e.split("||");"0"==a[1]?document.location=a[2]:alert("Error: "+a[1]+"\n\n"+a[2])},error:function(e,t,p){alert("Export Db Table "+a+" failed. Error = "+p+", status = "+t)},complete:function(e,t,p){jQuery("#"+a+"-spin").css("display","none")}})}function wppaDismissAdminNotice(e,t){wppaAjaxUpdateOptionCheckBox(e,t),jQuery("#wppa-wr-").css("display","none")}function wppaAjaxUpdateTogo(i){jQuery.ajax({url:wppaAjaxUrl,data:"action=wppa&wppa-action=gettogo&slug="+i,async:!0,type:"GET",timeout:1e5,beforeSend:function(e){},success:function(e,t,p){var a=e.split("|");jQuery("#"+i+"_togo").html(a[0]);var o=jQuery("#"+i+"_status").html(),n=a[1];""!=o&&""==n&&(n='<input type="button" class="button-secundary" style="border-radius:3px;font-size:11px;height:18px;margin: 0 4px;padding:0px;color:red;background-color:pink;" onclick="document.location.reload(true)" value="Reload" />'),jQuery("#"+i+"_status").html(n),setTimeout(function(){wppaAjaxUpdateTogo(i)},5e3)},error:function(e){},complete:function(e){}})}function wppaIsEmpty(e){return null==e||(void 0===e||(""==e||(0==e||0==e)))}function wppaTimedConfirm(e){var t={modal:!0,resizable:!1,width:400,show:{effect:"fadeIn",duration:800},closeText:"X",buttons:[{text:"NO",click:function(){jQuery(this).dialog("close")}},{text:"YES",click:function(){jQuery(this).dialog("close")}}]};jQuery("#wppa-modal-container").html(e).dialog(t).dialog("open"),jQuery(".ui-dialog").css({boxShadow:"0px 0px 5px 5px #aaaaaa",padding:"8px",backgroundColor:"#cccccc",boxSizing:"content-box",zIndex:"9999"}),jQuery(".ui-dialog-titlebar").css({lineHeight:"0px",height:"32px"}),jQuery(".ui-button").css({float:"right",position:"relative",bottom:"40px"}),jQuery(".ui-dialog-titlebar-close").css({display:"none"}),jQuery(".ui-button").attr("title",wppaCloseText),setTimeout(function(){jQuery(".ui-button").trigger("click")},6e4)}function wppaAjaxGetSpinnerHtml(e,o){jQuery.ajax({url:wppaAjaxUrl,data:"action=wppa&wppa-action=update-option&wppa-option=getspinnerpreview&type="+e+"&wppa-nonce="+document.getElementById("wppa-nonce").value,async:!0,type:"GET",timeout:1e5,beforeSend:function(e){},success:function(e,t,p){var a=e.split("|");jQuery("#"+o).html(a[0])},error:function(e){},complete:function(e){}})}
1
+ var wppaImageDirectory,wppaAjaxUrl,wppa_moveup_url="#",wppa_import="Import",wppa_update="Update",wppaUploadToThisAlbum="Upload to this album",wppaCropper=[];function checkjQueryRev(e,t,p){var a=parseFloat(jQuery.fn.jquery);t.checked&&a<p&&(alert(e+"\nThe version of your jQuery library: "+a+" is too low for this feature. It requires version "+p),t.checked="")}function wppaReUpload(e,t,p){document.getElementById("wppa-re-up-form-"+t);var a=document.getElementById("wppa-re-up-file-"+t),n=document.getElementById("wppa-re-up-butn-"+t);e.preventDefault();var i=a.files[0];if(i.type.match("image.*")){if(0==p.length)alert("Filename will be set to "+i.name);else if(i.name!=p&&!confirm("Filename is different.\nIf you continue, the filename will not be updated!.\n\nContinue?"))return void jQuery("#re-up-"+t).css("display","none");n.value="Uploading...",n.style.color="black";var o=new FormData;o.append("photo",i,i.name);var s=new XMLHttpRequest,l="?action=wppa&wppa-action=update-photo&photo-id="+t+"&item=file&wppa-nonce="+document.getElementById("photo-nonce-"+t).value;s.open("POST",wppaAjaxUrl+l,!0),s.onload=function(){if(200===s.status){var e=wppaTrim(s.responseText).split("||");switch(""!=e[0]&&alert("The server returned unexpected output:\n"+e[0]),e[1]){case"0":jQuery("#remark-"+t).html(e[2]),n.value="Upload",jQuery("#re-up-"+t).css("display","none");break;case"99":document.getElementById("photoitem-"+t).innerHTML='<span style="color:red">'+e[2]+"</span>";break;default:document.getElementById("remark-"+t).innerHTML='<span style="color:red">'+e[2]+" ("+e[1]+")</span>",n.value="Error occured",n.style.color="red"}}else alert("An error occurred!")},s.send(o)}else alert("File is not an image file!")}function wppaInitSettings(){wppaCheckBreadcrumb(),wppaCheckFullHalign(),wppaCheckUseThumbOpacity(),wppaCheckUseCoverOpacity(),wppaCheckThumbType(),wppaCheckThumbLink(),wppaCheckTopTenLink(),wppaCheckFeaTenLink(),wppaCheckLasTenLink(),wppaCheckThumbnailWLink(),wppaCheckCommentLink(),wppaCheckXphotoLink(),wppaCheckMphotoLink(),wppaCheckSphotoLink(),wppaCheckSlidePhotoLink(),wppaCheckSlideOnlyLink(),wppaCheckAlbumWidgetLink(),wppaCheckSlideLink(),wppaCheckCoverImg(),wppaCheckPotdLink(),wppaCheckTagLink(),wppaCheckRating(),wppaCheckComments(),wppaCheckCustom(),wppaCheckResize(),wppaCheckNumbar(),wppaCheckWatermark(),wppaCheckPopup(),wppaCheckGravatar(),wppaCheckUserUpload(),wppaCheckAjax(),wppaCheckFotomoto(),wppaCheckLinkPageErr("sphoto"),wppaCheckLinkPageErr("mphoto"),wppaCheckLinkPageErr("xphoto"),wppaCheckLinkPageErr("topten_widget"),wppaCheckLinkPageErr("slideonly_widget"),wppaCheckLinkPageErr("potd"),wppaCheckLinkPageErr("comment_widget"),wppaCheckLinkPageErr("thumbnail_widget"),wppaCheckLinkPageErr("lasten_widget"),wppaCheckLinkPageErr("album_widget"),wppaCheckLinkPageErr("tagcloud"),wppaCheckLinkPageErr("multitag"),wppaCheckLinkPageErr("super_view"),wppaCheckSplitNamedesc(),wppaCheckShares(),wppaCheckCoverType(),wppaCheckNewpag(),wppaCheckCDN(),wppaCheckAutoPage(),wppaCheckGps(),wppaCheckFontPreview(),wppaCheckCheck("wppa_enable_video","wppa-video"),wppaCheckCheck("wppa_custom_fields","custfields"),wppaCheckCheck("wppa_album_custom_fields","albumcustfields"),wppaCheckCheck("wppa_new_mod_label_is_text","nmtxt"),wppaCheckCheck("wppa_coverphoto_responsive","cvpr"),wppaCheckSmWidgetLink();var e=new Array("O","I","II","III","IV","V","VI","VII","VIII","IX","X","XI","XII"),t=new Array("A","B","C","D","E","F","G","H","I","J","K","L","M");for(table=1;table<13;table++){var p=wppa_getCookie("table_"+table);for("on"==p?wppaShowTable(table):wppaHideTable(table),subtab=0;subtab<13;subtab++)"on"==(p=wppa_getCookie("table_"+e[table-1]+"-"+t[subtab]))&&wppaToggleSubTable(e[table-1],t[subtab]);wppaToggleSubTable(e[table-1],"Z")}}function wppaQuickSel(){var e=new Array("O","I","II","III","IV","V","VI","VII","VIII","IX","X","XI","XII"),t=new Array("A","B","C","D","E","F","G","H","I","J","K","Z");for(table=1;table<13;table++)for(table<13?wppaShowTable(table):wppaHideTable(table),wppa_tablecookieoff(table),subtab=0;subtab<12;subtab++){cookie=wppa_getCookie("table_"+e[table-1]+"-"+t[subtab]),"on"==cookie&&wppaToggleSubTable(e[table-1],t[subtab]);var p=jQuery(".wppa-"+e[table-1]+"-"+t[subtab]);0<p.length&&(p.removeClass("wppa-none"),wppaSubTabOn[e[table-1]+"-"+t[subtab]]=!1,wppa_tablecookieoff(e[table-1]+"-"+t[subtab]))}if(tag1=jQuery("#wppa-quick-selbox-1").val(),tag2=jQuery("#wppa-quick-selbox-2").val(),"-"==tag1&&"-"==tag2)for(jQuery("._wppatag-").addClass("wppa-none"),table=1;table<13;table++)wppaHideTable(table);else"-"!=tag1&&jQuery("._wppatag-"+tag1).addClass("wppa-none"),"-"!=tag2&&jQuery("._wppatag-"+tag2).addClass("wppa-none")}function wppaToggleTable(e){"none"==jQuery("#wppa_table_"+e).css("display")?(jQuery("#wppa_table_"+e).css("display","inline"),wppa_tablecookieon(e)):(jQuery("#wppa_table_"+e).css("display","none"),wppa_tablecookieoff(e))}jQuery(document).ready(function(){jQuery(window).on("DOMContentLoaded load resize scroll",wppaMakeLazyVisible),wppaMakeLazyVisible()});var wppaSubTabOn=new Array;function wppaToggleSubTable(e,t){wppaSubTabOn[e+"-"+t]?(jQuery(".wppa-"+e+"-"+t).addClass("wppa-none"),jQuery(".wppa-"+e+"-"+t+"-help").css("display","none"),wppaSubTabOn[e+"-"+t]=!1,wppa_tablecookieoff(e+"-"+t)):(jQuery(".wppa-"+e+"-"+t).removeClass("wppa-none"),jQuery(".wppa-"+e+"-"+t+"-h").css("display",""),wppaSubTabOn[e+"-"+t]=!0,wppa_tablecookieon(e+"-"+t))}function wppaHideTable(e){jQuery("#wppa_table_"+e).css("display","none"),jQuery("#wppa_tableHide-"+e).css("display","none"),jQuery("#wppa_tableShow-"+e).css("display","inline"),wppa_tablecookieoff(e)}function wppaShowTable(e){jQuery("#wppa_table_"+e).css("display","block"),jQuery("#wppa_tableHide-"+e).css("display","inline"),jQuery("#wppa_tableShow-"+e).css("display","none"),wppa_tablecookieon(e)}var _wppaRefreshAfter=!1;function wppaRefreshAfter(){_wppaRefreshAfter=!0}function wppaFollow(e,t){jQuery("#"+e).prop("checked")?jQuery("."+t).css("display",""):jQuery("."+t).css("display","none")}function wppaCheckCheck(e,t){var p=e.substring(5);document.getElementById(p).checked?(jQuery("."+t).css("display",""),jQuery(".-"+t).css("display","none")):(jQuery("."+t).css("display","none"),jQuery(".-"+t).css("display",""))}function wppaCheckSlideVideoControls(){"none"!=document.getElementById("slideshow_linktype").value&&alert("Warning! \nYou can not have video controls on a videoslide when there is a link on the slide.\nThe videoslide will not show controls and will also not autoplay")}function wppaCheckFotomoto(){document.getElementById("fotomoto_on").checked?jQuery(".wppa_fotomoto").css("display",""):jQuery(".wppa_fotomoto").css("display","none")}function wppaCheckFontPreview(){var e=document.getElementById("textual_watermark_font").value,t=document.getElementById("textual_watermark_type").value,p=wppaFontDirectory+"wmf"+e+"-"+t+".png",a=wppaFontDirectory+"wmf"+t+"-"+e+".png";jQuery("#wm-font-preview").attr("src",p),jQuery("#wm-type-preview").attr("src",a)}function wppaCheckWidgetMethod(){var e,t;if("4"==document.getElementById("wppa-wm").value){document.getElementById("wppa-wp").style.visibility="visible";var p=jQuery("#wppa-wp").val();"day-of-week"==p||"day-of-month"==p||"day-of-year"==p?jQuery(".wppa-order").css("visibility",""):jQuery(".wppa-order").css("visibility","hidden")}else document.getElementById("wppa-wp").style.visibility="hidden",jQuery(".wppa-order").css("visibility","hidden");if("1"==document.getElementById("wppa-wm").value)for(e=document.getElementsByName("wppa-widget-photo"),t=0;t<e.length;)e[t].style.visibility="visible",t++;else for(e=document.getElementsByName("wppa-widget-photo"),t=0;t<e.length;)e[t].style.visibility="hidden",t++}function wppaCheckFullHalign(){var e=document.getElementById("fullsize").value,t=document.getElementById("colwidth").value,p=document.getElementById("fullvalign").value;e!=t&&"default"!=p?jQuery(".wppa_ha").css("display",""):jQuery(".wppa_ha").css("display","none"),"auto"==t?jQuery(".wppa_init_resp_width").css("display",""):jQuery(".wppa_init_resp_width").css("display","none")}function wppaCheckCDN(){var e=document.getElementById("cdn_service").value;"cloudinary"==e||"cloudinarymaintenance"==e?jQuery(".cloudinary").css("display",""):jQuery(".cloudinary").css("display","none")}function wppaCheckGps(){"wppa-plus-embedded"==document.getElementById("gpx_implementation").value?(jQuery(".wppa_gpx_native").css("display",""),jQuery(".wppa_gpx_plugin").css("display","none")):(jQuery(".wppa_gpx_native").css("display","none"),jQuery(".wppa_gpx_plugin").css("display",""))}function wppaCheckThumbType(){var e=document.getElementById("thumbtype").value;"default"==e&&(jQuery(".tt_normal").css("display",""),jQuery(".tt_ascovers").css("display","none"),jQuery(".tt_always").css("display",""),wppaCheckUseThumbOpacity()),"ascovers"!=e&&"ascovers-mcr"!=e||(jQuery(".tt_normal").css("display","none"),jQuery(".tt_ascovers").css("display",""),jQuery(".tt_always").css("display","")),"masonry"==e&&(jQuery(".tt_normal").css("display","none"),jQuery(".tt_ascovers").css("display","none"),jQuery(".tt_always").css("display",""),jQuery(".tt_masonry").css("display",""))}function wppaCheckAutoPage(){document.getElementById("auto_page").checked?jQuery(".autopage").css("display",""):jQuery(".autopage").css("display","none")}function wppaCheckUseThumbOpacity(){document.getElementById("use_thumb_opacity").checked?(jQuery(".thumb_opacity").css("color","#333"),jQuery(".thumb_opacity_html").css("visibility","visible")):(jQuery(".thumb_opacity").css("color","#999"),jQuery(".thumb_opacity_html").css("visibility","hidden"))}function wppaCheckUseCoverOpacity(){document.getElementById("use_cover_opacity").checked?(jQuery(".cover_opacity").css("color","#333"),jQuery(".cover_opacity_html").css("visibility","visible")):(jQuery(".cover_opacity").css("color","#999"),jQuery(".cover_opacity_html").css("visibility","hidden"))}function wppaCheckBreadcrumb(){var e=document.getElementById("show_bread_posts").checked,t=document.getElementById("show_bread_pages").checked;if(e||t){jQuery(".wppa_bc").css("display",""),jQuery(".wppa_bc_html").css("display","");var p=document.getElementById("bc_separator").value;"txt"==p?(jQuery(".wppa_bc_txt").css("display",""),jQuery(".wppa_bc_url").css("display","none"),jQuery(".wppa_bc_txt_html").css("display",""),jQuery(".wppa_bc_url_html").css("display","none")):"url"==p?(jQuery(".wppa_bc_txt").css("display","none"),jQuery(".wppa_bc_url").css("display",""),jQuery(".wppa_bc_txt_html").css("display","none"),jQuery(".wppa_bc_url_html").css("display","")):(jQuery(".wppa_bc_txt").css("display","none"),jQuery(".wppa_bc_url").css("display","none"))}else jQuery(".wppa_bc").css("display","none"),jQuery(".wppa_bc_txt").css("display","none"),jQuery(".wppa_bc_url").css("display","none")}function wppaCheckRating(){document.getElementById("rating_on").checked?(jQuery(".wppa_rating").css("color","#333"),jQuery(".wppa_rating_html").css("visibility","visible"),jQuery(".wppa_rating_").css("display","")):(jQuery(".wppa_rating").css("color","#999"),jQuery(".wppa_rating_html").css("visibility","hidden"),jQuery(".wppa_rating_").css("display","none"))}function wppaCheckComments(){document.getElementById("show_comments").checked?(jQuery(".wppa_comment").css("color","#333"),jQuery(".wppa_comment_html").css("visibility","visible"),jQuery(".wppa_comment_").css("display","")):(jQuery(".wppa_comment").css("color","#999"),jQuery(".wppa_comment_html").css("visibility","hidden"),jQuery(".wppa_comment_").css("display","none"))}function wppaCheckAjax(){document.getElementById("allow_ajax").checked?jQuery(".wppa_allow_ajax_").css("display",""):jQuery(".wppa_allow_ajax_").css("display","none")}function wppaCheckShares(){document.getElementById("share_on").checked||document.getElementById("share_on_widget").checked||document.getElementById("share_on_lightbox").checked||document.getElementById("share_on_thumbs").checked||document.getElementById("share_on_mphoto").checked?jQuery(".wppa_share").css("display",""):jQuery(".wppa_share").css("display","none")}function wppaCheckCoverType(){var e=document.getElementById("cover_type").value;document.getElementById("coverphoto_pos").value;"imagefactory"==e||"imagefactory-mcr"==e?jQuery(".wppa_imgfact_").css("display",""):jQuery(".wppa_imgfact_").css("display","none")}function wppaCheckNewpag(){document.getElementById("newpag_create").checked?jQuery(".wppa_newpag").css("display",""):jQuery(".wppa_newpag").css("display","none")}function wppaCheckCustom(){document.getElementById("custom_on").checked?(jQuery(".wppa_custom").css("color","#333"),jQuery(".wppa_custom_html").css("visibility","visible"),jQuery(".wppa_custom_").css("display","")):(jQuery(".wppa_custom").css("color","#999"),jQuery(".wppa_custom_html").css("visibility","hidden"),jQuery(".wppa_custom_").css("display","none"))}function wppaCheckWidgetLink(){"-1"==document.getElementById("wlp").value?(jQuery(".wppa_wlu").css("display",""),jQuery(".wppa_wlt").css("visibility","hidden")):(jQuery(".wppa_wlu").css("display","none"),jQuery(".wppa_wlt").css("visibility","visible"))}function wppaCheckSmWidgetLink(){"home"==document.getElementById("widget_sm_linktype").value?jQuery(".wppa_smrp").css("visibility","hidden"):jQuery(".wppa_smrp").css("visibility","")}function wppaCheckThumbLink(){var e=document.getElementById("thumb_linktype").value;"none"==e||"file"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_tlp").css("visibility","hidden"):jQuery(".wppa_tlp").css("visibility","visible"),"none"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_tlb").css("visibility","hidden"):jQuery(".wppa_tlb").css("visibility","visible")}function wppaCheckTopTenLink(){var e=document.getElementById("topten_widget_linktype").value;"none"==e||"file"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_ttlp").css("visibility","hidden"):jQuery(".wppa_ttlp").css("visibility","visible"),"none"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_ttlb").css("visibility","hidden"):jQuery(".wppa_ttlb").css("visibility","visible")}function wppaCheckFeaTenLink(){var e=document.getElementById("featen_widget_linktype").value;"none"==e||"file"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_ftlp").css("visibility","hidden"):jQuery(".wppa_ftlp").css("visibility","visible"),"none"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_ftlb").css("visibility","hidden"):jQuery(".wppa_ftlb").css("visibility","visible")}function wppaCheckLasTenLink(){var e=document.getElementById("lasten_widget_linktype").value;"none"==e||"file"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_ltlp").css("visibility","hidden"):jQuery(".wppa_ltlp").css("visibility","visible"),"none"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_ltlb").css("visibility","hidden"):jQuery(".wppa_ltlb").css("visibility","visible")}function wppaCheckThumbnailWLink(){var e=document.getElementById("thumbnail_widget_linktype").value;"none"==e||"file"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_tnlp").css("visibility","hidden"):jQuery(".wppa_tnlp").css("visibility","visible"),"none"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_tnlb").css("visibility","hidden"):jQuery(".wppa_tnlb").css("visibility","visible")}function wppaCheckCommentLink(){var e=document.getElementById("comment_widget_linktype").value;"none"==e||"file"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_cmlp").css("visibility","hidden"):jQuery(".wppa_cmlp").css("visibility","visible"),"none"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_cmlb").css("visibility","hidden"):jQuery(".wppa_cmlb").css("visibility","visible")}function wppaCheckSlideOnlyLink(){var e=document.getElementById("slideonly_widget_linktype").value;"none"==e||"file"==e||"widget"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_solp").css("visibility","hidden"):jQuery(".wppa_solp").css("visibility","visible"),"none"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_solb").css("visibility","hidden"):jQuery(".wppa_solb").css("visibility","visible")}function wppaCheckAlbumWidgetLink(){var e=document.getElementById("album_widget_linktype").value;"lightbox"==e?jQuery(".wppa_awlp").css("visibility","hidden"):jQuery(".wppa_awlp").css("visibility","visible"),"lightbox"==e?jQuery(".wppa_awlb").css("visibility","hidden"):jQuery(".wppa_awlb").css("visibility","visible")}function wppaCheckSlideLink(){var e=document.getElementById("slideshow_linktype").value;"none"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_sslb").css("visibility","hidden"):jQuery(".wppa_sslb").css("visibility","visible")}function wppaCheckCoverImg(){var e=document.getElementById("coverimg_linktype").value;"none"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_covimgbl").css("visibility","hidden"):jQuery(".wppa_covimgbl").css("visibility","visible")}function wppaCheckPotdLink(){var e=document.getElementById("potd_linktype").value;"none"==e||"lightbox"==e||"file"==e||"custom"==e?jQuery(".wppa_potdlp").css("visibility","hidden"):jQuery(".wppa_potdlp").css("visibility","visible"),"none"==e||"lightbox"==e||"fullpopup"==e?jQuery(".wppa_potdlb").css("visibility","hidden"):jQuery(".wppa_potdlb").css("visibility","visible")}function wppaCheckTagLink(){document.getElementById("tagcloud_linktype").value}function wppaCheckMTagLink(){document.getElementById("multitag_linktype").value}function wppaCheckXphotoLink(){var e=document.getElementById("xphoto_linktype").value;"none"==e||"file"==e||"lightbox"==e?jQuery(".wppa_xlp").css("visibility","hidden"):jQuery(".wppa_xlp").css("visibility","visible"),"none"==e||"lightbox"==e?jQuery(".wppa_xlb").css("visibility","hidden"):jQuery(".wppa_xlb").css("visibility","visible")}function wppaCheckMphotoLink(){var e=document.getElementById("mphoto_linktype").value;"none"==e||"file"==e||"lightbox"==e?jQuery(".wppa_mlp").css("visibility","hidden"):jQuery(".wppa_mlp").css("visibility","visible"),"none"==e||"lightbox"==e?jQuery(".wppa_mlb").css("visibility","hidden"):jQuery(".wppa_mlb").css("visibility","visible")}function wppaCheckSphotoLink(){var e=document.getElementById("sphoto_linktype").value;"none"==e||"file"==e||"lightbox"==e?jQuery(".wppa_slp").css("visibility","hidden"):jQuery(".wppa_slp").css("visibility","visible"),"none"==e||"lightbox"==e?jQuery(".wppa_slb").css("visibility","hidden"):jQuery(".wppa_slb").css("visibility","visible")}function wppaCheckSlidePhotoLink(){var e=document.getElementById("slideshow_linktype").value;"none"==e||"file"==e||"lightbox"==e||"lightboxsingle"==e||"fullpopup"==e?jQuery(".wppa_sslp").css("visibility","hidden"):jQuery(".wppa_sslp").css("visibility","visible"),"none"==e||"lightbox"==e||"lightboxsingle"==e||"fullpopup"==e?jQuery(".wppa_sslb").css("visibility","hidden"):jQuery(".wppa_sslb").css("visibility","visible")}function wppaCheckResize(){document.getElementById("resize_on_upload").checked?jQuery(".re_up").css("display",""):jQuery(".re_up").css("display","none")}function wppaCheckNumbar(){document.getElementById("show_slideshownumbar").checked?jQuery(".wppa_numbar").css("display",""):jQuery(".wppa_numbar").css("display","none")}function wppaCheckWatermark(){document.getElementById("watermark_on").checked?jQuery(".wppa_watermark").css("display",""):jQuery(".wppa_watermark").css("display","none")}function wppaCheckPopup(){document.getElementById("use_thumb_popup").checked?jQuery(".wppa_popup").css("display",""):jQuery(".wppa_popup").css("display","none")}function wppaCheckGravatar(){document.getElementById("comment_gravatar")&&("url"==document.getElementById("comment_gravatar").value?jQuery(".wppa_grav").css("display",""):jQuery(".wppa_grav").css("display","none"))}function wppaCheckUserUpload(){document.getElementById("user_upload_on").checked?jQuery(".wppa_feup").css("display",""):jQuery(".wppa_feup").css("display","none")}function wppaCheckSplitNamedesc(){document.getElementById("split_namedesc").checked?(jQuery(".swap_namedesc").css("display","none"),jQuery(".hide_empty").css("display","")):(jQuery(".swap_namedesc").css("display",""),jQuery(".hide_empty").css("display","none"))}function wppa_tablecookieon(e){wppa_setCookie("table_"+e,"on","365")}function wppa_tablecookieoff(e){wppa_setCookie("table_"+e,"off","365")}function wppaCookieCheckbox(e,t){e.checked?wppa_setCookie(t,"on","365"):wppa_setCookie(t,"off","365")}function wppa_move_up(e){document.location=wppa_moveup_url+e+"&wppa-nonce="+document.getElementById("wppa-nonce").value}function checkColor(e){var t=e.substr(5),p=jQuery("#"+t).val();jQuery("#colorbox-"+t).css("background-color",p)}function checkAll(e,t){var p=document.getElementById(e);p&&(p.checked?jQuery(t).prop("checked","checked"):jQuery(t).prop("checked",""))}function impUpd(e,t){e.checked?(jQuery(t).prop("value",wppa_update),jQuery(".hideifupdate").css("display","none")):(jQuery(t).prop("value",wppa_import),jQuery(".hideifupdate").css("display",""))}function wppaAjaxDeletePhoto(t,e,p){var a="",n="";a=e||'<div style="padding-left:5px;" >',p?n=p:aftrer="</div>",wppaFeAjaxLog("in");var i=wppaGetXmlHttp(),o=wppaAjaxUrl+"?action=wppa&wppa-action=delete-photo&photo-id="+t;o+="&wppa-nonce="+document.getElementById("photo-nonce-"+t).value,i.open("GET",o,!0),i.send(),i.onreadystatechange=function(){switch(i.readyState){case 1:document.getElementById("remark-"+t).innerHTML="server connection established";break;case 2:document.getElementById("remark-"+t).innerHTML="request received";break;case 3:document.getElementById("remark-"+t).innerHTML="processing request";break;case 4:if(200==i.status){var e=wppaTrim(i.responseText).split("||");"ER"==e[0]?(e[3]&&alert(e[3]),jQuery("#wppa-delete-"+t).css("text-decoration","line-through")):""!=e[0]&&alert("The server returned unexpected output:\n"+e[0]),0==e[1]?document.getElementById("remark-"+t).innerHTML=e[2]:(document.getElementById("photoitem-"+t).innerHTML=a+e[2]+n,wppaProcessFull(e[3],e[4])),jQuery(window).trigger("scroll"),wppaFeAjaxLog("out")}else document.getElementById("photoitem-"+t).innerHTML=a+'<span style="color:red;" >Comm error '+i.status+": "+i.statusText+"</span>"+n}}}function wppaAjaxUndeletePhoto(t){wppaFeAjaxLog("in");var p=wppaGetXmlHttp(),e=wppaAjaxUrl+"?action=wppa&wppa-action=undelete-photo&photo-id="+t;e+="&wppa-nonce="+document.getElementById("photo-nonce-"+t).value,p.open("GET",e,!0),p.send(),p.onreadystatechange=function(){switch(p.readyState){case 1:document.getElementById("remark-"+t).innerHTML="server connection established";break;case 2:document.getElementById("remark-"+t).innerHTML="request received";break;case 3:document.getElementById("remark-"+t).innerHTML="processing request";break;case 4:if(200==p.status){var e=wppaTrim(p.responseText).split("||");"ER"==e[0]?(e[3]&&alert(e[3]),jQuery("#wppa-delete-"+t).css("text-decoration","line-through")):""!=e[0]&&alert("The server returned unexpected output:\n"+e[0]),0==e[1]?document.getElementById("remark-"+t).innerHTML=e[2]:document.getElementById("photoitem-"+t).innerHTML='<div style="padding-left:5px;" >'+e[2]+"</div>",wppaFeAjaxLog("out")}else document.getElementById("photoitem-"+t).innerHTML=before+'<span style="color:red;" >Comm error '+p.status+": "+p.statusText+"</span>"+after}}}function wppaAjaxApplyWatermark(t,e,p){wppaFeAjaxLog("in");var a=wppaGetXmlHttp();jQuery("#wppa-water-spin-"+t).css({visibility:"visible"});var n="action=wppa&wppa-action=watermark-photo&photo-id="+t;n+="&wppa-nonce="+document.getElementById("photo-nonce-"+t).value,e&&(n+="&wppa-watermark-file="+e),p&&(n+="&wppa-watermark-pos="+p),a.open("POST",wppaAjaxUrl,!0),a.setRequestHeader("Content-type","application/x-www-form-urlencoded"),a.send(n),a.onreadystatechange=function(){if(4==a.readyState)if(200==a.status){var e=wppaTrim(a.responseText).split("||");switch(""!=e[0]&&alert("The server returned unexpected output:\n"+e[0]),e[1]){case"0":document.getElementById("remark-"+t).innerHTML=e[2];break;default:document.getElementById("remark-"+t).innerHTML='<span style="color:red">'+e[2]+"</span>"}jQuery("#wppa-water-spin-"+t).css({visibility:"hidden"}),wppaFeAjaxLog("out")}else document.getElementById("remark-"+t).innerHTML='<span style="color:red;" >Comm error '+a.status+": "+a.statusText+"</span>"}}function wppaAjaxUpdatePhoto(l,r,e,t,u,c){u||(u=""),c||(c=""),wppaFeAjaxLog("in"),jQuery.ajax({url:wppaAjaxUrl,data:"action=wppa&wppa-action=update-photo&photo-id="+l+"&item="+r+"&wppa-nonce="+document.getElementById("photo-nonce-"+l).value+"&value="+wppaEncode(e),async:!0,type:"POST",timeout:6e4,beforeSend:function(e){jQuery("#wppa-photo-spin-"+l).css({visibility:"visible"}),jQuery("#remark-"+l).html("Working, please wait...")},success:function(e,t,p){var a=wppaTrim(e).split("||");switch(""!=a[0]&&alert("The server returned unexpected output:\n"+a[0]),a[1]){case"99":jQuery("#photoitem-"+l).html(u+'<span style="color:red">'+a[2]+"</span>"+c);break;default:var n,i,o=JSON.parse(a[2]);for(n in o)switch(i=o[n],n){case"remark":var s;i=(i=(i=i.replace(/&lt;/g,"<")).replace(/&gt;/g,">")).replace(/\\/g,""),s="0"!=a[1]?'<span style="color:red;" >'+i+"</span>":'<span style="color:green;" >'+i+"</span>",jQuery("#remark-"+l).html(s);break;case"photourl":if(wppaCropper[l])wppaCropper[l].replace(i);else jQuery("#photourl-"+l).attr("src",i);jQuery("#thumba-"+l).attr("href",i);break;case"thumburl":jQuery("#thumburl-"+l).attr("src",i);break;case"magickstack":jQuery("#magickstack-"+l).html(i),0<i.length?jQuery("#imstackbutton-"+l).css("display","inline"):jQuery("#imstackbutton-"+l).css("display","none");break;default:jQuery("#"+n+"-"+l).html(i)}}"description"==r&&jQuery("#wppa-photo-spin-"+l).css({visibility:"hidden"}),wppaFeAjaxLog("out")},error:function(e,t,p){jQuery("#remark-"+l).html('<span style="color:red;" >Comm error '+t+"</span>"),wppaConsoleLog("wppaAjaxUpdatePhoto failed. Error = "+p+", status = "+t,"force")},complete:function(e,t,p){jQuery("#wppa-admin-spinner").css("display","none"),jQuery(window).trigger("scroll")}})}function wppaChangeScheduleAlbum(e,t){jQuery(t).prop("checked")?jQuery(".wppa-datetime-"+e).css("display","inline"):(jQuery(".wppa-datetime-"+e).css("display","none"),wppaAjaxUpdateAlbum(e,"scheduledtm",document.getElementById("wppa-dummy")))}_wppaRefreshAfter=!1;var wppaAjaxAlbumCount=0,wppaAlbumUpdateMatrix=new Array;function wppaAjaxUpdateAlbum(e,t,p,a){var n=0==jQuery("#wppaalbumdesc:visible").length;jQuery("#wppaalbumdesc-html").click();for(var i=wppaAlbumUpdateMatrix.length,o=0,s=!1,l=-1;o<i;)wppaAlbumUpdateMatrix[o][0]==e&&wppaAlbumUpdateMatrix[o][1]==t&&(s=!0,l=o),o++;if(!s){wppaAlbumUpdateMatrix[i]=[e,t,"undefined",!1,!1,a],l=i}wppaAlbumUpdateMatrix[l][3]="number"==typeof p?p:p.value,wppaAlbumUpdateMatrix[l][5]=a,wppaAjaxUpdateAlbumMonitor(n)}function wppaAjaxUpdateAlbumMonitor(e){for(var t=wppaAlbumUpdateMatrix.length,p=0;p<t;)wppaAlbumUpdateMatrix[p][2]==wppaAlbumUpdateMatrix[p][3]||wppaAlbumUpdateMatrix[p][4]||(wppaAlbumUpdateMatrix[p][4]=!0,_wppaAjaxUpdateAlbum(wppaAlbumUpdateMatrix[p][0],wppaAlbumUpdateMatrix[p][1],wppaAlbumUpdateMatrix[p][3],e,wppaAlbumUpdateMatrix[p][5])),p++;e&&jQuery("#wppaalbumdesc-tmce").click()}function _wppaAjaxUpdateAlbum(s,l,r,u,c){wppaAjaxAlbumCount++;jQuery.ajax({url:wppaAjaxUrl,data:"action=wppa&wppa-action=update-album&album-id="+s+"&item="+l+"&wppa-nonce="+document.getElementById("album-nonce-"+s).value+"&value="+wppaEncode(r),async:!0,type:"POST",timeout:6e4,beforeSend:function(e){"description"==l&&jQuery("#wppa-album-spin").css({visibility:"visible"}),jQuery("#albumstatus-"+s).html("Working, please wait... ("+wppaAjaxAlbumCount+")")},success:function(e,t,p){var a=wppaTrim(e).split("||");switch(wppaAjaxAlbumCount--,""!=a[0]&&alert("The server returned unexpected output:\n"+a[0]),a[1]){case"0":0==wppaAjaxAlbumCount?jQuery("#albumstatus-"+s).html(a[2]):jQuery("#albumstatus-"+s).html("Working, please wait... ("+wppaAjaxAlbumCount+")");break;default:jQuery("#albumstatus-"+s).html='<span style="color:red">'+a[2]+" ("+a[1]+")</span>"}if(void 0!==a[3]&&wppaProcessFull(a[3],a[4]),c&&"0"==a[1])return jQuery("#albumstatus-"+s).after('<span style="color:blue;font-weight:bold;"> Reloading...</span>'),jQuery("#wppa-admin-spinner").fadeIn(),void setTimeout(function(){wppaReload()},100);"description"==l&&jQuery("#wppa-album-spin").css({visibility:"hidden"});for(var n=0,i=-1,o=wppaAlbumUpdateMatrix.length;n<o;)wppaAlbumUpdateMatrix[n][0]==s&&wppaAlbumUpdateMatrix[n][1]==l&&(i=n),n++;wppaAlbumUpdateMatrix[i][2]=r||0,wppaAlbumUpdateMatrix[i][4]=!1,wppaAlbumUpdateMatrix[i][5]=!1,wppaAjaxUpdateAlbumMonitor(u)},error:function(e,t,p){wppaAjaxAlbumCount--,jQuery("#albumstatus-"+s).html('<span style="color:red;" >Comm error '+t+"</span>"),wppaConsoleLog("_wppaAjaxUpdateAlbum failed. Error = "+p+", status = "+t,"force")},complete:function(e,t,p){}})}function wppaProcessFull(e,t){"full"==e&&(jQuery("#full").css("display",""),jQuery("#notfull").css("display","none")),"notfull"==e&&(jQuery("#full").css("display","none"),0<t?jQuery("#notfull").attr("value",wppaUploadToThisAlbum+" (max "+t+")"):jQuery("#notfull").attr("value",wppaUploadToThisAlbum),jQuery("#notfull").css("display",""))}function wppaAjaxUpdateCommentStatus(t,p,e){var a=wppaGetXmlHttp(),n=wppaAjaxUrl+"?action=wppa&wppa-action=update-comment-status&wppa-photo-id="+t+"&wppa-comment-id="+p+"&wppa-comment-status="+e+"&wppa-nonce="+document.getElementById("photo-nonce-"+t).value;a.onreadystatechange=function(){if(4==a.readyState)if(200==a.status){var e=wppaTrim(a.responseText).split("||");switch(""!=e[0]&&alert("The server returned unexpected output:\n"+e[0]),e[1]){case"0":jQuery("#remark-"+t).html(e[2]);break;default:jQuery("#remark-"+t).html('<span style="color:red">'+e[2]+"</span>")}jQuery("#wppa-comment-spin-"+p).css("visibility","hidden")}else jQuery("#remark-"+t).html('<span style="color:red;" >Comm error '+a.status+": "+a.statusText+"</span>")},a.open("GET",n,!0),a.send()}function wppaAjaxUpdateOptionCheckBox(t,e){var p=wppaGetXmlHttp(),a=wppaAjaxUrl+"?action=wppa&wppa-action=update-option&wppa-option="+t;a+="&wppa-nonce="+document.getElementById("wppa-nonce").value,e.checked?a+="&value=yes":a+="&value=no",p.onreadystatechange=function(){switch(p.readyState){case 1:case 2:case 3:jQuery("#img_"+t).attr("src",wppaImageDirectory+"spinner.gif");break;case 4:var e=wppaTrim(p.responseText).split("||");if(""!=e[0]&&alert("The server returned unexpected output:\n"+e[0]),404!=p.status)switch(e[1]){case"0":jQuery("#img_"+t).attr("src",wppaImageDirectory+"tick.png"),jQuery("#img_"+t).attr("title",e[2]),e[3]&&alert(e[3]),_wppaRefreshAfter&&(_wppaRefreshAfter=!1,document.location.reload(!0));break;default:jQuery("#img_"+t).attr("src",wppaImageDirectory+"cross.png"),jQuery("#img_"+t).attr("title","Error #"+e[1]+", message: "+e[2]+", status: "+p.status),e[3]&&alert(e[3]),_wppaRefreshAfter&&(_wppaRefreshAfter=!1,document.location.reload(!0))}else jQuery("#img_"+t).attr("src",wppaImageDirectory+"cross.png"),jQuery("#img_"+t).attr("title","Communication error, status = "+p.status);wppaCheckInconsistencies()}},p.open("GET",a,!0),p.send()}var wppaAlwaysContinue=100;function wppaMaintenanceProc(n,e,o){if(o);else if(!e&&"yes"==document.getElementById(n+"_continue").value)return document.getElementById(n+"_continue").value="no",document.getElementById(n+"_button").value="Start!",void(0<jQuery("#"+n+"_togo").html()&&(jQuery("#"+n+"_status").html("Pausing..."),jQuery("#"+n+"_button").css("display","none")));o||(document.getElementById(n+"_continue").value="yes",document.getElementById(n+"_button").value="Stop!",""==jQuery("#"+n+"_status").html()&&jQuery("#"+n+"_status").html("Wait...")),jQuery.ajax({url:wppaAjaxUrl,data:"action=wppa&wppa-action=maintenance&slug="+n+"&wppa-nonce="+jQuery("#wppa-nonce").val()+(o?"&wppa-cron":""),async:!0,type:"POST",timeout:3e5,beforeSend:function(e){},success:function(e,t,p){var a=e.split("||"),n=a[1],i=!1;return n?(10<a[0].length&&(alert("An error occurred:\n"+a[0]),i=!0),jQuery("#"+n+"_status").html(a[2]),jQuery("#"+n+"_togo").html(a[3]),jQuery("#"+n+"_button").css("display",""),i||"0"==a[3]?"reload"==a[4]?(alert("This page will now be reloaded to finish the operation. Please stay tuned..."),void wppaReload()):void setTimeout("wppaMaintenanceProc('"+n+"', false)",20):void("yes"!=document.getElementById(n+"_continue").value?o||jQuery("#"+n+"_status").html("Pending"):setTimeout("wppaMaintenanceProc('"+n+"', true)",20))):(alert("The server returned unexpected output:\n"+e+"\nIf the current procedure has a Skip One button, press it before retrying. Reloading page..."),void wppaReload())},error:function(e,t,p){wppaConsoleLog("wppaMaintenanceProc failed. Slug = "+n+", Error = "+p+", status = "+t,"force"),jQuery("#"+n+"_status").html("Server error #"+(11-wppaAlwaysContinue));var a=!1;--wppaAlwaysContinue<1&&(a=confirm("10 Server errors happened.\nDo you want to continue?"))&&(wppaAlwaysContinue=100),(a||0<wppaAlwaysContinue)&&("wppa_remake"==n&&wppaAjaxUpdateOptionValue("wppa_remake_skip_one",0),"wppa_regen_thumbs"==n&&wppaAjaxUpdateOptionValue("wppa_regen_thumbs_skip_one",0),"wppa_create_o1_files"==n&&wppaAjaxUpdateOptionValue("wppa_create_o1_files_skip_one",0),setTimeout("wppaMaintenanceProc('"+n+"', true)",2e3))},complete:function(e,t,p){}})}function wppaAjaxPopupWindow(e){switch(e){case"wppa_list_index":"Search index table";break;case"wppa_list_errorlog":"WPPA+ Error log";break;case"wppa_list_rating":"Recent ratings";break;case"wppa_list_session":"Active sessions";break;case"wppa_list_comments":"Recent comments"}var t=.9*wppaWindowWidth(),p=wppaGetXmlHttp(),a=wppaAjaxUrl,n="action=wppa&wppa-action=maintenancepopup&slug="+e;if(n+="&wppa-nonce="+document.getElementById("wppa-nonce").value,p.open("POST",a,!1),p.setRequestHeader("Content-type","application/x-www-form-urlencoded"),p.send(n),4==p.readyState&&200==p.status){var i=wppaEntityDecode(p.responseText).split("|"),o=i[0];i[0]="";var s=i.join("|").substring(1),l={modal:!0,resizable:!0,width:t,show:{effect:"fadeIn",duration:800},closeText:wppaCloseText};jQuery("#wppa-modal-container").html(s).dialog(l).dialog("open"),jQuery(".ui-dialog").css({boxShadow:"0px 0px 5px 5px #aaaaaa",padding:"8px",backgroundColor:"#cccccc",boxSizing:"content-box",zIndex:"9999"}),jQuery(".ui-dialog-titlebar").css({lineHeight:"0px",height:"24px"}),jQuery(".ui-dialog-title").html("<h2>"+o+"</h2>"),jQuery(".ui-button").css({position:"absolute",top:"12px",right:"12px"}),jQuery(".ui-button").attr("title",wppaCloseText)}}function wppaAjaxUpdateOptionValue(r,e,t){var p="action=wppa&wppa-action=update-option&wppa-option="+wppaEncode(r)+"&wppa-nonce="+document.getElementById("wppa-nonce").value;0!=e&&(p+="number"==typeof e?"&value="+e:t?"&value="+wppaGetSelectionEnumByClass("."+r,","):"&value="+wppaEncode(e.value)),jQuery.ajax({url:wppaAjaxUrl,data:p,async:!0,type:"POST",timeout:1e5,beforeSend:function(e){jQuery("#img_"+r.replace("#","H")).attr("src",wppaImageDirectory+"spinner.gif")},success:function(e,t,p){var a=wppaTrim(e).split("||");if(""!=a[0])alert("The server returned unexpected output:\n"+a[0]);else{switch(a[1]){case"0":jQuery("#img_"+r.replace("#","H")).attr("src",wppaImageDirectory+"tick.png"),a[3]&&alert(a[3]),_wppaRefreshAfter&&(_wppaRefreshAfter=!1,document.location.reload(!0));break;default:jQuery("#img_"+r.replace("#","H")).attr("src",wppaImageDirectory+"cross.png"),a[3]&&alert(a[3])}if(jQuery("#img_"+r.replace("#","H")).attr("title",a[2]),a[4])for(var n,i,o,s=a[4].split(";"),l=0;l<s.length;)n=s[l].split(":"),i=jQuery("#"+n[0]).html(),o=n[1],""!=i&&""==o&&(o='<input type="button" class="button-secundary" style="border-radius:3px;font-size:11px;height:18px;margin: 0 4px;padding:0px;color:red;background-color:pink;" onclick="document.location.reload(true)" value="Reload" />'),jQuery("#"+n[0]).html(o),l++}},error:function(e){jQuery("#img_"+r.replace("#","H")).attr("src",wppaImageDirectory+"cross.png"),document.getElementById("img_"+r).title="Communication error"},complete:function(e){wppaCheckInconsistencies(),"spinner_shape"!=r&&"icon_corner_style"!=r||(wppaAjaxGetSpinnerHtml("normal","wppa-spin-pre-1"),wppaAjaxGetSpinnerHtml("lightbox","wppa-spin-pre-2")),"svg_color"!=r&&"svg_bg_color"!=r||wppaAjaxGetSpinnerHtml("normal","wppa-spin-pre-1"),"ovl_svg_color"!=r&&"ovl_svg_bg_color"!=r||wppaAjaxGetSpinnerHtml("lightbox","wppa-spin-pre-2")}})}function wppaEncode(e){var t;if(void 0!==e){if("number"==typeof e)return e;var p=(t=(t=e.replace(/#/g,"||HASH||")).replace(/&/g,"||AMP||")).split("+"),a=0;for(t="";a<p.length;)t+=p[a],++a<p.length&&(t+="||PLUS||");return t}}function wppaCheckInconsistencies(){jQuery("#use_thumb_popup").prop("checked")&&"lightbox"==jQuery("#thumb_linktype").val()?jQuery(".popup-lightbox-err").css("display",""):jQuery(".popup-lightbox-err").css("display","none")}function wppaGetXmlHttp(){return window.XMLHttpRequest?xmlhttp=new XMLHttpRequest:xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"),xmlhttp}function wppaPhotoStatusChange(e){if(jQuery("#psdesc-"+e).css({display:"none"}),jQuery("#status-"+e)){if(elm=document.getElementById("status-"+e),"pending"!=elm.value&&"scheduled"!=elm.value||jQuery("#photoitem-"+e).css({backgroundColor:"#ffebe8",borderColor:"#cc0000"}),"publish"==elm.value&&jQuery("#photoitem-"+e).css({backgroundColor:"#ffffe0",borderColor:"#e6db55"}),"featured"==elm.value){jQuery("#photoitem-"+e).css({backgroundColor:"#e0ffe0",borderColor:"#55ee55"});var t=document.getElementById("pname-"+e).value.split(".");if(1<t.length)for(var p=0;p<t.length;)"jpg"!=t[p]&&"JPG"!=t[p]||jQuery("#psdesc-"+e).css({display:""}),p++}"gold"==elm.value&&jQuery("#photoitem-"+e).css({backgroundColor:"#eeeecc",borderColor:"#ddddbb"}),"silver"==elm.value&&jQuery("#photoitem-"+e).css({backgroundColor:"#ffffff",borderColor:"#eeeeee"}),"bronze"==elm.value&&jQuery("#photoitem-"+e).css({backgroundColor:"#ddddbb",borderColor:"#ccccaa"}),"scheduled"==elm.value?jQuery(".wppa-datetime-"+e).css("display",""):jQuery(".wppa-datetime-"+e).css("display","none"),jQuery("#scheduledel-"+e).prop("checked")?jQuery(".wppa-del-datetime-"+e).css("display",""):jQuery(".wppa-del-datetime-"+e).css("display","none")}}function wppaSetComBgCol(e){"approved"==jQuery("#com-stat-"+e).val()?jQuery("#com-tr-"+e).css({backgroundColor:"#ffffe0"}):jQuery("#com-tr-"+e).css({backgroundColor:"#ffebe8"})}function wppaCheckLinkPageErr(e){var t="nil";document.getElementById(e+"_linktype")&&(t=document.getElementById(e+"_linktype").value),"0"!=document.getElementById(e+"_linkpage").value||"nil"!=t&&"photo"!=t&&"single"!=t&&"album"!=t&&"content"!=t&&"slide"!=t&&"plainpage"!=t?jQuery("#"+e+"-err").css({display:"none"}):jQuery("#"+e+"-err").css({display:""})}function wppaAddCat(e,t){wppaAddTag(e,t)}function wppaAddTag(e,t){var p=document.getElementById(t);e&&(p.value?p.value+=","+e:p.value=e,"-clear-"==e&&(p.value=""))}function wppaRefresh(e){var t=new String(document.location).split("#")[0]+"#"+e;document.location=t}function wppaReload(e){e?(url=document.location.href.split("#"),document.location.href=url[0]+e,setTimeout(function(){document.location.reload(!0)},10)):document.location.reload(!0)}var wppaFeCount=0;function wppaFeAjaxLog(e){"in"==e&&(0==wppaFeCount&&jQuery("#wppa-fe-exit").css("display","none"),wppaFeCount++,jQuery("#wppa-fe-count").html(wppaFeCount)),"out"==e&&(1==wppaFeCount&&(jQuery("#wppa-fe-count").html(""),jQuery("#wppa-fe-exit").css("display","inline"),wppaFeCount--),1<wppaFeCount&&(wppaFeCount--,jQuery("#wppa-fe-count").html(wppaFeCount)))}function wppaArrayToEnum(e,t){temp=e.sort(function(e,t){return e-t});for(var p,a="",n=-1,i=-2,o=0,s=!1,l=0;l<e.length;)0!=(p=e[l].valueOf())&&(o=n,p==++o?s=!0:s?(a+=n==i?t+n+t+p:t+t+n+t+p,s=!1):a+=t+p,s||(i=p,i++),n=p),l++;for(s&&(a+=".."+n);"."==a.substr(0,1);)a=a.substr(1);for(;a.substr(0,1)==t;)a=a.substr(1);return a}function wppaGetSelEnumToId(e,t){p=jQuery("."+e);var a=[];for(i=0,j=0;i<p.length;)p[i].selected&&(a[j]=p[i].value,j++),i++;jQuery("#"+t).val(wppaArrayToEnum(a,"."))}function wppaGetSelectionEnumByClass(e,t){var p,a=[],n=0,i=0;for(t||(t="."),p=jQuery(e),i=n=0;n<p.length;)p[n].selected&&(a[i]=p[n].value,i++),n++;return wppaArrayToEnum(a,t)}function wppaEditSearch(e,t){var p=jQuery("#"+t).val();0==p.length?alert("Please enter searchstring"):document.location.href=e+"&wppa-searchstring="+p}function wppaEditTrash(e){document.location.href=e}function wppaExportDbTable(a){jQuery.ajax({url:wppaAjaxUrl,data:"action=wppa&wppa-action=export-table&table="+a,async:!0,type:"GET",timeout:1e5,beforeSend:function(e){jQuery("#"+a+"-spin").css("display","inline")},success:function(e,t,p){var a=e.split("||");"0"==a[1]?document.location=a[2]:alert("Error: "+a[1]+"\n\n"+a[2])},error:function(e,t,p){alert("Export Db Table "+a+" failed. Error = "+p+", status = "+t)},complete:function(e,t,p){jQuery("#"+a+"-spin").css("display","none")}})}function wppaDismissAdminNotice(e,t){wppaAjaxUpdateOptionCheckBox(e,t),jQuery("#wppa-wr-").css("display","none")}function wppaAjaxUpdateTogo(o){jQuery.ajax({url:wppaAjaxUrl,data:"action=wppa&wppa-action=gettogo&slug="+o,async:!0,type:"GET",timeout:1e5,beforeSend:function(e){},success:function(e,t,p){var a=e.split("|");jQuery("#"+o+"_togo").html(a[0]);var n=jQuery("#"+o+"_status").html(),i=a[1];""!=n&&""==i&&(i='<input type="button" class="button-secundary" style="border-radius:3px;font-size:11px;height:18px;margin: 0 4px;padding:0px;color:red;background-color:pink;" onclick="document.location.reload(true)" value="Reload" />'),jQuery("#"+o+"_status").html(i),setTimeout(function(){wppaAjaxUpdateTogo(o)},5e3)},error:function(e){},complete:function(e){}})}function wppaIsEmpty(e){return null==e||(void 0===e||(""==e||(0==e||0==e)))}function wppaTimedConfirm(e){var t={modal:!0,resizable:!1,width:400,show:{effect:"fadeIn",duration:800},closeText:"X",buttons:[{text:"NO",click:function(){jQuery(this).dialog("close")}},{text:"YES",click:function(){jQuery(this).dialog("close")}}]};jQuery("#wppa-modal-container").html(e).dialog(t).dialog("open"),jQuery(".ui-dialog").css({boxShadow:"0px 0px 5px 5px #aaaaaa",padding:"8px",backgroundColor:"#cccccc",boxSizing:"content-box",zIndex:"9999"}),jQuery(".ui-dialog-titlebar").css({lineHeight:"0px",height:"32px"}),jQuery(".ui-button").css({float:"right",position:"relative",bottom:"40px"}),jQuery(".ui-dialog-titlebar-close").css({display:"none"}),jQuery(".ui-button").attr("title",wppaCloseText),setTimeout(function(){jQuery(".ui-button").trigger("click")},6e4)}function wppaAjaxGetSpinnerHtml(e,n){jQuery.ajax({url:wppaAjaxUrl,data:"action=wppa&wppa-action=update-option&wppa-option=getspinnerpreview&type="+e+"&wppa-nonce="+document.getElementById("wppa-nonce").value,async:!0,type:"GET",timeout:1e5,beforeSend:function(e){},success:function(e,t,p){var a=e.split("|");jQuery("#"+n).html(a[0])},error:function(e){},complete:function(e){}})}
js/wppa-lightbox.js CHANGED
@@ -3,7 +3,7 @@
3
  // Conatins lightbox modules
4
  // Dependancies: wppa.js and default wp jQuery library
5
  //
6
- var wppaLightboxVersion = '7.2.02';
7
 
8
  // Global inits
9
  var wppaNormsBtnOpac = 0.75;
@@ -1337,10 +1337,12 @@ wppaConsoleLog( 'wppaOvlRun, running='+wppaOvlRunning );
1337
  function wppaOvlShowPrev() {
1338
  wppaConsoleLog( 'wppaOvlShowPrev' );
1339
 
 
 
 
1340
  wppaOvlFsPhotoId = 0;
1341
  wppaPhotoId = 0;
1342
 
1343
- if ( wppaOvlIsSingle ) return false;
1344
  if ( wppaOvlIdx < 1 ) {
1345
  wppaOvlIdx = wppaOvlUrls.length; // Restart at last
1346
  }
@@ -1352,13 +1354,15 @@ wppaConsoleLog( 'wppaOvlShowPrev' );
1352
  function wppaOvlShowNext() {
1353
  wppaConsoleLog( 'wppaOvlShowNext' );
1354
 
 
 
 
1355
  // Show spinner
1356
  jQuery( '#wppa-ovl-spin' ).show();
1357
 
1358
  wppaOvlFsPhotoId = 0;
1359
  wppaPhotoId = 0;
1360
 
1361
- if ( wppaOvlIsSingle ) return false;
1362
  if ( wppaOvlIdx >= ( wppaOvlUrls.length-1 ) ) {
1363
  wppaOvlIdx = -1; // Restart at first
1364
  }
@@ -1565,7 +1569,7 @@ function wppaShowFsButtons(opac) {
1565
  // Click on image
1566
  function wppaOvlImgClick( event ) {
1567
 
1568
- if ( wppaOvlBrowseOnClick ) {
1569
  if ( event.screenX < ( screen.width / 2 ) ) {
1570
  wppaOvlShowPrev();
1571
  }
3
  // Conatins lightbox modules
4
  // Dependancies: wppa.js and default wp jQuery library
5
  //
6
+ var wppaLightboxVersion = '7.2.03';
7
 
8
  // Global inits
9
  var wppaNormsBtnOpac = 0.75;
1337
  function wppaOvlShowPrev() {
1338
  wppaConsoleLog( 'wppaOvlShowPrev' );
1339
 
1340
+ // Not on a single image
1341
+ if ( wppaOvlIsSingle ) return false;
1342
+
1343
  wppaOvlFsPhotoId = 0;
1344
  wppaPhotoId = 0;
1345
 
 
1346
  if ( wppaOvlIdx < 1 ) {
1347
  wppaOvlIdx = wppaOvlUrls.length; // Restart at last
1348
  }
1354
  function wppaOvlShowNext() {
1355
  wppaConsoleLog( 'wppaOvlShowNext' );
1356
 
1357
+ // Not on a single image
1358
+ if ( wppaOvlIsSingle ) return false;
1359
+
1360
  // Show spinner
1361
  jQuery( '#wppa-ovl-spin' ).show();
1362
 
1363
  wppaOvlFsPhotoId = 0;
1364
  wppaPhotoId = 0;
1365
 
 
1366
  if ( wppaOvlIdx >= ( wppaOvlUrls.length-1 ) ) {
1367
  wppaOvlIdx = -1; // Restart at first
1368
  }
1569
  // Click on image
1570
  function wppaOvlImgClick( event ) {
1571
 
1572
+ if ( wppaOvlBrowseOnClick && ! wppaOvlIsSingle ) {
1573
  if ( event.screenX < ( screen.width / 2 ) ) {
1574
  wppaOvlShowPrev();
1575
  }
js/wppa-lightbox.min.js CHANGED
@@ -1 +1 @@
1
- var wppaSavedContainerHeight,wppaSavedMarginLeft,wppaSavedMarginTop,wppaSavedImageWidth,wppaSavedImageHeight,wppaRenderer,wppaScene,wppaCamera,wppaSphere,wppaSphereMaterial,wppaSphereMesh,wppaLightboxVersion="7.2.02",wppaNormsBtnOpac=.75,wppaIsVideo=!1,wppaHasAudio=!1,wppaOvlIsPdf=!1,wppaOvlImgs=[],wppaKbHandlerInstalled=!1,wppaOvlMode="",wppaOvlCurIdx=0,wppaOvlSvgInverse=!1,wppaOvlFsExitBtnSize="48",wppaOvlActivePanorama=0,wppaOvlHasPanoramas=!1,wppaGlobalOvlPanoramaId=0,wppaOvlBrowseOnClick=!1,wppaSavedContainerWidth=0;function wppaDoOnOrientationChange(p){"normal"!=wppaOvlMode&&document.getElementById("wppa-overlay-img")&&setTimeout("wppaOvlShow( "+wppaOvlIdx+" )",10)}function wppaOvlKeyboardHandler(p){var a,e;e=(a=null==p?event.keyCode:p.keyCode,27);var t=String.fromCharCode(a).toLowerCase();switch(a){case e:wppaStopVideo(mocc),"normal"!=wppaOvlMode&&wppaOvlNorm(!0),wppaOvlHide();break;case 37:wppaOvlShowPrev();break;case 39:wppaOvlShowNext()}switch(t){case"p":wppaOvlShowPrev();break;case"n":wppaOvlShowNext();break;case"s":wppaOvlStartStop();break;case"d":jQuery("#wppa-ovl-legenda-1").css("visibility","hidden"),jQuery("#wppa-ovl-legenda-2").css("visibility","hidden"),wppaShowLegenda="hidden";break;case"f":wppaOvlFull();break;case"l":wppaOvlNorm();break;case"q":case"x":wppaStopVideo(mocc),"normal"!=wppaOvlMode&&wppaOvlNorm(!0),wppaOvlHide()}return!1}function wppaOvlFull(p){wppaConsoleLog("wppaOvlFull"),wppaNormsBtnOpac=.75;var a=wppaOvlMode;p||wppaOvlStepMode();var e=document.getElementById("wppa-overlay-ic");e&&(!p&&"normal"!=a||(e.requestFullscreen?e.requestFullscreen():e.mozRequestFullScreen?e.mozRequestFullScreen():e.webkitRequestFullscreen&&e.webkitRequestFullscreen()),"normal"==wppaOvlMode&&(document.cancelFullScreen?document.cancelFullScreen():document.mozCancelFullScreen?document.mozCancelFullScreen():document.webkitCancelFullScreen&&document.webkitCancelFullScreen()),setTimeout(function(){wppaShowFsButtons(.75)},30),jQuery("#wppa-ovl-legenda-1").html(""))}function wppaOvlNorm(p){wppaConsoleLog("wppaOvlNorm"),wppaOvlMode="normal",wppaNormsBtnOpac=.75,document.cancelFullScreen?document.cancelFullScreen():document.mozCancelFullScreen?document.mozCancelFullScreen():document.webkitCancelFullScreen&&document.webkitCancelFullScreen(),p?wppaOvlMode=wppaOvlModeInitial:(setTimeout(function(){wppaShowFsButtons(.75)},30),setTimeout(function(){wppaOvlShow(wppaOvlIdx)},50))}function wppaOvlShow(p){var a,e;if(wppaConsoleLog("wppaOvlShow arg="+p),0<wppaOvlActivePanorama?jQuery("#wppa-overlay-ic").css({top:0,left:0}):jQuery("#wppa-overlay-ic").css({top:"50%",left:"50%"}),wppaOvlFirst&&(jQuery("#weaver-final").removeClass("wvr-hide-bang"),jQuery("#wppa-overlay-bg").stop().fadeTo(3,wppaOvlOpacity),wppaKbHandlerInstalled||(jQuery(document).on("keydown",wppaOvlKeyboardHandler),wppaKbHandlerInstalled=!0),jQuery("#wppa-overlay-bg").css({width:window.innerWidth,height:window.innerHeight}),"normal"!=wppaOvlModeInitial&&wppaOvlFull(!0)),"object"==typeof p){wppaOvlIds=[],wppaOvlUrls=[],wppaOvlTitles=[],wppaOvlAlts=[],wppaOvlVideoHtmls=[],wppaOvlAudioHtmls=[],wppaOvlPdfHtmls=[],wppaOvlVideoNaturalWidths=[],wppaOvlVideoNaturalHeights=[],wppaOvlIdx=0,wppaOvlPanoramaHtml=[],wppaOvlPanoramaIds=[],wppaOvlHasPanoramas=!(wppaOvlImgs=[]);var t=(p.rel?p.rel:!!jQuery(p).attr("data-rel")&&jQuery(p).attr("data-rel")).split("[");if(t[1]){var o,l,i=t[1],n=jQuery("a"),r=0;for(l=0;l<n.length;l++)o=n[l],1<(t=!!jQuery(o).attr("data-rel")&&jQuery(o).attr("data-rel").split("[")).length&&"wppa"==t[0]&&t[1]==i&&(wppaOvlUrls[r]=o.href,jQuery(o).attr("data-lbtitle")?wppaOvlTitles[r]=wppaRepairScriptTags(jQuery(o).attr("data-lbtitle")):wppaOvlTitles[r]=wppaRepairScriptTags(o.title),wppaOvlIds[r]=jQuery(o).attr("data-id")?jQuery(o).attr("data-id"):"0",wppaOvlAlts[r]=jQuery(o).attr("data-alt")?jQuery(o).attr("data-alt"):"",wppaOvlVideoHtmls[r]=jQuery(o).attr("data-videohtml")?decodeURI(jQuery(o).attr("data-videohtml")):"",wppaOvlPdfHtmls[r]=jQuery(o).attr("data-pdfhtml")?decodeURI(jQuery(o).attr("data-pdfhtml")):"",wppaOvlAudioHtmls[r]=jQuery(o).attr("data-audiohtml")?decodeURI(jQuery(o).attr("data-audiohtml")):"",wppaOvlVideoNaturalWidths[r]=jQuery(o).attr("data-videonatwidth")?jQuery(o).attr("data-videonatwidth"):"",wppaOvlVideoNaturalHeights[r]=jQuery(o).attr("data-videonatheight")?jQuery(o).attr("data-videonatheight"):"",0<(a=jQuery(o).attr("data-panorama")?jQuery(o).attr("data-panorama"):"").length?(wppaOvlHasPanoramas=!0,e=a.indexOf("."),wppaOvlPanoramaHtml[r]=a.substr(e+1),wppaOvlPanoramaIds[r]=a.substr(0,e)):(wppaOvlPanoramaHtml[r]="",wppaOvlPanoramaIds[r]=0),decodeURI(jQuery(o).attr("data-pdfhtml"))==decodeURI(jQuery(p).attr("data-pdfhtml"))&&decodeURI(jQuery(o).attr("data-videohtml"))==decodeURI(jQuery(p).attr("data-videohtml"))&&decodeURI(jQuery(o).attr("data-audiohtml"))==decodeURI(jQuery(p).attr("data-audiohtml"))&&o.href==p.href&&(wppaOvlIdx=r,wppaConsoleLog("Found "+r+": "+p.href,"force")),r++)}else wppaOvlUrls[0]=p.href,jQuery(p).attr("data-lbtitle")?wppaOvlTitles[0]=wppaRepairScriptTags(jQuery(p).attr("data-lbtitle")):wppaOvlTitles[0]=wppaRepairScriptTags(p.title),wppaOvlIds[0]=jQuery(p).attr("data-id")?jQuery(p).attr("data-id"):"0",wppaOvlAlts[0]=jQuery(p).attr("data-alt")?jQuery(p).attr("data-alt"):"",wppaOvlVideoHtmls[0]=jQuery(p).attr("data-videohtml")?decodeURI(jQuery(p).attr("data-videohtml")):"",wppaOvlAudioHtmls[0]=jQuery(p).attr("data-audiohtml")?decodeURI(jQuery(p).attr("data-audiohtml")):"",wppaOvlPdfHtmls[0]=jQuery(p).attr("data-pdfhtml")?decodeURI(jQuery(p).attr("data-pdfhtml")):"",wppaOvlVideoNaturalWidths[0]=jQuery(p).attr("data-videonatwidth")?jQuery(p).attr("data-videonatwidth"):"",wppaOvlVideoNaturalHeights[0]=jQuery(p).attr("data-videonatheight")?jQuery(p).attr("data-videonatheight"):"",0<(a=jQuery(p).attr("data-panorama")?jQuery(p).attr("data-panorama"):"").length?(wppaOvlHasPanoramas=!0,e=a.indexOf("."),wppaOvlPanoramaHtml[0]=a.substr(e+1),wppaOvlPanoramaIds[0]=a.substr(0,e)):(wppaOvlPanoramaHtml[0]="",wppaOvlPanoramaIds[0]=0),wppaOvlIdx=0}else wppaOvlIdx=p;wppaOvlOpen=!0,setTimeout(function(){_wppaOvlShow(wppaOvlIdx)},1)}function _wppaOvlShow(p){if(wppaConsoleLog("_wppaOvlShow, idx="+p,"force"),wppaOvlCurIdx=p,wppaOvlFirst&&jQuery("#wppa-ovl-spin").show(),wppaIsVideo=""!=wppaOvlVideoHtmls[p],wppaHasAudio=""!=wppaOvlAudioHtmls[p],wppaOvlIsPdf=""!=wppaOvlPdfHtmls[p],0<wppaOvlUrls[p].length&&!wppaIsVideo&&(wppaOvlImgs[p]=new Image,wppaOvlImgs[p].src=wppaOvlUrls[p],wppaConsoleLog("Preloading "+(p+1)+"/"+wppaOvlUrls.length+" (current)"),!wppaIsIe&&!wppaOvlImgs[p].complete&&wppaOvlOpen))return wppaConsoleLog("Retrying preload current image"),void setTimeout("_wppaOvlShow("+p+")",500);var a,e;if(a=wppaOvlIdx==wppaOvlUrls.length-1?0:wppaOvlIdx+1,""==wppaOvlVideoHtmls[a]&&wppaOvlOpen&&(wppaOvlImgs[a]=new Image,wppaOvlImgs[a].src=wppaOvlUrls[a],wppaConsoleLog("Preloading > "+(a+1))),!wppaOvlRunning&&wppaOvlOpen&&(e=0==wppaOvlIdx?wppaOvlUrls.length-1:wppaOvlIdx-1,""==wppaOvlVideoHtmls[e]&&(wppaOvlImgs[e]=new Image,wppaOvlImgs[e].src=wppaOvlUrls[e],wppaConsoleLog("Preloading < "+(e+1)))),_bumpViewCount(wppaOvlIds[p]),wppaOvlIsSingle=1==wppaOvlUrls.length,0<wppaOvlPanoramaIds[p]?(wppaOvlActivePanorama=wppaOvlPanoramaIds[p],jQuery("#wppa-overlay-ic").css({top:0,left:0})):(wppaOvlActivePanorama=0,jQuery("#wppa-overlay-ic").css({top:"50%",left:"50%",display:"block"})),"normal"!=wppaOvlMode||wppaOvlActivePanorama){wppaOvlActivePanorama?(l=wppaOvlPanoramaHtml[p]+"<div style=\"height: 20px; width: 100%; position:absolute; top:0; left:0;\" onmouseover=\"jQuery('#wppa-ovl-legenda-2').css('visibility','visible');\" onmouseout=\"jQuery('#wppa-ovl-legenda-2').css('visibility','hidden');wppaShowLegenda='hidden';\" >",wppaOvlShowLegenda&&"normal"!=wppaOvlMode&&(l+='<div id="wppa-ovl-legenda-2" style="position:fixed; left:0; top:0; background-color:'+("black"==wppaOvlTheme?"#272727":"#a7a7a7")+"; color:"+("black"==wppaOvlTheme?"#a7a7a7":"#272727")+"; visibility:"+wppaShowLegenda+';" >Mode=fullscreen. '+(wppaOvlIsSingle?wppaOvlFullLegendaSinglePanorama:wppaOvlFullLegendaPanorama)+"</div>")):(wppaIsVideo?l='<div id="wppa-ovl-full-bg" style="position:fixed; width:'+screen.width+"px; height:"+screen.height+'px; left:0px; top:0px; text-align:center;" ><video id="wppa-overlay-img" controls preload="metadata"'+(wppaOvlVideoStart?" autoplay":"")+' ontouchstart="wppaTouchStart( event, \'wppa-overlay-img\', -1 );" ontouchend="wppaTouchEnd( event );" ontouchmove="wppaTouchMove( event );" ontouchcancel="wppaTouchCancel( event );" onclick="wppaOvlImgClick( event );" onpause="wppaOvlVideoPlaying = false;" onplay="wppaOvlVideoPlaying = true;" style="border:none; width:'+screen.width+'px; box-shadow:none; position:absolute;" alt="'+wppaOvlAlts[p]+'" >'+wppaOvlVideoHtmls[p]+"</video><div style=\"height: 20px; width: 100%; position:absolute; top:0; left:0;\" onmouseover=\"jQuery('#wppa-ovl-legenda-2').css('visibility','visible');\" onmouseout=\"jQuery('#wppa-ovl-legenda-2').css('visibility','hidden');wppaShowLegenda='hidden';\" >":wppaOvlIsPdf?l='<div id="wppa-ovl-full-bg" style="position:fixed; width:'+screen.width+"px; height:"+screen.height+'px; left:0px; top:0px; text-align:center;" ><iframe id="wppa-overlay-img" '+wppaOvlPdfHtmls[p]+' ontouchstart="wppaTouchStart( event, \'wppa-overlay-img\', -1 );" ontouchend="wppaTouchEnd( event );" ontouchmove="wppaTouchMove( event );" ontouchcancel="wppaTouchCancel( event );" onclick="wppaOvlImgClick( event );" style="border:none; width:'+screen.width+'px; box-shadow:none; position:absolute;" alt="'+wppaOvlAlts[p]+"\" ></iframe><div style=\"height: 20px; width: 100%; position:absolute; top:0; left:0;\" onmouseover=\"jQuery('#wppa-ovl-legenda-2').css('visibility','visible');\" onmouseout=\"jQuery('#wppa-ovl-legenda-2').css('visibility','hidden');wppaShowLegenda='hidden';\" >":(l='<div id="wppa-ovl-full-bg" style="position:fixed; width:'+screen.width+"px; height:"+screen.height+'px; left:0px; top:0px; text-align:center;" ><img id="wppa-overlay-img" ontouchstart="wppaTouchStart( event, \'wppa-overlay-img\', -1 );" ontouchend="wppaTouchEnd( event );" ontouchmove="wppaTouchMove( event );" ontouchcancel="wppaTouchCancel( event );" onclick="wppaOvlImgClick( event );" src="'+wppaOvlUrls[p]+'" style="border:none; width:'+screen.width+'px; visibility:hidden; box-shadow:none; position:absolute;" alt="'+wppaOvlAlts[p]+'" />',wppaHasAudio&&(l+='<audio id="wppa-overlay-audio" class="wppa-overlay-audio" data-from="wppa" preload="metadata"'+(wppaOvlAudioStart?" autoplay":"")+' onpause="wppaOvlAudioPlaying = false;" onplay="wppaOvlAudioPlaying = true;" style="width:100%;position:absolute;left:0px;bottom:0px;padding:0;" controls >'+wppaOvlAudioHtmls[p]+"</audio>"),l+="<div style=\"height: 20px; width: 100%; position:absolute; top:0; left:0;\" onmouseover=\"jQuery('#wppa-ovl-legenda-2').css('visibility','visible');\" onmouseout=\"jQuery('#wppa-ovl-legenda-2').css('visibility','hidden');wppaShowLegenda='hidden';\" >"),wppaOvlShowLegenda&&(l+='<div id="wppa-ovl-legenda-2" style="position:fixed; left:0; top:0; background-color:'+("black"==wppaOvlTheme?"#272727":"#a7a7a7")+"; color:"+("black"==wppaOvlTheme?"#a7a7a7":"#272727")+"; visibility:"+wppaShowLegenda+';" >Mode='+wppaOvlMode+". "+(wppaOvlIsSingle?wppaOvlFullLegendaSingle:wppaOvlFullLegenda)+"</div>")),l+="</div>";var t=(wppaIsMobile,"0.1");return l+='<div id="wppa-exit-btn" style="height:'+wppaOvlFsExitBtnSize+"px;z-index:100098;position:fixed;top:0;right:0;opacity:"+wppaNormsBtnOpac+';" onclick="wppaOvlHide()" onmouseover="jQuery(this).stop().fadeTo(300,1);" ontouchstart="jQuery(this).stop().fadeTo(300,1);" onmouseout="jQuery(this).stop().fadeTo(300,'+t+");wppaNormsBtnOpac="+t+';" ontouchend="jQuery(this).stop().fadeTo(300,'+t+");wppaNormsBtnOpac="+t+';" >'+wppaSvgHtml("Exit",wppaOvlFsExitBtnSize+"px",!0,!0,"0","0","0","0")+"</div>","normal"!=wppaOvlMode&&(l+='<div id="wppa-norms-btn" style="height:48px;z-index:100098;position:fixed;top:0;right:'+wppaOvlFsExitBtnSize+"px;opacity:"+wppaNormsBtnOpac+';" onclick="wppaOvlNorm()" onmouseover="jQuery(this).stop().fadeTo(300,1);" ontouchstart="jQuery(this).stop().fadeTo(300,1);" onmouseout="jQuery(this).stop().fadeTo(300,'+t+");wppaNormsBtnOpac="+t+';" ontouchend="jQuery(this).stop().fadeTo(300,'+t+");wppaNormsBtnOpac="+t+';" >'+wppaSvgHtml("Exit-Full-Screen",wppaOvlFsExitBtnSize+"px",!0,!0,"0","0","0","0")+"</div>"),(wppaIsVideo||wppaHasAudio)&&wppaOvlFsPhotoId==wppaPhotoId&&0!=wppaPhotoId||(wppaStopVideo(0),wppaStopAudio(),jQuery("#wppa-overlay-ic").html(l)),0<wppaOvlPanoramaIds[p]&&wppaOvlIsSingle&&jQuery(".wppa-pan-prevnext").hide(),wppaProtect(),wppaOvlIsVideo=wppaIsVideo,setTimeout("wppaOvlFormatFull()",10),wppaIsVideo||wppaHasAudio?setTimeout("wppaOvlUpdateFsId()",20):wppaOvlFsPhotoId=0,wppaOvlFirst=!1,wppaShowFsButtons(),!1}wppaOvlFsPhotoId=0,wppaPhotoId=0,wppaStopVideo(0);var o="black"==wppaOvlTheme?"#a7a7a7":"#272727";wppaOvlFontColor&&(o=wppaOvlFontColor);wppaOvlUrls.length;jQuery("#wppa-overlay-ic").css({width:wppaSavedContainerWidth,marginLeft:wppaSavedMarginLeft,marginTop:wppaSavedMarginTop});var l="";l+='<div id="img-sb-img-cont" style="position:relative;line-height:0;" >',wppaIsVideo?(l+='<video id="wppa-overlay-img" onmouseover="jQuery(\'.wppa-ovl-nav-btn\').stop().fadeTo(200,0.8);" onmouseout="jQuery(\'.wppa-ovl-nav-btn\').stop().fadeTo(200,0);" preload="metadata"'+(wppaOvlVideoStart?" autoplay":"")+' onpause="wppaOvlVideoPlaying = false;" onplay="wppaOvlVideoPlaying = true;" ontouchstart="wppaTouchStart( event, \'wppa-overlay-img\', -1 );" ontouchend="wppaTouchEnd( event );" ontouchmove="wppaTouchMove( event );" ontouchcancel="wppaTouchCancel( event );" onclick="wppaOvlImgClick( event );" controls style="border-width:'+wppaOvlBorderWidth+"px "+wppaOvlBorderWidth+"px 0;border-style:solid;border-color:"+wppaOvlTheme+";width:"+wppaSavedImageWidth+"px;height:"+wppaSavedImageHeight+"px;box-shadow:none;box-sizing:content-box;position:relative;border-top-left-radius:"+wppaOvlRadius+"px;border-top-right-radius:"+wppaOvlRadius+'px;margin:0;padding:0;" alt="'+wppaOvlAlts[p]+'" >'+wppaOvlVideoHtmls[p]+"</video>",wppaOvlIsVideo=!0):wppaOvlIsPdf?l+="<iframe "+wppaOvlPdfHtmls[p]+' id="wppa-overlay-img" onmouseover="jQuery(\'.wppa-ovl-nav-btn\').stop().fadeTo(200,0.8);" onmouseout="jQuery(\'.wppa-ovl-nav-btn\').stop().fadeTo(200,0);" ontouchstart="wppaTouchStart( event, \'wppa-overlay-img\', -1 );" ontouchend="wppaTouchEnd( event );" ontouchmove="wppaTouchMove( event );" ontouchcancel="wppaTouchCancel( event );" onclick="wppaOvlImgClick( event );" style="border-width:'+wppaOvlBorderWidth+"px "+wppaOvlBorderWidth+"px 0;border-style:solid;border-color:"+wppaOvlTheme+";width:"+wppaSavedImageWidth+"px;height:"+wppaSavedImageHeight+"px;box-shadow:none;box-sizing:content-box;position:relative;border-top-left-radius:"+wppaOvlRadius+"px;border-top-right-radius:"+wppaOvlRadius+'px;margin:0;padding:0;" alt="'+wppaOvlAlts[p]+'" ></iframe>':(l+='<img id="wppa-overlay-img" onmouseover="jQuery(\'.wppa-ovl-nav-btn\').stop().fadeTo(200,0.8);" onmouseout="jQuery(\'.wppa-ovl-nav-btn\').stop().fadeTo(200,0);" ontouchstart="wppaTouchStart( event, \'wppa-overlay-img\', -1 );" ontouchend="wppaTouchEnd( event );" ontouchmove="wppaTouchMove( event );" ontouchcancel="wppaTouchCancel( event );" onclick="wppaOvlImgClick( event );" src="'+wppaOvlUrls[p]+'" style="border-width:'+wppaOvlBorderWidth+"px "+wppaOvlBorderWidth+"px 0;border-style:solid;border-color:"+wppaOvlTheme+";width:"+wppaSavedImageWidth+"px;height:"+wppaSavedImageHeight+"px;box-shadow:none;box-sizing:content-box;position:relative;border-top-left-radius:"+wppaOvlRadius+"px;border-top-right-radius:"+wppaOvlRadius+'px;margin:0;padding:0;" alt="'+wppaOvlAlts[p]+'" />',wppaHasAudio&&(l+='<audio id="wppa-overlay-audio" class="wppa-overlay-audio" data-from="wppa" preload="metadata" onpause="wppaOvlAudioPlaying = false;" onplay="wppaOvlAudioPlaying = true;" style="width:100%;position:absolute;box-shadow:none;left:0;bottom:0;padding:0 '+wppaOvlBorderWidth+'px;margin:0;background-color:transparent;box-sizing:border-box;" controls >'+wppaOvlAudioHtmls[p]+"</audio>"),wppaOvlIsVideo=!1),!wppaOvlShowStartStop||wppaOvlIsSingle||wppaIsVideo||wppaOvlIsPdf||(l+='<div id="wppa-ovl-start-stop-btn" class="wppa-ovl-nav-btn" style="z-index:100101;position:absolute;top:50%;margin-top:-24px;left:50%;margin-left:-24px;'+(-1==wppaOvlIdx?"visibility:hidden;":"")+"box-shadow:none;"+(wppaOvlFirst?"opacity:1;":"opacity:0;")+'" onclick="wppaOvlStartStop()" onmouseover="jQuery(this).stop().fadeTo(200,1);" onmouseout="jQuery(this).stop().fadeTo(200,0);" ontouchstart="jQuery(this).stop().fadeTo(200,1);" onload="jQuery(this).stop().fadeTo(5000,0);" >'+wppaSvgHtml(wppaOvlRunning?"Pause-Button":"Play-Button",wppaOvlIconSize,!0,!0,"0","20","50","50")+"</div>"),wppaOvlIsSingle||(l+='<div id="wppa-ovl-prev-btn" class="wppa-ovl-nav-btn" style="position:absolute;z-index:100101;width:48px;top:50%;margin-top:-24px;left:1px;box-shadow:none;'+(wppaOvlFirst?"opacity:1;":"opacity:0;")+'" onclick="wppaOvlShowPrev()" onmouseover="jQuery(this).stop().fadeTo(200,1);" onmouseout="jQuery(this).stop().fadeTo(200,0);" ontouchstart="jQuery(this).stop().fadeTo(200,1);" onload="jQuery(this).stop().fadeTo(5000,0);" >'+wppaSvgHtml("Prev-Button",wppaOvlIconSize,!0,!0)+"</div>",l+='<div id="wppa-ovl-next-btn" class="wppa-ovl-nav-btn" style="position:absolute;z-index:100101;width:48px;top:50%;margin-top:-24px;right:1px;box-shadow:none;'+(wppaOvlFirst?"opacity:1;":"opacity:0;")+'" onclick="wppaOvlShowNext()" onmouseover="jQuery(this).stop().fadeTo(200,1);" onmouseout="jQuery(this).stop().fadeTo(200,0);" ontouchstart="jQuery(this).stop().fadeTo(200,1);" onload="jQuery(this).stop().fadeTo(5000,0);" >'+wppaSvgHtml("Next-Button",wppaOvlIconSize,!0,!0)+"</div>"),l+="</div>";var i=!wppaOvlIsSingle&&wppaOvlShowCounter;return l+='<div id="wppa-overlay-txt-container" style="position:relative;padding:10px;background-color:'+wppaOvlTheme+";color:"+o+";text-align:center;font-family:"+wppaOvlFontFamily+";font-size:"+wppaOvlFontSize+"px;font-weight:"+wppaOvlFontWeight+";line-height:"+wppaOvlLineHeight+"px;box-shadow:none;border-bottom-left-radius:"+wppaOvlRadius+"px;border-bottom-right-radius:"+wppaOvlRadius+'px;" ><div id="wppa-overlay-txt" style="text-align:center;min-height:36px;width:100%;'+("auto"==wppaOvlTxtHeight?"max-height:200px;":"max-height:"+wppaOvlTxtHeight+"px;")+'overflow:auto;box-shadow:none;" >'+(i?wppaOvlIdx+1+"/"+wppaOvlUrls.length+"<br />":"")+wppaOvlTitles[p]+"</div>",jQuery("#wppa-overlay-ic").html(l),wppaShowFsButtons(),jQuery("#wppa-overlay-img").bind("contextmenu",function(p){return!1}),0==wppaOvlPanoramaIds[p]&&wppaOvlResize(),wppaOvlFirst&&wppaShowFsButtons(),!1}function wppaOvlSize(p){if(wppaConsoleLog("wppaOvlSize"),!wppaOvlActivePanorama){var a=document.getElementById("wppa-overlay-img"),e=document.getElementById("wppa-overlay-txt");if(a&&e&&"none"!=jQuery("#wppa-overlay-bg").css("display")){if("normal"==wppaOvlMode){var t,o,l,i,n,r,w,d=wppaWindowWidth(),v=wppaWindowHeight();l=wppaOvlIsVideo?(t=a.clientWidth,o=wppaOvlVideoNaturalWidths[wppaOvlCurIdx],wppaOvlVideoNaturalHeights[wppaOvlCurIdx]):wppaOvlIsPdf?(t=.9*wppaWindowWidth(),o=.9*wppaWindowWidth(),.9*wppaWindowHeight()):(t=a.clientWidth,o=a.naturalWidth,a.naturalHeight),void 0===o&&(o=a.clientWidth,l=a.clientHeight),(r=(i=(d-3*wppaOvlBorderWidth)/o)<(n=v/l)?i:n)<1&&(o=parseInt(o*r),l=parseInt(l*r));var s=jQuery("#wppa-overlay-txt").height();w="auto"==wppaOvlTxtHeight?(0==s&&(s=20+2*wppaOvlBorderWidth),v-s-20-2*wppaOvlBorderWidth):v-wppaOvlTxtHeight-20-2*wppaOvlBorderWidth;var u=parseInt(w*o/l),h=(wppaOvlPadTop,parseInt((d-u)/2),u);l<w&&(wppaOvlPadTop+(w-l)/2,parseInt((d-o)/2),h=o);var c=wppaSavedImageWidth-h<3&&h-wppaSavedImageWidth<3;return h<=10&&(l=180,c=!(o=h=240)),h=parseInt(h),wppaSavedImageWidth=parseInt(h),wppaSavedImageHeight=parseInt(h*l/o),wppaSavedMarginLeft=-parseInt(h/2+wppaOvlBorderWidth),wppaSavedContainerWidth=parseInt(h+2*wppaOvlBorderWidth),wppaSavedContainerHeight=parseInt(wppaSavedImageHeight+wppaOvlBorderWidth+jQuery("#wppa-overlay-txt-container").height()+20),wppaSavedMarginTop=-parseInt(wppaSavedContainerHeight/2),jQuery("#wppa-overlay-img").stop().animate({width:wppaSavedImageWidth,height:wppaSavedImageHeight},p),jQuery("#wppa-overlay-ic").stop().animate({width:wppaSavedContainerWidth,marginLeft:wppaSavedMarginLeft,marginTop:wppaSavedMarginTop},p),c?(jQuery("#wppa-ovl-spin").hide(),wppaConsoleLog("Done "+wppaOvlIdx),wppaOvlFirst=!1):(setTimeout(function(){wppaOvlSize(wppaOvlAnimSpeed)},p+10),wppaConsoleLog("Not done "+wppaOvlIdx+" saved="+wppaSavedImageWidth+", wid="+h+", cw="+t+", nw="+o+", img complete="+document.getElementById("wppa-overlay-img").complete)),!0}wppaOvlFormatFull()}else wppaConsoleLog("Lb quitted","force")}}function wppaOvlFormatFull(){if(wppaConsoleLog("wppaOvlFormatFull "+wppaOvlMode),wppaOvlOpen&&!(0<wppaOvlActivePanorama)){var p,a,e;if(wppaOvlIsVideo)p=document.getElementById("wppa-overlay-img"),a=wppaOvlVideoNaturalWidths[wppaOvlIdx],e=wppaOvlVideoNaturalHeights[wppaOvlIdx];else if(wppaOvlIsPdf)p=document.getElementById("wppa-overlay-img"),a=screen.width,e=screen.height;else{if(p=document.getElementById("wppa-overlay-img"),!(wppaIsIe||p&&p.complete))return void setTimeout("wppaOvlFormatFull()",10);a=p.naturalWidth,e=p.naturalHeight}var t=screen.width/screen.height,o=a/e,l=0,i=0,n=0,r=0,w=0,d=0,v="hidden";switch(wppaOvlMode){case"padded":r=o<t?(l=(screen.width-screen.height*o)/2,i=0,n=screen.height,screen.height*o):(l=0,i=(screen.height-screen.width/o)/2,n=screen.width/o,screen.width);break;case"stretched":i=l=0,n=screen.height,r=screen.width;break;case"clipped":r=o<t?(l=0,i=(screen.height-screen.width/o)/2,n=screen.width/o,screen.width):(l=(screen.width-screen.height*o)/2,i=0,n=screen.height,screen.height*o);break;case"realsize":(l=(screen.width-a)/2)<0&&(d=parseInt(-l),l=0),(i=(screen.height-e)/2)<0&&(w=parseInt(-i),i=0),n=e,r=a,v="auto"}return l=parseInt(l),i=parseInt(i),n=parseInt(n),r=parseInt(r),jQuery(p).css({height:n,width:r,marginLeft:l,marginTop:i,left:0,top:0,maxWidth:1e4}),jQuery(p).css({visibility:"visible"}),jQuery("#wppa-ovl-full-bg").css({overflow:v}),jQuery("#wppa-ovl-full-bg").scrollTop(w),jQuery("#wppa-ovl-full-bg").scrollLeft(d),jQuery("#wppa-ovl-spin").hide(),!0}}function wppaOvlUpdateFsId(){wppaConsoleLog("wppaOvlUpdateFsId"),wppaOvlFsPhotoId=wppaPhotoId}function wppaOvlStartAudio(){wppaConsoleLog("wppaOvlStartAudio");var p=document.getElementById("wppa-overlay-audio");p&&"function"==typeof p.play&&(p.play(),wppaConsoleLog("Audio play wppa-overlay-audio"))}function wppaOvlStepMode(){wppaConsoleLog("wppaOvlStepMode from "+wppaOvlMode);for(var p=new Array("normal","padded","stretched","clipped","realsize","padded"),a=0;a<p.length;){if(wppaOvlMode==p[a])return wppaOvlMode=p[a+1],void wppaOvlShow(wppaOvlIdx);a++}}function wppaOvlStartStop(){wppaConsoleLog("wppaOvlStartStop called. Running="+wppaOvlRunning),wppaOvlRunning?(wppaOvlRunning=!1,jQuery("#wppa-ovl-start-stop-btn").html(wppaSvgHtml(wppaOvlRunning?"Pause-Button":"Play-Button",wppaOvlIconSize,!0,!0,"0","20","50","50")),-1!=wppaOvlIdx&&(0!=wppaOvlIdx&&jQuery("#wppa-ovl-prev-btn").css("visibility","visible"),wppaOvlIdx!=wppaOvlUrls.length-1&&jQuery("#wppa-ovl-next-btn").css("visibility","visible"))):(jQuery("#wppa-ovl-start-stop-btn").html(wppaSvgHtml((wppaOvlRunning,"Pause-Button"),wppaOvlIconSize,!0,!0,"0","20","50","50")),wppaOvlRunning=!0,wppaOvlRun())}function wppaOvlRun(){if(wppaConsoleLog("wppaOvlRun, running="+wppaOvlRunning),wppaOvlRunning)if(wppaOvlVideoPlaying||wppaOvlAudioPlaying)setTimeout("wppaOvlRun()",50);else{if(!wppaIsVideo){var p=document.getElementById("wppa-overlay-img");if(p&&!wppaIsIe&&!p.complete)return wppaConsoleLog("Wait during run"),void setTimeout("wppaOvlRun()",50)}var a;a=wppaOvlIdx>=wppaOvlUrls.length-1?0:wppaOvlIdx+1,wppaOvlFsPhotoId=0,wppaPhotoId=0,wppaOvlShow(a),setTimeout("wppaOvlRun()",wppaOvlSlideSpeed)}}function wppaOvlShowPrev(){return wppaConsoleLog("wppaOvlShowPrev"),wppaOvlFsPhotoId=0,wppaPhotoId=0,wppaOvlIsSingle||(wppaOvlIdx<1&&(wppaOvlIdx=wppaOvlUrls.length),wppaOvlShow(wppaOvlIdx-1)),!1}function wppaOvlShowNext(){return wppaConsoleLog("wppaOvlShowNext"),jQuery("#wppa-ovl-spin").show(),wppaOvlFsPhotoId=0,wppaPhotoId=0,wppaOvlIsSingle||(wppaOvlIdx>=wppaOvlUrls.length-1&&(wppaOvlIdx=-1),wppaOvlShow(wppaOvlIdx+1)),!1}function wppaOvlHide(){wppaConsoleLog("wppaOvlHide"),wppaStopAudio(),"normal"!=wppaOvlMode&&wppaOvlNorm(!0),jQuery("#wppa-overlay-ic").html(""),jQuery("#wppa-overlay-bg").fadeOut(300),jQuery(document).off("keydown",wppaOvlKeyboardHandler),wppaOvlFirst=!(wppaKbHandlerInstalled=!1),wppaOvlRunning=!1,wppaOvlMode=wppaOvlModeInitial,wppaNormsBtnOpac=.75,jQuery("#wppa-ovl-spin").hide(),jQuery("#wppa-fulls-btn").stop().fadeOut(300),jQuery("#wppa-exit-btn").stop().fadeOut(300),jQuery("#wppa-ovl-spin").hide(),wppaOvlActivePanorama=0,wppaOvlOpen=!1}function wppaOvlOnclick(p){switch(wppaConsoleLog("wppaOvlOnClick"),wppaOvlOnclickType){case"none":break;case"close":"normal"==wppaOvlMode&&wppaOvlHide();break;case"browse":var a=p.screenX-window.screenX;48<p.clientY&&(a<screen.width/2?wppaOvlShowPrev():wppaOvlShowNext());break;default:alert("Unimplemented action: "+wppaOvlOnclickType)}return!0}function wppaInitOverlay(){wppaConsoleLog("wppaInitOverlay"),jQuery(".wp-caption").each(function(){var p=jQuery(this),a=p.find("IMG[alt]").attr("alt")||"",e=p.find(".wp-caption-text").html()||"",t=p.find("a"),o=a+"<br>"+e;t.attr("data-lbtitle")||t.attr("data-lbtitle",o)}),""==wppaOvlMode&&(wppaOvlMode=wppaOvlModeInitial);var p,a,e=jQuery("a"),t=[];for(wppaOvlFsPhotoId=0,wppaPhotoId=0,(wppaOvlActivePanorama=wppaOvlCurIdx=0)==wppaSavedContainerWidth&&(wppaSavedContainerWidth=240+2*wppaOvlBorderWidth,wppaSavedContainerHeight=180+3*wppaOvlBorderWidth+20+("auto"==wppaOvlTxtHeight?50:wppaOvlTxtHeight),wppaSavedMarginLeft=-(120+wppaOvlBorderWidth),wppaSavedMarginTop=-(90+wppaOvlBorderWidth+10+("auto"==wppaOvlTxtHeight?25:wppaOvlTxtHeight/2)),wppaSavedImageWidth=240,wppaSavedImageHeight=180+wppaOvlBorderWidth),a=0;a<e.length;a++)if(p=e[a],jQuery(p).attr("data-rel")?t=jQuery(p).attr("data-rel").split("["):p.rel?t=p.rel.split("["):t[0]="","wppa"==t[0])switch(wppaWppaOverlayActivated=!0,jQuery(p).on("click",function(p){wppaOvlShow(this),p.preventDefault()}),wppaMagnifierCursor){case"pointer":jQuery(p).css("cursor","pointer");break;case"":jQuery(p).css("cursor","default");break;default:jQuery(p).css("cursor","url( "+wppaImageDirectory+wppaMagnifierCursor+" ),auto")}wppaIsMobile&&window.addEventListener("orientationchange",wppaDoOnOrientationChange)}function wppaOvlResize(){wppaConsoleLog("wppaOvlResize"),0<wppaOvlActivePanorama||(setTimeout("wppaOvlSize( "+wppaOvlAnimSpeed+" )",10),wppaOvlAudioStart&&!wppaOvlAudioPlaying&&setTimeout("wppaOvlStartAudio()",100))}function wppaShowFsButtons(p){void 0!==p&&(wppaNormsBtnOpac=p),jQuery("#wppa-exit-btn").stop().fadeTo(3,wppaNormsBtnOpac),"normal"==wppaOvlMode?jQuery("#wppa-fulls-btn").stop().fadeTo(3,wppaNormsBtnOpac):jQuery("#wppa-norms-btn").stop().fadeTo(3,wppaNormsBtnOpac)}function wppaOvlImgClick(p){wppaOvlBrowseOnClick&&(p.screenX<screen.width/2?wppaOvlShowPrev():wppaOvlShowNext())}jQuery(document).ready(function(p){wppaInitOverlay()}),jQuery(window).resize(function(){jQuery("#wppa-overlay-bg").css({height:window.innerHeight,width:window.innerWidth}),wppaOvlResize()}),wppaConsoleLog("wppa-lightbox.js version "+wppaLightboxVersion+" loaded.","force");
1
+ var wppaSavedContainerHeight,wppaSavedMarginLeft,wppaSavedMarginTop,wppaSavedImageWidth,wppaSavedImageHeight,wppaRenderer,wppaScene,wppaCamera,wppaSphere,wppaSphereMaterial,wppaSphereMesh,wppaLightboxVersion="7.2.03",wppaNormsBtnOpac=.75,wppaIsVideo=!1,wppaHasAudio=!1,wppaOvlIsPdf=!1,wppaOvlImgs=[],wppaKbHandlerInstalled=!1,wppaOvlMode="",wppaOvlCurIdx=0,wppaOvlSvgInverse=!1,wppaOvlFsExitBtnSize="48",wppaOvlActivePanorama=0,wppaOvlHasPanoramas=!1,wppaGlobalOvlPanoramaId=0,wppaOvlBrowseOnClick=!1,wppaSavedContainerWidth=0;function wppaDoOnOrientationChange(p){"normal"!=wppaOvlMode&&document.getElementById("wppa-overlay-img")&&setTimeout("wppaOvlShow( "+wppaOvlIdx+" )",10)}function wppaOvlKeyboardHandler(p){var a,e;e=(a=null==p?event.keyCode:p.keyCode,27);var t=String.fromCharCode(a).toLowerCase();switch(a){case e:wppaStopVideo(mocc),"normal"!=wppaOvlMode&&wppaOvlNorm(!0),wppaOvlHide();break;case 37:wppaOvlShowPrev();break;case 39:wppaOvlShowNext()}switch(t){case"p":wppaOvlShowPrev();break;case"n":wppaOvlShowNext();break;case"s":wppaOvlStartStop();break;case"d":jQuery("#wppa-ovl-legenda-1").css("visibility","hidden"),jQuery("#wppa-ovl-legenda-2").css("visibility","hidden"),wppaShowLegenda="hidden";break;case"f":wppaOvlFull();break;case"l":wppaOvlNorm();break;case"q":case"x":wppaStopVideo(mocc),"normal"!=wppaOvlMode&&wppaOvlNorm(!0),wppaOvlHide()}return!1}function wppaOvlFull(p){wppaConsoleLog("wppaOvlFull"),wppaNormsBtnOpac=.75;var a=wppaOvlMode;p||wppaOvlStepMode();var e=document.getElementById("wppa-overlay-ic");e&&(!p&&"normal"!=a||(e.requestFullscreen?e.requestFullscreen():e.mozRequestFullScreen?e.mozRequestFullScreen():e.webkitRequestFullscreen&&e.webkitRequestFullscreen()),"normal"==wppaOvlMode&&(document.cancelFullScreen?document.cancelFullScreen():document.mozCancelFullScreen?document.mozCancelFullScreen():document.webkitCancelFullScreen&&document.webkitCancelFullScreen()),setTimeout(function(){wppaShowFsButtons(.75)},30),jQuery("#wppa-ovl-legenda-1").html(""))}function wppaOvlNorm(p){wppaConsoleLog("wppaOvlNorm"),wppaOvlMode="normal",wppaNormsBtnOpac=.75,document.cancelFullScreen?document.cancelFullScreen():document.mozCancelFullScreen?document.mozCancelFullScreen():document.webkitCancelFullScreen&&document.webkitCancelFullScreen(),p?wppaOvlMode=wppaOvlModeInitial:(setTimeout(function(){wppaShowFsButtons(.75)},30),setTimeout(function(){wppaOvlShow(wppaOvlIdx)},50))}function wppaOvlShow(p){var a,e;if(wppaConsoleLog("wppaOvlShow arg="+p),0<wppaOvlActivePanorama?jQuery("#wppa-overlay-ic").css({top:0,left:0}):jQuery("#wppa-overlay-ic").css({top:"50%",left:"50%"}),wppaOvlFirst&&(jQuery("#weaver-final").removeClass("wvr-hide-bang"),jQuery("#wppa-overlay-bg").stop().fadeTo(3,wppaOvlOpacity),wppaKbHandlerInstalled||(jQuery(document).on("keydown",wppaOvlKeyboardHandler),wppaKbHandlerInstalled=!0),jQuery("#wppa-overlay-bg").css({width:window.innerWidth,height:window.innerHeight}),"normal"!=wppaOvlModeInitial&&wppaOvlFull(!0)),"object"==typeof p){wppaOvlIds=[],wppaOvlUrls=[],wppaOvlTitles=[],wppaOvlAlts=[],wppaOvlVideoHtmls=[],wppaOvlAudioHtmls=[],wppaOvlPdfHtmls=[],wppaOvlVideoNaturalWidths=[],wppaOvlVideoNaturalHeights=[],wppaOvlIdx=0,wppaOvlPanoramaHtml=[],wppaOvlPanoramaIds=[],wppaOvlHasPanoramas=!(wppaOvlImgs=[]);var t=(p.rel?p.rel:!!jQuery(p).attr("data-rel")&&jQuery(p).attr("data-rel")).split("[");if(t[1]){var o,l,i=t[1],n=jQuery("a"),r=0;for(l=0;l<n.length;l++)o=n[l],1<(t=!!jQuery(o).attr("data-rel")&&jQuery(o).attr("data-rel").split("[")).length&&"wppa"==t[0]&&t[1]==i&&(wppaOvlUrls[r]=o.href,jQuery(o).attr("data-lbtitle")?wppaOvlTitles[r]=wppaRepairScriptTags(jQuery(o).attr("data-lbtitle")):wppaOvlTitles[r]=wppaRepairScriptTags(o.title),wppaOvlIds[r]=jQuery(o).attr("data-id")?jQuery(o).attr("data-id"):"0",wppaOvlAlts[r]=jQuery(o).attr("data-alt")?jQuery(o).attr("data-alt"):"",wppaOvlVideoHtmls[r]=jQuery(o).attr("data-videohtml")?decodeURI(jQuery(o).attr("data-videohtml")):"",wppaOvlPdfHtmls[r]=jQuery(o).attr("data-pdfhtml")?decodeURI(jQuery(o).attr("data-pdfhtml")):"",wppaOvlAudioHtmls[r]=jQuery(o).attr("data-audiohtml")?decodeURI(jQuery(o).attr("data-audiohtml")):"",wppaOvlVideoNaturalWidths[r]=jQuery(o).attr("data-videonatwidth")?jQuery(o).attr("data-videonatwidth"):"",wppaOvlVideoNaturalHeights[r]=jQuery(o).attr("data-videonatheight")?jQuery(o).attr("data-videonatheight"):"",0<(a=jQuery(o).attr("data-panorama")?jQuery(o).attr("data-panorama"):"").length?(wppaOvlHasPanoramas=!0,e=a.indexOf("."),wppaOvlPanoramaHtml[r]=a.substr(e+1),wppaOvlPanoramaIds[r]=a.substr(0,e)):(wppaOvlPanoramaHtml[r]="",wppaOvlPanoramaIds[r]=0),decodeURI(jQuery(o).attr("data-pdfhtml"))==decodeURI(jQuery(p).attr("data-pdfhtml"))&&decodeURI(jQuery(o).attr("data-videohtml"))==decodeURI(jQuery(p).attr("data-videohtml"))&&decodeURI(jQuery(o).attr("data-audiohtml"))==decodeURI(jQuery(p).attr("data-audiohtml"))&&o.href==p.href&&(wppaOvlIdx=r,wppaConsoleLog("Found "+r+": "+p.href,"force")),r++)}else wppaOvlUrls[0]=p.href,jQuery(p).attr("data-lbtitle")?wppaOvlTitles[0]=wppaRepairScriptTags(jQuery(p).attr("data-lbtitle")):wppaOvlTitles[0]=wppaRepairScriptTags(p.title),wppaOvlIds[0]=jQuery(p).attr("data-id")?jQuery(p).attr("data-id"):"0",wppaOvlAlts[0]=jQuery(p).attr("data-alt")?jQuery(p).attr("data-alt"):"",wppaOvlVideoHtmls[0]=jQuery(p).attr("data-videohtml")?decodeURI(jQuery(p).attr("data-videohtml")):"",wppaOvlAudioHtmls[0]=jQuery(p).attr("data-audiohtml")?decodeURI(jQuery(p).attr("data-audiohtml")):"",wppaOvlPdfHtmls[0]=jQuery(p).attr("data-pdfhtml")?decodeURI(jQuery(p).attr("data-pdfhtml")):"",wppaOvlVideoNaturalWidths[0]=jQuery(p).attr("data-videonatwidth")?jQuery(p).attr("data-videonatwidth"):"",wppaOvlVideoNaturalHeights[0]=jQuery(p).attr("data-videonatheight")?jQuery(p).attr("data-videonatheight"):"",0<(a=jQuery(p).attr("data-panorama")?jQuery(p).attr("data-panorama"):"").length?(wppaOvlHasPanoramas=!0,e=a.indexOf("."),wppaOvlPanoramaHtml[0]=a.substr(e+1),wppaOvlPanoramaIds[0]=a.substr(0,e)):(wppaOvlPanoramaHtml[0]="",wppaOvlPanoramaIds[0]=0),wppaOvlIdx=0}else wppaOvlIdx=p;wppaOvlOpen=!0,setTimeout(function(){_wppaOvlShow(wppaOvlIdx)},1)}function _wppaOvlShow(p){if(wppaConsoleLog("_wppaOvlShow, idx="+p,"force"),wppaOvlCurIdx=p,wppaOvlFirst&&jQuery("#wppa-ovl-spin").show(),wppaIsVideo=""!=wppaOvlVideoHtmls[p],wppaHasAudio=""!=wppaOvlAudioHtmls[p],wppaOvlIsPdf=""!=wppaOvlPdfHtmls[p],0<wppaOvlUrls[p].length&&!wppaIsVideo&&(wppaOvlImgs[p]=new Image,wppaOvlImgs[p].src=wppaOvlUrls[p],wppaConsoleLog("Preloading "+(p+1)+"/"+wppaOvlUrls.length+" (current)"),!wppaIsIe&&!wppaOvlImgs[p].complete&&wppaOvlOpen))return wppaConsoleLog("Retrying preload current image"),void setTimeout("_wppaOvlShow("+p+")",500);var a,e;if(a=wppaOvlIdx==wppaOvlUrls.length-1?0:wppaOvlIdx+1,""==wppaOvlVideoHtmls[a]&&wppaOvlOpen&&(wppaOvlImgs[a]=new Image,wppaOvlImgs[a].src=wppaOvlUrls[a],wppaConsoleLog("Preloading > "+(a+1))),!wppaOvlRunning&&wppaOvlOpen&&(e=0==wppaOvlIdx?wppaOvlUrls.length-1:wppaOvlIdx-1,""==wppaOvlVideoHtmls[e]&&(wppaOvlImgs[e]=new Image,wppaOvlImgs[e].src=wppaOvlUrls[e],wppaConsoleLog("Preloading < "+(e+1)))),_bumpViewCount(wppaOvlIds[p]),wppaOvlIsSingle=1==wppaOvlUrls.length,0<wppaOvlPanoramaIds[p]?(wppaOvlActivePanorama=wppaOvlPanoramaIds[p],jQuery("#wppa-overlay-ic").css({top:0,left:0})):(wppaOvlActivePanorama=0,jQuery("#wppa-overlay-ic").css({top:"50%",left:"50%",display:"block"})),"normal"!=wppaOvlMode||wppaOvlActivePanorama){wppaOvlActivePanorama?(l=wppaOvlPanoramaHtml[p]+"<div style=\"height: 20px; width: 100%; position:absolute; top:0; left:0;\" onmouseover=\"jQuery('#wppa-ovl-legenda-2').css('visibility','visible');\" onmouseout=\"jQuery('#wppa-ovl-legenda-2').css('visibility','hidden');wppaShowLegenda='hidden';\" >",wppaOvlShowLegenda&&"normal"!=wppaOvlMode&&(l+='<div id="wppa-ovl-legenda-2" style="position:fixed; left:0; top:0; background-color:'+("black"==wppaOvlTheme?"#272727":"#a7a7a7")+"; color:"+("black"==wppaOvlTheme?"#a7a7a7":"#272727")+"; visibility:"+wppaShowLegenda+';" >Mode=fullscreen. '+(wppaOvlIsSingle?wppaOvlFullLegendaSinglePanorama:wppaOvlFullLegendaPanorama)+"</div>")):(wppaIsVideo?l='<div id="wppa-ovl-full-bg" style="position:fixed; width:'+screen.width+"px; height:"+screen.height+'px; left:0px; top:0px; text-align:center;" ><video id="wppa-overlay-img" controls preload="metadata"'+(wppaOvlVideoStart?" autoplay":"")+' ontouchstart="wppaTouchStart( event, \'wppa-overlay-img\', -1 );" ontouchend="wppaTouchEnd( event );" ontouchmove="wppaTouchMove( event );" ontouchcancel="wppaTouchCancel( event );" onclick="wppaOvlImgClick( event );" onpause="wppaOvlVideoPlaying = false;" onplay="wppaOvlVideoPlaying = true;" style="border:none; width:'+screen.width+'px; box-shadow:none; position:absolute;" alt="'+wppaOvlAlts[p]+'" >'+wppaOvlVideoHtmls[p]+"</video><div style=\"height: 20px; width: 100%; position:absolute; top:0; left:0;\" onmouseover=\"jQuery('#wppa-ovl-legenda-2').css('visibility','visible');\" onmouseout=\"jQuery('#wppa-ovl-legenda-2').css('visibility','hidden');wppaShowLegenda='hidden';\" >":wppaOvlIsPdf?l='<div id="wppa-ovl-full-bg" style="position:fixed; width:'+screen.width+"px; height:"+screen.height+'px; left:0px; top:0px; text-align:center;" ><iframe id="wppa-overlay-img" '+wppaOvlPdfHtmls[p]+' ontouchstart="wppaTouchStart( event, \'wppa-overlay-img\', -1 );" ontouchend="wppaTouchEnd( event );" ontouchmove="wppaTouchMove( event );" ontouchcancel="wppaTouchCancel( event );" onclick="wppaOvlImgClick( event );" style="border:none; width:'+screen.width+'px; box-shadow:none; position:absolute;" alt="'+wppaOvlAlts[p]+"\" ></iframe><div style=\"height: 20px; width: 100%; position:absolute; top:0; left:0;\" onmouseover=\"jQuery('#wppa-ovl-legenda-2').css('visibility','visible');\" onmouseout=\"jQuery('#wppa-ovl-legenda-2').css('visibility','hidden');wppaShowLegenda='hidden';\" >":(l='<div id="wppa-ovl-full-bg" style="position:fixed; width:'+screen.width+"px; height:"+screen.height+'px; left:0px; top:0px; text-align:center;" ><img id="wppa-overlay-img" ontouchstart="wppaTouchStart( event, \'wppa-overlay-img\', -1 );" ontouchend="wppaTouchEnd( event );" ontouchmove="wppaTouchMove( event );" ontouchcancel="wppaTouchCancel( event );" onclick="wppaOvlImgClick( event );" src="'+wppaOvlUrls[p]+'" style="border:none; width:'+screen.width+'px; visibility:hidden; box-shadow:none; position:absolute;" alt="'+wppaOvlAlts[p]+'" />',wppaHasAudio&&(l+='<audio id="wppa-overlay-audio" class="wppa-overlay-audio" data-from="wppa" preload="metadata"'+(wppaOvlAudioStart?" autoplay":"")+' onpause="wppaOvlAudioPlaying = false;" onplay="wppaOvlAudioPlaying = true;" style="width:100%;position:absolute;left:0px;bottom:0px;padding:0;" controls >'+wppaOvlAudioHtmls[p]+"</audio>"),l+="<div style=\"height: 20px; width: 100%; position:absolute; top:0; left:0;\" onmouseover=\"jQuery('#wppa-ovl-legenda-2').css('visibility','visible');\" onmouseout=\"jQuery('#wppa-ovl-legenda-2').css('visibility','hidden');wppaShowLegenda='hidden';\" >"),wppaOvlShowLegenda&&(l+='<div id="wppa-ovl-legenda-2" style="position:fixed; left:0; top:0; background-color:'+("black"==wppaOvlTheme?"#272727":"#a7a7a7")+"; color:"+("black"==wppaOvlTheme?"#a7a7a7":"#272727")+"; visibility:"+wppaShowLegenda+';" >Mode='+wppaOvlMode+". "+(wppaOvlIsSingle?wppaOvlFullLegendaSingle:wppaOvlFullLegenda)+"</div>")),l+="</div>";var t=(wppaIsMobile,"0.1");return l+='<div id="wppa-exit-btn" style="height:'+wppaOvlFsExitBtnSize+"px;z-index:100098;position:fixed;top:0;right:0;opacity:"+wppaNormsBtnOpac+';" onclick="wppaOvlHide()" onmouseover="jQuery(this).stop().fadeTo(300,1);" ontouchstart="jQuery(this).stop().fadeTo(300,1);" onmouseout="jQuery(this).stop().fadeTo(300,'+t+");wppaNormsBtnOpac="+t+';" ontouchend="jQuery(this).stop().fadeTo(300,'+t+");wppaNormsBtnOpac="+t+';" >'+wppaSvgHtml("Exit",wppaOvlFsExitBtnSize+"px",!0,!0,"0","0","0","0")+"</div>","normal"!=wppaOvlMode&&(l+='<div id="wppa-norms-btn" style="height:48px;z-index:100098;position:fixed;top:0;right:'+wppaOvlFsExitBtnSize+"px;opacity:"+wppaNormsBtnOpac+';" onclick="wppaOvlNorm()" onmouseover="jQuery(this).stop().fadeTo(300,1);" ontouchstart="jQuery(this).stop().fadeTo(300,1);" onmouseout="jQuery(this).stop().fadeTo(300,'+t+");wppaNormsBtnOpac="+t+';" ontouchend="jQuery(this).stop().fadeTo(300,'+t+");wppaNormsBtnOpac="+t+';" >'+wppaSvgHtml("Exit-Full-Screen",wppaOvlFsExitBtnSize+"px",!0,!0,"0","0","0","0")+"</div>"),(wppaIsVideo||wppaHasAudio)&&wppaOvlFsPhotoId==wppaPhotoId&&0!=wppaPhotoId||(wppaStopVideo(0),wppaStopAudio(),jQuery("#wppa-overlay-ic").html(l)),0<wppaOvlPanoramaIds[p]&&wppaOvlIsSingle&&jQuery(".wppa-pan-prevnext").hide(),wppaProtect(),wppaOvlIsVideo=wppaIsVideo,setTimeout("wppaOvlFormatFull()",10),wppaIsVideo||wppaHasAudio?setTimeout("wppaOvlUpdateFsId()",20):wppaOvlFsPhotoId=0,wppaOvlFirst=!1,wppaShowFsButtons(),!1}wppaOvlFsPhotoId=0,wppaPhotoId=0,wppaStopVideo(0);var o="black"==wppaOvlTheme?"#a7a7a7":"#272727";wppaOvlFontColor&&(o=wppaOvlFontColor);wppaOvlUrls.length;jQuery("#wppa-overlay-ic").css({width:wppaSavedContainerWidth,marginLeft:wppaSavedMarginLeft,marginTop:wppaSavedMarginTop});var l="";l+='<div id="img-sb-img-cont" style="position:relative;line-height:0;" >',wppaIsVideo?(l+='<video id="wppa-overlay-img" onmouseover="jQuery(\'.wppa-ovl-nav-btn\').stop().fadeTo(200,0.8);" onmouseout="jQuery(\'.wppa-ovl-nav-btn\').stop().fadeTo(200,0);" preload="metadata"'+(wppaOvlVideoStart?" autoplay":"")+' onpause="wppaOvlVideoPlaying = false;" onplay="wppaOvlVideoPlaying = true;" ontouchstart="wppaTouchStart( event, \'wppa-overlay-img\', -1 );" ontouchend="wppaTouchEnd( event );" ontouchmove="wppaTouchMove( event );" ontouchcancel="wppaTouchCancel( event );" onclick="wppaOvlImgClick( event );" controls style="border-width:'+wppaOvlBorderWidth+"px "+wppaOvlBorderWidth+"px 0;border-style:solid;border-color:"+wppaOvlTheme+";width:"+wppaSavedImageWidth+"px;height:"+wppaSavedImageHeight+"px;box-shadow:none;box-sizing:content-box;position:relative;border-top-left-radius:"+wppaOvlRadius+"px;border-top-right-radius:"+wppaOvlRadius+'px;margin:0;padding:0;" alt="'+wppaOvlAlts[p]+'" >'+wppaOvlVideoHtmls[p]+"</video>",wppaOvlIsVideo=!0):wppaOvlIsPdf?l+="<iframe "+wppaOvlPdfHtmls[p]+' id="wppa-overlay-img" onmouseover="jQuery(\'.wppa-ovl-nav-btn\').stop().fadeTo(200,0.8);" onmouseout="jQuery(\'.wppa-ovl-nav-btn\').stop().fadeTo(200,0);" ontouchstart="wppaTouchStart( event, \'wppa-overlay-img\', -1 );" ontouchend="wppaTouchEnd( event );" ontouchmove="wppaTouchMove( event );" ontouchcancel="wppaTouchCancel( event );" onclick="wppaOvlImgClick( event );" style="border-width:'+wppaOvlBorderWidth+"px "+wppaOvlBorderWidth+"px 0;border-style:solid;border-color:"+wppaOvlTheme+";width:"+wppaSavedImageWidth+"px;height:"+wppaSavedImageHeight+"px;box-shadow:none;box-sizing:content-box;position:relative;border-top-left-radius:"+wppaOvlRadius+"px;border-top-right-radius:"+wppaOvlRadius+'px;margin:0;padding:0;" alt="'+wppaOvlAlts[p]+'" ></iframe>':(l+='<img id="wppa-overlay-img" onmouseover="jQuery(\'.wppa-ovl-nav-btn\').stop().fadeTo(200,0.8);" onmouseout="jQuery(\'.wppa-ovl-nav-btn\').stop().fadeTo(200,0);" ontouchstart="wppaTouchStart( event, \'wppa-overlay-img\', -1 );" ontouchend="wppaTouchEnd( event );" ontouchmove="wppaTouchMove( event );" ontouchcancel="wppaTouchCancel( event );" onclick="wppaOvlImgClick( event );" src="'+wppaOvlUrls[p]+'" style="border-width:'+wppaOvlBorderWidth+"px "+wppaOvlBorderWidth+"px 0;border-style:solid;border-color:"+wppaOvlTheme+";width:"+wppaSavedImageWidth+"px;height:"+wppaSavedImageHeight+"px;box-shadow:none;box-sizing:content-box;position:relative;border-top-left-radius:"+wppaOvlRadius+"px;border-top-right-radius:"+wppaOvlRadius+'px;margin:0;padding:0;" alt="'+wppaOvlAlts[p]+'" />',wppaHasAudio&&(l+='<audio id="wppa-overlay-audio" class="wppa-overlay-audio" data-from="wppa" preload="metadata" onpause="wppaOvlAudioPlaying = false;" onplay="wppaOvlAudioPlaying = true;" style="width:100%;position:absolute;box-shadow:none;left:0;bottom:0;padding:0 '+wppaOvlBorderWidth+'px;margin:0;background-color:transparent;box-sizing:border-box;" controls >'+wppaOvlAudioHtmls[p]+"</audio>"),wppaOvlIsVideo=!1),!wppaOvlShowStartStop||wppaOvlIsSingle||wppaIsVideo||wppaOvlIsPdf||(l+='<div id="wppa-ovl-start-stop-btn" class="wppa-ovl-nav-btn" style="z-index:100101;position:absolute;top:50%;margin-top:-24px;left:50%;margin-left:-24px;'+(-1==wppaOvlIdx?"visibility:hidden;":"")+"box-shadow:none;"+(wppaOvlFirst?"opacity:1;":"opacity:0;")+'" onclick="wppaOvlStartStop()" onmouseover="jQuery(this).stop().fadeTo(200,1);" onmouseout="jQuery(this).stop().fadeTo(200,0);" ontouchstart="jQuery(this).stop().fadeTo(200,1);" onload="jQuery(this).stop().fadeTo(5000,0);" >'+wppaSvgHtml(wppaOvlRunning?"Pause-Button":"Play-Button",wppaOvlIconSize,!0,!0,"0","20","50","50")+"</div>"),wppaOvlIsSingle||(l+='<div id="wppa-ovl-prev-btn" class="wppa-ovl-nav-btn" style="position:absolute;z-index:100101;width:48px;top:50%;margin-top:-24px;left:1px;box-shadow:none;'+(wppaOvlFirst?"opacity:1;":"opacity:0;")+'" onclick="wppaOvlShowPrev()" onmouseover="jQuery(this).stop().fadeTo(200,1);" onmouseout="jQuery(this).stop().fadeTo(200,0);" ontouchstart="jQuery(this).stop().fadeTo(200,1);" onload="jQuery(this).stop().fadeTo(5000,0);" >'+wppaSvgHtml("Prev-Button",wppaOvlIconSize,!0,!0)+"</div>",l+='<div id="wppa-ovl-next-btn" class="wppa-ovl-nav-btn" style="position:absolute;z-index:100101;width:48px;top:50%;margin-top:-24px;right:1px;box-shadow:none;'+(wppaOvlFirst?"opacity:1;":"opacity:0;")+'" onclick="wppaOvlShowNext()" onmouseover="jQuery(this).stop().fadeTo(200,1);" onmouseout="jQuery(this).stop().fadeTo(200,0);" ontouchstart="jQuery(this).stop().fadeTo(200,1);" onload="jQuery(this).stop().fadeTo(5000,0);" >'+wppaSvgHtml("Next-Button",wppaOvlIconSize,!0,!0)+"</div>"),l+="</div>";var i=!wppaOvlIsSingle&&wppaOvlShowCounter;return l+='<div id="wppa-overlay-txt-container" style="position:relative;padding:10px;background-color:'+wppaOvlTheme+";color:"+o+";text-align:center;font-family:"+wppaOvlFontFamily+";font-size:"+wppaOvlFontSize+"px;font-weight:"+wppaOvlFontWeight+";line-height:"+wppaOvlLineHeight+"px;box-shadow:none;border-bottom-left-radius:"+wppaOvlRadius+"px;border-bottom-right-radius:"+wppaOvlRadius+'px;" ><div id="wppa-overlay-txt" style="text-align:center;min-height:36px;width:100%;'+("auto"==wppaOvlTxtHeight?"max-height:200px;":"max-height:"+wppaOvlTxtHeight+"px;")+'overflow:auto;box-shadow:none;" >'+(i?wppaOvlIdx+1+"/"+wppaOvlUrls.length+"<br />":"")+wppaOvlTitles[p]+"</div>",jQuery("#wppa-overlay-ic").html(l),wppaShowFsButtons(),jQuery("#wppa-overlay-img").bind("contextmenu",function(p){return!1}),0==wppaOvlPanoramaIds[p]&&wppaOvlResize(),wppaOvlFirst&&wppaShowFsButtons(),!1}function wppaOvlSize(p){if(wppaConsoleLog("wppaOvlSize"),!wppaOvlActivePanorama){var a=document.getElementById("wppa-overlay-img"),e=document.getElementById("wppa-overlay-txt");if(a&&e&&"none"!=jQuery("#wppa-overlay-bg").css("display")){if("normal"==wppaOvlMode){var t,o,l,i,n,r,w,d=wppaWindowWidth(),v=wppaWindowHeight();l=wppaOvlIsVideo?(t=a.clientWidth,o=wppaOvlVideoNaturalWidths[wppaOvlCurIdx],wppaOvlVideoNaturalHeights[wppaOvlCurIdx]):wppaOvlIsPdf?(t=.9*wppaWindowWidth(),o=.9*wppaWindowWidth(),.9*wppaWindowHeight()):(t=a.clientWidth,o=a.naturalWidth,a.naturalHeight),void 0===o&&(o=a.clientWidth,l=a.clientHeight),(r=(i=(d-3*wppaOvlBorderWidth)/o)<(n=v/l)?i:n)<1&&(o=parseInt(o*r),l=parseInt(l*r));var s=jQuery("#wppa-overlay-txt").height();w="auto"==wppaOvlTxtHeight?(0==s&&(s=20+2*wppaOvlBorderWidth),v-s-20-2*wppaOvlBorderWidth):v-wppaOvlTxtHeight-20-2*wppaOvlBorderWidth;var u=parseInt(w*o/l),h=(wppaOvlPadTop,parseInt((d-u)/2),u);l<w&&(wppaOvlPadTop+(w-l)/2,parseInt((d-o)/2),h=o);var c=wppaSavedImageWidth-h<3&&h-wppaSavedImageWidth<3;return h<=10&&(l=180,c=!(o=h=240)),h=parseInt(h),wppaSavedImageWidth=parseInt(h),wppaSavedImageHeight=parseInt(h*l/o),wppaSavedMarginLeft=-parseInt(h/2+wppaOvlBorderWidth),wppaSavedContainerWidth=parseInt(h+2*wppaOvlBorderWidth),wppaSavedContainerHeight=parseInt(wppaSavedImageHeight+wppaOvlBorderWidth+jQuery("#wppa-overlay-txt-container").height()+20),wppaSavedMarginTop=-parseInt(wppaSavedContainerHeight/2),jQuery("#wppa-overlay-img").stop().animate({width:wppaSavedImageWidth,height:wppaSavedImageHeight},p),jQuery("#wppa-overlay-ic").stop().animate({width:wppaSavedContainerWidth,marginLeft:wppaSavedMarginLeft,marginTop:wppaSavedMarginTop},p),c?(jQuery("#wppa-ovl-spin").hide(),wppaConsoleLog("Done "+wppaOvlIdx),wppaOvlFirst=!1):(setTimeout(function(){wppaOvlSize(wppaOvlAnimSpeed)},p+10),wppaConsoleLog("Not done "+wppaOvlIdx+" saved="+wppaSavedImageWidth+", wid="+h+", cw="+t+", nw="+o+", img complete="+document.getElementById("wppa-overlay-img").complete)),!0}wppaOvlFormatFull()}else wppaConsoleLog("Lb quitted","force")}}function wppaOvlFormatFull(){if(wppaConsoleLog("wppaOvlFormatFull "+wppaOvlMode),wppaOvlOpen&&!(0<wppaOvlActivePanorama)){var p,a,e;if(wppaOvlIsVideo)p=document.getElementById("wppa-overlay-img"),a=wppaOvlVideoNaturalWidths[wppaOvlIdx],e=wppaOvlVideoNaturalHeights[wppaOvlIdx];else if(wppaOvlIsPdf)p=document.getElementById("wppa-overlay-img"),a=screen.width,e=screen.height;else{if(p=document.getElementById("wppa-overlay-img"),!(wppaIsIe||p&&p.complete))return void setTimeout("wppaOvlFormatFull()",10);a=p.naturalWidth,e=p.naturalHeight}var t=screen.width/screen.height,o=a/e,l=0,i=0,n=0,r=0,w=0,d=0,v="hidden";switch(wppaOvlMode){case"padded":r=o<t?(l=(screen.width-screen.height*o)/2,i=0,n=screen.height,screen.height*o):(l=0,i=(screen.height-screen.width/o)/2,n=screen.width/o,screen.width);break;case"stretched":i=l=0,n=screen.height,r=screen.width;break;case"clipped":r=o<t?(l=0,i=(screen.height-screen.width/o)/2,n=screen.width/o,screen.width):(l=(screen.width-screen.height*o)/2,i=0,n=screen.height,screen.height*o);break;case"realsize":(l=(screen.width-a)/2)<0&&(d=parseInt(-l),l=0),(i=(screen.height-e)/2)<0&&(w=parseInt(-i),i=0),n=e,r=a,v="auto"}return l=parseInt(l),i=parseInt(i),n=parseInt(n),r=parseInt(r),jQuery(p).css({height:n,width:r,marginLeft:l,marginTop:i,left:0,top:0,maxWidth:1e4}),jQuery(p).css({visibility:"visible"}),jQuery("#wppa-ovl-full-bg").css({overflow:v}),jQuery("#wppa-ovl-full-bg").scrollTop(w),jQuery("#wppa-ovl-full-bg").scrollLeft(d),jQuery("#wppa-ovl-spin").hide(),!0}}function wppaOvlUpdateFsId(){wppaConsoleLog("wppaOvlUpdateFsId"),wppaOvlFsPhotoId=wppaPhotoId}function wppaOvlStartAudio(){wppaConsoleLog("wppaOvlStartAudio");var p=document.getElementById("wppa-overlay-audio");p&&"function"==typeof p.play&&(p.play(),wppaConsoleLog("Audio play wppa-overlay-audio"))}function wppaOvlStepMode(){wppaConsoleLog("wppaOvlStepMode from "+wppaOvlMode);for(var p=new Array("normal","padded","stretched","clipped","realsize","padded"),a=0;a<p.length;){if(wppaOvlMode==p[a])return wppaOvlMode=p[a+1],void wppaOvlShow(wppaOvlIdx);a++}}function wppaOvlStartStop(){wppaConsoleLog("wppaOvlStartStop called. Running="+wppaOvlRunning),wppaOvlRunning?(wppaOvlRunning=!1,jQuery("#wppa-ovl-start-stop-btn").html(wppaSvgHtml(wppaOvlRunning?"Pause-Button":"Play-Button",wppaOvlIconSize,!0,!0,"0","20","50","50")),-1!=wppaOvlIdx&&(0!=wppaOvlIdx&&jQuery("#wppa-ovl-prev-btn").css("visibility","visible"),wppaOvlIdx!=wppaOvlUrls.length-1&&jQuery("#wppa-ovl-next-btn").css("visibility","visible"))):(jQuery("#wppa-ovl-start-stop-btn").html(wppaSvgHtml((wppaOvlRunning,"Pause-Button"),wppaOvlIconSize,!0,!0,"0","20","50","50")),wppaOvlRunning=!0,wppaOvlRun())}function wppaOvlRun(){if(wppaConsoleLog("wppaOvlRun, running="+wppaOvlRunning),wppaOvlRunning)if(wppaOvlVideoPlaying||wppaOvlAudioPlaying)setTimeout("wppaOvlRun()",50);else{if(!wppaIsVideo){var p=document.getElementById("wppa-overlay-img");if(p&&!wppaIsIe&&!p.complete)return wppaConsoleLog("Wait during run"),void setTimeout("wppaOvlRun()",50)}var a;a=wppaOvlIdx>=wppaOvlUrls.length-1?0:wppaOvlIdx+1,wppaOvlFsPhotoId=0,wppaPhotoId=0,wppaOvlShow(a),setTimeout("wppaOvlRun()",wppaOvlSlideSpeed)}}function wppaOvlShowPrev(){return wppaConsoleLog("wppaOvlShowPrev"),wppaOvlIsSingle||(wppaOvlFsPhotoId=0,wppaPhotoId=0,wppaOvlIdx<1&&(wppaOvlIdx=wppaOvlUrls.length),wppaOvlShow(wppaOvlIdx-1)),!1}function wppaOvlShowNext(){return wppaConsoleLog("wppaOvlShowNext"),wppaOvlIsSingle||(jQuery("#wppa-ovl-spin").show(),wppaOvlFsPhotoId=0,wppaPhotoId=0,wppaOvlIdx>=wppaOvlUrls.length-1&&(wppaOvlIdx=-1),wppaOvlShow(wppaOvlIdx+1)),!1}function wppaOvlHide(){wppaConsoleLog("wppaOvlHide"),wppaStopAudio(),"normal"!=wppaOvlMode&&wppaOvlNorm(!0),jQuery("#wppa-overlay-ic").html(""),jQuery("#wppa-overlay-bg").fadeOut(300),jQuery(document).off("keydown",wppaOvlKeyboardHandler),wppaOvlFirst=!(wppaKbHandlerInstalled=!1),wppaOvlRunning=!1,wppaOvlMode=wppaOvlModeInitial,wppaNormsBtnOpac=.75,jQuery("#wppa-ovl-spin").hide(),jQuery("#wppa-fulls-btn").stop().fadeOut(300),jQuery("#wppa-exit-btn").stop().fadeOut(300),jQuery("#wppa-ovl-spin").hide(),wppaOvlActivePanorama=0,wppaOvlOpen=!1}function wppaOvlOnclick(p){switch(wppaConsoleLog("wppaOvlOnClick"),wppaOvlOnclickType){case"none":break;case"close":"normal"==wppaOvlMode&&wppaOvlHide();break;case"browse":var a=p.screenX-window.screenX;48<p.clientY&&(a<screen.width/2?wppaOvlShowPrev():wppaOvlShowNext());break;default:alert("Unimplemented action: "+wppaOvlOnclickType)}return!0}function wppaInitOverlay(){wppaConsoleLog("wppaInitOverlay"),jQuery(".wp-caption").each(function(){var p=jQuery(this),a=p.find("IMG[alt]").attr("alt")||"",e=p.find(".wp-caption-text").html()||"",t=p.find("a"),o=a+"<br>"+e;t.attr("data-lbtitle")||t.attr("data-lbtitle",o)}),""==wppaOvlMode&&(wppaOvlMode=wppaOvlModeInitial);var p,a,e=jQuery("a"),t=[];for(wppaOvlFsPhotoId=0,wppaPhotoId=0,(wppaOvlActivePanorama=wppaOvlCurIdx=0)==wppaSavedContainerWidth&&(wppaSavedContainerWidth=240+2*wppaOvlBorderWidth,wppaSavedContainerHeight=180+3*wppaOvlBorderWidth+20+("auto"==wppaOvlTxtHeight?50:wppaOvlTxtHeight),wppaSavedMarginLeft=-(120+wppaOvlBorderWidth),wppaSavedMarginTop=-(90+wppaOvlBorderWidth+10+("auto"==wppaOvlTxtHeight?25:wppaOvlTxtHeight/2)),wppaSavedImageWidth=240,wppaSavedImageHeight=180+wppaOvlBorderWidth),a=0;a<e.length;a++)if(p=e[a],jQuery(p).attr("data-rel")?t=jQuery(p).attr("data-rel").split("["):p.rel?t=p.rel.split("["):t[0]="","wppa"==t[0])switch(wppaWppaOverlayActivated=!0,jQuery(p).on("click",function(p){wppaOvlShow(this),p.preventDefault()}),wppaMagnifierCursor){case"pointer":jQuery(p).css("cursor","pointer");break;case"":jQuery(p).css("cursor","default");break;default:jQuery(p).css("cursor","url( "+wppaImageDirectory+wppaMagnifierCursor+" ),auto")}wppaIsMobile&&window.addEventListener("orientationchange",wppaDoOnOrientationChange)}function wppaOvlResize(){wppaConsoleLog("wppaOvlResize"),0<wppaOvlActivePanorama||(setTimeout("wppaOvlSize( "+wppaOvlAnimSpeed+" )",10),wppaOvlAudioStart&&!wppaOvlAudioPlaying&&setTimeout("wppaOvlStartAudio()",100))}function wppaShowFsButtons(p){void 0!==p&&(wppaNormsBtnOpac=p),jQuery("#wppa-exit-btn").stop().fadeTo(3,wppaNormsBtnOpac),"normal"==wppaOvlMode?jQuery("#wppa-fulls-btn").stop().fadeTo(3,wppaNormsBtnOpac):jQuery("#wppa-norms-btn").stop().fadeTo(3,wppaNormsBtnOpac)}function wppaOvlImgClick(p){wppaOvlBrowseOnClick&&!wppaOvlIsSingle&&(p.screenX<screen.width/2?wppaOvlShowPrev():wppaOvlShowNext())}jQuery(document).ready(function(p){wppaInitOverlay()}),jQuery(window).resize(function(){jQuery("#wppa-overlay-bg").css({height:window.innerHeight,width:window.innerWidth}),wppaOvlResize()}),wppaConsoleLog("wppa-lightbox.js version "+wppaLightboxVersion+" loaded.","force");
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: opajaap
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=OpaJaap@OpaJaap.nl&item_name=WP-Photo-Album-Plus&item_number=Support-Open-Source&currency_code=USD&lc=US
4
  Tags: photo, album, slideshow, video, audio, lightbox, iptc, exif, cloudinary, fotomoto, imagemagick, pdf
5
- Version: 7.2.02.005
6
- Stable tag: 7.2.01.004
7
  Author: J.N. Breetvelt
8
  Author URI: http://www.opajaap.nl/
9
  Requires at least: 3.9
2
  Contributors: opajaap
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=OpaJaap@OpaJaap.nl&item_name=WP-Photo-Album-Plus&item_number=Support-Open-Source&currency_code=USD&lc=US
4
  Tags: photo, album, slideshow, video, audio, lightbox, iptc, exif, cloudinary, fotomoto, imagemagick, pdf
5
+ Version: 7.2.03.006
6
+ Stable tag: 7.2.03.006
7
  Author: J.N. Breetvelt
8
  Author URI: http://www.opajaap.nl/
9
  Requires at least: 3.9
vendor/cropperjs/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The MIT License (MIT)
2
+
3
+ Copyright 2015-present Chen Fengyuan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
vendor/cropperjs/dist/cropper.common.js ADDED
@@ -0,0 +1,3545 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Cropper.js v1.5.3
3
+ * https://fengyuanchen.github.io/cropperjs
4
+ *
5
+ * Copyright 2015-present Chen Fengyuan
6
+ * Released under the MIT license
7
+ *
8
+ * Date: 2019-07-10T12:07:44.557Z
9
+ */
10
+
11
+ 'use strict';
12
+
13
+ function _typeof(obj) {
14
+ if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
15
+ _typeof = function (obj) {
16
+ return typeof obj;
17
+ };
18
+ } else {
19
+ _typeof = function (obj) {
20
+ return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
21
+ };
22
+ }
23
+
24
+ return _typeof(obj);
25
+ }
26
+
27
+ function _classCallCheck(instance, Constructor) {
28
+ if (!(instance instanceof Constructor)) {
29
+ throw new TypeError("Cannot call a class as a function");
30
+ }
31
+ }
32
+
33
+ function _defineProperties(target, props) {
34
+ for (var i = 0; i < props.length; i++) {
35
+ var descriptor = props[i];
36
+ descriptor.enumerable = descriptor.enumerable || false;
37
+ descriptor.configurable = true;
38
+ if ("value" in descriptor) descriptor.writable = true;
39
+ Object.defineProperty(target, descriptor.key, descriptor);
40
+ }
41
+ }
42
+
43
+ function _createClass(Constructor, protoProps, staticProps) {
44
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
45
+ if (staticProps) _defineProperties(Constructor, staticProps);
46
+ return Constructor;
47
+ }
48
+
49
+ function _toConsumableArray(arr) {
50
+ return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
51
+ }
52
+
53
+ function _arrayWithoutHoles(arr) {
54
+ if (Array.isArray(arr)) {
55
+ for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
56
+
57
+ return arr2;
58
+ }
59
+ }
60
+
61
+ function _iterableToArray(iter) {
62
+ if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
63
+ }
64
+
65
+ function _nonIterableSpread() {
66
+ throw new TypeError("Invalid attempt to spread non-iterable instance");
67
+ }
68
+
69
+ var IS_BROWSER = typeof window !== 'undefined';
70
+ var WINDOW = IS_BROWSER ? window : {};
71
+ var IS_TOUCH_DEVICE = IS_BROWSER ? 'ontouchstart' in WINDOW.document.documentElement : false;
72
+ var HAS_POINTER_EVENT = IS_BROWSER ? 'PointerEvent' in WINDOW : false;
73
+ var NAMESPACE = 'cropper'; // Actions
74
+
75
+ var ACTION_ALL = 'all';
76
+ var ACTION_CROP = 'crop';
77
+ var ACTION_MOVE = 'move';
78
+ var ACTION_ZOOM = 'zoom';
79
+ var ACTION_EAST = 'e';
80
+ var ACTION_WEST = 'w';
81
+ var ACTION_SOUTH = 's';
82
+ var ACTION_NORTH = 'n';
83
+ var ACTION_NORTH_EAST = 'ne';
84
+ var ACTION_NORTH_WEST = 'nw';
85
+ var ACTION_SOUTH_EAST = 'se';
86
+ var ACTION_SOUTH_WEST = 'sw'; // Classes
87
+
88
+ var CLASS_CROP = "".concat(NAMESPACE, "-crop");
89
+ var CLASS_DISABLED = "".concat(NAMESPACE, "-disabled");
90
+ var CLASS_HIDDEN = "".concat(NAMESPACE, "-hidden");
91
+ var CLASS_HIDE = "".concat(NAMESPACE, "-hide");
92
+ var CLASS_INVISIBLE = "".concat(NAMESPACE, "-invisible");
93
+ var CLASS_MODAL = "".concat(NAMESPACE, "-modal");
94
+ var CLASS_MOVE = "".concat(NAMESPACE, "-move"); // Data keys
95
+
96
+ var DATA_ACTION = "".concat(NAMESPACE, "Action");
97
+ var DATA_PREVIEW = "".concat(NAMESPACE, "Preview"); // Drag modes
98
+
99
+ var DRAG_MODE_CROP = 'crop';
100
+ var DRAG_MODE_MOVE = 'move';
101
+ var DRAG_MODE_NONE = 'none'; // Events
102
+
103
+ var EVENT_CROP = 'crop';
104
+ var EVENT_CROP_END = 'cropend';
105
+ var EVENT_CROP_MOVE = 'cropmove';
106
+ var EVENT_CROP_START = 'cropstart';
107
+ var EVENT_DBLCLICK = 'dblclick';
108
+ var EVENT_TOUCH_START = IS_TOUCH_DEVICE ? 'touchstart' : 'mousedown';
109
+ var EVENT_TOUCH_MOVE = IS_TOUCH_DEVICE ? 'touchmove' : 'mousemove';
110
+ var EVENT_TOUCH_END = IS_TOUCH_DEVICE ? 'touchend touchcancel' : 'mouseup';
111
+ var EVENT_POINTER_DOWN = HAS_POINTER_EVENT ? 'pointerdown' : EVENT_TOUCH_START;
112
+ var EVENT_POINTER_MOVE = HAS_POINTER_EVENT ? 'pointermove' : EVENT_TOUCH_MOVE;
113
+ var EVENT_POINTER_UP = HAS_POINTER_EVENT ? 'pointerup pointercancel' : EVENT_TOUCH_END;
114
+ var EVENT_READY = 'ready';
115
+ var EVENT_RESIZE = 'resize';
116
+ var EVENT_WHEEL = 'wheel';
117
+ var EVENT_ZOOM = 'zoom'; // Mime types
118
+
119
+ var MIME_TYPE_JPEG = 'image/jpeg'; // RegExps
120
+
121
+ var REGEXP_ACTIONS = /^e|w|s|n|se|sw|ne|nw|all|crop|move|zoom$/;
122
+ var REGEXP_DATA_URL_JPEG = /^data:image\/jpeg;base64,/;
123
+ var REGEXP_TAG_NAME = /^img|canvas$/i; // Misc
124
+ // Inspired by the default width and height of a canvas element.
125
+
126
+ var MIN_CONTAINER_WIDTH = 200;
127
+ var MIN_CONTAINER_HEIGHT = 100;
128
+
129
+ var DEFAULTS = {
130
+ // Define the view mode of the cropper
131
+ viewMode: 0,
132
+ // 0, 1, 2, 3
133
+ // Define the dragging mode of the cropper
134
+ dragMode: DRAG_MODE_CROP,
135
+ // 'crop', 'move' or 'none'
136
+ // Define the initial aspect ratio of the crop box
137
+ initialAspectRatio: NaN,
138
+ // Define the aspect ratio of the crop box
139
+ aspectRatio: NaN,
140
+ // An object with the previous cropping result data
141
+ data: null,
142
+ // A selector for adding extra containers to preview
143
+ preview: '',
144
+ // Re-render the cropper when resize the window
145
+ responsive: true,
146
+ // Restore the cropped area after resize the window
147
+ restore: true,
148
+ // Check if the current image is a cross-origin image
149
+ checkCrossOrigin: true,
150
+ // Check the current image's Exif Orientation information
151
+ checkOrientation: true,
152
+ // Show the black modal
153
+ modal: true,
154
+ // Show the dashed lines for guiding
155
+ guides: true,
156
+ // Show the center indicator for guiding
157
+ center: true,
158
+ // Show the white modal to highlight the crop box
159
+ highlight: true,
160
+ // Show the grid background
161
+ background: true,
162
+ // Enable to crop the image automatically when initialize
163
+ autoCrop: true,
164
+ // Define the percentage of automatic cropping area when initializes
165
+ autoCropArea: 0.8,
166
+ // Enable to move the image
167
+ movable: true,
168
+ // Enable to rotate the image
169
+ rotatable: true,
170
+ // Enable to scale the image
171
+ scalable: true,
172
+ // Enable to zoom the image
173
+ zoomable: true,
174
+ // Enable to zoom the image by dragging touch
175
+ zoomOnTouch: true,
176
+ // Enable to zoom the image by wheeling mouse
177
+ zoomOnWheel: true,
178
+ // Define zoom ratio when zoom the image by wheeling mouse
179
+ wheelZoomRatio: 0.1,
180
+ // Enable to move the crop box
181
+ cropBoxMovable: true,
182
+ // Enable to resize the crop box
183
+ cropBoxResizable: true,
184
+ // Toggle drag mode between "crop" and "move" when click twice on the cropper
185
+ toggleDragModeOnDblclick: true,
186
+ // Size limitation
187
+ minCanvasWidth: 0,
188
+ minCanvasHeight: 0,
189
+ minCropBoxWidth: 0,
190
+ minCropBoxHeight: 0,
191
+ minContainerWidth: 200,
192
+ minContainerHeight: 100,
193
+ // Shortcuts of events
194
+ ready: null,
195
+ cropstart: null,
196
+ cropmove: null,
197
+ cropend: null,
198
+ crop: null,
199
+ zoom: null
200
+ };
201
+
202
+ var TEMPLATE = '<div class="cropper-container" touch-action="none">' + '<div class="cropper-wrap-box">' + '<div class="cropper-canvas"></div>' + '</div>' + '<div class="cropper-drag-box"></div>' + '<div class="cropper-crop-box">' + '<span class="cropper-view-box"></span>' + '<span class="cropper-dashed dashed-h"></span>' + '<span class="cropper-dashed dashed-v"></span>' + '<span class="cropper-center"></span>' + '<span class="cropper-face"></span>' + '<span class="cropper-line line-e" data-cropper-action="e"></span>' + '<span class="cropper-line line-n" data-cropper-action="n"></span>' + '<span class="cropper-line line-w" data-cropper-action="w"></span>' + '<span class="cropper-line line-s" data-cropper-action="s"></span>' + '<span class="cropper-point point-e" data-cropper-action="e"></span>' + '<span class="cropper-point point-n" data-cropper-action="n"></span>' + '<span class="cropper-point point-w" data-cropper-action="w"></span>' + '<span class="cropper-point point-s" data-cropper-action="s"></span>' + '<span class="cropper-point point-ne" data-cropper-action="ne"></span>' + '<span class="cropper-point point-nw" data-cropper-action="nw"></span>' + '<span class="cropper-point point-sw" data-cropper-action="sw"></span>' + '<span class="cropper-point point-se" data-cropper-action="se"></span>' + '</div>' + '</div>';
203
+
204
+ /**
205
+ * Check if the given value is not a number.
206
+ */
207
+
208
+ var isNaN = Number.isNaN || WINDOW.isNaN;
209
+ /**
210
+ * Check if the given value is a number.
211
+ * @param {*} value - The value to check.
212
+ * @returns {boolean} Returns `true` if the given value is a number, else `false`.
213
+ */
214
+
215
+ function isNumber(value) {
216
+ return typeof value === 'number' && !isNaN(value);
217
+ }
218
+ /**
219
+ * Check if the given value is a positive number.
220
+ * @param {*} value - The value to check.
221
+ * @returns {boolean} Returns `true` if the given value is a positive number, else `false`.
222
+ */
223
+
224
+ var isPositiveNumber = function isPositiveNumber(value) {
225
+ return value > 0 && value < Infinity;
226
+ };
227
+ /**
228
+ * Check if the given value is undefined.
229
+ * @param {*} value - The value to check.
230
+ * @returns {boolean} Returns `true` if the given value is undefined, else `false`.
231
+ */
232
+
233
+ function isUndefined(value) {
234
+ return typeof value === 'undefined';
235
+ }
236
+ /**
237
+ * Check if the given value is an object.
238
+ * @param {*} value - The value to check.
239
+ * @returns {boolean} Returns `true` if the given value is an object, else `false`.
240
+ */
241
+
242
+ function isObject(value) {
243
+ return _typeof(value) === 'object' && value !== null;
244
+ }
245
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
246
+ /**
247
+ * Check if the given value is a plain object.
248
+ * @param {*} value - The value to check.
249
+ * @returns {boolean} Returns `true` if the given value is a plain object, else `false`.
250
+ */
251
+
252
+ function isPlainObject(value) {
253
+ if (!isObject(value)) {
254
+ return false;
255
+ }
256
+
257
+ try {
258
+ var _constructor = value.constructor;
259
+ var prototype = _constructor.prototype;
260
+ return _constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf');
261
+ } catch (error) {
262
+ return false;
263
+ }
264
+ }
265
+ /**
266
+ * Check if the given value is a function.
267
+ * @param {*} value - The value to check.
268
+ * @returns {boolean} Returns `true` if the given value is a function, else `false`.
269
+ */
270
+
271
+ function isFunction(value) {
272
+ return typeof value === 'function';
273
+ }
274
+ var slice = Array.prototype.slice;
275
+ /**
276
+ * Convert array-like or iterable object to an array.
277
+ * @param {*} value - The value to convert.
278
+ * @returns {Array} Returns a new array.
279
+ */
280
+
281
+ function toArray(value) {
282
+ return Array.from ? Array.from(value) : slice.call(value);
283
+ }
284
+ /**
285
+ * Iterate the given data.
286
+ * @param {*} data - The data to iterate.
287
+ * @param {Function} callback - The process function for each element.
288
+ * @returns {*} The original data.
289
+ */
290
+
291
+ function forEach(data, callback) {
292
+ if (data && isFunction(callback)) {
293
+ if (Array.isArray(data) || isNumber(data.length)
294
+ /* array-like */
295
+ ) {
296
+ toArray(data).forEach(function (value, key) {
297
+ callback.call(data, value, key, data);
298
+ });
299
+ } else if (isObject(data)) {
300
+ Object.keys(data).forEach(function (key) {
301
+ callback.call(data, data[key], key, data);
302
+ });
303
+ }
304
+ }
305
+
306
+ return data;
307
+ }
308
+ /**
309
+ * Extend the given object.
310
+ * @param {*} target - The target object to extend.
311
+ * @param {*} args - The rest objects for merging to the target object.
312
+ * @returns {Object} The extended object.
313
+ */
314
+
315
+ var assign = Object.assign || function assign(target) {
316
+ for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
317
+ args[_key - 1] = arguments[_key];
318
+ }
319
+
320
+ if (isObject(target) && args.length > 0) {
321
+ args.forEach(function (arg) {
322
+ if (isObject(arg)) {
323
+ Object.keys(arg).forEach(function (key) {
324
+ target[key] = arg[key];
325
+ });
326
+ }
327
+ });
328
+ }
329
+
330
+ return target;
331
+ };
332
+ var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/;
333
+ /**
334
+ * Normalize decimal number.
335
+ * Check out {@link http://0.30000000000000004.com/}
336
+ * @param {number} value - The value to normalize.
337
+ * @param {number} [times=100000000000] - The times for normalizing.
338
+ * @returns {number} Returns the normalized number.
339
+ */
340
+
341
+ function normalizeDecimalNumber(value) {
342
+ var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100000000000;
343
+ return REGEXP_DECIMALS.test(value) ? Math.round(value * times) / times : value;
344
+ }
345
+ var REGEXP_SUFFIX = /^width|height|left|top|marginLeft|marginTop$/;
346
+ /**
347
+ * Apply styles to the given element.
348
+ * @param {Element} element - The target element.
349
+ * @param {Object} styles - The styles for applying.
350
+ */
351
+
352
+ function setStyle(element, styles) {
353
+ var style = element.style;
354
+ forEach(styles, function (value, property) {
355
+ if (REGEXP_SUFFIX.test(property) && isNumber(value)) {
356
+ value = "".concat(value, "px");
357
+ }
358
+
359
+ style[property] = value;
360
+ });
361
+ }
362
+ /**
363
+ * Check if the given element has a special class.
364
+ * @param {Element} element - The element to check.
365
+ * @param {string} value - The class to search.
366
+ * @returns {boolean} Returns `true` if the special class was found.
367
+ */
368
+
369
+ function hasClass(element, value) {
370
+ return element.classList ? element.classList.contains(value) : element.className.indexOf(value) > -1;
371
+ }
372
+ /**
373
+ * Add classes to the given element.
374
+ * @param {Element} element - The target element.
375
+ * @param {string} value - The classes to be added.
376
+ */
377
+
378
+ function addClass(element, value) {
379
+ if (!value) {
380
+ return;
381
+ }
382
+
383
+ if (isNumber(element.length)) {
384
+ forEach(element, function (elem) {
385
+ addClass(elem, value);
386
+ });
387
+ return;
388
+ }
389
+
390
+ if (element.classList) {
391
+ element.classList.add(value);
392
+ return;
393
+ }
394
+
395
+ var className = element.className.trim();
396
+
397
+ if (!className) {
398
+ element.className = value;
399
+ } else if (className.indexOf(value) < 0) {
400
+ element.className = "".concat(className, " ").concat(value);
401
+ }
402
+ }
403
+ /**
404
+ * Remove classes from the given element.
405
+ * @param {Element} element - The target element.
406
+ * @param {string} value - The classes to be removed.
407
+ */
408
+
409
+ function removeClass(element, value) {
410
+ if (!value) {
411
+ return;
412
+ }
413
+
414
+ if (isNumber(element.length)) {
415
+ forEach(element, function (elem) {
416
+ removeClass(elem, value);
417
+ });
418
+ return;
419
+ }
420
+
421
+ if (element.classList) {
422
+ element.classList.remove(value);
423
+ return;
424
+ }
425
+
426
+ if (element.className.indexOf(value) >= 0) {
427
+ element.className = element.className.replace(value, '');
428
+ }
429
+ }
430
+ /**
431
+ * Add or remove classes from the given element.
432
+ * @param {Element} element - The target element.
433
+ * @param {string} value - The classes to be toggled.
434
+ * @param {boolean} added - Add only.
435
+ */
436
+
437
+ function toggleClass(element, value, added) {
438
+ if (!value) {
439
+ return;
440
+ }
441
+
442
+ if (isNumber(element.length)) {
443
+ forEach(element, function (elem) {
444
+ toggleClass(elem, value, added);
445
+ });
446
+ return;
447
+ } // IE10-11 doesn't support the second parameter of `classList.toggle`
448
+
449
+
450
+ if (added) {
451
+ addClass(element, value);
452
+ } else {
453
+ removeClass(element, value);
454
+ }
455
+ }
456
+ var REGEXP_CAMEL_CASE = /([a-z\d])([A-Z])/g;
457
+ /**
458
+ * Transform the given string from camelCase to kebab-case
459
+ * @param {string} value - The value to transform.
460
+ * @returns {string} The transformed value.
461
+ */
462
+
463
+ function toParamCase(value) {
464
+ return value.replace(REGEXP_CAMEL_CASE, '$1-$2').toLowerCase();
465
+ }
466
+ /**
467
+ * Get data from the given element.
468
+ * @param {Element} element - The target element.
469
+ * @param {string} name - The data key to get.
470
+ * @returns {string} The data value.
471
+ */
472
+
473
+ function getData(element, name) {
474
+ if (isObject(element[name])) {
475
+ return element[name];
476
+ }
477
+
478
+ if (element.dataset) {
479
+ return element.dataset[name];
480
+ }
481
+
482
+ return element.getAttribute("data-".concat(toParamCase(name)));
483
+ }
484
+ /**
485
+ * Set data to the given element.
486
+ * @param {Element} element - The target element.
487
+ * @param {string} name - The data key to set.
488
+ * @param {string} data - The data value.
489
+ */
490
+
491
+ function setData(element, name, data) {
492
+ if (isObject(data)) {
493
+ element[name] = data;
494
+ } else if (element.dataset) {
495
+ element.dataset[name] = data;
496
+ } else {
497
+ element.setAttribute("data-".concat(toParamCase(name)), data);
498
+ }
499
+ }
500
+ /**
501
+ * Remove data from the given element.
502
+ * @param {Element} element - The target element.
503
+ * @param {string} name - The data key to remove.
504
+ */
505
+
506
+ function removeData(element, name) {
507
+ if (isObject(element[name])) {
508
+ try {
509
+ delete element[name];
510
+ } catch (error) {
511
+ element[name] = undefined;
512
+ }
513
+ } else if (element.dataset) {
514
+ // #128 Safari not allows to delete dataset property
515
+ try {
516
+ delete element.dataset[name];
517
+ } catch (error) {
518
+ element.dataset[name] = undefined;
519
+ }
520
+ } else {
521
+ element.removeAttribute("data-".concat(toParamCase(name)));
522
+ }
523
+ }
524
+ var REGEXP_SPACES = /\s\s*/;
525
+
526
+ var onceSupported = function () {
527
+ var supported = false;
528
+
529
+ if (IS_BROWSER) {
530
+ var once = false;
531
+
532
+ var listener = function listener() {};
533
+
534
+ var options = Object.defineProperty({}, 'once', {
535
+ get: function get() {
536
+ supported = true;
537
+ return once;
538
+ },
539
+
540
+ /**
541
+ * This setter can fix a `TypeError` in strict mode
542
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only}
543
+ * @param {boolean} value - The value to set
544
+ */
545
+ set: function set(value) {
546
+ once = value;
547
+ }
548
+ });
549
+ WINDOW.addEventListener('test', listener, options);
550
+ WINDOW.removeEventListener('test', listener, options);
551
+ }
552
+
553
+ return supported;
554
+ }();
555
+ /**
556
+ * Remove event listener from the target element.
557
+ * @param {Element} element - The event target.
558
+ * @param {string} type - The event type(s).
559
+ * @param {Function} listener - The event listener.
560
+ * @param {Object} options - The event options.
561
+ */
562
+
563
+
564
+ function removeListener(element, type, listener) {
565
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
566
+ var handler = listener;
567
+ type.trim().split(REGEXP_SPACES).forEach(function (event) {
568
+ if (!onceSupported) {
569
+ var listeners = element.listeners;
570
+
571
+ if (listeners && listeners[event] && listeners[event][listener]) {
572
+ handler = listeners[event][listener];
573
+ delete listeners[event][listener];
574
+
575
+ if (Object.keys(listeners[event]).length === 0) {
576
+ delete listeners[event];
577
+ }
578
+
579
+ if (Object.keys(listeners).length === 0) {
580
+ delete element.listeners;
581
+ }
582
+ }
583
+ }
584
+
585
+ element.removeEventListener(event, handler, options);
586
+ });
587
+ }
588
+ /**
589
+ * Add event listener to the target element.
590
+ * @param {Element} element - The event target.
591
+ * @param {string} type - The event type(s).
592
+ * @param {Function} listener - The event listener.
593
+ * @param {Object} options - The event options.
594
+ */
595
+
596
+ function addListener(element, type, listener) {
597
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
598
+ var _handler = listener;
599
+ type.trim().split(REGEXP_SPACES).forEach(function (event) {
600
+ if (options.once && !onceSupported) {
601
+ var _element$listeners = element.listeners,
602
+ listeners = _element$listeners === void 0 ? {} : _element$listeners;
603
+
604
+ _handler = function handler() {
605
+ delete listeners[event][listener];
606
+ element.removeEventListener(event, _handler, options);
607
+
608
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
609
+ args[_key2] = arguments[_key2];
610
+ }
611
+
612
+ listener.apply(element, args);
613
+ };
614
+
615
+ if (!listeners[event]) {
616
+ listeners[event] = {};
617
+ }
618
+
619
+ if (listeners[event][listener]) {
620
+ element.removeEventListener(event, listeners[event][listener], options);
621
+ }
622
+
623
+ listeners[event][listener] = _handler;
624
+ element.listeners = listeners;
625
+ }
626
+
627
+ element.addEventListener(event, _handler, options);
628
+ });
629
+ }
630
+ /**
631
+ * Dispatch event on the target element.
632
+ * @param {Element} element - The event target.
633
+ * @param {string} type - The event type(s).
634
+ * @param {Object} data - The additional event data.
635
+ * @returns {boolean} Indicate if the event is default prevented or not.
636
+ */
637
+
638
+ function dispatchEvent(element, type, data) {
639
+ var event; // Event and CustomEvent on IE9-11 are global objects, not constructors
640
+
641
+ if (isFunction(Event) && isFunction(CustomEvent)) {
642
+ event = new CustomEvent(type, {
643
+ detail: data,
644
+ bubbles: true,
645
+ cancelable: true
646
+ });
647
+ } else {
648
+ event = document.createEvent('CustomEvent');
649
+ event.initCustomEvent(type, true, true, data);
650
+ }
651
+
652
+ return element.dispatchEvent(event);
653
+ }
654
+ /**
655
+ * Get the offset base on the document.
656
+ * @param {Element} element - The target element.
657
+ * @returns {Object} The offset data.
658
+ */
659
+
660
+ function getOffset(element) {
661
+ var box = element.getBoundingClientRect();
662
+ return {
663
+ left: box.left + (window.pageXOffset - document.documentElement.clientLeft),
664
+ top: box.top + (window.pageYOffset - document.documentElement.clientTop)
665
+ };
666
+ }
667
+ var location = WINDOW.location;
668
+ var REGEXP_ORIGINS = /^(\w+:)\/\/([^:/?#]*):?(\d*)/i;
669
+ /**
670
+ * Check if the given URL is a cross origin URL.
671
+ * @param {string} url - The target URL.
672
+ * @returns {boolean} Returns `true` if the given URL is a cross origin URL, else `false`.
673
+ */
674
+
675
+ function isCrossOriginURL(url) {
676
+ var parts = url.match(REGEXP_ORIGINS);
677
+ return parts !== null && (parts[1] !== location.protocol || parts[2] !== location.hostname || parts[3] !== location.port);
678
+ }
679
+ /**
680
+ * Add timestamp to the given URL.
681
+ * @param {string} url - The target URL.
682
+ * @returns {string} The result URL.
683
+ */
684
+
685
+ function addTimestamp(url) {
686
+ var timestamp = "timestamp=".concat(new Date().getTime());
687
+ return url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp;
688
+ }
689
+ /**
690
+ * Get transforms base on the given object.
691
+ * @param {Object} obj - The target object.
692
+ * @returns {string} A string contains transform values.
693
+ */
694
+
695
+ function getTransforms(_ref) {
696
+ var rotate = _ref.rotate,
697
+ scaleX = _ref.scaleX,
698
+ scaleY = _ref.scaleY,
699
+ translateX = _ref.translateX,
700
+ translateY = _ref.translateY;
701
+ var values = [];
702
+
703
+ if (isNumber(translateX) && translateX !== 0) {
704
+ values.push("translateX(".concat(translateX, "px)"));
705
+ }
706
+
707
+ if (isNumber(translateY) && translateY !== 0) {
708
+ values.push("translateY(".concat(translateY, "px)"));
709
+ } // Rotate should come first before scale to match orientation transform
710
+
711
+
712
+ if (isNumber(rotate) && rotate !== 0) {
713
+ values.push("rotate(".concat(rotate, "deg)"));
714
+ }
715
+
716
+ if (isNumber(scaleX) && scaleX !== 1) {
717
+ values.push("scaleX(".concat(scaleX, ")"));
718
+ }
719
+
720
+ if (isNumber(scaleY) && scaleY !== 1) {
721
+ values.push("scaleY(".concat(scaleY, ")"));
722
+ }
723
+
724
+ var transform = values.length ? values.join(' ') : 'none';
725
+ return {
726
+ WebkitTransform: transform,
727
+ msTransform: transform,
728
+ transform: transform
729
+ };
730
+ }
731
+ /**
732
+ * Get the max ratio of a group of pointers.
733
+ * @param {string} pointers - The target pointers.
734
+ * @returns {number} The result ratio.
735
+ */
736
+
737
+ function getMaxZoomRatio(pointers) {
738
+ var pointers2 = assign({}, pointers);
739
+ var ratios = [];
740
+ forEach(pointers, function (pointer, pointerId) {
741
+ delete pointers2[pointerId];
742
+ forEach(pointers2, function (pointer2) {
743
+ var x1 = Math.abs(pointer.startX - pointer2.startX);
744
+ var y1 = Math.abs(pointer.startY - pointer2.startY);
745
+ var x2 = Math.abs(pointer.endX - pointer2.endX);
746
+ var y2 = Math.abs(pointer.endY - pointer2.endY);
747
+ var z1 = Math.sqrt(x1 * x1 + y1 * y1);
748
+ var z2 = Math.sqrt(x2 * x2 + y2 * y2);
749
+ var ratio = (z2 - z1) / z1;
750
+ ratios.push(ratio);
751
+ });
752
+ });
753
+ ratios.sort(function (a, b) {
754
+ return Math.abs(a) < Math.abs(b);
755
+ });
756
+ return ratios[0];
757
+ }
758
+ /**
759
+ * Get a pointer from an event object.
760
+ * @param {Object} event - The target event object.
761
+ * @param {boolean} endOnly - Indicates if only returns the end point coordinate or not.
762
+ * @returns {Object} The result pointer contains start and/or end point coordinates.
763
+ */
764
+
765
+ function getPointer(_ref2, endOnly) {
766
+ var pageX = _ref2.pageX,
767
+ pageY = _ref2.pageY;
768
+ var end = {
769
+ endX: pageX,
770
+ endY: pageY
771
+ };
772
+ return endOnly ? end : assign({
773
+ startX: pageX,
774
+ startY: pageY
775
+ }, end);
776
+ }
777
+ /**
778
+ * Get the center point coordinate of a group of pointers.
779
+ * @param {Object} pointers - The target pointers.
780
+ * @returns {Object} The center point coordinate.
781
+ */
782
+
783
+ function getPointersCenter(pointers) {
784
+ var pageX = 0;
785
+ var pageY = 0;
786
+ var count = 0;
787
+ forEach(pointers, function (_ref3) {
788
+ var startX = _ref3.startX,
789
+ startY = _ref3.startY;
790
+ pageX += startX;
791
+ pageY += startY;
792
+ count += 1;
793
+ });
794
+ pageX /= count;
795
+ pageY /= count;
796
+ return {
797
+ pageX: pageX,
798
+ pageY: pageY
799
+ };
800
+ }
801
+ /**
802
+ * Get the max sizes in a rectangle under the given aspect ratio.
803
+ * @param {Object} data - The original sizes.
804
+ * @param {string} [type='contain'] - The adjust type.
805
+ * @returns {Object} The result sizes.
806
+ */
807
+
808
+ function getAdjustedSizes(_ref4) // or 'cover'
809
+ {
810
+ var aspectRatio = _ref4.aspectRatio,
811
+ height = _ref4.height,
812
+ width = _ref4.width;
813
+ var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'contain';
814
+ var isValidWidth = isPositiveNumber(width);
815
+ var isValidHeight = isPositiveNumber(height);
816
+
817
+ if (isValidWidth && isValidHeight) {
818
+ var adjustedWidth = height * aspectRatio;
819
+
820
+ if (type === 'contain' && adjustedWidth > width || type === 'cover' && adjustedWidth < width) {
821
+ height = width / aspectRatio;
822
+ } else {
823
+ width = height * aspectRatio;
824
+ }
825
+ } else if (isValidWidth) {
826
+ height = width / aspectRatio;
827
+ } else if (isValidHeight) {
828
+ width = height * aspectRatio;
829
+ }
830
+
831
+ return {
832
+ width: width,
833
+ height: height
834
+ };
835
+ }
836
+ /**
837
+ * Get the new sizes of a rectangle after rotated.
838
+ * @param {Object} data - The original sizes.
839
+ * @returns {Object} The result sizes.
840
+ */
841
+
842
+ function getRotatedSizes(_ref5) {
843
+ var width = _ref5.width,
844
+ height = _ref5.height,
845
+ degree = _ref5.degree;
846
+ degree = Math.abs(degree) % 180;
847
+
848
+ if (degree === 90) {
849
+ return {
850
+ width: height,
851
+ height: width
852
+ };
853
+ }
854
+
855
+ var arc = degree % 90 * Math.PI / 180;
856
+ var sinArc = Math.sin(arc);
857
+ var cosArc = Math.cos(arc);
858
+ var newWidth = width * cosArc + height * sinArc;
859
+ var newHeight = width * sinArc + height * cosArc;
860
+ return degree > 90 ? {
861
+ width: newHeight,
862
+ height: newWidth
863
+ } : {
864
+ width: newWidth,
865
+ height: newHeight
866
+ };
867
+ }
868
+ /**
869
+ * Get a canvas which drew the given image.
870
+ * @param {HTMLImageElement} image - The image for drawing.
871
+ * @param {Object} imageData - The image data.
872
+ * @param {Object} canvasData - The canvas data.
873
+ * @param {Object} options - The options.
874
+ * @returns {HTMLCanvasElement} The result canvas.
875
+ */
876
+
877
+ function getSourceCanvas(image, _ref6, _ref7, _ref8) {
878
+ var imageAspectRatio = _ref6.aspectRatio,
879
+ imageNaturalWidth = _ref6.naturalWidth,
880
+ imageNaturalHeight = _ref6.naturalHeight,
881
+ _ref6$rotate = _ref6.rotate,
882
+ rotate = _ref6$rotate === void 0 ? 0 : _ref6$rotate,
883
+ _ref6$scaleX = _ref6.scaleX,
884
+ scaleX = _ref6$scaleX === void 0 ? 1 : _ref6$scaleX,
885
+ _ref6$scaleY = _ref6.scaleY,
886
+ scaleY = _ref6$scaleY === void 0 ? 1 : _ref6$scaleY;
887
+ var aspectRatio = _ref7.aspectRatio,
888
+ naturalWidth = _ref7.naturalWidth,
889
+ naturalHeight = _ref7.naturalHeight;
890
+ var _ref8$fillColor = _ref8.fillColor,
891
+ fillColor = _ref8$fillColor === void 0 ? 'transparent' : _ref8$fillColor,
892
+ _ref8$imageSmoothingE = _ref8.imageSmoothingEnabled,
893
+ imageSmoothingEnabled = _ref8$imageSmoothingE === void 0 ? true : _ref8$imageSmoothingE,
894
+ _ref8$imageSmoothingQ = _ref8.imageSmoothingQuality,
895
+ imageSmoothingQuality = _ref8$imageSmoothingQ === void 0 ? 'low' : _ref8$imageSmoothingQ,
896
+ _ref8$maxWidth = _ref8.maxWidth,
897
+ maxWidth = _ref8$maxWidth === void 0 ? Infinity : _ref8$maxWidth,
898
+ _ref8$maxHeight = _ref8.maxHeight,
899
+ maxHeight = _ref8$maxHeight === void 0 ? Infinity : _ref8$maxHeight,
900
+ _ref8$minWidth = _ref8.minWidth,
901
+ minWidth = _ref8$minWidth === void 0 ? 0 : _ref8$minWidth,
902
+ _ref8$minHeight = _ref8.minHeight,
903
+ minHeight = _ref8$minHeight === void 0 ? 0 : _ref8$minHeight;
904
+ var canvas = document.createElement('canvas');
905
+ var context = canvas.getContext('2d');
906
+ var maxSizes = getAdjustedSizes({
907
+ aspectRatio: aspectRatio,
908
+ width: maxWidth,
909
+ height: maxHeight
910
+ });
911
+ var minSizes = getAdjustedSizes({
912
+ aspectRatio: aspectRatio,
913
+ width: minWidth,
914
+ height: minHeight
915
+ }, 'cover');
916
+ var width = Math.min(maxSizes.width, Math.max(minSizes.width, naturalWidth));
917
+ var height = Math.min(maxSizes.height, Math.max(minSizes.height, naturalHeight)); // Note: should always use image's natural sizes for drawing as
918
+ // imageData.naturalWidth === canvasData.naturalHeight when rotate % 180 === 90
919
+
920
+ var destMaxSizes = getAdjustedSizes({
921
+ aspectRatio: imageAspectRatio,
922
+ width: maxWidth,
923
+ height: maxHeight
924
+ });
925
+ var destMinSizes = getAdjustedSizes({
926
+ aspectRatio: imageAspectRatio,
927
+ width: minWidth,
928
+ height: minHeight
929
+ }, 'cover');
930
+ var destWidth = Math.min(destMaxSizes.width, Math.max(destMinSizes.width, imageNaturalWidth));
931
+ var destHeight = Math.min(destMaxSizes.height, Math.max(destMinSizes.height, imageNaturalHeight));
932
+ var params = [-destWidth / 2, -destHeight / 2, destWidth, destHeight];
933
+ canvas.width = normalizeDecimalNumber(width);
934
+ canvas.height = normalizeDecimalNumber(height);
935
+ context.fillStyle = fillColor;
936
+ context.fillRect(0, 0, width, height);
937
+ context.save();
938
+ context.translate(width / 2, height / 2);
939
+ context.rotate(rotate * Math.PI / 180);
940
+ context.scale(scaleX, scaleY);
941
+ context.imageSmoothingEnabled = imageSmoothingEnabled;
942
+ context.imageSmoothingQuality = imageSmoothingQuality;
943
+ context.drawImage.apply(context, [image].concat(_toConsumableArray(params.map(function (param) {
944
+ return Math.floor(normalizeDecimalNumber(param));
945
+ }))));
946
+ context.restore();
947
+ return canvas;
948
+ }
949
+ var fromCharCode = String.fromCharCode;
950
+ /**
951
+ * Get string from char code in data view.
952
+ * @param {DataView} dataView - The data view for read.
953
+ * @param {number} start - The start index.
954
+ * @param {number} length - The read length.
955
+ * @returns {string} The read result.
956
+ */
957
+
958
+ function getStringFromCharCode(dataView, start, length) {
959
+ var str = '';
960
+ length += start;
961
+
962
+ for (var i = start; i < length; i += 1) {
963
+ str += fromCharCode(dataView.getUint8(i));
964
+ }
965
+
966
+ return str;
967
+ }
968
+ var REGEXP_DATA_URL_HEAD = /^data:.*,/;
969
+ /**
970
+ * Transform Data URL to array buffer.
971
+ * @param {string} dataURL - The Data URL to transform.
972
+ * @returns {ArrayBuffer} The result array buffer.
973
+ */
974
+
975
+ function dataURLToArrayBuffer(dataURL) {
976
+ var base64 = dataURL.replace(REGEXP_DATA_URL_HEAD, '');
977
+ var binary = atob(base64);
978
+ var arrayBuffer = new ArrayBuffer(binary.length);
979
+ var uint8 = new Uint8Array(arrayBuffer);
980
+ forEach(uint8, function (value, i) {
981
+ uint8[i] = binary.charCodeAt(i);
982
+ });
983
+ return arrayBuffer;
984
+ }
985
+ /**
986
+ * Transform array buffer to Data URL.
987
+ * @param {ArrayBuffer} arrayBuffer - The array buffer to transform.
988
+ * @param {string} mimeType - The mime type of the Data URL.
989
+ * @returns {string} The result Data URL.
990
+ */
991
+
992
+ function arrayBufferToDataURL(arrayBuffer, mimeType) {
993
+ var chunks = []; // Chunk Typed Array for better performance (#435)
994
+
995
+ var chunkSize = 8192;
996
+ var uint8 = new Uint8Array(arrayBuffer);
997
+
998
+ while (uint8.length > 0) {
999
+ // XXX: Babel's `toConsumableArray` helper will throw error in IE or Safari 9
1000
+ // eslint-disable-next-line prefer-spread
1001
+ chunks.push(fromCharCode.apply(null, toArray(uint8.subarray(0, chunkSize))));
1002
+ uint8 = uint8.subarray(chunkSize);
1003
+ }
1004
+
1005
+ return "data:".concat(mimeType, ";base64,").concat(btoa(chunks.join('')));
1006
+ }
1007
+ /**
1008
+ * Get orientation value from given array buffer.
1009
+ * @param {ArrayBuffer} arrayBuffer - The array buffer to read.
1010
+ * @returns {number} The read orientation value.
1011
+ */
1012
+
1013
+ function resetAndGetOrientation(arrayBuffer) {
1014
+ var dataView = new DataView(arrayBuffer);
1015
+ var orientation; // Ignores range error when the image does not have correct Exif information
1016
+
1017
+ try {
1018
+ var littleEndian;
1019
+ var app1Start;
1020
+ var ifdStart; // Only handle JPEG image (start by 0xFFD8)
1021
+
1022
+ if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) {
1023
+ var length = dataView.byteLength;
1024
+ var offset = 2;
1025
+
1026
+ while (offset + 1 < length) {
1027
+ if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) {
1028
+ app1Start = offset;
1029
+ break;
1030
+ }
1031
+
1032
+ offset += 1;
1033
+ }
1034
+ }
1035
+
1036
+ if (app1Start) {
1037
+ var exifIDCode = app1Start + 4;
1038
+ var tiffOffset = app1Start + 10;
1039
+
1040
+ if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') {
1041
+ var endianness = dataView.getUint16(tiffOffset);
1042
+ littleEndian = endianness === 0x4949;
1043
+
1044
+ if (littleEndian || endianness === 0x4D4D
1045
+ /* bigEndian */
1046
+ ) {
1047
+ if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {
1048
+ var firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
1049
+
1050
+ if (firstIFDOffset >= 0x00000008) {
1051
+ ifdStart = tiffOffset + firstIFDOffset;
1052
+ }
1053
+ }
1054
+ }
1055
+ }
1056
+ }
1057
+
1058
+ if (ifdStart) {
1059
+ var _length = dataView.getUint16(ifdStart, littleEndian);
1060
+
1061
+ var _offset;
1062
+
1063
+ var i;
1064
+
1065
+ for (i = 0; i < _length; i += 1) {
1066
+ _offset = ifdStart + i * 12 + 2;
1067
+
1068
+ if (dataView.getUint16(_offset, littleEndian) === 0x0112
1069
+ /* Orientation */
1070
+ ) {
1071
+ // 8 is the offset of the current tag's value
1072
+ _offset += 8; // Get the original orientation value
1073
+
1074
+ orientation = dataView.getUint16(_offset, littleEndian); // Override the orientation with its default value
1075
+
1076
+ dataView.setUint16(_offset, 1, littleEndian);
1077
+ break;
1078
+ }
1079
+ }
1080
+ }
1081
+ } catch (error) {
1082
+ orientation = 1;
1083
+ }
1084
+
1085
+ return orientation;
1086
+ }
1087
+ /**
1088
+ * Parse Exif Orientation value.
1089
+ * @param {number} orientation - The orientation to parse.
1090
+ * @returns {Object} The parsed result.
1091
+ */
1092
+
1093
+ function parseOrientation(orientation) {
1094
+ var rotate = 0;
1095
+ var scaleX = 1;
1096
+ var scaleY = 1;
1097
+
1098
+ switch (orientation) {
1099
+ // Flip horizontal
1100
+ case 2:
1101
+ scaleX = -1;
1102
+ break;
1103
+ // Rotate left 180°
1104
+
1105
+ case 3:
1106
+ rotate = -180;
1107
+ break;
1108
+ // Flip vertical
1109
+
1110
+ case 4:
1111
+ scaleY = -1;
1112
+ break;
1113
+ // Flip vertical and rotate right 90°
1114
+
1115
+ case 5:
1116
+ rotate = 90;
1117
+ scaleY = -1;
1118
+ break;
1119
+ // Rotate right 90°
1120
+
1121
+ case 6:
1122
+ rotate = 90;
1123
+ break;
1124
+ // Flip horizontal and rotate right 90°
1125
+
1126
+ case 7:
1127
+ rotate = 90;
1128
+ scaleX = -1;
1129
+ break;
1130
+ // Rotate left 90°
1131
+
1132
+ case 8:
1133
+ rotate = -90;
1134
+ break;
1135
+
1136
+ default:
1137
+ }
1138
+
1139
+ return {
1140
+ rotate: rotate,
1141
+ scaleX: scaleX,
1142
+ scaleY: scaleY
1143
+ };
1144
+ }
1145
+
1146
+ var render = {
1147
+ render: function render() {
1148
+ this.initContainer();
1149
+ this.initCanvas();
1150
+ this.initCropBox();
1151
+ this.renderCanvas();
1152
+
1153
+ if (this.cropped) {
1154
+ this.renderCropBox();
1155
+ }
1156
+ },
1157
+ initContainer: function initContainer() {
1158
+ var element = this.element,
1159
+ options = this.options,
1160
+ container = this.container,
1161
+ cropper = this.cropper;
1162
+ addClass(cropper, CLASS_HIDDEN);
1163
+ removeClass(element, CLASS_HIDDEN);
1164
+ var containerData = {
1165
+ width: Math.max(container.offsetWidth, Number(options.minContainerWidth) || 200),
1166
+ height: Math.max(container.offsetHeight, Number(options.minContainerHeight) || 100)
1167
+ };
1168
+ this.containerData = containerData;
1169
+ setStyle(cropper, {
1170
+ width: containerData.width,
1171
+ height: containerData.height
1172
+ });
1173
+ addClass(element, CLASS_HIDDEN);
1174
+ removeClass(cropper, CLASS_HIDDEN);
1175
+ },
1176
+ // Canvas (image wrapper)
1177
+ initCanvas: function initCanvas() {
1178
+ var containerData = this.containerData,
1179
+ imageData = this.imageData;
1180
+ var viewMode = this.options.viewMode;
1181
+ var rotated = Math.abs(imageData.rotate) % 180 === 90;
1182
+ var naturalWidth = rotated ? imageData.naturalHeight : imageData.naturalWidth;
1183
+ var naturalHeight = rotated ? imageData.naturalWidth : imageData.naturalHeight;
1184
+ var aspectRatio = naturalWidth / naturalHeight;
1185
+ var canvasWidth = containerData.width;
1186
+ var canvasHeight = containerData.height;
1187
+
1188
+ if (containerData.height * aspectRatio > containerData.width) {
1189
+ if (viewMode === 3) {
1190
+ canvasWidth = containerData.height * aspectRatio;
1191
+ } else {
1192
+ canvasHeight = containerData.width / aspectRatio;
1193
+ }
1194
+ } else if (viewMode === 3) {
1195
+ canvasHeight = containerData.width / aspectRatio;
1196
+ } else {
1197
+ canvasWidth = containerData.height * aspectRatio;
1198
+ }
1199
+
1200
+ var canvasData = {
1201
+ aspectRatio: aspectRatio,
1202
+ naturalWidth: naturalWidth,
1203
+ naturalHeight: naturalHeight,
1204
+ width: canvasWidth,
1205
+ height: canvasHeight
1206
+ };
1207
+ canvasData.left = (containerData.width - canvasWidth) / 2;
1208
+ canvasData.top = (containerData.height - canvasHeight) / 2;
1209
+ canvasData.oldLeft = canvasData.left;
1210
+ canvasData.oldTop = canvasData.top;
1211
+ this.canvasData = canvasData;
1212
+ this.limited = viewMode === 1 || viewMode === 2;
1213
+ this.limitCanvas(true, true);
1214
+ this.initialImageData = assign({}, imageData);
1215
+ this.initialCanvasData = assign({}, canvasData);
1216
+ },
1217
+ limitCanvas: function limitCanvas(sizeLimited, positionLimited) {
1218
+ var options = this.options,
1219
+ containerData = this.containerData,
1220
+ canvasData = this.canvasData,
1221
+ cropBoxData = this.cropBoxData;
1222
+ var viewMode = options.viewMode;
1223
+ var aspectRatio = canvasData.aspectRatio;
1224
+ var cropped = this.cropped && cropBoxData;
1225
+
1226
+ if (sizeLimited) {
1227
+ var minCanvasWidth = Number(options.minCanvasWidth) || 0;
1228
+ var minCanvasHeight = Number(options.minCanvasHeight) || 0;
1229
+
1230
+ if (viewMode > 1) {
1231
+ minCanvasWidth = Math.max(minCanvasWidth, containerData.width);
1232
+ minCanvasHeight = Math.max(minCanvasHeight, containerData.height);
1233
+
1234
+ if (viewMode === 3) {
1235
+ if (minCanvasHeight * aspectRatio > minCanvasWidth) {
1236
+ minCanvasWidth = minCanvasHeight * aspectRatio;
1237
+ } else {
1238
+ minCanvasHeight = minCanvasWidth / aspectRatio;
1239
+ }
1240
+ }
1241
+ } else if (viewMode > 0) {
1242
+ if (minCanvasWidth) {
1243
+ minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBoxData.width : 0);
1244
+ } else if (minCanvasHeight) {
1245
+ minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBoxData.height : 0);
1246
+ } else if (cropped) {
1247
+ minCanvasWidth = cropBoxData.width;
1248
+ minCanvasHeight = cropBoxData.height;
1249
+
1250
+ if (minCanvasHeight * aspectRatio > minCanvasWidth) {
1251
+ minCanvasWidth = minCanvasHeight * aspectRatio;
1252
+ } else {
1253
+ minCanvasHeight = minCanvasWidth / aspectRatio;
1254
+ }
1255
+ }
1256
+ }
1257
+
1258
+ var _getAdjustedSizes = getAdjustedSizes({
1259
+ aspectRatio: aspectRatio,
1260
+ width: minCanvasWidth,
1261
+ height: minCanvasHeight
1262
+ });
1263
+
1264
+ minCanvasWidth = _getAdjustedSizes.width;
1265
+ minCanvasHeight = _getAdjustedSizes.height;
1266
+ canvasData.minWidth = minCanvasWidth;
1267
+ canvasData.minHeight = minCanvasHeight;
1268
+ canvasData.maxWidth = Infinity;
1269
+ canvasData.maxHeight = Infinity;
1270
+ }
1271
+
1272
+ if (positionLimited) {
1273
+ if (viewMode > (cropped ? 0 : 1)) {
1274
+ var newCanvasLeft = containerData.width - canvasData.width;
1275
+ var newCanvasTop = containerData.height - canvasData.height;
1276
+ canvasData.minLeft = Math.min(0, newCanvasLeft);
1277
+ canvasData.minTop = Math.min(0, newCanvasTop);
1278
+ canvasData.maxLeft = Math.max(0, newCanvasLeft);
1279
+ canvasData.maxTop = Math.max(0, newCanvasTop);
1280
+
1281
+ if (cropped && this.limited) {
1282
+ canvasData.minLeft = Math.min(cropBoxData.left, cropBoxData.left + (cropBoxData.width - canvasData.width));
1283
+ canvasData.minTop = Math.min(cropBoxData.top, cropBoxData.top + (cropBoxData.height - canvasData.height));
1284
+ canvasData.maxLeft = cropBoxData.left;
1285
+ canvasData.maxTop = cropBoxData.top;
1286
+
1287
+ if (viewMode === 2) {
1288
+ if (canvasData.width >= containerData.width) {
1289
+ canvasData.minLeft = Math.min(0, newCanvasLeft);
1290
+ canvasData.maxLeft = Math.max(0, newCanvasLeft);
1291
+ }
1292
+
1293
+ if (canvasData.height >= containerData.height) {
1294
+ canvasData.minTop = Math.min(0, newCanvasTop);
1295
+ canvasData.maxTop = Math.max(0, newCanvasTop);
1296
+ }
1297
+ }
1298
+ }
1299
+ } else {
1300
+ canvasData.minLeft = -canvasData.width;
1301
+ canvasData.minTop = -canvasData.height;
1302
+ canvasData.maxLeft = containerData.width;
1303
+ canvasData.maxTop = containerData.height;
1304
+ }
1305
+ }
1306
+ },
1307
+ renderCanvas: function renderCanvas(changed, transformed) {
1308
+ var canvasData = this.canvasData,
1309
+ imageData = this.imageData;
1310
+
1311
+ if (transformed) {
1312
+ var _getRotatedSizes = getRotatedSizes({
1313
+ width: imageData.naturalWidth * Math.abs(imageData.scaleX || 1),
1314
+ height: imageData.naturalHeight * Math.abs(imageData.scaleY || 1),
1315
+ degree: imageData.rotate || 0
1316
+ }),
1317
+ naturalWidth = _getRotatedSizes.width,
1318
+ naturalHeight = _getRotatedSizes.height;
1319
+
1320
+ var width = canvasData.width * (naturalWidth / canvasData.naturalWidth);
1321
+ var height = canvasData.height * (naturalHeight / canvasData.naturalHeight);
1322
+ canvasData.left -= (width - canvasData.width) / 2;
1323
+ canvasData.top -= (height - canvasData.height) / 2;
1324
+ canvasData.width = width;
1325
+ canvasData.height = height;
1326
+ canvasData.aspectRatio = naturalWidth / naturalHeight;
1327
+ canvasData.naturalWidth = naturalWidth;
1328
+ canvasData.naturalHeight = naturalHeight;
1329
+ this.limitCanvas(true, false);
1330
+ }
1331
+
1332
+ if (canvasData.width > canvasData.maxWidth || canvasData.width < canvasData.minWidth) {
1333
+ canvasData.left = canvasData.oldLeft;
1334
+ }
1335
+
1336
+ if (canvasData.height > canvasData.maxHeight || canvasData.height < canvasData.minHeight) {
1337
+ canvasData.top = canvasData.oldTop;
1338
+ }
1339
+
1340
+ canvasData.width = Math.min(Math.max(canvasData.width, canvasData.minWidth), canvasData.maxWidth);
1341
+ canvasData.height = Math.min(Math.max(canvasData.height, canvasData.minHeight), canvasData.maxHeight);
1342
+ this.limitCanvas(false, true);
1343
+ canvasData.left = Math.min(Math.max(canvasData.left, canvasData.minLeft), canvasData.maxLeft);
1344
+ canvasData.top = Math.min(Math.max(canvasData.top, canvasData.minTop), canvasData.maxTop);
1345
+ canvasData.oldLeft = canvasData.left;
1346
+ canvasData.oldTop = canvasData.top;
1347
+ setStyle(this.canvas, assign({
1348
+ width: canvasData.width,
1349
+ height: canvasData.height
1350
+ }, getTransforms({
1351
+ translateX: canvasData.left,
1352
+ translateY: canvasData.top
1353
+ })));
1354
+ this.renderImage(changed);
1355
+
1356
+ if (this.cropped && this.limited) {
1357
+ this.limitCropBox(true, true);
1358
+ }
1359
+ },
1360
+ renderImage: function renderImage(changed) {
1361
+ var canvasData = this.canvasData,
1362
+ imageData = this.imageData;
1363
+ var width = imageData.naturalWidth * (canvasData.width / canvasData.naturalWidth);
1364
+ var height = imageData.naturalHeight * (canvasData.height / canvasData.naturalHeight);
1365
+ assign(imageData, {
1366
+ width: width,
1367
+ height: height,
1368
+ left: (canvasData.width - width) / 2,
1369
+ top: (canvasData.height - height) / 2
1370
+ });
1371
+ setStyle(this.image, assign({
1372
+ width: imageData.width,
1373
+ height: imageData.height
1374
+ }, getTransforms(assign({
1375
+ translateX: imageData.left,
1376
+ translateY: imageData.top
1377
+ }, imageData))));
1378
+
1379
+ if (changed) {
1380
+ this.output();
1381
+ }
1382
+ },
1383
+ initCropBox: function initCropBox() {
1384
+ var options = this.options,
1385
+ canvasData = this.canvasData;
1386
+ var aspectRatio = options.aspectRatio || options.initialAspectRatio;
1387
+ var autoCropArea = Number(options.autoCropArea) || 0.8;
1388
+ var cropBoxData = {
1389
+ width: canvasData.width,
1390
+ height: canvasData.height
1391
+ };
1392
+
1393
+ if (aspectRatio) {
1394
+ if (canvasData.height * aspectRatio > canvasData.width) {
1395
+ cropBoxData.height = cropBoxData.width / aspectRatio;
1396
+ } else {
1397
+ cropBoxData.width = cropBoxData.height * aspectRatio;
1398
+ }
1399
+ }
1400
+
1401
+ this.cropBoxData = cropBoxData;
1402
+ this.limitCropBox(true, true); // Initialize auto crop area
1403
+
1404
+ cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth);
1405
+ cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight); // The width/height of auto crop area must large than "minWidth/Height"
1406
+
1407
+ cropBoxData.width = Math.max(cropBoxData.minWidth, cropBoxData.width * autoCropArea);
1408
+ cropBoxData.height = Math.max(cropBoxData.minHeight, cropBoxData.height * autoCropArea);
1409
+ cropBoxData.left = canvasData.left + (canvasData.width - cropBoxData.width) / 2;
1410
+ cropBoxData.top = canvasData.top + (canvasData.height - cropBoxData.height) / 2;
1411
+ cropBoxData.oldLeft = cropBoxData.left;
1412
+ cropBoxData.oldTop = cropBoxData.top;
1413
+ this.initialCropBoxData = assign({}, cropBoxData);
1414
+ },
1415
+ limitCropBox: function limitCropBox(sizeLimited, positionLimited) {
1416
+ var options = this.options,
1417
+ containerData = this.containerData,
1418
+ canvasData = this.canvasData,
1419
+ cropBoxData = this.cropBoxData,
1420
+ limited = this.limited;
1421
+ var aspectRatio = options.aspectRatio;
1422
+
1423
+ if (sizeLimited) {
1424
+ var minCropBoxWidth = Number(options.minCropBoxWidth) || 0;
1425
+ var minCropBoxHeight = Number(options.minCropBoxHeight) || 0;
1426
+ var maxCropBoxWidth = limited ? Math.min(containerData.width, canvasData.width, canvasData.width + canvasData.left, containerData.width - canvasData.left) : containerData.width;
1427
+ var maxCropBoxHeight = limited ? Math.min(containerData.height, canvasData.height, canvasData.height + canvasData.top, containerData.height - canvasData.top) : containerData.height; // The min/maxCropBoxWidth/Height must be less than container's width/height
1428
+
1429
+ minCropBoxWidth = Math.min(minCropBoxWidth, containerData.width);
1430
+ minCropBoxHeight = Math.min(minCropBoxHeight, containerData.height);
1431
+
1432
+ if (aspectRatio) {
1433
+ if (minCropBoxWidth && minCropBoxHeight) {
1434
+ if (minCropBoxHeight * aspectRatio > minCropBoxWidth) {
1435
+ minCropBoxHeight = minCropBoxWidth / aspectRatio;
1436
+ } else {
1437
+ minCropBoxWidth = minCropBoxHeight * aspectRatio;
1438
+ }
1439
+ } else if (minCropBoxWidth) {
1440
+ minCropBoxHeight = minCropBoxWidth / aspectRatio;
1441
+ } else if (minCropBoxHeight) {
1442
+ minCropBoxWidth = minCropBoxHeight * aspectRatio;
1443
+ }
1444
+
1445
+ if (maxCropBoxHeight * aspectRatio > maxCropBoxWidth) {
1446
+ maxCropBoxHeight = maxCropBoxWidth / aspectRatio;
1447
+ } else {
1448
+ maxCropBoxWidth = maxCropBoxHeight * aspectRatio;
1449
+ }
1450
+ } // The minWidth/Height must be less than maxWidth/Height
1451
+
1452
+
1453
+ cropBoxData.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth);
1454
+ cropBoxData.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight);
1455
+ cropBoxData.maxWidth = maxCropBoxWidth;
1456
+ cropBoxData.maxHeight = maxCropBoxHeight;
1457
+ }
1458
+
1459
+ if (positionLimited) {
1460
+ if (limited) {
1461
+ cropBoxData.minLeft = Math.max(0, canvasData.left);
1462
+ cropBoxData.minTop = Math.max(0, canvasData.top);
1463
+ cropBoxData.maxLeft = Math.min(containerData.width, canvasData.left + canvasData.width) - cropBoxData.width;
1464
+ cropBoxData.maxTop = Math.min(containerData.height, canvasData.top + canvasData.height) - cropBoxData.height;
1465
+ } else {
1466
+ cropBoxData.minLeft = 0;
1467
+ cropBoxData.minTop = 0;
1468
+ cropBoxData.maxLeft = containerData.width - cropBoxData.width;
1469
+ cropBoxData.maxTop = containerData.height - cropBoxData.height;
1470
+ }
1471
+ }
1472
+ },
1473
+ renderCropBox: function renderCropBox() {
1474
+ var options = this.options,
1475
+ containerData = this.containerData,
1476
+ cropBoxData = this.cropBoxData;
1477
+
1478
+ if (cropBoxData.width > cropBoxData.maxWidth || cropBoxData.width < cropBoxData.minWidth) {
1479
+ cropBoxData.left = cropBoxData.oldLeft;
1480
+ }
1481
+
1482
+ if (cropBoxData.height > cropBoxData.maxHeight || cropBoxData.height < cropBoxData.minHeight) {
1483
+ cropBoxData.top = cropBoxData.oldTop;
1484
+ }
1485
+
1486
+ cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth);
1487
+ cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight);
1488
+ this.limitCropBox(false, true);
1489
+ cropBoxData.left = Math.min(Math.max(cropBoxData.left, cropBoxData.minLeft), cropBoxData.maxLeft);
1490
+ cropBoxData.top = Math.min(Math.max(cropBoxData.top, cropBoxData.minTop), cropBoxData.maxTop);
1491
+ cropBoxData.oldLeft = cropBoxData.left;
1492
+ cropBoxData.oldTop = cropBoxData.top;
1493
+
1494
+ if (options.movable && options.cropBoxMovable) {
1495
+ // Turn to move the canvas when the crop box is equal to the container
1496
+ setData(this.face, DATA_ACTION, cropBoxData.width >= containerData.width && cropBoxData.height >= containerData.height ? ACTION_MOVE : ACTION_ALL);
1497
+ }
1498
+
1499
+ setStyle(this.cropBox, assign({
1500
+ width: cropBoxData.width,
1501
+ height: cropBoxData.height
1502
+ }, getTransforms({
1503
+ translateX: cropBoxData.left,
1504
+ translateY: cropBoxData.top
1505
+ })));
1506
+
1507
+ if (this.cropped && this.limited) {
1508
+ this.limitCanvas(true, true);
1509
+ }
1510
+
1511
+ if (!this.disabled) {
1512
+ this.output();
1513
+ }
1514
+ },
1515
+ output: function output() {
1516
+ this.preview();
1517
+ dispatchEvent(this.element, EVENT_CROP, this.getData());
1518
+ }
1519
+ };
1520
+
1521
+ var preview = {
1522
+ initPreview: function initPreview() {
1523
+ var crossOrigin = this.crossOrigin;
1524
+ var preview = this.options.preview;
1525
+ var url = crossOrigin ? this.crossOriginUrl : this.url;
1526
+ var image = document.createElement('img');
1527
+
1528
+ if (crossOrigin) {
1529
+ image.crossOrigin = crossOrigin;
1530
+ }
1531
+
1532
+ image.src = url;
1533
+ this.viewBox.appendChild(image);
1534
+ this.viewBoxImage = image;
1535
+
1536
+ if (!preview) {
1537
+ return;
1538
+ }
1539
+
1540
+ var previews = preview;
1541
+
1542
+ if (typeof preview === 'string') {
1543
+ previews = this.element.ownerDocument.querySelectorAll(preview);
1544
+ } else if (preview.querySelector) {
1545
+ previews = [preview];
1546
+ }
1547
+
1548
+ this.previews = previews;
1549
+ forEach(previews, function (el) {
1550
+ var img = document.createElement('img'); // Save the original size for recover
1551
+
1552
+ setData(el, DATA_PREVIEW, {
1553
+ width: el.offsetWidth,
1554
+ height: el.offsetHeight,
1555
+ html: el.innerHTML
1556
+ });
1557
+
1558
+ if (crossOrigin) {
1559
+ img.crossOrigin = crossOrigin;
1560
+ }
1561
+
1562
+ img.src = url;
1563
+ /**
1564
+ * Override img element styles
1565
+ * Add `display:block` to avoid margin top issue
1566
+ * Add `height:auto` to override `height` attribute on IE8
1567
+ * (Occur only when margin-top <= -height)
1568
+ */
1569
+
1570
+ img.style.cssText = 'display:block;' + 'width:100%;' + 'height:auto;' + 'min-width:0!important;' + 'min-height:0!important;' + 'max-width:none!important;' + 'max-height:none!important;' + 'image-orientation:0deg!important;"';
1571
+ el.innerHTML = '';
1572
+ el.appendChild(img);
1573
+ });
1574
+ },
1575
+ resetPreview: function resetPreview() {
1576
+ forEach(this.previews, function (element) {
1577
+ var data = getData(element, DATA_PREVIEW);
1578
+ setStyle(element, {
1579
+ width: data.width,
1580
+ height: data.height
1581
+ });
1582
+ element.innerHTML = data.html;
1583
+ removeData(element, DATA_PREVIEW);
1584
+ });
1585
+ },
1586
+ preview: function preview() {
1587
+ var imageData = this.imageData,
1588
+ canvasData = this.canvasData,
1589
+ cropBoxData = this.cropBoxData;
1590
+ var cropBoxWidth = cropBoxData.width,
1591
+ cropBoxHeight = cropBoxData.height;
1592
+ var width = imageData.width,
1593
+ height = imageData.height;
1594
+ var left = cropBoxData.left - canvasData.left - imageData.left;
1595
+ var top = cropBoxData.top - canvasData.top - imageData.top;
1596
+
1597
+ if (!this.cropped || this.disabled) {
1598
+ return;
1599
+ }
1600
+
1601
+ setStyle(this.viewBoxImage, assign({
1602
+ width: width,
1603
+ height: height
1604
+ }, getTransforms(assign({
1605
+ translateX: -left,
1606
+ translateY: -top
1607
+ }, imageData))));
1608
+ forEach(this.previews, function (element) {
1609
+ var data = getData(element, DATA_PREVIEW);
1610
+ var originalWidth = data.width;
1611
+ var originalHeight = data.height;
1612
+ var newWidth = originalWidth;
1613
+ var newHeight = originalHeight;
1614
+ var ratio = 1;
1615
+
1616
+ if (cropBoxWidth) {
1617
+ ratio = originalWidth / cropBoxWidth;
1618
+ newHeight = cropBoxHeight * ratio;
1619
+ }
1620
+
1621
+ if (cropBoxHeight && newHeight > originalHeight) {
1622
+ ratio = originalHeight / cropBoxHeight;
1623
+ newWidth = cropBoxWidth * ratio;
1624
+ newHeight = originalHeight;
1625
+ }
1626
+
1627
+ setStyle(element, {
1628
+ width: newWidth,
1629
+ height: newHeight
1630
+ });
1631
+ setStyle(element.getElementsByTagName('img')[0], assign({
1632
+ width: width * ratio,
1633
+ height: height * ratio
1634
+ }, getTransforms(assign({
1635
+ translateX: -left * ratio,
1636
+ translateY: -top * ratio
1637
+ }, imageData))));
1638
+ });
1639
+ }
1640
+ };
1641
+
1642
+ var events = {
1643
+ bind: function bind() {
1644
+ var element = this.element,
1645
+ options = this.options,
1646
+ cropper = this.cropper;
1647
+
1648
+ if (isFunction(options.cropstart)) {
1649
+ addListener(element, EVENT_CROP_START, options.cropstart);
1650
+ }
1651
+
1652
+ if (isFunction(options.cropmove)) {
1653
+ addListener(element, EVENT_CROP_MOVE, options.cropmove);
1654
+ }
1655
+
1656
+ if (isFunction(options.cropend)) {
1657
+ addListener(element, EVENT_CROP_END, options.cropend);
1658
+ }
1659
+
1660
+ if (isFunction(options.crop)) {
1661
+ addListener(element, EVENT_CROP, options.crop);
1662
+ }
1663
+
1664
+ if (isFunction(options.zoom)) {
1665
+ addListener(element, EVENT_ZOOM, options.zoom);
1666
+ }
1667
+
1668
+ addListener(cropper, EVENT_POINTER_DOWN, this.onCropStart = this.cropStart.bind(this));
1669
+
1670
+ if (options.zoomable && options.zoomOnWheel) {
1671
+ addListener(cropper, EVENT_WHEEL, this.onWheel = this.wheel.bind(this), {
1672
+ passive: false,
1673
+ capture: true
1674
+ });
1675
+ }
1676
+
1677
+ if (options.toggleDragModeOnDblclick) {
1678
+ addListener(cropper, EVENT_DBLCLICK, this.onDblclick = this.dblclick.bind(this));
1679
+ }
1680
+
1681
+ addListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove = this.cropMove.bind(this));
1682
+ addListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd = this.cropEnd.bind(this));
1683
+
1684
+ if (options.responsive) {
1685
+ addListener(window, EVENT_RESIZE, this.onResize = this.resize.bind(this));
1686
+ }
1687
+ },
1688
+ unbind: function unbind() {
1689
+ var element = this.element,
1690
+ options = this.options,
1691
+ cropper = this.cropper;
1692
+
1693
+ if (isFunction(options.cropstart)) {
1694
+ removeListener(element, EVENT_CROP_START, options.cropstart);
1695
+ }
1696
+
1697
+ if (isFunction(options.cropmove)) {
1698
+ removeListener(element, EVENT_CROP_MOVE, options.cropmove);
1699
+ }
1700
+
1701
+ if (isFunction(options.cropend)) {
1702
+ removeListener(element, EVENT_CROP_END, options.cropend);
1703
+ }
1704
+
1705
+ if (isFunction(options.crop)) {
1706
+ removeListener(element, EVENT_CROP, options.crop);
1707
+ }
1708
+
1709
+ if (isFunction(options.zoom)) {
1710
+ removeListener(element, EVENT_ZOOM, options.zoom);
1711
+ }
1712
+
1713
+ removeListener(cropper, EVENT_POINTER_DOWN, this.onCropStart);
1714
+
1715
+ if (options.zoomable && options.zoomOnWheel) {
1716
+ removeListener(cropper, EVENT_WHEEL, this.onWheel, {
1717
+ passive: false,
1718
+ capture: true
1719
+ });
1720
+ }
1721
+
1722
+ if (options.toggleDragModeOnDblclick) {
1723
+ removeListener(cropper, EVENT_DBLCLICK, this.onDblclick);
1724
+ }
1725
+
1726
+ removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove);
1727
+ removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd);
1728
+
1729
+ if (options.responsive) {
1730
+ removeListener(window, EVENT_RESIZE, this.onResize);
1731
+ }
1732
+ }
1733
+ };
1734
+
1735
+ var handlers = {
1736
+ resize: function resize() {
1737
+ var options = this.options,
1738
+ container = this.container,
1739
+ containerData = this.containerData;
1740
+ var minContainerWidth = Number(options.minContainerWidth) || MIN_CONTAINER_WIDTH;
1741
+ var minContainerHeight = Number(options.minContainerHeight) || MIN_CONTAINER_HEIGHT;
1742
+
1743
+ if (this.disabled || containerData.width <= minContainerWidth || containerData.height <= minContainerHeight) {
1744
+ return;
1745
+ }
1746
+
1747
+ var ratio = container.offsetWidth / containerData.width; // Resize when width changed or height changed
1748
+
1749
+ if (ratio !== 1 || container.offsetHeight !== containerData.height) {
1750
+ var canvasData;
1751
+ var cropBoxData;
1752
+
1753
+ if (options.restore) {
1754
+ canvasData = this.getCanvasData();
1755
+ cropBoxData = this.getCropBoxData();
1756
+ }
1757
+
1758
+ this.render();
1759
+
1760
+ if (options.restore) {
1761
+ this.setCanvasData(forEach(canvasData, function (n, i) {
1762
+ canvasData[i] = n * ratio;
1763
+ }));
1764
+ this.setCropBoxData(forEach(cropBoxData, function (n, i) {
1765
+ cropBoxData[i] = n * ratio;
1766
+ }));
1767
+ }
1768
+ }
1769
+ },
1770
+ dblclick: function dblclick() {
1771
+ if (this.disabled || this.options.dragMode === DRAG_MODE_NONE) {
1772
+ return;
1773
+ }
1774
+
1775
+ this.setDragMode(hasClass(this.dragBox, CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP);
1776
+ },
1777
+ wheel: function wheel(event) {
1778
+ var _this = this;
1779
+
1780
+ var ratio = Number(this.options.wheelZoomRatio) || 0.1;
1781
+ var delta = 1;
1782
+
1783
+ if (this.disabled) {
1784
+ return;
1785
+ }
1786
+
1787
+ event.preventDefault(); // Limit wheel speed to prevent zoom too fast (#21)
1788
+
1789
+ if (this.wheeling) {
1790
+ return;
1791
+ }
1792
+
1793
+ this.wheeling = true;
1794
+ setTimeout(function () {
1795
+ _this.wheeling = false;
1796
+ }, 50);
1797
+
1798
+ if (event.deltaY) {
1799
+ delta = event.deltaY > 0 ? 1 : -1;
1800
+ } else if (event.wheelDelta) {
1801
+ delta = -event.wheelDelta / 120;
1802
+ } else if (event.detail) {
1803
+ delta = event.detail > 0 ? 1 : -1;
1804
+ }
1805
+
1806
+ this.zoom(-delta * ratio, event);
1807
+ },
1808
+ cropStart: function cropStart(event) {
1809
+ var buttons = event.buttons,
1810
+ button = event.button;
1811
+
1812
+ if (this.disabled // No primary button (Usually the left button)
1813
+ // Note that touch events have no `buttons` or `button` property
1814
+ || isNumber(buttons) && buttons !== 1 || isNumber(button) && button !== 0 // Open context menu
1815
+ || event.ctrlKey) {
1816
+ return;
1817
+ }
1818
+
1819
+ var options = this.options,
1820
+ pointers = this.pointers;
1821
+ var action;
1822
+
1823
+ if (event.changedTouches) {
1824
+ // Handle touch event
1825
+ forEach(event.changedTouches, function (touch) {
1826
+ pointers[touch.identifier] = getPointer(touch);
1827
+ });
1828
+ } else {
1829
+ // Handle mouse event and pointer event
1830
+ pointers[event.pointerId || 0] = getPointer(event);
1831
+ }
1832
+
1833
+ if (Object.keys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) {
1834
+ action = ACTION_ZOOM;
1835
+ } else {
1836
+ action = getData(event.target, DATA_ACTION);
1837
+ }
1838
+
1839
+ if (!REGEXP_ACTIONS.test(action)) {
1840
+ return;
1841
+ }
1842
+
1843
+ if (dispatchEvent(this.element, EVENT_CROP_START, {
1844
+ originalEvent: event,
1845
+ action: action
1846
+ }) === false) {
1847
+ return;
1848
+ } // This line is required for preventing page zooming in iOS browsers
1849
+
1850
+
1851
+ event.preventDefault();
1852
+ this.action = action;
1853
+ this.cropping = false;
1854
+
1855
+ if (action === ACTION_CROP) {
1856
+ this.cropping = true;
1857
+ addClass(this.dragBox, CLASS_MODAL);
1858
+ }
1859
+ },
1860
+ cropMove: function cropMove(event) {
1861
+ var action = this.action;
1862
+
1863
+ if (this.disabled || !action) {
1864
+ return;
1865
+ }
1866
+
1867
+ var pointers = this.pointers;
1868
+ event.preventDefault();
1869
+
1870
+ if (dispatchEvent(this.element, EVENT_CROP_MOVE, {
1871
+ originalEvent: event,
1872
+ action: action
1873
+ }) === false) {
1874
+ return;
1875
+ }
1876
+
1877
+ if (event.changedTouches) {
1878
+ forEach(event.changedTouches, function (touch) {
1879
+ // The first parameter should not be undefined (#432)
1880
+ assign(pointers[touch.identifier] || {}, getPointer(touch, true));
1881
+ });
1882
+ } else {
1883
+ assign(pointers[event.pointerId || 0] || {}, getPointer(event, true));
1884
+ }
1885
+
1886
+ this.change(event);
1887
+ },
1888
+ cropEnd: function cropEnd(event) {
1889
+ if (this.disabled) {
1890
+ return;
1891
+ }
1892
+
1893
+ var action = this.action,
1894
+ pointers = this.pointers;
1895
+
1896
+ if (event.changedTouches) {
1897
+ forEach(event.changedTouches, function (touch) {
1898
+ delete pointers[touch.identifier];
1899
+ });
1900
+ } else {
1901
+ delete pointers[event.pointerId || 0];
1902
+ }
1903
+
1904
+ if (!action) {
1905
+ return;
1906
+ }
1907
+
1908
+ event.preventDefault();
1909
+
1910
+ if (!Object.keys(pointers).length) {
1911
+ this.action = '';
1912
+ }
1913
+
1914
+ if (this.cropping) {
1915
+ this.cropping = false;
1916
+ toggleClass(this.dragBox, CLASS_MODAL, this.cropped && this.options.modal);
1917
+ }
1918
+
1919
+ dispatchEvent(this.element, EVENT_CROP_END, {
1920
+ originalEvent: event,
1921
+ action: action
1922
+ });
1923
+ }
1924
+ };
1925
+
1926
+ var change = {
1927
+ change: function change(event) {
1928
+ var options = this.options,
1929
+ canvasData = this.canvasData,
1930
+ containerData = this.containerData,
1931
+ cropBoxData = this.cropBoxData,
1932
+ pointers = this.pointers;
1933
+ var action = this.action;
1934
+ var aspectRatio = options.aspectRatio;
1935
+ var left = cropBoxData.left,
1936
+ top = cropBoxData.top,
1937
+ width = cropBoxData.width,
1938
+ height = cropBoxData.height;
1939
+ var right = left + width;
1940
+ var bottom = top + height;
1941
+ var minLeft = 0;
1942
+ var minTop = 0;
1943
+ var maxWidth = containerData.width;
1944
+ var maxHeight = containerData.height;
1945
+ var renderable = true;
1946
+ var offset; // Locking aspect ratio in "free mode" by holding shift key
1947
+
1948
+ if (!aspectRatio && event.shiftKey) {
1949
+ aspectRatio = width && height ? width / height : 1;
1950
+ }
1951
+
1952
+ if (this.limited) {
1953
+ minLeft = cropBoxData.minLeft;
1954
+ minTop = cropBoxData.minTop;
1955
+ maxWidth = minLeft + Math.min(containerData.width, canvasData.width, canvasData.left + canvasData.width);
1956
+ maxHeight = minTop + Math.min(containerData.height, canvasData.height, canvasData.top + canvasData.height);
1957
+ }
1958
+
1959
+ var pointer = pointers[Object.keys(pointers)[0]];
1960
+ var range = {
1961
+ x: pointer.endX - pointer.startX,
1962
+ y: pointer.endY - pointer.startY
1963
+ };
1964
+
1965
+ var check = function check(side) {
1966
+ switch (side) {
1967
+ case ACTION_EAST:
1968
+ if (right + range.x > maxWidth) {
1969
+ range.x = maxWidth - right;
1970
+ }
1971
+
1972
+ break;
1973
+
1974
+ case ACTION_WEST:
1975
+ if (left + range.x < minLeft) {
1976
+ range.x = minLeft - left;
1977
+ }
1978
+
1979
+ break;
1980
+
1981
+ case ACTION_NORTH:
1982
+ if (top + range.y < minTop) {
1983
+ range.y = minTop - top;
1984
+ }
1985
+
1986
+ break;
1987
+
1988
+ case ACTION_SOUTH:
1989
+ if (bottom + range.y > maxHeight) {
1990
+ range.y = maxHeight - bottom;
1991
+ }
1992
+
1993
+ break;
1994
+
1995
+ default:
1996
+ }
1997
+ };
1998
+
1999
+ switch (action) {
2000
+ // Move crop box
2001
+ case ACTION_ALL:
2002
+ left += range.x;
2003
+ top += range.y;
2004
+ break;
2005
+ // Resize crop box
2006
+
2007
+ case ACTION_EAST:
2008
+ if (range.x >= 0 && (right >= maxWidth || aspectRatio && (top <= minTop || bottom >= maxHeight))) {
2009
+ renderable = false;
2010
+ break;
2011
+ }
2012
+
2013
+ check(ACTION_EAST);
2014
+ width += range.x;
2015
+
2016
+ if (width < 0) {
2017
+ action = ACTION_WEST;
2018
+ width = -width;
2019
+ left -= width;
2020
+ }
2021
+
2022
+ if (aspectRatio) {
2023
+ height = width / aspectRatio;
2024
+ top += (cropBoxData.height - height) / 2;
2025
+ }
2026
+
2027
+ break;
2028
+
2029
+ case ACTION_NORTH:
2030
+ if (range.y <= 0 && (top <= minTop || aspectRatio && (left <= minLeft || right >= maxWidth))) {
2031
+ renderable = false;
2032
+ break;
2033
+ }
2034
+
2035
+ check(ACTION_NORTH);
2036
+ height -= range.y;
2037
+ top += range.y;
2038
+
2039
+ if (height < 0) {
2040
+ action = ACTION_SOUTH;
2041
+ height = -height;
2042
+ top -= height;
2043
+ }
2044
+
2045
+ if (aspectRatio) {
2046
+ width = height * aspectRatio;
2047
+ left += (cropBoxData.width - width) / 2;
2048
+ }
2049
+
2050
+ break;
2051
+
2052
+ case ACTION_WEST:
2053
+ if (range.x <= 0 && (left <= minLeft || aspectRatio && (top <= minTop || bottom >= maxHeight))) {
2054
+ renderable = false;
2055
+ break;
2056
+ }
2057
+
2058
+ check(ACTION_WEST);
2059
+ width -= range.x;
2060
+ left += range.x;
2061
+
2062
+ if (width < 0) {
2063
+ action = ACTION_EAST;
2064
+ width = -width;
2065
+ left -= width;
2066
+ }
2067
+
2068
+ if (aspectRatio) {
2069
+ height = width / aspectRatio;
2070
+ top += (cropBoxData.height - height) / 2;
2071
+ }
2072
+
2073
+ break;
2074
+
2075
+ case ACTION_SOUTH:
2076
+ if (range.y >= 0 && (bottom >= maxHeight || aspectRatio && (left <= minLeft || right >= maxWidth))) {
2077
+ renderable = false;
2078
+ break;
2079
+ }
2080
+
2081
+ check(ACTION_SOUTH);
2082
+ height += range.y;
2083
+
2084
+ if (height < 0) {
2085
+ action = ACTION_NORTH;
2086
+ height = -height;
2087
+ top -= height;
2088
+ }
2089
+
2090
+ if (aspectRatio) {
2091
+ width = height * aspectRatio;
2092
+ left += (cropBoxData.width - width) / 2;
2093
+ }
2094
+
2095
+ break;
2096
+
2097
+ case ACTION_NORTH_EAST:
2098
+ if (aspectRatio) {
2099
+ if (range.y <= 0 && (top <= minTop || right >= maxWidth)) {
2100
+ renderable = false;
2101
+ break;
2102
+ }
2103
+
2104
+ check(ACTION_NORTH);
2105
+ height -= range.y;
2106
+ top += range.y;
2107
+ width = height * aspectRatio;
2108
+ } else {
2109
+ check(ACTION_NORTH);
2110
+ check(ACTION_EAST);
2111
+
2112
+ if (range.x >= 0) {
2113
+ if (right < maxWidth) {
2114
+ width += range.x;
2115
+ } else if (range.y <= 0 && top <= minTop) {
2116
+ renderable = false;
2117
+ }
2118
+ } else {
2119
+ width += range.x;
2120
+ }
2121
+
2122
+ if (range.y <= 0) {
2123
+ if (top > minTop) {
2124
+ height -= range.y;
2125
+ top += range.y;
2126
+ }
2127
+ } else {
2128
+ height -= range.y;
2129
+ top += range.y;
2130
+ }
2131
+ }
2132
+
2133
+ if (width < 0 && height < 0) {
2134
+ action = ACTION_SOUTH_WEST;
2135
+ height = -height;
2136
+ width = -width;
2137
+ top -= height;
2138
+ left -= width;
2139
+ } else if (width < 0) {
2140
+ action = ACTION_NORTH_WEST;
2141
+ width = -width;
2142
+ left -= width;
2143
+ } else if (height < 0) {
2144
+ action = ACTION_SOUTH_EAST;
2145
+ height = -height;
2146
+ top -= height;
2147
+ }
2148
+
2149
+ break;
2150
+
2151
+ case ACTION_NORTH_WEST:
2152
+ if (aspectRatio) {
2153
+ if (range.y <= 0 && (top <= minTop || left <= minLeft)) {
2154
+ renderable = false;
2155
+ break;
2156
+ }
2157
+
2158
+ check(ACTION_NORTH);
2159
+ height -= range.y;
2160
+ top += range.y;
2161
+ width = height * aspectRatio;
2162
+ left += cropBoxData.width - width;
2163
+ } else {
2164
+ check(ACTION_NORTH);
2165
+ check(ACTION_WEST);
2166
+
2167
+ if (range.x <= 0) {
2168
+ if (left > minLeft) {
2169
+ width -= range.x;
2170
+ left += range.x;
2171
+ } else if (range.y <= 0 && top <= minTop) {
2172
+ renderable = false;
2173
+ }
2174
+ } else {
2175
+ width -= range.x;
2176
+ left += range.x;
2177
+ }
2178
+
2179
+ if (range.y <= 0) {
2180
+ if (top > minTop) {
2181
+ height -= range.y;
2182
+ top += range.y;
2183
+ }
2184
+ } else {
2185
+ height -= range.y;
2186
+ top += range.y;
2187
+ }
2188
+ }
2189
+
2190
+ if (width < 0 && height < 0) {
2191
+ action = ACTION_SOUTH_EAST;
2192
+ height = -height;
2193
+ width = -width;
2194
+ top -= height;
2195
+ left -= width;
2196
+ } else if (width < 0) {
2197
+ action = ACTION_NORTH_EAST;
2198
+ width = -width;
2199
+ left -= width;
2200
+ } else if (height < 0) {
2201
+ action = ACTION_SOUTH_WEST;
2202
+ height = -height;
2203
+ top -= height;
2204
+ }
2205
+
2206
+ break;
2207
+
2208
+ case ACTION_SOUTH_WEST:
2209
+ if (aspectRatio) {
2210
+ if (range.x <= 0 && (left <= minLeft || bottom >= maxHeight)) {
2211
+ renderable = false;
2212
+ break;
2213
+ }
2214
+
2215
+ check(ACTION_WEST);
2216
+ width -= range.x;
2217
+ left += range.x;
2218
+ height = width / aspectRatio;
2219
+ } else {
2220
+ check(ACTION_SOUTH);
2221
+ check(ACTION_WEST);
2222
+
2223
+ if (range.x <= 0) {
2224
+ if (left > minLeft) {
2225
+ width -= range.x;
2226
+ left += range.x;
2227
+ } else if (range.y >= 0 && bottom >= maxHeight) {
2228
+ renderable = false;
2229
+ }
2230
+ } else {
2231
+ width -= range.x;
2232
+ left += range.x;
2233
+ }
2234
+
2235
+ if (range.y >= 0) {
2236
+ if (bottom < maxHeight) {
2237
+ height += range.y;
2238
+ }
2239
+ } else {
2240
+ height += range.y;
2241
+ }
2242
+ }
2243
+
2244
+ if (width < 0 && height < 0) {
2245
+ action = ACTION_NORTH_EAST;
2246
+ height = -height;
2247
+ width = -width;
2248
+ top -= height;
2249
+ left -= width;
2250
+ } else if (width < 0) {
2251
+ action = ACTION_SOUTH_EAST;
2252
+ width = -width;
2253
+ left -= width;
2254
+ } else if (height < 0) {
2255
+ action = ACTION_NORTH_WEST;
2256
+ height = -height;
2257
+ top -= height;
2258
+ }
2259
+
2260
+ break;
2261
+
2262
+ case ACTION_SOUTH_EAST:
2263
+ if (aspectRatio) {
2264
+ if (range.x >= 0 && (right >= maxWidth || bottom >= maxHeight)) {
2265
+ renderable = false;
2266
+ break;
2267
+ }
2268
+
2269
+ check(ACTION_EAST);
2270
+ width += range.x;
2271
+ height = width / aspectRatio;
2272
+ } else {
2273
+ check(ACTION_SOUTH);
2274
+ check(ACTION_EAST);
2275
+
2276
+ if (range.x >= 0) {
2277
+ if (right < maxWidth) {
2278
+ width += range.x;
2279
+ } else if (range.y >= 0 && bottom >= maxHeight) {
2280
+ renderable = false;
2281
+ }
2282
+ } else {
2283
+ width += range.x;
2284
+ }
2285
+
2286
+ if (range.y >= 0) {
2287
+ if (bottom < maxHeight) {
2288
+ height += range.y;
2289
+ }
2290
+ } else {
2291
+ height += range.y;
2292
+ }
2293
+ }
2294
+
2295
+ if (width < 0 && height < 0) {
2296
+ action = ACTION_NORTH_WEST;
2297
+ height = -height;
2298
+ width = -width;
2299
+ top -= height;
2300
+ left -= width;
2301
+ } else if (width < 0) {
2302
+ action = ACTION_SOUTH_WEST;
2303
+ width = -width;
2304
+ left -= width;
2305
+ } else if (height < 0) {
2306
+ action = ACTION_NORTH_EAST;
2307
+ height = -height;
2308
+ top -= height;
2309
+ }
2310
+
2311
+ break;
2312
+ // Move canvas
2313
+
2314
+ case ACTION_MOVE:
2315
+ this.move(range.x, range.y);
2316
+ renderable = false;
2317
+ break;
2318
+ // Zoom canvas
2319
+
2320
+ case ACTION_ZOOM:
2321
+ this.zoom(getMaxZoomRatio(pointers), event);
2322
+ renderable = false;
2323
+ break;
2324
+ // Create crop box
2325
+
2326
+ case ACTION_CROP:
2327
+ if (!range.x || !range.y) {
2328
+ renderable = false;
2329
+ break;
2330
+ }
2331
+
2332
+ offset = getOffset(this.cropper);
2333
+ left = pointer.startX - offset.left;
2334
+ top = pointer.startY - offset.top;
2335
+ width = cropBoxData.minWidth;
2336
+ height = cropBoxData.minHeight;
2337
+
2338
+ if (range.x > 0) {
2339
+ action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST;
2340
+ } else if (range.x < 0) {
2341
+ left -= width;
2342
+ action = range.y > 0 ? ACTION_SOUTH_WEST : ACTION_NORTH_WEST;
2343
+ }
2344
+
2345
+ if (range.y < 0) {
2346
+ top -= height;
2347
+ } // Show the crop box if is hidden
2348
+
2349
+
2350
+ if (!this.cropped) {
2351
+ removeClass(this.cropBox, CLASS_HIDDEN);
2352
+ this.cropped = true;
2353
+
2354
+ if (this.limited) {
2355
+ this.limitCropBox(true, true);
2356
+ }
2357
+ }
2358
+
2359
+ break;
2360
+
2361
+ default:
2362
+ }
2363
+
2364
+ if (renderable) {
2365
+ cropBoxData.width = width;
2366
+ cropBoxData.height = height;
2367
+ cropBoxData.left = left;
2368
+ cropBoxData.top = top;
2369
+ this.action = action;
2370
+ this.renderCropBox();
2371
+ } // Override
2372
+
2373
+
2374
+ forEach(pointers, function (p) {
2375
+ p.startX = p.endX;
2376
+ p.startY = p.endY;
2377
+ });
2378
+ }
2379
+ };
2380
+
2381
+ var methods = {
2382
+ // Show the crop box manually
2383
+ crop: function crop() {
2384
+ if (this.ready && !this.cropped && !this.disabled) {
2385
+ this.cropped = true;
2386
+ this.limitCropBox(true, true);
2387
+
2388
+ if (this.options.modal) {
2389
+ addClass(this.dragBox, CLASS_MODAL);
2390
+ }
2391
+
2392
+ removeClass(this.cropBox, CLASS_HIDDEN);
2393
+ this.setCropBoxData(this.initialCropBoxData);
2394
+ }
2395
+
2396
+ return this;
2397
+ },
2398
+ // Reset the image and crop box to their initial states
2399
+ reset: function reset() {
2400
+ if (this.ready && !this.disabled) {
2401
+ this.imageData = assign({}, this.initialImageData);
2402
+ this.canvasData = assign({}, this.initialCanvasData);
2403
+ this.cropBoxData = assign({}, this.initialCropBoxData);
2404
+ this.renderCanvas();
2405
+
2406
+ if (this.cropped) {
2407
+ this.renderCropBox();
2408
+ }
2409
+ }
2410
+
2411
+ return this;
2412
+ },
2413
+ // Clear the crop box
2414
+ clear: function clear() {
2415
+ if (this.cropped && !this.disabled) {
2416
+ assign(this.cropBoxData, {
2417
+ left: 0,
2418
+ top: 0,
2419
+ width: 0,
2420
+ height: 0
2421
+ });
2422
+ this.cropped = false;
2423
+ this.renderCropBox();
2424
+ this.limitCanvas(true, true); // Render canvas after crop box rendered
2425
+
2426
+ this.renderCanvas();
2427
+ removeClass(this.dragBox, CLASS_MODAL);
2428
+ addClass(this.cropBox, CLASS_HIDDEN);
2429
+ }
2430
+
2431
+ return this;
2432
+ },
2433
+
2434
+ /**
2435
+ * Replace the image's src and rebuild the cropper
2436
+ * @param {string} url - The new URL.
2437
+ * @param {boolean} [hasSameSize] - Indicate if the new image has the same size as the old one.
2438
+ * @returns {Cropper} this
2439
+ */
2440
+ replace: function replace(url) {
2441
+ var hasSameSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
2442
+
2443
+ if (!this.disabled && url) {
2444
+ if (this.isImg) {
2445
+ this.element.src = url;
2446
+ }
2447
+
2448
+ if (hasSameSize) {
2449
+ this.url = url;
2450
+ this.image.src = url;
2451
+
2452
+ if (this.ready) {
2453
+ this.viewBoxImage.src = url;
2454
+ forEach(this.previews, function (element) {
2455
+ element.getElementsByTagName('img')[0].src = url;
2456
+ });
2457
+ }
2458
+ } else {
2459
+ if (this.isImg) {
2460
+ this.replaced = true;
2461
+ }
2462
+
2463
+ this.options.data = null;
2464
+ this.uncreate();
2465
+ this.load(url);
2466
+ }
2467
+ }
2468
+
2469
+ return this;
2470
+ },
2471
+ // Enable (unfreeze) the cropper
2472
+ enable: function enable() {
2473
+ if (this.ready && this.disabled) {
2474
+ this.disabled = false;
2475
+ removeClass(this.cropper, CLASS_DISABLED);
2476
+ }
2477
+
2478
+ return this;
2479
+ },
2480
+ // Disable (freeze) the cropper
2481
+ disable: function disable() {
2482
+ if (this.ready && !this.disabled) {
2483
+ this.disabled = true;
2484
+ addClass(this.cropper, CLASS_DISABLED);
2485
+ }
2486
+
2487
+ return this;
2488
+ },
2489
+
2490
+ /**
2491
+ * Destroy the cropper and remove the instance from the image
2492
+ * @returns {Cropper} this
2493
+ */
2494
+ destroy: function destroy() {
2495
+ var element = this.element;
2496
+
2497
+ if (!element[NAMESPACE]) {
2498
+ return this;
2499
+ }
2500
+
2501
+ element[NAMESPACE] = undefined;
2502
+
2503
+ if (this.isImg && this.replaced) {
2504
+ element.src = this.originalUrl;
2505
+ }
2506
+
2507
+ this.uncreate();
2508
+ return this;
2509
+ },
2510
+
2511
+ /**
2512
+ * Move the canvas with relative offsets
2513
+ * @param {number} offsetX - The relative offset distance on the x-axis.
2514
+ * @param {number} [offsetY=offsetX] - The relative offset distance on the y-axis.
2515
+ * @returns {Cropper} this
2516
+ */
2517
+ move: function move(offsetX) {
2518
+ var offsetY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : offsetX;
2519
+ var _this$canvasData = this.canvasData,
2520
+ left = _this$canvasData.left,
2521
+ top = _this$canvasData.top;
2522
+ return this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY));
2523
+ },
2524
+
2525
+ /**
2526
+ * Move the canvas to an absolute point
2527
+ * @param {number} x - The x-axis coordinate.
2528
+ * @param {number} [y=x] - The y-axis coordinate.
2529
+ * @returns {Cropper} this
2530
+ */
2531
+ moveTo: function moveTo(x) {
2532
+ var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x;
2533
+ var canvasData = this.canvasData;
2534
+ var changed = false;
2535
+ x = Number(x);
2536
+ y = Number(y);
2537
+
2538
+ if (this.ready && !this.disabled && this.options.movable) {
2539
+ if (isNumber(x)) {
2540
+ canvasData.left = x;
2541
+ changed = true;
2542
+ }
2543
+
2544
+ if (isNumber(y)) {
2545
+ canvasData.top = y;
2546
+ changed = true;
2547
+ }
2548
+
2549
+ if (changed) {
2550
+ this.renderCanvas(true);
2551
+ }
2552
+ }
2553
+
2554
+ return this;
2555
+ },
2556
+
2557
+ /**
2558
+ * Zoom the canvas with a relative ratio
2559
+ * @param {number} ratio - The target ratio.
2560
+ * @param {Event} _originalEvent - The original event if any.
2561
+ * @returns {Cropper} this
2562
+ */
2563
+ zoom: function zoom(ratio, _originalEvent) {
2564
+ var canvasData = this.canvasData;
2565
+ ratio = Number(ratio);
2566
+
2567
+ if (ratio < 0) {
2568
+ ratio = 1 / (1 - ratio);
2569
+ } else {
2570
+ ratio = 1 + ratio;
2571
+ }
2572
+
2573
+ return this.zoomTo(canvasData.width * ratio / canvasData.naturalWidth, null, _originalEvent);
2574
+ },
2575
+
2576
+ /**
2577
+ * Zoom the canvas to an absolute ratio
2578
+ * @param {number} ratio - The target ratio.
2579
+ * @param {Object} pivot - The zoom pivot point coordinate.
2580
+ * @param {Event} _originalEvent - The original event if any.
2581
+ * @returns {Cropper} this
2582
+ */
2583
+ zoomTo: function zoomTo(ratio, pivot, _originalEvent) {
2584
+ var options = this.options,
2585
+ canvasData = this.canvasData;
2586
+ var width = canvasData.width,
2587
+ height = canvasData.height,
2588
+ naturalWidth = canvasData.naturalWidth,
2589
+ naturalHeight = canvasData.naturalHeight;
2590
+ ratio = Number(ratio);
2591
+
2592
+ if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) {
2593
+ var newWidth = naturalWidth * ratio;
2594
+ var newHeight = naturalHeight * ratio;
2595
+
2596
+ if (dispatchEvent(this.element, EVENT_ZOOM, {
2597
+ ratio: ratio,
2598
+ oldRatio: width / naturalWidth,
2599
+ originalEvent: _originalEvent
2600
+ }) === false) {
2601
+ return this;
2602
+ }
2603
+
2604
+ if (_originalEvent) {
2605
+ var pointers = this.pointers;
2606
+ var offset = getOffset(this.cropper);
2607
+ var center = pointers && Object.keys(pointers).length ? getPointersCenter(pointers) : {
2608
+ pageX: _originalEvent.pageX,
2609
+ pageY: _originalEvent.pageY
2610
+ }; // Zoom from the triggering point of the event
2611
+
2612
+ canvasData.left -= (newWidth - width) * ((center.pageX - offset.left - canvasData.left) / width);
2613
+ canvasData.top -= (newHeight - height) * ((center.pageY - offset.top - canvasData.top) / height);
2614
+ } else if (isPlainObject(pivot) && isNumber(pivot.x) && isNumber(pivot.y)) {
2615
+ canvasData.left -= (newWidth - width) * ((pivot.x - canvasData.left) / width);
2616
+ canvasData.top -= (newHeight - height) * ((pivot.y - canvasData.top) / height);
2617
+ } else {
2618
+ // Zoom from the center of the canvas
2619
+ canvasData.left -= (newWidth - width) / 2;
2620
+ canvasData.top -= (newHeight - height) / 2;
2621
+ }
2622
+
2623
+ canvasData.width = newWidth;
2624
+ canvasData.height = newHeight;
2625
+ this.renderCanvas(true);
2626
+ }
2627
+
2628
+ return this;
2629
+ },
2630
+
2631
+ /**
2632
+ * Rotate the canvas with a relative degree
2633
+ * @param {number} degree - The rotate degree.
2634
+ * @returns {Cropper} this
2635
+ */
2636
+ rotate: function rotate(degree) {
2637
+ return this.rotateTo((this.imageData.rotate || 0) + Number(degree));
2638
+ },
2639
+
2640
+ /**
2641
+ * Rotate the canvas to an absolute degree
2642
+ * @param {number} degree - The rotate degree.
2643
+ * @returns {Cropper} this
2644
+ */
2645
+ rotateTo: function rotateTo(degree) {
2646
+ degree = Number(degree);
2647
+
2648
+ if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) {
2649
+ this.imageData.rotate = degree % 360;
2650
+ this.renderCanvas(true, true);
2651
+ }
2652
+
2653
+ return this;
2654
+ },
2655
+
2656
+ /**
2657
+ * Scale the image on the x-axis.
2658
+ * @param {number} scaleX - The scale ratio on the x-axis.
2659
+ * @returns {Cropper} this
2660
+ */
2661
+ scaleX: function scaleX(_scaleX) {
2662
+ var scaleY = this.imageData.scaleY;
2663
+ return this.scale(_scaleX, isNumber(scaleY) ? scaleY : 1);
2664
+ },
2665
+
2666
+ /**
2667
+ * Scale the image on the y-axis.
2668
+ * @param {number} scaleY - The scale ratio on the y-axis.
2669
+ * @returns {Cropper} this
2670
+ */
2671
+ scaleY: function scaleY(_scaleY) {
2672
+ var scaleX = this.imageData.scaleX;
2673
+ return this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY);
2674
+ },
2675
+
2676
+ /**
2677
+ * Scale the image
2678
+ * @param {number} scaleX - The scale ratio on the x-axis.
2679
+ * @param {number} [scaleY=scaleX] - The scale ratio on the y-axis.
2680
+ * @returns {Cropper} this
2681
+ */
2682
+ scale: function scale(scaleX) {
2683
+ var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX;
2684
+ var imageData = this.imageData;
2685
+ var transformed = false;
2686
+ scaleX = Number(scaleX);
2687
+ scaleY = Number(scaleY);
2688
+
2689
+ if (this.ready && !this.disabled && this.options.scalable) {
2690
+ if (isNumber(scaleX)) {
2691
+ imageData.scaleX = scaleX;
2692
+ transformed = true;
2693
+ }
2694
+
2695
+ if (isNumber(scaleY)) {
2696
+ imageData.scaleY = scaleY;
2697
+ transformed = true;
2698
+ }
2699
+
2700
+ if (transformed) {
2701
+ this.renderCanvas(true, true);
2702
+ }
2703
+ }
2704
+
2705
+ return this;
2706
+ },
2707
+
2708
+ /**
2709
+ * Get the cropped area position and size data (base on the original image)
2710
+ * @param {boolean} [rounded=false] - Indicate if round the data values or not.
2711
+ * @returns {Object} The result cropped data.
2712
+ */
2713
+ getData: function getData() {
2714
+ var rounded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
2715
+ var options = this.options,
2716
+ imageData = this.imageData,
2717
+ canvasData = this.canvasData,
2718
+ cropBoxData = this.cropBoxData;
2719
+ var data;
2720
+
2721
+ if (this.ready && this.cropped) {
2722
+ data = {
2723
+ x: cropBoxData.left - canvasData.left,
2724
+ y: cropBoxData.top - canvasData.top,
2725
+ width: cropBoxData.width,
2726
+ height: cropBoxData.height
2727
+ };
2728
+ var ratio = imageData.width / imageData.naturalWidth;
2729
+ forEach(data, function (n, i) {
2730
+ data[i] = n / ratio;
2731
+ });
2732
+
2733
+ if (rounded) {
2734
+ // In case rounding off leads to extra 1px in right or bottom border
2735
+ // we should round the top-left corner and the dimension (#343).
2736
+ var bottom = Math.round(data.y + data.height);
2737
+ var right = Math.round(data.x + data.width);
2738
+ data.x = Math.round(data.x);
2739
+ data.y = Math.round(data.y);
2740
+ data.width = right - data.x;
2741
+ data.height = bottom - data.y;
2742
+ }
2743
+ } else {
2744
+ data = {
2745
+ x: 0,
2746
+ y: 0,
2747
+ width: 0,
2748
+ height: 0
2749
+ };
2750
+ }
2751
+
2752
+ if (options.rotatable) {
2753
+ data.rotate = imageData.rotate || 0;
2754
+ }
2755
+
2756
+ if (options.scalable) {
2757
+ data.scaleX = imageData.scaleX || 1;
2758
+ data.scaleY = imageData.scaleY || 1;
2759
+ }
2760
+
2761
+ return data;
2762
+ },
2763
+
2764
+ /**
2765
+ * Set the cropped area position and size with new data
2766
+ * @param {Object} data - The new data.
2767
+ * @returns {Cropper} this
2768
+ */
2769
+ setData: function setData(data) {
2770
+ var options = this.options,
2771
+ imageData = this.imageData,
2772
+ canvasData = this.canvasData;
2773
+ var cropBoxData = {};
2774
+
2775
+ if (this.ready && !this.disabled && isPlainObject(data)) {
2776
+ var transformed = false;
2777
+
2778
+ if (options.rotatable) {
2779
+ if (isNumber(data.rotate) && data.rotate !== imageData.rotate) {
2780
+ imageData.rotate = data.rotate;
2781
+ transformed = true;
2782
+ }
2783
+ }
2784
+
2785
+ if (options.scalable) {
2786
+ if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) {
2787
+ imageData.scaleX = data.scaleX;
2788
+ transformed = true;
2789
+ }
2790
+
2791
+ if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) {
2792
+ imageData.scaleY = data.scaleY;
2793
+ transformed = true;
2794
+ }
2795
+ }
2796
+
2797
+ if (transformed) {
2798
+ this.renderCanvas(true, true);
2799
+ }
2800
+
2801
+ var ratio = imageData.width / imageData.naturalWidth;
2802
+
2803
+ if (isNumber(data.x)) {
2804
+ cropBoxData.left = data.x * ratio + canvasData.left;
2805
+ }
2806
+
2807
+ if (isNumber(data.y)) {
2808
+ cropBoxData.top = data.y * ratio + canvasData.top;
2809
+ }
2810
+
2811
+ if (isNumber(data.width)) {
2812
+ cropBoxData.width = data.width * ratio;
2813
+ }
2814
+
2815
+ if (isNumber(data.height)) {
2816
+ cropBoxData.height = data.height * ratio;
2817
+ }
2818
+
2819
+ this.setCropBoxData(cropBoxData);
2820
+ }
2821
+
2822
+ return this;
2823
+ },
2824
+
2825
+ /**
2826
+ * Get the container size data.
2827
+ * @returns {Object} The result container data.
2828
+ */
2829
+ getContainerData: function getContainerData() {
2830
+ return this.ready ? assign({}, this.containerData) : {};
2831
+ },
2832
+
2833
+ /**
2834
+ * Get the image position and size data.
2835
+ * @returns {Object} The result image data.
2836
+ */
2837
+ getImageData: function getImageData() {
2838
+ return this.sized ? assign({}, this.imageData) : {};
2839
+ },
2840
+
2841
+ /**
2842
+ * Get the canvas position and size data.
2843
+ * @returns {Object} The result canvas data.
2844
+ */
2845
+ getCanvasData: function getCanvasData() {
2846
+ var canvasData = this.canvasData;
2847
+ var data = {};
2848
+
2849
+ if (this.ready) {
2850
+ forEach(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (n) {
2851
+ data[n] = canvasData[n];
2852
+ });
2853
+ }
2854
+
2855
+ return data;
2856
+ },
2857
+
2858
+ /**
2859
+ * Set the canvas position and size with new data.
2860
+ * @param {Object} data - The new canvas data.
2861
+ * @returns {Cropper} this
2862
+ */
2863
+ setCanvasData: function setCanvasData(data) {
2864
+ var canvasData = this.canvasData;
2865
+ var aspectRatio = canvasData.aspectRatio;
2866
+
2867
+ if (this.ready && !this.disabled && isPlainObject(data)) {
2868
+ if (isNumber(data.left)) {
2869
+ canvasData.left = data.left;
2870
+ }
2871
+
2872
+ if (isNumber(data.top)) {
2873
+ canvasData.top = data.top;
2874
+ }
2875
+
2876
+ if (isNumber(data.width)) {
2877
+ canvasData.width = data.width;
2878
+ canvasData.height = data.width / aspectRatio;
2879
+ } else if (isNumber(data.height)) {
2880
+ canvasData.height = data.height;
2881
+ canvasData.width = data.height * aspectRatio;
2882
+ }
2883
+
2884
+ this.renderCanvas(true);
2885
+ }
2886
+
2887
+ return this;
2888
+ },
2889
+
2890
+ /**
2891
+ * Get the crop box position and size data.
2892
+ * @returns {Object} The result crop box data.
2893
+ */
2894
+ getCropBoxData: function getCropBoxData() {
2895
+ var cropBoxData = this.cropBoxData;
2896
+ var data;
2897
+
2898
+ if (this.ready && this.cropped) {
2899
+ data = {
2900
+ left: cropBoxData.left,
2901
+ top: cropBoxData.top,
2902
+ width: cropBoxData.width,
2903
+ height: cropBoxData.height
2904
+ };
2905
+ }
2906
+
2907
+ return data || {};
2908
+ },
2909
+
2910
+ /**
2911
+ * Set the crop box position and size with new data.
2912
+ * @param {Object} data - The new crop box data.
2913
+ * @returns {Cropper} this
2914
+ */
2915
+ setCropBoxData: function setCropBoxData(data) {
2916
+ var cropBoxData = this.cropBoxData;
2917
+ var aspectRatio = this.options.aspectRatio;
2918
+ var widthChanged;
2919
+ var heightChanged;
2920
+
2921
+ if (this.ready && this.cropped && !this.disabled && isPlainObject(data)) {
2922
+ if (isNumber(data.left)) {
2923
+ cropBoxData.left = data.left;
2924
+ }
2925
+
2926
+ if (isNumber(data.top)) {
2927
+ cropBoxData.top = data.top;
2928
+ }
2929
+
2930
+ if (isNumber(data.width) && data.width !== cropBoxData.width) {
2931
+ widthChanged = true;
2932
+ cropBoxData.width = data.width;
2933
+ }
2934
+
2935
+ if (isNumber(data.height) && data.height !== cropBoxData.height) {
2936
+ heightChanged = true;
2937
+ cropBoxData.height = data.height;
2938
+ }
2939
+
2940
+ if (aspectRatio) {
2941
+ if (widthChanged) {
2942
+ cropBoxData.height = cropBoxData.width / aspectRatio;
2943
+ } else if (heightChanged) {
2944
+ cropBoxData.width = cropBoxData.height * aspectRatio;
2945
+ }
2946
+ }
2947
+
2948
+ this.renderCropBox();
2949
+ }
2950
+
2951
+ return this;
2952
+ },
2953
+
2954
+ /**
2955
+ * Get a canvas drawn the cropped image.
2956
+ * @param {Object} [options={}] - The config options.
2957
+ * @returns {HTMLCanvasElement} - The result canvas.
2958
+ */
2959
+ getCroppedCanvas: function getCroppedCanvas() {
2960
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2961
+
2962
+ if (!this.ready || !window.HTMLCanvasElement) {
2963
+ return null;
2964
+ }
2965
+
2966
+ var canvasData = this.canvasData;
2967
+ var source = getSourceCanvas(this.image, this.imageData, canvasData, options); // Returns the source canvas if it is not cropped.
2968
+
2969
+ if (!this.cropped) {
2970
+ return source;
2971
+ }
2972
+
2973
+ var _this$getData = this.getData(),
2974
+ initialX = _this$getData.x,
2975
+ initialY = _this$getData.y,
2976
+ initialWidth = _this$getData.width,
2977
+ initialHeight = _this$getData.height;
2978
+
2979
+ var ratio = source.width / Math.floor(canvasData.naturalWidth);
2980
+
2981
+ if (ratio !== 1) {
2982
+ initialX *= ratio;
2983
+ initialY *= ratio;
2984
+ initialWidth *= ratio;
2985
+ initialHeight *= ratio;
2986
+ }
2987
+
2988
+ var aspectRatio = initialWidth / initialHeight;
2989
+ var maxSizes = getAdjustedSizes({
2990
+ aspectRatio: aspectRatio,
2991
+ width: options.maxWidth || Infinity,
2992
+ height: options.maxHeight || Infinity
2993
+ });
2994
+ var minSizes = getAdjustedSizes({
2995
+ aspectRatio: aspectRatio,
2996
+ width: options.minWidth || 0,
2997
+ height: options.minHeight || 0
2998
+ }, 'cover');
2999
+
3000
+ var _getAdjustedSizes = getAdjustedSizes({
3001
+ aspectRatio: aspectRatio,
3002
+ width: options.width || (ratio !== 1 ? source.width : initialWidth),
3003
+ height: options.height || (ratio !== 1 ? source.height : initialHeight)
3004
+ }),
3005
+ width = _getAdjustedSizes.width,
3006
+ height = _getAdjustedSizes.height;
3007
+
3008
+ width = Math.min(maxSizes.width, Math.max(minSizes.width, width));
3009
+ height = Math.min(maxSizes.height, Math.max(minSizes.height, height));
3010
+ var canvas = document.createElement('canvas');
3011
+ var context = canvas.getContext('2d');
3012
+ canvas.width = normalizeDecimalNumber(width);
3013
+ canvas.height = normalizeDecimalNumber(height);
3014
+ context.fillStyle = options.fillColor || 'transparent';
3015
+ context.fillRect(0, 0, width, height);
3016
+ var _options$imageSmoothi = options.imageSmoothingEnabled,
3017
+ imageSmoothingEnabled = _options$imageSmoothi === void 0 ? true : _options$imageSmoothi,
3018
+ imageSmoothingQuality = options.imageSmoothingQuality;
3019
+ context.imageSmoothingEnabled = imageSmoothingEnabled;
3020
+
3021
+ if (imageSmoothingQuality) {
3022
+ context.imageSmoothingQuality = imageSmoothingQuality;
3023
+ } // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage
3024
+
3025
+
3026
+ var sourceWidth = source.width;
3027
+ var sourceHeight = source.height; // Source canvas parameters
3028
+
3029
+ var srcX = initialX;
3030
+ var srcY = initialY;
3031
+ var srcWidth;
3032
+ var srcHeight; // Destination canvas parameters
3033
+
3034
+ var dstX;
3035
+ var dstY;
3036
+ var dstWidth;
3037
+ var dstHeight;
3038
+
3039
+ if (srcX <= -initialWidth || srcX > sourceWidth) {
3040
+ srcX = 0;
3041
+ srcWidth = 0;
3042
+ dstX = 0;
3043
+ dstWidth = 0;
3044
+ } else if (srcX <= 0) {
3045
+ dstX = -srcX;
3046
+ srcX = 0;
3047
+ srcWidth = Math.min(sourceWidth, initialWidth + srcX);
3048
+ dstWidth = srcWidth;
3049
+ } else if (srcX <= sourceWidth) {
3050
+ dstX = 0;
3051
+ srcWidth = Math.min(initialWidth, sourceWidth - srcX);
3052
+ dstWidth = srcWidth;
3053
+ }
3054
+
3055
+ if (srcWidth <= 0 || srcY <= -initialHeight || srcY > sourceHeight) {
3056
+ srcY = 0;
3057
+ srcHeight = 0;
3058
+ dstY = 0;
3059
+ dstHeight = 0;
3060
+ } else if (srcY <= 0) {
3061
+ dstY = -srcY;
3062
+ srcY = 0;
3063
+ srcHeight = Math.min(sourceHeight, initialHeight + srcY);
3064
+ dstHeight = srcHeight;
3065
+ } else if (srcY <= sourceHeight) {
3066
+ dstY = 0;
3067
+ srcHeight = Math.min(initialHeight, sourceHeight - srcY);
3068
+ dstHeight = srcHeight;
3069
+ }
3070
+
3071
+ var params = [srcX, srcY, srcWidth, srcHeight]; // Avoid "IndexSizeError"
3072
+
3073
+ if (dstWidth > 0 && dstHeight > 0) {
3074
+ var scale = width / initialWidth;
3075
+ params.push(dstX * scale, dstY * scale, dstWidth * scale, dstHeight * scale);
3076
+ } // All the numerical parameters should be integer for `drawImage`
3077
+ // https://github.com/fengyuanchen/cropper/issues/476
3078
+
3079
+
3080
+ context.drawImage.apply(context, [source].concat(_toConsumableArray(params.map(function (param) {
3081
+ return Math.floor(normalizeDecimalNumber(param));
3082
+ }))));
3083
+ return canvas;
3084
+ },
3085
+
3086
+ /**
3087
+ * Change the aspect ratio of the crop box.
3088
+ * @param {number} aspectRatio - The new aspect ratio.
3089
+ * @returns {Cropper} this
3090
+ */
3091
+ setAspectRatio: function setAspectRatio(aspectRatio) {
3092
+ var options = this.options;
3093
+
3094
+ if (!this.disabled && !isUndefined(aspectRatio)) {
3095
+ // 0 -> NaN
3096
+ options.aspectRatio = Math.max(0, aspectRatio) || NaN;
3097
+
3098
+ if (this.ready) {
3099
+ this.initCropBox();
3100
+
3101
+ if (this.cropped) {
3102
+ this.renderCropBox();
3103
+ }
3104
+ }
3105
+ }
3106
+
3107
+ return this;
3108
+ },
3109
+
3110
+ /**
3111
+ * Change the drag mode.
3112
+ * @param {string} mode - The new drag mode.
3113
+ * @returns {Cropper} this
3114
+ */
3115
+ setDragMode: function setDragMode(mode) {
3116
+ var options = this.options,
3117
+ dragBox = this.dragBox,
3118
+ face = this.face;
3119
+
3120
+ if (this.ready && !this.disabled) {
3121
+ var croppable = mode === DRAG_MODE_CROP;
3122
+ var movable = options.movable && mode === DRAG_MODE_MOVE;
3123
+ mode = croppable || movable ? mode : DRAG_MODE_NONE;
3124
+ options.dragMode = mode;
3125
+ setData(dragBox, DATA_ACTION, mode);
3126
+ toggleClass(dragBox, CLASS_CROP, croppable);
3127
+ toggleClass(dragBox, CLASS_MOVE, movable);
3128
+
3129
+ if (!options.cropBoxMovable) {
3130
+ // Sync drag mode to crop box when it is not movable
3131
+ setData(face, DATA_ACTION, mode);
3132
+ toggleClass(face, CLASS_CROP, croppable);
3133
+ toggleClass(face, CLASS_MOVE, movable);
3134
+ }
3135
+ }
3136
+
3137
+ return this;
3138
+ }
3139
+ };
3140
+
3141
+ var AnotherCropper = WINDOW.Cropper;
3142
+
3143
+ var Cropper =
3144
+ /*#__PURE__*/
3145
+ function () {
3146
+ /**
3147
+ * Create a new Cropper.
3148
+ * @param {Element} element - The target element for cropping.
3149
+ * @param {Object} [options={}] - The configuration options.
3150
+ */
3151
+ function Cropper(element) {
3152
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
3153
+
3154
+ _classCallCheck(this, Cropper);
3155
+
3156
+ if (!element || !REGEXP_TAG_NAME.test(element.tagName)) {
3157
+ throw new Error('The first argument is required and must be an <img> or <canvas> element.');
3158
+ }
3159
+
3160
+ this.element = element;
3161
+ this.options = assign({}, DEFAULTS, isPlainObject(options) && options);
3162
+ this.cropped = false;
3163
+ this.disabled = false;
3164
+ this.pointers = {};
3165
+ this.ready = false;
3166
+ this.reloading = false;
3167
+ this.replaced = false;
3168
+ this.sized = false;
3169
+ this.sizing = false;
3170
+ this.init();
3171
+ }
3172
+
3173
+ _createClass(Cropper, [{
3174
+ key: "init",
3175
+ value: function init() {
3176
+ var element = this.element;
3177
+ var tagName = element.tagName.toLowerCase();
3178
+ var url;
3179
+
3180
+ if (element[NAMESPACE]) {
3181
+ return;
3182
+ }
3183
+
3184
+ element[NAMESPACE] = this;
3185
+
3186
+ if (tagName === 'img') {
3187
+ this.isImg = true; // e.g.: "img/picture.jpg"
3188
+
3189
+ url = element.getAttribute('src') || '';
3190
+ this.originalUrl = url; // Stop when it's a blank image
3191
+
3192
+ if (!url) {
3193
+ return;
3194
+ } // e.g.: "http://example.com/img/picture.jpg"
3195
+
3196
+
3197
+ url = element.src;
3198
+ } else if (tagName === 'canvas' && window.HTMLCanvasElement) {
3199
+ url = element.toDataURL();
3200
+ }
3201
+
3202
+ this.load(url);
3203
+ }
3204
+ }, {
3205
+ key: "load",
3206
+ value: function load(url) {
3207
+ var _this = this;
3208
+
3209
+ if (!url) {
3210
+ return;
3211
+ }
3212
+
3213
+ this.url = url;
3214
+ this.imageData = {};
3215
+ var element = this.element,
3216
+ options = this.options;
3217
+
3218
+ if (!options.rotatable && !options.scalable) {
3219
+ options.checkOrientation = false;
3220
+ } // Only IE10+ supports Typed Arrays
3221
+
3222
+
3223
+ if (!options.checkOrientation || !window.ArrayBuffer) {
3224
+ this.clone();
3225
+ return;
3226
+ } // Read ArrayBuffer from Data URL of JPEG images directly for better performance.
3227
+
3228
+
3229
+ if (REGEXP_DATA_URL_JPEG.test(url)) {
3230
+ this.read(dataURLToArrayBuffer(url));
3231
+ return;
3232
+ }
3233
+
3234
+ var xhr = new XMLHttpRequest();
3235
+ var clone = this.clone.bind(this);
3236
+ this.reloading = true;
3237
+ this.xhr = xhr; // 1. Cross origin requests are only supported for protocol schemes:
3238
+ // http, https, data, chrome, chrome-extension.
3239
+ // 2. Access to XMLHttpRequest from a Data URL will be blocked by CORS policy
3240
+ // in some browsers as IE11 and Safari.
3241
+
3242
+ xhr.onabort = clone;
3243
+ xhr.onerror = clone;
3244
+ xhr.ontimeout = clone;
3245
+
3246
+ xhr.onprogress = function () {
3247
+ if (xhr.getResponseHeader('content-type') !== MIME_TYPE_JPEG) {
3248
+ xhr.abort();
3249
+ }
3250
+ };
3251
+
3252
+ xhr.onload = function () {
3253
+ _this.read(xhr.response);
3254
+ };
3255
+
3256
+ xhr.onloadend = function () {
3257
+ _this.reloading = false;
3258
+ _this.xhr = null;
3259
+ }; // Bust cache when there is a "crossOrigin" property to avoid browser cache error
3260
+
3261
+
3262
+ if (options.checkCrossOrigin && isCrossOriginURL(url) && element.crossOrigin) {
3263
+ url = addTimestamp(url);
3264
+ }
3265
+
3266
+ xhr.open('GET', url);
3267
+ xhr.responseType = 'arraybuffer';
3268
+ xhr.withCredentials = element.crossOrigin === 'use-credentials';
3269
+ xhr.send();
3270
+ }
3271
+ }, {
3272
+ key: "read",
3273
+ value: function read(arrayBuffer) {
3274
+ var options = this.options,
3275
+ imageData = this.imageData; // Reset the orientation value to its default value 1
3276
+ // as some iOS browsers will render image with its orientation
3277
+
3278
+ var orientation = resetAndGetOrientation(arrayBuffer);
3279
+ var rotate = 0;
3280
+ var scaleX = 1;
3281
+ var scaleY = 1;
3282
+
3283
+ if (orientation > 1) {
3284
+ // Generate a new URL which has the default orientation value
3285
+ this.url = arrayBufferToDataURL(arrayBuffer, MIME_TYPE_JPEG);
3286
+
3287
+ var _parseOrientation = parseOrientation(orientation);
3288
+
3289
+ rotate = _parseOrientation.rotate;
3290
+ scaleX = _parseOrientation.scaleX;
3291
+ scaleY = _parseOrientation.scaleY;
3292
+ }
3293
+
3294
+ if (options.rotatable) {
3295
+ imageData.rotate = rotate;
3296
+ }
3297
+
3298
+ if (options.scalable) {
3299
+ imageData.scaleX = scaleX;
3300
+ imageData.scaleY = scaleY;
3301
+ }
3302
+
3303
+ this.clone();
3304
+ }
3305
+ }, {
3306
+ key: "clone",
3307
+ value: function clone() {
3308
+ var element = this.element,
3309
+ url = this.url;
3310
+ var crossOrigin;
3311
+ var crossOriginUrl;
3312
+
3313
+ if (this.options.checkCrossOrigin && isCrossOriginURL(url)) {
3314
+ crossOrigin = element.crossOrigin;
3315
+
3316
+ if (!crossOrigin) {
3317
+ crossOrigin = 'anonymous';
3318
+ } // Bust cache when there is not a "crossOrigin" property (#519)
3319
+
3320
+
3321
+ crossOriginUrl = addTimestamp(url);
3322
+ }
3323
+
3324
+ this.crossOrigin = crossOrigin;
3325
+ this.crossOriginUrl = crossOriginUrl;
3326
+ var image = document.createElement('img');
3327
+
3328
+ if (crossOrigin) {
3329
+ image.crossOrigin = crossOrigin;
3330
+ }
3331
+
3332
+ image.src = crossOriginUrl || url;
3333
+ this.image = image;
3334
+ image.onload = this.start.bind(this);
3335
+ image.onerror = this.stop.bind(this);
3336
+ addClass(image, CLASS_HIDE);
3337
+ element.parentNode.insertBefore(image, element.nextSibling);
3338
+ }
3339
+ }, {
3340
+ key: "start",
3341
+ value: function start() {
3342
+ var _this2 = this;
3343
+
3344
+ var image = this.isImg ? this.element : this.image;
3345
+ image.onload = null;
3346
+ image.onerror = null;
3347
+ this.sizing = true; // Match all browsers that use WebKit as the layout engine in iOS devices,
3348
+ // such as Safari for iOS, Chrome for iOS, and in-app browsers.
3349
+
3350
+ var isIOSWebKit = WINDOW.navigator && /(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(WINDOW.navigator.userAgent);
3351
+
3352
+ var done = function done(naturalWidth, naturalHeight) {
3353
+ assign(_this2.imageData, {
3354
+ naturalWidth: naturalWidth,
3355
+ naturalHeight: naturalHeight,
3356
+ aspectRatio: naturalWidth / naturalHeight
3357
+ });
3358
+ _this2.sizing = false;
3359
+ _this2.sized = true;
3360
+
3361
+ _this2.build();
3362
+ }; // Most modern browsers (excepts iOS WebKit)
3363
+
3364
+
3365
+ if (image.naturalWidth && !isIOSWebKit) {
3366
+ done(image.naturalWidth, image.naturalHeight);
3367
+ return;
3368
+ }
3369
+
3370
+ var sizingImage = document.createElement('img');
3371
+ var body = document.body || document.documentElement;
3372
+ this.sizingImage = sizingImage;
3373
+
3374
+ sizingImage.onload = function () {
3375
+ done(sizingImage.width, sizingImage.height);
3376
+
3377
+ if (!isIOSWebKit) {
3378
+ body.removeChild(sizingImage);
3379
+ }
3380
+ };
3381
+
3382
+ sizingImage.src = image.src; // iOS WebKit will convert the image automatically
3383
+ // with its orientation once append it into DOM (#279)
3384
+
3385
+ if (!isIOSWebKit) {
3386
+ sizingImage.style.cssText = 'left:0;' + 'max-height:none!important;' + 'max-width:none!important;' + 'min-height:0!important;' + 'min-width:0!important;' + 'opacity:0;' + 'position:absolute;' + 'top:0;' + 'z-index:-1;';
3387
+ body.appendChild(sizingImage);
3388
+ }
3389
+ }
3390
+ }, {
3391
+ key: "stop",
3392
+ value: function stop() {
3393
+ var image = this.image;
3394
+ image.onload = null;
3395
+ image.onerror = null;
3396
+ image.parentNode.removeChild(image);
3397
+ this.image = null;
3398
+ }
3399
+ }, {
3400
+ key: "build",
3401
+ value: function build() {
3402
+ if (!this.sized || this.ready) {
3403
+ return;
3404
+ }
3405
+
3406
+ var element = this.element,
3407
+ options = this.options,
3408
+ image = this.image; // Create cropper elements
3409
+
3410
+ var container = element.parentNode;
3411
+ var template = document.createElement('div');
3412
+ template.innerHTML = TEMPLATE;
3413
+ var cropper = template.querySelector(".".concat(NAMESPACE, "-container"));
3414
+ var canvas = cropper.querySelector(".".concat(NAMESPACE, "-canvas"));
3415
+ var dragBox = cropper.querySelector(".".concat(NAMESPACE, "-drag-box"));
3416
+ var cropBox = cropper.querySelector(".".concat(NAMESPACE, "-crop-box"));
3417
+ var face = cropBox.querySelector(".".concat(NAMESPACE, "-face"));
3418
+ this.container = container;
3419
+ this.cropper = cropper;
3420
+ this.canvas = canvas;
3421
+ this.dragBox = dragBox;
3422
+ this.cropBox = cropBox;
3423
+ this.viewBox = cropper.querySelector(".".concat(NAMESPACE, "-view-box"));
3424
+ this.face = face;
3425
+ canvas.appendChild(image); // Hide the original image
3426
+
3427
+ addClass(element, CLASS_HIDDEN); // Inserts the cropper after to the current image
3428
+
3429
+ container.insertBefore(cropper, element.nextSibling); // Show the image if is hidden
3430
+
3431
+ if (!this.isImg) {
3432
+ removeClass(image, CLASS_HIDE);
3433
+ }
3434
+
3435
+ this.initPreview();
3436
+ this.bind();
3437
+ options.initialAspectRatio = Math.max(0, options.initialAspectRatio) || NaN;
3438
+ options.aspectRatio = Math.max(0, options.aspectRatio) || NaN;
3439
+ options.viewMode = Math.max(0, Math.min(3, Math.round(options.viewMode))) || 0;
3440
+ addClass(cropBox, CLASS_HIDDEN);
3441
+
3442
+ if (!options.guides) {
3443
+ addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-dashed")), CLASS_HIDDEN);
3444
+ }
3445
+
3446
+ if (!options.center) {
3447
+ addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-center")), CLASS_HIDDEN);
3448
+ }
3449
+
3450
+ if (options.background) {
3451
+ addClass(cropper, "".concat(NAMESPACE, "-bg"));
3452
+ }
3453
+
3454
+ if (!options.highlight) {
3455
+ addClass(face, CLASS_INVISIBLE);
3456
+ }
3457
+
3458
+ if (options.cropBoxMovable) {
3459
+ addClass(face, CLASS_MOVE);
3460
+ setData(face, DATA_ACTION, ACTION_ALL);
3461
+ }
3462
+
3463
+ if (!options.cropBoxResizable) {
3464
+ addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-line")), CLASS_HIDDEN);
3465
+ addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-point")), CLASS_HIDDEN);
3466
+ }
3467
+
3468
+ this.render();
3469
+ this.ready = true;
3470
+ this.setDragMode(options.dragMode);
3471
+
3472
+ if (options.autoCrop) {
3473
+ this.crop();
3474
+ }
3475
+
3476
+ this.setData(options.data);
3477
+
3478
+ if (isFunction(options.ready)) {
3479
+ addListener(element, EVENT_READY, options.ready, {
3480
+ once: true
3481
+ });
3482
+ }
3483
+
3484
+ dispatchEvent(element, EVENT_READY);
3485
+ }
3486
+ }, {
3487
+ key: "unbuild",
3488
+ value: function unbuild() {
3489
+ if (!this.ready) {
3490
+ return;
3491
+ }
3492
+
3493
+ this.ready = false;
3494
+ this.unbind();
3495
+ this.resetPreview();
3496
+ this.cropper.parentNode.removeChild(this.cropper);
3497
+ removeClass(this.element, CLASS_HIDDEN);
3498
+ }
3499
+ }, {
3500
+ key: "uncreate",
3501
+ value: function uncreate() {
3502
+ if (this.ready) {
3503
+ this.unbuild();
3504
+ this.ready = false;
3505
+ this.cropped = false;
3506
+ } else if (this.sizing) {
3507
+ this.sizingImage.onload = null;
3508
+ this.sizing = false;
3509
+ this.sized = false;
3510
+ } else if (this.reloading) {
3511
+ this.xhr.onabort = null;
3512
+ this.xhr.abort();
3513
+ } else if (this.image) {
3514
+ this.stop();
3515
+ }
3516
+ }
3517
+ /**
3518
+ * Get the no conflict cropper class.
3519
+ * @returns {Cropper} The cropper class.
3520
+ */
3521
+
3522
+ }], [{
3523
+ key: "noConflict",
3524
+ value: function noConflict() {
3525
+ window.Cropper = AnotherCropper;
3526
+ return Cropper;
3527
+ }
3528
+ /**
3529
+ * Change the default options.
3530
+ * @param {Object} options - The new default options.
3531
+ */
3532
+
3533
+ }, {
3534
+ key: "setDefaults",
3535
+ value: function setDefaults(options) {
3536
+ assign(DEFAULTS, isPlainObject(options) && options);
3537
+ }
3538
+ }]);
3539
+
3540
+ return Cropper;
3541
+ }();
3542
+
3543
+ assign(Cropper.prototype, render, preview, events, handlers, change, methods);
3544
+
3545
+ module.exports = Cropper;
vendor/cropperjs/dist/cropper.css ADDED
@@ -0,0 +1,304 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Cropper.js v1.5.3
3
+ * https://fengyuanchen.github.io/cropperjs
4
+ *
5
+ * Copyright 2015-present Chen Fengyuan
6
+ * Released under the MIT license
7
+ *
8
+ * Date: 2019-07-10T12:07:41.696Z
9
+ */
10
+
11
+ .cropper-container {
12
+ direction: ltr;
13
+ font-size: 0;
14
+ line-height: 0;
15
+ position: relative;
16
+ -ms-touch-action: none;
17
+ touch-action: none;
18
+ -webkit-user-select: none;
19
+ -moz-user-select: none;
20
+ -ms-user-select: none;
21
+ user-select: none;
22
+ }
23
+
24
+ .cropper-container img {
25
+ display: block;
26
+ height: 100%;
27
+ image-orientation: 0deg;
28
+ max-height: none !important;
29
+ max-width: none !important;
30
+ min-height: 0 !important;
31
+ min-width: 0 !important;
32
+ width: 100%;
33
+ }
34
+
35
+ .cropper-wrap-box,
36
+ .cropper-canvas,
37
+ .cropper-drag-box,
38
+ .cropper-crop-box,
39
+ .cropper-modal {
40
+ bottom: 0;
41
+ left: 0;
42
+ position: absolute;
43
+ right: 0;
44
+ top: 0;
45
+ }
46
+
47
+ .cropper-wrap-box,
48
+ .cropper-canvas {
49
+ overflow: hidden;
50
+ }
51
+
52
+ .cropper-drag-box {
53
+ background-color: #fff;
54
+ opacity: 0;
55
+ }
56
+
57
+ .cropper-modal {
58
+ background-color: #000;
59
+ opacity: 0.5;
60
+ }
61
+
62
+ .cropper-view-box {
63
+ display: block;
64
+ height: 100%;
65
+ outline: 1px solid #39f;
66
+ outline-color: rgba(51, 153, 255, 0.75);
67
+ overflow: hidden;
68
+ width: 100%;
69
+ }
70
+
71
+ .cropper-dashed {
72
+ border: 0 dashed #eee;
73
+ display: block;
74
+ opacity: 0.5;
75
+ position: absolute;
76
+ }
77
+
78
+ .cropper-dashed.dashed-h {
79
+ border-bottom-width: 1px;
80
+ border-top-width: 1px;
81
+ height: calc(100% / 3);
82
+ left: 0;
83
+ top: calc(100% / 3);
84
+ width: 100%;
85
+ }
86
+
87
+ .cropper-dashed.dashed-v {
88
+ border-left-width: 1px;
89
+ border-right-width: 1px;
90
+ height: 100%;
91
+ left: calc(100% / 3);
92
+ top: 0;
93
+ width: calc(100% / 3);
94
+ }
95
+
96
+ .cropper-center {
97
+ display: block;
98
+ height: 0;
99
+ left: 50%;
100
+ opacity: 0.75;
101
+ position: absolute;
102
+ top: 50%;
103
+ width: 0;
104
+ }
105
+
106
+ .cropper-center::before,
107
+ .cropper-center::after {
108
+ background-color: #eee;
109
+ content: ' ';
110
+ display: block;
111
+ position: absolute;
112
+ }
113
+
114
+ .cropper-center::before {
115
+ height: 1px;
116
+ left: -3px;
117
+ top: 0;
118
+ width: 7px;
119
+ }
120
+
121
+ .cropper-center::after {
122
+ height: 7px;
123
+ left: 0;
124
+ top: -3px;
125
+ width: 1px;
126
+ }
127
+
128
+ .cropper-face,
129
+ .cropper-line,
130
+ .cropper-point {
131
+ display: block;
132
+ height: 100%;
133
+ opacity: 0.1;
134
+ position: absolute;
135
+ width: 100%;
136
+ }
137
+
138
+ .cropper-face {
139
+ background-color: #fff;
140
+ left: 0;
141
+ top: 0;
142
+ }
143
+
144
+ .cropper-line {
145
+ background-color: #39f;
146
+ }
147
+
148
+ .cropper-line.line-e {
149
+ cursor: ew-resize;
150
+ right: -3px;
151
+ top: 0;
152
+ width: 5px;
153
+ }
154
+
155
+ .cropper-line.line-n {
156
+ cursor: ns-resize;
157
+ height: 5px;
158
+ left: 0;
159
+ top: -3px;
160
+ }
161
+
162
+ .cropper-line.line-w {
163
+ cursor: ew-resize;
164
+ left: -3px;
165
+ top: 0;
166
+ width: 5px;
167
+ }
168
+
169
+ .cropper-line.line-s {
170
+ bottom: -3px;
171
+ cursor: ns-resize;
172
+ height: 5px;
173
+ left: 0;
174
+ }
175
+
176
+ .cropper-point {
177
+ background-color: #39f;
178
+ height: 5px;
179
+ opacity: 0.75;
180
+ width: 5px;
181
+ }
182
+
183
+ .cropper-point.point-e {
184
+ cursor: ew-resize;
185
+ margin-top: -3px;
186
+ right: -3px;
187
+ top: 50%;
188
+ }
189
+
190
+ .cropper-point.point-n {
191
+ cursor: ns-resize;
192
+ left: 50%;
193
+ margin-left: -3px;
194
+ top: -3px;
195
+ }
196
+
197
+ .cropper-point.point-w {
198
+ cursor: ew-resize;
199
+ left: -3px;
200
+ margin-top: -3px;
201
+ top: 50%;
202
+ }
203
+
204
+ .cropper-point.point-s {
205
+ bottom: -3px;
206
+ cursor: s-resize;
207
+ left: 50%;
208
+ margin-left: -3px;
209
+ }
210
+
211
+ .cropper-point.point-ne {
212
+ cursor: nesw-resize;
213
+ right: -3px;
214
+ top: -3px;
215
+ }
216
+
217
+ .cropper-point.point-nw {
218
+ cursor: nwse-resize;
219
+ left: -3px;
220
+ top: -3px;
221
+ }
222
+
223
+ .cropper-point.point-sw {
224
+ bottom: -3px;
225
+ cursor: nesw-resize;
226
+ left: -3px;
227
+ }
228
+
229
+ .cropper-point.point-se {
230
+ bottom: -3px;
231
+ cursor: nwse-resize;
232
+ height: 20px;
233
+ opacity: 1;
234
+ right: -3px;
235
+ width: 20px;
236
+ }
237
+
238
+ @media (min-width: 768px) {
239
+ .cropper-point.point-se {
240
+ height: 15px;
241
+ width: 15px;
242
+ }
243
+ }
244
+
245
+ @media (min-width: 992px) {
246
+ .cropper-point.point-se {
247
+ height: 10px;
248
+ width: 10px;
249
+ }
250
+ }
251
+
252
+ @media (min-width: 1200px) {
253
+ .cropper-point.point-se {
254
+ height: 5px;
255
+ opacity: 0.75;
256
+ width: 5px;
257
+ }
258
+ }
259
+
260
+ .cropper-point.point-se::before {
261
+ background-color: #39f;
262
+ bottom: -50%;
263
+ content: ' ';
264
+ display: block;
265
+ height: 200%;
266
+ opacity: 0;
267
+ position: absolute;
268
+ right: -50%;
269
+ width: 200%;
270
+ }
271
+
272
+ .cropper-invisible {
273
+ opacity: 0;
274
+ }
275
+
276
+ .cropper-bg {
277
+ background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');
278
+ }
279
+
280
+ .cropper-hide {
281
+ display: block;
282
+ height: 0;
283
+ position: absolute;
284
+ width: 0;
285
+ }
286
+
287
+ .cropper-hidden {
288
+ display: none !important;
289
+ }
290
+
291
+ .cropper-move {
292
+ cursor: move;
293
+ }
294
+
295
+ .cropper-crop {
296
+ cursor: crosshair;
297
+ }
298
+
299
+ .cropper-disabled .cropper-drag-box,
300
+ .cropper-disabled .cropper-face,
301
+ .cropper-disabled .cropper-line,
302
+ .cropper-disabled .cropper-point {
303
+ cursor: not-allowed;
304
+ }
vendor/cropperjs/dist/cropper.esm.js ADDED
@@ -0,0 +1,3543 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Cropper.js v1.5.3
3
+ * https://fengyuanchen.github.io/cropperjs
4
+ *
5
+ * Copyright 2015-present Chen Fengyuan
6
+ * Released under the MIT license
7
+ *
8
+ * Date: 2019-07-10T12:07:44.557Z
9
+ */
10
+
11
+ function _typeof(obj) {
12
+ if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
13
+ _typeof = function (obj) {
14
+ return typeof obj;
15
+ };
16
+ } else {
17
+ _typeof = function (obj) {
18
+ return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
19
+ };
20
+ }
21
+
22
+ return _typeof(obj);
23
+ }
24
+
25
+ function _classCallCheck(instance, Constructor) {
26
+ if (!(instance instanceof Constructor)) {
27
+ throw new TypeError("Cannot call a class as a function");
28
+ }
29
+ }
30
+
31
+ function _defineProperties(target, props) {
32
+ for (var i = 0; i < props.length; i++) {
33
+ var descriptor = props[i];
34
+ descriptor.enumerable = descriptor.enumerable || false;
35
+ descriptor.configurable = true;
36
+ if ("value" in descriptor) descriptor.writable = true;
37
+ Object.defineProperty(target, descriptor.key, descriptor);
38
+ }
39
+ }
40
+
41
+ function _createClass(Constructor, protoProps, staticProps) {
42
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
43
+ if (staticProps) _defineProperties(Constructor, staticProps);
44
+ return Constructor;
45
+ }
46
+
47
+ function _toConsumableArray(arr) {
48
+ return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
49
+ }
50
+
51
+ function _arrayWithoutHoles(arr) {
52
+ if (Array.isArray(arr)) {
53
+ for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
54
+
55
+ return arr2;
56
+ }
57
+ }
58
+
59
+ function _iterableToArray(iter) {
60
+ if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
61
+ }
62
+
63
+ function _nonIterableSpread() {
64
+ throw new TypeError("Invalid attempt to spread non-iterable instance");
65
+ }
66
+
67
+ var IS_BROWSER = typeof window !== 'undefined';
68
+ var WINDOW = IS_BROWSER ? window : {};
69
+ var IS_TOUCH_DEVICE = IS_BROWSER ? 'ontouchstart' in WINDOW.document.documentElement : false;
70
+ var HAS_POINTER_EVENT = IS_BROWSER ? 'PointerEvent' in WINDOW : false;
71
+ var NAMESPACE = 'cropper'; // Actions
72
+
73
+ var ACTION_ALL = 'all';
74
+ var ACTION_CROP = 'crop';
75
+ var ACTION_MOVE = 'move';
76
+ var ACTION_ZOOM = 'zoom';
77
+ var ACTION_EAST = 'e';
78
+ var ACTION_WEST = 'w';
79
+ var ACTION_SOUTH = 's';
80
+ var ACTION_NORTH = 'n';
81
+ var ACTION_NORTH_EAST = 'ne';
82
+ var ACTION_NORTH_WEST = 'nw';
83
+ var ACTION_SOUTH_EAST = 'se';
84
+ var ACTION_SOUTH_WEST = 'sw'; // Classes
85
+
86
+ var CLASS_CROP = "".concat(NAMESPACE, "-crop");
87
+ var CLASS_DISABLED = "".concat(NAMESPACE, "-disabled");
88
+ var CLASS_HIDDEN = "".concat(NAMESPACE, "-hidden");
89
+ var CLASS_HIDE = "".concat(NAMESPACE, "-hide");
90
+ var CLASS_INVISIBLE = "".concat(NAMESPACE, "-invisible");
91
+ var CLASS_MODAL = "".concat(NAMESPACE, "-modal");
92
+ var CLASS_MOVE = "".concat(NAMESPACE, "-move"); // Data keys
93
+
94
+ var DATA_ACTION = "".concat(NAMESPACE, "Action");
95
+ var DATA_PREVIEW = "".concat(NAMESPACE, "Preview"); // Drag modes
96
+
97
+ var DRAG_MODE_CROP = 'crop';
98
+ var DRAG_MODE_MOVE = 'move';
99
+ var DRAG_MODE_NONE = 'none'; // Events
100
+
101
+ var EVENT_CROP = 'crop';
102
+ var EVENT_CROP_END = 'cropend';
103
+ var EVENT_CROP_MOVE = 'cropmove';
104
+ var EVENT_CROP_START = 'cropstart';
105
+ var EVENT_DBLCLICK = 'dblclick';
106
+ var EVENT_TOUCH_START = IS_TOUCH_DEVICE ? 'touchstart' : 'mousedown';
107
+ var EVENT_TOUCH_MOVE = IS_TOUCH_DEVICE ? 'touchmove' : 'mousemove';
108
+ var EVENT_TOUCH_END = IS_TOUCH_DEVICE ? 'touchend touchcancel' : 'mouseup';
109
+ var EVENT_POINTER_DOWN = HAS_POINTER_EVENT ? 'pointerdown' : EVENT_TOUCH_START;
110
+ var EVENT_POINTER_MOVE = HAS_POINTER_EVENT ? 'pointermove' : EVENT_TOUCH_MOVE;
111
+ var EVENT_POINTER_UP = HAS_POINTER_EVENT ? 'pointerup pointercancel' : EVENT_TOUCH_END;
112
+ var EVENT_READY = 'ready';
113
+ var EVENT_RESIZE = 'resize';
114
+ var EVENT_WHEEL = 'wheel';
115
+ var EVENT_ZOOM = 'zoom'; // Mime types
116
+
117
+ var MIME_TYPE_JPEG = 'image/jpeg'; // RegExps
118
+
119
+ var REGEXP_ACTIONS = /^e|w|s|n|se|sw|ne|nw|all|crop|move|zoom$/;
120
+ var REGEXP_DATA_URL_JPEG = /^data:image\/jpeg;base64,/;
121
+ var REGEXP_TAG_NAME = /^img|canvas$/i; // Misc
122
+ // Inspired by the default width and height of a canvas element.
123
+
124
+ var MIN_CONTAINER_WIDTH = 200;
125
+ var MIN_CONTAINER_HEIGHT = 100;
126
+
127
+ var DEFAULTS = {
128
+ // Define the view mode of the cropper
129
+ viewMode: 0,
130
+ // 0, 1, 2, 3
131
+ // Define the dragging mode of the cropper
132
+ dragMode: DRAG_MODE_CROP,
133
+ // 'crop', 'move' or 'none'
134
+ // Define the initial aspect ratio of the crop box
135
+ initialAspectRatio: NaN,
136
+ // Define the aspect ratio of the crop box
137
+ aspectRatio: NaN,
138
+ // An object with the previous cropping result data
139
+ data: null,
140
+ // A selector for adding extra containers to preview
141
+ preview: '',
142
+ // Re-render the cropper when resize the window
143
+ responsive: true,
144
+ // Restore the cropped area after resize the window
145
+ restore: true,
146
+ // Check if the current image is a cross-origin image
147
+ checkCrossOrigin: true,
148
+ // Check the current image's Exif Orientation information
149
+ checkOrientation: true,
150
+ // Show the black modal
151
+ modal: true,
152
+ // Show the dashed lines for guiding
153
+ guides: true,
154
+ // Show the center indicator for guiding
155
+ center: true,
156
+ // Show the white modal to highlight the crop box
157
+ highlight: true,
158
+ // Show the grid background
159
+ background: true,
160
+ // Enable to crop the image automatically when initialize
161
+ autoCrop: true,
162
+ // Define the percentage of automatic cropping area when initializes
163
+ autoCropArea: 0.8,
164
+ // Enable to move the image
165
+ movable: true,
166
+ // Enable to rotate the image
167
+ rotatable: true,
168
+ // Enable to scale the image
169
+ scalable: true,
170
+ // Enable to zoom the image
171
+ zoomable: true,
172
+ // Enable to zoom the image by dragging touch
173
+ zoomOnTouch: true,
174
+ // Enable to zoom the image by wheeling mouse
175
+ zoomOnWheel: true,
176
+ // Define zoom ratio when zoom the image by wheeling mouse
177
+ wheelZoomRatio: 0.1,
178
+ // Enable to move the crop box
179
+ cropBoxMovable: true,
180
+ // Enable to resize the crop box
181
+ cropBoxResizable: true,
182
+ // Toggle drag mode between "crop" and "move" when click twice on the cropper
183
+ toggleDragModeOnDblclick: true,
184
+ // Size limitation
185
+ minCanvasWidth: 0,
186
+ minCanvasHeight: 0,
187
+ minCropBoxWidth: 0,
188
+ minCropBoxHeight: 0,
189
+ minContainerWidth: 200,
190
+ minContainerHeight: 100,
191
+ // Shortcuts of events
192
+ ready: null,
193
+ cropstart: null,
194
+ cropmove: null,
195
+ cropend: null,
196
+ crop: null,
197
+ zoom: null
198
+ };
199
+
200
+ var TEMPLATE = '<div class="cropper-container" touch-action="none">' + '<div class="cropper-wrap-box">' + '<div class="cropper-canvas"></div>' + '</div>' + '<div class="cropper-drag-box"></div>' + '<div class="cropper-crop-box">' + '<span class="cropper-view-box"></span>' + '<span class="cropper-dashed dashed-h"></span>' + '<span class="cropper-dashed dashed-v"></span>' + '<span class="cropper-center"></span>' + '<span class="cropper-face"></span>' + '<span class="cropper-line line-e" data-cropper-action="e"></span>' + '<span class="cropper-line line-n" data-cropper-action="n"></span>' + '<span class="cropper-line line-w" data-cropper-action="w"></span>' + '<span class="cropper-line line-s" data-cropper-action="s"></span>' + '<span class="cropper-point point-e" data-cropper-action="e"></span>' + '<span class="cropper-point point-n" data-cropper-action="n"></span>' + '<span class="cropper-point point-w" data-cropper-action="w"></span>' + '<span class="cropper-point point-s" data-cropper-action="s"></span>' + '<span class="cropper-point point-ne" data-cropper-action="ne"></span>' + '<span class="cropper-point point-nw" data-cropper-action="nw"></span>' + '<span class="cropper-point point-sw" data-cropper-action="sw"></span>' + '<span class="cropper-point point-se" data-cropper-action="se"></span>' + '</div>' + '</div>';
201
+
202
+ /**
203
+ * Check if the given value is not a number.
204
+ */
205
+
206
+ var isNaN = Number.isNaN || WINDOW.isNaN;
207
+ /**
208
+ * Check if the given value is a number.
209
+ * @param {*} value - The value to check.
210
+ * @returns {boolean} Returns `true` if the given value is a number, else `false`.
211
+ */
212
+
213
+ function isNumber(value) {
214
+ return typeof value === 'number' && !isNaN(value);
215
+ }
216
+ /**
217
+ * Check if the given value is a positive number.
218
+ * @param {*} value - The value to check.
219
+ * @returns {boolean} Returns `true` if the given value is a positive number, else `false`.
220
+ */
221
+
222
+ var isPositiveNumber = function isPositiveNumber(value) {
223
+ return value > 0 && value < Infinity;
224
+ };
225
+ /**
226
+ * Check if the given value is undefined.
227
+ * @param {*} value - The value to check.
228
+ * @returns {boolean} Returns `true` if the given value is undefined, else `false`.
229
+ */
230
+
231
+ function isUndefined(value) {
232
+ return typeof value === 'undefined';
233
+ }
234
+ /**
235
+ * Check if the given value is an object.
236
+ * @param {*} value - The value to check.
237
+ * @returns {boolean} Returns `true` if the given value is an object, else `false`.
238
+ */
239
+
240
+ function isObject(value) {
241
+ return _typeof(value) === 'object' && value !== null;
242
+ }
243
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
244
+ /**
245
+ * Check if the given value is a plain object.
246
+ * @param {*} value - The value to check.
247
+ * @returns {boolean} Returns `true` if the given value is a plain object, else `false`.
248
+ */
249
+
250
+ function isPlainObject(value) {
251
+ if (!isObject(value)) {
252
+ return false;
253
+ }
254
+
255
+ try {
256
+ var _constructor = value.constructor;
257
+ var prototype = _constructor.prototype;
258
+ return _constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf');
259
+ } catch (error) {
260
+ return false;
261
+ }
262
+ }
263
+ /**
264
+ * Check if the given value is a function.
265
+ * @param {*} value - The value to check.
266
+ * @returns {boolean} Returns `true` if the given value is a function, else `false`.
267
+ */
268
+
269
+ function isFunction(value) {
270
+ return typeof value === 'function';
271
+ }
272
+ var slice = Array.prototype.slice;
273
+ /**
274
+ * Convert array-like or iterable object to an array.
275
+ * @param {*} value - The value to convert.
276
+ * @returns {Array} Returns a new array.
277
+ */
278
+
279
+ function toArray(value) {
280
+ return Array.from ? Array.from(value) : slice.call(value);
281
+ }
282
+ /**
283
+ * Iterate the given data.
284
+ * @param {*} data - The data to iterate.
285
+ * @param {Function} callback - The process function for each element.
286
+ * @returns {*} The original data.
287
+ */
288
+
289
+ function forEach(data, callback) {
290
+ if (data && isFunction(callback)) {
291
+ if (Array.isArray(data) || isNumber(data.length)
292
+ /* array-like */
293
+ ) {
294
+ toArray(data).forEach(function (value, key) {
295
+ callback.call(data, value, key, data);
296
+ });
297
+ } else if (isObject(data)) {
298
+ Object.keys(data).forEach(function (key) {
299
+ callback.call(data, data[key], key, data);
300
+ });
301
+ }
302
+ }
303
+
304
+ return data;
305
+ }
306
+ /**
307
+ * Extend the given object.
308
+ * @param {*} target - The target object to extend.
309
+ * @param {*} args - The rest objects for merging to the target object.
310
+ * @returns {Object} The extended object.
311
+ */
312
+
313
+ var assign = Object.assign || function assign(target) {
314
+ for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
315
+ args[_key - 1] = arguments[_key];
316
+ }
317
+
318
+ if (isObject(target) && args.length > 0) {
319
+ args.forEach(function (arg) {
320
+ if (isObject(arg)) {
321
+ Object.keys(arg).forEach(function (key) {
322
+ target[key] = arg[key];
323
+ });
324
+ }
325
+ });
326
+ }
327
+
328
+ return target;
329
+ };
330
+ var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/;
331
+ /**
332
+ * Normalize decimal number.
333
+ * Check out {@link http://0.30000000000000004.com/}
334
+ * @param {number} value - The value to normalize.
335
+ * @param {number} [times=100000000000] - The times for normalizing.
336
+ * @returns {number} Returns the normalized number.
337
+ */
338
+
339
+ function normalizeDecimalNumber(value) {
340
+ var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100000000000;
341
+ return REGEXP_DECIMALS.test(value) ? Math.round(value * times) / times : value;
342
+ }
343
+ var REGEXP_SUFFIX = /^width|height|left|top|marginLeft|marginTop$/;
344
+ /**
345
+ * Apply styles to the given element.
346
+ * @param {Element} element - The target element.
347
+ * @param {Object} styles - The styles for applying.
348
+ */
349
+
350
+ function setStyle(element, styles) {
351
+ var style = element.style;
352
+ forEach(styles, function (value, property) {
353
+ if (REGEXP_SUFFIX.test(property) && isNumber(value)) {
354
+ value = "".concat(value, "px");
355
+ }
356
+
357
+ style[property] = value;
358
+ });
359
+ }
360
+ /**
361
+ * Check if the given element has a special class.
362
+ * @param {Element} element - The element to check.
363
+ * @param {string} value - The class to search.
364
+ * @returns {boolean} Returns `true` if the special class was found.
365
+ */
366
+
367
+ function hasClass(element, value) {
368
+ return element.classList ? element.classList.contains(value) : element.className.indexOf(value) > -1;
369
+ }
370
+ /**
371
+ * Add classes to the given element.
372
+ * @param {Element} element - The target element.
373
+ * @param {string} value - The classes to be added.
374
+ */
375
+
376
+ function addClass(element, value) {
377
+ if (!value) {
378
+ return;
379
+ }
380
+
381
+ if (isNumber(element.length)) {
382
+ forEach(element, function (elem) {
383
+ addClass(elem, value);
384
+ });
385
+ return;
386
+ }
387
+
388
+ if (element.classList) {
389
+ element.classList.add(value);
390
+ return;
391
+ }
392
+
393
+ var className = element.className.trim();
394
+
395
+ if (!className) {
396
+ element.className = value;
397
+ } else if (className.indexOf(value) < 0) {
398
+ element.className = "".concat(className, " ").concat(value);
399
+ }
400
+ }
401
+ /**
402
+ * Remove classes from the given element.
403
+ * @param {Element} element - The target element.
404
+ * @param {string} value - The classes to be removed.
405
+ */
406
+
407
+ function removeClass(element, value) {
408
+ if (!value) {
409
+ return;
410
+ }
411
+
412
+ if (isNumber(element.length)) {
413
+ forEach(element, function (elem) {
414
+ removeClass(elem, value);
415
+ });
416
+ return;
417
+ }
418
+
419
+ if (element.classList) {
420
+ element.classList.remove(value);
421
+ return;
422
+ }
423
+
424
+ if (element.className.indexOf(value) >= 0) {
425
+ element.className = element.className.replace(value, '');
426
+ }
427
+ }
428
+ /**
429
+ * Add or remove classes from the given element.
430
+ * @param {Element} element - The target element.
431
+ * @param {string} value - The classes to be toggled.
432
+ * @param {boolean} added - Add only.
433
+ */
434
+
435
+ function toggleClass(element, value, added) {
436
+ if (!value) {
437
+ return;
438
+ }
439
+
440
+ if (isNumber(element.length)) {
441
+ forEach(element, function (elem) {
442
+ toggleClass(elem, value, added);
443
+ });
444
+ return;
445
+ } // IE10-11 doesn't support the second parameter of `classList.toggle`
446
+
447
+
448
+ if (added) {
449
+ addClass(element, value);
450
+ } else {
451
+ removeClass(element, value);
452
+ }
453
+ }
454
+ var REGEXP_CAMEL_CASE = /([a-z\d])([A-Z])/g;
455
+ /**
456
+ * Transform the given string from camelCase to kebab-case
457
+ * @param {string} value - The value to transform.
458
+ * @returns {string} The transformed value.
459
+ */
460
+
461
+ function toParamCase(value) {
462
+ return value.replace(REGEXP_CAMEL_CASE, '$1-$2').toLowerCase();
463
+ }
464
+ /**
465
+ * Get data from the given element.
466
+ * @param {Element} element - The target element.
467
+ * @param {string} name - The data key to get.
468
+ * @returns {string} The data value.
469
+ */
470
+
471
+ function getData(element, name) {
472
+ if (isObject(element[name])) {
473
+ return element[name];
474
+ }
475
+
476
+ if (element.dataset) {
477
+ return element.dataset[name];
478
+ }
479
+
480
+ return element.getAttribute("data-".concat(toParamCase(name)));
481
+ }
482
+ /**
483
+ * Set data to the given element.
484
+ * @param {Element} element - The target element.
485
+ * @param {string} name - The data key to set.
486
+ * @param {string} data - The data value.
487
+ */
488
+
489
+ function setData(element, name, data) {
490
+ if (isObject(data)) {
491
+ element[name] = data;
492
+ } else if (element.dataset) {
493
+ element.dataset[name] = data;
494
+ } else {
495
+ element.setAttribute("data-".concat(toParamCase(name)), data);
496
+ }
497
+ }
498
+ /**
499
+ * Remove data from the given element.
500
+ * @param {Element} element - The target element.
501
+ * @param {string} name - The data key to remove.
502
+ */
503
+
504
+ function removeData(element, name) {
505
+ if (isObject(element[name])) {
506
+ try {
507
+ delete element[name];
508
+ } catch (error) {
509
+ element[name] = undefined;
510
+ }
511
+ } else if (element.dataset) {
512
+ // #128 Safari not allows to delete dataset property
513
+ try {
514
+ delete element.dataset[name];
515
+ } catch (error) {
516
+ element.dataset[name] = undefined;
517
+ }
518
+ } else {
519
+ element.removeAttribute("data-".concat(toParamCase(name)));
520
+ }
521
+ }
522
+ var REGEXP_SPACES = /\s\s*/;
523
+
524
+ var onceSupported = function () {
525
+ var supported = false;
526
+
527
+ if (IS_BROWSER) {
528
+ var once = false;
529
+
530
+ var listener = function listener() {};
531
+
532
+ var options = Object.defineProperty({}, 'once', {
533
+ get: function get() {
534
+ supported = true;
535
+ return once;
536
+ },
537
+
538
+ /**
539
+ * This setter can fix a `TypeError` in strict mode
540
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only}
541
+ * @param {boolean} value - The value to set
542
+ */
543
+ set: function set(value) {
544
+ once = value;
545
+ }
546
+ });
547
+ WINDOW.addEventListener('test', listener, options);
548
+ WINDOW.removeEventListener('test', listener, options);
549
+ }
550
+
551
+ return supported;
552
+ }();
553
+ /**
554
+ * Remove event listener from the target element.
555
+ * @param {Element} element - The event target.
556
+ * @param {string} type - The event type(s).
557
+ * @param {Function} listener - The event listener.
558
+ * @param {Object} options - The event options.
559
+ */
560
+
561
+
562
+ function removeListener(element, type, listener) {
563
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
564
+ var handler = listener;
565
+ type.trim().split(REGEXP_SPACES).forEach(function (event) {
566
+ if (!onceSupported) {
567
+ var listeners = element.listeners;
568
+
569
+ if (listeners && listeners[event] && listeners[event][listener]) {
570
+ handler = listeners[event][listener];
571
+ delete listeners[event][listener];
572
+
573
+ if (Object.keys(listeners[event]).length === 0) {
574
+ delete listeners[event];
575
+ }
576
+
577
+ if (Object.keys(listeners).length === 0) {
578
+ delete element.listeners;
579
+ }
580
+ }
581
+ }
582
+
583
+ element.removeEventListener(event, handler, options);
584
+ });
585
+ }
586
+ /**
587
+ * Add event listener to the target element.
588
+ * @param {Element} element - The event target.
589
+ * @param {string} type - The event type(s).
590
+ * @param {Function} listener - The event listener.
591
+ * @param {Object} options - The event options.
592
+ */
593
+
594
+ function addListener(element, type, listener) {
595
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
596
+ var _handler = listener;
597
+ type.trim().split(REGEXP_SPACES).forEach(function (event) {
598
+ if (options.once && !onceSupported) {
599
+ var _element$listeners = element.listeners,
600
+ listeners = _element$listeners === void 0 ? {} : _element$listeners;
601
+
602
+ _handler = function handler() {
603
+ delete listeners[event][listener];
604
+ element.removeEventListener(event, _handler, options);
605
+
606
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
607
+ args[_key2] = arguments[_key2];
608
+ }
609
+
610
+ listener.apply(element, args);
611
+ };
612
+
613
+ if (!listeners[event]) {
614
+ listeners[event] = {};
615
+ }
616
+
617
+ if (listeners[event][listener]) {
618
+ element.removeEventListener(event, listeners[event][listener], options);
619
+ }
620
+
621
+ listeners[event][listener] = _handler;
622
+ element.listeners = listeners;
623
+ }
624
+
625
+ element.addEventListener(event, _handler, options);
626
+ });
627
+ }
628
+ /**
629
+ * Dispatch event on the target element.
630
+ * @param {Element} element - The event target.
631
+ * @param {string} type - The event type(s).
632
+ * @param {Object} data - The additional event data.
633
+ * @returns {boolean} Indicate if the event is default prevented or not.
634
+ */
635
+
636
+ function dispatchEvent(element, type, data) {
637
+ var event; // Event and CustomEvent on IE9-11 are global objects, not constructors
638
+
639
+ if (isFunction(Event) && isFunction(CustomEvent)) {
640
+ event = new CustomEvent(type, {
641
+ detail: data,
642
+ bubbles: true,
643
+ cancelable: true
644
+ });
645
+ } else {
646
+ event = document.createEvent('CustomEvent');
647
+ event.initCustomEvent(type, true, true, data);
648
+ }
649
+
650
+ return element.dispatchEvent(event);
651
+ }
652
+ /**
653
+ * Get the offset base on the document.
654
+ * @param {Element} element - The target element.
655
+ * @returns {Object} The offset data.
656
+ */
657
+
658
+ function getOffset(element) {
659
+ var box = element.getBoundingClientRect();
660
+ return {
661
+ left: box.left + (window.pageXOffset - document.documentElement.clientLeft),
662
+ top: box.top + (window.pageYOffset - document.documentElement.clientTop)
663
+ };
664
+ }
665
+ var location = WINDOW.location;
666
+ var REGEXP_ORIGINS = /^(\w+:)\/\/([^:/?#]*):?(\d*)/i;
667
+ /**
668
+ * Check if the given URL is a cross origin URL.
669
+ * @param {string} url - The target URL.
670
+ * @returns {boolean} Returns `true` if the given URL is a cross origin URL, else `false`.
671
+ */
672
+
673
+ function isCrossOriginURL(url) {
674
+ var parts = url.match(REGEXP_ORIGINS);
675
+ return parts !== null && (parts[1] !== location.protocol || parts[2] !== location.hostname || parts[3] !== location.port);
676
+ }
677
+ /**
678
+ * Add timestamp to the given URL.
679
+ * @param {string} url - The target URL.
680
+ * @returns {string} The result URL.
681
+ */
682
+
683
+ function addTimestamp(url) {
684
+ var timestamp = "timestamp=".concat(new Date().getTime());
685
+ return url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp;
686
+ }
687
+ /**
688
+ * Get transforms base on the given object.
689
+ * @param {Object} obj - The target object.
690
+ * @returns {string} A string contains transform values.
691
+ */
692
+
693
+ function getTransforms(_ref) {
694
+ var rotate = _ref.rotate,
695
+ scaleX = _ref.scaleX,
696
+ scaleY = _ref.scaleY,
697
+ translateX = _ref.translateX,
698
+ translateY = _ref.translateY;
699
+ var values = [];
700
+
701
+ if (isNumber(translateX) && translateX !== 0) {
702
+ values.push("translateX(".concat(translateX, "px)"));
703
+ }
704
+
705
+ if (isNumber(translateY) && translateY !== 0) {
706
+ values.push("translateY(".concat(translateY, "px)"));
707
+ } // Rotate should come first before scale to match orientation transform
708
+
709
+
710
+ if (isNumber(rotate) && rotate !== 0) {
711
+ values.push("rotate(".concat(rotate, "deg)"));
712
+ }
713
+
714
+ if (isNumber(scaleX) && scaleX !== 1) {
715
+ values.push("scaleX(".concat(scaleX, ")"));
716
+ }
717
+
718
+ if (isNumber(scaleY) && scaleY !== 1) {
719
+ values.push("scaleY(".concat(scaleY, ")"));
720
+ }
721
+
722
+ var transform = values.length ? values.join(' ') : 'none';
723
+ return {
724
+ WebkitTransform: transform,
725
+ msTransform: transform,
726
+ transform: transform
727
+ };
728
+ }
729
+ /**
730
+ * Get the max ratio of a group of pointers.
731
+ * @param {string} pointers - The target pointers.
732
+ * @returns {number} The result ratio.
733
+ */
734
+
735
+ function getMaxZoomRatio(pointers) {
736
+ var pointers2 = assign({}, pointers);
737
+ var ratios = [];
738
+ forEach(pointers, function (pointer, pointerId) {
739
+ delete pointers2[pointerId];
740
+ forEach(pointers2, function (pointer2) {
741
+ var x1 = Math.abs(pointer.startX - pointer2.startX);
742
+ var y1 = Math.abs(pointer.startY - pointer2.startY);
743
+ var x2 = Math.abs(pointer.endX - pointer2.endX);
744
+ var y2 = Math.abs(pointer.endY - pointer2.endY);
745
+ var z1 = Math.sqrt(x1 * x1 + y1 * y1);
746
+ var z2 = Math.sqrt(x2 * x2 + y2 * y2);
747
+ var ratio = (z2 - z1) / z1;
748
+ ratios.push(ratio);
749
+ });
750
+ });
751
+ ratios.sort(function (a, b) {
752
+ return Math.abs(a) < Math.abs(b);
753
+ });
754
+ return ratios[0];
755
+ }
756
+ /**
757
+ * Get a pointer from an event object.
758
+ * @param {Object} event - The target event object.
759
+ * @param {boolean} endOnly - Indicates if only returns the end point coordinate or not.
760
+ * @returns {Object} The result pointer contains start and/or end point coordinates.
761
+ */
762
+
763
+ function getPointer(_ref2, endOnly) {
764
+ var pageX = _ref2.pageX,
765
+ pageY = _ref2.pageY;
766
+ var end = {
767
+ endX: pageX,
768
+ endY: pageY
769
+ };
770
+ return endOnly ? end : assign({
771
+ startX: pageX,
772
+ startY: pageY
773
+ }, end);
774
+ }
775
+ /**
776
+ * Get the center point coordinate of a group of pointers.
777
+ * @param {Object} pointers - The target pointers.
778
+ * @returns {Object} The center point coordinate.
779
+ */
780
+
781
+ function getPointersCenter(pointers) {
782
+ var pageX = 0;
783
+ var pageY = 0;
784
+ var count = 0;
785
+ forEach(pointers, function (_ref3) {
786
+ var startX = _ref3.startX,
787
+ startY = _ref3.startY;
788
+ pageX += startX;
789
+ pageY += startY;
790
+ count += 1;
791
+ });
792
+ pageX /= count;
793
+ pageY /= count;
794
+ return {
795
+ pageX: pageX,
796
+ pageY: pageY
797
+ };
798
+ }
799
+ /**
800
+ * Get the max sizes in a rectangle under the given aspect ratio.
801
+ * @param {Object} data - The original sizes.
802
+ * @param {string} [type='contain'] - The adjust type.
803
+ * @returns {Object} The result sizes.
804
+ */
805
+
806
+ function getAdjustedSizes(_ref4) // or 'cover'
807
+ {
808
+ var aspectRatio = _ref4.aspectRatio,
809
+ height = _ref4.height,
810
+ width = _ref4.width;
811
+ var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'contain';
812
+ var isValidWidth = isPositiveNumber(width);
813
+ var isValidHeight = isPositiveNumber(height);
814
+
815
+ if (isValidWidth && isValidHeight) {
816
+ var adjustedWidth = height * aspectRatio;
817
+
818
+ if (type === 'contain' && adjustedWidth > width || type === 'cover' && adjustedWidth < width) {
819
+ height = width / aspectRatio;
820
+ } else {
821
+ width = height * aspectRatio;
822
+ }
823
+ } else if (isValidWidth) {
824
+ height = width / aspectRatio;
825
+ } else if (isValidHeight) {
826
+ width = height * aspectRatio;
827
+ }
828
+
829
+ return {
830
+ width: width,
831
+ height: height
832
+ };
833
+ }
834
+ /**
835
+ * Get the new sizes of a rectangle after rotated.
836
+ * @param {Object} data - The original sizes.
837
+ * @returns {Object} The result sizes.
838
+ */
839
+
840
+ function getRotatedSizes(_ref5) {
841
+ var width = _ref5.width,
842
+ height = _ref5.height,
843
+ degree = _ref5.degree;
844
+ degree = Math.abs(degree) % 180;
845
+
846
+ if (degree === 90) {
847
+ return {
848
+ width: height,
849
+ height: width
850
+ };
851
+ }
852
+
853
+ var arc = degree % 90 * Math.PI / 180;
854
+ var sinArc = Math.sin(arc);
855
+ var cosArc = Math.cos(arc);
856
+ var newWidth = width * cosArc + height * sinArc;
857
+ var newHeight = width * sinArc + height * cosArc;
858
+ return degree > 90 ? {
859
+ width: newHeight,
860
+ height: newWidth
861
+ } : {
862
+ width: newWidth,
863
+ height: newHeight
864
+ };
865
+ }
866
+ /**
867
+ * Get a canvas which drew the given image.
868
+ * @param {HTMLImageElement} image - The image for drawing.
869
+ * @param {Object} imageData - The image data.
870
+ * @param {Object} canvasData - The canvas data.
871
+ * @param {Object} options - The options.
872
+ * @returns {HTMLCanvasElement} The result canvas.
873
+ */
874
+
875
+ function getSourceCanvas(image, _ref6, _ref7, _ref8) {
876
+ var imageAspectRatio = _ref6.aspectRatio,
877
+ imageNaturalWidth = _ref6.naturalWidth,
878
+ imageNaturalHeight = _ref6.naturalHeight,
879
+ _ref6$rotate = _ref6.rotate,
880
+ rotate = _ref6$rotate === void 0 ? 0 : _ref6$rotate,
881
+ _ref6$scaleX = _ref6.scaleX,
882
+ scaleX = _ref6$scaleX === void 0 ? 1 : _ref6$scaleX,
883
+ _ref6$scaleY = _ref6.scaleY,
884
+ scaleY = _ref6$scaleY === void 0 ? 1 : _ref6$scaleY;
885
+ var aspectRatio = _ref7.aspectRatio,
886
+ naturalWidth = _ref7.naturalWidth,
887
+ naturalHeight = _ref7.naturalHeight;
888
+ var _ref8$fillColor = _ref8.fillColor,
889
+ fillColor = _ref8$fillColor === void 0 ? 'transparent' : _ref8$fillColor,
890
+ _ref8$imageSmoothingE = _ref8.imageSmoothingEnabled,
891
+ imageSmoothingEnabled = _ref8$imageSmoothingE === void 0 ? true : _ref8$imageSmoothingE,
892
+ _ref8$imageSmoothingQ = _ref8.imageSmoothingQuality,
893
+ imageSmoothingQuality = _ref8$imageSmoothingQ === void 0 ? 'low' : _ref8$imageSmoothingQ,
894
+ _ref8$maxWidth = _ref8.maxWidth,
895
+ maxWidth = _ref8$maxWidth === void 0 ? Infinity : _ref8$maxWidth,
896
+ _ref8$maxHeight = _ref8.maxHeight,
897
+ maxHeight = _ref8$maxHeight === void 0 ? Infinity : _ref8$maxHeight,
898
+ _ref8$minWidth = _ref8.minWidth,
899
+ minWidth = _ref8$minWidth === void 0 ? 0 : _ref8$minWidth,
900
+ _ref8$minHeight = _ref8.minHeight,
901
+ minHeight = _ref8$minHeight === void 0 ? 0 : _ref8$minHeight;
902
+ var canvas = document.createElement('canvas');
903
+ var context = canvas.getContext('2d');
904
+ var maxSizes = getAdjustedSizes({
905
+ aspectRatio: aspectRatio,
906
+ width: maxWidth,
907
+ height: maxHeight
908
+ });
909
+ var minSizes = getAdjustedSizes({
910
+ aspectRatio: aspectRatio,
911
+ width: minWidth,
912
+ height: minHeight
913
+ }, 'cover');
914
+ var width = Math.min(maxSizes.width, Math.max(minSizes.width, naturalWidth));
915
+ var height = Math.min(maxSizes.height, Math.max(minSizes.height, naturalHeight)); // Note: should always use image's natural sizes for drawing as
916
+ // imageData.naturalWidth === canvasData.naturalHeight when rotate % 180 === 90
917
+
918
+ var destMaxSizes = getAdjustedSizes({
919
+ aspectRatio: imageAspectRatio,
920
+ width: maxWidth,
921
+ height: maxHeight
922
+ });
923
+ var destMinSizes = getAdjustedSizes({
924
+ aspectRatio: imageAspectRatio,
925
+ width: minWidth,
926
+ height: minHeight
927
+ }, 'cover');
928
+ var destWidth = Math.min(destMaxSizes.width, Math.max(destMinSizes.width, imageNaturalWidth));
929
+ var destHeight = Math.min(destMaxSizes.height, Math.max(destMinSizes.height, imageNaturalHeight));
930
+ var params = [-destWidth / 2, -destHeight / 2, destWidth, destHeight];
931
+ canvas.width = normalizeDecimalNumber(width);
932
+ canvas.height = normalizeDecimalNumber(height);
933
+ context.fillStyle = fillColor;
934
+ context.fillRect(0, 0, width, height);
935
+ context.save();
936
+ context.translate(width / 2, height / 2);
937
+ context.rotate(rotate * Math.PI / 180);
938
+ context.scale(scaleX, scaleY);
939
+ context.imageSmoothingEnabled = imageSmoothingEnabled;
940
+ context.imageSmoothingQuality = imageSmoothingQuality;
941
+ context.drawImage.apply(context, [image].concat(_toConsumableArray(params.map(function (param) {
942
+ return Math.floor(normalizeDecimalNumber(param));
943
+ }))));
944
+ context.restore();
945
+ return canvas;
946
+ }
947
+ var fromCharCode = String.fromCharCode;
948
+ /**
949
+ * Get string from char code in data view.
950
+ * @param {DataView} dataView - The data view for read.
951
+ * @param {number} start - The start index.
952
+ * @param {number} length - The read length.
953
+ * @returns {string} The read result.
954
+ */
955
+
956
+ function getStringFromCharCode(dataView, start, length) {
957
+ var str = '';
958
+ length += start;
959
+
960
+ for (var i = start; i < length; i += 1) {
961
+ str += fromCharCode(dataView.getUint8(i));
962
+ }
963
+
964
+ return str;
965
+ }
966
+ var REGEXP_DATA_URL_HEAD = /^data:.*,/;
967
+ /**
968
+ * Transform Data URL to array buffer.
969
+ * @param {string} dataURL - The Data URL to transform.
970
+ * @returns {ArrayBuffer} The result array buffer.
971
+ */
972
+
973
+ function dataURLToArrayBuffer(dataURL) {
974
+ var base64 = dataURL.replace(REGEXP_DATA_URL_HEAD, '');
975
+ var binary = atob(base64);
976
+ var arrayBuffer = new ArrayBuffer(binary.length);
977
+ var uint8 = new Uint8Array(arrayBuffer);
978
+ forEach(uint8, function (value, i) {
979
+ uint8[i] = binary.charCodeAt(i);
980
+ });
981
+ return arrayBuffer;
982
+ }
983
+ /**
984
+ * Transform array buffer to Data URL.
985
+ * @param {ArrayBuffer} arrayBuffer - The array buffer to transform.
986
+ * @param {string} mimeType - The mime type of the Data URL.
987
+ * @returns {string} The result Data URL.
988
+ */
989
+
990
+ function arrayBufferToDataURL(arrayBuffer, mimeType) {
991
+ var chunks = []; // Chunk Typed Array for better performance (#435)
992
+
993
+ var chunkSize = 8192;
994
+ var uint8 = new Uint8Array(arrayBuffer);
995
+
996
+ while (uint8.length > 0) {
997
+ // XXX: Babel's `toConsumableArray` helper will throw error in IE or Safari 9
998
+ // eslint-disable-next-line prefer-spread
999
+ chunks.push(fromCharCode.apply(null, toArray(uint8.subarray(0, chunkSize))));
1000
+ uint8 = uint8.subarray(chunkSize);
1001
+ }
1002
+
1003
+ return "data:".concat(mimeType, ";base64,").concat(btoa(chunks.join('')));
1004
+ }
1005
+ /**
1006
+ * Get orientation value from given array buffer.
1007
+ * @param {ArrayBuffer} arrayBuffer - The array buffer to read.
1008
+ * @returns {number} The read orientation value.
1009
+ */
1010
+
1011
+ function resetAndGetOrientation(arrayBuffer) {
1012
+ var dataView = new DataView(arrayBuffer);
1013
+ var orientation; // Ignores range error when the image does not have correct Exif information
1014
+
1015
+ try {
1016
+ var littleEndian;
1017
+ var app1Start;
1018
+ var ifdStart; // Only handle JPEG image (start by 0xFFD8)
1019
+
1020
+ if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) {
1021
+ var length = dataView.byteLength;
1022
+ var offset = 2;
1023
+
1024
+ while (offset + 1 < length) {
1025
+ if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) {
1026
+ app1Start = offset;
1027
+ break;
1028
+ }
1029
+
1030
+ offset += 1;
1031
+ }
1032
+ }
1033
+
1034
+ if (app1Start) {
1035
+ var exifIDCode = app1Start + 4;
1036
+ var tiffOffset = app1Start + 10;
1037
+
1038
+ if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') {
1039
+ var endianness = dataView.getUint16(tiffOffset);
1040
+ littleEndian = endianness === 0x4949;
1041
+
1042
+ if (littleEndian || endianness === 0x4D4D
1043
+ /* bigEndian */
1044
+ ) {
1045
+ if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {
1046
+ var firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
1047
+
1048
+ if (firstIFDOffset >= 0x00000008) {
1049
+ ifdStart = tiffOffset + firstIFDOffset;
1050
+ }
1051
+ }
1052
+ }
1053
+ }
1054
+ }
1055
+
1056
+ if (ifdStart) {
1057
+ var _length = dataView.getUint16(ifdStart, littleEndian);
1058
+
1059
+ var _offset;
1060
+
1061
+ var i;
1062
+
1063
+ for (i = 0; i < _length; i += 1) {
1064
+ _offset = ifdStart + i * 12 + 2;
1065
+
1066
+ if (dataView.getUint16(_offset, littleEndian) === 0x0112
1067
+ /* Orientation */
1068
+ ) {
1069
+ // 8 is the offset of the current tag's value
1070
+ _offset += 8; // Get the original orientation value
1071
+
1072
+ orientation = dataView.getUint16(_offset, littleEndian); // Override the orientation with its default value
1073
+
1074
+ dataView.setUint16(_offset, 1, littleEndian);
1075
+ break;
1076
+ }
1077
+ }
1078
+ }
1079
+ } catch (error) {
1080
+ orientation = 1;
1081
+ }
1082
+
1083
+ return orientation;
1084
+ }
1085
+ /**
1086
+ * Parse Exif Orientation value.
1087
+ * @param {number} orientation - The orientation to parse.
1088
+ * @returns {Object} The parsed result.
1089
+ */
1090
+
1091
+ function parseOrientation(orientation) {
1092
+ var rotate = 0;
1093
+ var scaleX = 1;
1094
+ var scaleY = 1;
1095
+
1096
+ switch (orientation) {
1097
+ // Flip horizontal
1098
+ case 2:
1099
+ scaleX = -1;
1100
+ break;
1101
+ // Rotate left 180°
1102
+
1103
+ case 3:
1104
+ rotate = -180;
1105
+ break;
1106
+ // Flip vertical
1107
+
1108
+ case 4:
1109
+ scaleY = -1;
1110
+ break;
1111
+ // Flip vertical and rotate right 90°
1112
+
1113
+ case 5:
1114
+ rotate = 90;
1115
+ scaleY = -1;
1116
+ break;
1117
+ // Rotate right 90°
1118
+
1119
+ case 6:
1120
+ rotate = 90;
1121
+ break;
1122
+ // Flip horizontal and rotate right 90°
1123
+
1124
+ case 7:
1125
+ rotate = 90;
1126
+ scaleX = -1;
1127
+ break;
1128
+ // Rotate left 90°
1129
+
1130
+ case 8:
1131
+ rotate = -90;
1132
+ break;
1133
+
1134
+ default:
1135
+ }
1136
+
1137
+ return {
1138
+ rotate: rotate,
1139
+ scaleX: scaleX,
1140
+ scaleY: scaleY
1141
+ };
1142
+ }
1143
+
1144
+ var render = {
1145
+ render: function render() {
1146
+ this.initContainer();
1147
+ this.initCanvas();
1148
+ this.initCropBox();
1149
+ this.renderCanvas();
1150
+
1151
+ if (this.cropped) {
1152
+ this.renderCropBox();
1153
+ }
1154
+ },
1155
+ initContainer: function initContainer() {
1156
+ var element = this.element,
1157
+ options = this.options,
1158
+ container = this.container,
1159
+ cropper = this.cropper;
1160
+ addClass(cropper, CLASS_HIDDEN);
1161
+ removeClass(element, CLASS_HIDDEN);
1162
+ var containerData = {
1163
+ width: Math.max(container.offsetWidth, Number(options.minContainerWidth) || 200),
1164
+ height: Math.max(container.offsetHeight, Number(options.minContainerHeight) || 100)
1165
+ };
1166
+ this.containerData = containerData;
1167
+ setStyle(cropper, {
1168
+ width: containerData.width,
1169
+ height: containerData.height
1170
+ });
1171
+ addClass(element, CLASS_HIDDEN);
1172
+ removeClass(cropper, CLASS_HIDDEN);
1173
+ },
1174
+ // Canvas (image wrapper)
1175
+ initCanvas: function initCanvas() {
1176
+ var containerData = this.containerData,
1177
+ imageData = this.imageData;
1178
+ var viewMode = this.options.viewMode;
1179
+ var rotated = Math.abs(imageData.rotate) % 180 === 90;
1180
+ var naturalWidth = rotated ? imageData.naturalHeight : imageData.naturalWidth;
1181
+ var naturalHeight = rotated ? imageData.naturalWidth : imageData.naturalHeight;
1182
+ var aspectRatio = naturalWidth / naturalHeight;
1183
+ var canvasWidth = containerData.width;
1184
+ var canvasHeight = containerData.height;
1185
+
1186
+ if (containerData.height * aspectRatio > containerData.width) {
1187
+ if (viewMode === 3) {
1188
+ canvasWidth = containerData.height * aspectRatio;
1189
+ } else {
1190
+ canvasHeight = containerData.width / aspectRatio;
1191
+ }
1192
+ } else if (viewMode === 3) {
1193
+ canvasHeight = containerData.width / aspectRatio;
1194
+ } else {
1195
+ canvasWidth = containerData.height * aspectRatio;
1196
+ }
1197
+
1198
+ var canvasData = {
1199
+ aspectRatio: aspectRatio,
1200
+ naturalWidth: naturalWidth,
1201
+ naturalHeight: naturalHeight,
1202
+ width: canvasWidth,
1203
+ height: canvasHeight
1204
+ };
1205
+ canvasData.left = (containerData.width - canvasWidth) / 2;
1206
+ canvasData.top = (containerData.height - canvasHeight) / 2;
1207
+ canvasData.oldLeft = canvasData.left;
1208
+ canvasData.oldTop = canvasData.top;
1209
+ this.canvasData = canvasData;
1210
+ this.limited = viewMode === 1 || viewMode === 2;
1211
+ this.limitCanvas(true, true);
1212
+ this.initialImageData = assign({}, imageData);
1213
+ this.initialCanvasData = assign({}, canvasData);
1214
+ },
1215
+ limitCanvas: function limitCanvas(sizeLimited, positionLimited) {
1216
+ var options = this.options,
1217
+ containerData = this.containerData,
1218
+ canvasData = this.canvasData,
1219
+ cropBoxData = this.cropBoxData;
1220
+ var viewMode = options.viewMode;
1221
+ var aspectRatio = canvasData.aspectRatio;
1222
+ var cropped = this.cropped && cropBoxData;
1223
+
1224
+ if (sizeLimited) {
1225
+ var minCanvasWidth = Number(options.minCanvasWidth) || 0;
1226
+ var minCanvasHeight = Number(options.minCanvasHeight) || 0;
1227
+
1228
+ if (viewMode > 1) {
1229
+ minCanvasWidth = Math.max(minCanvasWidth, containerData.width);
1230
+ minCanvasHeight = Math.max(minCanvasHeight, containerData.height);
1231
+
1232
+ if (viewMode === 3) {
1233
+ if (minCanvasHeight * aspectRatio > minCanvasWidth) {
1234
+ minCanvasWidth = minCanvasHeight * aspectRatio;
1235
+ } else {
1236
+ minCanvasHeight = minCanvasWidth / aspectRatio;
1237
+ }
1238
+ }
1239
+ } else if (viewMode > 0) {
1240
+ if (minCanvasWidth) {
1241
+ minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBoxData.width : 0);
1242
+ } else if (minCanvasHeight) {
1243
+ minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBoxData.height : 0);
1244
+ } else if (cropped) {
1245
+ minCanvasWidth = cropBoxData.width;
1246
+ minCanvasHeight = cropBoxData.height;
1247
+
1248
+ if (minCanvasHeight * aspectRatio > minCanvasWidth) {
1249
+ minCanvasWidth = minCanvasHeight * aspectRatio;
1250
+ } else {
1251
+ minCanvasHeight = minCanvasWidth / aspectRatio;
1252
+ }
1253
+ }
1254
+ }
1255
+
1256
+ var _getAdjustedSizes = getAdjustedSizes({
1257
+ aspectRatio: aspectRatio,
1258
+ width: minCanvasWidth,
1259
+ height: minCanvasHeight
1260
+ });
1261
+
1262
+ minCanvasWidth = _getAdjustedSizes.width;
1263
+ minCanvasHeight = _getAdjustedSizes.height;
1264
+ canvasData.minWidth = minCanvasWidth;
1265
+ canvasData.minHeight = minCanvasHeight;
1266
+ canvasData.maxWidth = Infinity;
1267
+ canvasData.maxHeight = Infinity;
1268
+ }
1269
+
1270
+ if (positionLimited) {
1271
+ if (viewMode > (cropped ? 0 : 1)) {
1272
+ var newCanvasLeft = containerData.width - canvasData.width;
1273
+ var newCanvasTop = containerData.height - canvasData.height;
1274
+ canvasData.minLeft = Math.min(0, newCanvasLeft);
1275
+ canvasData.minTop = Math.min(0, newCanvasTop);
1276
+ canvasData.maxLeft = Math.max(0, newCanvasLeft);
1277
+ canvasData.maxTop = Math.max(0, newCanvasTop);
1278
+
1279
+ if (cropped && this.limited) {
1280
+ canvasData.minLeft = Math.min(cropBoxData.left, cropBoxData.left + (cropBoxData.width - canvasData.width));
1281
+ canvasData.minTop = Math.min(cropBoxData.top, cropBoxData.top + (cropBoxData.height - canvasData.height));
1282
+ canvasData.maxLeft = cropBoxData.left;
1283
+ canvasData.maxTop = cropBoxData.top;
1284
+
1285
+ if (viewMode === 2) {
1286
+ if (canvasData.width >= containerData.width) {
1287
+ canvasData.minLeft = Math.min(0, newCanvasLeft);
1288
+ canvasData.maxLeft = Math.max(0, newCanvasLeft);
1289
+ }
1290
+
1291
+ if (canvasData.height >= containerData.height) {
1292
+ canvasData.minTop = Math.min(0, newCanvasTop);
1293
+ canvasData.maxTop = Math.max(0, newCanvasTop);
1294
+ }
1295
+ }
1296
+ }
1297
+ } else {
1298
+ canvasData.minLeft = -canvasData.width;
1299
+ canvasData.minTop = -canvasData.height;
1300
+ canvasData.maxLeft = containerData.width;
1301
+ canvasData.maxTop = containerData.height;
1302
+ }
1303
+ }
1304
+ },
1305
+ renderCanvas: function renderCanvas(changed, transformed) {
1306
+ var canvasData = this.canvasData,
1307
+ imageData = this.imageData;
1308
+
1309
+ if (transformed) {
1310
+ var _getRotatedSizes = getRotatedSizes({
1311
+ width: imageData.naturalWidth * Math.abs(imageData.scaleX || 1),
1312
+ height: imageData.naturalHeight * Math.abs(imageData.scaleY || 1),
1313
+ degree: imageData.rotate || 0
1314
+ }),
1315
+ naturalWidth = _getRotatedSizes.width,
1316
+ naturalHeight = _getRotatedSizes.height;
1317
+
1318
+ var width = canvasData.width * (naturalWidth / canvasData.naturalWidth);
1319
+ var height = canvasData.height * (naturalHeight / canvasData.naturalHeight);
1320
+ canvasData.left -= (width - canvasData.width) / 2;
1321
+ canvasData.top -= (height - canvasData.height) / 2;
1322
+ canvasData.width = width;
1323
+ canvasData.height = height;
1324
+ canvasData.aspectRatio = naturalWidth / naturalHeight;
1325
+ canvasData.naturalWidth = naturalWidth;
1326
+ canvasData.naturalHeight = naturalHeight;
1327
+ this.limitCanvas(true, false);
1328
+ }
1329
+
1330
+ if (canvasData.width > canvasData.maxWidth || canvasData.width < canvasData.minWidth) {
1331
+ canvasData.left = canvasData.oldLeft;
1332
+ }
1333
+
1334
+ if (canvasData.height > canvasData.maxHeight || canvasData.height < canvasData.minHeight) {
1335
+ canvasData.top = canvasData.oldTop;
1336
+ }
1337
+
1338
+ canvasData.width = Math.min(Math.max(canvasData.width, canvasData.minWidth), canvasData.maxWidth);
1339
+ canvasData.height = Math.min(Math.max(canvasData.height, canvasData.minHeight), canvasData.maxHeight);
1340
+ this.limitCanvas(false, true);
1341
+ canvasData.left = Math.min(Math.max(canvasData.left, canvasData.minLeft), canvasData.maxLeft);
1342
+ canvasData.top = Math.min(Math.max(canvasData.top, canvasData.minTop), canvasData.maxTop);
1343
+ canvasData.oldLeft = canvasData.left;
1344
+ canvasData.oldTop = canvasData.top;
1345
+ setStyle(this.canvas, assign({
1346
+ width: canvasData.width,
1347
+ height: canvasData.height
1348
+ }, getTransforms({
1349
+ translateX: canvasData.left,
1350
+ translateY: canvasData.top
1351
+ })));
1352
+ this.renderImage(changed);
1353
+
1354
+ if (this.cropped && this.limited) {
1355
+ this.limitCropBox(true, true);
1356
+ }
1357
+ },
1358
+ renderImage: function renderImage(changed) {
1359
+ var canvasData = this.canvasData,
1360
+ imageData = this.imageData;
1361
+ var width = imageData.naturalWidth * (canvasData.width / canvasData.naturalWidth);
1362
+ var height = imageData.naturalHeight * (canvasData.height / canvasData.naturalHeight);
1363
+ assign(imageData, {
1364
+ width: width,
1365
+ height: height,
1366
+ left: (canvasData.width - width) / 2,
1367
+ top: (canvasData.height - height) / 2
1368
+ });
1369
+ setStyle(this.image, assign({
1370
+ width: imageData.width,
1371
+ height: imageData.height
1372
+ }, getTransforms(assign({
1373
+ translateX: imageData.left,
1374
+ translateY: imageData.top
1375
+ }, imageData))));
1376
+
1377
+ if (changed) {
1378
+ this.output();
1379
+ }
1380
+ },
1381
+ initCropBox: function initCropBox() {
1382
+ var options = this.options,
1383
+ canvasData = this.canvasData;
1384
+ var aspectRatio = options.aspectRatio || options.initialAspectRatio;
1385
+ var autoCropArea = Number(options.autoCropArea) || 0.8;
1386
+ var cropBoxData = {
1387
+ width: canvasData.width,
1388
+ height: canvasData.height
1389
+ };
1390
+
1391
+ if (aspectRatio) {
1392
+ if (canvasData.height * aspectRatio > canvasData.width) {
1393
+ cropBoxData.height = cropBoxData.width / aspectRatio;
1394
+ } else {
1395
+ cropBoxData.width = cropBoxData.height * aspectRatio;
1396
+ }
1397
+ }
1398
+
1399
+ this.cropBoxData = cropBoxData;
1400
+ this.limitCropBox(true, true); // Initialize auto crop area
1401
+
1402
+ cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth);
1403
+ cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight); // The width/height of auto crop area must large than "minWidth/Height"
1404
+
1405
+ cropBoxData.width = Math.max(cropBoxData.minWidth, cropBoxData.width * autoCropArea);
1406
+ cropBoxData.height = Math.max(cropBoxData.minHeight, cropBoxData.height * autoCropArea);
1407
+ cropBoxData.left = canvasData.left + (canvasData.width - cropBoxData.width) / 2;
1408
+ cropBoxData.top = canvasData.top + (canvasData.height - cropBoxData.height) / 2;
1409
+ cropBoxData.oldLeft = cropBoxData.left;
1410
+ cropBoxData.oldTop = cropBoxData.top;
1411
+ this.initialCropBoxData = assign({}, cropBoxData);
1412
+ },
1413
+ limitCropBox: function limitCropBox(sizeLimited, positionLimited) {
1414
+ var options = this.options,
1415
+ containerData = this.containerData,
1416
+ canvasData = this.canvasData,
1417
+ cropBoxData = this.cropBoxData,
1418
+ limited = this.limited;
1419
+ var aspectRatio = options.aspectRatio;
1420
+
1421
+ if (sizeLimited) {
1422
+ var minCropBoxWidth = Number(options.minCropBoxWidth) || 0;
1423
+ var minCropBoxHeight = Number(options.minCropBoxHeight) || 0;
1424
+ var maxCropBoxWidth = limited ? Math.min(containerData.width, canvasData.width, canvasData.width + canvasData.left, containerData.width - canvasData.left) : containerData.width;
1425
+ var maxCropBoxHeight = limited ? Math.min(containerData.height, canvasData.height, canvasData.height + canvasData.top, containerData.height - canvasData.top) : containerData.height; // The min/maxCropBoxWidth/Height must be less than container's width/height
1426
+
1427
+ minCropBoxWidth = Math.min(minCropBoxWidth, containerData.width);
1428
+ minCropBoxHeight = Math.min(minCropBoxHeight, containerData.height);
1429
+
1430
+ if (aspectRatio) {
1431
+ if (minCropBoxWidth && minCropBoxHeight) {
1432
+ if (minCropBoxHeight * aspectRatio > minCropBoxWidth) {
1433
+ minCropBoxHeight = minCropBoxWidth / aspectRatio;
1434
+ } else {
1435
+ minCropBoxWidth = minCropBoxHeight * aspectRatio;
1436
+ }
1437
+ } else if (minCropBoxWidth) {
1438
+ minCropBoxHeight = minCropBoxWidth / aspectRatio;
1439
+ } else if (minCropBoxHeight) {
1440
+ minCropBoxWidth = minCropBoxHeight * aspectRatio;
1441
+ }
1442
+
1443
+ if (maxCropBoxHeight * aspectRatio > maxCropBoxWidth) {
1444
+ maxCropBoxHeight = maxCropBoxWidth / aspectRatio;
1445
+ } else {
1446
+ maxCropBoxWidth = maxCropBoxHeight * aspectRatio;
1447
+ }
1448
+ } // The minWidth/Height must be less than maxWidth/Height
1449
+
1450
+
1451
+ cropBoxData.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth);
1452
+ cropBoxData.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight);
1453
+ cropBoxData.maxWidth = maxCropBoxWidth;
1454
+ cropBoxData.maxHeight = maxCropBoxHeight;
1455
+ }
1456
+
1457
+ if (positionLimited) {
1458
+ if (limited) {
1459
+ cropBoxData.minLeft = Math.max(0, canvasData.left);
1460
+ cropBoxData.minTop = Math.max(0, canvasData.top);
1461
+ cropBoxData.maxLeft = Math.min(containerData.width, canvasData.left + canvasData.width) - cropBoxData.width;
1462
+ cropBoxData.maxTop = Math.min(containerData.height, canvasData.top + canvasData.height) - cropBoxData.height;
1463
+ } else {
1464
+ cropBoxData.minLeft = 0;
1465
+ cropBoxData.minTop = 0;
1466
+ cropBoxData.maxLeft = containerData.width - cropBoxData.width;
1467
+ cropBoxData.maxTop = containerData.height - cropBoxData.height;
1468
+ }
1469
+ }
1470
+ },
1471
+ renderCropBox: function renderCropBox() {
1472
+ var options = this.options,
1473
+ containerData = this.containerData,
1474
+ cropBoxData = this.cropBoxData;
1475
+
1476
+ if (cropBoxData.width > cropBoxData.maxWidth || cropBoxData.width < cropBoxData.minWidth) {
1477
+ cropBoxData.left = cropBoxData.oldLeft;
1478
+ }
1479
+
1480
+ if (cropBoxData.height > cropBoxData.maxHeight || cropBoxData.height < cropBoxData.minHeight) {
1481
+ cropBoxData.top = cropBoxData.oldTop;
1482
+ }
1483
+
1484
+ cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth);
1485
+ cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight);
1486
+ this.limitCropBox(false, true);
1487
+ cropBoxData.left = Math.min(Math.max(cropBoxData.left, cropBoxData.minLeft), cropBoxData.maxLeft);
1488
+ cropBoxData.top = Math.min(Math.max(cropBoxData.top, cropBoxData.minTop), cropBoxData.maxTop);
1489
+ cropBoxData.oldLeft = cropBoxData.left;
1490
+ cropBoxData.oldTop = cropBoxData.top;
1491
+
1492
+ if (options.movable && options.cropBoxMovable) {
1493
+ // Turn to move the canvas when the crop box is equal to the container
1494
+ setData(this.face, DATA_ACTION, cropBoxData.width >= containerData.width && cropBoxData.height >= containerData.height ? ACTION_MOVE : ACTION_ALL);
1495
+ }
1496
+
1497
+ setStyle(this.cropBox, assign({
1498
+ width: cropBoxData.width,
1499
+ height: cropBoxData.height
1500
+ }, getTransforms({
1501
+ translateX: cropBoxData.left,
1502
+ translateY: cropBoxData.top
1503
+ })));
1504
+
1505
+ if (this.cropped && this.limited) {
1506
+ this.limitCanvas(true, true);
1507
+ }
1508
+
1509
+ if (!this.disabled) {
1510
+ this.output();
1511
+ }
1512
+ },
1513
+ output: function output() {
1514
+ this.preview();
1515
+ dispatchEvent(this.element, EVENT_CROP, this.getData());
1516
+ }
1517
+ };
1518
+
1519
+ var preview = {
1520
+ initPreview: function initPreview() {
1521
+ var crossOrigin = this.crossOrigin;
1522
+ var preview = this.options.preview;
1523
+ var url = crossOrigin ? this.crossOriginUrl : this.url;
1524
+ var image = document.createElement('img');
1525
+
1526
+ if (crossOrigin) {
1527
+ image.crossOrigin = crossOrigin;
1528
+ }
1529
+
1530
+ image.src = url;
1531
+ this.viewBox.appendChild(image);
1532
+ this.viewBoxImage = image;
1533
+
1534
+ if (!preview) {
1535
+ return;
1536
+ }
1537
+
1538
+ var previews = preview;
1539
+
1540
+ if (typeof preview === 'string') {
1541
+ previews = this.element.ownerDocument.querySelectorAll(preview);
1542
+ } else if (preview.querySelector) {
1543
+ previews = [preview];
1544
+ }
1545
+
1546
+ this.previews = previews;
1547
+ forEach(previews, function (el) {
1548
+ var img = document.createElement('img'); // Save the original size for recover
1549
+
1550
+ setData(el, DATA_PREVIEW, {
1551
+ width: el.offsetWidth,
1552
+ height: el.offsetHeight,
1553
+ html: el.innerHTML
1554
+ });
1555
+
1556
+ if (crossOrigin) {
1557
+ img.crossOrigin = crossOrigin;
1558
+ }
1559
+
1560
+ img.src = url;
1561
+ /**
1562
+ * Override img element styles
1563
+ * Add `display:block` to avoid margin top issue
1564
+ * Add `height:auto` to override `height` attribute on IE8
1565
+ * (Occur only when margin-top <= -height)
1566
+ */
1567
+
1568
+ img.style.cssText = 'display:block;' + 'width:100%;' + 'height:auto;' + 'min-width:0!important;' + 'min-height:0!important;' + 'max-width:none!important;' + 'max-height:none!important;' + 'image-orientation:0deg!important;"';
1569
+ el.innerHTML = '';
1570
+ el.appendChild(img);
1571
+ });
1572
+ },
1573
+ resetPreview: function resetPreview() {
1574
+ forEach(this.previews, function (element) {
1575
+ var data = getData(element, DATA_PREVIEW);
1576
+ setStyle(element, {
1577
+ width: data.width,
1578
+ height: data.height
1579
+ });
1580
+ element.innerHTML = data.html;
1581
+ removeData(element, DATA_PREVIEW);
1582
+ });
1583
+ },
1584
+ preview: function preview() {
1585
+ var imageData = this.imageData,
1586
+ canvasData = this.canvasData,
1587
+ cropBoxData = this.cropBoxData;
1588
+ var cropBoxWidth = cropBoxData.width,
1589
+ cropBoxHeight = cropBoxData.height;
1590
+ var width = imageData.width,
1591
+ height = imageData.height;
1592
+ var left = cropBoxData.left - canvasData.left - imageData.left;
1593
+ var top = cropBoxData.top - canvasData.top - imageData.top;
1594
+
1595
+ if (!this.cropped || this.disabled) {
1596
+ return;
1597
+ }
1598
+
1599
+ setStyle(this.viewBoxImage, assign({
1600
+ width: width,
1601
+ height: height
1602
+ }, getTransforms(assign({
1603
+ translateX: -left,
1604
+ translateY: -top
1605
+ }, imageData))));
1606
+ forEach(this.previews, function (element) {
1607
+ var data = getData(element, DATA_PREVIEW);
1608
+ var originalWidth = data.width;
1609
+ var originalHeight = data.height;
1610
+ var newWidth = originalWidth;
1611
+ var newHeight = originalHeight;
1612
+ var ratio = 1;
1613
+
1614
+ if (cropBoxWidth) {
1615
+ ratio = originalWidth / cropBoxWidth;
1616
+ newHeight = cropBoxHeight * ratio;
1617
+ }
1618
+
1619
+ if (cropBoxHeight && newHeight > originalHeight) {
1620
+ ratio = originalHeight / cropBoxHeight;
1621
+ newWidth = cropBoxWidth * ratio;
1622
+ newHeight = originalHeight;
1623
+ }
1624
+
1625
+ setStyle(element, {
1626
+ width: newWidth,
1627
+ height: newHeight
1628
+ });
1629
+ setStyle(element.getElementsByTagName('img')[0], assign({
1630
+ width: width * ratio,
1631
+ height: height * ratio
1632
+ }, getTransforms(assign({
1633
+ translateX: -left * ratio,
1634
+ translateY: -top * ratio
1635
+ }, imageData))));
1636
+ });
1637
+ }
1638
+ };
1639
+
1640
+ var events = {
1641
+ bind: function bind() {
1642
+ var element = this.element,
1643
+ options = this.options,
1644
+ cropper = this.cropper;
1645
+
1646
+ if (isFunction(options.cropstart)) {
1647
+ addListener(element, EVENT_CROP_START, options.cropstart);
1648
+ }
1649
+
1650
+ if (isFunction(options.cropmove)) {
1651
+ addListener(element, EVENT_CROP_MOVE, options.cropmove);
1652
+ }
1653
+
1654
+ if (isFunction(options.cropend)) {
1655
+ addListener(element, EVENT_CROP_END, options.cropend);
1656
+ }
1657
+
1658
+ if (isFunction(options.crop)) {
1659
+ addListener(element, EVENT_CROP, options.crop);
1660
+ }
1661
+
1662
+ if (isFunction(options.zoom)) {
1663
+ addListener(element, EVENT_ZOOM, options.zoom);
1664
+ }
1665
+
1666
+ addListener(cropper, EVENT_POINTER_DOWN, this.onCropStart = this.cropStart.bind(this));
1667
+
1668
+ if (options.zoomable && options.zoomOnWheel) {
1669
+ addListener(cropper, EVENT_WHEEL, this.onWheel = this.wheel.bind(this), {
1670
+ passive: false,
1671
+ capture: true
1672
+ });
1673
+ }
1674
+
1675
+ if (options.toggleDragModeOnDblclick) {
1676
+ addListener(cropper, EVENT_DBLCLICK, this.onDblclick = this.dblclick.bind(this));
1677
+ }
1678
+
1679
+ addListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove = this.cropMove.bind(this));
1680
+ addListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd = this.cropEnd.bind(this));
1681
+
1682
+ if (options.responsive) {
1683
+ addListener(window, EVENT_RESIZE, this.onResize = this.resize.bind(this));
1684
+ }
1685
+ },
1686
+ unbind: function unbind() {
1687
+ var element = this.element,
1688
+ options = this.options,
1689
+ cropper = this.cropper;
1690
+
1691
+ if (isFunction(options.cropstart)) {
1692
+ removeListener(element, EVENT_CROP_START, options.cropstart);
1693
+ }
1694
+
1695
+ if (isFunction(options.cropmove)) {
1696
+ removeListener(element, EVENT_CROP_MOVE, options.cropmove);
1697
+ }
1698
+
1699
+ if (isFunction(options.cropend)) {
1700
+ removeListener(element, EVENT_CROP_END, options.cropend);
1701
+ }
1702
+
1703
+ if (isFunction(options.crop)) {
1704
+ removeListener(element, EVENT_CROP, options.crop);
1705
+ }
1706
+
1707
+ if (isFunction(options.zoom)) {
1708
+ removeListener(element, EVENT_ZOOM, options.zoom);
1709
+ }
1710
+
1711
+ removeListener(cropper, EVENT_POINTER_DOWN, this.onCropStart);
1712
+
1713
+ if (options.zoomable && options.zoomOnWheel) {
1714
+ removeListener(cropper, EVENT_WHEEL, this.onWheel, {
1715
+ passive: false,
1716
+ capture: true
1717
+ });
1718
+ }
1719
+
1720
+ if (options.toggleDragModeOnDblclick) {
1721
+ removeListener(cropper, EVENT_DBLCLICK, this.onDblclick);
1722
+ }
1723
+
1724
+ removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove);
1725
+ removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd);
1726
+
1727
+ if (options.responsive) {
1728
+ removeListener(window, EVENT_RESIZE, this.onResize);
1729
+ }
1730
+ }
1731
+ };
1732
+
1733
+ var handlers = {
1734
+ resize: function resize() {
1735
+ var options = this.options,
1736
+ container = this.container,
1737
+ containerData = this.containerData;
1738
+ var minContainerWidth = Number(options.minContainerWidth) || MIN_CONTAINER_WIDTH;
1739
+ var minContainerHeight = Number(options.minContainerHeight) || MIN_CONTAINER_HEIGHT;
1740
+
1741
+ if (this.disabled || containerData.width <= minContainerWidth || containerData.height <= minContainerHeight) {
1742
+ return;
1743
+ }
1744
+
1745
+ var ratio = container.offsetWidth / containerData.width; // Resize when width changed or height changed
1746
+
1747
+ if (ratio !== 1 || container.offsetHeight !== containerData.height) {
1748
+ var canvasData;
1749
+ var cropBoxData;
1750
+
1751
+ if (options.restore) {
1752
+ canvasData = this.getCanvasData();
1753
+ cropBoxData = this.getCropBoxData();
1754
+ }
1755
+
1756
+ this.render();
1757
+
1758
+ if (options.restore) {
1759
+ this.setCanvasData(forEach(canvasData, function (n, i) {
1760
+ canvasData[i] = n * ratio;
1761
+ }));
1762
+ this.setCropBoxData(forEach(cropBoxData, function (n, i) {
1763
+ cropBoxData[i] = n * ratio;
1764
+ }));
1765
+ }
1766
+ }
1767
+ },
1768
+ dblclick: function dblclick() {
1769
+ if (this.disabled || this.options.dragMode === DRAG_MODE_NONE) {
1770
+ return;
1771
+ }
1772
+
1773
+ this.setDragMode(hasClass(this.dragBox, CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP);
1774
+ },
1775
+ wheel: function wheel(event) {
1776
+ var _this = this;
1777
+
1778
+ var ratio = Number(this.options.wheelZoomRatio) || 0.1;
1779
+ var delta = 1;
1780
+
1781
+ if (this.disabled) {
1782
+ return;
1783
+ }
1784
+
1785
+ event.preventDefault(); // Limit wheel speed to prevent zoom too fast (#21)
1786
+
1787
+ if (this.wheeling) {
1788
+ return;
1789
+ }
1790
+
1791
+ this.wheeling = true;
1792
+ setTimeout(function () {
1793
+ _this.wheeling = false;
1794
+ }, 50);
1795
+
1796
+ if (event.deltaY) {
1797
+ delta = event.deltaY > 0 ? 1 : -1;
1798
+ } else if (event.wheelDelta) {
1799
+ delta = -event.wheelDelta / 120;
1800
+ } else if (event.detail) {
1801
+ delta = event.detail > 0 ? 1 : -1;
1802
+ }
1803
+
1804
+ this.zoom(-delta * ratio, event);
1805
+ },
1806
+ cropStart: function cropStart(event) {
1807
+ var buttons = event.buttons,
1808
+ button = event.button;
1809
+
1810
+ if (this.disabled // No primary button (Usually the left button)
1811
+ // Note that touch events have no `buttons` or `button` property
1812
+ || isNumber(buttons) && buttons !== 1 || isNumber(button) && button !== 0 // Open context menu
1813
+ || event.ctrlKey) {
1814
+ return;
1815
+ }
1816
+
1817
+ var options = this.options,
1818
+ pointers = this.pointers;
1819
+ var action;
1820
+
1821
+ if (event.changedTouches) {
1822
+ // Handle touch event
1823
+ forEach(event.changedTouches, function (touch) {
1824
+ pointers[touch.identifier] = getPointer(touch);
1825
+ });
1826
+ } else {
1827
+ // Handle mouse event and pointer event
1828
+ pointers[event.pointerId || 0] = getPointer(event);
1829
+ }
1830
+
1831
+ if (Object.keys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) {
1832
+ action = ACTION_ZOOM;
1833
+ } else {
1834
+ action = getData(event.target, DATA_ACTION);
1835
+ }
1836
+
1837
+ if (!REGEXP_ACTIONS.test(action)) {
1838
+ return;
1839
+ }
1840
+
1841
+ if (dispatchEvent(this.element, EVENT_CROP_START, {
1842
+ originalEvent: event,
1843
+ action: action
1844
+ }) === false) {
1845
+ return;
1846
+ } // This line is required for preventing page zooming in iOS browsers
1847
+
1848
+
1849
+ event.preventDefault();
1850
+ this.action = action;
1851
+ this.cropping = false;
1852
+
1853
+ if (action === ACTION_CROP) {
1854
+ this.cropping = true;
1855
+ addClass(this.dragBox, CLASS_MODAL);
1856
+ }
1857
+ },
1858
+ cropMove: function cropMove(event) {
1859
+ var action = this.action;
1860
+
1861
+ if (this.disabled || !action) {
1862
+ return;
1863
+ }
1864
+
1865
+ var pointers = this.pointers;
1866
+ event.preventDefault();
1867
+
1868
+ if (dispatchEvent(this.element, EVENT_CROP_MOVE, {
1869
+ originalEvent: event,
1870
+ action: action
1871
+ }) === false) {
1872
+ return;
1873
+ }
1874
+
1875
+ if (event.changedTouches) {
1876
+ forEach(event.changedTouches, function (touch) {
1877
+ // The first parameter should not be undefined (#432)
1878
+ assign(pointers[touch.identifier] || {}, getPointer(touch, true));
1879
+ });
1880
+ } else {
1881
+ assign(pointers[event.pointerId || 0] || {}, getPointer(event, true));
1882
+ }
1883
+
1884
+ this.change(event);
1885
+ },
1886
+ cropEnd: function cropEnd(event) {
1887
+ if (this.disabled) {
1888
+ return;
1889
+ }
1890
+
1891
+ var action = this.action,
1892
+ pointers = this.pointers;
1893
+
1894
+ if (event.changedTouches) {
1895
+ forEach(event.changedTouches, function (touch) {
1896
+ delete pointers[touch.identifier];
1897
+ });
1898
+ } else {
1899
+ delete pointers[event.pointerId || 0];
1900
+ }
1901
+
1902
+ if (!action) {
1903
+ return;
1904
+ }
1905
+
1906
+ event.preventDefault();
1907
+
1908
+ if (!Object.keys(pointers).length) {
1909
+ this.action = '';
1910
+ }
1911
+
1912
+ if (this.cropping) {
1913
+ this.cropping = false;
1914
+ toggleClass(this.dragBox, CLASS_MODAL, this.cropped && this.options.modal);
1915
+ }
1916
+
1917
+ dispatchEvent(this.element, EVENT_CROP_END, {
1918
+ originalEvent: event,
1919
+ action: action
1920
+ });
1921
+ }
1922
+ };
1923
+
1924
+ var change = {
1925
+ change: function change(event) {
1926
+ var options = this.options,
1927
+ canvasData = this.canvasData,
1928
+ containerData = this.containerData,
1929
+ cropBoxData = this.cropBoxData,
1930
+ pointers = this.pointers;
1931
+ var action = this.action;
1932
+ var aspectRatio = options.aspectRatio;
1933
+ var left = cropBoxData.left,
1934
+ top = cropBoxData.top,
1935
+ width = cropBoxData.width,
1936
+ height = cropBoxData.height;
1937
+ var right = left + width;
1938
+ var bottom = top + height;
1939
+ var minLeft = 0;
1940
+ var minTop = 0;
1941
+ var maxWidth = containerData.width;
1942
+ var maxHeight = containerData.height;
1943
+ var renderable = true;
1944
+ var offset; // Locking aspect ratio in "free mode" by holding shift key
1945
+
1946
+ if (!aspectRatio && event.shiftKey) {
1947
+ aspectRatio = width && height ? width / height : 1;
1948
+ }
1949
+
1950
+ if (this.limited) {
1951
+ minLeft = cropBoxData.minLeft;
1952
+ minTop = cropBoxData.minTop;
1953
+ maxWidth = minLeft + Math.min(containerData.width, canvasData.width, canvasData.left + canvasData.width);
1954
+ maxHeight = minTop + Math.min(containerData.height, canvasData.height, canvasData.top + canvasData.height);
1955
+ }
1956
+
1957
+ var pointer = pointers[Object.keys(pointers)[0]];
1958
+ var range = {
1959
+ x: pointer.endX - pointer.startX,
1960
+ y: pointer.endY - pointer.startY
1961
+ };
1962
+
1963
+ var check = function check(side) {
1964
+ switch (side) {
1965
+ case ACTION_EAST:
1966
+ if (right + range.x > maxWidth) {
1967
+ range.x = maxWidth - right;
1968
+ }
1969
+
1970
+ break;
1971
+
1972
+ case ACTION_WEST:
1973
+ if (left + range.x < minLeft) {
1974
+ range.x = minLeft - left;
1975
+ }
1976
+
1977
+ break;
1978
+
1979
+ case ACTION_NORTH:
1980
+ if (top + range.y < minTop) {
1981
+ range.y = minTop - top;
1982
+ }
1983
+
1984
+ break;
1985
+
1986
+ case ACTION_SOUTH:
1987
+ if (bottom + range.y > maxHeight) {
1988
+ range.y = maxHeight - bottom;
1989
+ }
1990
+
1991
+ break;
1992
+
1993
+ default:
1994
+ }
1995
+ };
1996
+
1997
+ switch (action) {
1998
+ // Move crop box
1999
+ case ACTION_ALL:
2000
+ left += range.x;
2001
+ top += range.y;
2002
+ break;
2003
+ // Resize crop box
2004
+
2005
+ case ACTION_EAST:
2006
+ if (range.x >= 0 && (right >= maxWidth || aspectRatio && (top <= minTop || bottom >= maxHeight))) {
2007
+ renderable = false;
2008
+ break;
2009
+ }
2010
+
2011
+ check(ACTION_EAST);
2012
+ width += range.x;
2013
+
2014
+ if (width < 0) {
2015
+ action = ACTION_WEST;
2016
+ width = -width;
2017
+ left -= width;
2018
+ }
2019
+
2020
+ if (aspectRatio) {
2021
+ height = width / aspectRatio;
2022
+ top += (cropBoxData.height - height) / 2;
2023
+ }
2024
+
2025
+ break;
2026
+
2027
+ case ACTION_NORTH:
2028
+ if (range.y <= 0 && (top <= minTop || aspectRatio && (left <= minLeft || right >= maxWidth))) {
2029
+ renderable = false;
2030
+ break;
2031
+ }
2032
+
2033
+ check(ACTION_NORTH);
2034
+ height -= range.y;
2035
+ top += range.y;
2036
+
2037
+ if (height < 0) {
2038
+ action = ACTION_SOUTH;
2039
+ height = -height;
2040
+ top -= height;
2041
+ }
2042
+
2043
+ if (aspectRatio) {
2044
+ width = height * aspectRatio;
2045
+ left += (cropBoxData.width - width) / 2;
2046
+ }
2047
+
2048
+ break;
2049
+
2050
+ case ACTION_WEST:
2051
+ if (range.x <= 0 && (left <= minLeft || aspectRatio && (top <= minTop || bottom >= maxHeight))) {
2052
+ renderable = false;
2053
+ break;
2054
+ }
2055
+
2056
+ check(ACTION_WEST);
2057
+ width -= range.x;
2058
+ left += range.x;
2059
+
2060
+ if (width < 0) {
2061
+ action = ACTION_EAST;
2062
+ width = -width;
2063
+ left -= width;
2064
+ }
2065
+
2066
+ if (aspectRatio) {
2067
+ height = width / aspectRatio;
2068
+ top += (cropBoxData.height - height) / 2;
2069
+ }
2070
+
2071
+ break;
2072
+
2073
+ case ACTION_SOUTH:
2074
+ if (range.y >= 0 && (bottom >= maxHeight || aspectRatio && (left <= minLeft || right >= maxWidth))) {
2075
+ renderable = false;
2076
+ break;
2077
+ }
2078
+
2079
+ check(ACTION_SOUTH);
2080
+ height += range.y;
2081
+
2082
+ if (height < 0) {
2083
+ action = ACTION_NORTH;
2084
+ height = -height;
2085
+ top -= height;
2086
+ }
2087
+
2088
+ if (aspectRatio) {
2089
+ width = height * aspectRatio;
2090
+ left += (cropBoxData.width - width) / 2;
2091
+ }
2092
+
2093
+ break;
2094
+
2095
+ case ACTION_NORTH_EAST:
2096
+ if (aspectRatio) {
2097
+ if (range.y <= 0 && (top <= minTop || right >= maxWidth)) {
2098
+ renderable = false;
2099
+ break;
2100
+ }
2101
+
2102
+ check(ACTION_NORTH);
2103
+ height -= range.y;
2104
+ top += range.y;
2105
+ width = height * aspectRatio;
2106
+ } else {
2107
+ check(ACTION_NORTH);
2108
+ check(ACTION_EAST);
2109
+
2110
+ if (range.x >= 0) {
2111
+ if (right < maxWidth) {
2112
+ width += range.x;
2113
+ } else if (range.y <= 0 && top <= minTop) {
2114
+ renderable = false;
2115
+ }
2116
+ } else {
2117
+ width += range.x;
2118
+ }
2119
+
2120
+ if (range.y <= 0) {
2121
+ if (top > minTop) {
2122
+ height -= range.y;
2123
+ top += range.y;
2124
+ }
2125
+ } else {
2126
+ height -= range.y;
2127
+ top += range.y;
2128
+ }
2129
+ }
2130
+
2131
+ if (width < 0 && height < 0) {
2132
+ action = ACTION_SOUTH_WEST;
2133
+ height = -height;
2134
+ width = -width;
2135
+ top -= height;
2136
+ left -= width;
2137
+ } else if (width < 0) {
2138
+ action = ACTION_NORTH_WEST;
2139
+ width = -width;
2140
+ left -= width;
2141
+ } else if (height < 0) {
2142
+ action = ACTION_SOUTH_EAST;
2143
+ height = -height;
2144
+ top -= height;
2145
+ }
2146
+
2147
+ break;
2148
+
2149
+ case ACTION_NORTH_WEST:
2150
+ if (aspectRatio) {
2151
+ if (range.y <= 0 && (top <= minTop || left <= minLeft)) {
2152
+ renderable = false;
2153
+ break;
2154
+ }
2155
+
2156
+ check(ACTION_NORTH);
2157
+ height -= range.y;
2158
+ top += range.y;
2159
+ width = height * aspectRatio;
2160
+ left += cropBoxData.width - width;
2161
+ } else {
2162
+ check(ACTION_NORTH);
2163
+ check(ACTION_WEST);
2164
+
2165
+ if (range.x <= 0) {
2166
+ if (left > minLeft) {
2167
+ width -= range.x;
2168
+ left += range.x;
2169
+ } else if (range.y <= 0 && top <= minTop) {
2170
+ renderable = false;
2171
+ }
2172
+ } else {
2173
+ width -= range.x;
2174
+ left += range.x;
2175
+ }
2176
+
2177
+ if (range.y <= 0) {
2178
+ if (top > minTop) {
2179
+ height -= range.y;
2180
+ top += range.y;
2181
+ }
2182
+ } else {
2183
+ height -= range.y;
2184
+ top += range.y;
2185
+ }
2186
+ }
2187
+
2188
+ if (width < 0 && height < 0) {
2189
+ action = ACTION_SOUTH_EAST;
2190
+ height = -height;
2191
+ width = -width;
2192
+ top -= height;
2193
+ left -= width;
2194
+ } else if (width < 0) {
2195
+ action = ACTION_NORTH_EAST;
2196
+ width = -width;
2197
+ left -= width;
2198
+ } else if (height < 0) {
2199
+ action = ACTION_SOUTH_WEST;
2200
+ height = -height;
2201
+ top -= height;
2202
+ }
2203
+
2204
+ break;
2205
+
2206
+ case ACTION_SOUTH_WEST:
2207
+ if (aspectRatio) {
2208
+ if (range.x <= 0 && (left <= minLeft || bottom >= maxHeight)) {
2209
+ renderable = false;
2210
+ break;
2211
+ }
2212
+
2213
+ check(ACTION_WEST);
2214
+ width -= range.x;
2215
+ left += range.x;
2216
+ height = width / aspectRatio;
2217
+ } else {
2218
+ check(ACTION_SOUTH);
2219
+ check(ACTION_WEST);
2220
+
2221
+ if (range.x <= 0) {
2222
+ if (left > minLeft) {
2223
+ width -= range.x;
2224
+ left += range.x;
2225
+ } else if (range.y >= 0 && bottom >= maxHeight) {
2226
+ renderable = false;
2227
+ }
2228
+ } else {
2229
+ width -= range.x;
2230
+ left += range.x;
2231
+ }
2232
+
2233
+ if (range.y >= 0) {
2234
+ if (bottom < maxHeight) {
2235
+ height += range.y;
2236
+ }
2237
+ } else {
2238
+ height += range.y;
2239
+ }
2240
+ }
2241
+
2242
+ if (width < 0 && height < 0) {
2243
+ action = ACTION_NORTH_EAST;
2244
+ height = -height;
2245
+ width = -width;
2246
+ top -= height;
2247
+ left -= width;
2248
+ } else if (width < 0) {
2249
+ action = ACTION_SOUTH_EAST;
2250
+ width = -width;
2251
+ left -= width;
2252
+ } else if (height < 0) {
2253
+ action = ACTION_NORTH_WEST;
2254
+ height = -height;
2255
+ top -= height;
2256
+ }
2257
+
2258
+ break;
2259
+
2260
+ case ACTION_SOUTH_EAST:
2261
+ if (aspectRatio) {
2262
+ if (range.x >= 0 && (right >= maxWidth || bottom >= maxHeight)) {
2263
+ renderable = false;
2264
+ break;
2265
+ }
2266
+
2267
+ check(ACTION_EAST);
2268
+ width += range.x;
2269
+ height = width / aspectRatio;
2270
+ } else {
2271
+ check(ACTION_SOUTH);
2272
+ check(ACTION_EAST);
2273
+
2274
+ if (range.x >= 0) {
2275
+ if (right < maxWidth) {
2276
+ width += range.x;
2277
+ } else if (range.y >= 0 && bottom >= maxHeight) {
2278
+ renderable = false;
2279
+ }
2280
+ } else {
2281
+ width += range.x;
2282
+ }
2283
+
2284
+ if (range.y >= 0) {
2285
+ if (bottom < maxHeight) {
2286
+ height += range.y;
2287
+ }
2288
+ } else {
2289
+ height += range.y;
2290
+ }
2291
+ }
2292
+
2293
+ if (width < 0 && height < 0) {
2294
+ action = ACTION_NORTH_WEST;
2295
+ height = -height;
2296
+ width = -width;
2297
+ top -= height;
2298
+ left -= width;
2299
+ } else if (width < 0) {
2300
+ action = ACTION_SOUTH_WEST;
2301
+ width = -width;
2302
+ left -= width;
2303
+ } else if (height < 0) {
2304
+ action = ACTION_NORTH_EAST;
2305
+ height = -height;
2306
+ top -= height;
2307
+ }
2308
+
2309
+ break;
2310
+ // Move canvas
2311
+
2312
+ case ACTION_MOVE:
2313
+ this.move(range.x, range.y);
2314
+ renderable = false;
2315
+ break;
2316
+ // Zoom canvas
2317
+
2318
+ case ACTION_ZOOM:
2319
+ this.zoom(getMaxZoomRatio(pointers), event);
2320
+ renderable = false;
2321
+ break;
2322
+ // Create crop box
2323
+
2324
+ case ACTION_CROP:
2325
+ if (!range.x || !range.y) {
2326
+ renderable = false;
2327
+ break;
2328
+ }
2329
+
2330
+ offset = getOffset(this.cropper);
2331
+ left = pointer.startX - offset.left;
2332
+ top = pointer.startY - offset.top;
2333
+ width = cropBoxData.minWidth;
2334
+ height = cropBoxData.minHeight;
2335
+
2336
+ if (range.x > 0) {
2337
+ action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST;
2338
+ } else if (range.x < 0) {
2339
+ left -= width;
2340
+ action = range.y > 0 ? ACTION_SOUTH_WEST : ACTION_NORTH_WEST;
2341
+ }
2342
+
2343
+ if (range.y < 0) {
2344
+ top -= height;
2345
+ } // Show the crop box if is hidden
2346
+
2347
+
2348
+ if (!this.cropped) {
2349
+ removeClass(this.cropBox, CLASS_HIDDEN);
2350
+ this.cropped = true;
2351
+
2352
+ if (this.limited) {
2353
+ this.limitCropBox(true, true);
2354
+ }
2355
+ }
2356
+
2357
+ break;
2358
+
2359
+ default:
2360
+ }
2361
+
2362
+ if (renderable) {
2363
+ cropBoxData.width = width;
2364
+ cropBoxData.height = height;
2365
+ cropBoxData.left = left;
2366
+ cropBoxData.top = top;
2367
+ this.action = action;
2368
+ this.renderCropBox();
2369
+ } // Override
2370
+
2371
+
2372
+ forEach(pointers, function (p) {
2373
+ p.startX = p.endX;
2374
+ p.startY = p.endY;
2375
+ });
2376
+ }
2377
+ };
2378
+
2379
+ var methods = {
2380
+ // Show the crop box manually
2381
+ crop: function crop() {
2382
+ if (this.ready && !this.cropped && !this.disabled) {
2383
+ this.cropped = true;
2384
+ this.limitCropBox(true, true);
2385
+
2386
+ if (this.options.modal) {
2387
+ addClass(this.dragBox, CLASS_MODAL);
2388
+ }
2389
+
2390
+ removeClass(this.cropBox, CLASS_HIDDEN);
2391
+ this.setCropBoxData(this.initialCropBoxData);
2392
+ }
2393
+
2394
+ return this;
2395
+ },
2396
+ // Reset the image and crop box to their initial states
2397
+ reset: function reset() {
2398
+ if (this.ready && !this.disabled) {
2399
+ this.imageData = assign({}, this.initialImageData);
2400
+ this.canvasData = assign({}, this.initialCanvasData);
2401
+ this.cropBoxData = assign({}, this.initialCropBoxData);
2402
+ this.renderCanvas();
2403
+
2404
+ if (this.cropped) {
2405
+ this.renderCropBox();
2406
+ }
2407
+ }
2408
+
2409
+ return this;
2410
+ },
2411
+ // Clear the crop box
2412
+ clear: function clear() {
2413
+ if (this.cropped && !this.disabled) {
2414
+ assign(this.cropBoxData, {
2415
+ left: 0,
2416
+ top: 0,
2417
+ width: 0,
2418
+ height: 0
2419
+ });
2420
+ this.cropped = false;
2421
+ this.renderCropBox();
2422
+ this.limitCanvas(true, true); // Render canvas after crop box rendered
2423
+
2424
+ this.renderCanvas();
2425
+ removeClass(this.dragBox, CLASS_MODAL);
2426
+ addClass(this.cropBox, CLASS_HIDDEN);
2427
+ }
2428
+
2429
+ return this;
2430
+ },
2431
+
2432
+ /**
2433
+ * Replace the image's src and rebuild the cropper
2434
+ * @param {string} url - The new URL.
2435
+ * @param {boolean} [hasSameSize] - Indicate if the new image has the same size as the old one.
2436
+ * @returns {Cropper} this
2437
+ */
2438
+ replace: function replace(url) {
2439
+ var hasSameSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
2440
+
2441
+ if (!this.disabled && url) {
2442
+ if (this.isImg) {
2443
+ this.element.src = url;
2444
+ }
2445
+
2446
+ if (hasSameSize) {
2447
+ this.url = url;
2448
+ this.image.src = url;
2449
+
2450
+ if (this.ready) {
2451
+ this.viewBoxImage.src = url;
2452
+ forEach(this.previews, function (element) {
2453
+ element.getElementsByTagName('img')[0].src = url;
2454
+ });
2455
+ }
2456
+ } else {
2457
+ if (this.isImg) {
2458
+ this.replaced = true;
2459
+ }
2460
+
2461
+ this.options.data = null;
2462
+ this.uncreate();
2463
+ this.load(url);
2464
+ }
2465
+ }
2466
+
2467
+ return this;
2468
+ },
2469
+ // Enable (unfreeze) the cropper
2470
+ enable: function enable() {
2471
+ if (this.ready && this.disabled) {
2472
+ this.disabled = false;
2473
+ removeClass(this.cropper, CLASS_DISABLED);
2474
+ }
2475
+
2476
+ return this;
2477
+ },
2478
+ // Disable (freeze) the cropper
2479
+ disable: function disable() {
2480
+ if (this.ready && !this.disabled) {
2481
+ this.disabled = true;
2482
+ addClass(this.cropper, CLASS_DISABLED);
2483
+ }
2484
+
2485
+ return this;
2486
+ },
2487
+
2488
+ /**
2489
+ * Destroy the cropper and remove the instance from the image
2490
+ * @returns {Cropper} this
2491
+ */
2492
+ destroy: function destroy() {
2493
+ var element = this.element;
2494
+
2495
+ if (!element[NAMESPACE]) {
2496
+ return this;
2497
+ }
2498
+
2499
+ element[NAMESPACE] = undefined;
2500
+
2501
+ if (this.isImg && this.replaced) {
2502
+ element.src = this.originalUrl;
2503
+ }
2504
+
2505
+ this.uncreate();
2506
+ return this;
2507
+ },
2508
+
2509
+ /**
2510
+ * Move the canvas with relative offsets
2511
+ * @param {number} offsetX - The relative offset distance on the x-axis.
2512
+ * @param {number} [offsetY=offsetX] - The relative offset distance on the y-axis.
2513
+ * @returns {Cropper} this
2514
+ */
2515
+ move: function move(offsetX) {
2516
+ var offsetY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : offsetX;
2517
+ var _this$canvasData = this.canvasData,
2518
+ left = _this$canvasData.left,
2519
+ top = _this$canvasData.top;
2520
+ return this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY));
2521
+ },
2522
+
2523
+ /**
2524
+ * Move the canvas to an absolute point
2525
+ * @param {number} x - The x-axis coordinate.
2526
+ * @param {number} [y=x] - The y-axis coordinate.
2527
+ * @returns {Cropper} this
2528
+ */
2529
+ moveTo: function moveTo(x) {
2530
+ var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x;
2531
+ var canvasData = this.canvasData;
2532
+ var changed = false;
2533
+ x = Number(x);
2534
+ y = Number(y);
2535
+
2536
+ if (this.ready && !this.disabled && this.options.movable) {
2537
+ if (isNumber(x)) {
2538
+ canvasData.left = x;
2539
+ changed = true;
2540
+ }
2541
+
2542
+ if (isNumber(y)) {
2543
+ canvasData.top = y;
2544
+ changed = true;
2545
+ }
2546
+
2547
+ if (changed) {
2548
+ this.renderCanvas(true);
2549
+ }
2550
+ }
2551
+
2552
+ return this;
2553
+ },
2554
+
2555
+ /**
2556
+ * Zoom the canvas with a relative ratio
2557
+ * @param {number} ratio - The target ratio.
2558
+ * @param {Event} _originalEvent - The original event if any.
2559
+ * @returns {Cropper} this
2560
+ */
2561
+ zoom: function zoom(ratio, _originalEvent) {
2562
+ var canvasData = this.canvasData;
2563
+ ratio = Number(ratio);
2564
+
2565
+ if (ratio < 0) {
2566
+ ratio = 1 / (1 - ratio);
2567
+ } else {
2568
+ ratio = 1 + ratio;
2569
+ }
2570
+
2571
+ return this.zoomTo(canvasData.width * ratio / canvasData.naturalWidth, null, _originalEvent);
2572
+ },
2573
+
2574
+ /**
2575
+ * Zoom the canvas to an absolute ratio
2576
+ * @param {number} ratio - The target ratio.
2577
+ * @param {Object} pivot - The zoom pivot point coordinate.
2578
+ * @param {Event} _originalEvent - The original event if any.
2579
+ * @returns {Cropper} this
2580
+ */
2581
+ zoomTo: function zoomTo(ratio, pivot, _originalEvent) {
2582
+ var options = this.options,
2583
+ canvasData = this.canvasData;
2584
+ var width = canvasData.width,
2585
+ height = canvasData.height,
2586
+ naturalWidth = canvasData.naturalWidth,
2587
+ naturalHeight = canvasData.naturalHeight;
2588
+ ratio = Number(ratio);
2589
+
2590
+ if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) {
2591
+ var newWidth = naturalWidth * ratio;
2592
+ var newHeight = naturalHeight * ratio;
2593
+
2594
+ if (dispatchEvent(this.element, EVENT_ZOOM, {
2595
+ ratio: ratio,
2596
+ oldRatio: width / naturalWidth,
2597
+ originalEvent: _originalEvent
2598
+ }) === false) {
2599
+ return this;
2600
+ }
2601
+
2602
+ if (_originalEvent) {
2603
+ var pointers = this.pointers;
2604
+ var offset = getOffset(this.cropper);
2605
+ var center = pointers && Object.keys(pointers).length ? getPointersCenter(pointers) : {
2606
+ pageX: _originalEvent.pageX,
2607
+ pageY: _originalEvent.pageY
2608
+ }; // Zoom from the triggering point of the event
2609
+
2610
+ canvasData.left -= (newWidth - width) * ((center.pageX - offset.left - canvasData.left) / width);
2611
+ canvasData.top -= (newHeight - height) * ((center.pageY - offset.top - canvasData.top) / height);
2612
+ } else if (isPlainObject(pivot) && isNumber(pivot.x) && isNumber(pivot.y)) {
2613
+ canvasData.left -= (newWidth - width) * ((pivot.x - canvasData.left) / width);
2614
+ canvasData.top -= (newHeight - height) * ((pivot.y - canvasData.top) / height);
2615
+ } else {
2616
+ // Zoom from the center of the canvas
2617
+ canvasData.left -= (newWidth - width) / 2;
2618
+ canvasData.top -= (newHeight - height) / 2;
2619
+ }
2620
+
2621
+ canvasData.width = newWidth;
2622
+ canvasData.height = newHeight;
2623
+ this.renderCanvas(true);
2624
+ }
2625
+
2626
+ return this;
2627
+ },
2628
+
2629
+ /**
2630
+ * Rotate the canvas with a relative degree
2631
+ * @param {number} degree - The rotate degree.
2632
+ * @returns {Cropper} this
2633
+ */
2634
+ rotate: function rotate(degree) {
2635
+ return this.rotateTo((this.imageData.rotate || 0) + Number(degree));
2636
+ },
2637
+
2638
+ /**
2639
+ * Rotate the canvas to an absolute degree
2640
+ * @param {number} degree - The rotate degree.
2641
+ * @returns {Cropper} this
2642
+ */
2643
+ rotateTo: function rotateTo(degree) {
2644
+ degree = Number(degree);
2645
+
2646
+ if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) {
2647
+ this.imageData.rotate = degree % 360;
2648
+ this.renderCanvas(true, true);
2649
+ }
2650
+
2651
+ return this;
2652
+ },
2653
+
2654
+ /**
2655
+ * Scale the image on the x-axis.
2656
+ * @param {number} scaleX - The scale ratio on the x-axis.
2657
+ * @returns {Cropper} this
2658
+ */
2659
+ scaleX: function scaleX(_scaleX) {
2660
+ var scaleY = this.imageData.scaleY;
2661
+ return this.scale(_scaleX, isNumber(scaleY) ? scaleY : 1);
2662
+ },
2663
+
2664
+ /**
2665
+ * Scale the image on the y-axis.
2666
+ * @param {number} scaleY - The scale ratio on the y-axis.
2667
+ * @returns {Cropper} this
2668
+ */
2669
+ scaleY: function scaleY(_scaleY) {
2670
+ var scaleX = this.imageData.scaleX;
2671
+ return this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY);
2672
+ },
2673
+
2674
+ /**
2675
+ * Scale the image
2676
+ * @param {number} scaleX - The scale ratio on the x-axis.
2677
+ * @param {number} [scaleY=scaleX] - The scale ratio on the y-axis.
2678
+ * @returns {Cropper} this
2679
+ */
2680
+ scale: function scale(scaleX) {
2681
+ var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX;
2682
+ var imageData = this.imageData;
2683
+ var transformed = false;
2684
+ scaleX = Number(scaleX);
2685
+ scaleY = Number(scaleY);
2686
+
2687
+ if (this.ready && !this.disabled && this.options.scalable) {
2688
+ if (isNumber(scaleX)) {
2689
+ imageData.scaleX = scaleX;
2690
+ transformed = true;
2691
+ }
2692
+
2693
+ if (isNumber(scaleY)) {
2694
+ imageData.scaleY = scaleY;
2695
+ transformed = true;
2696
+ }
2697
+
2698
+ if (transformed) {
2699
+ this.renderCanvas(true, true);
2700
+ }
2701
+ }
2702
+
2703
+ return this;
2704
+ },
2705
+
2706
+ /**
2707
+ * Get the cropped area position and size data (base on the original image)
2708
+ * @param {boolean} [rounded=false] - Indicate if round the data values or not.
2709
+ * @returns {Object} The result cropped data.
2710
+ */
2711
+ getData: function getData() {
2712
+ var rounded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
2713
+ var options = this.options,
2714
+ imageData = this.imageData,
2715
+ canvasData = this.canvasData,
2716
+ cropBoxData = this.cropBoxData;
2717
+ var data;
2718
+
2719
+ if (this.ready && this.cropped) {
2720
+ data = {
2721
+ x: cropBoxData.left - canvasData.left,
2722
+ y: cropBoxData.top - canvasData.top,
2723
+ width: cropBoxData.width,
2724
+ height: cropBoxData.height
2725
+ };
2726
+ var ratio = imageData.width / imageData.naturalWidth;
2727
+ forEach(data, function (n, i) {
2728
+ data[i] = n / ratio;
2729
+ });
2730
+
2731
+ if (rounded) {
2732
+ // In case rounding off leads to extra 1px in right or bottom border
2733
+ // we should round the top-left corner and the dimension (#343).
2734
+ var bottom = Math.round(data.y + data.height);
2735
+ var right = Math.round(data.x + data.width);
2736
+ data.x = Math.round(data.x);
2737
+ data.y = Math.round(data.y);
2738
+ data.width = right - data.x;
2739
+ data.height = bottom - data.y;
2740
+ }
2741
+ } else {
2742
+ data = {
2743
+ x: 0,
2744
+ y: 0,
2745
+ width: 0,
2746
+ height: 0
2747
+ };
2748
+ }
2749
+
2750
+ if (options.rotatable) {
2751
+ data.rotate = imageData.rotate || 0;
2752
+ }
2753
+
2754
+ if (options.scalable) {
2755
+ data.scaleX = imageData.scaleX || 1;
2756
+ data.scaleY = imageData.scaleY || 1;
2757
+ }
2758
+
2759
+ return data;
2760
+ },
2761
+
2762
+ /**
2763
+ * Set the cropped area position and size with new data
2764
+ * @param {Object} data - The new data.
2765
+ * @returns {Cropper} this
2766
+ */
2767
+ setData: function setData(data) {
2768
+ var options = this.options,
2769
+ imageData = this.imageData,
2770
+ canvasData = this.canvasData;
2771
+ var cropBoxData = {};
2772
+
2773
+ if (this.ready && !this.disabled && isPlainObject(data)) {
2774
+ var transformed = false;
2775
+
2776
+ if (options.rotatable) {
2777
+ if (isNumber(data.rotate) && data.rotate !== imageData.rotate) {
2778
+ imageData.rotate = data.rotate;
2779
+ transformed = true;
2780
+ }
2781
+ }
2782
+
2783
+ if (options.scalable) {
2784
+ if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) {
2785
+ imageData.scaleX = data.scaleX;
2786
+ transformed = true;
2787
+ }
2788
+
2789
+ if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) {
2790
+ imageData.scaleY = data.scaleY;
2791
+ transformed = true;
2792
+ }
2793
+ }
2794
+
2795
+ if (transformed) {
2796
+ this.renderCanvas(true, true);
2797
+ }
2798
+
2799
+ var ratio = imageData.width / imageData.naturalWidth;
2800
+
2801
+ if (isNumber(data.x)) {
2802
+ cropBoxData.left = data.x * ratio + canvasData.left;
2803
+ }
2804
+
2805
+ if (isNumber(data.y)) {
2806
+ cropBoxData.top = data.y * ratio + canvasData.top;
2807
+ }
2808
+
2809
+ if (isNumber(data.width)) {
2810
+ cropBoxData.width = data.width * ratio;
2811
+ }
2812
+
2813
+ if (isNumber(data.height)) {
2814
+ cropBoxData.height = data.height * ratio;
2815
+ }
2816
+
2817
+ this.setCropBoxData(cropBoxData);
2818
+ }
2819
+
2820
+ return this;
2821
+ },
2822
+
2823
+ /**
2824
+ * Get the container size data.
2825
+ * @returns {Object} The result container data.
2826
+ */
2827
+ getContainerData: function getContainerData() {
2828
+ return this.ready ? assign({}, this.containerData) : {};
2829
+ },
2830
+
2831
+ /**
2832
+ * Get the image position and size data.
2833
+ * @returns {Object} The result image data.
2834
+ */
2835
+ getImageData: function getImageData() {
2836
+ return this.sized ? assign({}, this.imageData) : {};
2837
+ },
2838
+
2839
+ /**
2840
+ * Get the canvas position and size data.
2841
+ * @returns {Object} The result canvas data.
2842
+ */
2843
+ getCanvasData: function getCanvasData() {
2844
+ var canvasData = this.canvasData;
2845
+ var data = {};
2846
+
2847
+ if (this.ready) {
2848
+ forEach(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (n) {
2849
+ data[n] = canvasData[n];
2850
+ });
2851
+ }
2852
+
2853
+ return data;
2854
+ },
2855
+
2856
+ /**
2857
+ * Set the canvas position and size with new data.
2858
+ * @param {Object} data - The new canvas data.
2859
+ * @returns {Cropper} this
2860
+ */
2861
+ setCanvasData: function setCanvasData(data) {
2862
+ var canvasData = this.canvasData;
2863
+ var aspectRatio = canvasData.aspectRatio;
2864
+
2865
+ if (this.ready && !this.disabled && isPlainObject(data)) {
2866
+ if (isNumber(data.left)) {
2867
+ canvasData.left = data.left;
2868
+ }
2869
+
2870
+ if (isNumber(data.top)) {
2871
+ canvasData.top = data.top;
2872
+ }
2873
+
2874
+ if (isNumber(data.width)) {
2875
+ canvasData.width = data.width;
2876
+ canvasData.height = data.width / aspectRatio;
2877
+ } else if (isNumber(data.height)) {
2878
+ canvasData.height = data.height;
2879
+ canvasData.width = data.height * aspectRatio;
2880
+ }
2881
+
2882
+ this.renderCanvas(true);
2883
+ }
2884
+
2885
+ return this;
2886
+ },
2887
+
2888
+ /**
2889
+ * Get the crop box position and size data.
2890
+ * @returns {Object} The result crop box data.
2891
+ */
2892
+ getCropBoxData: function getCropBoxData() {
2893
+ var cropBoxData = this.cropBoxData;
2894
+ var data;
2895
+
2896
+ if (this.ready && this.cropped) {
2897
+ data = {
2898
+ left: cropBoxData.left,
2899
+ top: cropBoxData.top,
2900
+ width: cropBoxData.width,
2901
+ height: cropBoxData.height
2902
+ };
2903
+ }
2904
+
2905
+ return data || {};
2906
+ },
2907
+
2908
+ /**
2909
+ * Set the crop box position and size with new data.
2910
+ * @param {Object} data - The new crop box data.
2911
+ * @returns {Cropper} this
2912
+ */
2913
+ setCropBoxData: function setCropBoxData(data) {
2914
+ var cropBoxData = this.cropBoxData;
2915
+ var aspectRatio = this.options.aspectRatio;
2916
+ var widthChanged;
2917
+ var heightChanged;
2918
+
2919
+ if (this.ready && this.cropped && !this.disabled && isPlainObject(data)) {
2920
+ if (isNumber(data.left)) {
2921
+ cropBoxData.left = data.left;
2922
+ }
2923
+
2924
+ if (isNumber(data.top)) {
2925
+ cropBoxData.top = data.top;
2926
+ }
2927
+
2928
+ if (isNumber(data.width) && data.width !== cropBoxData.width) {
2929
+ widthChanged = true;
2930
+ cropBoxData.width = data.width;
2931
+ }
2932
+
2933
+ if (isNumber(data.height) && data.height !== cropBoxData.height) {
2934
+ heightChanged = true;
2935
+ cropBoxData.height = data.height;
2936
+ }
2937
+
2938
+ if (aspectRatio) {
2939
+ if (widthChanged) {
2940
+ cropBoxData.height = cropBoxData.width / aspectRatio;
2941
+ } else if (heightChanged) {
2942
+ cropBoxData.width = cropBoxData.height * aspectRatio;
2943
+ }
2944
+ }
2945
+
2946
+ this.renderCropBox();
2947
+ }
2948
+
2949
+ return this;
2950
+ },
2951
+
2952
+ /**
2953
+ * Get a canvas drawn the cropped image.
2954
+ * @param {Object} [options={}] - The config options.
2955
+ * @returns {HTMLCanvasElement} - The result canvas.
2956
+ */
2957
+ getCroppedCanvas: function getCroppedCanvas() {
2958
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2959
+
2960
+ if (!this.ready || !window.HTMLCanvasElement) {
2961
+ return null;
2962
+ }
2963
+
2964
+ var canvasData = this.canvasData;
2965
+ var source = getSourceCanvas(this.image, this.imageData, canvasData, options); // Returns the source canvas if it is not cropped.
2966
+
2967
+ if (!this.cropped) {
2968
+ return source;
2969
+ }
2970
+
2971
+ var _this$getData = this.getData(),
2972
+ initialX = _this$getData.x,
2973
+ initialY = _this$getData.y,
2974
+ initialWidth = _this$getData.width,
2975
+ initialHeight = _this$getData.height;
2976
+
2977
+ var ratio = source.width / Math.floor(canvasData.naturalWidth);
2978
+
2979
+ if (ratio !== 1) {
2980
+ initialX *= ratio;
2981
+ initialY *= ratio;
2982
+ initialWidth *= ratio;
2983
+ initialHeight *= ratio;
2984
+ }
2985
+
2986
+ var aspectRatio = initialWidth / initialHeight;
2987
+ var maxSizes = getAdjustedSizes({
2988
+ aspectRatio: aspectRatio,
2989
+ width: options.maxWidth || Infinity,
2990
+ height: options.maxHeight || Infinity
2991
+ });
2992
+ var minSizes = getAdjustedSizes({
2993
+ aspectRatio: aspectRatio,
2994
+ width: options.minWidth || 0,
2995
+ height: options.minHeight || 0
2996
+ }, 'cover');
2997
+
2998
+ var _getAdjustedSizes = getAdjustedSizes({
2999
+ aspectRatio: aspectRatio,
3000
+ width: options.width || (ratio !== 1 ? source.width : initialWidth),
3001
+ height: options.height || (ratio !== 1 ? source.height : initialHeight)
3002
+ }),
3003
+ width = _getAdjustedSizes.width,
3004
+ height = _getAdjustedSizes.height;
3005
+
3006
+ width = Math.min(maxSizes.width, Math.max(minSizes.width, width));
3007
+ height = Math.min(maxSizes.height, Math.max(minSizes.height, height));
3008
+ var canvas = document.createElement('canvas');
3009
+ var context = canvas.getContext('2d');
3010
+ canvas.width = normalizeDecimalNumber(width);
3011
+ canvas.height = normalizeDecimalNumber(height);
3012
+ context.fillStyle = options.fillColor || 'transparent';
3013
+ context.fillRect(0, 0, width, height);
3014
+ var _options$imageSmoothi = options.imageSmoothingEnabled,
3015
+ imageSmoothingEnabled = _options$imageSmoothi === void 0 ? true : _options$imageSmoothi,
3016
+ imageSmoothingQuality = options.imageSmoothingQuality;
3017
+ context.imageSmoothingEnabled = imageSmoothingEnabled;
3018
+
3019
+ if (imageSmoothingQuality) {
3020
+ context.imageSmoothingQuality = imageSmoothingQuality;
3021
+ } // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage
3022
+
3023
+
3024
+ var sourceWidth = source.width;
3025
+ var sourceHeight = source.height; // Source canvas parameters
3026
+
3027
+ var srcX = initialX;
3028
+ var srcY = initialY;
3029
+ var srcWidth;
3030
+ var srcHeight; // Destination canvas parameters
3031
+
3032
+ var dstX;
3033
+ var dstY;
3034
+ var dstWidth;
3035
+ var dstHeight;
3036
+
3037
+ if (srcX <= -initialWidth || srcX > sourceWidth) {
3038
+ srcX = 0;
3039
+ srcWidth = 0;
3040
+ dstX = 0;
3041
+ dstWidth = 0;
3042
+ } else if (srcX <= 0) {
3043
+ dstX = -srcX;
3044
+ srcX = 0;
3045
+ srcWidth = Math.min(sourceWidth, initialWidth + srcX);
3046
+ dstWidth = srcWidth;
3047
+ } else if (srcX <= sourceWidth) {
3048
+ dstX = 0;
3049
+ srcWidth = Math.min(initialWidth, sourceWidth - srcX);
3050
+ dstWidth = srcWidth;
3051
+ }
3052
+
3053
+ if (srcWidth <= 0 || srcY <= -initialHeight || srcY > sourceHeight) {
3054
+ srcY = 0;
3055
+ srcHeight = 0;
3056
+ dstY = 0;
3057
+ dstHeight = 0;
3058
+ } else if (srcY <= 0) {
3059
+ dstY = -srcY;
3060
+ srcY = 0;
3061
+ srcHeight = Math.min(sourceHeight, initialHeight + srcY);
3062
+ dstHeight = srcHeight;
3063
+ } else if (srcY <= sourceHeight) {
3064
+ dstY = 0;
3065
+ srcHeight = Math.min(initialHeight, sourceHeight - srcY);
3066
+ dstHeight = srcHeight;
3067
+ }
3068
+
3069
+ var params = [srcX, srcY, srcWidth, srcHeight]; // Avoid "IndexSizeError"
3070
+
3071
+ if (dstWidth > 0 && dstHeight > 0) {
3072
+ var scale = width / initialWidth;
3073
+ params.push(dstX * scale, dstY * scale, dstWidth * scale, dstHeight * scale);
3074
+ } // All the numerical parameters should be integer for `drawImage`
3075
+ // https://github.com/fengyuanchen/cropper/issues/476
3076
+
3077
+
3078
+ context.drawImage.apply(context, [source].concat(_toConsumableArray(params.map(function (param) {
3079
+ return Math.floor(normalizeDecimalNumber(param));
3080
+ }))));
3081
+ return canvas;
3082
+ },
3083
+
3084
+ /**
3085
+ * Change the aspect ratio of the crop box.
3086
+ * @param {number} aspectRatio - The new aspect ratio.
3087
+ * @returns {Cropper} this
3088
+ */
3089
+ setAspectRatio: function setAspectRatio(aspectRatio) {
3090
+ var options = this.options;
3091
+
3092
+ if (!this.disabled && !isUndefined(aspectRatio)) {
3093
+ // 0 -> NaN
3094
+ options.aspectRatio = Math.max(0, aspectRatio) || NaN;
3095
+
3096
+ if (this.ready) {
3097
+ this.initCropBox();
3098
+
3099
+ if (this.cropped) {
3100
+ this.renderCropBox();
3101
+ }
3102
+ }
3103
+ }
3104
+
3105
+ return this;
3106
+ },
3107
+
3108
+ /**
3109
+ * Change the drag mode.
3110
+ * @param {string} mode - The new drag mode.
3111
+ * @returns {Cropper} this
3112
+ */
3113
+ setDragMode: function setDragMode(mode) {
3114
+ var options = this.options,
3115
+ dragBox = this.dragBox,
3116
+ face = this.face;
3117
+
3118
+ if (this.ready && !this.disabled) {
3119
+ var croppable = mode === DRAG_MODE_CROP;
3120
+ var movable = options.movable && mode === DRAG_MODE_MOVE;
3121
+ mode = croppable || movable ? mode : DRAG_MODE_NONE;
3122
+ options.dragMode = mode;
3123
+ setData(dragBox, DATA_ACTION, mode);
3124
+ toggleClass(dragBox, CLASS_CROP, croppable);
3125
+ toggleClass(dragBox, CLASS_MOVE, movable);
3126
+
3127
+ if (!options.cropBoxMovable) {
3128
+ // Sync drag mode to crop box when it is not movable
3129
+ setData(face, DATA_ACTION, mode);
3130
+ toggleClass(face, CLASS_CROP, croppable);
3131
+ toggleClass(face, CLASS_MOVE, movable);
3132
+ }
3133
+ }
3134
+
3135
+ return this;
3136
+ }
3137
+ };
3138
+
3139
+ var AnotherCropper = WINDOW.Cropper;
3140
+
3141
+ var Cropper =
3142
+ /*#__PURE__*/
3143
+ function () {
3144
+ /**
3145
+ * Create a new Cropper.
3146
+ * @param {Element} element - The target element for cropping.
3147
+ * @param {Object} [options={}] - The configuration options.
3148
+ */
3149
+ function Cropper(element) {
3150
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
3151
+
3152
+ _classCallCheck(this, Cropper);
3153
+
3154
+ if (!element || !REGEXP_TAG_NAME.test(element.tagName)) {
3155
+ throw new Error('The first argument is required and must be an <img> or <canvas> element.');
3156
+ }
3157
+
3158
+ this.element = element;
3159
+ this.options = assign({}, DEFAULTS, isPlainObject(options) && options);
3160
+ this.cropped = false;
3161
+ this.disabled = false;
3162
+ this.pointers = {};
3163
+ this.ready = false;
3164
+ this.reloading = false;
3165
+ this.replaced = false;
3166
+ this.sized = false;
3167
+ this.sizing = false;
3168
+ this.init();
3169
+ }
3170
+
3171
+ _createClass(Cropper, [{
3172
+ key: "init",
3173
+ value: function init() {
3174
+ var element = this.element;
3175
+ var tagName = element.tagName.toLowerCase();
3176
+ var url;
3177
+
3178
+ if (element[NAMESPACE]) {
3179
+ return;
3180
+ }
3181
+
3182
+ element[NAMESPACE] = this;
3183
+
3184
+ if (tagName === 'img') {
3185
+ this.isImg = true; // e.g.: "img/picture.jpg"
3186
+
3187
+ url = element.getAttribute('src') || '';
3188
+ this.originalUrl = url; // Stop when it's a blank image
3189
+
3190
+ if (!url) {
3191
+ return;
3192
+ } // e.g.: "http://example.com/img/picture.jpg"
3193
+
3194
+
3195
+ url = element.src;
3196
+ } else if (tagName === 'canvas' && window.HTMLCanvasElement) {
3197
+ url = element.toDataURL();
3198
+ }
3199
+
3200
+ this.load(url);
3201
+ }
3202
+ }, {
3203
+ key: "load",
3204
+ value: function load(url) {
3205
+ var _this = this;
3206
+
3207
+ if (!url) {
3208
+ return;
3209
+ }
3210
+
3211
+ this.url = url;
3212
+ this.imageData = {};
3213
+ var element = this.element,
3214
+ options = this.options;
3215
+
3216
+ if (!options.rotatable && !options.scalable) {
3217
+ options.checkOrientation = false;
3218
+ } // Only IE10+ supports Typed Arrays
3219
+
3220
+
3221
+ if (!options.checkOrientation || !window.ArrayBuffer) {
3222
+ this.clone();
3223
+ return;
3224
+ } // Read ArrayBuffer from Data URL of JPEG images directly for better performance.
3225
+
3226
+
3227
+ if (REGEXP_DATA_URL_JPEG.test(url)) {
3228
+ this.read(dataURLToArrayBuffer(url));
3229
+ return;
3230
+ }
3231
+
3232
+ var xhr = new XMLHttpRequest();
3233
+ var clone = this.clone.bind(this);
3234
+ this.reloading = true;
3235
+ this.xhr = xhr; // 1. Cross origin requests are only supported for protocol schemes:
3236
+ // http, https, data, chrome, chrome-extension.
3237
+ // 2. Access to XMLHttpRequest from a Data URL will be blocked by CORS policy
3238
+ // in some browsers as IE11 and Safari.
3239
+
3240
+ xhr.onabort = clone;
3241
+ xhr.onerror = clone;
3242
+ xhr.ontimeout = clone;
3243
+
3244
+ xhr.onprogress = function () {
3245
+ if (xhr.getResponseHeader('content-type') !== MIME_TYPE_JPEG) {
3246
+ xhr.abort();
3247
+ }
3248
+ };
3249
+
3250
+ xhr.onload = function () {
3251
+ _this.read(xhr.response);
3252
+ };
3253
+
3254
+ xhr.onloadend = function () {
3255
+ _this.reloading = false;
3256
+ _this.xhr = null;
3257
+ }; // Bust cache when there is a "crossOrigin" property to avoid browser cache error
3258
+
3259
+
3260
+ if (options.checkCrossOrigin && isCrossOriginURL(url) && element.crossOrigin) {
3261
+ url = addTimestamp(url);
3262
+ }
3263
+
3264
+ xhr.open('GET', url);
3265
+ xhr.responseType = 'arraybuffer';
3266
+ xhr.withCredentials = element.crossOrigin === 'use-credentials';
3267
+ xhr.send();
3268
+ }
3269
+ }, {
3270
+ key: "read",
3271
+ value: function read(arrayBuffer) {
3272
+ var options = this.options,
3273
+ imageData = this.imageData; // Reset the orientation value to its default value 1
3274
+ // as some iOS browsers will render image with its orientation
3275
+
3276
+ var orientation = resetAndGetOrientation(arrayBuffer);
3277
+ var rotate = 0;
3278
+ var scaleX = 1;
3279
+ var scaleY = 1;
3280
+
3281
+ if (orientation > 1) {
3282
+ // Generate a new URL which has the default orientation value
3283
+ this.url = arrayBufferToDataURL(arrayBuffer, MIME_TYPE_JPEG);
3284
+
3285
+ var _parseOrientation = parseOrientation(orientation);
3286
+
3287
+ rotate = _parseOrientation.rotate;
3288
+ scaleX = _parseOrientation.scaleX;
3289
+ scaleY = _parseOrientation.scaleY;
3290
+ }
3291
+
3292
+ if (options.rotatable) {
3293
+ imageData.rotate = rotate;
3294
+ }
3295
+
3296
+ if (options.scalable) {
3297
+ imageData.scaleX = scaleX;
3298
+ imageData.scaleY = scaleY;
3299
+ }
3300
+
3301
+ this.clone();
3302
+ }
3303
+ }, {
3304
+ key: "clone",
3305
+ value: function clone() {
3306
+ var element = this.element,
3307
+ url = this.url;
3308
+ var crossOrigin;
3309
+ var crossOriginUrl;
3310
+
3311
+ if (this.options.checkCrossOrigin && isCrossOriginURL(url)) {
3312
+ crossOrigin = element.crossOrigin;
3313
+
3314
+ if (!crossOrigin) {
3315
+ crossOrigin = 'anonymous';
3316
+ } // Bust cache when there is not a "crossOrigin" property (#519)
3317
+
3318
+
3319
+ crossOriginUrl = addTimestamp(url);
3320
+ }
3321
+
3322
+ this.crossOrigin = crossOrigin;
3323
+ this.crossOriginUrl = crossOriginUrl;
3324
+ var image = document.createElement('img');
3325
+
3326
+ if (crossOrigin) {
3327
+ image.crossOrigin = crossOrigin;
3328
+ }
3329
+
3330
+ image.src = crossOriginUrl || url;
3331
+ this.image = image;
3332
+ image.onload = this.start.bind(this);
3333
+ image.onerror = this.stop.bind(this);
3334
+ addClass(image, CLASS_HIDE);
3335
+ element.parentNode.insertBefore(image, element.nextSibling);
3336
+ }
3337
+ }, {
3338
+ key: "start",
3339
+ value: function start() {
3340
+ var _this2 = this;
3341
+
3342
+ var image = this.isImg ? this.element : this.image;
3343
+ image.onload = null;
3344
+ image.onerror = null;
3345
+ this.sizing = true; // Match all browsers that use WebKit as the layout engine in iOS devices,
3346
+ // such as Safari for iOS, Chrome for iOS, and in-app browsers.
3347
+
3348
+ var isIOSWebKit = WINDOW.navigator && /(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(WINDOW.navigator.userAgent);
3349
+
3350
+ var done = function done(naturalWidth, naturalHeight) {
3351
+ assign(_this2.imageData, {
3352
+ naturalWidth: naturalWidth,
3353
+ naturalHeight: naturalHeight,
3354
+ aspectRatio: naturalWidth / naturalHeight
3355
+ });
3356
+ _this2.sizing = false;
3357
+ _this2.sized = true;
3358
+
3359
+ _this2.build();
3360
+ }; // Most modern browsers (excepts iOS WebKit)
3361
+
3362
+
3363
+ if (image.naturalWidth && !isIOSWebKit) {
3364
+ done(image.naturalWidth, image.naturalHeight);
3365
+ return;
3366
+ }
3367
+
3368
+ var sizingImage = document.createElement('img');
3369
+ var body = document.body || document.documentElement;
3370
+ this.sizingImage = sizingImage;
3371
+
3372
+ sizingImage.onload = function () {
3373
+ done(sizingImage.width, sizingImage.height);
3374
+
3375
+ if (!isIOSWebKit) {
3376
+ body.removeChild(sizingImage);
3377
+ }
3378
+ };
3379
+
3380
+ sizingImage.src = image.src; // iOS WebKit will convert the image automatically
3381
+ // with its orientation once append it into DOM (#279)
3382
+
3383
+ if (!isIOSWebKit) {
3384
+ sizingImage.style.cssText = 'left:0;' + 'max-height:none!important;' + 'max-width:none!important;' + 'min-height:0!important;' + 'min-width:0!important;' + 'opacity:0;' + 'position:absolute;' + 'top:0;' + 'z-index:-1;';
3385
+ body.appendChild(sizingImage);
3386
+ }
3387
+ }
3388
+ }, {
3389
+ key: "stop",
3390
+ value: function stop() {
3391
+ var image = this.image;
3392
+ image.onload = null;
3393
+ image.onerror = null;
3394
+ image.parentNode.removeChild(image);
3395
+ this.image = null;
3396
+ }
3397
+ }, {
3398
+ key: "build",
3399
+ value: function build() {
3400
+ if (!this.sized || this.ready) {
3401
+ return;
3402
+ }
3403
+
3404
+ var element = this.element,
3405
+ options = this.options,
3406
+ image = this.image; // Create cropper elements
3407
+
3408
+ var container = element.parentNode;
3409
+ var template = document.createElement('div');
3410
+ template.innerHTML = TEMPLATE;
3411
+ var cropper = template.querySelector(".".concat(NAMESPACE, "-container"));
3412
+ var canvas = cropper.querySelector(".".concat(NAMESPACE, "-canvas"));
3413
+ var dragBox = cropper.querySelector(".".concat(NAMESPACE, "-drag-box"));
3414
+ var cropBox = cropper.querySelector(".".concat(NAMESPACE, "-crop-box"));
3415
+ var face = cropBox.querySelector(".".concat(NAMESPACE, "-face"));
3416
+ this.container = container;
3417
+ this.cropper = cropper;
3418
+ this.canvas = canvas;
3419
+ this.dragBox = dragBox;
3420
+ this.cropBox = cropBox;
3421
+ this.viewBox = cropper.querySelector(".".concat(NAMESPACE, "-view-box"));
3422
+ this.face = face;
3423
+ canvas.appendChild(image); // Hide the original image
3424
+
3425
+ addClass(element, CLASS_HIDDEN); // Inserts the cropper after to the current image
3426
+
3427
+ container.insertBefore(cropper, element.nextSibling); // Show the image if is hidden
3428
+
3429
+ if (!this.isImg) {
3430
+ removeClass(image, CLASS_HIDE);
3431
+ }
3432
+
3433
+ this.initPreview();
3434
+ this.bind();
3435
+ options.initialAspectRatio = Math.max(0, options.initialAspectRatio) || NaN;
3436
+ options.aspectRatio = Math.max(0, options.aspectRatio) || NaN;
3437
+ options.viewMode = Math.max(0, Math.min(3, Math.round(options.viewMode))) || 0;
3438
+ addClass(cropBox, CLASS_HIDDEN);
3439
+
3440
+ if (!options.guides) {
3441
+ addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-dashed")), CLASS_HIDDEN);
3442
+ }
3443
+
3444
+ if (!options.center) {
3445
+ addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-center")), CLASS_HIDDEN);
3446
+ }
3447
+
3448
+ if (options.background) {
3449
+ addClass(cropper, "".concat(NAMESPACE, "-bg"));
3450
+ }
3451
+
3452
+ if (!options.highlight) {
3453
+ addClass(face, CLASS_INVISIBLE);
3454
+ }
3455
+
3456
+ if (options.cropBoxMovable) {
3457
+ addClass(face, CLASS_MOVE);
3458
+ setData(face, DATA_ACTION, ACTION_ALL);
3459
+ }
3460
+
3461
+ if (!options.cropBoxResizable) {
3462
+ addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-line")), CLASS_HIDDEN);
3463
+ addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-point")), CLASS_HIDDEN);
3464
+ }
3465
+
3466
+ this.render();
3467
+ this.ready = true;
3468
+ this.setDragMode(options.dragMode);
3469
+
3470
+ if (options.autoCrop) {
3471
+ this.crop();
3472
+ }
3473
+
3474
+ this.setData(options.data);
3475
+
3476
+ if (isFunction(options.ready)) {
3477
+ addListener(element, EVENT_READY, options.ready, {
3478
+ once: true
3479
+ });
3480
+ }
3481
+
3482
+ dispatchEvent(element, EVENT_READY);
3483
+ }
3484
+ }, {
3485
+ key: "unbuild",
3486
+ value: function unbuild() {
3487
+ if (!this.ready) {
3488
+ return;
3489
+ }
3490
+
3491
+ this.ready = false;
3492
+ this.unbind();
3493
+ this.resetPreview();
3494
+ this.cropper.parentNode.removeChild(this.cropper);
3495
+ removeClass(this.element, CLASS_HIDDEN);
3496
+ }
3497
+ }, {
3498
+ key: "uncreate",
3499
+ value: function uncreate() {
3500
+ if (this.ready) {
3501
+ this.unbuild();
3502
+ this.ready = false;
3503
+ this.cropped = false;
3504
+ } else if (this.sizing) {
3505
+ this.sizingImage.onload = null;
3506
+ this.sizing = false;
3507
+ this.sized = false;
3508
+ } else if (this.reloading) {
3509
+ this.xhr.onabort = null;
3510
+ this.xhr.abort();
3511
+ } else if (this.image) {
3512
+ this.stop();
3513
+ }
3514
+ }
3515
+ /**
3516
+ * Get the no conflict cropper class.
3517
+ * @returns {Cropper} The cropper class.
3518
+ */
3519
+
3520
+ }], [{
3521
+ key: "noConflict",
3522
+ value: function noConflict() {
3523
+ window.Cropper = AnotherCropper;
3524
+ return Cropper;
3525
+ }
3526
+ /**
3527
+ * Change the default options.
3528
+ * @param {Object} options - The new default options.
3529
+ */
3530
+
3531
+ }, {
3532
+ key: "setDefaults",
3533
+ value: function setDefaults(options) {
3534
+ assign(DEFAULTS, isPlainObject(options) && options);
3535
+ }
3536
+ }]);
3537
+
3538
+ return Cropper;
3539
+ }();
3540
+
3541
+ assign(Cropper.prototype, render, preview, events, handlers, change, methods);
3542
+
3543
+ export default Cropper;
vendor/cropperjs/dist/cropper.js ADDED
@@ -0,0 +1,3551 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Cropper.js v1.5.3
3
+ * https://fengyuanchen.github.io/cropperjs
4
+ *
5
+ * Copyright 2015-present Chen Fengyuan
6
+ * Released under the MIT license
7
+ *
8
+ * Date: 2019-07-10T12:07:44.557Z
9
+ */
10
+
11
+ (function (global, factory) {
12
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
13
+ typeof define === 'function' && define.amd ? define(factory) :
14
+ (global = global || self, global.Cropper = factory());
15
+ }(this, function () { 'use strict';
16
+
17
+ function _typeof(obj) {
18
+ if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
19
+ _typeof = function (obj) {
20
+ return typeof obj;
21
+ };
22
+ } else {
23
+ _typeof = function (obj) {
24
+ return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
25
+ };
26
+ }
27
+
28
+ return _typeof(obj);
29
+ }
30
+
31
+ function _classCallCheck(instance, Constructor) {
32
+ if (!(instance instanceof Constructor)) {
33
+ throw new TypeError("Cannot call a class as a function");
34
+ }
35
+ }
36
+
37
+ function _defineProperties(target, props) {
38
+ for (var i = 0; i < props.length; i++) {
39
+ var descriptor = props[i];
40
+ descriptor.enumerable = descriptor.enumerable || false;
41
+ descriptor.configurable = true;
42
+ if ("value" in descriptor) descriptor.writable = true;
43
+ Object.defineProperty(target, descriptor.key, descriptor);
44
+ }
45
+ }
46
+
47
+ function _createClass(Constructor, protoProps, staticProps) {
48
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
49
+ if (staticProps) _defineProperties(Constructor, staticProps);
50
+ return Constructor;
51
+ }
52
+
53
+ function _toConsumableArray(arr) {
54
+ return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
55
+ }
56
+
57
+ function _arrayWithoutHoles(arr) {
58
+ if (Array.isArray(arr)) {
59
+ for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
60
+
61
+ return arr2;
62
+ }
63
+ }
64
+
65
+ function _iterableToArray(iter) {
66
+ if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
67
+ }
68
+
69
+ function _nonIterableSpread() {
70
+ throw new TypeError("Invalid attempt to spread non-iterable instance");
71
+ }
72
+
73
+ var IS_BROWSER = typeof window !== 'undefined';
74
+ var WINDOW = IS_BROWSER ? window : {};
75
+ var IS_TOUCH_DEVICE = IS_BROWSER ? 'ontouchstart' in WINDOW.document.documentElement : false;
76
+ var HAS_POINTER_EVENT = IS_BROWSER ? 'PointerEvent' in WINDOW : false;
77
+ var NAMESPACE = 'cropper'; // Actions
78
+
79
+ var ACTION_ALL = 'all';
80
+ var ACTION_CROP = 'crop';
81
+ var ACTION_MOVE = 'move';
82
+ var ACTION_ZOOM = 'zoom';
83
+ var ACTION_EAST = 'e';
84
+ var ACTION_WEST = 'w';
85
+ var ACTION_SOUTH = 's';
86
+ var ACTION_NORTH = 'n';
87
+ var ACTION_NORTH_EAST = 'ne';
88
+ var ACTION_NORTH_WEST = 'nw';
89
+ var ACTION_SOUTH_EAST = 'se';
90
+ var ACTION_SOUTH_WEST = 'sw'; // Classes
91
+
92
+ var CLASS_CROP = "".concat(NAMESPACE, "-crop");
93
+ var CLASS_DISABLED = "".concat(NAMESPACE, "-disabled");
94
+ var CLASS_HIDDEN = "".concat(NAMESPACE, "-hidden");
95
+ var CLASS_HIDE = "".concat(NAMESPACE, "-hide");
96
+ var CLASS_INVISIBLE = "".concat(NAMESPACE, "-invisible");
97
+ var CLASS_MODAL = "".concat(NAMESPACE, "-modal");
98
+ var CLASS_MOVE = "".concat(NAMESPACE, "-move"); // Data keys
99
+
100
+ var DATA_ACTION = "".concat(NAMESPACE, "Action");
101
+ var DATA_PREVIEW = "".concat(NAMESPACE, "Preview"); // Drag modes
102
+
103
+ var DRAG_MODE_CROP = 'crop';
104
+ var DRAG_MODE_MOVE = 'move';
105
+ var DRAG_MODE_NONE = 'none'; // Events
106
+
107
+ var EVENT_CROP = 'crop';
108
+ var EVENT_CROP_END = 'cropend';
109
+ var EVENT_CROP_MOVE = 'cropmove';
110
+ var EVENT_CROP_START = 'cropstart';
111
+ var EVENT_DBLCLICK = 'dblclick';
112
+ var EVENT_TOUCH_START = IS_TOUCH_DEVICE ? 'touchstart' : 'mousedown';
113
+ var EVENT_TOUCH_MOVE = IS_TOUCH_DEVICE ? 'touchmove' : 'mousemove';
114
+ var EVENT_TOUCH_END = IS_TOUCH_DEVICE ? 'touchend touchcancel' : 'mouseup';
115
+ var EVENT_POINTER_DOWN = HAS_POINTER_EVENT ? 'pointerdown' : EVENT_TOUCH_START;
116
+ var EVENT_POINTER_MOVE = HAS_POINTER_EVENT ? 'pointermove' : EVENT_TOUCH_MOVE;
117
+ var EVENT_POINTER_UP = HAS_POINTER_EVENT ? 'pointerup pointercancel' : EVENT_TOUCH_END;
118
+ var EVENT_READY = 'ready';
119
+ var EVENT_RESIZE = 'resize';
120
+ var EVENT_WHEEL = 'wheel';
121
+ var EVENT_ZOOM = 'zoom'; // Mime types
122
+
123
+ var MIME_TYPE_JPEG = 'image/jpeg'; // RegExps
124
+
125
+ var REGEXP_ACTIONS = /^e|w|s|n|se|sw|ne|nw|all|crop|move|zoom$/;
126
+ var REGEXP_DATA_URL_JPEG = /^data:image\/jpeg;base64,/;
127
+ var REGEXP_TAG_NAME = /^img|canvas$/i; // Misc
128
+ // Inspired by the default width and height of a canvas element.
129
+
130
+ var MIN_CONTAINER_WIDTH = 200;
131
+ var MIN_CONTAINER_HEIGHT = 100;
132
+
133
+ var DEFAULTS = {
134
+ // Define the view mode of the cropper
135
+ viewMode: 0,
136
+ // 0, 1, 2, 3
137
+ // Define the dragging mode of the cropper
138
+ dragMode: DRAG_MODE_CROP,
139
+ // 'crop', 'move' or 'none'
140
+ // Define the initial aspect ratio of the crop box
141
+ initialAspectRatio: NaN,
142
+ // Define the aspect ratio of the crop box
143
+ aspectRatio: NaN,
144
+ // An object with the previous cropping result data
145
+ data: null,
146
+ // A selector for adding extra containers to preview
147
+ preview: '',
148
+ // Re-render the cropper when resize the window
149
+ responsive: true,
150
+ // Restore the cropped area after resize the window
151
+ restore: true,
152
+ // Check if the current image is a cross-origin image
153
+ checkCrossOrigin: true,
154
+ // Check the current image's Exif Orientation information
155
+ checkOrientation: true,
156
+ // Show the black modal
157
+ modal: true,
158
+ // Show the dashed lines for guiding
159
+ guides: true,
160
+ // Show the center indicator for guiding
161
+ center: true,
162
+ // Show the white modal to highlight the crop box
163
+ highlight: true,
164
+ // Show the grid background
165
+ background: true,
166
+ // Enable to crop the image automatically when initialize
167
+ autoCrop: true,
168
+ // Define the percentage of automatic cropping area when initializes
169
+ autoCropArea: 0.8,
170
+ // Enable to move the image
171
+ movable: true,
172
+ // Enable to rotate the image
173
+ rotatable: true,
174
+ // Enable to scale the image
175
+ scalable: true,
176
+ // Enable to zoom the image
177
+ zoomable: true,
178
+ // Enable to zoom the image by dragging touch
179
+ zoomOnTouch: true,
180
+ // Enable to zoom the image by wheeling mouse
181
+ zoomOnWheel: true,
182
+ // Define zoom ratio when zoom the image by wheeling mouse
183
+ wheelZoomRatio: 0.1,
184
+ // Enable to move the crop box
185
+ cropBoxMovable: true,
186
+ // Enable to resize the crop box
187
+ cropBoxResizable: true,
188
+ // Toggle drag mode between "crop" and "move" when click twice on the cropper
189
+ toggleDragModeOnDblclick: true,
190
+ // Size limitation
191
+ minCanvasWidth: 0,
192
+ minCanvasHeight: 0,
193
+ minCropBoxWidth: 0,
194
+ minCropBoxHeight: 0,
195
+ minContainerWidth: 200,
196
+ minContainerHeight: 100,
197
+ // Shortcuts of events
198
+ ready: null,
199
+ cropstart: null,
200
+ cropmove: null,
201
+ cropend: null,
202
+ crop: null,
203
+ zoom: null
204
+ };
205
+
206
+ var TEMPLATE = '<div class="cropper-container" touch-action="none">' + '<div class="cropper-wrap-box">' + '<div class="cropper-canvas"></div>' + '</div>' + '<div class="cropper-drag-box"></div>' + '<div class="cropper-crop-box">' + '<span class="cropper-view-box"></span>' + '<span class="cropper-dashed dashed-h"></span>' + '<span class="cropper-dashed dashed-v"></span>' + '<span class="cropper-center"></span>' + '<span class="cropper-face"></span>' + '<span class="cropper-line line-e" data-cropper-action="e"></span>' + '<span class="cropper-line line-n" data-cropper-action="n"></span>' + '<span class="cropper-line line-w" data-cropper-action="w"></span>' + '<span class="cropper-line line-s" data-cropper-action="s"></span>' + '<span class="cropper-point point-e" data-cropper-action="e"></span>' + '<span class="cropper-point point-n" data-cropper-action="n"></span>' + '<span class="cropper-point point-w" data-cropper-action="w"></span>' + '<span class="cropper-point point-s" data-cropper-action="s"></span>' + '<span class="cropper-point point-ne" data-cropper-action="ne"></span>' + '<span class="cropper-point point-nw" data-cropper-action="nw"></span>' + '<span class="cropper-point point-sw" data-cropper-action="sw"></span>' + '<span class="cropper-point point-se" data-cropper-action="se"></span>' + '</div>' + '</div>';
207
+
208
+ /**
209
+ * Check if the given value is not a number.
210
+ */
211
+
212
+ var isNaN = Number.isNaN || WINDOW.isNaN;
213
+ /**
214
+ * Check if the given value is a number.
215
+ * @param {*} value - The value to check.
216
+ * @returns {boolean} Returns `true` if the given value is a number, else `false`.
217
+ */
218
+
219
+ function isNumber(value) {
220
+ return typeof value === 'number' && !isNaN(value);
221
+ }
222
+ /**
223
+ * Check if the given value is a positive number.
224
+ * @param {*} value - The value to check.
225
+ * @returns {boolean} Returns `true` if the given value is a positive number, else `false`.
226
+ */
227
+
228
+ var isPositiveNumber = function isPositiveNumber(value) {
229
+ return value > 0 && value < Infinity;
230
+ };
231
+ /**
232
+ * Check if the given value is undefined.
233
+ * @param {*} value - The value to check.
234
+ * @returns {boolean} Returns `true` if the given value is undefined, else `false`.
235
+ */
236
+
237
+ function isUndefined(value) {
238
+ return typeof value === 'undefined';
239
+ }
240
+ /**
241
+ * Check if the given value is an object.
242
+ * @param {*} value - The value to check.
243
+ * @returns {boolean} Returns `true` if the given value is an object, else `false`.
244
+ */
245
+
246
+ function isObject(value) {
247
+ return _typeof(value) === 'object' && value !== null;
248
+ }
249
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
250
+ /**
251
+ * Check if the given value is a plain object.
252
+ * @param {*} value - The value to check.
253
+ * @returns {boolean} Returns `true` if the given value is a plain object, else `false`.
254
+ */
255
+
256
+ function isPlainObject(value) {
257
+ if (!isObject(value)) {
258
+ return false;
259
+ }
260
+
261
+ try {
262
+ var _constructor = value.constructor;
263
+ var prototype = _constructor.prototype;
264
+ return _constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf');
265
+ } catch (error) {
266
+ return false;
267
+ }
268
+ }
269
+ /**
270
+ * Check if the given value is a function.
271
+ * @param {*} value - The value to check.
272
+ * @returns {boolean} Returns `true` if the given value is a function, else `false`.
273
+ */
274
+
275
+ function isFunction(value) {
276
+ return typeof value === 'function';
277
+ }
278
+ var slice = Array.prototype.slice;
279
+ /**
280
+ * Convert array-like or iterable object to an array.
281
+ * @param {*} value - The value to convert.
282
+ * @returns {Array} Returns a new array.
283
+ */
284
+
285
+ function toArray(value) {
286
+ return Array.from ? Array.from(value) : slice.call(value);
287
+ }
288
+ /**
289
+ * Iterate the given data.
290
+ * @param {*} data - The data to iterate.
291
+ * @param {Function} callback - The process function for each element.
292
+ * @returns {*} The original data.
293
+ */
294
+
295
+ function forEach(data, callback) {
296
+ if (data && isFunction(callback)) {
297
+ if (Array.isArray(data) || isNumber(data.length)
298
+ /* array-like */
299
+ ) {
300
+ toArray(data).forEach(function (value, key) {
301
+ callback.call(data, value, key, data);
302
+ });
303
+ } else if (isObject(data)) {
304
+ Object.keys(data).forEach(function (key) {
305
+ callback.call(data, data[key], key, data);
306
+ });
307
+ }
308
+ }
309
+
310
+ return data;
311
+ }
312
+ /**
313
+ * Extend the given object.
314
+ * @param {*} target - The target object to extend.
315
+ * @param {*} args - The rest objects for merging to the target object.
316
+ * @returns {Object} The extended object.
317
+ */
318
+
319
+ var assign = Object.assign || function assign(target) {
320
+ for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
321
+ args[_key - 1] = arguments[_key];
322
+ }
323
+
324
+ if (isObject(target) && args.length > 0) {
325
+ args.forEach(function (arg) {
326
+ if (isObject(arg)) {
327
+ Object.keys(arg).forEach(function (key) {
328
+ target[key] = arg[key];
329
+ });
330
+ }
331
+ });
332
+ }
333
+
334
+ return target;
335
+ };
336
+ var REGEXP_DECIMALS = /\.\d*(?:0|9){12}\d*$/;
337
+ /**
338
+ * Normalize decimal number.
339
+ * Check out {@link http://0.30000000000000004.com/}
340
+ * @param {number} value - The value to normalize.
341
+ * @param {number} [times=100000000000] - The times for normalizing.
342
+ * @returns {number} Returns the normalized number.
343
+ */
344
+
345
+ function normalizeDecimalNumber(value) {
346
+ var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100000000000;
347
+ return REGEXP_DECIMALS.test(value) ? Math.round(value * times) / times : value;
348
+ }
349
+ var REGEXP_SUFFIX = /^width|height|left|top|marginLeft|marginTop$/;
350
+ /**
351
+ * Apply styles to the given element.
352
+ * @param {Element} element - The target element.
353
+ * @param {Object} styles - The styles for applying.
354
+ */
355
+
356
+ function setStyle(element, styles) {
357
+ var style = element.style;
358
+ forEach(styles, function (value, property) {
359
+ if (REGEXP_SUFFIX.test(property) && isNumber(value)) {
360
+ value = "".concat(value, "px");
361
+ }
362
+
363
+ style[property] = value;
364
+ });
365
+ }
366
+ /**
367
+ * Check if the given element has a special class.
368
+ * @param {Element} element - The element to check.
369
+ * @param {string} value - The class to search.
370
+ * @returns {boolean} Returns `true` if the special class was found.
371
+ */
372
+
373
+ function hasClass(element, value) {
374
+ return element.classList ? element.classList.contains(value) : element.className.indexOf(value) > -1;
375
+ }
376
+ /**
377
+ * Add classes to the given element.
378
+ * @param {Element} element - The target element.
379
+ * @param {string} value - The classes to be added.
380
+ */
381
+
382
+ function addClass(element, value) {
383
+ if (!value) {
384
+ return;
385
+ }
386
+
387
+ if (isNumber(element.length)) {
388
+ forEach(element, function (elem) {
389
+ addClass(elem, value);
390
+ });
391
+ return;
392
+ }
393
+
394
+ if (element.classList) {
395
+ element.classList.add(value);
396
+ return;
397
+ }
398
+
399
+ var className = element.className.trim();
400
+
401
+ if (!className) {
402
+ element.className = value;
403
+ } else if (className.indexOf(value) < 0) {
404
+ element.className = "".concat(className, " ").concat(value);
405
+ }
406
+ }
407
+ /**
408
+ * Remove classes from the given element.
409
+ * @param {Element} element - The target element.
410
+ * @param {string} value - The classes to be removed.
411
+ */
412
+
413
+ function removeClass(element, value) {
414
+ if (!value) {
415
+ return;
416
+ }
417
+
418
+ if (isNumber(element.length)) {
419
+ forEach(element, function (elem) {
420
+ removeClass(elem, value);
421
+ });
422
+ return;
423
+ }
424
+
425
+ if (element.classList) {
426
+ element.classList.remove(value);
427
+ return;
428
+ }
429
+
430
+ if (element.className.indexOf(value) >= 0) {
431
+ element.className = element.className.replace(value, '');
432
+ }
433
+ }
434
+ /**
435
+ * Add or remove classes from the given element.
436
+ * @param {Element} element - The target element.
437
+ * @param {string} value - The classes to be toggled.
438
+ * @param {boolean} added - Add only.
439
+ */
440
+
441
+ function toggleClass(element, value, added) {
442
+ if (!value) {
443
+ return;
444
+ }
445
+
446
+ if (isNumber(element.length)) {
447
+ forEach(element, function (elem) {
448
+ toggleClass(elem, value, added);
449
+ });
450
+ return;
451
+ } // IE10-11 doesn't support the second parameter of `classList.toggle`
452
+
453
+
454
+ if (added) {
455
+ addClass(element, value);
456
+ } else {
457
+ removeClass(element, value);
458
+ }
459
+ }
460
+ var REGEXP_CAMEL_CASE = /([a-z\d])([A-Z])/g;
461
+ /**
462
+ * Transform the given string from camelCase to kebab-case
463
+ * @param {string} value - The value to transform.
464
+ * @returns {string} The transformed value.
465
+ */
466
+
467
+ function toParamCase(value) {
468
+ return value.replace(REGEXP_CAMEL_CASE, '$1-$2').toLowerCase();
469
+ }
470
+ /**
471
+ * Get data from the given element.
472
+ * @param {Element} element - The target element.
473
+ * @param {string} name - The data key to get.
474
+ * @returns {string} The data value.
475
+ */
476
+
477
+ function getData(element, name) {
478
+ if (isObject(element[name])) {
479
+ return element[name];
480
+ }
481
+
482
+ if (element.dataset) {
483
+ return element.dataset[name];
484
+ }
485
+
486
+ return element.getAttribute("data-".concat(toParamCase(name)));
487
+ }
488
+ /**
489
+ * Set data to the given element.
490
+ * @param {Element} element - The target element.
491
+ * @param {string} name - The data key to set.
492
+ * @param {string} data - The data value.
493
+ */
494
+
495
+ function setData(element, name, data) {
496
+ if (isObject(data)) {
497
+ element[name] = data;
498
+ } else if (element.dataset) {
499
+ element.dataset[name] = data;
500
+ } else {
501
+ element.setAttribute("data-".concat(toParamCase(name)), data);
502
+ }
503
+ }
504
+ /**
505
+ * Remove data from the given element.
506
+ * @param {Element} element - The target element.
507
+ * @param {string} name - The data key to remove.
508
+ */
509
+
510
+ function removeData(element, name) {
511
+ if (isObject(element[name])) {
512
+ try {
513
+ delete element[name];
514
+ } catch (error) {
515
+ element[name] = undefined;
516
+ }
517
+ } else if (element.dataset) {
518
+ // #128 Safari not allows to delete dataset property
519
+ try {
520
+ delete element.dataset[name];
521
+ } catch (error) {
522
+ element.dataset[name] = undefined;
523
+ }
524
+ } else {
525
+ element.removeAttribute("data-".concat(toParamCase(name)));
526
+ }
527
+ }
528
+ var REGEXP_SPACES = /\s\s*/;
529
+
530
+ var onceSupported = function () {
531
+ var supported = false;
532
+
533
+ if (IS_BROWSER) {
534
+ var once = false;
535
+
536
+ var listener = function listener() {};
537
+
538
+ var options = Object.defineProperty({}, 'once', {
539
+ get: function get() {
540
+ supported = true;
541
+ return once;
542
+ },
543
+
544
+ /**
545
+ * This setter can fix a `TypeError` in strict mode
546
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only}
547
+ * @param {boolean} value - The value to set
548
+ */
549
+ set: function set(value) {
550
+ once = value;
551
+ }
552
+ });
553
+ WINDOW.addEventListener('test', listener, options);
554
+ WINDOW.removeEventListener('test', listener, options);
555
+ }
556
+
557
+ return supported;
558
+ }();
559
+ /**
560
+ * Remove event listener from the target element.
561
+ * @param {Element} element - The event target.
562
+ * @param {string} type - The event type(s).
563
+ * @param {Function} listener - The event listener.
564
+ * @param {Object} options - The event options.
565
+ */
566
+
567
+
568
+ function removeListener(element, type, listener) {
569
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
570
+ var handler = listener;
571
+ type.trim().split(REGEXP_SPACES).forEach(function (event) {
572
+ if (!onceSupported) {
573
+ var listeners = element.listeners;
574
+
575
+ if (listeners && listeners[event] && listeners[event][listener]) {
576
+ handler = listeners[event][listener];
577
+ delete listeners[event][listener];
578
+
579
+ if (Object.keys(listeners[event]).length === 0) {
580
+ delete listeners[event];
581
+ }
582
+
583
+ if (Object.keys(listeners).length === 0) {
584
+ delete element.listeners;
585
+ }
586
+ }
587
+ }
588
+
589
+ element.removeEventListener(event, handler, options);
590
+ });
591
+ }
592
+ /**
593
+ * Add event listener to the target element.
594
+ * @param {Element} element - The event target.
595
+ * @param {string} type - The event type(s).
596
+ * @param {Function} listener - The event listener.
597
+ * @param {Object} options - The event options.
598
+ */
599
+
600
+ function addListener(element, type, listener) {
601
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
602
+ var _handler = listener;
603
+ type.trim().split(REGEXP_SPACES).forEach(function (event) {
604
+ if (options.once && !onceSupported) {
605
+ var _element$listeners = element.listeners,
606
+ listeners = _element$listeners === void 0 ? {} : _element$listeners;
607
+
608
+ _handler = function handler() {
609
+ delete listeners[event][listener];
610
+ element.removeEventListener(event, _handler, options);
611
+
612
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
613
+ args[_key2] = arguments[_key2];
614
+ }
615
+
616
+ listener.apply(element, args);
617
+ };
618
+
619
+ if (!listeners[event]) {
620
+ listeners[event] = {};
621
+ }
622
+
623
+ if (listeners[event][listener]) {
624
+ element.removeEventListener(event, listeners[event][listener], options);
625
+ }
626
+
627
+ listeners[event][listener] = _handler;
628
+ element.listeners = listeners;
629
+ }
630
+
631
+ element.addEventListener(event, _handler, options);
632
+ });
633
+ }
634
+ /**
635
+ * Dispatch event on the target element.
636
+ * @param {Element} element - The event target.
637
+ * @param {string} type - The event type(s).
638
+ * @param {Object} data - The additional event data.
639
+ * @returns {boolean} Indicate if the event is default prevented or not.
640
+ */
641
+
642
+ function dispatchEvent(element, type, data) {
643
+ var event; // Event and CustomEvent on IE9-11 are global objects, not constructors
644
+
645
+ if (isFunction(Event) && isFunction(CustomEvent)) {
646
+ event = new CustomEvent(type, {
647
+ detail: data,
648
+ bubbles: true,
649
+ cancelable: true
650
+ });
651
+ } else {
652
+ event = document.createEvent('CustomEvent');
653
+ event.initCustomEvent(type, true, true, data);
654
+ }
655
+
656
+ return element.dispatchEvent(event);
657
+ }
658
+ /**
659
+ * Get the offset base on the document.
660
+ * @param {Element} element - The target element.
661
+ * @returns {Object} The offset data.
662
+ */
663
+
664
+ function getOffset(element) {
665
+ var box = element.getBoundingClientRect();
666
+ return {
667
+ left: box.left + (window.pageXOffset - document.documentElement.clientLeft),
668
+ top: box.top + (window.pageYOffset - document.documentElement.clientTop)
669
+ };
670
+ }
671
+ var location = WINDOW.location;
672
+ var REGEXP_ORIGINS = /^(\w+:)\/\/([^:/?#]*):?(\d*)/i;
673
+ /**
674
+ * Check if the given URL is a cross origin URL.
675
+ * @param {string} url - The target URL.
676
+ * @returns {boolean} Returns `true` if the given URL is a cross origin URL, else `false`.
677
+ */
678
+
679
+ function isCrossOriginURL(url) {
680
+ var parts = url.match(REGEXP_ORIGINS);
681
+ return parts !== null && (parts[1] !== location.protocol || parts[2] !== location.hostname || parts[3] !== location.port);
682
+ }
683
+ /**
684
+ * Add timestamp to the given URL.
685
+ * @param {string} url - The target URL.
686
+ * @returns {string} The result URL.
687
+ */
688
+
689
+ function addTimestamp(url) {
690
+ var timestamp = "timestamp=".concat(new Date().getTime());
691
+ return url + (url.indexOf('?') === -1 ? '?' : '&') + timestamp;
692
+ }
693
+ /**
694
+ * Get transforms base on the given object.
695
+ * @param {Object} obj - The target object.
696
+ * @returns {string} A string contains transform values.
697
+ */
698
+
699
+ function getTransforms(_ref) {
700
+ var rotate = _ref.rotate,
701
+ scaleX = _ref.scaleX,
702
+ scaleY = _ref.scaleY,
703
+ translateX = _ref.translateX,
704
+ translateY = _ref.translateY;
705
+ var values = [];
706
+
707
+ if (isNumber(translateX) && translateX !== 0) {
708
+ values.push("translateX(".concat(translateX, "px)"));
709
+ }
710
+
711
+ if (isNumber(translateY) && translateY !== 0) {
712
+ values.push("translateY(".concat(translateY, "px)"));
713
+ } // Rotate should come first before scale to match orientation transform
714
+
715
+
716
+ if (isNumber(rotate) && rotate !== 0) {
717
+ values.push("rotate(".concat(rotate, "deg)"));
718
+ }
719
+
720
+ if (isNumber(scaleX) && scaleX !== 1) {
721
+ values.push("scaleX(".concat(scaleX, ")"));
722
+ }
723
+
724
+ if (isNumber(scaleY) && scaleY !== 1) {
725
+ values.push("scaleY(".concat(scaleY, ")"));
726
+ }
727
+
728
+ var transform = values.length ? values.join(' ') : 'none';
729
+ return {
730
+ WebkitTransform: transform,
731
+ msTransform: transform,
732
+ transform: transform
733
+ };
734
+ }
735
+ /**
736
+ * Get the max ratio of a group of pointers.
737
+ * @param {string} pointers - The target pointers.
738
+ * @returns {number} The result ratio.
739
+ */
740
+
741
+ function getMaxZoomRatio(pointers) {
742
+ var pointers2 = assign({}, pointers);
743
+ var ratios = [];
744
+ forEach(pointers, function (pointer, pointerId) {
745
+ delete pointers2[pointerId];
746
+ forEach(pointers2, function (pointer2) {
747
+ var x1 = Math.abs(pointer.startX - pointer2.startX);
748
+ var y1 = Math.abs(pointer.startY - pointer2.startY);
749
+ var x2 = Math.abs(pointer.endX - pointer2.endX);
750
+ var y2 = Math.abs(pointer.endY - pointer2.endY);
751
+ var z1 = Math.sqrt(x1 * x1 + y1 * y1);
752
+ var z2 = Math.sqrt(x2 * x2 + y2 * y2);
753
+ var ratio = (z2 - z1) / z1;
754
+ ratios.push(ratio);
755
+ });
756
+ });
757
+ ratios.sort(function (a, b) {
758
+ return Math.abs(a) < Math.abs(b);
759
+ });
760
+ return ratios[0];
761
+ }
762
+ /**
763
+ * Get a pointer from an event object.
764
+ * @param {Object} event - The target event object.
765
+ * @param {boolean} endOnly - Indicates if only returns the end point coordinate or not.
766
+ * @returns {Object} The result pointer contains start and/or end point coordinates.
767
+ */
768
+
769
+ function getPointer(_ref2, endOnly) {
770
+ var pageX = _ref2.pageX,
771
+ pageY = _ref2.pageY;
772
+ var end = {
773
+ endX: pageX,
774
+ endY: pageY
775
+ };
776
+ return endOnly ? end : assign({
777
+ startX: pageX,
778
+ startY: pageY
779
+ }, end);
780
+ }
781
+ /**
782
+ * Get the center point coordinate of a group of pointers.
783
+ * @param {Object} pointers - The target pointers.
784
+ * @returns {Object} The center point coordinate.
785
+ */
786
+
787
+ function getPointersCenter(pointers) {
788
+ var pageX = 0;
789
+ var pageY = 0;
790
+ var count = 0;
791
+ forEach(pointers, function (_ref3) {
792
+ var startX = _ref3.startX,
793
+ startY = _ref3.startY;
794
+ pageX += startX;
795
+ pageY += startY;
796
+ count += 1;
797
+ });
798
+ pageX /= count;
799
+ pageY /= count;
800
+ return {
801
+ pageX: pageX,
802
+ pageY: pageY
803
+ };
804
+ }
805
+ /**
806
+ * Get the max sizes in a rectangle under the given aspect ratio.
807
+ * @param {Object} data - The original sizes.
808
+ * @param {string} [type='contain'] - The adjust type.
809
+ * @returns {Object} The result sizes.
810
+ */
811
+
812
+ function getAdjustedSizes(_ref4) // or 'cover'
813
+ {
814
+ var aspectRatio = _ref4.aspectRatio,
815
+ height = _ref4.height,
816
+ width = _ref4.width;
817
+ var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'contain';
818
+ var isValidWidth = isPositiveNumber(width);
819
+ var isValidHeight = isPositiveNumber(height);
820
+
821
+ if (isValidWidth && isValidHeight) {
822
+ var adjustedWidth = height * aspectRatio;
823
+
824
+ if (type === 'contain' && adjustedWidth > width || type === 'cover' && adjustedWidth < width) {
825
+ height = width / aspectRatio;
826
+ } else {
827
+ width = height * aspectRatio;
828
+ }
829
+ } else if (isValidWidth) {
830
+ height = width / aspectRatio;
831
+ } else if (isValidHeight) {
832
+ width = height * aspectRatio;
833
+ }
834
+
835
+ return {
836
+ width: width,
837
+ height: height
838
+ };
839
+ }
840
+ /**
841
+ * Get the new sizes of a rectangle after rotated.
842
+ * @param {Object} data - The original sizes.
843
+ * @returns {Object} The result sizes.
844
+ */
845
+
846
+ function getRotatedSizes(_ref5) {
847
+ var width = _ref5.width,
848
+ height = _ref5.height,
849
+ degree = _ref5.degree;
850
+ degree = Math.abs(degree) % 180;
851
+
852
+ if (degree === 90) {
853
+ return {
854
+ width: height,
855
+ height: width
856
+ };
857
+ }
858
+
859
+ var arc = degree % 90 * Math.PI / 180;
860
+ var sinArc = Math.sin(arc);
861
+ var cosArc = Math.cos(arc);
862
+ var newWidth = width * cosArc + height * sinArc;
863
+ var newHeight = width * sinArc + height * cosArc;
864
+ return degree > 90 ? {
865
+ width: newHeight,
866
+ height: newWidth
867
+ } : {
868
+ width: newWidth,
869
+ height: newHeight
870
+ };
871
+ }
872
+ /**
873
+ * Get a canvas which drew the given image.
874
+ * @param {HTMLImageElement} image - The image for drawing.
875
+ * @param {Object} imageData - The image data.
876
+ * @param {Object} canvasData - The canvas data.
877
+ * @param {Object} options - The options.
878
+ * @returns {HTMLCanvasElement} The result canvas.
879
+ */
880
+
881
+ function getSourceCanvas(image, _ref6, _ref7, _ref8) {
882
+ var imageAspectRatio = _ref6.aspectRatio,
883
+ imageNaturalWidth = _ref6.naturalWidth,
884
+ imageNaturalHeight = _ref6.naturalHeight,
885
+ _ref6$rotate = _ref6.rotate,
886
+ rotate = _ref6$rotate === void 0 ? 0 : _ref6$rotate,
887
+ _ref6$scaleX = _ref6.scaleX,
888
+ scaleX = _ref6$scaleX === void 0 ? 1 : _ref6$scaleX,
889
+ _ref6$scaleY = _ref6.scaleY,
890
+ scaleY = _ref6$scaleY === void 0 ? 1 : _ref6$scaleY;
891
+ var aspectRatio = _ref7.aspectRatio,
892
+ naturalWidth = _ref7.naturalWidth,
893
+ naturalHeight = _ref7.naturalHeight;
894
+ var _ref8$fillColor = _ref8.fillColor,
895
+ fillColor = _ref8$fillColor === void 0 ? 'transparent' : _ref8$fillColor,
896
+ _ref8$imageSmoothingE = _ref8.imageSmoothingEnabled,
897
+ imageSmoothingEnabled = _ref8$imageSmoothingE === void 0 ? true : _ref8$imageSmoothingE,
898
+ _ref8$imageSmoothingQ = _ref8.imageSmoothingQuality,
899
+ imageSmoothingQuality = _ref8$imageSmoothingQ === void 0 ? 'low' : _ref8$imageSmoothingQ,
900
+ _ref8$maxWidth = _ref8.maxWidth,
901
+ maxWidth = _ref8$maxWidth === void 0 ? Infinity : _ref8$maxWidth,
902
+ _ref8$maxHeight = _ref8.maxHeight,
903
+ maxHeight = _ref8$maxHeight === void 0 ? Infinity : _ref8$maxHeight,
904
+ _ref8$minWidth = _ref8.minWidth,
905
+ minWidth = _ref8$minWidth === void 0 ? 0 : _ref8$minWidth,
906
+ _ref8$minHeight = _ref8.minHeight,
907
+ minHeight = _ref8$minHeight === void 0 ? 0 : _ref8$minHeight;
908
+ var canvas = document.createElement('canvas');
909
+ var context = canvas.getContext('2d');
910
+ var maxSizes = getAdjustedSizes({
911
+ aspectRatio: aspectRatio,
912
+ width: maxWidth,
913
+ height: maxHeight
914
+ });
915
+ var minSizes = getAdjustedSizes({
916
+ aspectRatio: aspectRatio,
917
+ width: minWidth,
918
+ height: minHeight
919
+ }, 'cover');
920
+ var width = Math.min(maxSizes.width, Math.max(minSizes.width, naturalWidth));
921
+ var height = Math.min(maxSizes.height, Math.max(minSizes.height, naturalHeight)); // Note: should always use image's natural sizes for drawing as
922
+ // imageData.naturalWidth === canvasData.naturalHeight when rotate % 180 === 90
923
+
924
+ var destMaxSizes = getAdjustedSizes({
925
+ aspectRatio: imageAspectRatio,
926
+ width: maxWidth,
927
+ height: maxHeight
928
+ });
929
+ var destMinSizes = getAdjustedSizes({
930
+ aspectRatio: imageAspectRatio,
931
+ width: minWidth,
932
+ height: minHeight
933
+ }, 'cover');
934
+ var destWidth = Math.min(destMaxSizes.width, Math.max(destMinSizes.width, imageNaturalWidth));
935
+ var destHeight = Math.min(destMaxSizes.height, Math.max(destMinSizes.height, imageNaturalHeight));
936
+ var params = [-destWidth / 2, -destHeight / 2, destWidth, destHeight];
937
+ canvas.width = normalizeDecimalNumber(width);
938
+ canvas.height = normalizeDecimalNumber(height);
939
+ context.fillStyle = fillColor;
940
+ context.fillRect(0, 0, width, height);
941
+ context.save();
942
+ context.translate(width / 2, height / 2);
943
+ context.rotate(rotate * Math.PI / 180);
944
+ context.scale(scaleX, scaleY);
945
+ context.imageSmoothingEnabled = imageSmoothingEnabled;
946
+ context.imageSmoothingQuality = imageSmoothingQuality;
947
+ context.drawImage.apply(context, [image].concat(_toConsumableArray(params.map(function (param) {
948
+ return Math.floor(normalizeDecimalNumber(param));
949
+ }))));
950
+ context.restore();
951
+ return canvas;
952
+ }
953
+ var fromCharCode = String.fromCharCode;
954
+ /**
955
+ * Get string from char code in data view.
956
+ * @param {DataView} dataView - The data view for read.
957
+ * @param {number} start - The start index.
958
+ * @param {number} length - The read length.
959
+ * @returns {string} The read result.
960
+ */
961
+
962
+ function getStringFromCharCode(dataView, start, length) {
963
+ var str = '';
964
+ length += start;
965
+
966
+ for (var i = start; i < length; i += 1) {
967
+ str += fromCharCode(dataView.getUint8(i));
968
+ }
969
+
970
+ return str;
971
+ }
972
+ var REGEXP_DATA_URL_HEAD = /^data:.*,/;
973
+ /**
974
+ * Transform Data URL to array buffer.
975
+ * @param {string} dataURL - The Data URL to transform.
976
+ * @returns {ArrayBuffer} The result array buffer.
977
+ */
978
+
979
+ function dataURLToArrayBuffer(dataURL) {
980
+ var base64 = dataURL.replace(REGEXP_DATA_URL_HEAD, '');
981
+ var binary = atob(base64);
982
+ var arrayBuffer = new ArrayBuffer(binary.length);
983
+ var uint8 = new Uint8Array(arrayBuffer);
984
+ forEach(uint8, function (value, i) {
985
+ uint8[i] = binary.charCodeAt(i);
986
+ });
987
+ return arrayBuffer;
988
+ }
989
+ /**
990
+ * Transform array buffer to Data URL.
991
+ * @param {ArrayBuffer} arrayBuffer - The array buffer to transform.
992
+ * @param {string} mimeType - The mime type of the Data URL.
993
+ * @returns {string} The result Data URL.
994
+ */
995
+
996
+ function arrayBufferToDataURL(arrayBuffer, mimeType) {
997
+ var chunks = []; // Chunk Typed Array for better performance (#435)
998
+
999
+ var chunkSize = 8192;
1000
+ var uint8 = new Uint8Array(arrayBuffer);
1001
+
1002
+ while (uint8.length > 0) {
1003
+ // XXX: Babel's `toConsumableArray` helper will throw error in IE or Safari 9
1004
+ // eslint-disable-next-line prefer-spread
1005
+ chunks.push(fromCharCode.apply(null, toArray(uint8.subarray(0, chunkSize))));
1006
+ uint8 = uint8.subarray(chunkSize);
1007
+ }
1008
+
1009
+ return "data:".concat(mimeType, ";base64,").concat(btoa(chunks.join('')));
1010
+ }
1011
+ /**
1012
+ * Get orientation value from given array buffer.
1013
+ * @param {ArrayBuffer} arrayBuffer - The array buffer to read.
1014
+ * @returns {number} The read orientation value.
1015
+ */
1016
+
1017
+ function resetAndGetOrientation(arrayBuffer) {
1018
+ var dataView = new DataView(arrayBuffer);
1019
+ var orientation; // Ignores range error when the image does not have correct Exif information
1020
+
1021
+ try {
1022
+ var littleEndian;
1023
+ var app1Start;
1024
+ var ifdStart; // Only handle JPEG image (start by 0xFFD8)
1025
+
1026
+ if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) {
1027
+ var length = dataView.byteLength;
1028
+ var offset = 2;
1029
+
1030
+ while (offset + 1 < length) {
1031
+ if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) {
1032
+ app1Start = offset;
1033
+ break;
1034
+ }
1035
+
1036
+ offset += 1;
1037
+ }
1038
+ }
1039
+
1040
+ if (app1Start) {
1041
+ var exifIDCode = app1Start + 4;
1042
+ var tiffOffset = app1Start + 10;
1043
+
1044
+ if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') {
1045
+ var endianness = dataView.getUint16(tiffOffset);
1046
+ littleEndian = endianness === 0x4949;
1047
+
1048
+ if (littleEndian || endianness === 0x4D4D
1049
+ /* bigEndian */
1050
+ ) {
1051
+ if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) {
1052
+ var firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian);
1053
+
1054
+ if (firstIFDOffset >= 0x00000008) {
1055
+ ifdStart = tiffOffset + firstIFDOffset;
1056
+ }
1057
+ }
1058
+ }
1059
+ }
1060
+ }
1061
+
1062
+ if (ifdStart) {
1063
+ var _length = dataView.getUint16(ifdStart, littleEndian);
1064
+
1065
+ var _offset;
1066
+
1067
+ var i;
1068
+
1069
+ for (i = 0; i < _length; i += 1) {
1070
+ _offset = ifdStart + i * 12 + 2;
1071
+
1072
+ if (dataView.getUint16(_offset, littleEndian) === 0x0112
1073
+ /* Orientation */
1074
+ ) {
1075
+ // 8 is the offset of the current tag's value
1076
+ _offset += 8; // Get the original orientation value
1077
+
1078
+ orientation = dataView.getUint16(_offset, littleEndian); // Override the orientation with its default value
1079
+
1080
+ dataView.setUint16(_offset, 1, littleEndian);
1081
+ break;
1082
+ }
1083
+ }
1084
+ }
1085
+ } catch (error) {
1086
+ orientation = 1;
1087
+ }
1088
+
1089
+ return orientation;
1090
+ }
1091
+ /**
1092
+ * Parse Exif Orientation value.
1093
+ * @param {number} orientation - The orientation to parse.
1094
+ * @returns {Object} The parsed result.
1095
+ */
1096
+
1097
+ function parseOrientation(orientation) {
1098
+ var rotate = 0;
1099
+ var scaleX = 1;
1100
+ var scaleY = 1;
1101
+
1102
+ switch (orientation) {
1103
+ // Flip horizontal
1104
+ case 2:
1105
+ scaleX = -1;
1106
+ break;
1107
+ // Rotate left 180°
1108
+
1109
+ case 3:
1110
+ rotate = -180;
1111
+ break;
1112
+ // Flip vertical
1113
+
1114
+ case 4:
1115
+ scaleY = -1;
1116
+ break;
1117
+ // Flip vertical and rotate right 90°
1118
+
1119
+ case 5:
1120
+ rotate = 90;
1121
+ scaleY = -1;
1122
+ break;
1123
+ // Rotate right 90°
1124
+
1125
+ case 6:
1126
+ rotate = 90;
1127
+ break;
1128
+ // Flip horizontal and rotate right 90°
1129
+
1130
+ case 7:
1131
+ rotate = 90;
1132
+ scaleX = -1;
1133
+ break;
1134
+ // Rotate left 90°
1135
+
1136
+ case 8:
1137
+ rotate = -90;
1138
+ break;
1139
+
1140
+ default:
1141
+ }
1142
+
1143
+ return {
1144
+ rotate: rotate,
1145
+ scaleX: scaleX,
1146
+ scaleY: scaleY
1147
+ };
1148
+ }
1149
+
1150
+ var render = {
1151
+ render: function render() {
1152
+ this.initContainer();
1153
+ this.initCanvas();
1154
+ this.initCropBox();
1155
+ this.renderCanvas();
1156
+
1157
+ if (this.cropped) {
1158
+ this.renderCropBox();
1159
+ }
1160
+ },
1161
+ initContainer: function initContainer() {
1162
+ var element = this.element,
1163
+ options = this.options,
1164
+ container = this.container,
1165
+ cropper = this.cropper;
1166
+ addClass(cropper, CLASS_HIDDEN);
1167
+ removeClass(element, CLASS_HIDDEN);
1168
+ var containerData = {
1169
+ width: Math.max(container.offsetWidth, Number(options.minContainerWidth) || 200),
1170
+ height: Math.max(container.offsetHeight, Number(options.minContainerHeight) || 100)
1171
+ };
1172
+ this.containerData = containerData;
1173
+ setStyle(cropper, {
1174
+ width: containerData.width,
1175
+ height: containerData.height
1176
+ });
1177
+ addClass(element, CLASS_HIDDEN);
1178
+ removeClass(cropper, CLASS_HIDDEN);
1179
+ },
1180
+ // Canvas (image wrapper)
1181
+ initCanvas: function initCanvas() {
1182
+ var containerData = this.containerData,
1183
+ imageData = this.imageData;
1184
+ var viewMode = this.options.viewMode;
1185
+ var rotated = Math.abs(imageData.rotate) % 180 === 90;
1186
+ var naturalWidth = rotated ? imageData.naturalHeight : imageData.naturalWidth;
1187
+ var naturalHeight = rotated ? imageData.naturalWidth : imageData.naturalHeight;
1188
+ var aspectRatio = naturalWidth / naturalHeight;
1189
+ var canvasWidth = containerData.width;
1190
+ var canvasHeight = containerData.height;
1191
+
1192
+ if (containerData.height * aspectRatio > containerData.width) {
1193
+ if (viewMode === 3) {
1194
+ canvasWidth = containerData.height * aspectRatio;
1195
+ } else {
1196
+ canvasHeight = containerData.width / aspectRatio;
1197
+ }
1198
+ } else if (viewMode === 3) {
1199
+ canvasHeight = containerData.width / aspectRatio;
1200
+ } else {
1201
+ canvasWidth = containerData.height * aspectRatio;
1202
+ }
1203
+
1204
+ var canvasData = {
1205
+ aspectRatio: aspectRatio,
1206
+ naturalWidth: naturalWidth,
1207
+ naturalHeight: naturalHeight,
1208
+ width: canvasWidth,
1209
+ height: canvasHeight
1210
+ };
1211
+ canvasData.left = (containerData.width - canvasWidth) / 2;
1212
+ canvasData.top = (containerData.height - canvasHeight) / 2;
1213
+ canvasData.oldLeft = canvasData.left;
1214
+ canvasData.oldTop = canvasData.top;
1215
+ this.canvasData = canvasData;
1216
+ this.limited = viewMode === 1 || viewMode === 2;
1217
+ this.limitCanvas(true, true);
1218
+ this.initialImageData = assign({}, imageData);
1219
+ this.initialCanvasData = assign({}, canvasData);
1220
+ },
1221
+ limitCanvas: function limitCanvas(sizeLimited, positionLimited) {
1222
+ var options = this.options,
1223
+ containerData = this.containerData,
1224
+ canvasData = this.canvasData,
1225
+ cropBoxData = this.cropBoxData;
1226
+ var viewMode = options.viewMode;
1227
+ var aspectRatio = canvasData.aspectRatio;
1228
+ var cropped = this.cropped && cropBoxData;
1229
+
1230
+ if (sizeLimited) {
1231
+ var minCanvasWidth = Number(options.minCanvasWidth) || 0;
1232
+ var minCanvasHeight = Number(options.minCanvasHeight) || 0;
1233
+
1234
+ if (viewMode > 1) {
1235
+ minCanvasWidth = Math.max(minCanvasWidth, containerData.width);
1236
+ minCanvasHeight = Math.max(minCanvasHeight, containerData.height);
1237
+
1238
+ if (viewMode === 3) {
1239
+ if (minCanvasHeight * aspectRatio > minCanvasWidth) {
1240
+ minCanvasWidth = minCanvasHeight * aspectRatio;
1241
+ } else {
1242
+ minCanvasHeight = minCanvasWidth / aspectRatio;
1243
+ }
1244
+ }
1245
+ } else if (viewMode > 0) {
1246
+ if (minCanvasWidth) {
1247
+ minCanvasWidth = Math.max(minCanvasWidth, cropped ? cropBoxData.width : 0);
1248
+ } else if (minCanvasHeight) {
1249
+ minCanvasHeight = Math.max(minCanvasHeight, cropped ? cropBoxData.height : 0);
1250
+ } else if (cropped) {
1251
+ minCanvasWidth = cropBoxData.width;
1252
+ minCanvasHeight = cropBoxData.height;
1253
+
1254
+ if (minCanvasHeight * aspectRatio > minCanvasWidth) {
1255
+ minCanvasWidth = minCanvasHeight * aspectRatio;
1256
+ } else {
1257
+ minCanvasHeight = minCanvasWidth / aspectRatio;
1258
+ }
1259
+ }
1260
+ }
1261
+
1262
+ var _getAdjustedSizes = getAdjustedSizes({
1263
+ aspectRatio: aspectRatio,
1264
+ width: minCanvasWidth,
1265
+ height: minCanvasHeight
1266
+ });
1267
+
1268
+ minCanvasWidth = _getAdjustedSizes.width;
1269
+ minCanvasHeight = _getAdjustedSizes.height;
1270
+ canvasData.minWidth = minCanvasWidth;
1271
+ canvasData.minHeight = minCanvasHeight;
1272
+ canvasData.maxWidth = Infinity;
1273
+ canvasData.maxHeight = Infinity;
1274
+ }
1275
+
1276
+ if (positionLimited) {
1277
+ if (viewMode > (cropped ? 0 : 1)) {
1278
+ var newCanvasLeft = containerData.width - canvasData.width;
1279
+ var newCanvasTop = containerData.height - canvasData.height;
1280
+ canvasData.minLeft = Math.min(0, newCanvasLeft);
1281
+ canvasData.minTop = Math.min(0, newCanvasTop);
1282
+ canvasData.maxLeft = Math.max(0, newCanvasLeft);
1283
+ canvasData.maxTop = Math.max(0, newCanvasTop);
1284
+
1285
+ if (cropped && this.limited) {
1286
+ canvasData.minLeft = Math.min(cropBoxData.left, cropBoxData.left + (cropBoxData.width - canvasData.width));
1287
+ canvasData.minTop = Math.min(cropBoxData.top, cropBoxData.top + (cropBoxData.height - canvasData.height));
1288
+ canvasData.maxLeft = cropBoxData.left;
1289
+ canvasData.maxTop = cropBoxData.top;
1290
+
1291
+ if (viewMode === 2) {
1292
+ if (canvasData.width >= containerData.width) {
1293
+ canvasData.minLeft = Math.min(0, newCanvasLeft);
1294
+ canvasData.maxLeft = Math.max(0, newCanvasLeft);
1295
+ }
1296
+
1297
+ if (canvasData.height >= containerData.height) {
1298
+ canvasData.minTop = Math.min(0, newCanvasTop);
1299
+ canvasData.maxTop = Math.max(0, newCanvasTop);
1300
+ }
1301
+ }
1302
+ }
1303
+ } else {
1304
+ canvasData.minLeft = -canvasData.width;
1305
+ canvasData.minTop = -canvasData.height;
1306
+ canvasData.maxLeft = containerData.width;
1307
+ canvasData.maxTop = containerData.height;
1308
+ }
1309
+ }
1310
+ },
1311
+ renderCanvas: function renderCanvas(changed, transformed) {
1312
+ var canvasData = this.canvasData,
1313
+ imageData = this.imageData;
1314
+
1315
+ if (transformed) {
1316
+ var _getRotatedSizes = getRotatedSizes({
1317
+ width: imageData.naturalWidth * Math.abs(imageData.scaleX || 1),
1318
+ height: imageData.naturalHeight * Math.abs(imageData.scaleY || 1),
1319
+ degree: imageData.rotate || 0
1320
+ }),
1321
+ naturalWidth = _getRotatedSizes.width,
1322
+ naturalHeight = _getRotatedSizes.height;
1323
+
1324
+ var width = canvasData.width * (naturalWidth / canvasData.naturalWidth);
1325
+ var height = canvasData.height * (naturalHeight / canvasData.naturalHeight);
1326
+ canvasData.left -= (width - canvasData.width) / 2;
1327
+ canvasData.top -= (height - canvasData.height) / 2;
1328
+ canvasData.width = width;
1329
+ canvasData.height = height;
1330
+ canvasData.aspectRatio = naturalWidth / naturalHeight;
1331
+ canvasData.naturalWidth = naturalWidth;
1332
+ canvasData.naturalHeight = naturalHeight;
1333
+ this.limitCanvas(true, false);
1334
+ }
1335
+
1336
+ if (canvasData.width > canvasData.maxWidth || canvasData.width < canvasData.minWidth) {
1337
+ canvasData.left = canvasData.oldLeft;
1338
+ }
1339
+
1340
+ if (canvasData.height > canvasData.maxHeight || canvasData.height < canvasData.minHeight) {
1341
+ canvasData.top = canvasData.oldTop;
1342
+ }
1343
+
1344
+ canvasData.width = Math.min(Math.max(canvasData.width, canvasData.minWidth), canvasData.maxWidth);
1345
+ canvasData.height = Math.min(Math.max(canvasData.height, canvasData.minHeight), canvasData.maxHeight);
1346
+ this.limitCanvas(false, true);
1347
+ canvasData.left = Math.min(Math.max(canvasData.left, canvasData.minLeft), canvasData.maxLeft);
1348
+ canvasData.top = Math.min(Math.max(canvasData.top, canvasData.minTop), canvasData.maxTop);
1349
+ canvasData.oldLeft = canvasData.left;
1350
+ canvasData.oldTop = canvasData.top;
1351
+ setStyle(this.canvas, assign({
1352
+ width: canvasData.width,
1353
+ height: canvasData.height
1354
+ }, getTransforms({
1355
+ translateX: canvasData.left,
1356
+ translateY: canvasData.top
1357
+ })));
1358
+ this.renderImage(changed);
1359
+
1360
+ if (this.cropped && this.limited) {
1361
+ this.limitCropBox(true, true);
1362
+ }
1363
+ },
1364
+ renderImage: function renderImage(changed) {
1365
+ var canvasData = this.canvasData,
1366
+ imageData = this.imageData;
1367
+ var width = imageData.naturalWidth * (canvasData.width / canvasData.naturalWidth);
1368
+ var height = imageData.naturalHeight * (canvasData.height / canvasData.naturalHeight);
1369
+ assign(imageData, {
1370
+ width: width,
1371
+ height: height,
1372
+ left: (canvasData.width - width) / 2,
1373
+ top: (canvasData.height - height) / 2
1374
+ });
1375
+ setStyle(this.image, assign({
1376
+ width: imageData.width,
1377
+ height: imageData.height
1378
+ }, getTransforms(assign({
1379
+ translateX: imageData.left,
1380
+ translateY: imageData.top
1381
+ }, imageData))));
1382
+
1383
+ if (changed) {
1384
+ this.output();
1385
+ }
1386
+ },
1387
+ initCropBox: function initCropBox() {
1388
+ var options = this.options,
1389
+ canvasData = this.canvasData;
1390
+ var aspectRatio = options.aspectRatio || options.initialAspectRatio;
1391
+ var autoCropArea = Number(options.autoCropArea) || 0.8;
1392
+ var cropBoxData = {
1393
+ width: canvasData.width,
1394
+ height: canvasData.height
1395
+ };
1396
+
1397
+ if (aspectRatio) {
1398
+ if (canvasData.height * aspectRatio > canvasData.width) {
1399
+ cropBoxData.height = cropBoxData.width / aspectRatio;
1400
+ } else {
1401
+ cropBoxData.width = cropBoxData.height * aspectRatio;
1402
+ }
1403
+ }
1404
+
1405
+ this.cropBoxData = cropBoxData;
1406
+ this.limitCropBox(true, true); // Initialize auto crop area
1407
+
1408
+ cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth);
1409
+ cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight); // The width/height of auto crop area must large than "minWidth/Height"
1410
+
1411
+ cropBoxData.width = Math.max(cropBoxData.minWidth, cropBoxData.width * autoCropArea);
1412
+ cropBoxData.height = Math.max(cropBoxData.minHeight, cropBoxData.height * autoCropArea);
1413
+ cropBoxData.left = canvasData.left + (canvasData.width - cropBoxData.width) / 2;
1414
+ cropBoxData.top = canvasData.top + (canvasData.height - cropBoxData.height) / 2;
1415
+ cropBoxData.oldLeft = cropBoxData.left;
1416
+ cropBoxData.oldTop = cropBoxData.top;
1417
+ this.initialCropBoxData = assign({}, cropBoxData);
1418
+ },
1419
+ limitCropBox: function limitCropBox(sizeLimited, positionLimited) {
1420
+ var options = this.options,
1421
+ containerData = this.containerData,
1422
+ canvasData = this.canvasData,
1423
+ cropBoxData = this.cropBoxData,
1424
+ limited = this.limited;
1425
+ var aspectRatio = options.aspectRatio;
1426
+
1427
+ if (sizeLimited) {
1428
+ var minCropBoxWidth = Number(options.minCropBoxWidth) || 0;
1429
+ var minCropBoxHeight = Number(options.minCropBoxHeight) || 0;
1430
+ var maxCropBoxWidth = limited ? Math.min(containerData.width, canvasData.width, canvasData.width + canvasData.left, containerData.width - canvasData.left) : containerData.width;
1431
+ var maxCropBoxHeight = limited ? Math.min(containerData.height, canvasData.height, canvasData.height + canvasData.top, containerData.height - canvasData.top) : containerData.height; // The min/maxCropBoxWidth/Height must be less than container's width/height
1432
+
1433
+ minCropBoxWidth = Math.min(minCropBoxWidth, containerData.width);
1434
+ minCropBoxHeight = Math.min(minCropBoxHeight, containerData.height);
1435
+
1436
+ if (aspectRatio) {
1437
+ if (minCropBoxWidth && minCropBoxHeight) {
1438
+ if (minCropBoxHeight * aspectRatio > minCropBoxWidth) {
1439
+ minCropBoxHeight = minCropBoxWidth / aspectRatio;
1440
+ } else {
1441
+ minCropBoxWidth = minCropBoxHeight * aspectRatio;
1442
+ }
1443
+ } else if (minCropBoxWidth) {
1444
+ minCropBoxHeight = minCropBoxWidth / aspectRatio;
1445
+ } else if (minCropBoxHeight) {
1446
+ minCropBoxWidth = minCropBoxHeight * aspectRatio;
1447
+ }
1448
+
1449
+ if (maxCropBoxHeight * aspectRatio > maxCropBoxWidth) {
1450
+ maxCropBoxHeight = maxCropBoxWidth / aspectRatio;
1451
+ } else {
1452
+ maxCropBoxWidth = maxCropBoxHeight * aspectRatio;
1453
+ }
1454
+ } // The minWidth/Height must be less than maxWidth/Height
1455
+
1456
+
1457
+ cropBoxData.minWidth = Math.min(minCropBoxWidth, maxCropBoxWidth);
1458
+ cropBoxData.minHeight = Math.min(minCropBoxHeight, maxCropBoxHeight);
1459
+ cropBoxData.maxWidth = maxCropBoxWidth;
1460
+ cropBoxData.maxHeight = maxCropBoxHeight;
1461
+ }
1462
+
1463
+ if (positionLimited) {
1464
+ if (limited) {
1465
+ cropBoxData.minLeft = Math.max(0, canvasData.left);
1466
+ cropBoxData.minTop = Math.max(0, canvasData.top);
1467
+ cropBoxData.maxLeft = Math.min(containerData.width, canvasData.left + canvasData.width) - cropBoxData.width;
1468
+ cropBoxData.maxTop = Math.min(containerData.height, canvasData.top + canvasData.height) - cropBoxData.height;
1469
+ } else {
1470
+ cropBoxData.minLeft = 0;
1471
+ cropBoxData.minTop = 0;
1472
+ cropBoxData.maxLeft = containerData.width - cropBoxData.width;
1473
+ cropBoxData.maxTop = containerData.height - cropBoxData.height;
1474
+ }
1475
+ }
1476
+ },
1477
+ renderCropBox: function renderCropBox() {
1478
+ var options = this.options,
1479
+ containerData = this.containerData,
1480
+ cropBoxData = this.cropBoxData;
1481
+
1482
+ if (cropBoxData.width > cropBoxData.maxWidth || cropBoxData.width < cropBoxData.minWidth) {
1483
+ cropBoxData.left = cropBoxData.oldLeft;
1484
+ }
1485
+
1486
+ if (cropBoxData.height > cropBoxData.maxHeight || cropBoxData.height < cropBoxData.minHeight) {
1487
+ cropBoxData.top = cropBoxData.oldTop;
1488
+ }
1489
+
1490
+ cropBoxData.width = Math.min(Math.max(cropBoxData.width, cropBoxData.minWidth), cropBoxData.maxWidth);
1491
+ cropBoxData.height = Math.min(Math.max(cropBoxData.height, cropBoxData.minHeight), cropBoxData.maxHeight);
1492
+ this.limitCropBox(false, true);
1493
+ cropBoxData.left = Math.min(Math.max(cropBoxData.left, cropBoxData.minLeft), cropBoxData.maxLeft);
1494
+ cropBoxData.top = Math.min(Math.max(cropBoxData.top, cropBoxData.minTop), cropBoxData.maxTop);
1495
+ cropBoxData.oldLeft = cropBoxData.left;
1496
+ cropBoxData.oldTop = cropBoxData.top;
1497
+
1498
+ if (options.movable && options.cropBoxMovable) {
1499
+ // Turn to move the canvas when the crop box is equal to the container
1500
+ setData(this.face, DATA_ACTION, cropBoxData.width >= containerData.width && cropBoxData.height >= containerData.height ? ACTION_MOVE : ACTION_ALL);
1501
+ }
1502
+
1503
+ setStyle(this.cropBox, assign({
1504
+ width: cropBoxData.width,
1505
+ height: cropBoxData.height
1506
+ }, getTransforms({
1507
+ translateX: cropBoxData.left,
1508
+ translateY: cropBoxData.top
1509
+ })));
1510
+
1511
+ if (this.cropped && this.limited) {
1512
+ this.limitCanvas(true, true);
1513
+ }
1514
+
1515
+ if (!this.disabled) {
1516
+ this.output();
1517
+ }
1518
+ },
1519
+ output: function output() {
1520
+ this.preview();
1521
+ dispatchEvent(this.element, EVENT_CROP, this.getData());
1522
+ }
1523
+ };
1524
+
1525
+ var preview = {
1526
+ initPreview: function initPreview() {
1527
+ var crossOrigin = this.crossOrigin;
1528
+ var preview = this.options.preview;
1529
+ var url = crossOrigin ? this.crossOriginUrl : this.url;
1530
+ var image = document.createElement('img');
1531
+
1532
+ if (crossOrigin) {
1533
+ image.crossOrigin = crossOrigin;
1534
+ }
1535
+
1536
+ image.src = url;
1537
+ this.viewBox.appendChild(image);
1538
+ this.viewBoxImage = image;
1539
+
1540
+ if (!preview) {
1541
+ return;
1542
+ }
1543
+
1544
+ var previews = preview;
1545
+
1546
+ if (typeof preview === 'string') {
1547
+ previews = this.element.ownerDocument.querySelectorAll(preview);
1548
+ } else if (preview.querySelector) {
1549
+ previews = [preview];
1550
+ }
1551
+
1552
+ this.previews = previews;
1553
+ forEach(previews, function (el) {
1554
+ var img = document.createElement('img'); // Save the original size for recover
1555
+
1556
+ setData(el, DATA_PREVIEW, {
1557
+ width: el.offsetWidth,
1558
+ height: el.offsetHeight,
1559
+ html: el.innerHTML
1560
+ });
1561
+
1562
+ if (crossOrigin) {
1563
+ img.crossOrigin = crossOrigin;
1564
+ }
1565
+
1566
+ img.src = url;
1567
+ /**
1568
+ * Override img element styles
1569
+ * Add `display:block` to avoid margin top issue
1570
+ * Add `height:auto` to override `height` attribute on IE8
1571
+ * (Occur only when margin-top <= -height)
1572
+ */
1573
+
1574
+ img.style.cssText = 'display:block;' + 'width:100%;' + 'height:auto;' + 'min-width:0!important;' + 'min-height:0!important;' + 'max-width:none!important;' + 'max-height:none!important;' + 'image-orientation:0deg!important;"';
1575
+ el.innerHTML = '';
1576
+ el.appendChild(img);
1577
+ });
1578
+ },
1579
+ resetPreview: function resetPreview() {
1580
+ forEach(this.previews, function (element) {
1581
+ var data = getData(element, DATA_PREVIEW);
1582
+ setStyle(element, {
1583
+ width: data.width,
1584
+ height: data.height
1585
+ });
1586
+ element.innerHTML = data.html;
1587
+ removeData(element, DATA_PREVIEW);
1588
+ });
1589
+ },
1590
+ preview: function preview() {
1591
+ var imageData = this.imageData,
1592
+ canvasData = this.canvasData,
1593
+ cropBoxData = this.cropBoxData;
1594
+ var cropBoxWidth = cropBoxData.width,
1595
+ cropBoxHeight = cropBoxData.height;
1596
+ var width = imageData.width,
1597
+ height = imageData.height;
1598
+ var left = cropBoxData.left - canvasData.left - imageData.left;
1599
+ var top = cropBoxData.top - canvasData.top - imageData.top;
1600
+
1601
+ if (!this.cropped || this.disabled) {
1602
+ return;
1603
+ }
1604
+
1605
+ setStyle(this.viewBoxImage, assign({
1606
+ width: width,
1607
+ height: height
1608
+ }, getTransforms(assign({
1609
+ translateX: -left,
1610
+ translateY: -top
1611
+ }, imageData))));
1612
+ forEach(this.previews, function (element) {
1613
+ var data = getData(element, DATA_PREVIEW);
1614
+ var originalWidth = data.width;
1615
+ var originalHeight = data.height;
1616
+ var newWidth = originalWidth;
1617
+ var newHeight = originalHeight;
1618
+ var ratio = 1;
1619
+
1620
+ if (cropBoxWidth) {
1621
+ ratio = originalWidth / cropBoxWidth;
1622
+ newHeight = cropBoxHeight * ratio;
1623
+ }
1624
+
1625
+ if (cropBoxHeight && newHeight > originalHeight) {
1626
+ ratio = originalHeight / cropBoxHeight;
1627
+ newWidth = cropBoxWidth * ratio;
1628
+ newHeight = originalHeight;
1629
+ }
1630
+
1631
+ setStyle(element, {
1632
+ width: newWidth,
1633
+ height: newHeight
1634
+ });
1635
+ setStyle(element.getElementsByTagName('img')[0], assign({
1636
+ width: width * ratio,
1637
+ height: height * ratio
1638
+ }, getTransforms(assign({
1639
+ translateX: -left * ratio,
1640
+ translateY: -top * ratio
1641
+ }, imageData))));
1642
+ });
1643
+ }
1644
+ };
1645
+
1646
+ var events = {
1647
+ bind: function bind() {
1648
+ var element = this.element,
1649
+ options = this.options,
1650
+ cropper = this.cropper;
1651
+
1652
+ if (isFunction(options.cropstart)) {
1653
+ addListener(element, EVENT_CROP_START, options.cropstart);
1654
+ }
1655
+
1656
+ if (isFunction(options.cropmove)) {
1657
+ addListener(element, EVENT_CROP_MOVE, options.cropmove);
1658
+ }
1659
+
1660
+ if (isFunction(options.cropend)) {
1661
+ addListener(element, EVENT_CROP_END, options.cropend);
1662
+ }
1663
+
1664
+ if (isFunction(options.crop)) {
1665
+ addListener(element, EVENT_CROP, options.crop);
1666
+ }
1667
+
1668
+ if (isFunction(options.zoom)) {
1669
+ addListener(element, EVENT_ZOOM, options.zoom);
1670
+ }
1671
+
1672
+ addListener(cropper, EVENT_POINTER_DOWN, this.onCropStart = this.cropStart.bind(this));
1673
+
1674
+ if (options.zoomable && options.zoomOnWheel) {
1675
+ addListener(cropper, EVENT_WHEEL, this.onWheel = this.wheel.bind(this), {
1676
+ passive: false,
1677
+ capture: true
1678
+ });
1679
+ }
1680
+
1681
+ if (options.toggleDragModeOnDblclick) {
1682
+ addListener(cropper, EVENT_DBLCLICK, this.onDblclick = this.dblclick.bind(this));
1683
+ }
1684
+
1685
+ addListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove = this.cropMove.bind(this));
1686
+ addListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd = this.cropEnd.bind(this));
1687
+
1688
+ if (options.responsive) {
1689
+ addListener(window, EVENT_RESIZE, this.onResize = this.resize.bind(this));
1690
+ }
1691
+ },
1692
+ unbind: function unbind() {
1693
+ var element = this.element,
1694
+ options = this.options,
1695
+ cropper = this.cropper;
1696
+
1697
+ if (isFunction(options.cropstart)) {
1698
+ removeListener(element, EVENT_CROP_START, options.cropstart);
1699
+ }
1700
+
1701
+ if (isFunction(options.cropmove)) {
1702
+ removeListener(element, EVENT_CROP_MOVE, options.cropmove);
1703
+ }
1704
+
1705
+ if (isFunction(options.cropend)) {
1706
+ removeListener(element, EVENT_CROP_END, options.cropend);
1707
+ }
1708
+
1709
+ if (isFunction(options.crop)) {
1710
+ removeListener(element, EVENT_CROP, options.crop);
1711
+ }
1712
+
1713
+ if (isFunction(options.zoom)) {
1714
+ removeListener(element, EVENT_ZOOM, options.zoom);
1715
+ }
1716
+
1717
+ removeListener(cropper, EVENT_POINTER_DOWN, this.onCropStart);
1718
+
1719
+ if (options.zoomable && options.zoomOnWheel) {
1720
+ removeListener(cropper, EVENT_WHEEL, this.onWheel, {
1721
+ passive: false,
1722
+ capture: true
1723
+ });
1724
+ }
1725
+
1726
+ if (options.toggleDragModeOnDblclick) {
1727
+ removeListener(cropper, EVENT_DBLCLICK, this.onDblclick);
1728
+ }
1729
+
1730
+ removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onCropMove);
1731
+ removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onCropEnd);
1732
+
1733
+ if (options.responsive) {
1734
+ removeListener(window, EVENT_RESIZE, this.onResize);
1735
+ }
1736
+ }
1737
+ };
1738
+
1739
+ var handlers = {
1740
+ resize: function resize() {
1741
+ var options = this.options,
1742
+ container = this.container,
1743
+ containerData = this.containerData;
1744
+ var minContainerWidth = Number(options.minContainerWidth) || MIN_CONTAINER_WIDTH;
1745
+ var minContainerHeight = Number(options.minContainerHeight) || MIN_CONTAINER_HEIGHT;
1746
+
1747
+ if (this.disabled || containerData.width <= minContainerWidth || containerData.height <= minContainerHeight) {
1748
+ return;
1749
+ }
1750
+
1751
+ var ratio = container.offsetWidth / containerData.width; // Resize when width changed or height changed
1752
+
1753
+ if (ratio !== 1 || container.offsetHeight !== containerData.height) {
1754
+ var canvasData;
1755
+ var cropBoxData;
1756
+
1757
+ if (options.restore) {
1758
+ canvasData = this.getCanvasData();
1759
+ cropBoxData = this.getCropBoxData();
1760
+ }
1761
+
1762
+ this.render();
1763
+
1764
+ if (options.restore) {
1765
+ this.setCanvasData(forEach(canvasData, function (n, i) {
1766
+ canvasData[i] = n * ratio;
1767
+ }));
1768
+ this.setCropBoxData(forEach(cropBoxData, function (n, i) {
1769
+ cropBoxData[i] = n * ratio;
1770
+ }));
1771
+ }
1772
+ }
1773
+ },
1774
+ dblclick: function dblclick() {
1775
+ if (this.disabled || this.options.dragMode === DRAG_MODE_NONE) {
1776
+ return;
1777
+ }
1778
+
1779
+ this.setDragMode(hasClass(this.dragBox, CLASS_CROP) ? DRAG_MODE_MOVE : DRAG_MODE_CROP);
1780
+ },
1781
+ wheel: function wheel(event) {
1782
+ var _this = this;
1783
+
1784
+ var ratio = Number(this.options.wheelZoomRatio) || 0.1;
1785
+ var delta = 1;
1786
+
1787
+ if (this.disabled) {
1788
+ return;
1789
+ }
1790
+
1791
+ event.preventDefault(); // Limit wheel speed to prevent zoom too fast (#21)
1792
+
1793
+ if (this.wheeling) {
1794
+ return;
1795
+ }
1796
+
1797
+ this.wheeling = true;
1798
+ setTimeout(function () {
1799
+ _this.wheeling = false;
1800
+ }, 50);
1801
+
1802
+ if (event.deltaY) {
1803
+ delta = event.deltaY > 0 ? 1 : -1;
1804
+ } else if (event.wheelDelta) {
1805
+ delta = -event.wheelDelta / 120;
1806
+ } else if (event.detail) {
1807
+ delta = event.detail > 0 ? 1 : -1;
1808
+ }
1809
+
1810
+ this.zoom(-delta * ratio, event);
1811
+ },
1812
+ cropStart: function cropStart(event) {
1813
+ var buttons = event.buttons,
1814
+ button = event.button;
1815
+
1816
+ if (this.disabled // No primary button (Usually the left button)
1817
+ // Note that touch events have no `buttons` or `button` property
1818
+ || isNumber(buttons) && buttons !== 1 || isNumber(button) && button !== 0 // Open context menu
1819
+ || event.ctrlKey) {
1820
+ return;
1821
+ }
1822
+
1823
+ var options = this.options,
1824
+ pointers = this.pointers;
1825
+ var action;
1826
+
1827
+ if (event.changedTouches) {
1828
+ // Handle touch event
1829
+ forEach(event.changedTouches, function (touch) {
1830
+ pointers[touch.identifier] = getPointer(touch);
1831
+ });
1832
+ } else {
1833
+ // Handle mouse event and pointer event
1834
+ pointers[event.pointerId || 0] = getPointer(event);
1835
+ }
1836
+
1837
+ if (Object.keys(pointers).length > 1 && options.zoomable && options.zoomOnTouch) {
1838
+ action = ACTION_ZOOM;
1839
+ } else {
1840
+ action = getData(event.target, DATA_ACTION);
1841
+ }
1842
+
1843
+ if (!REGEXP_ACTIONS.test(action)) {
1844
+ return;
1845
+ }
1846
+
1847
+ if (dispatchEvent(this.element, EVENT_CROP_START, {
1848
+ originalEvent: event,
1849
+ action: action
1850
+ }) === false) {
1851
+ return;
1852
+ } // This line is required for preventing page zooming in iOS browsers
1853
+
1854
+
1855
+ event.preventDefault();
1856
+ this.action = action;
1857
+ this.cropping = false;
1858
+
1859
+ if (action === ACTION_CROP) {
1860
+ this.cropping = true;
1861
+ addClass(this.dragBox, CLASS_MODAL);
1862
+ }
1863
+ },
1864
+ cropMove: function cropMove(event) {
1865
+ var action = this.action;
1866
+
1867
+ if (this.disabled || !action) {
1868
+ return;
1869
+ }
1870
+
1871
+ var pointers = this.pointers;
1872
+ event.preventDefault();
1873
+
1874
+ if (dispatchEvent(this.element, EVENT_CROP_MOVE, {
1875
+ originalEvent: event,
1876
+ action: action
1877
+ }) === false) {
1878
+ return;
1879
+ }
1880
+
1881
+ if (event.changedTouches) {
1882
+ forEach(event.changedTouches, function (touch) {
1883
+ // The first parameter should not be undefined (#432)
1884
+ assign(pointers[touch.identifier] || {}, getPointer(touch, true));
1885
+ });
1886
+ } else {
1887
+ assign(pointers[event.pointerId || 0] || {}, getPointer(event, true));
1888
+ }
1889
+
1890
+ this.change(event);
1891
+ },
1892
+ cropEnd: function cropEnd(event) {
1893
+ if (this.disabled) {
1894
+ return;
1895
+ }
1896
+
1897
+ var action = this.action,
1898
+ pointers = this.pointers;
1899
+
1900
+ if (event.changedTouches) {
1901
+ forEach(event.changedTouches, function (touch) {
1902
+ delete pointers[touch.identifier];
1903
+ });
1904
+ } else {
1905
+ delete pointers[event.pointerId || 0];
1906
+ }
1907
+
1908
+ if (!action) {
1909
+ return;
1910
+ }
1911
+
1912
+ event.preventDefault();
1913
+
1914
+ if (!Object.keys(pointers).length) {
1915
+ this.action = '';
1916
+ }
1917
+
1918
+ if (this.cropping) {
1919
+ this.cropping = false;
1920
+ toggleClass(this.dragBox, CLASS_MODAL, this.cropped && this.options.modal);
1921
+ }
1922
+
1923
+ dispatchEvent(this.element, EVENT_CROP_END, {
1924
+ originalEvent: event,
1925
+ action: action
1926
+ });
1927
+ }
1928
+ };
1929
+
1930
+ var change = {
1931
+ change: function change(event) {
1932
+ var options = this.options,
1933
+ canvasData = this.canvasData,
1934
+ containerData = this.containerData,
1935
+ cropBoxData = this.cropBoxData,
1936
+ pointers = this.pointers;
1937
+ var action = this.action;
1938
+ var aspectRatio = options.aspectRatio;
1939
+ var left = cropBoxData.left,
1940
+ top = cropBoxData.top,
1941
+ width = cropBoxData.width,
1942
+ height = cropBoxData.height;
1943
+ var right = left + width;
1944
+ var bottom = top + height;
1945
+ var minLeft = 0;
1946
+ var minTop = 0;
1947
+ var maxWidth = containerData.width;
1948
+ var maxHeight = containerData.height;
1949
+ var renderable = true;
1950
+ var offset; // Locking aspect ratio in "free mode" by holding shift key
1951
+
1952
+ if (!aspectRatio && event.shiftKey) {
1953
+ aspectRatio = width && height ? width / height : 1;
1954
+ }
1955
+
1956
+ if (this.limited) {
1957
+ minLeft = cropBoxData.minLeft;
1958
+ minTop = cropBoxData.minTop;
1959
+ maxWidth = minLeft + Math.min(containerData.width, canvasData.width, canvasData.left + canvasData.width);
1960
+ maxHeight = minTop + Math.min(containerData.height, canvasData.height, canvasData.top + canvasData.height);
1961
+ }
1962
+
1963
+ var pointer = pointers[Object.keys(pointers)[0]];
1964
+ var range = {
1965
+ x: pointer.endX - pointer.startX,
1966
+ y: pointer.endY - pointer.startY
1967
+ };
1968
+
1969
+ var check = function check(side) {
1970
+ switch (side) {
1971
+ case ACTION_EAST:
1972
+ if (right + range.x > maxWidth) {
1973
+ range.x = maxWidth - right;
1974
+ }
1975
+
1976
+ break;
1977
+
1978
+ case ACTION_WEST:
1979
+ if (left + range.x < minLeft) {
1980
+ range.x = minLeft - left;
1981
+ }
1982
+
1983
+ break;
1984
+
1985
+ case ACTION_NORTH:
1986
+ if (top + range.y < minTop) {
1987
+ range.y = minTop - top;
1988
+ }
1989
+
1990
+ break;
1991
+
1992
+ case ACTION_SOUTH:
1993
+ if (bottom + range.y > maxHeight) {
1994
+ range.y = maxHeight - bottom;
1995
+ }
1996
+
1997
+ break;
1998
+
1999
+ default:
2000
+ }
2001
+ };
2002
+
2003
+ switch (action) {
2004
+ // Move crop box
2005
+ case ACTION_ALL:
2006
+ left += range.x;
2007
+ top += range.y;
2008
+ break;
2009
+ // Resize crop box
2010
+
2011
+ case ACTION_EAST:
2012
+ if (range.x >= 0 && (right >= maxWidth || aspectRatio && (top <= minTop || bottom >= maxHeight))) {
2013
+ renderable = false;
2014
+ break;
2015
+ }
2016
+
2017
+ check(ACTION_EAST);
2018
+ width += range.x;
2019
+
2020
+ if (width < 0) {
2021
+ action = ACTION_WEST;
2022
+ width = -width;
2023
+ left -= width;
2024
+ }
2025
+
2026
+ if (aspectRatio) {
2027
+ height = width / aspectRatio;
2028
+ top += (cropBoxData.height - height) / 2;
2029
+ }
2030
+
2031
+ break;
2032
+
2033
+ case ACTION_NORTH:
2034
+ if (range.y <= 0 && (top <= minTop || aspectRatio && (left <= minLeft || right >= maxWidth))) {
2035
+ renderable = false;
2036
+ break;
2037
+ }
2038
+
2039
+ check(ACTION_NORTH);
2040
+ height -= range.y;
2041
+ top += range.y;
2042
+
2043
+ if (height < 0) {
2044
+ action = ACTION_SOUTH;
2045
+ height = -height;
2046
+ top -= height;
2047
+ }
2048
+
2049
+ if (aspectRatio) {
2050
+ width = height * aspectRatio;
2051
+ left += (cropBoxData.width - width) / 2;
2052
+ }
2053
+
2054
+ break;
2055
+
2056
+ case ACTION_WEST:
2057
+ if (range.x <= 0 && (left <= minLeft || aspectRatio && (top <= minTop || bottom >= maxHeight))) {
2058
+ renderable = false;
2059
+ break;
2060
+ }
2061
+
2062
+ check(ACTION_WEST);
2063
+ width -= range.x;
2064
+ left += range.x;
2065
+
2066
+ if (width < 0) {
2067
+ action = ACTION_EAST;
2068
+ width = -width;
2069
+ left -= width;
2070
+ }
2071
+
2072
+ if (aspectRatio) {
2073
+ height = width / aspectRatio;
2074
+ top += (cropBoxData.height - height) / 2;
2075
+ }
2076
+
2077
+ break;
2078
+
2079
+ case ACTION_SOUTH:
2080
+ if (range.y >= 0 && (bottom >= maxHeight || aspectRatio && (left <= minLeft || right >= maxWidth))) {
2081
+ renderable = false;
2082
+ break;
2083
+ }
2084
+
2085
+ check(ACTION_SOUTH);
2086
+ height += range.y;
2087
+
2088
+ if (height < 0) {
2089
+ action = ACTION_NORTH;
2090
+ height = -height;
2091
+ top -= height;
2092
+ }
2093
+
2094
+ if (aspectRatio) {
2095
+ width = height * aspectRatio;
2096
+ left += (cropBoxData.width - width) / 2;
2097
+ }
2098
+
2099
+ break;
2100
+
2101
+ case ACTION_NORTH_EAST:
2102
+ if (aspectRatio) {
2103
+ if (range.y <= 0 && (top <= minTop || right >= maxWidth)) {
2104
+ renderable = false;
2105
+ break;
2106
+ }
2107
+
2108
+ check(ACTION_NORTH);
2109
+ height -= range.y;
2110
+ top += range.y;
2111
+ width = height * aspectRatio;
2112
+ } else {
2113
+ check(ACTION_NORTH);
2114
+ check(ACTION_EAST);
2115
+
2116
+ if (range.x >= 0) {
2117
+ if (right < maxWidth) {
2118
+ width += range.x;
2119
+ } else if (range.y <= 0 && top <= minTop) {
2120
+ renderable = false;
2121
+ }
2122
+ } else {
2123
+ width += range.x;
2124
+ }
2125
+
2126
+ if (range.y <= 0) {
2127
+ if (top > minTop) {
2128
+ height -= range.y;
2129
+ top += range.y;
2130
+ }
2131
+ } else {
2132
+ height -= range.y;
2133
+ top += range.y;
2134
+ }
2135
+ }
2136
+
2137
+ if (width < 0 && height < 0) {
2138
+ action = ACTION_SOUTH_WEST;
2139
+ height = -height;
2140
+ width = -width;
2141
+ top -= height;
2142
+ left -= width;
2143
+ } else if (width < 0) {
2144
+ action = ACTION_NORTH_WEST;
2145
+ width = -width;
2146
+ left -= width;
2147
+ } else if (height < 0) {
2148
+ action = ACTION_SOUTH_EAST;
2149
+ height = -height;
2150
+ top -= height;
2151
+ }
2152
+
2153
+ break;
2154
+
2155
+ case ACTION_NORTH_WEST:
2156
+ if (aspectRatio) {
2157
+ if (range.y <= 0 && (top <= minTop || left <= minLeft)) {
2158
+ renderable = false;
2159
+ break;
2160
+ }
2161
+
2162
+ check(ACTION_NORTH);
2163
+ height -= range.y;
2164
+ top += range.y;
2165
+ width = height * aspectRatio;
2166
+ left += cropBoxData.width - width;
2167
+ } else {
2168
+ check(ACTION_NORTH);
2169
+ check(ACTION_WEST);
2170
+
2171
+ if (range.x <= 0) {
2172
+ if (left > minLeft) {
2173
+ width -= range.x;
2174
+ left += range.x;
2175
+ } else if (range.y <= 0 && top <= minTop) {
2176
+ renderable = false;
2177
+ }
2178
+ } else {
2179
+ width -= range.x;
2180
+ left += range.x;
2181
+ }
2182
+
2183
+ if (range.y <= 0) {
2184
+ if (top > minTop) {
2185
+ height -= range.y;
2186
+ top += range.y;
2187
+ }
2188
+ } else {
2189
+ height -= range.y;
2190
+ top += range.y;
2191
+ }
2192
+ }
2193
+
2194
+ if (width < 0 && height < 0) {
2195
+ action = ACTION_SOUTH_EAST;
2196
+ height = -height;
2197
+ width = -width;
2198
+ top -= height;
2199
+ left -= width;
2200
+ } else if (width < 0) {
2201
+ action = ACTION_NORTH_EAST;
2202
+ width = -width;
2203
+ left -= width;
2204
+ } else if (height < 0) {
2205
+ action = ACTION_SOUTH_WEST;
2206
+ height = -height;
2207
+ top -= height;
2208
+ }
2209
+
2210
+ break;
2211
+
2212
+ case ACTION_SOUTH_WEST:
2213
+ if (aspectRatio) {
2214
+ if (range.x <= 0 && (left <= minLeft || bottom >= maxHeight)) {
2215
+ renderable = false;
2216
+ break;
2217
+ }
2218
+
2219
+ check(ACTION_WEST);
2220
+ width -= range.x;
2221
+ left += range.x;
2222
+ height = width / aspectRatio;
2223
+ } else {
2224
+ check(ACTION_SOUTH);
2225
+ check(ACTION_WEST);
2226
+
2227
+ if (range.x <= 0) {
2228
+ if (left > minLeft) {
2229
+ width -= range.x;
2230
+ left += range.x;
2231
+ } else if (range.y >= 0 && bottom >= maxHeight) {
2232
+ renderable = false;
2233
+ }
2234
+ } else {
2235
+ width -= range.x;
2236
+ left += range.x;
2237
+ }
2238
+
2239
+ if (range.y >= 0) {
2240
+ if (bottom < maxHeight) {
2241
+ height += range.y;
2242
+ }
2243
+ } else {
2244
+ height += range.y;
2245
+ }
2246
+ }
2247
+
2248
+ if (width < 0 && height < 0) {
2249
+ action = ACTION_NORTH_EAST;
2250
+ height = -height;
2251
+ width = -width;
2252
+ top -= height;
2253
+ left -= width;
2254
+ } else if (width < 0) {
2255
+ action = ACTION_SOUTH_EAST;
2256
+ width = -width;
2257
+ left -= width;
2258
+ } else if (height < 0) {
2259
+ action = ACTION_NORTH_WEST;
2260
+ height = -height;
2261
+ top -= height;
2262
+ }
2263
+
2264
+ break;
2265
+
2266
+ case ACTION_SOUTH_EAST:
2267
+ if (aspectRatio) {
2268
+ if (range.x >= 0 && (right >= maxWidth || bottom >= maxHeight)) {
2269
+ renderable = false;
2270
+ break;
2271
+ }
2272
+
2273
+ check(ACTION_EAST);
2274
+ width += range.x;
2275
+ height = width / aspectRatio;
2276
+ } else {
2277
+ check(ACTION_SOUTH);
2278
+ check(ACTION_EAST);
2279
+
2280
+ if (range.x >= 0) {
2281
+ if (right < maxWidth) {
2282
+ width += range.x;
2283
+ } else if (range.y >= 0 && bottom >= maxHeight) {
2284
+ renderable = false;
2285
+ }
2286
+ } else {
2287
+ width += range.x;
2288
+ }
2289
+
2290
+ if (range.y >= 0) {
2291
+ if (bottom < maxHeight) {
2292
+ height += range.y;
2293
+ }
2294
+ } else {
2295
+ height += range.y;
2296
+ }
2297
+ }
2298
+
2299
+ if (width < 0 && height < 0) {
2300
+ action = ACTION_NORTH_WEST;
2301
+ height = -height;
2302
+ width = -width;
2303
+ top -= height;
2304
+ left -= width;
2305
+ } else if (width < 0) {
2306
+ action = ACTION_SOUTH_WEST;
2307
+ width = -width;
2308
+ left -= width;
2309
+ } else if (height < 0) {
2310
+ action = ACTION_NORTH_EAST;
2311
+ height = -height;
2312
+ top -= height;
2313
+ }
2314
+
2315
+ break;
2316
+ // Move canvas
2317
+
2318
+ case ACTION_MOVE:
2319
+ this.move(range.x, range.y);
2320
+ renderable = false;
2321
+ break;
2322
+ // Zoom canvas
2323
+
2324
+ case ACTION_ZOOM:
2325
+ this.zoom(getMaxZoomRatio(pointers), event);
2326
+ renderable = false;
2327
+ break;
2328
+ // Create crop box
2329
+
2330
+ case ACTION_CROP:
2331
+ if (!range.x || !range.y) {
2332
+ renderable = false;
2333
+ break;
2334
+ }
2335
+
2336
+ offset = getOffset(this.cropper);
2337
+ left = pointer.startX - offset.left;
2338
+ top = pointer.startY - offset.top;
2339
+ width = cropBoxData.minWidth;
2340
+ height = cropBoxData.minHeight;
2341
+
2342
+ if (range.x > 0) {
2343
+ action = range.y > 0 ? ACTION_SOUTH_EAST : ACTION_NORTH_EAST;
2344
+ } else if (range.x < 0) {
2345
+ left -= width;
2346
+ action = range.y > 0 ? ACTION_SOUTH_WEST : ACTION_NORTH_WEST;
2347
+ }
2348
+
2349
+ if (range.y < 0) {
2350
+ top -= height;
2351
+ } // Show the crop box if is hidden
2352
+
2353
+
2354
+ if (!this.cropped) {
2355
+ removeClass(this.cropBox, CLASS_HIDDEN);
2356
+ this.cropped = true;
2357
+
2358
+ if (this.limited) {
2359
+ this.limitCropBox(true, true);
2360
+ }
2361
+ }
2362
+
2363
+ break;
2364
+
2365
+ default:
2366
+ }
2367
+
2368
+ if (renderable) {
2369
+ cropBoxData.width = width;
2370
+ cropBoxData.height = height;
2371
+ cropBoxData.left = left;
2372
+ cropBoxData.top = top;
2373
+ this.action = action;
2374
+ this.renderCropBox();
2375
+ } // Override
2376
+
2377
+
2378
+ forEach(pointers, function (p) {
2379
+ p.startX = p.endX;
2380
+ p.startY = p.endY;
2381
+ });
2382
+ }
2383
+ };
2384
+
2385
+ var methods = {
2386
+ // Show the crop box manually
2387
+ crop: function crop() {
2388
+ if (this.ready && !this.cropped && !this.disabled) {
2389
+ this.cropped = true;
2390
+ this.limitCropBox(true, true);
2391
+
2392
+ if (this.options.modal) {
2393
+ addClass(this.dragBox, CLASS_MODAL);
2394
+ }
2395
+
2396
+ removeClass(this.cropBox, CLASS_HIDDEN);
2397
+ this.setCropBoxData(this.initialCropBoxData);
2398
+ }
2399
+
2400
+ return this;
2401
+ },
2402
+ // Reset the image and crop box to their initial states
2403
+ reset: function reset() {
2404
+ if (this.ready && !this.disabled) {
2405
+ this.imageData = assign({}, this.initialImageData);
2406
+ this.canvasData = assign({}, this.initialCanvasData);
2407
+ this.cropBoxData = assign({}, this.initialCropBoxData);
2408
+ this.renderCanvas();
2409
+
2410
+ if (this.cropped) {
2411
+ this.renderCropBox();
2412
+ }
2413
+ }
2414
+
2415
+ return this;
2416
+ },
2417
+ // Clear the crop box
2418
+ clear: function clear() {
2419
+ if (this.cropped && !this.disabled) {
2420
+ assign(this.cropBoxData, {
2421
+ left: 0,
2422
+ top: 0,
2423
+ width: 0,
2424
+ height: 0
2425
+ });
2426
+ this.cropped = false;
2427
+ this.renderCropBox();
2428
+ this.limitCanvas(true, true); // Render canvas after crop box rendered
2429
+
2430
+ this.renderCanvas();
2431
+ removeClass(this.dragBox, CLASS_MODAL);
2432
+ addClass(this.cropBox, CLASS_HIDDEN);
2433
+ }
2434
+
2435
+ return this;
2436
+ },
2437
+
2438
+ /**
2439
+ * Replace the image's src and rebuild the cropper
2440
+ * @param {string} url - The new URL.
2441
+ * @param {boolean} [hasSameSize] - Indicate if the new image has the same size as the old one.
2442
+ * @returns {Cropper} this
2443
+ */
2444
+ replace: function replace(url) {
2445
+ var hasSameSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
2446
+
2447
+ if (!this.disabled && url) {
2448
+ if (this.isImg) {
2449
+ this.element.src = url;
2450
+ }
2451
+
2452
+ if (hasSameSize) {
2453
+ this.url = url;
2454
+ this.image.src = url;
2455
+
2456
+ if (this.ready) {
2457
+ this.viewBoxImage.src = url;
2458
+ forEach(this.previews, function (element) {
2459
+ element.getElementsByTagName('img')[0].src = url;
2460
+ });
2461
+ }
2462
+ } else {
2463
+ if (this.isImg) {
2464
+ this.replaced = true;
2465
+ }
2466
+
2467
+ this.options.data = null;
2468
+ this.uncreate();
2469
+ this.load(url);
2470
+ }
2471
+ }
2472
+
2473
+ return this;
2474
+ },
2475
+ // Enable (unfreeze) the cropper
2476
+ enable: function enable() {
2477
+ if (this.ready && this.disabled) {
2478
+ this.disabled = false;
2479
+ removeClass(this.cropper, CLASS_DISABLED);
2480
+ }
2481
+
2482
+ return this;
2483
+ },
2484
+ // Disable (freeze) the cropper
2485
+ disable: function disable() {
2486
+ if (this.ready && !this.disabled) {
2487
+ this.disabled = true;
2488
+ addClass(this.cropper, CLASS_DISABLED);
2489
+ }
2490
+
2491
+ return this;
2492
+ },
2493
+
2494
+ /**
2495
+ * Destroy the cropper and remove the instance from the image
2496
+ * @returns {Cropper} this
2497
+ */
2498
+ destroy: function destroy() {
2499
+ var element = this.element;
2500
+
2501
+ if (!element[NAMESPACE]) {
2502
+ return this;
2503
+ }
2504
+
2505
+ element[NAMESPACE] = undefined;
2506
+
2507
+ if (this.isImg && this.replaced) {
2508
+ element.src = this.originalUrl;
2509
+ }
2510
+
2511
+ this.uncreate();
2512
+ return this;
2513
+ },
2514
+
2515
+ /**
2516
+ * Move the canvas with relative offsets
2517
+ * @param {number} offsetX - The relative offset distance on the x-axis.
2518
+ * @param {number} [offsetY=offsetX] - The relative offset distance on the y-axis.
2519
+ * @returns {Cropper} this
2520
+ */
2521
+ move: function move(offsetX) {
2522
+ var offsetY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : offsetX;
2523
+ var _this$canvasData = this.canvasData,
2524
+ left = _this$canvasData.left,
2525
+ top = _this$canvasData.top;
2526
+ return this.moveTo(isUndefined(offsetX) ? offsetX : left + Number(offsetX), isUndefined(offsetY) ? offsetY : top + Number(offsetY));
2527
+ },
2528
+
2529
+ /**
2530
+ * Move the canvas to an absolute point
2531
+ * @param {number} x - The x-axis coordinate.
2532
+ * @param {number} [y=x] - The y-axis coordinate.
2533
+ * @returns {Cropper} this
2534
+ */
2535
+ moveTo: function moveTo(x) {
2536
+ var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x;
2537
+ var canvasData = this.canvasData;
2538
+ var changed = false;
2539
+ x = Number(x);
2540
+ y = Number(y);
2541
+
2542
+ if (this.ready && !this.disabled && this.options.movable) {
2543
+ if (isNumber(x)) {
2544
+ canvasData.left = x;
2545
+ changed = true;
2546
+ }
2547
+
2548
+ if (isNumber(y)) {
2549
+ canvasData.top = y;
2550
+ changed = true;
2551
+ }
2552
+
2553
+ if (changed) {
2554
+ this.renderCanvas(true);
2555
+ }
2556
+ }
2557
+
2558
+ return this;
2559
+ },
2560
+
2561
+ /**
2562
+ * Zoom the canvas with a relative ratio
2563
+ * @param {number} ratio - The target ratio.
2564
+ * @param {Event} _originalEvent - The original event if any.
2565
+ * @returns {Cropper} this
2566
+ */
2567
+ zoom: function zoom(ratio, _originalEvent) {
2568
+ var canvasData = this.canvasData;
2569
+ ratio = Number(ratio);
2570
+
2571
+ if (ratio < 0) {
2572
+ ratio = 1 / (1 - ratio);
2573
+ } else {
2574
+ ratio = 1 + ratio;
2575
+ }
2576
+
2577
+ return this.zoomTo(canvasData.width * ratio / canvasData.naturalWidth, null, _originalEvent);
2578
+ },
2579
+
2580
+ /**
2581
+ * Zoom the canvas to an absolute ratio
2582
+ * @param {number} ratio - The target ratio.
2583
+ * @param {Object} pivot - The zoom pivot point coordinate.
2584
+ * @param {Event} _originalEvent - The original event if any.
2585
+ * @returns {Cropper} this
2586
+ */
2587
+ zoomTo: function zoomTo(ratio, pivot, _originalEvent) {
2588
+ var options = this.options,
2589
+ canvasData = this.canvasData;
2590
+ var width = canvasData.width,
2591
+ height = canvasData.height,
2592
+ naturalWidth = canvasData.naturalWidth,
2593
+ naturalHeight = canvasData.naturalHeight;
2594
+ ratio = Number(ratio);
2595
+
2596
+ if (ratio >= 0 && this.ready && !this.disabled && options.zoomable) {
2597
+ var newWidth = naturalWidth * ratio;
2598
+ var newHeight = naturalHeight * ratio;
2599
+
2600
+ if (dispatchEvent(this.element, EVENT_ZOOM, {
2601
+ ratio: ratio,
2602
+ oldRatio: width / naturalWidth,
2603
+ originalEvent: _originalEvent
2604
+ }) === false) {
2605
+ return this;
2606
+ }
2607
+
2608
+ if (_originalEvent) {
2609
+ var pointers = this.pointers;
2610
+ var offset = getOffset(this.cropper);
2611
+ var center = pointers && Object.keys(pointers).length ? getPointersCenter(pointers) : {
2612
+ pageX: _originalEvent.pageX,
2613
+ pageY: _originalEvent.pageY
2614
+ }; // Zoom from the triggering point of the event
2615
+
2616
+ canvasData.left -= (newWidth - width) * ((center.pageX - offset.left - canvasData.left) / width);
2617
+ canvasData.top -= (newHeight - height) * ((center.pageY - offset.top - canvasData.top) / height);
2618
+ } else if (isPlainObject(pivot) && isNumber(pivot.x) && isNumber(pivot.y)) {
2619
+ canvasData.left -= (newWidth - width) * ((pivot.x - canvasData.left) / width);
2620
+ canvasData.top -= (newHeight - height) * ((pivot.y - canvasData.top) / height);
2621
+ } else {
2622
+ // Zoom from the center of the canvas
2623
+ canvasData.left -= (newWidth - width) / 2;
2624
+ canvasData.top -= (newHeight - height) / 2;
2625
+ }
2626
+
2627
+ canvasData.width = newWidth;
2628
+ canvasData.height = newHeight;
2629
+ this.renderCanvas(true);
2630
+ }
2631
+
2632
+ return this;
2633
+ },
2634
+
2635
+ /**
2636
+ * Rotate the canvas with a relative degree
2637
+ * @param {number} degree - The rotate degree.
2638
+ * @returns {Cropper} this
2639
+ */
2640
+ rotate: function rotate(degree) {
2641
+ return this.rotateTo((this.imageData.rotate || 0) + Number(degree));
2642
+ },
2643
+
2644
+ /**
2645
+ * Rotate the canvas to an absolute degree
2646
+ * @param {number} degree - The rotate degree.
2647
+ * @returns {Cropper} this
2648
+ */
2649
+ rotateTo: function rotateTo(degree) {
2650
+ degree = Number(degree);
2651
+
2652
+ if (isNumber(degree) && this.ready && !this.disabled && this.options.rotatable) {
2653
+ this.imageData.rotate = degree % 360;
2654
+ this.renderCanvas(true, true);
2655
+ }
2656
+
2657
+ return this;
2658
+ },
2659
+
2660
+ /**
2661
+ * Scale the image on the x-axis.
2662
+ * @param {number} scaleX - The scale ratio on the x-axis.
2663
+ * @returns {Cropper} this
2664
+ */
2665
+ scaleX: function scaleX(_scaleX) {
2666
+ var scaleY = this.imageData.scaleY;
2667
+ return this.scale(_scaleX, isNumber(scaleY) ? scaleY : 1);
2668
+ },
2669
+
2670
+ /**
2671
+ * Scale the image on the y-axis.
2672
+ * @param {number} scaleY - The scale ratio on the y-axis.
2673
+ * @returns {Cropper} this
2674
+ */
2675
+ scaleY: function scaleY(_scaleY) {
2676
+ var scaleX = this.imageData.scaleX;
2677
+ return this.scale(isNumber(scaleX) ? scaleX : 1, _scaleY);
2678
+ },
2679
+
2680
+ /**
2681
+ * Scale the image
2682
+ * @param {number} scaleX - The scale ratio on the x-axis.
2683
+ * @param {number} [scaleY=scaleX] - The scale ratio on the y-axis.
2684
+ * @returns {Cropper} this
2685
+ */
2686
+ scale: function scale(scaleX) {
2687
+ var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX;
2688
+ var imageData = this.imageData;
2689
+ var transformed = false;
2690
+ scaleX = Number(scaleX);
2691
+ scaleY = Number(scaleY);
2692
+
2693
+ if (this.ready && !this.disabled && this.options.scalable) {
2694
+ if (isNumber(scaleX)) {
2695
+ imageData.scaleX = scaleX;
2696
+ transformed = true;
2697
+ }
2698
+
2699
+ if (isNumber(scaleY)) {
2700
+ imageData.scaleY = scaleY;
2701
+ transformed = true;
2702
+ }
2703
+
2704
+ if (transformed) {
2705
+ this.renderCanvas(true, true);
2706
+ }
2707
+ }
2708
+
2709
+ return this;
2710
+ },
2711
+
2712
+ /**
2713
+ * Get the cropped area position and size data (base on the original image)
2714
+ * @param {boolean} [rounded=false] - Indicate if round the data values or not.
2715
+ * @returns {Object} The result cropped data.
2716
+ */
2717
+ getData: function getData() {
2718
+ var rounded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
2719
+ var options = this.options,
2720
+ imageData = this.imageData,
2721
+ canvasData = this.canvasData,
2722
+ cropBoxData = this.cropBoxData;
2723
+ var data;
2724
+
2725
+ if (this.ready && this.cropped) {
2726
+ data = {
2727
+ x: cropBoxData.left - canvasData.left,
2728
+ y: cropBoxData.top - canvasData.top,
2729
+ width: cropBoxData.width,
2730
+ height: cropBoxData.height
2731
+ };
2732
+ var ratio = imageData.width / imageData.naturalWidth;
2733
+ forEach(data, function (n, i) {
2734
+ data[i] = n / ratio;
2735
+ });
2736
+
2737
+ if (rounded) {
2738
+ // In case rounding off leads to extra 1px in right or bottom border
2739
+ // we should round the top-left corner and the dimension (#343).
2740
+ var bottom = Math.round(data.y + data.height);
2741
+ var right = Math.round(data.x + data.width);
2742
+ data.x = Math.round(data.x);
2743
+ data.y = Math.round(data.y);
2744
+ data.width = right - data.x;
2745
+ data.height = bottom - data.y;
2746
+ }
2747
+ } else {
2748
+ data = {
2749
+ x: 0,
2750
+ y: 0,
2751
+ width: 0,
2752
+ height: 0
2753
+ };
2754
+ }
2755
+
2756
+ if (options.rotatable) {
2757
+ data.rotate = imageData.rotate || 0;
2758
+ }
2759
+
2760
+ if (options.scalable) {
2761
+ data.scaleX = imageData.scaleX || 1;
2762
+ data.scaleY = imageData.scaleY || 1;
2763
+ }
2764
+
2765
+ return data;
2766
+ },
2767
+
2768
+ /**
2769
+ * Set the cropped area position and size with new data
2770
+ * @param {Object} data - The new data.
2771
+ * @returns {Cropper} this
2772
+ */
2773
+ setData: function setData(data) {
2774
+ var options = this.options,
2775
+ imageData = this.imageData,
2776
+ canvasData = this.canvasData;
2777
+ var cropBoxData = {};
2778
+
2779
+ if (this.ready && !this.disabled && isPlainObject(data)) {
2780
+ var transformed = false;
2781
+
2782
+ if (options.rotatable) {
2783
+ if (isNumber(data.rotate) && data.rotate !== imageData.rotate) {
2784
+ imageData.rotate = data.rotate;
2785
+ transformed = true;
2786
+ }
2787
+ }
2788
+
2789
+ if (options.scalable) {
2790
+ if (isNumber(data.scaleX) && data.scaleX !== imageData.scaleX) {
2791
+ imageData.scaleX = data.scaleX;
2792
+ transformed = true;
2793
+ }
2794
+
2795
+ if (isNumber(data.scaleY) && data.scaleY !== imageData.scaleY) {
2796
+ imageData.scaleY = data.scaleY;
2797
+ transformed = true;
2798
+ }
2799
+ }
2800
+
2801
+ if (transformed) {
2802
+ this.renderCanvas(true, true);
2803
+ }
2804
+
2805
+ var ratio = imageData.width / imageData.naturalWidth;
2806
+
2807
+ if (isNumber(data.x)) {
2808
+ cropBoxData.left = data.x * ratio + canvasData.left;
2809
+ }
2810
+
2811
+ if (isNumber(data.y)) {
2812
+ cropBoxData.top = data.y * ratio + canvasData.top;
2813
+ }
2814
+
2815
+ if (isNumber(data.width)) {
2816
+ cropBoxData.width = data.width * ratio;
2817
+ }
2818
+
2819
+ if (isNumber(data.height)) {
2820
+ cropBoxData.height = data.height * ratio;
2821
+ }
2822
+
2823
+ this.setCropBoxData(cropBoxData);
2824
+ }
2825
+
2826
+ return this;
2827
+ },
2828
+
2829
+ /**
2830
+ * Get the container size data.
2831
+ * @returns {Object} The result container data.
2832
+ */
2833
+ getContainerData: function getContainerData() {
2834
+ return this.ready ? assign({}, this.containerData) : {};
2835
+ },
2836
+
2837
+ /**
2838
+ * Get the image position and size data.
2839
+ * @returns {Object} The result image data.
2840
+ */
2841
+ getImageData: function getImageData() {
2842
+ return this.sized ? assign({}, this.imageData) : {};
2843
+ },
2844
+
2845
+ /**
2846
+ * Get the canvas position and size data.
2847
+ * @returns {Object} The result canvas data.
2848
+ */
2849
+ getCanvasData: function getCanvasData() {
2850
+ var canvasData = this.canvasData;
2851
+ var data = {};
2852
+
2853
+ if (this.ready) {
2854
+ forEach(['left', 'top', 'width', 'height', 'naturalWidth', 'naturalHeight'], function (n) {
2855
+ data[n] = canvasData[n];
2856
+ });
2857
+ }
2858
+
2859
+ return data;
2860
+ },
2861
+
2862
+ /**
2863
+ * Set the canvas position and size with new data.
2864
+ * @param {Object} data - The new canvas data.
2865
+ * @returns {Cropper} this
2866
+ */
2867
+ setCanvasData: function setCanvasData(data) {
2868
+ var canvasData = this.canvasData;
2869
+ var aspectRatio = canvasData.aspectRatio;
2870
+
2871
+ if (this.ready && !this.disabled && isPlainObject(data)) {
2872
+ if (isNumber(data.left)) {
2873
+ canvasData.left = data.left;
2874
+ }
2875
+
2876
+ if (isNumber(data.top)) {
2877
+ canvasData.top = data.top;
2878
+ }
2879
+
2880
+ if (isNumber(data.width)) {
2881
+ canvasData.width = data.width;
2882
+ canvasData.height = data.width / aspectRatio;
2883
+ } else if (isNumber(data.height)) {
2884
+ canvasData.height = data.height;
2885
+ canvasData.width = data.height * aspectRatio;
2886
+ }
2887
+
2888
+ this.renderCanvas(true);
2889
+ }
2890
+
2891
+ return this;
2892
+ },
2893
+
2894
+ /**
2895
+ * Get the crop box position and size data.
2896
+ * @returns {Object} The result crop box data.
2897
+ */
2898
+ getCropBoxData: function getCropBoxData() {
2899
+ var cropBoxData = this.cropBoxData;
2900
+ var data;
2901
+
2902
+ if (this.ready && this.cropped) {
2903
+ data = {
2904
+ left: cropBoxData.left,
2905
+ top: cropBoxData.top,
2906
+ width: cropBoxData.width,
2907
+ height: cropBoxData.height
2908
+ };
2909
+ }
2910
+
2911
+ return data || {};
2912
+ },
2913
+
2914
+ /**
2915
+ * Set the crop box position and size with new data.
2916
+ * @param {Object} data - The new crop box data.
2917
+ * @returns {Cropper} this
2918
+ */
2919
+ setCropBoxData: function setCropBoxData(data) {
2920
+ var cropBoxData = this.cropBoxData;
2921
+ var aspectRatio = this.options.aspectRatio;
2922
+ var widthChanged;
2923
+ var heightChanged;
2924
+
2925
+ if (this.ready && this.cropped && !this.disabled && isPlainObject(data)) {
2926
+ if (isNumber(data.left)) {
2927
+ cropBoxData.left = data.left;
2928
+ }
2929
+
2930
+ if (isNumber(data.top)) {
2931
+ cropBoxData.top = data.top;
2932
+ }
2933
+
2934
+ if (isNumber(data.width) && data.width !== cropBoxData.width) {
2935
+ widthChanged = true;
2936
+ cropBoxData.width = data.width;
2937
+ }
2938
+
2939
+ if (isNumber(data.height) && data.height !== cropBoxData.height) {
2940
+ heightChanged = true;
2941
+ cropBoxData.height = data.height;
2942
+ }
2943
+
2944
+ if (aspectRatio) {
2945
+ if (widthChanged) {
2946
+ cropBoxData.height = cropBoxData.width / aspectRatio;
2947
+ } else if (heightChanged) {
2948
+ cropBoxData.width = cropBoxData.height * aspectRatio;
2949
+ }
2950
+ }
2951
+
2952
+ this.renderCropBox();
2953
+ }
2954
+
2955
+ return this;
2956
+ },
2957
+
2958
+ /**
2959
+ * Get a canvas drawn the cropped image.
2960
+ * @param {Object} [options={}] - The config options.
2961
+ * @returns {HTMLCanvasElement} - The result canvas.
2962
+ */
2963
+ getCroppedCanvas: function getCroppedCanvas() {
2964
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2965
+
2966
+ if (!this.ready || !window.HTMLCanvasElement) {
2967
+ return null;
2968
+ }
2969
+
2970
+ var canvasData = this.canvasData;
2971
+ var source = getSourceCanvas(this.image, this.imageData, canvasData, options); // Returns the source canvas if it is not cropped.
2972
+
2973
+ if (!this.cropped) {
2974
+ return source;
2975
+ }
2976
+
2977
+ var _this$getData = this.getData(),
2978
+ initialX = _this$getData.x,
2979
+ initialY = _this$getData.y,
2980
+ initialWidth = _this$getData.width,
2981
+ initialHeight = _this$getData.height;
2982
+
2983
+ var ratio = source.width / Math.floor(canvasData.naturalWidth);
2984
+
2985
+ if (ratio !== 1) {
2986
+ initialX *= ratio;
2987
+ initialY *= ratio;
2988
+ initialWidth *= ratio;
2989
+ initialHeight *= ratio;
2990
+ }
2991
+
2992
+ var aspectRatio = initialWidth / initialHeight;
2993
+ var maxSizes = getAdjustedSizes({
2994
+ aspectRatio: aspectRatio,
2995
+ width: options.maxWidth || Infinity,
2996
+ height: options.maxHeight || Infinity
2997
+ });
2998
+ var minSizes = getAdjustedSizes({
2999
+ aspectRatio: aspectRatio,
3000
+ width: options.minWidth || 0,
3001
+ height: options.minHeight || 0
3002
+ }, 'cover');
3003
+
3004
+ var _getAdjustedSizes = getAdjustedSizes({
3005
+ aspectRatio: aspectRatio,
3006
+ width: options.width || (ratio !== 1 ? source.width : initialWidth),
3007
+ height: options.height || (ratio !== 1 ? source.height : initialHeight)
3008
+ }),
3009
+ width = _getAdjustedSizes.width,
3010
+ height = _getAdjustedSizes.height;
3011
+
3012
+ width = Math.min(maxSizes.width, Math.max(minSizes.width, width));
3013
+ height = Math.min(maxSizes.height, Math.max(minSizes.height, height));
3014
+ var canvas = document.createElement('canvas');
3015
+ var context = canvas.getContext('2d');
3016
+ canvas.width = normalizeDecimalNumber(width);
3017
+ canvas.height = normalizeDecimalNumber(height);
3018
+ context.fillStyle = options.fillColor || 'transparent';
3019
+ context.fillRect(0, 0, width, height);
3020
+ var _options$imageSmoothi = options.imageSmoothingEnabled,
3021
+ imageSmoothingEnabled = _options$imageSmoothi === void 0 ? true : _options$imageSmoothi,
3022
+ imageSmoothingQuality = options.imageSmoothingQuality;
3023
+ context.imageSmoothingEnabled = imageSmoothingEnabled;
3024
+
3025
+ if (imageSmoothingQuality) {
3026
+ context.imageSmoothingQuality = imageSmoothingQuality;
3027
+ } // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.drawImage
3028
+
3029
+
3030
+ var sourceWidth = source.width;
3031
+ var sourceHeight = source.height; // Source canvas parameters
3032
+
3033
+ var srcX = initialX;
3034
+ var srcY = initialY;
3035
+ var srcWidth;
3036
+ var srcHeight; // Destination canvas parameters
3037
+
3038
+ var dstX;
3039
+ var dstY;
3040
+ var dstWidth;
3041
+ var dstHeight;
3042
+
3043
+ if (srcX <= -initialWidth || srcX > sourceWidth) {
3044
+ srcX = 0;
3045
+ srcWidth = 0;
3046
+ dstX = 0;
3047
+ dstWidth = 0;
3048
+ } else if (srcX <= 0) {
3049
+ dstX = -srcX;
3050
+ srcX = 0;
3051
+ srcWidth = Math.min(sourceWidth, initialWidth + srcX);
3052
+ dstWidth = srcWidth;
3053
+ } else if (srcX <= sourceWidth) {
3054
+ dstX = 0;
3055
+ srcWidth = Math.min(initialWidth, sourceWidth - srcX);
3056
+ dstWidth = srcWidth;
3057
+ }
3058
+
3059
+ if (srcWidth <= 0 || srcY <= -initialHeight || srcY > sourceHeight) {
3060
+ srcY = 0;
3061
+ srcHeight = 0;
3062
+ dstY = 0;
3063
+ dstHeight = 0;
3064
+ } else if (srcY <= 0) {
3065
+ dstY = -srcY;
3066
+ srcY = 0;
3067
+ srcHeight = Math.min(sourceHeight, initialHeight + srcY);
3068
+ dstHeight = srcHeight;
3069
+ } else if (srcY <= sourceHeight) {
3070
+ dstY = 0;
3071
+ srcHeight = Math.min(initialHeight, sourceHeight - srcY);
3072
+ dstHeight = srcHeight;
3073
+ }
3074
+
3075
+ var params = [srcX, srcY, srcWidth, srcHeight]; // Avoid "IndexSizeError"
3076
+
3077
+ if (dstWidth > 0 && dstHeight > 0) {
3078
+ var scale = width / initialWidth;
3079
+ params.push(dstX * scale, dstY * scale, dstWidth * scale, dstHeight * scale);
3080
+ } // All the numerical parameters should be integer for `drawImage`
3081
+ // https://github.com/fengyuanchen/cropper/issues/476
3082
+
3083
+
3084
+ context.drawImage.apply(context, [source].concat(_toConsumableArray(params.map(function (param) {
3085
+ return Math.floor(normalizeDecimalNumber(param));
3086
+ }))));
3087
+ return canvas;
3088
+ },
3089
+
3090
+ /**
3091
+ * Change the aspect ratio of the crop box.
3092
+ * @param {number} aspectRatio - The new aspect ratio.
3093
+ * @returns {Cropper} this
3094
+ */
3095
+ setAspectRatio: function setAspectRatio(aspectRatio) {
3096
+ var options = this.options;
3097
+
3098
+ if (!this.disabled && !isUndefined(aspectRatio)) {
3099
+ // 0 -> NaN
3100
+ options.aspectRatio = Math.max(0, aspectRatio) || NaN;
3101
+
3102
+ if (this.ready) {
3103
+ this.initCropBox();
3104
+
3105
+ if (this.cropped) {
3106
+ this.renderCropBox();
3107
+ }
3108
+ }
3109
+ }
3110
+
3111
+ return this;
3112
+ },
3113
+
3114
+ /**
3115
+ * Change the drag mode.
3116
+ * @param {string} mode - The new drag mode.
3117
+ * @returns {Cropper} this
3118
+ */
3119
+ setDragMode: function setDragMode(mode) {
3120
+ var options = this.options,
3121
+ dragBox = this.dragBox,
3122
+ face = this.face;
3123
+
3124
+ if (this.ready && !this.disabled) {
3125
+ var croppable = mode === DRAG_MODE_CROP;
3126
+ var movable = options.movable && mode === DRAG_MODE_MOVE;
3127
+ mode = croppable || movable ? mode : DRAG_MODE_NONE;
3128
+ options.dragMode = mode;
3129
+ setData(dragBox, DATA_ACTION, mode);
3130
+ toggleClass(dragBox, CLASS_CROP, croppable);
3131
+ toggleClass(dragBox, CLASS_MOVE, movable);
3132
+
3133
+ if (!options.cropBoxMovable) {
3134
+ // Sync drag mode to crop box when it is not movable
3135
+ setData(face, DATA_ACTION, mode);
3136
+ toggleClass(face, CLASS_CROP, croppable);
3137
+ toggleClass(face, CLASS_MOVE, movable);
3138
+ }
3139
+ }
3140
+
3141
+ return this;
3142
+ }
3143
+ };
3144
+
3145
+ var AnotherCropper = WINDOW.Cropper;
3146
+
3147
+ var Cropper =
3148
+ /*#__PURE__*/
3149
+ function () {
3150
+ /**
3151
+ * Create a new Cropper.
3152
+ * @param {Element} element - The target element for cropping.
3153
+ * @param {Object} [options={}] - The configuration options.
3154
+ */
3155
+ function Cropper(element) {
3156
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
3157
+
3158
+ _classCallCheck(this, Cropper);
3159
+
3160
+ if (!element || !REGEXP_TAG_NAME.test(element.tagName)) {
3161
+ throw new Error('The first argument is required and must be an <img> or <canvas> element.');
3162
+ }
3163
+
3164
+ this.element = element;
3165
+ this.options = assign({}, DEFAULTS, isPlainObject(options) && options);
3166
+ this.cropped = false;
3167
+ this.disabled = false;
3168
+ this.pointers = {};
3169
+ this.ready = false;
3170
+ this.reloading = false;
3171
+ this.replaced = false;
3172
+ this.sized = false;
3173
+ this.sizing = false;
3174
+ this.init();
3175
+ }
3176
+
3177
+ _createClass(Cropper, [{
3178
+ key: "init",
3179
+ value: function init() {
3180
+ var element = this.element;
3181
+ var tagName = element.tagName.toLowerCase();
3182
+ var url;
3183
+
3184
+ if (element[NAMESPACE]) {
3185
+ return;
3186
+ }
3187
+
3188
+ element[NAMESPACE] = this;
3189
+
3190
+ if (tagName === 'img') {
3191
+ this.isImg = true; // e.g.: "img/picture.jpg"
3192
+
3193
+ url = element.getAttribute('src') || '';
3194
+ this.originalUrl = url; // Stop when it's a blank image
3195
+
3196
+ if (!url) {
3197
+ return;
3198
+ } // e.g.: "http://example.com/img/picture.jpg"
3199
+
3200
+
3201
+ url = element.src;
3202
+ } else if (tagName === 'canvas' && window.HTMLCanvasElement) {
3203
+ url = element.toDataURL();
3204
+ }
3205
+
3206
+ this.load(url);
3207
+ }
3208
+ }, {
3209
+ key: "load",
3210
+ value: function load(url) {
3211
+ var _this = this;
3212
+
3213
+ if (!url) {
3214
+ return;
3215
+ }
3216
+
3217
+ this.url = url;
3218
+ this.imageData = {};
3219
+ var element = this.element,
3220
+ options = this.options;
3221
+
3222
+ if (!options.rotatable && !options.scalable) {
3223
+ options.checkOrientation = false;
3224
+ } // Only IE10+ supports Typed Arrays
3225
+
3226
+
3227
+ if (!options.checkOrientation || !window.ArrayBuffer) {
3228
+ this.clone();
3229
+ return;
3230
+ } // Read ArrayBuffer from Data URL of JPEG images directly for better performance.
3231
+
3232
+
3233
+ if (REGEXP_DATA_URL_JPEG.test(url)) {
3234
+ this.read(dataURLToArrayBuffer(url));
3235
+ return;
3236
+ }
3237
+
3238
+ var xhr = new XMLHttpRequest();
3239
+ var clone = this.clone.bind(this);
3240
+ this.reloading = true;
3241
+ this.xhr = xhr; // 1. Cross origin requests are only supported for protocol schemes:
3242
+ // http, https, data, chrome, chrome-extension.
3243
+ // 2. Access to XMLHttpRequest from a Data URL will be blocked by CORS policy
3244
+ // in some browsers as IE11 and Safari.
3245
+
3246
+ xhr.onabort = clone;
3247
+ xhr.onerror = clone;
3248
+ xhr.ontimeout = clone;
3249
+
3250
+ xhr.onprogress = function () {
3251
+ if (xhr.getResponseHeader('content-type') !== MIME_TYPE_JPEG) {
3252
+ xhr.abort();
3253
+ }
3254
+ };
3255
+
3256
+ xhr.onload = function () {
3257
+ _this.read(xhr.response);
3258
+ };
3259
+
3260
+ xhr.onloadend = function () {
3261
+ _this.reloading = false;
3262
+ _this.xhr = null;
3263
+ }; // Bust cache when there is a "crossOrigin" property to avoid browser cache error
3264
+
3265
+
3266
+ if (options.checkCrossOrigin && isCrossOriginURL(url) && element.crossOrigin) {
3267
+ url = addTimestamp(url);
3268
+ }
3269
+
3270
+ xhr.open('GET', url);
3271
+ xhr.responseType = 'arraybuffer';
3272
+ xhr.withCredentials = element.crossOrigin === 'use-credentials';
3273
+ xhr.send();
3274
+ }
3275
+ }, {
3276
+ key: "read",
3277
+ value: function read(arrayBuffer) {
3278
+ var options = this.options,
3279
+ imageData = this.imageData; // Reset the orientation value to its default value 1
3280
+ // as some iOS browsers will render image with its orientation
3281
+
3282
+ var orientation = resetAndGetOrientation(arrayBuffer);
3283
+ var rotate = 0;
3284
+ var scaleX = 1;
3285
+ var scaleY = 1;
3286
+
3287
+ if (orientation > 1) {
3288
+ // Generate a new URL which has the default orientation value
3289
+ this.url = arrayBufferToDataURL(arrayBuffer, MIME_TYPE_JPEG);
3290
+
3291
+ var _parseOrientation = parseOrientation(orientation);
3292
+
3293
+ rotate = _parseOrientation.rotate;
3294
+ scaleX = _parseOrientation.scaleX;
3295
+ scaleY = _parseOrientation.scaleY;
3296
+ }
3297
+
3298
+ if (options.rotatable) {
3299
+ imageData.rotate = rotate;
3300
+ }
3301
+
3302
+ if (options.scalable) {
3303
+ imageData.scaleX = scaleX;
3304
+ imageData.scaleY = scaleY;
3305
+ }
3306
+
3307
+ this.clone();
3308
+ }
3309
+ }, {
3310
+ key: "clone",
3311
+ value: function clone() {
3312
+ var element = this.element,
3313
+ url = this.url;
3314
+ var crossOrigin;
3315
+ var crossOriginUrl;
3316
+
3317
+ if (this.options.checkCrossOrigin && isCrossOriginURL(url)) {
3318
+ crossOrigin = element.crossOrigin;
3319
+
3320
+ if (!crossOrigin) {
3321
+ crossOrigin = 'anonymous';
3322
+ } // Bust cache when there is not a "crossOrigin" property (#519)
3323
+
3324
+
3325
+ crossOriginUrl = addTimestamp(url);
3326
+ }
3327
+
3328
+ this.crossOrigin = crossOrigin;
3329
+ this.crossOriginUrl = crossOriginUrl;
3330
+ var image = document.createElement('img');
3331
+
3332
+ if (crossOrigin) {
3333
+ image.crossOrigin = crossOrigin;
3334
+ }
3335
+
3336
+ image.src = crossOriginUrl || url;
3337
+ this.image = image;
3338
+ image.onload = this.start.bind(this);
3339
+ image.onerror = this.stop.bind(this);
3340
+ addClass(image, CLASS_HIDE);
3341
+ element.parentNode.insertBefore(image, element.nextSibling);
3342
+ }
3343
+ }, {
3344
+ key: "start",
3345
+ value: function start() {
3346
+ var _this2 = this;
3347
+
3348
+ var image = this.isImg ? this.element : this.image;
3349
+ image.onload = null;
3350
+ image.onerror = null;
3351
+ this.sizing = true; // Match all browsers that use WebKit as the layout engine in iOS devices,
3352
+ // such as Safari for iOS, Chrome for iOS, and in-app browsers.
3353
+
3354
+ var isIOSWebKit = WINDOW.navigator && /(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(WINDOW.navigator.userAgent);
3355
+
3356
+ var done = function done(naturalWidth, naturalHeight) {
3357
+ assign(_this2.imageData, {
3358
+ naturalWidth: naturalWidth,
3359
+ naturalHeight: naturalHeight,
3360
+ aspectRatio: naturalWidth / naturalHeight
3361
+ });
3362
+ _this2.sizing = false;
3363
+ _this2.sized = true;
3364
+
3365
+ _this2.build();
3366
+ }; // Most modern browsers (excepts iOS WebKit)
3367
+
3368
+
3369
+ if (image.naturalWidth && !isIOSWebKit) {
3370
+ done(image.naturalWidth, image.naturalHeight);
3371
+ return;
3372
+ }
3373
+
3374
+ var sizingImage = document.createElement('img');
3375
+ var body = document.body || document.documentElement;
3376
+ this.sizingImage = sizingImage;
3377
+
3378
+ sizingImage.onload = function () {
3379
+ done(sizingImage.width, sizingImage.height);
3380
+
3381
+ if (!isIOSWebKit) {
3382
+ body.removeChild(sizingImage);
3383
+ }
3384
+ };
3385
+
3386
+ sizingImage.src = image.src; // iOS WebKit will convert the image automatically
3387
+ // with its orientation once append it into DOM (#279)
3388
+
3389
+ if (!isIOSWebKit) {
3390
+ sizingImage.style.cssText = 'left:0;' + 'max-height:none!important;' + 'max-width:none!important;' + 'min-height:0!important;' + 'min-width:0!important;' + 'opacity:0;' + 'position:absolute;' + 'top:0;' + 'z-index:-1;';
3391
+ body.appendChild(sizingImage);
3392
+ }
3393
+ }
3394
+ }, {
3395
+ key: "stop",
3396
+ value: function stop() {
3397
+ var image = this.image;
3398
+ image.onload = null;
3399
+ image.onerror = null;
3400
+ image.parentNode.removeChild(image);
3401
+ this.image = null;
3402
+ }
3403
+ }, {
3404
+ key: "build",
3405
+ value: function build() {
3406
+ if (!this.sized || this.ready) {
3407
+ return;
3408
+ }
3409
+
3410
+ var element = this.element,
3411
+ options = this.options,
3412
+ image = this.image; // Create cropper elements
3413
+
3414
+ var container = element.parentNode;
3415
+ var template = document.createElement('div');
3416
+ template.innerHTML = TEMPLATE;
3417
+ var cropper = template.querySelector(".".concat(NAMESPACE, "-container"));
3418
+ var canvas = cropper.querySelector(".".concat(NAMESPACE, "-canvas"));
3419
+ var dragBox = cropper.querySelector(".".concat(NAMESPACE, "-drag-box"));
3420
+ var cropBox = cropper.querySelector(".".concat(NAMESPACE, "-crop-box"));
3421
+ var face = cropBox.querySelector(".".concat(NAMESPACE, "-face"));
3422
+ this.container = container;
3423
+ this.cropper = cropper;
3424
+ this.canvas = canvas;
3425
+ this.dragBox = dragBox;
3426
+ this.cropBox = cropBox;
3427
+ this.viewBox = cropper.querySelector(".".concat(NAMESPACE, "-view-box"));
3428
+ this.face = face;
3429
+ canvas.appendChild(image); // Hide the original image
3430
+
3431
+ addClass(element, CLASS_HIDDEN); // Inserts the cropper after to the current image
3432
+
3433
+ container.insertBefore(cropper, element.nextSibling); // Show the image if is hidden
3434
+
3435
+ if (!this.isImg) {
3436
+ removeClass(image, CLASS_HIDE);
3437
+ }
3438
+
3439
+ this.initPreview();
3440
+ this.bind();
3441
+ options.initialAspectRatio = Math.max(0, options.initialAspectRatio) || NaN;
3442
+ options.aspectRatio = Math.max(0, options.aspectRatio) || NaN;
3443
+ options.viewMode = Math.max(0, Math.min(3, Math.round(options.viewMode))) || 0;
3444
+ addClass(cropBox, CLASS_HIDDEN);
3445
+
3446
+ if (!options.guides) {
3447
+ addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-dashed")), CLASS_HIDDEN);
3448
+ }
3449
+
3450
+ if (!options.center) {
3451
+ addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-center")), CLASS_HIDDEN);
3452
+ }
3453
+
3454
+ if (options.background) {
3455
+ addClass(cropper, "".concat(NAMESPACE, "-bg"));
3456
+ }
3457
+
3458
+ if (!options.highlight) {
3459
+ addClass(face, CLASS_INVISIBLE);
3460
+ }
3461
+
3462
+ if (options.cropBoxMovable) {
3463
+ addClass(face, CLASS_MOVE);
3464
+ setData(face, DATA_ACTION, ACTION_ALL);
3465
+ }
3466
+
3467
+ if (!options.cropBoxResizable) {
3468
+ addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-line")), CLASS_HIDDEN);
3469
+ addClass(cropBox.getElementsByClassName("".concat(NAMESPACE, "-point")), CLASS_HIDDEN);
3470
+ }
3471
+
3472
+ this.render();
3473
+ this.ready = true;
3474
+ this.setDragMode(options.dragMode);
3475
+
3476
+ if (options.autoCrop) {
3477
+ this.crop();
3478
+ }
3479
+
3480
+ this.setData(options.data);
3481
+
3482
+ if (isFunction(options.ready)) {
3483
+ addListener(element, EVENT_READY, options.ready, {
3484
+ once: true
3485
+ });
3486
+ }
3487
+
3488
+ dispatchEvent(element, EVENT_READY);
3489
+ }
3490
+ }, {
3491
+ key: "unbuild",
3492
+ value: function unbuild() {
3493
+ if (!this.ready) {
3494
+ return;
3495
+ }
3496
+
3497
+ this.ready = false;
3498
+ this.unbind();
3499
+ this.resetPreview();
3500
+ this.cropper.parentNode.removeChild(this.cropper);
3501
+ removeClass(this.element, CLASS_HIDDEN);
3502
+ }
3503
+ }, {
3504
+ key: "uncreate",
3505
+ value: function uncreate() {
3506
+ if (this.ready) {
3507
+ this.unbuild();
3508
+ this.ready = false;
3509
+ this.cropped = false;
3510
+ } else if (this.sizing) {
3511
+ this.sizingImage.onload = null;
3512
+ this.sizing = false;
3513
+ this.sized = false;
3514
+ } else if (this.reloading) {
3515
+ this.xhr.onabort = null;
3516
+ this.xhr.abort();
3517
+ } else if (this.image) {
3518
+ this.stop();
3519
+ }
3520
+ }
3521
+ /**
3522
+ * Get the no conflict cropper class.
3523
+ * @returns {Cropper} The cropper class.
3524
+ */
3525
+
3526
+ }], [{
3527
+ key: "noConflict",
3528
+ value: function noConflict() {
3529
+ window.Cropper = AnotherCropper;
3530
+ return Cropper;
3531
+ }
3532
+ /**
3533
+ * Change the default options.
3534
+ * @param {Object} options - The new default options.
3535
+ */
3536
+
3537
+ }, {
3538
+ key: "setDefaults",
3539
+ value: function setDefaults(options) {
3540
+ assign(DEFAULTS, isPlainObject(options) && options);
3541
+ }
3542
+ }]);
3543
+
3544
+ return Cropper;
3545
+ }();
3546
+
3547
+ assign(Cropper.prototype, render, preview, events, handlers, change, methods);
3548
+
3549
+ return Cropper;
3550
+
3551
+ }));
vendor/cropperjs/dist/cropper.min.css ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Cropper.js v1.5.3
3
+ * https://fengyuanchen.github.io/cropperjs
4
+ *
5
+ * Copyright 2015-present Chen Fengyuan
6
+ * Released under the MIT license
7
+ *
8
+ * Date: 2019-07-10T12:07:41.696Z
9
+ */.cropper-container{direction:ltr;font-size:0;line-height:0;position:relative;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.cropper-container img{display:block;height:100%;image-orientation:0deg;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal,.cropper-wrap-box{bottom:0;left:0;position:absolute;right:0;top:0}.cropper-canvas,.cropper-wrap-box{overflow:hidden}.cropper-drag-box{background-color:#fff;opacity:0}.cropper-modal{background-color:#000;opacity:.5}.cropper-view-box{display:block;height:100%;outline:1px solid #39f;outline-color:rgba(51,153,255,.75);overflow:hidden;width:100%}.cropper-dashed{border:0 dashed #eee;display:block;opacity:.5;position:absolute}.cropper-dashed.dashed-h{border-bottom-width:1px;border-top-width:1px;height:33.33333%;left:0;top:33.33333%;width:100%}.cropper-dashed.dashed-v{border-left-width:1px;border-right-width:1px;height:100%;left:33.33333%;top:0;width:33.33333%}.cropper-center{display:block;height:0;left:50%;opacity:.75;position:absolute;top:50%;width:0}.cropper-center:after,.cropper-center:before{background-color:#eee;content:" ";display:block;position:absolute}.cropper-center:before{height:1px;left:-3px;top:0;width:7px}.cropper-center:after{height:7px;left:0;top:-3px;width:1px}.cropper-face,.cropper-line,.cropper-point{display:block;height:100%;opacity:.1;position:absolute;width:100%}.cropper-face{background-color:#fff;left:0;top:0}.cropper-line{background-color:#39f}.cropper-line.line-e{cursor:ew-resize;right:-3px;top:0;width:5px}.cropper-line.line-n{cursor:ns-resize;height:5px;left:0;top:-3px}.cropper-line.line-w{cursor:ew-resize;left:-3px;top:0;width:5px}.cropper-line.line-s{bottom:-3px;cursor:ns-resize;height:5px;left:0}.cropper-point{background-color:#39f;height:5px;opacity:.75;width:5px}.cropper-point.point-e{cursor:ew-resize;margin-top:-3px;right:-3px;top:50%}.cropper-point.point-n{cursor:ns-resize;left:50%;margin-left:-3px;top:-3px}.cropper-point.point-w{cursor:ew-resize;left:-3px;margin-top:-3px;top:50%}.cropper-point.point-s{bottom:-3px;cursor:s-resize;left:50%;margin-left:-3px}.cropper-point.point-ne{cursor:nesw-resize;right:-3px;top:-3px}.cropper-point.point-nw{cursor:nwse-resize;left:-3px;top:-3px}.cropper-point.point-sw{bottom:-3px;cursor:nesw-resize;left:-3px}.cropper-point.point-se{bottom:-3px;cursor:nwse-resize;height:20px;opacity:1;right:-3px;width:20px}@media (min-width:768px){.cropper-point.point-se{height:15px;width:15px}}@media (min-width:992px){.cropper-point.point-se{height:10px;width:10px}}@media (min-width:1200px){.cropper-point.point-se{height:5px;opacity:.75;width:5px}}.cropper-point.point-se:before{background-color:#39f;bottom:-50%;content:" ";display:block;height:200%;opacity:0;position:absolute;right:-50%;width:200%}.cropper-invisible{opacity:0}.cropper-bg{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC")}.cropper-hide{display:block;height:0;position:absolute;width:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed}
vendor/cropperjs/dist/cropper.min.js ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Cropper.js v1.5.3
3
+ * https://fengyuanchen.github.io/cropperjs
4
+ *
5
+ * Copyright 2015-present Chen Fengyuan
6
+ * Released under the MIT license
7
+ *
8
+ * Date: 2019-07-10T12:07:44.557Z
9
+ */
10
+ !function(t,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i():"function"==typeof define&&define.amd?define(i):(t=t||self).Cropper=i()}(this,function(){"use strict";function i(t){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(t,i){for(var e=0;e<i.length;e++){var a=i[e];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(t,a.key,a)}}function j(t){return function(t){if(Array.isArray(t)){for(var i=0,e=new Array(t.length);i<t.length;i++)e[i]=t[i];return e}}(t)||function(t){if(Symbol.iterator in Object(t)||"[object Arguments]"===Object.prototype.toString.call(t))return Array.from(t)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}var n="undefined"!=typeof window,h=n?window:{},t=n&&"ontouchstart"in h.document.documentElement,e=n&&"PointerEvent"in h,d="cropper",C="all",D="crop",B="move",k="zoom",T="e",E="w",W="s",N="n",H="ne",L="nw",O="se",z="sw",r="".concat(d,"-crop"),o="".concat(d,"-disabled"),Y="".concat(d,"-hidden"),l="".concat(d,"-hide"),p="".concat(d,"-invisible"),s="".concat(d,"-modal"),m="".concat(d,"-move"),u="".concat(d,"Action"),g="".concat(d,"Preview"),c="crop",f="move",v="none",w="crop",b="cropend",x="cropmove",y="cropstart",M="dblclick",X=e?"pointerdown":t?"touchstart":"mousedown",R=e?"pointermove":t?"touchmove":"mousemove",A=e?"pointerup pointercancel":t?"touchend touchcancel":"mouseup",S="ready",I="resize",U="wheel",P="zoom",q="image/jpeg",$=/^e|w|s|n|se|sw|ne|nw|all|crop|move|zoom$/,Q=/^data:image\/jpeg;base64,/,K=/^img|canvas$/i,Z={viewMode:0,dragMode:c,initialAspectRatio:NaN,aspectRatio:NaN,data:null,preview:"",responsive:!0,restore:!0,checkCrossOrigin:!0,checkOrientation:!0,modal:!0,guides:!0,center:!0,highlight:!0,background:!0,autoCrop:!0,autoCropArea:.8,movable:!0,rotatable:!0,scalable:!0,zoomable:!0,zoomOnTouch:!0,zoomOnWheel:!0,wheelZoomRatio:.1,cropBoxMovable:!0,cropBoxResizable:!0,toggleDragModeOnDblclick:!0,minCanvasWidth:0,minCanvasHeight:0,minCropBoxWidth:0,minCropBoxHeight:0,minContainerWidth:200,minContainerHeight:100,ready:null,cropstart:null,cropmove:null,cropend:null,crop:null,zoom:null},G=Number.isNaN||h.isNaN;function V(t){return"number"==typeof t&&!G(t)}var F=function(t){return 0<t&&t<1/0};function J(t){return void 0===t}function _(t){return"object"===i(t)&&null!==t}var tt=Object.prototype.hasOwnProperty;function it(t){if(!_(t))return!1;try{var i=t.constructor,e=i.prototype;return i&&e&&tt.call(e,"isPrototypeOf")}catch(t){return!1}}function et(t){return"function"==typeof t}var at=Array.prototype.slice;function nt(t){return Array.from?Array.from(t):at.call(t)}function ot(e,a){return e&&et(a)&&(Array.isArray(e)||V(e.length)?nt(e).forEach(function(t,i){a.call(e,t,i,e)}):_(e)&&Object.keys(e).forEach(function(t){a.call(e,e[t],t,e)})),e}var ht=Object.assign||function(e){for(var t=arguments.length,i=new Array(1<t?t-1:0),a=1;a<t;a++)i[a-1]=arguments[a];return _(e)&&0<i.length&&i.forEach(function(i){_(i)&&Object.keys(i).forEach(function(t){e[t]=i[t]})}),e},rt=/\.\d*(?:0|9){12}\d*$/;function st(t,i){var e=1<arguments.length&&void 0!==i?i:1e11;return rt.test(t)?Math.round(t*e)/e:t}var ct=/^width|height|left|top|marginLeft|marginTop$/;function dt(t,i){var e=t.style;ot(i,function(t,i){ct.test(i)&&V(t)&&(t="".concat(t,"px")),e[i]=t})}function lt(t,i){if(i)if(V(t.length))ot(t,function(t){lt(t,i)});else if(t.classList)t.classList.add(i);else{var e=t.className.trim();e?e.indexOf(i)<0&&(t.className="".concat(e," ").concat(i)):t.className=i}}function pt(t,i){i&&(V(t.length)?ot(t,function(t){pt(t,i)}):t.classList?t.classList.remove(i):0<=t.className.indexOf(i)&&(t.className=t.className.replace(i,"")))}function mt(t,i,e){i&&(V(t.length)?ot(t,function(t){mt(t,i,e)}):e?lt(t,i):pt(t,i))}var ut=/([a-z\d])([A-Z])/g;function gt(t){return t.replace(ut,"$1-$2").toLowerCase()}function ft(t,i){return _(t[i])?t[i]:t.dataset?t.dataset[i]:t.getAttribute("data-".concat(gt(i)))}function vt(t,i,e){_(e)?t[i]=e:t.dataset?t.dataset[i]=e:t.setAttribute("data-".concat(gt(i)),e)}var wt=/\s\s*/,bt=function(){var t=!1;if(n){var i=!1,e=function(){},a=Object.defineProperty({},"once",{get:function(){return t=!0,i},set:function(t){i=t}});h.addEventListener("test",e,a),h.removeEventListener("test",e,a)}return t}();function xt(e,t,a,i){var n=3<arguments.length&&void 0!==i?i:{},o=a;t.trim().split(wt).forEach(function(t){if(!bt){var i=e.listeners;i&&i[t]&&i[t][a]&&(o=i[t][a],delete i[t][a],0===Object.keys(i[t]).length&&delete i[t],0===Object.keys(i).length&&delete e.listeners)}e.removeEventListener(t,o,n)})}function yt(o,t,h,i){var r=3<arguments.length&&void 0!==i?i:{},s=h;t.trim().split(wt).forEach(function(a){if(r.once&&!bt){var t=o.listeners,n=void 0===t?{}:t;s=function(){delete n[a][h],o.removeEventListener(a,s,r);for(var t=arguments.length,i=new Array(t),e=0;e<t;e++)i[e]=arguments[e];h.apply(o,i)},n[a]||(n[a]={}),n[a][h]&&o.removeEventListener(a,n[a][h],r),n[a][h]=s,o.listeners=n}o.addEventListener(a,s,r)})}function Mt(t,i,e){var a;return et(Event)&&et(CustomEvent)?a=new CustomEvent(i,{detail:e,bubbles:!0,cancelable:!0}):(a=document.createEvent("CustomEvent")).initCustomEvent(i,!0,!0,e),t.dispatchEvent(a)}function Ct(t){var i=t.getBoundingClientRect();return{left:i.left+(window.pageXOffset-document.documentElement.clientLeft),top:i.top+(window.pageYOffset-document.documentElement.clientTop)}}var Dt=h.location,Bt=/^(\w+:)\/\/([^:/?#]*):?(\d*)/i;function kt(t){var i=t.match(Bt);return null!==i&&(i[1]!==Dt.protocol||i[2]!==Dt.hostname||i[3]!==Dt.port)}function Tt(t){var i="timestamp=".concat((new Date).getTime());return t+(-1===t.indexOf("?")?"?":"&")+i}function Et(t){var i=t.rotate,e=t.scaleX,a=t.scaleY,n=t.translateX,o=t.translateY,h=[];V(n)&&0!==n&&h.push("translateX(".concat(n,"px)")),V(o)&&0!==o&&h.push("translateY(".concat(o,"px)")),V(i)&&0!==i&&h.push("rotate(".concat(i,"deg)")),V(e)&&1!==e&&h.push("scaleX(".concat(e,")")),V(a)&&1!==a&&h.push("scaleY(".concat(a,")"));var r=h.length?h.join(" "):"none";return{WebkitTransform:r,msTransform:r,transform:r}}function Wt(t,i){var e=t.pageX,a=t.pageY,n={endX:e,endY:a};return i?n:ht({startX:e,startY:a},n)}function Nt(t,i){var e=t.aspectRatio,a=t.height,n=t.width,o=1<arguments.length&&void 0!==i?i:"contain",h=F(n),r=F(a);if(h&&r){var s=a*e;"contain"===o&&n<s||"cover"===o&&s<n?a=n/e:n=a*e}else h?a=n/e:r&&(n=a*e);return{width:n,height:a}}var Ht=String.fromCharCode;var Lt=/^data:.*,/;function Ot(t){var i,e=new DataView(t);try{var a,n,o;if(255===e.getUint8(0)&&216===e.getUint8(1))for(var h=e.byteLength,r=2;r+1<h;){if(255===e.getUint8(r)&&225===e.getUint8(r+1)){n=r;break}r+=1}if(n){var s=n+10;if("Exif"===function(t,i,e){var a="";e+=i;for(var n=i;n<e;n+=1)a+=Ht(t.getUint8(n));return a}(e,n+4,4)){var c=e.getUint16(s);if(((a=18761===c)||19789===c)&&42===e.getUint16(s+2,a)){var d=e.getUint32(s+4,a);8<=d&&(o=s+d)}}}if(o){var l,p,m=e.getUint16(o,a);for(p=0;p<m;p+=1)if(l=o+12*p+2,274===e.getUint16(l,a)){l+=8,i=e.getUint16(l,a),e.setUint16(l,1,a);break}}}catch(t){i=1}return i}var zt={render:function(){this.initContainer(),this.initCanvas(),this.initCropBox(),this.renderCanvas(),this.cropped&&this.renderCropBox()},initContainer:function(){var t=this.element,i=this.options,e=this.container,a=this.cropper;lt(a,Y),pt(t,Y);var n={width:Math.max(e.offsetWidth,Number(i.minContainerWidth)||200),height:Math.max(e.offsetHeight,Number(i.minContainerHeight)||100)};dt(a,{width:(this.containerData=n).width,height:n.height}),lt(t,Y),pt(a,Y)},initCanvas:function(){var t=this.containerData,i=this.imageData,e=this.options.viewMode,a=Math.abs(i.rotate)%180==90,n=a?i.naturalHeight:i.naturalWidth,o=a?i.naturalWidth:i.naturalHeight,h=n/o,r=t.width,s=t.height;t.height*h>t.width?3===e?r=t.height*h:s=t.width/h:3===e?s=t.width/h:r=t.height*h;var c={aspectRatio:h,naturalWidth:n,naturalHeight:o,width:r,height:s};c.left=(t.width-r)/2,c.top=(t.height-s)/2,c.oldLeft=c.left,c.oldTop=c.top,this.canvasData=c,this.limited=1===e||2===e,this.limitCanvas(!0,!0),this.initialImageData=ht({},i),this.initialCanvasData=ht({},c)},limitCanvas:function(t,i){var e=this.options,a=this.containerData,n=this.canvasData,o=this.cropBoxData,h=e.viewMode,r=n.aspectRatio,s=this.cropped&&o;if(t){var c=Number(e.minCanvasWidth)||0,d=Number(e.minCanvasHeight)||0;1<h?(c=Math.max(c,a.width),d=Math.max(d,a.height),3===h&&(c<d*r?c=d*r:d=c/r)):0<h&&(c?c=Math.max(c,s?o.width:0):d?d=Math.max(d,s?o.height:0):s&&((c=o.width)<(d=o.height)*r?c=d*r:d=c/r));var l=Nt({aspectRatio:r,width:c,height:d});c=l.width,d=l.height,n.minWidth=c,n.minHeight=d,n.maxWidth=1/0,n.maxHeight=1/0}if(i)if((s?0:1)<h){var p=a.width-n.width,m=a.height-n.height;n.minLeft=Math.min(0,p),n.minTop=Math.min(0,m),n.maxLeft=Math.max(0,p),n.maxTop=Math.max(0,m),s&&this.limited&&(n.minLeft=Math.min(o.left,o.left+(o.width-n.width)),n.minTop=Math.min(o.top,o.top+(o.height-n.height)),n.maxLeft=o.left,n.maxTop=o.top,2===h&&(n.width>=a.width&&(n.minLeft=Math.min(0,p),n.maxLeft=Math.max(0,p)),n.height>=a.height&&(n.minTop=Math.min(0,m),n.maxTop=Math.max(0,m))))}else n.minLeft=-n.width,n.minTop=-n.height,n.maxLeft=a.width,n.maxTop=a.height},renderCanvas:function(t,i){var e=this.canvasData,a=this.imageData;if(i){var n=function(t){var i=t.width,e=t.height,a=t.degree;if(90===(a=Math.abs(a)%180))return{width:e,height:i};var n=a%90*Math.PI/180,o=Math.sin(n),h=Math.cos(n),r=i*h+e*o,s=i*o+e*h;return 90<a?{width:s,height:r}:{width:r,height:s}}({width:a.naturalWidth*Math.abs(a.scaleX||1),height:a.naturalHeight*Math.abs(a.scaleY||1),degree:a.rotate||0}),o=n.width,h=n.height,r=e.width*(o/e.naturalWidth),s=e.height*(h/e.naturalHeight);e.left-=(r-e.width)/2,e.top-=(s-e.height)/2,e.width=r,e.height=s,e.aspectRatio=o/h,e.naturalWidth=o,e.naturalHeight=h,this.limitCanvas(!0,!1)}(e.width>e.maxWidth||e.width<e.minWidth)&&(e.left=e.oldLeft),(e.height>e.maxHeight||e.height<e.minHeight)&&(e.top=e.oldTop),e.width=Math.min(Math.max(e.width,e.minWidth),e.maxWidth),e.height=Math.min(Math.max(e.height,e.minHeight),e.maxHeight),this.limitCanvas(!1,!0),e.left=Math.min(Math.max(e.left,e.minLeft),e.maxLeft),e.top=Math.min(Math.max(e.top,e.minTop),e.maxTop),e.oldLeft=e.left,e.oldTop=e.top,dt(this.canvas,ht({width:e.width,height:e.height},Et({translateX:e.left,translateY:e.top}))),this.renderImage(t),this.cropped&&this.limited&&this.limitCropBox(!0,!0)},renderImage:function(t){var i=this.canvasData,e=this.imageData,a=e.naturalWidth*(i.width/i.naturalWidth),n=e.naturalHeight*(i.height/i.naturalHeight);ht(e,{width:a,height:n,left:(i.width-a)/2,top:(i.height-n)/2}),dt(this.image,ht({width:e.width,height:e.height},Et(ht({translateX:e.left,translateY:e.top},e)))),t&&this.output()},initCropBox:function(){var t=this.options,i=this.canvasData,e=t.aspectRatio||t.initialAspectRatio,a=Number(t.autoCropArea)||.8,n={width:i.width,height:i.height};e&&(i.height*e>i.width?n.height=n.width/e:n.width=n.height*e),this.cropBoxData=n,this.limitCropBox(!0,!0),n.width=Math.min(Math.max(n.width,n.minWidth),n.maxWidth),n.height=Math.min(Math.max(n.height,n.minHeight),n.maxHeight),n.width=Math.max(n.minWidth,n.width*a),n.height=Math.max(n.minHeight,n.height*a),n.left=i.left+(i.width-n.width)/2,n.top=i.top+(i.height-n.height)/2,n.oldLeft=n.left,n.oldTop=n.top,this.initialCropBoxData=ht({},n)},limitCropBox:function(t,i){var e=this.options,a=this.containerData,n=this.canvasData,o=this.cropBoxData,h=this.limited,r=e.aspectRatio;if(t){var s=Number(e.minCropBoxWidth)||0,c=Number(e.minCropBoxHeight)||0,d=h?Math.min(a.width,n.width,n.width+n.left,a.width-n.left):a.width,l=h?Math.min(a.height,n.height,n.height+n.top,a.height-n.top):a.height;s=Math.min(s,a.width),c=Math.min(c,a.height),r&&(s&&c?s<c*r?c=s/r:s=c*r:s?c=s/r:c&&(s=c*r),d<l*r?l=d/r:d=l*r),o.minWidth=Math.min(s,d),o.minHeight=Math.min(c,l),o.maxWidth=d,o.maxHeight=l}i&&(h?(o.minLeft=Math.max(0,n.left),o.minTop=Math.max(0,n.top),o.maxLeft=Math.min(a.width,n.left+n.width)-o.width,o.maxTop=Math.min(a.height,n.top+n.height)-o.height):(o.minLeft=0,o.minTop=0,o.maxLeft=a.width-o.width,o.maxTop=a.height-o.height))},renderCropBox:function(){var t=this.options,i=this.containerData,e=this.cropBoxData;(e.width>e.maxWidth||e.width<e.minWidth)&&(e.left=e.oldLeft),(e.height>e.maxHeight||e.height<e.minHeight)&&(e.top=e.oldTop),e.width=Math.min(Math.max(e.width,e.minWidth),e.maxWidth),e.height=Math.min(Math.max(e.height,e.minHeight),e.maxHeight),this.limitCropBox(!1,!0),e.left=Math.min(Math.max(e.left,e.minLeft),e.maxLeft),e.top=Math.min(Math.max(e.top,e.minTop),e.maxTop),e.oldLeft=e.left,e.oldTop=e.top,t.movable&&t.cropBoxMovable&&vt(this.face,u,e.width>=i.width&&e.height>=i.height?B:C),dt(this.cropBox,ht({width:e.width,height:e.height},Et({translateX:e.left,translateY:e.top}))),this.cropped&&this.limited&&this.limitCanvas(!0,!0),this.disabled||this.output()},output:function(){this.preview(),Mt(this.element,w,this.getData())}},Yt={initPreview:function(){var e=this.crossOrigin,t=this.options.preview,a=e?this.crossOriginUrl:this.url,i=document.createElement("img");if(e&&(i.crossOrigin=e),i.src=a,this.viewBox.appendChild(i),this.viewBoxImage=i,t){var n=t;"string"==typeof t?n=this.element.ownerDocument.querySelectorAll(t):t.querySelector&&(n=[t]),ot(this.previews=n,function(t){var i=document.createElement("img");vt(t,g,{width:t.offsetWidth,height:t.offsetHeight,html:t.innerHTML}),e&&(i.crossOrigin=e),i.src=a,i.style.cssText='display:block;width:100%;height:auto;min-width:0!important;min-height:0!important;max-width:none!important;max-height:none!important;image-orientation:0deg!important;"',t.innerHTML="",t.appendChild(i)})}},resetPreview:function(){ot(this.previews,function(t){var i=ft(t,g);dt(t,{width:i.width,height:i.height}),t.innerHTML=i.html,function(i,e){if(_(i[e]))try{delete i[e]}catch(t){i[e]=void 0}else if(i.dataset)try{delete i.dataset[e]}catch(t){i.dataset[e]=void 0}else i.removeAttribute("data-".concat(gt(e)))}(t,g)})},preview:function(){var r=this.imageData,t=this.canvasData,i=this.cropBoxData,s=i.width,c=i.height,d=r.width,l=r.height,p=i.left-t.left-r.left,m=i.top-t.top-r.top;this.cropped&&!this.disabled&&(dt(this.viewBoxImage,ht({width:d,height:l},Et(ht({translateX:-p,translateY:-m},r)))),ot(this.previews,function(t){var i=ft(t,g),e=i.width,a=i.height,n=e,o=a,h=1;s&&(o=c*(h=e/s)),c&&a<o&&(n=s*(h=a/c),o=a),dt(t,{width:n,height:o}),dt(t.getElementsByTagName("img")[0],ht({width:d*h,height:l*h},Et(ht({translateX:-p*h,translateY:-m*h},r))))}))}},Xt={bind:function(){var t=this.element,i=this.options,e=this.cropper;et(i.cropstart)&&yt(t,y,i.cropstart),et(i.cropmove)&&yt(t,x,i.cropmove),et(i.cropend)&&yt(t,b,i.cropend),et(i.crop)&&yt(t,w,i.crop),et(i.zoom)&&yt(t,P,i.zoom),yt(e,X,this.onCropStart=this.cropStart.bind(this)),i.zoomable&&i.zoomOnWheel&&yt(e,U,this.onWheel=this.wheel.bind(this),{passive:!1,capture:!0}),i.toggleDragModeOnDblclick&&yt(e,M,this.onDblclick=this.dblclick.bind(this)),yt(t.ownerDocument,R,this.onCropMove=this.cropMove.bind(this)),yt(t.ownerDocument,A,this.onCropEnd=this.cropEnd.bind(this)),i.responsive&&yt(window,I,this.onResize=this.resize.bind(this))},unbind:function(){var t=this.element,i=this.options,e=this.cropper;et(i.cropstart)&&xt(t,y,i.cropstart),et(i.cropmove)&&xt(t,x,i.cropmove),et(i.cropend)&&xt(t,b,i.cropend),et(i.crop)&&xt(t,w,i.crop),et(i.zoom)&&xt(t,P,i.zoom),xt(e,X,this.onCropStart),i.zoomable&&i.zoomOnWheel&&xt(e,U,this.onWheel,{passive:!1,capture:!0}),i.toggleDragModeOnDblclick&&xt(e,M,this.onDblclick),xt(t.ownerDocument,R,this.onCropMove),xt(t.ownerDocument,A,this.onCropEnd),i.responsive&&xt(window,I,this.onResize)}},Rt={resize:function(){var t=this.options,i=this.container,e=this.containerData,a=Number(t.minContainerWidth)||200,n=Number(t.minContainerHeight)||100;if(!(this.disabled||e.width<=a||e.height<=n)){var o,h,r=i.offsetWidth/e.width;if(1!=r||i.offsetHeight!==e.height)t.restore&&(o=this.getCanvasData(),h=this.getCropBoxData()),this.render(),t.restore&&(this.setCanvasData(ot(o,function(t,i){o[i]=t*r})),this.setCropBoxData(ot(h,function(t,i){h[i]=t*r})))}},dblclick:function(){this.disabled||this.options.dragMode===v||this.setDragMode(function(t,i){return t.classList?t.classList.contains(i):-1<t.className.indexOf(i)}(this.dragBox,r)?f:c)},wheel:function(t){var i=this,e=Number(this.options.wheelZoomRatio)||.1,a=1;this.disabled||(t.preventDefault(),this.wheeling||(this.wheeling=!0,setTimeout(function(){i.wheeling=!1},50),t.deltaY?a=0<t.deltaY?1:-1:t.wheelDelta?a=-t.wheelDelta/120:t.detail&&(a=0<t.detail?1:-1),this.zoom(-a*e,t)))},cropStart:function(t){var i=t.buttons,e=t.button;if(!(this.disabled||V(i)&&1!==i||V(e)&&0!==e||t.ctrlKey)){var a,n=this.options,o=this.pointers;t.changedTouches?ot(t.changedTouches,function(t){o[t.identifier]=Wt(t)}):o[t.pointerId||0]=Wt(t),a=1<Object.keys(o).length&&n.zoomable&&n.zoomOnTouch?k:ft(t.target,u),$.test(a)&&!1!==Mt(this.element,y,{originalEvent:t,action:a})&&(t.preventDefault(),this.action=a,this.cropping=!1,a===D&&(this.cropping=!0,lt(this.dragBox,s)))}},cropMove:function(t){var i=this.action;if(!this.disabled&&i){var e=this.pointers;t.preventDefault(),!1!==Mt(this.element,x,{originalEvent:t,action:i})&&(t.changedTouches?ot(t.changedTouches,function(t){ht(e[t.identifier]||{},Wt(t,!0))}):ht(e[t.pointerId||0]||{},Wt(t,!0)),this.change(t))}},cropEnd:function(t){if(!this.disabled){var i=this.action,e=this.pointers;t.changedTouches?ot(t.changedTouches,function(t){delete e[t.identifier]}):delete e[t.pointerId||0],i&&(t.preventDefault(),Object.keys(e).length||(this.action=""),this.cropping&&(this.cropping=!1,mt(this.dragBox,s,this.cropped&&this.options.modal)),Mt(this.element,b,{originalEvent:t,action:i}))}}},At={change:function(t){var i,e=this.options,a=this.canvasData,n=this.containerData,o=this.cropBoxData,h=this.pointers,r=this.action,s=e.aspectRatio,c=o.left,d=o.top,l=o.width,p=o.height,m=c+l,u=d+p,g=0,f=0,v=n.width,w=n.height,b=!0;!s&&t.shiftKey&&(s=l&&p?l/p:1),this.limited&&(g=o.minLeft,f=o.minTop,v=g+Math.min(n.width,a.width,a.left+a.width),w=f+Math.min(n.height,a.height,a.top+a.height));function x(t){switch(t){case T:m+M.x>v&&(M.x=v-m);break;case E:c+M.x<g&&(M.x=g-c);break;case N:d+M.y<f&&(M.y=f-d);break;case W:u+M.y>w&&(M.y=w-u)}}var y=h[Object.keys(h)[0]],M={x:y.endX-y.startX,y:y.endY-y.startY};switch(r){case C:c+=M.x,d+=M.y;break;case T:if(0<=M.x&&(v<=m||s&&(d<=f||w<=u))){b=!1;break}x(T),(l+=M.x)<0&&(r=E,c-=l=-l),s&&(p=l/s,d+=(o.height-p)/2);break;case N:if(M.y<=0&&(d<=f||s&&(c<=g||v<=m))){b=!1;break}x(N),p-=M.y,d+=M.y,p<0&&(r=W,d-=p=-p),s&&(l=p*s,c+=(o.width-l)/2);break;case E:if(M.x<=0&&(c<=g||s&&(d<=f||w<=u))){b=!1;break}x(E),l-=M.x,c+=M.x,l<0&&(r=T,c-=l=-l),s&&(p=l/s,d+=(o.height-p)/2);break;case W:if(0<=M.y&&(w<=u||s&&(c<=g||v<=m))){b=!1;break}x(W),(p+=M.y)<0&&(r=N,d-=p=-p),s&&(l=p*s,c+=(o.width-l)/2);break;case H:if(s){if(M.y<=0&&(d<=f||v<=m)){b=!1;break}x(N),p-=M.y,d+=M.y,l=p*s}else x(N),x(T),0<=M.x?m<v?l+=M.x:M.y<=0&&d<=f&&(b=!1):l+=M.x,M.y<=0?f<d&&(p-=M.y,d+=M.y):(p-=M.y,d+=M.y);l<0&&p<0?(r=z,d-=p=-p,c-=l=-l):l<0?(r=L,c-=l=-l):p<0&&(r=O,d-=p=-p);break;case L:if(s){if(M.y<=0&&(d<=f||c<=g)){b=!1;break}x(N),p-=M.y,d+=M.y,l=p*s,c+=o.width-l}else x(N),x(E),M.x<=0?g<c?(l-=M.x,c+=M.x):M.y<=0&&d<=f&&(b=!1):(l-=M.x,c+=M.x),M.y<=0?f<d&&(p-=M.y,d+=M.y):(p-=M.y,d+=M.y);l<0&&p<0?(r=O,d-=p=-p,c-=l=-l):l<0?(r=H,c-=l=-l):p<0&&(r=z,d-=p=-p);break;case z:if(s){if(M.x<=0&&(c<=g||w<=u)){b=!1;break}x(E),l-=M.x,c+=M.x,p=l/s}else x(W),x(E),M.x<=0?g<c?(l-=M.x,c+=M.x):0<=M.y&&w<=u&&(b=!1):(l-=M.x,c+=M.x),0<=M.y?u<w&&(p+=M.y):p+=M.y;l<0&&p<0?(r=H,d-=p=-p,c-=l=-l):l<0?(r=O,c-=l=-l):p<0&&(r=L,d-=p=-p);break;case O:if(s){if(0<=M.x&&(v<=m||w<=u)){b=!1;break}x(T),p=(l+=M.x)/s}else x(W),x(T),0<=M.x?m<v?l+=M.x:0<=M.y&&w<=u&&(b=!1):l+=M.x,0<=M.y?u<w&&(p+=M.y):p+=M.y;l<0&&p<0?(r=L,d-=p=-p,c-=l=-l):l<0?(r=z,c-=l=-l):p<0&&(r=H,d-=p=-p);break;case B:this.move(M.x,M.y),b=!1;break;case k:this.zoom(function(t){var i=ht({},t),s=[];return ot(t,function(r,t){delete i[t],ot(i,function(t){var i=Math.abs(r.startX-t.startX),e=Math.abs(r.startY-t.startY),a=Math.abs(r.endX-t.endX),n=Math.abs(r.endY-t.endY),o=Math.sqrt(i*i+e*e),h=(Math.sqrt(a*a+n*n)-o)/o;s.push(h)})}),s.sort(function(t,i){return Math.abs(t)<Math.abs(i)}),s[0]}(h),t),b=!1;break;case D:if(!M.x||!M.y){b=!1;break}i=Ct(this.cropper),c=y.startX-i.left,d=y.startY-i.top,l=o.minWidth,p=o.minHeight,0<M.x?r=0<M.y?O:H:M.x<0&&(c-=l,r=0<M.y?z:L),M.y<0&&(d-=p),this.cropped||(pt(this.cropBox,Y),this.cropped=!0,this.limited&&this.limitCropBox(!0,!0))}b&&(o.width=l,o.height=p,o.left=c,o.top=d,this.action=r,this.renderCropBox()),ot(h,function(t){t.startX=t.endX,t.startY=t.endY})}},St={crop:function(){return!this.ready||this.cropped||this.disabled||(this.cropped=!0,this.limitCropBox(!0,!0),this.options.modal&&lt(this.dragBox,s),pt(this.cropBox,Y),this.setCropBoxData(this.initialCropBoxData)),this},reset:function(){return this.ready&&!this.disabled&&(this.imageData=ht({},this.initialImageData),this.canvasData=ht({},this.initialCanvasData),this.cropBoxData=ht({},this.initialCropBoxData),this.renderCanvas(),this.cropped&&this.renderCropBox()),this},clear:function(){return this.cropped&&!this.disabled&&(ht(this.cropBoxData,{left:0,top:0,width:0,height:0}),this.cropped=!1,this.renderCropBox(),this.limitCanvas(!0,!0),this.renderCanvas(),pt(this.dragBox,s),lt(this.cropBox,Y)),this},replace:function(i,t){var e=1<arguments.length&&void 0!==t&&t;return!this.disabled&&i&&(this.isImg&&(this.element.src=i),e?(this.url=i,this.image.src=i,this.ready&&(this.viewBoxImage.src=i,ot(this.previews,function(t){t.getElementsByTagName("img")[0].src=i}))):(this.isImg&&(this.replaced=!0),this.options.data=null,this.uncreate(),this.load(i))),this},enable:function(){return this.ready&&this.disabled&&(this.disabled=!1,pt(this.cropper,o)),this},disable:function(){return this.ready&&!this.disabled&&(this.disabled=!0,lt(this.cropper,o)),this},destroy:function(){var t=this.element;return t[d]&&(t[d]=void 0,this.isImg&&this.replaced&&(t.src=this.originalUrl),this.uncreate()),this},move:function(t,i){var e=1<arguments.length&&void 0!==i?i:t,a=this.canvasData,n=a.left,o=a.top;return this.moveTo(J(t)?t:n+Number(t),J(e)?e:o+Number(e))},moveTo:function(t,i){var e=1<arguments.length&&void 0!==i?i:t,a=this.canvasData,n=!1;return t=Number(t),e=Number(e),this.ready&&!this.disabled&&this.options.movable&&(V(t)&&(a.left=t,n=!0),V(e)&&(a.top=e,n=!0),n&&this.renderCanvas(!0)),this},zoom:function(t,i){var e=this.canvasData;return t=(t=Number(t))<0?1/(1-t):1+t,this.zoomTo(e.width*t/e.naturalWidth,null,i)},zoomTo:function(t,i,e){var a=this.options,n=this.canvasData,o=n.width,h=n.height,r=n.naturalWidth,s=n.naturalHeight;if(0<=(t=Number(t))&&this.ready&&!this.disabled&&a.zoomable){var c=r*t,d=s*t;if(!1===Mt(this.element,P,{ratio:t,oldRatio:o/r,originalEvent:e}))return this;if(e){var l=this.pointers,p=Ct(this.cropper),m=l&&Object.keys(l).length?function(t){var a=0,n=0,o=0;return ot(t,function(t){var i=t.startX,e=t.startY;a+=i,n+=e,o+=1}),{pageX:a/=o,pageY:n/=o}}(l):{pageX:e.pageX,pageY:e.pageY};n.left-=(c-o)*((m.pageX-p.left-n.left)/o),n.top-=(d-h)*((m.pageY-p.top-n.top)/h)}else it(i)&&V(i.x)&&V(i.y)?(n.left-=(c-o)*((i.x-n.left)/o),n.top-=(d-h)*((i.y-n.top)/h)):(n.left-=(c-o)/2,n.top-=(d-h)/2);n.width=c,n.height=d,this.renderCanvas(!0)}return this},rotate:function(t){return this.rotateTo((this.imageData.rotate||0)+Number(t))},rotateTo:function(t){return V(t=Number(t))&&this.ready&&!this.disabled&&this.options.rotatable&&(this.imageData.rotate=t%360,this.renderCanvas(!0,!0)),this},scaleX:function(t){var i=this.imageData.scaleY;return this.scale(t,V(i)?i:1)},scaleY:function(t){var i=this.imageData.scaleX;return this.scale(V(i)?i:1,t)},scale:function(t,i){var e=1<arguments.length&&void 0!==i?i:t,a=this.imageData,n=!1;return t=Number(t),e=Number(e),this.ready&&!this.disabled&&this.options.scalable&&(V(t)&&(a.scaleX=t,n=!0),V(e)&&(a.scaleY=e,n=!0),n&&this.renderCanvas(!0,!0)),this},getData:function(t){var e,i=0<arguments.length&&void 0!==t&&t,a=this.options,n=this.imageData,o=this.canvasData,h=this.cropBoxData;if(this.ready&&this.cropped){e={x:h.left-o.left,y:h.top-o.top,width:h.width,height:h.height};var r=n.width/n.naturalWidth;if(ot(e,function(t,i){e[i]=t/r}),i){var s=Math.round(e.y+e.height),c=Math.round(e.x+e.width);e.x=Math.round(e.x),e.y=Math.round(e.y),e.width=c-e.x,e.height=s-e.y}}else e={x:0,y:0,width:0,height:0};return a.rotatable&&(e.rotate=n.rotate||0),a.scalable&&(e.scaleX=n.scaleX||1,e.scaleY=n.scaleY||1),e},setData:function(t){var i=this.options,e=this.imageData,a=this.canvasData,n={};if(this.ready&&!this.disabled&&it(t)){var o=!1;i.rotatable&&V(t.rotate)&&t.rotate!==e.rotate&&(e.rotate=t.rotate,o=!0),i.scalable&&(V(t.scaleX)&&t.scaleX!==e.scaleX&&(e.scaleX=t.scaleX,o=!0),V(t.scaleY)&&t.scaleY!==e.scaleY&&(e.scaleY=t.scaleY,o=!0)),o&&this.renderCanvas(!0,!0);var h=e.width/e.naturalWidth;V(t.x)&&(n.left=t.x*h+a.left),V(t.y)&&(n.top=t.y*h+a.top),V(t.width)&&(n.width=t.width*h),V(t.height)&&(n.height=t.height*h),this.setCropBoxData(n)}return this},getContainerData:function(){return this.ready?ht({},this.containerData):{}},getImageData:function(){return this.sized?ht({},this.imageData):{}},getCanvasData:function(){var i=this.canvasData,e={};return this.ready&&ot(["left","top","width","height","naturalWidth","naturalHeight"],function(t){e[t]=i[t]}),e},setCanvasData:function(t){var i=this.canvasData,e=i.aspectRatio;return this.ready&&!this.disabled&&it(t)&&(V(t.left)&&(i.left=t.left),V(t.top)&&(i.top=t.top),V(t.width)?(i.width=t.width,i.height=t.width/e):V(t.height)&&(i.height=t.height,i.width=t.height*e),this.renderCanvas(!0)),this},getCropBoxData:function(){var t,i=this.cropBoxData;return this.ready&&this.cropped&&(t={left:i.left,top:i.top,width:i.width,height:i.height}),t||{}},setCropBoxData:function(t){var i,e,a=this.cropBoxData,n=this.options.aspectRatio;return this.ready&&this.cropped&&!this.disabled&&it(t)&&(V(t.left)&&(a.left=t.left),V(t.top)&&(a.top=t.top),V(t.width)&&t.width!==a.width&&(i=!0,a.width=t.width),V(t.height)&&t.height!==a.height&&(e=!0,a.height=t.height),n&&(i?a.height=a.width/n:e&&(a.width=a.height*n)),this.renderCropBox()),this},getCroppedCanvas:function(t){var i=0<arguments.length&&void 0!==t?t:{};if(!this.ready||!window.HTMLCanvasElement)return null;var e=this.canvasData,a=function(t,i,e,a){var n=i.aspectRatio,o=i.naturalWidth,h=i.naturalHeight,r=i.rotate,s=void 0===r?0:r,c=i.scaleX,d=void 0===c?1:c,l=i.scaleY,p=void 0===l?1:l,m=e.aspectRatio,u=e.naturalWidth,g=e.naturalHeight,f=a.fillColor,v=void 0===f?"transparent":f,w=a.imageSmoothingEnabled,b=void 0===w||w,x=a.imageSmoothingQuality,y=void 0===x?"low":x,M=a.maxWidth,C=void 0===M?1/0:M,D=a.maxHeight,B=void 0===D?1/0:D,k=a.minWidth,T=void 0===k?0:k,E=a.minHeight,W=void 0===E?0:E,N=document.createElement("canvas"),H=N.getContext("2d"),L=Nt({aspectRatio:m,width:C,height:B}),O=Nt({aspectRatio:m,width:T,height:W},"cover"),z=Math.min(L.width,Math.max(O.width,u)),Y=Math.min(L.height,Math.max(O.height,g)),X=Nt({aspectRatio:n,width:C,height:B}),R=Nt({aspectRatio:n,width:T,height:W},"cover"),A=Math.min(X.width,Math.max(R.width,o)),S=Math.min(X.height,Math.max(R.height,h)),I=[-A/2,-S/2,A,S];return N.width=st(z),N.height=st(Y),H.fillStyle=v,H.fillRect(0,0,z,Y),H.save(),H.translate(z/2,Y/2),H.rotate(s*Math.PI/180),H.scale(d,p),H.imageSmoothingEnabled=b,H.imageSmoothingQuality=y,H.drawImage.apply(H,[t].concat(j(I.map(function(t){return Math.floor(st(t))})))),H.restore(),N}(this.image,this.imageData,e,i);if(!this.cropped)return a;var n=this.getData(),o=n.x,h=n.y,r=n.width,s=n.height,c=a.width/Math.floor(e.naturalWidth);1!=c&&(o*=c,h*=c,r*=c,s*=c);var d=r/s,l=Nt({aspectRatio:d,width:i.maxWidth||1/0,height:i.maxHeight||1/0}),p=Nt({aspectRatio:d,width:i.minWidth||0,height:i.minHeight||0},"cover"),m=Nt({aspectRatio:d,width:i.width||(1!=c?a.width:r),height:i.height||(1!=c?a.height:s)}),u=m.width,g=m.height;u=Math.min(l.width,Math.max(p.width,u)),g=Math.min(l.height,Math.max(p.height,g));var f=document.createElement("canvas"),v=f.getContext("2d");f.width=st(u),f.height=st(g),v.fillStyle=i.fillColor||"transparent",v.fillRect(0,0,u,g);var w=i.imageSmoothingEnabled,b=void 0===w||w,x=i.imageSmoothingQuality;v.imageSmoothingEnabled=b,x&&(v.imageSmoothingQuality=x);var y,M,C,D,B,k,T=a.width,E=a.height,W=o,N=h;W<=-r||T<W?B=C=y=W=0:W<=0?(C=-W,W=0,B=y=Math.min(T,r+W)):W<=T&&(C=0,B=y=Math.min(r,T-W)),y<=0||N<=-s||E<N?k=D=M=N=0:N<=0?(D=-N,N=0,k=M=Math.min(E,s+N)):N<=E&&(D=0,k=M=Math.min(s,E-N));var H=[W,N,y,M];if(0<B&&0<k){var L=u/r;H.push(C*L,D*L,B*L,k*L)}return v.drawImage.apply(v,[a].concat(j(H.map(function(t){return Math.floor(st(t))})))),f},setAspectRatio:function(t){var i=this.options;return this.disabled||J(t)||(i.aspectRatio=Math.max(0,t)||NaN,this.ready&&(this.initCropBox(),this.cropped&&this.renderCropBox())),this},setDragMode:function(t){var i=this.options,e=this.dragBox,a=this.face;if(this.ready&&!this.disabled){var n=t===c,o=i.movable&&t===f;t=n||o?t:v,i.dragMode=t,vt(e,u,t),mt(e,r,n),mt(e,m,o),i.cropBoxMovable||(vt(a,u,t),mt(a,r,n),mt(a,m,o))}return this}},It=h.Cropper,jt=function(){function e(t){var i=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{};if(function(t,i){if(!(t instanceof i))throw new TypeError("Cannot call a class as a function")}(this,e),!t||!K.test(t.tagName))throw new Error("The first argument is required and must be an <img> or <canvas> element.");this.element=t,this.options=ht({},Z,it(i)&&i),this.cropped=!1,this.disabled=!1,this.pointers={},this.ready=!1,this.reloading=!1,this.replaced=!1,this.sized=!1,this.sizing=!1,this.init()}return function(t,i,e){i&&a(t.prototype,i),e&&a(t,e)}(e,[{key:"init",value:function(){var t,i=this.element,e=i.tagName.toLowerCase();if(!i[d]){if(i[d]=this,"img"===e){if(this.isImg=!0,t=i.getAttribute("src")||"",!(this.originalUrl=t))return;t=i.src}else"canvas"===e&&window.HTMLCanvasElement&&(t=i.toDataURL());this.load(t)}}},{key:"load",value:function(t){var i=this;if(t){this.url=t,this.imageData={};var e=this.element,a=this.options;if(a.rotatable||a.scalable||(a.checkOrientation=!1),a.checkOrientation&&window.ArrayBuffer)if(Q.test(t))this.read(function(t){var i=t.replace(Lt,""),e=atob(i),a=new ArrayBuffer(e.length),n=new Uint8Array(a);return ot(n,function(t,i){n[i]=e.charCodeAt(i)}),a}(t));else{var n=new XMLHttpRequest,o=this.clone.bind(this);this.reloading=!0,(this.xhr=n).onabort=o,n.onerror=o,n.ontimeout=o,n.onprogress=function(){n.getResponseHeader("content-type")!==q&&n.abort()},n.onload=function(){i.read(n.response)},n.onloadend=function(){i.reloading=!1,i.xhr=null},a.checkCrossOrigin&&kt(t)&&e.crossOrigin&&(t=Tt(t)),n.open("GET",t),n.responseType="arraybuffer",n.withCredentials="use-credentials"===e.crossOrigin,n.send()}else this.clone()}}},{key:"read",value:function(t){var i=this.options,e=this.imageData,a=Ot(t),n=0,o=1,h=1;if(1<a){this.url=function(t,i){for(var e=[],a=new Uint8Array(t);0<a.length;)e.push(Ht.apply(null,nt(a.subarray(0,8192)))),a=a.subarray(8192);return"data:".concat(i,";base64,").concat(btoa(e.join("")))}(t,q);var r=function(t){var i=0,e=1,a=1;switch(t){case 2:e=-1;break;case 3:i=-180;break;case 4:a=-1;break;case 5:i=90,a=-1;break;case 6:i=90;break;case 7:i=90,e=-1;break;case 8:i=-90}return{rotate:i,scaleX:e,scaleY:a}}(a);n=r.rotate,o=r.scaleX,h=r.scaleY}i.rotatable&&(e.rotate=n),i.scalable&&(e.scaleX=o,e.scaleY=h),this.clone()}},{key:"clone",value:function(){var t,i,e=this.element,a=this.url;this.options.checkCrossOrigin&&kt(a)&&(t=(t=e.crossOrigin)||"anonymous",i=Tt(a)),this.crossOrigin=t,this.crossOriginUrl=i;var n=document.createElement("img");t&&(n.crossOrigin=t),n.src=i||a,(this.image=n).onload=this.start.bind(this),n.onerror=this.stop.bind(this),lt(n,l),e.parentNode.insertBefore(n,e.nextSibling)}},{key:"start",value:function(){var e=this,t=this.isImg?this.element:this.image;t.onload=null,t.onerror=null,this.sizing=!0;function i(t,i){ht(e.imageData,{naturalWidth:t,naturalHeight:i,aspectRatio:t/i}),e.sizing=!1,e.sized=!0,e.build()}var a=h.navigator&&/(?:iPad|iPhone|iPod).*?AppleWebKit/i.test(h.navigator.userAgent);if(!t.naturalWidth||a){var n=document.createElement("img"),o=document.body||document.documentElement;(this.sizingImage=n).onload=function(){i(n.width,n.height),a||o.removeChild(n)},n.src=t.src,a||(n.style.cssText="left:0;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;opacity:0;position:absolute;top:0;z-index:-1;",o.appendChild(n))}else i(t.naturalWidth,t.naturalHeight)}},{key:"stop",value:function(){var t=this.image;t.onload=null,t.onerror=null,t.parentNode.removeChild(t),this.image=null}},{key:"build",value:function(){if(this.sized&&!this.ready){var t=this.element,i=this.options,e=this.image,a=t.parentNode,n=document.createElement("div");n.innerHTML='<div class="cropper-container" touch-action="none"><div class="cropper-wrap-box"><div class="cropper-canvas"></div></div><div class="cropper-drag-box"></div><div class="cropper-crop-box"><span class="cropper-view-box"></span><span class="cropper-dashed dashed-h"></span><span class="cropper-dashed dashed-v"></span><span class="cropper-center"></span><span class="cropper-face"></span><span class="cropper-line line-e" data-cropper-action="e"></span><span class="cropper-line line-n" data-cropper-action="n"></span><span class="cropper-line line-w" data-cropper-action="w"></span><span class="cropper-line line-s" data-cropper-action="s"></span><span class="cropper-point point-e" data-cropper-action="e"></span><span class="cropper-point point-n" data-cropper-action="n"></span><span class="cropper-point point-w" data-cropper-action="w"></span><span class="cropper-point point-s" data-cropper-action="s"></span><span class="cropper-point point-ne" data-cropper-action="ne"></span><span class="cropper-point point-nw" data-cropper-action="nw"></span><span class="cropper-point point-sw" data-cropper-action="sw"></span><span class="cropper-point point-se" data-cropper-action="se"></span></div></div>';var o=n.querySelector(".".concat(d,"-container")),h=o.querySelector(".".concat(d,"-canvas")),r=o.querySelector(".".concat(d,"-drag-box")),s=o.querySelector(".".concat(d,"-crop-box")),c=s.querySelector(".".concat(d,"-face"));this.container=a,this.cropper=o,this.canvas=h,this.dragBox=r,this.cropBox=s,this.viewBox=o.querySelector(".".concat(d,"-view-box")),this.face=c,h.appendChild(e),lt(t,Y),a.insertBefore(o,t.nextSibling),this.isImg||pt(e,l),this.initPreview(),this.bind(),i.initialAspectRatio=Math.max(0,i.initialAspectRatio)||NaN,i.aspectRatio=Math.max(0,i.aspectRatio)||NaN,i.viewMode=Math.max(0,Math.min(3,Math.round(i.viewMode)))||0,lt(s,Y),i.guides||lt(s.getElementsByClassName("".concat(d,"-dashed")),Y),i.center||lt(s.getElementsByClassName("".concat(d,"-center")),Y),i.background&&lt(o,"".concat(d,"-bg")),i.highlight||lt(c,p),i.cropBoxMovable&&(lt(c,m),vt(c,u,C)),i.cropBoxResizable||(lt(s.getElementsByClassName("".concat(d,"-line")),Y),lt(s.getElementsByClassName("".concat(d,"-point")),Y)),this.render(),this.ready=!0,this.setDragMode(i.dragMode),i.autoCrop&&this.crop(),this.setData(i.data),et(i.ready)&&yt(t,S,i.ready,{once:!0}),Mt(t,S)}}},{key:"unbuild",value:function(){this.ready&&(this.ready=!1,this.unbind(),this.resetPreview(),this.cropper.parentNode.removeChild(this.cropper),pt(this.element,Y))}},{key:"uncreate",value:function(){this.ready?(this.unbuild(),this.ready=!1,this.cropped=!1):this.sizing?(this.sizingImage.onload=null,this.sizing=!1,this.sized=!1):this.reloading?(this.xhr.onabort=null,this.xhr.abort()):this.image&&this.stop()}}],[{key:"noConflict",value:function(){return window.Cropper=It,e}},{key:"setDefaults",value:function(t){ht(Z,it(t)&&t)}}]),e}();return ht(jt.prototype,zt,Yt,Xt,Rt,At,St),jt});
wppa-admin-functions.php CHANGED
@@ -3,7 +3,7 @@
3
  * Package: wp-photo-album-plus
4
  *
5
  * gp admin functions
6
- * Version 7.1.10
7
  *
8
  */
9
 
@@ -451,10 +451,10 @@ global $wpdb;
451
  if ( ! $bret ) return $err;
452
 
453
  // Destroy the source
454
- imagedestroy( $source );
455
 
456
  // Destroy the result
457
- imagedestroy( $rotate );
458
 
459
  // Optimized
460
  wppa_optimize_image_file( $file );
3
  * Package: wp-photo-album-plus
4
  *
5
  * gp admin functions
6
+ * Version 7.2.03
7
  *
8
  */
9
 
451
  if ( ! $bret ) return $err;
452
 
453
  // Destroy the source
454
+ @ imagedestroy( $source );
455
 
456
  // Destroy the result
457
+ @ imagedestroy( $rotate );
458
 
459
  // Optimized
460
  wppa_optimize_image_file( $file );
wppa-admin.php CHANGED
@@ -3,7 +3,7 @@
3
  * Package: wp-photo-album-plus
4
  *
5
  * Contains the admin menu and startups the admin pages
6
- * Version 7.1.04
7
  *
8
  */
9
 
@@ -82,6 +82,11 @@ global $wppa_api_version;
82
  wp_register_style( 'wppa_admin_style', WPPA_URL.'/wppa-admin-styles.css', '', $wppa_api_version );
83
  wp_enqueue_style( 'wppa_admin_style' );
84
 
 
 
 
 
 
85
  // Standard frontend styles
86
  wp_register_style('wppa_style', WPPA_URL.'/theme/wppa-style.css', array(), $wppa_api_version);
87
  wp_enqueue_style('wppa_style');
@@ -110,6 +115,9 @@ global $wppa_api_version;
110
  wp_enqueue_script( 'wppa', WPPA_URL . '/js/wppa.js', array(), $wppa_api_version );
111
  wp_enqueue_script( 'wppa-slideshow', WPPA_URL . '/js/wppa-slideshow.js', array(), $wppa_api_version );
112
  wp_enqueue_script( 'wppa-ajax-front', WPPA_URL . '/js/wppa-ajax-front.js', array(), $wppa_api_version );
 
 
 
113
  // wp_enqueue_script( 'wppa-utils', WPPA_URL . '/js/wppa-utils.js', array(), $wppa_api_version );
114
  // wp_enqueue_script( 'wppa-utils', WPPA_URL . '/js/wppa-utils.js', array(), $wppa_api_version );
115
  /*
3
  * Package: wp-photo-album-plus
4
  *
5
  * Contains the admin menu and startups the admin pages
6
+ * Version 7.2.03
7
  *
8
  */
9
 
82
  wp_register_style( 'wppa_admin_style', WPPA_URL.'/wppa-admin-styles.css', '', $wppa_api_version );
83
  wp_enqueue_style( 'wppa_admin_style' );
84
 
85
+ if ( wppa_opt( 'image_magick' ) ) {
86
+ wp_register_style( 'wppa_cropper_style', WPPA_URL.'/vendor/cropperjs/dist/cropper.min.css' );
87
+ wp_enqueue_style( 'wppa_cropper_style' );
88
+ }
89
+
90
  // Standard frontend styles
91
  wp_register_style('wppa_style', WPPA_URL.'/theme/wppa-style.css', array(), $wppa_api_version);
92
  wp_enqueue_style('wppa_style');
115
  wp_enqueue_script( 'wppa', WPPA_URL . '/js/wppa.js', array(), $wppa_api_version );
116
  wp_enqueue_script( 'wppa-slideshow', WPPA_URL . '/js/wppa-slideshow.js', array(), $wppa_api_version );
117
  wp_enqueue_script( 'wppa-ajax-front', WPPA_URL . '/js/wppa-ajax-front.js', array(), $wppa_api_version );
118
+ if ( wppa_opt( 'image_magick' ) ) {
119
+ wp_enqueue_script( 'cropperjs', WPPA_URL . '/vendor/cropperjs/dist/cropper.min.js', array(), $wppa_api_version );
120
+ }
121
  // wp_enqueue_script( 'wppa-utils', WPPA_URL . '/js/wppa-utils.js', array(), $wppa_api_version );
122
  // wp_enqueue_script( 'wppa-utils', WPPA_URL . '/js/wppa-utils.js', array(), $wppa_api_version );
123
  /*
wppa-ajax.php CHANGED
@@ -2,7 +2,7 @@
2
  /* wppa-ajax.php
3
  *
4
  * Functions used in ajax requests
5
- * Version 7.2.02
6
  *
7
  */
8
 
@@ -1402,6 +1402,7 @@ global $wppa_log_file;
1402
  }
1403
  if ( $photos && $iret !== false ) {
1404
  echo '||0||'.__( 'Tags set to defaults' , 'wp-photo-album-plus');
 
1405
  }
1406
  elseif ( $photos ) {
1407
  echo '||1||'.__( 'An error occurred while setting tags' , 'wp-photo-album-plus');
@@ -1429,6 +1430,7 @@ global $wppa_log_file;
1429
  wppa_index_update( 'photo', $photo['id'] );
1430
  }
1431
  if ( $photos && $iret !== false ) {
 
1432
  echo '||0||'.__( 'Tags added with defaults' , 'wp-photo-album-plus');
1433
  }
1434
  elseif ( $photos ) {
@@ -1453,7 +1455,7 @@ global $wppa_log_file;
1453
  }
1454
  else { // 'inhadd_cats'
1455
  $mycats = wppa_get_album_item( $alb, 'cats' );
1456
- wppa_update_album( array( 'id' => $alb, 'cats' => $mycats . $cats ) );
1457
  }
1458
  }
1459
  }
@@ -1477,7 +1479,7 @@ global $wppa_log_file;
1477
  echo '||5||' . sprintf( __( 'Album name may not be empty.<br />Reset to %s', 'wp-photo-album-plus' ), htmlentities( $value ) );
1478
  }
1479
  $itemname = __( 'Name' , 'wp-photo-album-plus');
1480
- wppa_update_album( array( 'id' => $album, 'name' => $value ) );
1481
  break;
1482
  case 'description':
1483
  $itemname = __( 'Description' , 'wp-photo-album-plus');
@@ -1576,7 +1578,7 @@ global $wppa_log_file;
1576
  if ( $item == 'hour' ) $temp[3] = $value;
1577
  if ( $item == 'min' ) $temp[4] = $value;
1578
  $scheduledtm = implode( ',', $temp );
1579
- wppa_update_album( array( 'id' => $album, 'scheduledtm' => $scheduledtm ) );
1580
  echo '||0||'.sprintf( __( '%s of album %s updated', 'wp-photo-album-plus' ), $itemname, htmlentities( $album ) );
1581
  wppa_exit();
1582
  break;
@@ -1640,6 +1642,7 @@ global $wppa_log_file;
1640
  if ( ! $a ) echo 'full';
1641
  else echo 'notfull||'.$a;
1642
  }
 
1643
  }
1644
  else {
1645
  echo '||2||'.sprintf( __( 'An error occurred while trying to update %s of album %s' , 'wp-photo-album-plus'), $itemname, htmlentities( $album ) );
@@ -1707,6 +1710,8 @@ global $wppa_log_file;
1707
  wppa_exit();
1708
  }
1709
 
 
 
1710
  case 'update-photo':
1711
  $photo = wppa_decrypt_photo( $_REQUEST['photo-id'], false, true );
1712
  $photo = strval( intval( $photo ) );
@@ -1717,14 +1722,14 @@ global $wppa_log_file;
1717
 
1718
  // Check validity
1719
  if ( ! wp_verify_nonce( $nonce, 'wppa_nonce_'.$photo ) ) {
1720
- echo '||0||'.__( 'You do not have the rights to update photo information' , 'wp-photo-album-plus');
1721
- wppa_exit(); // Nonce check failed
1722
  }
1723
 
1724
  if ( substr( $item, 0, 20 ) == 'wppa_watermark_file_' || substr( $item, 0, 19 ) == 'wppa_watermark_pos_' ) {
1725
  wppa_update_option( $item, $value );
1726
- echo '||0||'.sprintf( __( '%s updated to %s.' , 'wp-photo-album-plus'), $item, $value );
1727
- wppa_exit();
1728
  }
1729
 
1730
  switch ( $item ) {
@@ -1773,18 +1778,19 @@ global $wppa_log_file;
1773
  if ( ! $err && $temp['5'] > '59' ) $err = '23'; // Sec > 59
1774
  }
1775
  if ( $err ) {
1776
- echo '||1||'.sprintf(__( 'Format error %s. Must be yyyy:mm:dd hh:mm:ss' , 'wp-photo-album-plus'), $err );
 
1777
  }
1778
  else {
1779
  wppa_update_photo( array( 'id' => $photo, 'exifdtm' => $value ) );
1780
- echo '||0||'.__( 'Exif date/time updated' , 'wp-photo-album-plus');
 
1781
  }
1782
- wppa_exit();
1783
  break;
1784
  case 'lat':
1785
  if ( ! is_numeric( $value ) || $value < '-90.0' || $value > '90.0' ) {
1786
- echo '||1||'.__( 'Enter a value > -90 and < 90' , 'wp-photo-album-plus');
1787
- wppa_exit();
1788
  }
1789
  $photodata = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->wppa_photos
1790
  WHERE id = %d", $photo ), ARRAY_A );
@@ -1794,16 +1800,20 @@ global $wppa_log_file;
1794
  $iret = $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->wppa_photos
1795
  SET location = %s
1796
  WHERE id = %d", $geo, $photo ) );
1797
- if ( $iret ) echo '||0||'.__( 'Lattitude updated' , 'wp-photo-album-plus');
 
 
 
1798
  else {
1799
- echo '||1||'.__( 'Could not update latitude' , 'wp-photo-album-plus');
 
1800
  }
1801
- wppa_exit();
1802
  break;
1803
  case 'lon':
1804
  if ( ! is_numeric( $value ) || $value < '-180.0' || $value > '180.0' ) {
1805
- echo '||1||'.__( 'Enter a value > -180 and < 180' , 'wp-photo-album-plus');
1806
- wppa_exit();
1807
  }
1808
  $photodata = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->wppa_photos
1809
  WHERE id = %d", $photo ), ARRAY_A );
@@ -1813,31 +1823,41 @@ global $wppa_log_file;
1813
  $iret = $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->wppa_photos
1814
  SET location = %s
1815
  WHERE id = %d", $geo, $photo ) );
1816
- if ( $iret ) echo '||0||'.__( 'Longitude updated' , 'wp-photo-album-plus');
 
 
 
1817
  else {
1818
- echo '||1||'.__( 'Could not update longitude' , 'wp-photo-album-plus');
 
1819
  }
1820
- wppa_exit();
1821
  break;
1822
  case 'remake':
 
 
 
 
 
 
1823
  if ( wppa_remake_files( '', $photo ) ) {
1824
- wppa_bump_photo_rev();
1825
- wppa_bump_thumb_rev();
1826
- echo '||0||'.__( 'Photo files remade' , 'wp-photo-album-plus');
1827
  }
1828
  else {
1829
- echo '||2||'.__( 'Could not remake files' , 'wp-photo-album-plus');
 
1830
  }
1831
- wppa_exit();
1832
  break;
1833
  case 'remakethumb':
1834
  if ( wppa_create_thumbnail( $photo ) ) {
1835
- echo '||0||'.__( 'Thumbnail remade' , 'wp-photo-album-plus');
 
1836
  }
1837
  else {
1838
- echo '||0||'.__( 'Could not remake thumbnail' , 'wp-photo-album-plus');
 
1839
  }
1840
- wppa_exit();
1841
  break;
1842
  case 'rotright':
1843
  case 'rot180':
@@ -1859,25 +1879,31 @@ global $wppa_log_file;
1859
  $dir = '';
1860
  break;
1861
  }
1862
- wppa( 'error', wppa_rotate( $photo, $item ) );
1863
- if ( ! wppa( 'error' ) ) {
 
1864
  wppa_update_modified( $photo );
1865
- wppa_bump_photo_rev();
1866
- wppa_bump_thumb_rev();
 
 
 
 
1867
  if ( $item == 'flip' ) {
1868
- echo '||0||'.sprintf( __( 'Photo flipped' , 'wp-photo-album-plus'), $photo );
1869
  }
1870
  elseif ( $item == 'flop' ) {
1871
- echo '||0||'.sprintf( __( 'Photo flipped' , 'wp-photo-album-plus'), $photo );
1872
  }
1873
  else {
1874
- echo '||0||'.sprintf( __( 'Photo %s rotated %s' , 'wp-photo-album-plus'), $photo, $dir );
1875
  }
 
1876
  }
1877
  else {
1878
- echo '||'.wppa( 'error' ).'||'.sprintf( __( 'An error occurred while trying to rotate or flip photo %s' , 'wp-photo-album-plus'), $photo );
 
1879
  }
1880
- wppa_exit();
1881
  break;
1882
  case 'magickrotleft':
1883
  case 'magickrot180':
@@ -1901,6 +1927,7 @@ global $wppa_log_file;
1901
  case 'sepia':
1902
  case 'skyleft':
1903
  case 'skyright':
 
1904
  $id = $photo;
1905
  $src_o1_path = wppa_get_o1_source_path( $id );
1906
  $src_path = wppa_get_source_path( $id );
@@ -1987,6 +2014,9 @@ global $wppa_log_file;
1987
  case 'skyright':
1988
  $command = '-rotate 0.5 -shave ' . ( ceil( 0.0087 * wppa_get_photoy( $photo ) ) + 1 ) . 'x' . ( ceil( 0.0087 * wppa_get_photox( $photo ) ) + 1 );
1989
  break;
 
 
 
1990
  }
1991
 
1992
  $path = wppa_get_photo_path( $id );
@@ -2003,7 +2033,8 @@ global $wppa_log_file;
2003
 
2004
  // Error?
2005
  if ( $err ) {
2006
- echo '||'.$err.'||'.sprintf( __( 'An error occurred while trying to process photo %s' , 'wp-photo-album-plus' ), $id );
 
2007
  }
2008
 
2009
  // Housekeeping
@@ -2014,7 +2045,6 @@ global $wppa_log_file;
2014
  wppa_get_photox( $id, true );
2015
  }
2016
 
2017
- wppa_bump_photo_rev();
2018
  wppa_create_thumbnail( $id, false );
2019
  $stack = wppa_get_photo_item( $id, 'magickstack' );
2020
  if ( ! $stack ) {
@@ -2023,7 +2053,7 @@ global $wppa_log_file;
2023
  else {
2024
  $stack .= ' | ' . $command;
2025
  }
2026
- wppa_update_photo( array( 'id' => $id, 'magickstack' => $stack ) );
2027
 
2028
  // Update CDN
2029
  $cdn = wppa_cdn( 'admin' );
@@ -2033,21 +2063,17 @@ global $wppa_log_file;
2033
  wppa_upload_to_cloudinary( $id );
2034
  break;
2035
  case 'local':
 
2036
  break;
2037
  default:
2038
  wppa_dbg_msg( 'Missing upload instructions for '.$cdn, 'red', 'force' );
2039
  }
2040
  }
2041
 
2042
- echo
2043
- '||0||' .
2044
- sprintf( __( 'Command %s magically executed on photo %s', 'wp-photo-album-plus' ), '<span style="color:blue;" ><i>'.$command.'</i></span>', $id ) .
2045
- '||' . get_option( 'wppa_photo_version' ) . '||' . get_option( 'wppa_thumb_version' ) . '||' . $stack .
2046
- '||' . floor( wppa_get_photox( $id ) ) . ' x ' . floor( wppa_get_photoy( $id ) ).' px, ' . wppa_get_filesize( wppa_get_photo_path( $id ) ) . '.';
2047
- }
2048
 
2049
- // Done
2050
- wppa_exit();
2051
  break;
2052
 
2053
  case 'magickundo':
@@ -2074,25 +2100,8 @@ global $wppa_log_file;
2074
  wppa_create_thumbnail( $photo, false );
2075
  wppa_update_photo( array( 'id' => $photo, 'magickstack' => $newstack ) );
2076
 
2077
- // Update CDN
2078
- $cdn = wppa_cdn( 'admin' );
2079
- if ( $cdn ) {
2080
- switch ( $cdn ) {
2081
- case 'cloudinary':
2082
- wppa_upload_to_cloudinary( $photo );
2083
- break;
2084
- case 'local':
2085
- break;
2086
- default:
2087
- wppa_dbg_msg( 'Missing upload instructions for '.$cdn, 'red', 'force' );
2088
- }
2089
- }
2090
-
2091
- echo
2092
- '||0||' .
2093
- sprintf( __( 'Command %s magically executed on photo %s', 'wp-photo-album-plus' ), '<span style="color:blue;" ><i>'.$item.'</i></span>', $photo ) .
2094
- '||' . get_option( 'wppa_photo_version' ) . '||' . get_option( 'wppa_thumb_version' ) . '||' . $newstack;
2095
- wppa_exit();
2096
  break;
2097
 
2098
  case 'moveto':
@@ -2102,29 +2111,30 @@ global $wppa_log_file;
2102
  if ( wppa_switch( 'void_dups' ) ) { // Check for already exists
2103
  $exists = wppa_is_file_duplicate_photo( $photodata['filename'], $value );
2104
  if ( $exists ) { // Already exists
2105
- echo '||3||' . sprintf ( __( 'A photo with filename %s already exists in album %s.' , 'wp-photo-album-plus'), $photodata['filename'], $value );
2106
- wppa_exit();
2107
  break;
2108
  }
2109
  }
2110
  if ( ! wppa_album_exists( $value ) ) {
2111
- echo '||4||' . sprintf( __( 'Album %s does not exist', 'wp-photo-album-plus' ), $value );
2112
- wppa_exit();
2113
  break;
2114
  }
2115
  wppa_invalidate_treecounts( $photodata['album'] ); // Current album
2116
  wppa_invalidate_treecounts( $value ); // New album
2117
  $iret = wppa_update_photo( array( 'id' => $photo, 'album' => $value ) );
2118
  $edit_link = wppa_ea_url( 'single', $tab = 'edit' ) . '&photo=' . $photodata['id'];
2119
- if ( $iret !== false ) {
2120
  wppa_move_source( $photodata['filename'], $photodata['album'], $value );
2121
  echo '||99||'.sprintf( __( 'Photo %s has been moved to album %s (%s)' , 'wp-photo-album-plus'), '<a href="'.$edit_link.'" target="_blank" >' . $photodata['id'] . '</a>', wppa_get_album_name( $value ), $value );
2122
-
2123
  }
2124
  else {
2125
- echo '||3||'.sprintf( __( 'An error occurred while trying to move photo %s' , 'wp-photo-album-plus'), $photo );
 
 
2126
  }
2127
- wppa_exit();
2128
  break;
2129
 
2130
  case 'copyto':
@@ -2134,26 +2144,26 @@ global $wppa_log_file;
2134
  if ( wppa_switch( 'void_dups' ) ) { // Check for already exists
2135
  $exists = wppa_is_file_duplicate_photo( $photodata['filename'], $value );
2136
  if ( $exists ) { // Already exists
2137
- echo '||4||' . sprintf( __( 'A photo with filename %s already exists in album %s.' , 'wp-photo-album-plus'), $photodata['filename'], $value );
2138
- wppa_exit();
2139
  break;
2140
  }
2141
  }
2142
  if ( ! wppa_album_exists( $value ) ) {
2143
- echo '||4||' . sprintf( __( 'Album %s does not exist', 'wp-photo-album-plus' ), $value );
2144
- wppa_exit();
2145
  break;
2146
  }
2147
  wppa( 'error', wppa_copy_photo( $photo, $value ) );
2148
  wppa_invalidate_treecounts( $value ); // New album
2149
  if ( ! wppa( 'error' ) ) {
2150
- echo '||0||'.sprintf( __( 'Photo %s copied to album %s (%s)' , 'wp-photo-album-plus'), $photo, wppa_get_album_name( $value ), $value );
 
2151
  }
2152
  else {
2153
- echo '||4||'.sprintf( __( 'An error occurred while trying to copy photo %s' , 'wp-photo-album-plus'), $photo ).' wppa_copy_photo() returned '.wppa('error');
2154
- echo '<br>'.__( 'Press CTRL+F5 and try again.' , 'wp-photo-album-plus');
2155
  }
2156
- wppa_exit();
2157
  break;
2158
 
2159
  case 'status':
@@ -2233,15 +2243,15 @@ global $wppa_log_file;
2233
  case 'videox':
2234
  $itemname = __( 'Video width' , 'wp-photo-album-plus');
2235
  if ( ! wppa_is_int( $value ) || $value < '0' ) {
2236
- echo '||3||'.__( 'Please enter an integer value >= 0' , 'wp-photo-album-plus');
2237
- wppa_exit();
2238
  }
2239
  break;
2240
  case 'videoy':
2241
  $itemname = __( 'Video height', 'wp-photo-album-plus');
2242
  if ( ! wppa_is_int( $value ) || $value < '0' ) {
2243
- echo '||3||'.__( 'Please enter an integer value >= 0' , 'wp-photo-album-plus');
2244
- wppa_exit();
2245
  }
2246
  break;
2247
 
@@ -2258,16 +2268,18 @@ global $wppa_log_file;
2258
  if ( $iret !== false ) {
2259
  wppa_update_modified( $photo );
2260
  if ( wppa_is_video( $photo ) ) {
2261
- echo '||0||'.sprintf( __( '%s of video %s updated' , 'wp-photo-album-plus'), $itemname, $photo );
2262
  }
2263
  else {
2264
- echo '||0||'.sprintf( __( '%s of photo %s updated' , 'wp-photo-album-plus'), $itemname, $photo );
2265
  }
 
2266
  }
2267
  else {
2268
- echo '||2||'.sprintf( __( 'An error occurred while trying to update %s of photo %s' , 'wp-photo-album-plus'), $itemname, $photo );
2269
- wppa_exit();
2270
  }
 
2271
  break;
2272
 
2273
  case 'year':
@@ -2291,11 +2303,12 @@ global $wppa_log_file;
2291
  wppa_invalidate_treecounts( $wpdb->get_var( $wpdb->prepare( "SELECT album FROM $wpdb->wppa_photos WHERE id = %s", $photo ) ) );
2292
  wppa_flush_upldr_cache( 'photoid', $photo );
2293
  if ( wppa_is_video( $photo ) ) {
2294
- echo '||0||'.sprintf( __( '%s of video %s updated' , 'wp-photo-album-plus'), $itemname, $photo );
2295
  }
2296
  else {
2297
- echo '||0||'.sprintf( __( '%s of photo %s updated' , 'wp-photo-album-plus'), $itemname, $photo );
2298
  }
 
2299
  break;
2300
 
2301
  case 'delyear':
@@ -2326,20 +2339,24 @@ global $wppa_log_file;
2326
  wppa_invalidate_treecounts( $alb );
2327
  wppa_flush_upldr_cache( 'photoid', $photo );
2328
  if ( wppa_is_video( $photo ) ) {
2329
- echo '||0||'.sprintf( __( '%s of video %s updated' , 'wp-photo-album-plus'), $itemname, $photo );
2330
  }
2331
  else {
2332
- echo '||0||'.sprintf( __( '%s of photo %s updated' , 'wp-photo-album-plus'), $itemname, $photo );
2333
  }
 
2334
  break;
2335
  case 'removescheduledel':
2336
  if ( ( current_user_can( 'wppa_admin' ) || current_user_can( 'wppa_moderate' ) ) ) {
2337
  wppa_update_photo( array( 'id' => $photo, 'scheduledel' => '' ) );
2338
- echo '||0||'.sprintf( __( 'Scheduled deletion of photo %s cancelled' , 'wp-photo-album-plus'), $photo );
 
2339
  }
2340
  else {
2341
- echo '||2||'. __( 'No rights' , 'wp-photo-album-plus');
 
2342
  }
 
2343
  break;
2344
 
2345
  case 'custom_0':
@@ -2364,14 +2381,16 @@ global $wppa_log_file;
2364
  $custom = serialize( $custom_data );
2365
  wppa_update_photo( array( 'id' => $photo, 'custom' => $custom, 'modified' => time() ) );
2366
  wppa_index_update( 'photo', $photo );
2367
- echo '||0||'.sprintf( __( 'Custom field %s of photo %s updated' , 'wp-photo-album-plus'), wppa_opt( 'custom_caption_'.$index ), $photo );
 
2368
  break;
2369
 
2370
  case 'file':
2371
 
2372
  // Check on upload error
2373
  if ( $_FILES['photo']['error'] ) {
2374
- echo '||'.$_FILES['photo']['error'].'||'.__( 'Error during upload.', 'wp-photo-album-plus');
 
2375
  wppa_exit();
2376
  }
2377
 
@@ -2414,14 +2433,15 @@ global $wppa_log_file;
2414
  ) );
2415
 
2416
  // Report success
2417
- echo '||0||'.__( 'Photo files updated.' , 'wp-photo-album-plus');
 
2418
  }
2419
  else {
2420
 
2421
  // Report fail
2422
- echo '||1||'.__( 'Could not update files.' , 'wp-photo-album-plus');
 
2423
  }
2424
- wppa_exit();
2425
  break;
2426
 
2427
  case 'stereo':
@@ -2430,23 +2450,30 @@ global $wppa_log_file;
2430
  wppa_create_stereo_images( $photo );
2431
  wppa_create_thumbnail( $photo );
2432
  $t = microtime(true) - $t;
2433
- echo '||0||' . sprintf( __( 'Stereo mode updated in %d milliseconds', 'wp-photo-album-plus'), floor( $t * 1000 ) );
2434
- wppa_exit();
2435
  break;
2436
 
2437
  case 'panorama':
2438
  wppa_update_photo( array( 'id' => $photo, 'panorama' => $value ) );
2439
- echo '||0||' . 'Panorama set to '.$value;
2440
- wppa_exit();
 
 
 
 
 
 
2441
  break;
2442
 
2443
  default:
2444
- echo '||98||This update action is not implemented yet( '.$item.' )';
2445
- wppa_exit();
2446
  }
2447
- wppa_clear_cache();
2448
  break;
2449
 
 
 
2450
  // The wppa-settings page calls ajax with $wppa_action == 'update-option';
2451
  case 'update-option':
2452
 
@@ -3446,17 +3473,19 @@ global $wppa_log_file;
3446
  break;
3447
  case 'wppa_image_magick':
3448
  $value = rtrim( $value, '/' );
3449
- $out = array();
3450
- exec( escapeshellcmd( $value . '/convert' ), $out, $err );
3451
- $ok = ( count( $out ) != 0 );
3452
- if ( $ok ) {
3453
- $out = array_reverse( $out );
3454
- array_push( $out, 'Setting magick path returned:' );
3455
- wppa_log( 'dbg', var_export( $out, true ) );
3456
- }
3457
- else {
3458
- wppa( 'error', '4713' );
3459
- $alert .= __( 'This path does not contain ImageMagick commands', 'wp-photo-album-plus' );
 
 
3460
  }
3461
  break;
3462
  case 'wppa_grant_cats':
@@ -3694,4 +3723,116 @@ function wppa_secfail( $id, $prolog = '' ) {
3694
  $text = sprintf( __( 'Security check failure %d', 'wp-photo-album-plus' ), $id );
3695
  echo ( $prolog . ' ' . $text );
3696
  wppa_exit();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3697
  }
2
  /* wppa-ajax.php
3
  *
4
  * Functions used in ajax requests
5
+ * Version 7.2.03
6
  *
7
  */
8
 
1402
  }
1403
  if ( $photos && $iret !== false ) {
1404
  echo '||0||'.__( 'Tags set to defaults' , 'wp-photo-album-plus');
1405
+ wppa_update_album( $album );
1406
  }
1407
  elseif ( $photos ) {
1408
  echo '||1||'.__( 'An error occurred while setting tags' , 'wp-photo-album-plus');
1430
  wppa_index_update( 'photo', $photo['id'] );
1431
  }
1432
  if ( $photos && $iret !== false ) {
1433
+ wppa_update_album( $album );
1434
  echo '||0||'.__( 'Tags added with defaults' , 'wp-photo-album-plus');
1435
  }
1436
  elseif ( $photos ) {
1455
  }
1456
  else { // 'inhadd_cats'
1457
  $mycats = wppa_get_album_item( $alb, 'cats' );
1458
+ wppa_update_album( array( 'id' => $alb, 'cats' => $mycats . $cats, 'modified' => time() ) );
1459
  }
1460
  }
1461
  }
1479
  echo '||5||' . sprintf( __( 'Album name may not be empty.<br />Reset to %s', 'wp-photo-album-plus' ), htmlentities( $value ) );
1480
  }
1481
  $itemname = __( 'Name' , 'wp-photo-album-plus');
1482
+ wppa_update_album( array( 'id' => $album, 'name' => $value, 'modified' => time() ) );
1483
  break;
1484
  case 'description':
1485
  $itemname = __( 'Description' , 'wp-photo-album-plus');
1578
  if ( $item == 'hour' ) $temp[3] = $value;
1579
  if ( $item == 'min' ) $temp[4] = $value;
1580
  $scheduledtm = implode( ',', $temp );
1581
+ wppa_update_album( array( 'id' => $album, 'scheduledtm' => $scheduledtm, 'modified' => time() ) );
1582
  echo '||0||'.sprintf( __( '%s of album %s updated', 'wp-photo-album-plus' ), $itemname, htmlentities( $album ) );
1583
  wppa_exit();
1584
  break;
1642
  if ( ! $a ) echo 'full';
1643
  else echo 'notfull||'.$a;
1644
  }
1645
+ wppa_update_album( $album );
1646
  }
1647
  else {
1648
  echo '||2||'.sprintf( __( 'An error occurred while trying to update %s of album %s' , 'wp-photo-album-plus'), $itemname, htmlentities( $album ) );
1710
  wppa_exit();
1711
  }
1712
 
1713
+ /* START UPDATE PHOTO */
1714
+
1715
  case 'update-photo':
1716
  $photo = wppa_decrypt_photo( $_REQUEST['photo-id'], false, true );
1717
  $photo = strval( intval( $photo ) );
1722
 
1723
  // Check validity
1724
  if ( ! wp_verify_nonce( $nonce, 'wppa_nonce_'.$photo ) ) {
1725
+ $txt = __( 'You do not have the rights to update photo information' , 'wp-photo-album-plus');
1726
+ wppa_json_photo_update( $photo, $txt, '1' ); // Nonce check failed
1727
  }
1728
 
1729
  if ( substr( $item, 0, 20 ) == 'wppa_watermark_file_' || substr( $item, 0, 19 ) == 'wppa_watermark_pos_' ) {
1730
  wppa_update_option( $item, $value );
1731
+ $txt = sprintf( __( '%s updated to %s.' , 'wp-photo-album-plus'), $item, $value );
1732
+ wppa_json_photo_update( $photo, $txt );
1733
  }
1734
 
1735
  switch ( $item ) {
1778
  if ( ! $err && $temp['5'] > '59' ) $err = '23'; // Sec > 59
1779
  }
1780
  if ( $err ) {
1781
+ $txt = sprintf( __( 'Format error %s. Must be yyyy:mm:dd hh:mm:ss' , 'wp-photo-album-plus'), $err );
1782
+ wppa_json_photo_update( $photo, $txt, '1' );
1783
  }
1784
  else {
1785
  wppa_update_photo( array( 'id' => $photo, 'exifdtm' => $value ) );
1786
+ $txt = __( 'Exif date/time updated' , 'wp-photo-album-plus');
1787
+ wppa_json_photo_update( $photo, $txt );
1788
  }
 
1789
  break;
1790
  case 'lat':
1791
  if ( ! is_numeric( $value ) || $value < '-90.0' || $value > '90.0' ) {
1792
+ $txt = __( 'Enter a value > -90 and < 90' , 'wp-photo-album-plus');
1793
+ wppa_json_photo_update( $photo, $txt, '1' );
1794
  }
1795
  $photodata = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->wppa_photos
1796
  WHERE id = %d", $photo ), ARRAY_A );
1800
  $iret = $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->wppa_photos
1801
  SET location = %s
1802
  WHERE id = %d", $geo, $photo ) );
1803
+ if ( $iret ) {
1804
+ $txt = __( 'Lattitude updated' , 'wp-photo-album-plus');
1805
+ $err = '0';
1806
+ }
1807
  else {
1808
+ $txt = __( 'Could not update latitude' , 'wp-photo-album-plus');
1809
+ $err = '1';
1810
  }
1811
+ wppa_json_photo_update( $photo, $txt, $err );
1812
  break;
1813
  case 'lon':
1814
  if ( ! is_numeric( $value ) || $value < '-180.0' || $value > '180.0' ) {
1815
+ $txt = __( 'Enter a value > -180 and < 180' , 'wp-photo-album-plus');
1816
+ wppa_json_photo_update( $photo, $txt, '1' );
1817
  }
1818
  $photodata = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->wppa_photos
1819
  WHERE id = %d", $photo ), ARRAY_A );
1823
  $iret = $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->wppa_photos
1824
  SET location = %s
1825
  WHERE id = %d", $geo, $photo ) );
1826
+ if ( $iret ) {
1827
+ $txt = __( 'Longitude updated' , 'wp-photo-album-plus' );
1828
+ $err = '0';
1829
+ }
1830
  else {
1831
+ $txt = __( 'Could not update longitude' , 'wp-photo-album-plus' );
1832
+ $err = '1';
1833
  }
1834
+ wppa_json_photo_update( $photo, $txt, $err );
1835
  break;
1836
  case 'remake':
1837
+ if ( wppa_get_photo_item( $photo, 'thumblock' ) ) {
1838
+ $extra = '<span style=\"color:red;\" > ' . __( 'The thumbnail could not be remade', 'wp-photo-album-plus' ) . '</span>';
1839
+ }
1840
+ else {
1841
+ $extra = '';
1842
+ }
1843
  if ( wppa_remake_files( '', $photo ) ) {
1844
+ $txt = __( 'Photo files remade' , 'wp-photo-album-plus' ) . $extra;
1845
+ wppa_json_photo_update( $photo, $txt, '0', ( $extra ? false : true ), true );
 
1846
  }
1847
  else {
1848
+ $txt = __( 'Could not remake files' , 'wp-photo-album-plus');
1849
+ wppa_json_photo_update( $photo, $txt, '1' );
1850
  }
 
1851
  break;
1852
  case 'remakethumb':
1853
  if ( wppa_create_thumbnail( $photo ) ) {
1854
+ $txt = __( 'Thumbnail remade' , 'wp-photo-album-plus' );
1855
+ wppa_json_photo_update( $photo, $txt, '0', true );
1856
  }
1857
  else {
1858
+ $txt = __( 'Could not remake thumbnail', 'wp-photo-album-plus' );
1859
+ wppa_json_photo_update( $photo, $txt, '1' );
1860
  }
 
1861
  break;
1862
  case 'rotright':
1863
  case 'rot180':
1879
  $dir = '';
1880
  break;
1881
  }
1882
+ $err = wppa_rotate( $photo, $item );
1883
+ wppa( 'error', $err );
1884
+ if ( ! $err || $err == '30' ) {
1885
  wppa_update_modified( $photo );
1886
+ if ( wppa_get_photo_item( $photo, 'thumblock' ) ) {
1887
+ $extra = '<span style=\"color:red\" > ' . __( 'The thumbnail could not be remade', 'wp-photo-album-plus' ) . '</span>';
1888
+ }
1889
+ else {
1890
+ $extra = '';
1891
+ }
1892
  if ( $item == 'flip' ) {
1893
+ $txt = sprintf( __( 'Photo flipped' , 'wp-photo-album-plus'), $photo ) . $extra;
1894
  }
1895
  elseif ( $item == 'flop' ) {
1896
+ $txt = sprintf( __( 'Photo flipped' , 'wp-photo-album-plus'), $photo ) . $extra;
1897
  }
1898
  else {
1899
+ $txt = sprintf( __( 'Photo %s rotated %s' , 'wp-photo-album-plus'), $photo, $dir ) . $extra;
1900
  }
1901
+ wppa_json_photo_update( $photo, $txt, '0', true, true );
1902
  }
1903
  else {
1904
+ $txt = __( 'An error occurred while trying to rotate or flip photo' , 'wp-photo-album-plus' );
1905
+ wppa_json_photo_update( $photo, $txt, '1' );
1906
  }
 
1907
  break;
1908
  case 'magickrotleft':
1909
  case 'magickrot180':
1927
  case 'sepia':
1928
  case 'skyleft':
1929
  case 'skyright':
1930
+ case 'crop':
1931
  $id = $photo;
1932
  $src_o1_path = wppa_get_o1_source_path( $id );
1933
  $src_path = wppa_get_source_path( $id );
2014
  case 'skyright':
2015
  $command = '-rotate 0.5 -shave ' . ( ceil( 0.0087 * wppa_get_photoy( $photo ) ) + 1 ) . 'x' . ( ceil( 0.0087 * wppa_get_photox( $photo ) ) + 1 );
2016
  break;
2017
+ case 'crop':
2018
+ $command = '-crop ' . $value;
2019
+ break;
2020
  }
2021
 
2022
  $path = wppa_get_photo_path( $id );
2033
 
2034
  // Error?
2035
  if ( $err ) {
2036
+ $txt = __( 'An error occurred while trying to process photo', 'wp-photo-album-plus' );
2037
+ wppa_json_photo_update( $photo, $txt, $err = '1' );
2038
  }
2039
 
2040
  // Housekeeping
2045
  wppa_get_photox( $id, true );
2046
  }
2047
 
 
2048
  wppa_create_thumbnail( $id, false );
2049
  $stack = wppa_get_photo_item( $id, 'magickstack' );
2050
  if ( ! $stack ) {
2053
  else {
2054
  $stack .= ' | ' . $command;
2055
  }
2056
+ wppa_update_photo( array( 'id' => $id, 'magickstack' => $stack, 'modified' => time() ) );
2057
 
2058
  // Update CDN
2059
  $cdn = wppa_cdn( 'admin' );
2063
  wppa_upload_to_cloudinary( $id );
2064
  break;
2065
  case 'local':
2066
+ /* */
2067
  break;
2068
  default:
2069
  wppa_dbg_msg( 'Missing upload instructions for '.$cdn, 'red', 'force' );
2070
  }
2071
  }
2072
 
2073
+ $txt = sprintf( __( 'Command %s magically executed on photo %s', 'wp-photo-album-plus' ), '<span style=\"color:blue;\" ><i>'.$command.'</i></span>', $id );
 
 
 
 
 
2074
 
2075
+ wppa_json_photo_update( $photo, $txt, '0', true, true, true );
2076
+ }
2077
  break;
2078
 
2079
  case 'magickundo':
2100
  wppa_create_thumbnail( $photo, false );
2101
  wppa_update_photo( array( 'id' => $photo, 'magickstack' => $newstack ) );
2102
 
2103
+ $txt = sprintf( __( 'Command %s magically executed on photo %s', 'wp-photo-album-plus' ), '<span style=\"color:blue;\" ><i>magickundo</i></span>', $photo );
2104
+ wppa_json_photo_update( $photo, $txt, '0', true, true, true );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2105
  break;
2106
 
2107
  case 'moveto':
2111
  if ( wppa_switch( 'void_dups' ) ) { // Check for already exists
2112
  $exists = wppa_is_file_duplicate_photo( $photodata['filename'], $value );
2113
  if ( $exists ) { // Already exists
2114
+ $txt = sprintf ( __( 'A photo with filename %s already exists in album %s.' , 'wp-photo-album-plus'), $photodata['filename'], $value );
2115
+ wppa_json_photo_update( $photo, $txt, '1' );
2116
  break;
2117
  }
2118
  }
2119
  if ( ! wppa_album_exists( $value ) ) {
2120
+ $txt = sprintf( __( 'Album %s does not exist', 'wp-photo-album-plus' ), $value );
2121
+ wppa_json_photo_update( $photo, $txt, '1' );
2122
  break;
2123
  }
2124
  wppa_invalidate_treecounts( $photodata['album'] ); // Current album
2125
  wppa_invalidate_treecounts( $value ); // New album
2126
  $iret = wppa_update_photo( array( 'id' => $photo, 'album' => $value ) );
2127
  $edit_link = wppa_ea_url( 'single', $tab = 'edit' ) . '&photo=' . $photodata['id'];
2128
+ if ( $iret ) {
2129
  wppa_move_source( $photodata['filename'], $photodata['album'], $value );
2130
  echo '||99||'.sprintf( __( 'Photo %s has been moved to album %s (%s)' , 'wp-photo-album-plus'), '<a href="'.$edit_link.'" target="_blank" >' . $photodata['id'] . '</a>', wppa_get_album_name( $value ), $value );
2131
+ wppa_exit();
2132
  }
2133
  else {
2134
+ $txt = sprintf( __( 'An error occurred while trying to move photo %s' , 'wp-photo-album-plus'), $photo );
2135
+ wppa_json_photo_update( $photo, $txt, '1' );
2136
+ wppa_exit();
2137
  }
 
2138
  break;
2139
 
2140
  case 'copyto':
2144
  if ( wppa_switch( 'void_dups' ) ) { // Check for already exists
2145
  $exists = wppa_is_file_duplicate_photo( $photodata['filename'], $value );
2146
  if ( $exists ) { // Already exists
2147
+ $txt = sprintf( __( 'A photo with filename %s already exists in album %s.' , 'wp-photo-album-plus'), $photodata['filename'], $value );
2148
+ wppa_json_photo_update( $photo, $txt, '1' );
2149
  break;
2150
  }
2151
  }
2152
  if ( ! wppa_album_exists( $value ) ) {
2153
+ $txt = sprintf( __( 'Album %s does not exist', 'wp-photo-album-plus' ), $value );
2154
+ wppa_json_photo_update( $photo, $txt, '1' );
2155
  break;
2156
  }
2157
  wppa( 'error', wppa_copy_photo( $photo, $value ) );
2158
  wppa_invalidate_treecounts( $value ); // New album
2159
  if ( ! wppa( 'error' ) ) {
2160
+ $txt = sprintf( __( 'Photo %s copied to album %s (%s)' , 'wp-photo-album-plus'), $photo, wppa_get_album_name( $value ), $value );
2161
+ wppa_json_photo_update( $photo, $txt, '0' );
2162
  }
2163
  else {
2164
+ $txt = sprintf( __( 'An error occurred while trying to copy photo %s' , 'wp-photo-album-plus'), $photo );
2165
+ wppa_json_photo_update( $photo, $txt, '1' );
2166
  }
 
2167
  break;
2168
 
2169
  case 'status':
2243
  case 'videox':
2244
  $itemname = __( 'Video width' , 'wp-photo-album-plus');
2245
  if ( ! wppa_is_int( $value ) || $value < '0' ) {
2246
+ $txt = __( 'Please enter an integer value >= 0', 'wp-photo-album-plus' );
2247
+ wppa_json_photo_update( $photo, $txt, '1' );
2248
  }
2249
  break;
2250
  case 'videoy':
2251
  $itemname = __( 'Video height', 'wp-photo-album-plus');
2252
  if ( ! wppa_is_int( $value ) || $value < '0' ) {
2253
+ $txt = __( 'Please enter an integer value >= 0', 'wp-photo-album-plus' );
2254
+ wppa_json_photo_update( $photo, $txt, '1' );
2255
  }
2256
  break;
2257
 
2268
  if ( $iret !== false ) {
2269
  wppa_update_modified( $photo );
2270
  if ( wppa_is_video( $photo ) ) {
2271
+ $txt = sprintf( __( '%s of video %s updated' , 'wp-photo-album-plus'), $itemname, $photo );
2272
  }
2273
  else {
2274
+ $txt = sprintf( __( '%s of photo %s updated' , 'wp-photo-album-plus'), $itemname, $photo );
2275
  }
2276
+ $err = '0';
2277
  }
2278
  else {
2279
+ $txt = sprintf( __( 'An error occurred while trying to update %s of photo %s', 'wp-photo-album-plus' ), $itemname, $photo );
2280
+ $err = '1';
2281
  }
2282
+ wppa_json_photo_update( $photo, $txt, $err );
2283
  break;
2284
 
2285
  case 'year':
2303
  wppa_invalidate_treecounts( $wpdb->get_var( $wpdb->prepare( "SELECT album FROM $wpdb->wppa_photos WHERE id = %s", $photo ) ) );
2304
  wppa_flush_upldr_cache( 'photoid', $photo );
2305
  if ( wppa_is_video( $photo ) ) {
2306
+ $txt = sprintf( __( '%s of video %s updated' , 'wp-photo-album-plus'), $itemname, $photo );
2307
  }
2308
  else {
2309
+ $txt = sprintf( __( '%s of video %s updated' , 'wp-photo-album-plus'), $itemname, $photo );
2310
  }
2311
+ wppa_json_photo_update( $photo, $txt );
2312
  break;
2313
 
2314
  case 'delyear':
2339
  wppa_invalidate_treecounts( $alb );
2340
  wppa_flush_upldr_cache( 'photoid', $photo );
2341
  if ( wppa_is_video( $photo ) ) {
2342
+ $txt = sprintf( __( '%s of video %s updated' , 'wp-photo-album-plus'), $itemname, $photo );
2343
  }
2344
  else {
2345
+ $txt = sprintf( __( '%s of video %s updated' , 'wp-photo-album-plus'), $itemname, $photo );
2346
  }
2347
+ wppa_json_photo_update( $photo, $txt );
2348
  break;
2349
  case 'removescheduledel':
2350
  if ( ( current_user_can( 'wppa_admin' ) || current_user_can( 'wppa_moderate' ) ) ) {
2351
  wppa_update_photo( array( 'id' => $photo, 'scheduledel' => '' ) );
2352
+ $txt = sprintf( __( 'Scheduled deletion of photo %s cancelled' , 'wp-photo-album-plus'), $photo );
2353
+ $err = '0';
2354
  }
2355
  else {
2356
+ $txt = __( 'No rights', 'wp-photo-album-plus' );
2357
+ $err = '1';
2358
  }
2359
+ wppa_json_photo_update( $photo, $txt, $err );
2360
  break;
2361
 
2362
  case 'custom_0':
2381
  $custom = serialize( $custom_data );
2382
  wppa_update_photo( array( 'id' => $photo, 'custom' => $custom, 'modified' => time() ) );
2383
  wppa_index_update( 'photo', $photo );
2384
+ $txt = sprintf( __( 'Custom field %s of photo %s updated' , 'wp-photo-album-plus'), wppa_opt( 'custom_caption_'.$index ), $photo );
2385
+ wppa_json_photo_update( $photo, $txt );
2386
  break;
2387
 
2388
  case 'file':
2389
 
2390
  // Check on upload error
2391
  if ( $_FILES['photo']['error'] ) {
2392
+ $txt = __( 'Error during upload.', 'wp-photo-album-plus' );
2393
+ wppa_json_photo_update( $photo, $txt, '1' );
2394
  wppa_exit();
2395
  }
2396
 
2433
  ) );
2434
 
2435
  // Report success
2436
+ $txt = __( 'Photo files updated.', 'wp-photo-album-plus');
2437
+ wppa_json_photo_update( $photo, $txt, '0', true, true );
2438
  }
2439
  else {
2440
 
2441
  // Report fail
2442
+ $txt = __( 'Could not update files.', 'wp-photo-album-plus' );
2443
+ wppa_json_photo_update( $photo, $txt, '1', true, true );
2444
  }
 
2445
  break;
2446
 
2447
  case 'stereo':
2450
  wppa_create_stereo_images( $photo );
2451
  wppa_create_thumbnail( $photo );
2452
  $t = microtime(true) - $t;
2453
+ $txt = sprintf( __( 'Stereo mode updated in %d milliseconds', 'wp-photo-album-plus'), floor( $t * 1000 ) );
2454
+ wppa_json_photo_update( $photo, $txt, '0', true, true );
2455
  break;
2456
 
2457
  case 'panorama':
2458
  wppa_update_photo( array( 'id' => $photo, 'panorama' => $value ) );
2459
+ $txt = sprintf( __( 'Panorama set to %s', 'wp-photo-album-plus' ), $value );
2460
+ wppa_json_photo_update( $photo, $txt );
2461
+ break;
2462
+
2463
+ case 'thumblock':
2464
+ wppa_update_photo( array( 'id' => $photo, 'thumblock' => ( $value ? '1' : '0' ) ) );
2465
+ $txt = __( 'Thumbfile', 'wp-photo-album-plus' ) . ( $value ? ' ' : ' un' ) . 'locked';
2466
+ wppa_json_photo_update( $photo, $txt );
2467
  break;
2468
 
2469
  default:
2470
+ $txt = 'This update action is not implemented yet ( '.$item.' )';
2471
+ wppa_json_photo_update( $photo, $txt, '1' );
2472
  }
 
2473
  break;
2474
 
2475
+ /* END UPDATE PHOTO */
2476
+
2477
  // The wppa-settings page calls ajax with $wppa_action == 'update-option';
2478
  case 'update-option':
2479
 
3473
  break;
3474
  case 'wppa_image_magick':
3475
  $value = rtrim( $value, '/' );
3476
+ if ( $value ) {
3477
+ $out = array();
3478
+ exec( escapeshellcmd( $value . '/convert' ), $out, $err );
3479
+ $ok = ( count( $out ) != 0 );
3480
+ if ( $ok ) {
3481
+ $out = array_reverse( $out );
3482
+ array_push( $out, 'Setting magick path returned:' );
3483
+ wppa_log( 'dbg', var_export( $out, true ) );
3484
+ }
3485
+ else {
3486
+ wppa( 'error', '4713' );
3487
+ $alert .= __( 'This path does not contain ImageMagick commands', 'wp-photo-album-plus' );
3488
+ }
3489
  }
3490
  break;
3491
  case 'wppa_grant_cats':
3723
  $text = sprintf( __( 'Security check failure %d', 'wp-photo-album-plus' ), $id );
3724
  echo ( $prolog . ' ' . $text );
3725
  wppa_exit();
3726
+ }
3727
+
3728
+ // Get the JSON formatted photo update data
3729
+ function wppa_json_photo_update( $id, $txt, $err = '0', $thumbmod = false, $photomod = false, $magickmod = false ) {
3730
+
3731
+ // Re-compute photo and thumbnail pixel sizes
3732
+ $tx = wppa_get_thumbx($id, true);
3733
+ $ty = wppa_get_thumby($id, true);
3734
+ $px = wppa_get_photox($id, true);
3735
+ $py = wppa_get_photoy($id, true);
3736
+ wppa_cache_thumb( 'invalidate', $id );
3737
+ $t = wppa_cache_thumb( $id );
3738
+
3739
+ // Just to be sure increment version numbers
3740
+ if ( $thumbmod || $magickmod ) {
3741
+ wppa_bump_thumb_rev();
3742
+ }
3743
+ if ( $photomod || $magickmod ) {
3744
+ wppa_bump_photo_rev();
3745
+ }
3746
+
3747
+ // Find and format filesizes
3748
+ $tf = wppa_fix_poster_ext( wppa_get_thumb_path( $id ), $id );
3749
+ if ( wppa_is_file( $tf ) ) {
3750
+ $tfs = wppa_get_filesize( $tf );
3751
+ }
3752
+ else {
3753
+ $tfs = __( 'Unavailable', 'wp-photo-album-plus' );
3754
+ }
3755
+
3756
+ $pf = wppa_fix_poster_ext( wppa_get_photo_path( $id ), $id );
3757
+ if ( wppa_is_file( $pf ) ) {
3758
+ $pfs = wppa_get_filesize( $pf );
3759
+ }
3760
+ else {
3761
+ $pfs = __( 'Unavailable', 'wp-photo-album-plus' );
3762
+ }
3763
+
3764
+ // Update CDN
3765
+ if ( $thumbmod || $photomod || $magickmod ) {
3766
+ $cdn = wppa_cdn( 'admin' );
3767
+ if ( $cdn ) {
3768
+ switch ( $cdn ) {
3769
+ case 'cloudinary':
3770
+ wppa_upload_to_cloudinary( $photo );
3771
+ break;
3772
+ case 'local':
3773
+ wppa_cdn_delete( $photo );
3774
+ break;
3775
+ default:
3776
+ wppa_dbg_msg( 'Missing upload instructions for '.$cdn, 'red', 'force' );
3777
+ }
3778
+ }
3779
+ }
3780
+
3781
+ // Clear cache
3782
+ wppa_clear_cache();
3783
+
3784
+ $data = array();
3785
+
3786
+ // Build JSON data string
3787
+ $result = '||' . $err . '||{"remark":"' . $txt . '"';
3788
+
3789
+ $data['remark'] = htmlentities( str_replace( '"', "'", $txt ) );
3790
+ $data['modified'] = wppa_local_date( '', $t['modified'] );
3791
+
3792
+ if ( $thumbmod || $magickmod ) {
3793
+ $result .=
3794
+ ',"thumbx":"' . $tx . '"' .
3795
+ ',"thumby":"' . $ty . '"' .
3796
+ ',"thumbfilesize":"' . $tfs . '"' .
3797
+ ',"thumburl":"' . wppa_get_thumb_url( $id ) . '"';
3798
+
3799
+ $data['thumbx'] = $tx;
3800
+ $data['thumby'] = $ty;
3801
+ $data['thumbfilesize'] = $tfs;
3802
+ $data['thumburl'] = wppa_get_thumb_url( $id );
3803
+ }
3804
+
3805
+ if ( $photomod || $magickmod ) {
3806
+ $result .=
3807
+ ',"photox":"' . $px . '"' .
3808
+ ',"photoy":"' . $py . '"' .
3809
+ ',"photofilesize":"' . $pfs . '"' .
3810
+ ',"photourl":"' . wppa_get_photo_url( $id ) . '"';
3811
+
3812
+ $data['photox'] = $tx;
3813
+ $data['photoy'] = $ty;
3814
+ $data['photofilesize'] = $tfs;
3815
+ $data['photourl'] = wppa_get_photo_url( $id );
3816
+ }
3817
+
3818
+ if ( $photomod || $magickmod ) {
3819
+ $result .= ',"magickstack":"' . $t['magickstack'] . '"';
3820
+
3821
+ $data['magickstack'] = $t['magickstack'];
3822
+ }
3823
+
3824
+ if ( $thumbmod || $photomod || $magickmod ) {
3825
+ $result .= ',"cdnfiles":"' . __( 'none', 'wp-photo-album-plus' ) . '"';
3826
+
3827
+ $data['cdnfiles'] = __( 'none', 'wp-photo-album-plus' );
3828
+ }
3829
+
3830
+ $result .= '}';
3831
+
3832
+ $result = '||' . $err . '||' . json_encode( $data );
3833
+
3834
+ wppa_log( 'dbg', $result );
3835
+
3836
+ echo $result;
3837
+ wppa_exit();
3838
  }
wppa-album-admin-autosave.php CHANGED
@@ -3,7 +3,7 @@
3
  * Package: wp-photo-album-plus
4
  *
5
  * create, edit and delete albums
6
- * Version 7.1.08
7
  *
8
  */
9
 
@@ -87,13 +87,19 @@ global $wppa_revno;
87
 
88
  if ( $_REQUEST['edit_id'] == 'single' ) {
89
 
90
- echo '
91
- <div class="wrap" >
92
- <h2>' . __( 'Edit Single Photo', 'wp-photo-album-plus' ) .
93
- ' - <small><i>' . __( 'Edit photo information', 'wp-photo-album-plus' ) . '</i></small>
94
- </h2>' .
95
- wppa_album_photos( $ei ) . '
96
- </div>';
 
 
 
 
 
 
97
  return;
98
  }
99
 
@@ -161,8 +167,9 @@ global $wppa_revno;
161
  <div class="wrap">
162
  <h2>' . __( 'Manage Trashed Photos', 'wp-photo-album-plus' ) .
163
  ' - <small><i>' . __( 'Edit photo information', 'wp-photo-album-plus' ) . '</i></small>
164
- </h2>' .
165
- wppa_album_photos( $ei ) . '
 
166
  </div>';
167
 
168
  return;
@@ -378,7 +385,8 @@ global $wppa_revno;
378
  </h1>
379
  <p class="description">' .
380
  __( 'All modifications are instantly updated on the server, except for those that require a button push.', 'wp-photo-album-plus' ) . ' ' .
381
- __( 'The <b style="color:#070" >Remark</b> fields keep you informed on the actions taken at the background.', 'wp-photo-album-plus' ) . '
 
382
  </p>
383
  <input
384
  type="hidden"
@@ -486,7 +494,6 @@ global $wppa_revno;
486
  __( 'Album order #', 'wp-photo-album-plus' ) . ':&nbsp;
487
  <input
488
  type="text"
489
- onkeyup="wppaAjaxUpdateAlbum( ' . $id . ', \'a_order\', this )"
490
  onchange="wppaAjaxUpdateAlbum( ' . $id . ', \'a_order\', this )"
491
  value="' . esc_attr( $a_order ) . '"
492
  style="width:50px;"
@@ -751,7 +758,6 @@ global $wppa_revno;
751
  <input
752
  type="text"
753
  style="width:100%;"
754
- onkeyup="wppaAjaxUpdateAlbum( ' . $id . ', \'name\', this )"
755
  onchange="wppaAjaxUpdateAlbum( ' . $id . ', \'name\', this )"
756
  value="' . esc_attr( $name ) . '"
757
  />
@@ -803,7 +809,6 @@ global $wppa_revno;
803
  <td>
804
  <textarea
805
  style="width:100%;height:60px;"
806
- onkeyup="wppaAjaxUpdateAlbum( ' . $id . ', \'description\', this )"
807
  onchange="wppaAjaxUpdateAlbum( ' . $id . ', \'description\', this )"
808
  >' .
809
  esc_textarea( stripslashes( $description ) ) .
@@ -826,7 +831,6 @@ global $wppa_revno;
826
  id="cats"
827
  type="text"
828
  style="width:100%;"
829
- onkeyup="wppaAjaxUpdateAlbum( ' . $id . ', \'cats\', this )"
830
  onchange="wppaAjaxUpdateAlbum( ' . $id . ', \'cats\', this )"
831
  value="' . esc_attr( $cats ) . '"
832
  />
@@ -869,7 +873,6 @@ global $wppa_revno;
869
  id="default_tags"
870
  value="' . esc_attr( $default_tags ) . '"
871
  style="width:100%"
872
- onkeyup="wppaAjaxUpdateAlbum( ' . $id . ', \'default_tags\', this )"
873
  onchange="wppaAjaxUpdateAlbum( ' . $id . ', \'default_tags\', this )"
874
  />
875
  <br />
@@ -905,7 +908,6 @@ global $wppa_revno;
905
  type="text"
906
  style="width:100%;"
907
  id="album_custom_' . $key . '-' . $id . '"
908
- onkeyup="wppaAjaxUpdateAlbum( ' . $id . ', \'album_custom_' . $key . '\', this );"
909
  onchange="wppaAjaxUpdateAlbum( ' . $id . ', \'album_custom_' . $key . '\', this );"
910
  value="' . esc_attr( stripslashes( $custom_data[$key] ) ) . '"
911
  />
@@ -1056,13 +1058,13 @@ global $wppa_revno;
1056
  ' type="button"' .
1057
  ' title="' . esc_attr( __( 'Apply categories to all (grand)children.', 'wp-photo-album-plus' ) ) . '"' .
1058
  ' onclick="wppaTryInheritCats( ' . $id . ' )"' .
1059
- ' value="' . esc_attr( __( 'Inherit Cats', 'wp-photo-album-plus' ) ) . '"' .
1060
  ' />' .
1061
  '<input' .
1062
  ' type="button"' .
1063
  ' title="' . esc_attr( __( 'Add categories to all (grand)children.', 'wp-photo-album-plus' ) ) . '"' .
1064
  ' onclick="wppaTryAddCats( ' . $id . ' )"' .
1065
- ' value="' . esc_attr( __( 'Add Inherit Cats', 'wp-photo-album-plus' ) ) . '"' .
1066
  ' />';
1067
 
1068
  // Apply default tags
@@ -1684,6 +1686,7 @@ global $wpdb;
1684
  <td ><?php _e('Quick', 'wp-photo-album-plus'); ?></td>
1685
  <td ><?php _e('Bulk', 'wp-photo-album-plus'); ?></td>
1686
  <td ><?php _e('Seq', 'wp-photo-album-plus'); ?></td>
 
1687
  <?php
1688
  if ( current_user_can( 'wppa_upload' ) ) {
1689
  echo '<td >' . __('Upload', 'wp-photo-album-plus') . '</td>';
@@ -1730,6 +1733,16 @@ global $wpdb;
1730
  <td><a href="<?php echo($url.'&amp;quick') ?>" class="wppaedit"><?php _e('Quick', 'wp-photo-album-plus'); ?></a></td>
1731
  <td><a href="<?php echo($url.'&amp;bulk#manage-photos') ?>" class="wppaedit"><?php _e('Bulk', 'wp-photo-album-plus'); ?></a></td>
1732
  <td><a href="<?php echo($url.'&amp;seq') ?>" class="wppaedit"><?php _e('Seq', 'wp-photo-album-plus'); ?></a></td>
 
 
 
 
 
 
 
 
 
 
1733
  <?php
1734
  if ( current_user_can( 'wppa_upload' ) ) {
1735
  echo '<td ><a href="' . get_admin_url().'/admin.php?page=wppa_upload_photos&wppa-set-album='.$album['id'] . '" class="wppaedit" >' . __('Upload', 'wp-photo-album-plus') . '</a></td>';
@@ -1836,6 +1849,7 @@ global $wpdb;
1836
  <td ><?php _e('Quick', 'wp-photo-album-plus'); ?></td>
1837
  <td ><?php _e('Bulk', 'wp-photo-album-plus'); ?></td>
1838
  <td ><?php _e('Seq', 'wp-photo-album-plus'); ?></td>
 
1839
  <?php
1840
  if ( current_user_can( 'wppa_upload' ) ) {
1841
  echo '<td >' . __('Upload', 'wp-photo-album-plus') . '</td>';
@@ -2133,6 +2147,7 @@ global $wpdb;
2133
  <td ><?php _e('Quick', 'wp-photo-album-plus'); ?></td>
2134
  <td ><?php _e('Bulk', 'wp-photo-album-plus'); ?></td>
2135
  <td ><?php _e('Seq', 'wp-photo-album-plus'); ?></td>
 
2136
  <?php
2137
  if ( current_user_can( 'wppa_upload' ) ) {
2138
  echo '<td >' . __('Upload', 'wp-photo-album-plus') . '</td>';
@@ -2241,6 +2256,7 @@ global $wpdb;
2241
  <td ><?php _e('Quick', 'wp-photo-album-plus'); ?></td>
2242
  <td ><?php _e('Bulk', 'wp-photo-album-plus'); ?></td>
2243
  <td ><?php _e('Seq', 'wp-photo-album-plus'); ?></td>
 
2244
  <?php
2245
  if ( current_user_can( 'wppa_upload' ) ) {
2246
  echo '<td >' . __('Upload', 'wp-photo-album-plus') . '</td>';
@@ -2525,6 +2541,14 @@ global $wpdb;
2525
  <td><a href="<?php echo($url.'&amp;bulk#manage-photos') ?>" class="wppaedit"><?php _e('Bulk', 'wp-photo-album-plus'); ?></a></td>
2526
  <td><a href="<?php echo($url.'&amp;seq') ?>" class="wppaedit"><?php _e('Seq', 'wp-photo-album-plus'); ?></a></td>
2527
  <?php
 
 
 
 
 
 
 
 
2528
  if ( current_user_can( 'wppa_upload' ) ) {
2529
  echo '<td ><a href="' . get_admin_url().'/admin.php?page=wppa_upload_photos&wppa-set-album='.$album['id'] . '" class="wppaedit" >' . __('Upload', 'wp-photo-album-plus') . '</a></td>';
2530
  }
3
  * Package: wp-photo-album-plus
4
  *
5
  * create, edit and delete albums
6
+ * Version 7.2.03
7
  *
8
  */
9
 
87
 
88
  if ( $_REQUEST['edit_id'] == 'single' ) {
89
 
90
+ if ( isset( $_REQUEST['just-edit'] ) ) {
91
+ $txt = $_REQUEST['just-edit'];
92
+ }
93
+ else $txt = '';
94
+
95
+ if ( ! $txt ) {
96
+ $txt = __( 'Edit Single Photo', 'wp-photo-album-plus' );
97
+ }
98
+
99
+ echo '<div class="wrap" >
100
+ <h2>' . $txt . '</h2>';
101
+ wppa_album_photos( $ei );
102
+ echo '</div>';
103
  return;
104
  }
105
 
167
  <div class="wrap">
168
  <h2>' . __( 'Manage Trashed Photos', 'wp-photo-album-plus' ) .
169
  ' - <small><i>' . __( 'Edit photo information', 'wp-photo-album-plus' ) . '</i></small>
170
+ </h2>';
171
+ wppa_album_photos( $ei );
172
+ echo '
173
  </div>';
174
 
175
  return;
385
  </h1>
386
  <p class="description">' .
387
  __( 'All modifications are instantly updated on the server, except for those that require a button push.', 'wp-photo-album-plus' ) . ' ' .
388
+ __( 'After entering/modification of text, click outside the textfield to get it updated.', 'wp-photo-album-plus' ) . ' ' .
389
+ '<br />' . __( 'The <b style="color:#070" >Remark</b> fields keep you informed on the actions taken at the background.', 'wp-photo-album-plus' ) . '
390
  </p>
391
  <input
392
  type="hidden"
494
  __( 'Album order #', 'wp-photo-album-plus' ) . ':&nbsp;
495
  <input
496
  type="text"
 
497
  onchange="wppaAjaxUpdateAlbum( ' . $id . ', \'a_order\', this )"
498
  value="' . esc_attr( $a_order ) . '"
499
  style="width:50px;"
758
  <input
759
  type="text"
760
  style="width:100%;"
 
761
  onchange="wppaAjaxUpdateAlbum( ' . $id . ', \'name\', this )"
762
  value="' . esc_attr( $name ) . '"
763
  />
809
  <td>
810
  <textarea
811
  style="width:100%;height:60px;"
 
812
  onchange="wppaAjaxUpdateAlbum( ' . $id . ', \'description\', this )"
813
  >' .
814
  esc_textarea( stripslashes( $description ) ) .
831
  id="cats"
832
  type="text"
833
  style="width:100%;"
 
834
  onchange="wppaAjaxUpdateAlbum( ' . $id . ', \'cats\', this )"
835
  value="' . esc_attr( $cats ) . '"
836
  />
873
  id="default_tags"
874
  value="' . esc_attr( $default_tags ) . '"
875
  style="width:100%"
 
876
  onchange="wppaAjaxUpdateAlbum( ' . $id . ', \'default_tags\', this )"
877
  />
878
  <br />
908
  type="text"
909
  style="width:100%;"
910
  id="album_custom_' . $key . '-' . $id . '"
 
911
  onchange="wppaAjaxUpdateAlbum( ' . $id . ', \'album_custom_' . $key . '\', this );"
912
  value="' . esc_attr( stripslashes( $custom_data[$key] ) ) . '"
913
  />
1058
  ' type="button"' .
1059
  ' title="' . esc_attr( __( 'Apply categories to all (grand)children.', 'wp-photo-album-plus' ) ) . '"' .
1060
  ' onclick="wppaTryInheritCats( ' . $id . ' )"' .
1061
+ ' value="' . esc_attr( __( 'Apply Cats to subalbums', 'wp-photo-album-plus' ) ) . '"' .
1062
  ' />' .
1063
  '<input' .
1064
  ' type="button"' .
1065
  ' title="' . esc_attr( __( 'Add categories to all (grand)children.', 'wp-photo-album-plus' ) ) . '"' .
1066
  ' onclick="wppaTryAddCats( ' . $id . ' )"' .
1067
+ ' value="' . esc_attr( __( 'Add Cats to subalbums', 'wp-photo-album-plus' ) ) . '"' .
1068
  ' />';
1069
 
1070
  // Apply default tags
1686
  <td ><?php _e('Quick', 'wp-photo-album-plus'); ?></td>
1687
  <td ><?php _e('Bulk', 'wp-photo-album-plus'); ?></td>
1688
  <td ><?php _e('Seq', 'wp-photo-album-plus'); ?></td>
1689
+ <td ><?php _e('CovImg', 'wp-photo-album-plus'); ?></td>
1690
  <?php
1691
  if ( current_user_can( 'wppa_upload' ) ) {
1692
  echo '<td >' . __('Upload', 'wp-photo-album-plus') . '</td>';
1733
  <td><a href="<?php echo($url.'&amp;quick') ?>" class="wppaedit"><?php _e('Quick', 'wp-photo-album-plus'); ?></a></td>
1734
  <td><a href="<?php echo($url.'&amp;bulk#manage-photos') ?>" class="wppaedit"><?php _e('Bulk', 'wp-photo-album-plus'); ?></a></td>
1735
  <td><a href="<?php echo($url.'&amp;seq') ?>" class="wppaedit"><?php _e('Seq', 'wp-photo-album-plus'); ?></a></td>
1736
+ <?php
1737
+ $covid = max( $album['main_photo'], '0' );
1738
+ if ( $covid ) {
1739
+ $curl = wppa_dbg_url(get_admin_url().'admin.php?page=wppa_admin_menu&amp;tab=edit&amp;edit_id=single&amp;photo='.$covid.'&amp;wppa_nonce='.wp_create_nonce('wppa_nonce').'&amp;just-edit='.__('Edit cover image', 'wp-photo-album-plus'));
1740
+ echo '<td><a href="'.$curl.'" class="wppaedit">'.__('CovImg', 'wp-photo-album-plus').'</a></td>';
1741
+ }
1742
+ else {
1743
+ echo '<td></td>';
1744
+ }
1745
+ ?>
1746
  <?php
1747
  if ( current_user_can( 'wppa_upload' ) ) {
1748
  echo '<td ><a href="' . get_admin_url().'/admin.php?page=wppa_upload_photos&wppa-set-album='.$album['id'] . '" class="wppaedit" >' . __('Upload', 'wp-photo-album-plus') . '</a></td>';
1849
  <td ><?php _e('Quick', 'wp-photo-album-plus'); ?></td>
1850
  <td ><?php _e('Bulk', 'wp-photo-album-plus'); ?></td>
1851
  <td ><?php _e('Seq', 'wp-photo-album-plus'); ?></td>
1852
+ <td ><?php _e('CovImg', 'wp-photo-album-plus'); ?></td>
1853
  <?php
1854
  if ( current_user_can( 'wppa_upload' ) ) {
1855
  echo '<td >' . __('Upload', 'wp-photo-album-plus') . '</td>';
2147
  <td ><?php _e('Quick', 'wp-photo-album-plus'); ?></td>
2148
  <td ><?php _e('Bulk', 'wp-photo-album-plus'); ?></td>
2149
  <td ><?php _e('Seq', 'wp-photo-album-plus'); ?></td>
2150
+ <td ><?php _e('CovImg', 'wp-photo-album-plus'); ?></td>
2151
  <?php
2152
  if ( current_user_can( 'wppa_upload' ) ) {
2153
  echo '<td >' . __('Upload', 'wp-photo-album-plus') . '</td>';
2256
  <td ><?php _e('Quick', 'wp-photo-album-plus'); ?></td>
2257
  <td ><?php _e('Bulk', 'wp-photo-album-plus'); ?></td>
2258
  <td ><?php _e('Seq', 'wp-photo-album-plus'); ?></td>
2259
+ <td ><?php _e('CovImg', 'wp-photo-album-plus'); ?></td>
2260
  <?php
2261
  if ( current_user_can( 'wppa_upload' ) ) {
2262
  echo '<td >' . __('Upload', 'wp-photo-album-plus') . '</td>';
2541
  <td><a href="<?php echo($url.'&amp;bulk#manage-photos') ?>" class="wppaedit"><?php _e('Bulk', 'wp-photo-album-plus'); ?></a></td>
2542
  <td><a href="<?php echo($url.'&amp;seq') ?>" class="wppaedit"><?php _e('Seq', 'wp-photo-album-plus'); ?></a></td>
2543
  <?php
2544
+ $covid = max( $album['main_photo'], '0' );
2545
+ if ( $covid ) {
2546
+ $curl = wppa_dbg_url(get_admin_url().'admin.php?page=wppa_admin_menu&amp;tab=edit&amp;edit_id=single&amp;photo='.$covid.'&amp;wppa_nonce='.wp_create_nonce('wppa_nonce').'&amp;just-edit='.__('Edit cover image', 'wp-photo-album-plus'));
2547
+ echo '<td><a href="'.$curl.'" class="wppaedit">'.__('CovImg', 'wp-photo-album-plus').'</a></td>';
2548
+ }
2549
+ else {
2550
+ echo '<td></td>';
2551
+ }
2552
  if ( current_user_can( 'wppa_upload' ) ) {
2553
  echo '<td ><a href="' . get_admin_url().'/admin.php?page=wppa_upload_photos&wppa-set-album='.$album['id'] . '" class="wppaedit" >' . __('Upload', 'wp-photo-album-plus') . '</a></td>';
2554
  }
wppa-functions.php CHANGED
@@ -2051,7 +2051,7 @@ function wppa_extended_duplicate_remove( &$thumbs ) {
2051
  $ret = wppa_are_items_equal( $thumbs[$i], $thumbs[$j] );
2052
  if ( $ret ) {
2053
  wppa_log( 'dbg', 'Items ' . $thumbs[$i]['id'] . ' and ' . $thumbs[$j]['id'] .
2054
- ' are identical. Flags = ' . sprintf( '0x%04x', $ret ) );
2055
  unset( $thumbs[$j] );
2056
  }
2057
  }
@@ -2067,54 +2067,39 @@ function wppa_extended_duplicate_remove( &$thumbs ) {
2067
  }
2068
 
2069
  // Compare two items for equality
2070
- /* Two items are regarded to be the same when:
2071
- Photo names, descriptions and filenames are the same and one of the following statements is true:
2072
- - The EXIF ImageUniqueIDs have been recorded in the wppa_exif db table and are non empty and are identical. Flag = 0x0001.
2073
- - The EXIF Date/Time originnals were present during uploaded and are identical. Flag = 0x0002.
2074
- - At least three of the following tests are positive:
2075
- - - Source files exist and have the same filesize. Flag = 0x4000.
2076
- - - Display files exist and have the same filesize. Flag = 0x2000.
2077
- - - Thumbnail files exist and have the same filesize. Flag = 0x1000.
2078
- - - Thumbnail files exist and have the same content. Flag = 0x0100.
2079
- - - Display files exist and have the same content. Flag = 0x0200.
2080
- - - Source files exist and have the same content. Flag = 0x0400.
2081
- Status codes (flags) are combined bits and are printed as hex numbers in the debug log like:
2082
- Dbg: on:20.06.2019 10:42:06: opajaap: Items 1574 and 1569 are identical. Flags = 0x3100
2083
- */
2084
  function wppa_are_items_equal( $xit1, $xit2 ) {
2085
  global $wpdb;
2086
 
2087
  $it1 = wppa_cache_photo( $xit1['id'] );
2088
  $it2 = wppa_cache_photo( $xit2['id'] );
2089
 
2090
- // These items must be equal
 
2091
  // Name
2092
- if ( ! wppa_looks_equal( $it1['name'], $it2['name'] ) ) return false; // Names unequal
2093
 
2094
  // Description
2095
- if ( ! wppa_looks_equal( $it1['description'], $it2['description'] ) ) return false; // Descriptions unequal
2096
 
2097
  // Filename
2098
- if ( ! wppa_looks_equal( $it1['filename'], $it2['filename'] ) ) return false; // Descriptions unequal
2099
 
2100
  // If one of these item is equal, the items are the same
2101
  // EXIF ImageUniqueID
2102
  $E1 = $wpdb->get_var( $wpdb->prepare( "SELECT description FROM $wpdb->wppa_exif WHERE photo=%s AND tag=%s", $it1['id'], 'E#A420' ) );
2103
  $E2 = $wpdb->get_var( $wpdb->prepare( "SELECT description FROM $wpdb->wppa_exif WHERE photo=%s AND tag=%s", $it2['id'], 'E#A420' ) );
2104
  if ( $E1 && $E2 && $E1 == $E2 ) {
2105
- return 0x0001;
2106
  }
2107
  // EXIF date/time
2108
  $E1 = $it1['exifdtm'];
2109
  $E2 = $it2['exifdtm'];
2110
  if ( $E1 && $E2 && $E1 == $E2 ) {
2111
- return 0x0002;
2112
  }
2113
 
2114
  // So far so good.
2115
- // Now try to find at least three equal file properties
2116
- $score = 0;
2117
- $flags = 0x0000;
2118
 
2119
  // Equal source filesize?
2120
  $s1 = wppa_get_source_path( $it1['id'] );
@@ -2122,9 +2107,9 @@ global $wpdb;
2122
  if ( wppa_is_file( $s1 ) && wppa_is_file( $s2 ) ) {
2123
  if ( wppa_filesize( $s1 ) == wppa_filesize( $s2 ) ) {
2124
  $score++;
2125
- $flags |= 0x4000;
2126
  }
2127
  }
 
2128
 
2129
  // Equal display filesize?
2130
  $d1 = wppa_get_photo_path( $it1['id'] );
@@ -2132,9 +2117,9 @@ global $wpdb;
2132
  if ( wppa_is_file( $d1 ) && wppa_is_file( $d2 ) ) {
2133
  if ( wppa_filesize( $d1 ) == wppa_filesize( $d2 ) ) {
2134
  $score++;
2135
- $flags |= 0x2000;
2136
  }
2137
  }
 
2138
 
2139
  // Equal thumnail filesize?
2140
  $t1 = wppa_get_thumb_path( $it1['id'] );
@@ -2142,42 +2127,37 @@ global $wpdb;
2142
  if ( wppa_is_file( $t1 ) && wppa_is_file( $t2 ) ) {
2143
  if ( wppa_filesize( $t1 ) == wppa_filesize( $t2 ) ) {
2144
  $score++;
2145
- $flags |= 0x1000;
2146
  }
2147
  }
2148
-
2149
- if ( $score == 3 ) return $flags; // Items are identical
2150
 
2151
  // Equal thumbnail file content?
2152
  if ( wppa_is_file( $t1 ) && wppa_is_file( $t2 ) ) {
2153
  if ( wppa_get_contents( $t1 ) == wppa_get_contents( $t2 ) ) {
2154
  $score++;
2155
- $flags |= 0x0100;
2156
  }
2157
  }
2158
- if ( $score == 3 ) return $flags; // Items are identical
2159
-
2160
  // Equal display file content?
2161
  if ( wppa_is_file( $d1 ) && wppa_is_file( $d2 ) ) {
2162
  if ( wppa_get_contents( $d1 ) == wppa_get_contents( $d2 ) ) {
2163
  $score++;
2164
- $flags |= 0x0200;
2165
  }
2166
  }
2167
- if ( $score == 3 ) return $flags; // Items are identical
2168
 
2169
  // Equal source file content?
2170
  if ( wppa_is_file( $s1 ) && wppa_is_file( $s2 ) ) {
2171
  if ( wppa_get_contents( $s1 ) == wppa_get_contents( $s2 ) ) {
2172
  $score++;
2173
- $flags |= 0x0400;
2174
  }
2175
  }
2176
- if ( $score == 3 ) return $flags; // Items are identical
2177
 
2178
  wppa_log( 'war', 'Items ' . $it1['id'] . ' and ' . $it2['id'] .
2179
- ' have the same name, filename and description but score only ' .
2180
- $score . ' out of 6 possible matches. Flags = ' . sprintf( '0x04%x', $flags ) );
2181
 
2182
  // No match afterall
2183
  return false;
2051
  $ret = wppa_are_items_equal( $thumbs[$i], $thumbs[$j] );
2052
  if ( $ret ) {
2053
  wppa_log( 'dbg', 'Items ' . $thumbs[$i]['id'] . ' and ' . $thumbs[$j]['id'] .
2054
+ ' are identical.' );
2055
  unset( $thumbs[$j] );
2056
  }
2057
  }
2067
  }
2068
 
2069
  // Compare two items for equality
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2070
  function wppa_are_items_equal( $xit1, $xit2 ) {
2071
  global $wpdb;
2072
 
2073
  $it1 = wppa_cache_photo( $xit1['id'] );
2074
  $it2 = wppa_cache_photo( $xit2['id'] );
2075
 
2076
+ $score = 0;
2077
+
2078
  // Name
2079
+ if ( wppa_looks_equal( $it1['name'], $it2['name'] ) && $it1['name'] ) $score++; // equal and not empty
2080
 
2081
  // Description
2082
+ if ( wppa_looks_equal( $it1['description'], $it2['description'] ) && $it1['description'] ) $score++; // equal and not empty
2083
 
2084
  // Filename
2085
+ if ( wppa_looks_equal( $it1['filename'], $it2['filename'] ) && $it1['filename'] ) $score++; // equal and not empty
2086
 
2087
  // If one of these item is equal, the items are the same
2088
  // EXIF ImageUniqueID
2089
  $E1 = $wpdb->get_var( $wpdb->prepare( "SELECT description FROM $wpdb->wppa_exif WHERE photo=%s AND tag=%s", $it1['id'], 'E#A420' ) );
2090
  $E2 = $wpdb->get_var( $wpdb->prepare( "SELECT description FROM $wpdb->wppa_exif WHERE photo=%s AND tag=%s", $it2['id'], 'E#A420' ) );
2091
  if ( $E1 && $E2 && $E1 == $E2 ) {
2092
+ $score+=4;;
2093
  }
2094
  // EXIF date/time
2095
  $E1 = $it1['exifdtm'];
2096
  $E2 = $it2['exifdtm'];
2097
  if ( $E1 && $E2 && $E1 == $E2 ) {
2098
+ $score+=4;
2099
  }
2100
 
2101
  // So far so good.
2102
+ if ( $score >= 4 ) return true;
 
 
2103
 
2104
  // Equal source filesize?
2105
  $s1 = wppa_get_source_path( $it1['id'] );
2107
  if ( wppa_is_file( $s1 ) && wppa_is_file( $s2 ) ) {
2108
  if ( wppa_filesize( $s1 ) == wppa_filesize( $s2 ) ) {
2109
  $score++;
 
2110
  }
2111
  }
2112
+ if ( $score >= 4 ) return true;
2113
 
2114
  // Equal display filesize?
2115
  $d1 = wppa_get_photo_path( $it1['id'] );
2117
  if ( wppa_is_file( $d1 ) && wppa_is_file( $d2 ) ) {
2118
  if ( wppa_filesize( $d1 ) == wppa_filesize( $d2 ) ) {
2119
  $score++;
 
2120
  }
2121
  }
2122
+ if ( $score >= 4 ) return true;
2123
 
2124
  // Equal thumnail filesize?
2125
  $t1 = wppa_get_thumb_path( $it1['id'] );
2127
  if ( wppa_is_file( $t1 ) && wppa_is_file( $t2 ) ) {
2128
  if ( wppa_filesize( $t1 ) == wppa_filesize( $t2 ) ) {
2129
  $score++;
 
2130
  }
2131
  }
2132
+ if ( $score >= 4 ) return true;
 
2133
 
2134
  // Equal thumbnail file content?
2135
  if ( wppa_is_file( $t1 ) && wppa_is_file( $t2 ) ) {
2136
  if ( wppa_get_contents( $t1 ) == wppa_get_contents( $t2 ) ) {
2137
  $score++;
 
2138
  }
2139
  }
2140
+ if ( $score >= 4 ) return true;
2141
+
2142
  // Equal display file content?
2143
  if ( wppa_is_file( $d1 ) && wppa_is_file( $d2 ) ) {
2144
  if ( wppa_get_contents( $d1 ) == wppa_get_contents( $d2 ) ) {
2145
  $score++;
 
2146
  }
2147
  }
2148
+ if ( $score >= 4 ) return true;
2149
 
2150
  // Equal source file content?
2151
  if ( wppa_is_file( $s1 ) && wppa_is_file( $s2 ) ) {
2152
  if ( wppa_get_contents( $s1 ) == wppa_get_contents( $s2 ) ) {
2153
  $score++;
 
2154
  }
2155
  }
2156
+ if ( $score >= 4 ) return true;
2157
 
2158
  wppa_log( 'war', 'Items ' . $it1['id'] . ' and ' . $it2['id'] .
2159
+ ' score only ' .
2160
+ $score . ' matches' );
2161
 
2162
  // No match afterall
2163
  return false;
wppa-photo-admin-autosave.php CHANGED
@@ -3,7 +3,7 @@
3
  * Package: wp-photo-album-plus
4
  *
5
  * edit and delete photos
6
- * Version 7.2.00
7
  *
8
  */
9
 
@@ -60,6 +60,7 @@ function _wppa_moderate_photos() {
60
  echo
61
  '<div class="wrap">' .
62
  '<h2>' . __( 'Edit photo', 'wp-photo-album-plus' ) . '</h2>';
 
63
  wppa_album_photos( '', $photo, '', false );
64
  echo
65
  '</div>';
@@ -328,7 +329,7 @@ function wppaTryMove( id, video ) {
328
  }
329
 
330
  if ( confirm( query ) ) {
331
- wppaAjaxUpdatePhoto( id, 'moveto', document.getElementById( 'target-' + id ) );
332
  }
333
  }
334
 
@@ -349,7 +350,7 @@ function wppaTryCopy( id, video ) {
349
  }
350
 
351
  if ( confirm( query ) ) {
352
- wppaAjaxUpdatePhoto( id, 'copyto', document.getElementById( 'target-' + id ) );
353
  }
354
  }
355
 
@@ -379,7 +380,7 @@ function wppaTryRotLeft( id ) {
379
  var query = '<?php echo esc_js( __( 'Are you sure you want to rotate this photo left?', 'wp-photo-album-plus' ) ) ?>';
380
 
381
  if ( confirm( query ) ) {
382
- wppaAjaxUpdatePhoto( id, 'rotleft', 0, <?php echo ( wppa( 'front_edit' ) ? 'false' : 'true' ) ?> );
383
  }
384
  }
385
 
@@ -388,7 +389,7 @@ function wppaTryRot180( id ) {
388
  var query = '<?php echo esc_js( __( 'Are you sure you want to rotate this photo 180&deg;?', 'wp-photo-album-plus' ) ) ?>';
389
 
390
  if ( confirm( query ) ) {
391
- wppaAjaxUpdatePhoto( id, 'rot180', 0, <?php echo ( wppa( 'front_edit' ) ? 'false' : 'true' ) ?> );
392
  }
393
  }
394
 
@@ -397,7 +398,7 @@ function wppaTryRotRight( id ) {
397
  var query = '<?php echo esc_js( __( 'Are you sure you want to rotate this photo right?', 'wp-photo-album-plus' ) ) ?>';
398
 
399
  if ( confirm( query ) ) {
400
- wppaAjaxUpdatePhoto( id, 'rotright', 0, <?php echo ( wppa( 'front_edit' ) ? 'false' : 'true' ) ?> );
401
  }
402
  }
403
 
@@ -406,7 +407,7 @@ function wppaTryFlip( id ) {
406
  var query = '<?php echo esc_js( __( 'Are you sure you want to flip this photo?', 'wp-photo-album-plus' ) ) ?>';
407
 
408
  if ( confirm( query ) ) {
409
- wppaAjaxUpdatePhoto( id, 'flip', 0, <?php echo ( wppa( 'front_edit' ) ? 'false' : 'true' ) ?> );
410
  }
411
  }
412
 
@@ -415,7 +416,7 @@ function wppaTryFlop( id ) {
415
  var query = '<?php echo esc_js( __( 'Are you sure you want to flip this photo?', 'wp-photo-album-plus' ) ) ?>';
416
 
417
  if ( confirm( query ) ) {
418
- wppaAjaxUpdatePhoto( id, 'flop', 0, <?php echo ( wppa( 'front_edit' ) ? 'false' : 'true' ) ?> );
419
  }
420
  }
421
 
@@ -447,13 +448,17 @@ function wppaTryWatermark( id, hasSource, canRemove ) {
447
  }
448
  }
449
 
450
- function wppaTryMagick( id, slug ) {
 
 
 
 
451
 
452
  var query = '<?php echo esc_js( __( 'Are you sure you want to magically process this photo?', 'wp-photo-album-plus' ) ) ?>';
453
 
454
  if ( true || confirm( query ) ) {
455
  jQuery( '#wppa-admin-spinner' ).css( 'display', 'inline' );
456
- _wppaAjaxUpdatePhoto( id, slug, 0, false );
457
  }
458
  }
459
 
@@ -472,7 +477,7 @@ function wppaToggleHorizon() {
472
  function wppaTryScheduledel( id ) {
473
  wppaPhotoStatusChange( id );
474
  if ( jQuery( '#scheduledel-' + id ).attr( 'checked' ) != 'checked' ) {
475
- _wppaAjaxUpdatePhoto( id, 'removescheduledel', 0, true );
476
  }
477
  }
478
 
@@ -512,7 +517,7 @@ function wppaToggleExif( id, count ) {
512
 
513
  // We may not use extract(), so we do something like it here manually, hence controlled.
514
  $id = $photo['id'];
515
- $timestamp = $photo['timestamp'];
516
  $modified = $photo['modified'];
517
  $owner = $photo['owner'];
518
  $crypt = $photo['crypt'];
@@ -542,6 +547,7 @@ function wppaToggleExif( id, count ) {
542
  $ext = $photo['ext'];
543
  $sname = $photo['sname'];
544
  $dlcount = $photo['dlcount'];
 
545
 
546
  // See if item is a multimedia item
547
  $is_multi = wppa_is_multi( $id );
@@ -569,7 +575,7 @@ function wppaToggleExif( id, count ) {
569
  'botlft' => __( 'bottom - left' , 'wp-photo-album-plus'), 'botcen' => __( 'bottom - center' , 'wp-photo-album-plus'), 'botrht' => __( 'bottom - right' , 'wp-photo-album-plus'), );
570
 
571
  // Album for moderate
572
- if ( $modalbum != $album && ! isset( $_GET['just-edit'] ) ) {
573
  echo '<h3>' . sprintf( __( 'Edit/Moderate photos from album %s by %s', 'wp-photo-album-plus' ),
574
  '<i>' . sanitize_text_field( wppa_get_album_name( $album ) ) . '</i>',
575
  '<i>' . sanitize_user( wppa_get_album_item( $album, 'owner' ) ) . '</i>' ) . '</h3>';
@@ -644,13 +650,13 @@ function wppaToggleExif( id, count ) {
644
  }
645
  echo
646
  '<a' .
647
- ' id="fs-a-' . $id . '"' .
648
  ' href="' . $big . '"' .
649
  ' target="_blank"' .
650
  ' title="' . esc_attr( __( 'Preview fullsize photo', 'wp-photo-album-plus' ) ) . '"' .
651
  ' >' .
652
  '<img' .
653
- ' id="tnp-' . $id . '"' .
654
  ' ' . ( wppa_switch( 'lazy' ) && $count > '1' ? 'data-' : '' ) . 'src="' . $src . '"' .
655
  ' alt="' . esc_attr( $name ) . '"' .
656
  ' style="max-width: 160px; vertical-align:middle;"' .
@@ -696,8 +702,7 @@ function wppaToggleExif( id, count ) {
696
  __( 'Owned by:', 'wp-photo-album-plus' ) .
697
  '<input' .
698
  ' type="text"' .
699
- ' onkeyup="wppaAjaxUpdatePhoto( ' . $id . ', \'owner\', this )"' .
700
- ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'owner\', this )"' .
701
  ' value="' . esc_attr( $owner ) . '"' .
702
  ' /> ';
703
  }
@@ -726,7 +731,9 @@ function wppaToggleExif( id, count ) {
726
  if ( $modified > $timestamp ) {
727
  echo
728
  ' ' . __( 'Modified:', 'wp-photo-album-plus' ) . ' ' .
729
- wppa_local_date( '', $modified ) . ' ' . __( 'local time', 'wp-photo-album-plus' );
 
 
730
  }
731
  else {
732
  echo
@@ -743,8 +750,7 @@ function wppaToggleExif( id, count ) {
743
  '<input' .
744
  ' type="text"' .
745
  ' style="width:125px;"' .
746
- ' onkeyup="wppaAjaxUpdatePhoto( ' . $id . ', \'exifdtm\', this )"' .
747
- ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'exifdtm\', this )"' .
748
  ' value="' . $exifdtm . '"' .
749
  ' />';
750
  }
@@ -771,16 +777,14 @@ function wppaToggleExif( id, count ) {
771
  ' type="text"' .
772
  ' style="width:100px;"' .
773
  ' id="lat-' . $id . '"' .
774
- ' onkeyup="wppaAjaxUpdatePhoto( ' . $id . ', \'lat\', this );"' .
775
- ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'lat\', this );"' .
776
  ' value="' . esc_attr( $geo['2'] ) . '"' .
777
  ' />' .
778
  __( 'Lon:', 'wp-photo-album-plus' ) .
779
  '<input type="text"' .
780
  ' style="width:100px;"' .
781
  ' id="lon-' . $id . '"' .
782
- ' onkeyup="wppaAjaxUpdatePhoto( ' . $id . ', \'lon\', this );"' .
783
- ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'lon\', this );"' .
784
  ' value="' . esc_attr( $geo['3'] ) . '"' .
785
  ' />';
786
  }
@@ -796,8 +800,7 @@ function wppaToggleExif( id, count ) {
796
  ' id="porder-' . $id . '"' .
797
  ' value="' . esc_attr( $p_order ) . '"' .
798
  ' style="width:30px;"' .
799
- ' onkeyup="wppaAjaxUpdatePhoto( ' . $id . ', \'p_order\', this )"' .
800
- ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'p_order\', this )"' .
801
  ' />' .
802
  ' ';
803
  }
@@ -883,7 +886,7 @@ function wppaToggleExif( id, count ) {
883
  echo
884
  '<select' .
885
  ' id="status-' . $id . '"' .
886
- ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'status\', this ); wppaPhotoStatusChange( ' . $id . ' );"' .
887
  ' >' .
888
  '<option value="pending"' . ( $status == 'pending' ? $sel : '' ) . ' >' .
889
  __( 'Pending', 'wp-photo-album-plus' ) .
@@ -955,7 +958,7 @@ function wppaToggleExif( id, count ) {
955
  echo
956
  __( 'Remark:', 'wp-photo-album-plus' ) . ' ' .
957
  '<span' .
958
- ' id="photostatus-' . $id . '"' .
959
  ' style="font-weight:bold;color:#00AA00;"' .
960
  ' >' .
961
  ( $is_video ? sprintf( __( 'Video %s is not modified yet', 'wp-photo-album-plus' ), $id ) :
@@ -1004,16 +1007,23 @@ function wppaToggleExif( id, count ) {
1004
  $dp = wppa_get_photo_path( $id );
1005
  if ( is_file( $dp ) ) {
1006
  echo
 
 
 
 
 
 
1007
  '<span id="dispfileinfo-' . $id . '" >' .
1008
  floor( wppa_get_photox( $id ) ) . ' x ' . floor( wppa_get_photoy( $id ) ).' px, ' .
1009
  wppa_get_filesize( $dp ) . '.' .
1010
  '</span> ';
 
1011
  }
1012
  else {
1013
  echo
1014
  '<span style="color:red;" >' .
1015
  __( 'Unavailable', 'wp-photo-album-plus' ) . '. ' .
1016
- '</span>';
1017
  }
1018
 
1019
  // Thumbnail
@@ -1022,23 +1032,34 @@ function wppaToggleExif( id, count ) {
1022
  __( 'Thumbnail file:', 'wp-photo-album-plus') . ' ';
1023
  $tp = wppa_get_thumb_path( $id );
1024
  if ( is_file( $tp ) ) {
 
 
 
 
 
 
 
1025
  echo
1026
- floor( wppa_get_thumbx( $id ) ) . ' x ' . floor( wppa_get_thumby( $id ) ) . ' px, ' .
1027
- wppa_get_filesize( $tp ) . '. ';
 
 
 
 
 
1028
  }
1029
  else {
1030
  echo
1031
  '<span style="color:red;" >' .
1032
  __( 'Unavailable', 'wp-photo-album-plus' ) . '. ' .
1033
- '</span>';
1034
  }
1035
  }
1036
 
1037
  // Local CDN
1038
  if ( wppa_cdn( 'admin' ) == 'local' ) {
1039
- echo __( 'Local CDN files', 'wp-photo-album-plus' ) . ': ';
1040
  $files = wppa_cdn_files( $id );
1041
- //var_dump($files);
1042
  if ( is_array( $files ) ) {
1043
  foreach( $files as $file ) {
1044
  if ( basename( $file ) != 'index.php' ) {
@@ -1058,6 +1079,7 @@ function wppaToggleExif( id, count ) {
1058
  }
1059
  }
1060
  }
 
1061
  }
1062
 
1063
  // New line
@@ -1070,16 +1092,14 @@ function wppaToggleExif( id, count ) {
1070
  __( 'Width:', 'wp-photo-album-plus' ) .
1071
  '<input' .
1072
  ' style="width:50px;margin:0 4px;"' .
1073
- ' onkeyup="wppaAjaxUpdatePhoto( ' . strval( intval( $id ) ) . ', \'videox\', this )"' .
1074
- ' onchange="wppaAjaxUpdatePhoto( ' . strval( intval( $id ) ) . ', \'videox\', this )"' .
1075
  ' value="' . esc_attr( $videox ) . '"' .
1076
  ' />' .
1077
  sprintf( __( 'pix, (0=default:%s)', 'wp-photo-album-plus' ), wppa_opt( 'video_width' ) ) .
1078
  __( 'Height:', 'wp-photo-album-plus' ) .
1079
  '<input' .
1080
  ' style="width:50px;margin:0 4px;"' .
1081
- ' onkeyup="wppaAjaxUpdatePhoto( ' . strval( intval( $id ) ) . ', \'videoy\', this )"' .
1082
- ' onchange="wppaAjaxUpdatePhoto( ' . strval( intval( $id ) ) . ', \'videoy\', this )"' .
1083
  ' value="' . esc_attr( $videoy ) . '"' .
1084
  ' />' .
1085
  sprintf( __( 'pix, (0=default:%s)', 'wp-photo-album-plus' ), wppa_opt( 'video_height' ) ) .
@@ -1149,7 +1169,7 @@ function wppaToggleExif( id, count ) {
1149
  __( 'Stereophoto:', 'wp-photo-album-plus' ) . ' ' .
1150
  '<select' .
1151
  ' id="stereo-' . $id . '"' .
1152
- ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'stereo\', this )"' .
1153
  ' >' .
1154
  '<option value="0"' . ( $stereo == '0' ? ' selected="selected"' : '' ) . ' >' .
1155
  __( 'no stereo image or ready anaglyph', 'wp-photo-album-plus' ) .
@@ -1194,7 +1214,7 @@ function wppaToggleExif( id, count ) {
1194
  echo
1195
  __( 'Panorama' ) . ': ' .
1196
  ( $can_panorama ?
1197
- '<select onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'panorama\', this )" >' .
1198
  '<option value="0"' . ( $panorama == '0' ? ' selected="selected"' : '' ) . ' >' . __( '- none -', 'wp-photo-album-plus' ) . '</option>' .
1199
  '<option value="1"' . ( $panorama == '1' ? ' selected="selected"' : '' ) . ' >' . __( '360&deg; Spheric', 'wp-photo-album-plus' ) . '</option>' .
1200
  '<option value="2"' . ( $panorama == '2' ? ' selected="selected"' : '' ) . ' >' . __( 'Non 360&deg; Flat', 'wp-photo-album-plus' ) . '</option>' .
@@ -1221,14 +1241,14 @@ function wppaToggleExif( id, count ) {
1221
  echo
1222
  '<select' .
1223
  ' id="wmfsel_' . $id . '"' .
1224
- ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'wppa_watermark_file_' . $user . '\', this );"' .
1225
  ' >' .
1226
  wppa_watermark_file_select( 'user', $album ) .
1227
  '</select>' .
1228
  ' ' . __( 'Pos:', 'wp-photo-album-plus' ) . ' ' .
1229
  '<select' .
1230
  ' id="wmpsel_' . $id . '"' .
1231
- ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'wppa_watermark_pos_' . $user . '\', this );"' .
1232
  ' >' .
1233
  wppa_watermark_pos_select( 'user', $album ) .
1234
  '</select>' .
@@ -1320,7 +1340,7 @@ function wppaToggleExif( id, count ) {
1320
  '<input' .
1321
  ' type="button"' .
1322
  ' title="' . esc_attr( __( 'Remake display file and thumbnail file', 'wp-photo-album-plus' ) ) . '"' .
1323
- ' onclick="wppaAjaxUpdatePhoto( ' . $id . ', \'remake\', this, ' . ( wppa( 'front_edit' ) ? 'false' : 'true' ) . ' )"' .
1324
  ' value="' . esc_attr( __( 'Remake files', 'wp-photo-album-plus' ) ) . '"' .
1325
  ' />' .
1326
  ' ';
@@ -1331,8 +1351,8 @@ function wppaToggleExif( id, count ) {
1331
  echo
1332
  '<input' .
1333
  ' type="button"' .
1334
- ' title=' . esc_attr( __( 'Remake thumbnail file', 'wp-photo-album-plus' ) ) . '"' .
1335
- ' onclick="wppaAjaxUpdatePhoto( ' . $id . ', \'remakethumb\', this, ' . ( wppa( 'front_edit' ) ? 'false' : 'true' ) . ' )"' .
1336
  ' value="' . esc_attr( __( 'Remake thumbnail file', 'wp-photo-album-plus' ) ) . '"' .
1337
  ' />' .
1338
  ' ';
@@ -1670,7 +1690,62 @@ function wppaToggleExif( id, count ) {
1670
  ' title="-sepia-tone 80%"' .
1671
  ' />' .
1672
  ' ';
 
 
1673
  echo
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1674
  '</td>' .
1675
  '</tr>' .
1676
  '<tr>' .
@@ -1678,7 +1753,7 @@ function wppaToggleExif( id, count ) {
1678
  __( '<b>ImageMagick</b> command stack', 'wp-photo-album-plus' ) .
1679
  ': ' .
1680
  '<span' .
1681
- ' id="imstack-' . strval( intval( $id ) ). '"' .
1682
  ' style="color:blue;"' .
1683
  ' >' .
1684
  sanitize_text_field( $magickstack ) .
@@ -1690,7 +1765,7 @@ function wppaToggleExif( id, count ) {
1690
  ' onclick="wppaTryMagick( ' . strval( intval( $id ) ) . ', \'magickundo\' )"' .
1691
  ' value="' . esc_attr( __( 'Undo', 'wp-photo-album-plus' ) ) . '"' .
1692
  ' title="' . esc_attr( __( 'Undo last Magick command', 'wp-photo-album-plus' ) ) . '"' .
1693
- ' style="' . ( $magickstack ? '' : 'display:none;' ) . '"' .
1694
  ' />' .
1695
  '</td>' .
1696
  '</tr>';
@@ -1703,33 +1778,44 @@ function wppaToggleExif( id, count ) {
1703
  '<img' .
1704
  ' id="fs-img-' . $id . '"' .
1705
  ' ' . ( wppa_switch( 'lazy' ) && $count > '1' ? 'data-' : '' ) . 'src="' . wppa_get_photo_url( $id ) . '"' .
1706
- ' style="float:left;max-width:90%;" ' .
1707
  ( wppa_switch( 'lazy' ) && $count > '1' ? ' class="wppa-lazy"' : '' ) .
1708
  ' />' .
1709
- '<div' .
1710
- ' style="display:inline-block;vertical-align:middle;margin-left:4px;margin-top:' . ( min( 600, wppa_get_photoy( $id ) ) / 2 - 30 ) . 'px;"' .
1711
- ' >' .
1712
- '<input' .
1713
- ' type="button"' .
1714
- ' onclick="wppaTryMagick( ' . $id . ', \'skyleft\' );"' .
1715
- ' value="' . esc_attr( 'Up', 'wp-photo-album-plus' ) . '"' .
1716
- ' title="' . esc_attr( 'Turn horizon up by 0.5&deg;', 'wp-photo-album-plus' ) . '"' .
1717
- ' />' .
1718
- '<br />' .
1719
- '<input' .
1720
- ' type="button"' .
1721
- ' onclick="wppaToggleHorizon()"' .
1722
- ' value="' . esc_attr( 'Hor', 'wp-photo-album-plus' ) . '"' .
1723
- ' title="' . esc_attr( 'Toggle horizon reference line on/off', 'wp-photo-album-plus' ) . '"' .
1724
- ' />' .
1725
- '<br />' .
1726
- '<input' .
1727
- ' type="button"' .
1728
- ' onclick="wppaTryMagick( ' . $id . ', \'skyright\' );"' .
1729
- ' value="' . esc_attr( 'Down', 'wp-photo-album-plus' ) . '"' .
1730
- ' title="' . esc_attr( 'Turn horizon down by 0.5&deg;', 'wp-photo-album-plus' ) . '"' .
1731
- ' />' .
1732
- '</div>' .
 
 
 
 
 
 
 
 
 
 
 
1733
  '</td>' .
1734
  '</tr>';
1735
 
@@ -1760,8 +1846,7 @@ function wppaToggleExif( id, count ) {
1760
  ' type="text"' .
1761
  ' style="width:100%;"' .
1762
  ' id="pname-' . $id . '"' .
1763
- ' onkeyup="wppaAjaxUpdatePhoto( ' . $id . ', \'name\', this );"' .
1764
- ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'name\', this );"' .
1765
  ' value="' . esc_attr( stripslashes( $name ) ) . '"' .
1766
  ' />
1767
  <br />
@@ -1813,8 +1898,7 @@ function wppaToggleExif( id, count ) {
1813
  '<td>' .
1814
  '<textarea' .
1815
  ' style="width:100%;height:60px;"' .
1816
- ' onkeyup="wppaAjaxUpdatePhoto( ' . $id . ', \'description\', this )"' .
1817
- ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'description\', this )"' .
1818
  ' >' .
1819
  esc_textarea( stripslashes( $description ) ) .
1820
  '</textarea>' .
@@ -1853,7 +1937,7 @@ function wppaToggleExif( id, count ) {
1853
  ' id="tags-' . $id . '"' .
1854
  ' type="text"' .
1855
  ' style="width:100%;"' .
1856
- ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'tags\', this )"' .
1857
  ' value="' . $tags . '"' .
1858
  ( $allowed ? '' : ' readonly="readonly"' ) .
1859
  ' />' .
@@ -1909,8 +1993,7 @@ function wppaToggleExif( id, count ) {
1909
  ' type="text"' .
1910
  ' style="width:100%;"' .
1911
  ' id="custom_' . $key . '-' . $id . '"' .
1912
- ' onkeyup="wppaAjaxUpdatePhoto( ' . $id . ', \'custom_' . $key . '\', this );"' .
1913
- ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'custom_' . $key . '\', this );"' .
1914
  ' value="' . esc_attr( stripslashes( $custom_data[$key] ) ) . '"' .
1915
  '/>' .
1916
  '</td>' .
@@ -1952,15 +2035,14 @@ function wppaToggleExif( id, count ) {
1952
  ' type="text"' .
1953
  ' id="pislink-' . $id . '"' .
1954
  ' style="width:100%;"' .
1955
- ' onkeyup="wppaAjaxUpdatePhoto( ' . $id . ', \'linkurl\', this )"' .
1956
- ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'linkurl\', this )"' .
1957
  ' value="' . esc_attr( $linkurl ) . '"' .
1958
  ' />' .
1959
  '</td>' .
1960
  '<td>' .
1961
  '<select' .
1962
  ' id="pistarget-' . $id . '"' .
1963
- ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'linktarget\', this )"' .
1964
  ' >' .
1965
  '<option' .
1966
  ' value="_self"' .
@@ -1993,8 +2075,7 @@ function wppaToggleExif( id, count ) {
1993
  '<input' .
1994
  ' type="text"' .
1995
  ' style="width:100%;"' .
1996
- ' onkeyup="wppaAjaxUpdatePhoto( ' . $id . ', \'linktitle\', this )"' .
1997
- ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'linktitle\', this )"' .
1998
  ' value="' . esc_attr( $linktitle ) . '"' .
1999
  ' />';
2000
  if ( current_user_can( 'wppa_settings' ) ) {
@@ -2022,8 +2103,7 @@ function wppaToggleExif( id, count ) {
2022
  '<input' .
2023
  ' type="text"' .
2024
  ' style="width:100%;"' .
2025
- ' onkeyup="wppaAjaxUpdatePhoto( ' . $id . ', \'alt\', this )"' .
2026
- ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'alt\', this )"' .
2027
  ' value="' . esc_attr( $alt ) . '"' .
2028
  ' />' .
2029
  '</td>' .
@@ -2562,7 +2642,7 @@ function wppaTryMove( id, video ) {
2562
 
2563
  if ( jQuery('#confirm-move').attr('checked') != 'checked' || confirm( query ) ) {
2564
  jQuery( '#moving-' + id ).html( '<?php _e( 'Moving...', 'wp-photo-album-plus' ) ?>' );
2565
- _wppaAjaxUpdatePhoto( id, 'moveto', jQuery( '#target-' + id ).val(), false, '<td colspan="8" >', '</td>' );
2566
  }
2567
  }
2568
 
@@ -2829,7 +2909,7 @@ function wppaSetConfirmMove( id ) {
2829
  <!-- Name, size, move -->
2830
  <!-- Name -->
2831
  <td style="width:25%;" >
2832
- <input type="text" style="width:300px;" id="pname-<?php echo $photo['id'] ?>" onchange="wppaAjaxUpdatePhoto( <?php echo $photo['id'] ?>, 'name', this );" value="<?php echo esc_attr( stripslashes( $photo['name'] ) ) ?>" />
2833
  <!-- Size -->
2834
  <?php
2835
  if ( wppa_is_video( $photo['id'] ) ) {
@@ -2878,12 +2958,12 @@ function wppaSetConfirmMove( id ) {
2878
  </td>
2879
  <!-- Description -->
2880
  <td style="width:25%;" >
2881
- <textarea class="wppa-bulk-dec" style="height:50px; width:100%" onchange="wppaAjaxUpdatePhoto( <?php echo $photo['id'] ?>, 'description', this )" ><?php echo( esc_textarea( stripslashes( $photo['description'] ) ) ) ?></textarea>
2882
  </td>
2883
  <!-- Status -->
2884
  <td>
2885
  <?php if ( current_user_can( 'wppa_admin' ) || current_user_can( 'wppa_moderate' ) ) { ?>
2886
- <select id="status-<?php echo $photo['id'] ?>" onchange="wppaAjaxUpdatePhoto( <?php echo $photo['id'] ?>, 'status', this ); wppaPhotoStatusChange( <?php echo $photo['id'] ?> ); ">
2887
  <option value="pending" <?php if ( $photo['status']=='pending' ) echo 'selected="selected"'?> ><?php _e( 'Pending' , 'wp-photo-album-plus') ?></option>
2888
  <option value="publish" <?php if ( $photo['status']=='publish' ) echo 'selected="selected"'?> ><?php _e( 'Publish' , 'wp-photo-album-plus') ?></option>
2889
  <?php if ( wppa_switch( 'ext_status_restricted' ) && ! wppa_user_is( 'administrator' ) ) $dis = ' disabled'; else $dis = ''; ?>
@@ -2911,7 +2991,7 @@ function wppaSetConfirmMove( id ) {
2911
  <?php echo $photo['owner'] ?>
2912
  </td>
2913
  <!-- Remark -->
2914
- <td id="photostatus-<?php echo $photo['id'] ?>" style="width:25%;" >
2915
  <?php _e( 'Not modified' , 'wp-photo-album-plus') ?>
2916
  <script type="text/javascript" >wppaPhotoStatusChange( <?php echo $photo['id'] ?> )</script>
2917
  </td>
3
  * Package: wp-photo-album-plus
4
  *
5
  * edit and delete photos
6
+ * Version 7.2.03
7
  *
8
  */
9
 
60
  echo
61
  '<div class="wrap">' .
62
  '<h2>' . __( 'Edit photo', 'wp-photo-album-plus' ) . '</h2>';
63
+ echo $_GET['just-edit'];
64
  wppa_album_photos( '', $photo, '', false );
65
  echo
66
  '</div>';
329
  }
330
 
331
  if ( confirm( query ) ) {
332
+ wppaAjaxUpdatePhoto( id, 'moveto', document.getElementById( 'target-' + id ).value );
333
  }
334
  }
335
 
350
  }
351
 
352
  if ( confirm( query ) ) {
353
+ wppaAjaxUpdatePhoto( id, 'copyto', document.getElementById( 'target-' + id ).value );
354
  }
355
  }
356
 
380
  var query = '<?php echo esc_js( __( 'Are you sure you want to rotate this photo left?', 'wp-photo-album-plus' ) ) ?>';
381
 
382
  if ( confirm( query ) ) {
383
+ wppaAjaxUpdatePhoto( id, 'rotleft', 0, true );
384
  }
385
  }
386
 
389
  var query = '<?php echo esc_js( __( 'Are you sure you want to rotate this photo 180&deg;?', 'wp-photo-album-plus' ) ) ?>';
390
 
391
  if ( confirm( query ) ) {
392
+ wppaAjaxUpdatePhoto( id, 'rot180', 0, true );
393
  }
394
  }
395
 
398
  var query = '<?php echo esc_js( __( 'Are you sure you want to rotate this photo right?', 'wp-photo-album-plus' ) ) ?>';
399
 
400
  if ( confirm( query ) ) {
401
+ wppaAjaxUpdatePhoto( id, 'rotright', 0, true );
402
  }
403
  }
404
 
407
  var query = '<?php echo esc_js( __( 'Are you sure you want to flip this photo?', 'wp-photo-album-plus' ) ) ?>';
408
 
409
  if ( confirm( query ) ) {
410
+ wppaAjaxUpdatePhoto( id, 'flip', 0, true );
411
  }
412
  }
413
 
416
  var query = '<?php echo esc_js( __( 'Are you sure you want to flip this photo?', 'wp-photo-album-plus' ) ) ?>';
417
 
418
  if ( confirm( query ) ) {
419
+ wppaAjaxUpdatePhoto( id, 'flop', 0, true );
420
  }
421
  }
422
 
448
  }
449
  }
450
 
451
+ function wppaTryMagick( id, slug, value ) {
452
+
453
+ if ( ! value ) {
454
+ value = 0;
455
+ }
456
 
457
  var query = '<?php echo esc_js( __( 'Are you sure you want to magically process this photo?', 'wp-photo-album-plus' ) ) ?>';
458
 
459
  if ( true || confirm( query ) ) {
460
  jQuery( '#wppa-admin-spinner' ).css( 'display', 'inline' );
461
+ wppaAjaxUpdatePhoto( id, slug, value, true );
462
  }
463
  }
464
 
477
  function wppaTryScheduledel( id ) {
478
  wppaPhotoStatusChange( id );
479
  if ( jQuery( '#scheduledel-' + id ).attr( 'checked' ) != 'checked' ) {
480
+ wppaAjaxUpdatePhoto( id, 'removescheduledel', 0 );
481
  }
482
  }
483
 
517
 
518
  // We may not use extract(), so we do something like it here manually, hence controlled.
519
  $id = $photo['id'];
520
+ $timestamp = ( $photo['timestamp'] ? $photo['timestamp'] : '0' );
521
  $modified = $photo['modified'];
522
  $owner = $photo['owner'];
523
  $crypt = $photo['crypt'];
547
  $ext = $photo['ext'];
548
  $sname = $photo['sname'];
549
  $dlcount = $photo['dlcount'];
550
+ $thumblock = $photo['thumblock'];
551
 
552
  // See if item is a multimedia item
553
  $is_multi = wppa_is_multi( $id );
575
  'botlft' => __( 'bottom - left' , 'wp-photo-album-plus'), 'botcen' => __( 'bottom - center' , 'wp-photo-album-plus'), 'botrht' => __( 'bottom - right' , 'wp-photo-album-plus'), );
576
 
577
  // Album for moderate
578
+ if ( $modalbum != $album && $album && ! isset( $_GET['just-edit'] ) && isset( $_GET['edit-id'] ) && $_GET['edit=id'] != 'trash' ) {
579
  echo '<h3>' . sprintf( __( 'Edit/Moderate photos from album %s by %s', 'wp-photo-album-plus' ),
580
  '<i>' . sanitize_text_field( wppa_get_album_name( $album ) ) . '</i>',
581
  '<i>' . sanitize_user( wppa_get_album_item( $album, 'owner' ) ) . '</i>' ) . '</h3>';
650
  }
651
  echo
652
  '<a' .
653
+ ' id="thumba-' . $id . '"' .
654
  ' href="' . $big . '"' .
655
  ' target="_blank"' .
656
  ' title="' . esc_attr( __( 'Preview fullsize photo', 'wp-photo-album-plus' ) ) . '"' .
657
  ' >' .
658
  '<img' .
659
+ ' id="thumburl-' . $id . '"' .
660
  ' ' . ( wppa_switch( 'lazy' ) && $count > '1' ? 'data-' : '' ) . 'src="' . $src . '"' .
661
  ' alt="' . esc_attr( $name ) . '"' .
662
  ' style="max-width: 160px; vertical-align:middle;"' .
702
  __( 'Owned by:', 'wp-photo-album-plus' ) .
703
  '<input' .
704
  ' type="text"' .
705
+ ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'owner\', this.value)"' .
 
706
  ' value="' . esc_attr( $owner ) . '"' .
707
  ' /> ';
708
  }
731
  if ( $modified > $timestamp ) {
732
  echo
733
  ' ' . __( 'Modified:', 'wp-photo-album-plus' ) . ' ' .
734
+ '<span id="modified-' . $id . '" >' .
735
+ wppa_local_date( '', $modified ) .
736
+ ' </span>' . __( 'local time', 'wp-photo-album-plus' );
737
  }
738
  else {
739
  echo
750
  '<input' .
751
  ' type="text"' .
752
  ' style="width:125px;"' .
753
+ ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'exifdtm\', this.value)"' .
 
754
  ' value="' . $exifdtm . '"' .
755
  ' />';
756
  }
777
  ' type="text"' .
778
  ' style="width:100px;"' .
779
  ' id="lat-' . $id . '"' .
780
+ ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'lat\', this.value);"' .
 
781
  ' value="' . esc_attr( $geo['2'] ) . '"' .
782
  ' />' .
783
  __( 'Lon:', 'wp-photo-album-plus' ) .
784
  '<input type="text"' .
785
  ' style="width:100px;"' .
786
  ' id="lon-' . $id . '"' .
787
+ ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'lon\', this.value);"' .
 
788
  ' value="' . esc_attr( $geo['3'] ) . '"' .
789
  ' />';
790
  }
800
  ' id="porder-' . $id . '"' .
801
  ' value="' . esc_attr( $p_order ) . '"' .
802
  ' style="width:30px;"' .
803
+ ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'p_order\', this.value)"' .
 
804
  ' />' .
805
  ' ';
806
  }
886
  echo
887
  '<select' .
888
  ' id="status-' . $id . '"' .
889
+ ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'status\', this.value); wppaPhotoStatusChange( ' . $id . ' );"' .
890
  ' >' .
891
  '<option value="pending"' . ( $status == 'pending' ? $sel : '' ) . ' >' .
892
  __( 'Pending', 'wp-photo-album-plus' ) .
958
  echo
959
  __( 'Remark:', 'wp-photo-album-plus' ) . ' ' .
960
  '<span' .
961
+ ' id="remark-' . $id . '"' .
962
  ' style="font-weight:bold;color:#00AA00;"' .
963
  ' >' .
964
  ( $is_video ? sprintf( __( 'Video %s is not modified yet', 'wp-photo-album-plus' ), $id ) :
1007
  $dp = wppa_get_photo_path( $id );
1008
  if ( is_file( $dp ) ) {
1009
  echo
1010
+ '<span id="photox-'.$id.'" >'.wppa_get_photox( $id ).'</span>' .
1011
+ ' x ' .
1012
+ '<span id="photoy-'.$id.'" >'.wppa_get_photoy( $id ).'</span>' .
1013
+ ' ' . '<span id="photofilesize-' . $id . '" >' . wppa_get_filesize( $dp ) . '</span>. ';
1014
+
1015
+ /* echo
1016
  '<span id="dispfileinfo-' . $id . '" >' .
1017
  floor( wppa_get_photox( $id ) ) . ' x ' . floor( wppa_get_photoy( $id ) ).' px, ' .
1018
  wppa_get_filesize( $dp ) . '.' .
1019
  '</span> ';
1020
+ */
1021
  }
1022
  else {
1023
  echo
1024
  '<span style="color:red;" >' .
1025
  __( 'Unavailable', 'wp-photo-album-plus' ) . '. ' .
1026
+ '</span>. ';
1027
  }
1028
 
1029
  // Thumbnail
1032
  __( 'Thumbnail file:', 'wp-photo-album-plus') . ' ';
1033
  $tp = wppa_get_thumb_path( $id );
1034
  if ( is_file( $tp ) ) {
1035
+
1036
+ echo
1037
+ '<span id="thumbx-'.$id.'" >'.wppa_get_thumbx( $id ).'</span>' .
1038
+ ' x ' .
1039
+ '<span id="thumby-'.$id.'" >'.wppa_get_thumby( $id ).'</span>';
1040
+ ' ' . '<span id="thumbfilesize-' . $id . '" >' . wppa_get_filesize( $tp ) . '</span>. ';
1041
+
1042
  echo
1043
+ ' <input' .
1044
+ ' type="checkbox"' .
1045
+ ( $thumblock ? ' checked="checked"' : '' ) .
1046
+ ' onchange="wppaAjaxUpdatePhoto( ' . strval( intval( $id ) ) . ', \'thumblock\', jQuery(this).prop(\'checked\') ? 1 : 0 );"' .
1047
+ ' /> ' .
1048
+ __( 'Locked', 'wp-photo-album-plus' ) . '. ';
1049
+
1050
  }
1051
  else {
1052
  echo
1053
  '<span style="color:red;" >' .
1054
  __( 'Unavailable', 'wp-photo-album-plus' ) . '. ' .
1055
+ '</span>. ';
1056
  }
1057
  }
1058
 
1059
  // Local CDN
1060
  if ( wppa_cdn( 'admin' ) == 'local' ) {
1061
+ echo __( 'Local CDN files', 'wp-photo-album-plus' ) . ':<span id="cdnfiles-' . $id . '" >';
1062
  $files = wppa_cdn_files( $id );
 
1063
  if ( is_array( $files ) ) {
1064
  foreach( $files as $file ) {
1065
  if ( basename( $file ) != 'index.php' ) {
1079
  }
1080
  }
1081
  }
1082
+ echo '</span>';
1083
  }
1084
 
1085
  // New line
1092
  __( 'Width:', 'wp-photo-album-plus' ) .
1093
  '<input' .
1094
  ' style="width:50px;margin:0 4px;"' .
1095
+ ' onchange="wppaAjaxUpdatePhoto( ' . strval( intval( $id ) ) . ', \'videox\', this.value)"' .
 
1096
  ' value="' . esc_attr( $videox ) . '"' .
1097
  ' />' .
1098
  sprintf( __( 'pix, (0=default:%s)', 'wp-photo-album-plus' ), wppa_opt( 'video_width' ) ) .
1099
  __( 'Height:', 'wp-photo-album-plus' ) .
1100
  '<input' .
1101
  ' style="width:50px;margin:0 4px;"' .
1102
+ ' onchange="wppaAjaxUpdatePhoto( ' . strval( intval( $id ) ) . ', \'videoy\', this.value)"' .
 
1103
  ' value="' . esc_attr( $videoy ) . '"' .
1104
  ' />' .
1105
  sprintf( __( 'pix, (0=default:%s)', 'wp-photo-album-plus' ), wppa_opt( 'video_height' ) ) .
1169
  __( 'Stereophoto:', 'wp-photo-album-plus' ) . ' ' .
1170
  '<select' .
1171
  ' id="stereo-' . $id . '"' .
1172
+ ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'stereo\', this.value)"' .
1173
  ' >' .
1174
  '<option value="0"' . ( $stereo == '0' ? ' selected="selected"' : '' ) . ' >' .
1175
  __( 'no stereo image or ready anaglyph', 'wp-photo-album-plus' ) .
1214
  echo
1215
  __( 'Panorama' ) . ': ' .
1216
  ( $can_panorama ?
1217
+ '<select onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'panorama\', this.value)" >' .
1218
  '<option value="0"' . ( $panorama == '0' ? ' selected="selected"' : '' ) . ' >' . __( '- none -', 'wp-photo-album-plus' ) . '</option>' .
1219
  '<option value="1"' . ( $panorama == '1' ? ' selected="selected"' : '' ) . ' >' . __( '360&deg; Spheric', 'wp-photo-album-plus' ) . '</option>' .
1220
  '<option value="2"' . ( $panorama == '2' ? ' selected="selected"' : '' ) . ' >' . __( 'Non 360&deg; Flat', 'wp-photo-album-plus' ) . '</option>' .
1241
  echo
1242
  '<select' .
1243
  ' id="wmfsel_' . $id . '"' .
1244
+ ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'wppa_watermark_file_' . $user . '\', this.value);"' .
1245
  ' >' .
1246
  wppa_watermark_file_select( 'user', $album ) .
1247
  '</select>' .
1248
  ' ' . __( 'Pos:', 'wp-photo-album-plus' ) . ' ' .
1249
  '<select' .
1250
  ' id="wmpsel_' . $id . '"' .
1251
+ ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'wppa_watermark_pos_' . $user . '\', this.value);"' .
1252
  ' >' .
1253
  wppa_watermark_pos_select( 'user', $album ) .
1254
  '</select>' .
1340
  '<input' .
1341
  ' type="button"' .
1342
  ' title="' . esc_attr( __( 'Remake display file and thumbnail file', 'wp-photo-album-plus' ) ) . '"' .
1343
+ ' onclick="wppaAjaxUpdatePhoto( ' . $id . ', \'remake\', 0, true )"' .
1344
  ' value="' . esc_attr( __( 'Remake files', 'wp-photo-album-plus' ) ) . '"' .
1345
  ' />' .
1346
  ' ';
1351
  echo
1352
  '<input' .
1353
  ' type="button"' .
1354
+ ' title="' . esc_attr( __( 'Remake thumbnail file', 'wp-photo-album-plus' ) ) . '"' .
1355
+ ' onclick="wppaAjaxUpdatePhoto( ' . $id . ', \'remakethumb\', 0, true )"' .
1356
  ' value="' . esc_attr( __( 'Remake thumbnail file', 'wp-photo-album-plus' ) ) . '"' .
1357
  ' />' .
1358
  ' ';
1690
  ' title="-sepia-tone 80%"' .
1691
  ' />' .
1692
  ' ';
1693
+
1694
+ // Show/hide horizon
1695
  echo
1696
+ '<input' .
1697
+ ' type="button"' .
1698
+ ' onclick="wppaToggleHorizon()"' .
1699
+ ' value="' . esc_attr( 'Show/hide horizon', 'wp-photo-album-plus' ) . '"' .
1700
+ ' title="' . esc_attr( 'Toggle horizon reference line on/off', 'wp-photo-album-plus' ) . '"' .
1701
+ ' />' .
1702
+ ' ';
1703
+
1704
+ // Anticlock 0.5 deg
1705
+ echo
1706
+ '<input' .
1707
+ ' type="button"' .
1708
+ ' onclick="wppaTryMagick( ' . $id . ', \'skyleft\' );"' .
1709
+ ' value="' . esc_attr( '0.5&deg;', 'wp-photo-album-plus' ) . '"' .
1710
+ ' title="' . esc_attr( 'Rotate image by 0.5&deg; anticlockwise', 'wp-photo-album-plus' ) . '"' .
1711
+ ' />' .
1712
+ ' ';
1713
+
1714
+ // Clockwise 0.5 deg
1715
+ echo
1716
+ '<input' .
1717
+ ' type="button"' .
1718
+ ' onclick="wppaTryMagick( ' . $id . ', \'skyright\' );"' .
1719
+ ' value="' . esc_attr( '-0.5&deg;', 'wp-photo-album-plus' ) . '"' .
1720
+ ' title="' . esc_attr( 'Rotate image by 0.5&deg; clockwise', 'wp-photo-album-plus' ) . '"' .
1721
+ ' />' .
1722
+ ' ';
1723
+
1724
+ // Crop
1725
+ echo
1726
+ '<input' .
1727
+ ' type="button"' .
1728
+ ' id="button-' . $id . '"' .
1729
+ ' value="Crop"' .
1730
+ ' title=""' .
1731
+ ' />' .
1732
+ ' ';
1733
+
1734
+ // Set cropbox aspect ratio
1735
+ echo
1736
+ '<select' .
1737
+ ' onchange="wppaCropper[' . $id . '].setAspectRatio(this.value);"' .
1738
+ '>' .
1739
+ '<option value="NaN" >' . __( 'free', 'wp-photo-album-plus' ) . '</option>' .
1740
+ '<option value="1">' . __( 'square', 'wp-photo-album-plus' ) . '</option>' .
1741
+ '<option value="1.25">' . __( '4:5 landscape clipped', 'wp-photo-album-plus' ) . '</option>' .
1742
+ '<option value="1.33333">' . __( '3:4 landscape clipped', 'wp-photo-album-plus' ) . '</option>' .
1743
+ '<option value="1.5">' . __( '2:3 landscape clipped', 'wp-photo-album-plus' ) . '</option>' .
1744
+ '<option value="1.77777">' . __( '9:16 landscape clipped', 'wp-photo-album-plus' ) . '</option>' .
1745
+ '<option value="2">' . __( '1:2 landscape clipped', 'wp-photo-album-plus' ) . '</option>' .
1746
+ '</select>';
1747
+
1748
+ echo
1749
  '</td>' .
1750
  '</tr>' .
1751
  '<tr>' .
1753
  __( '<b>ImageMagick</b> command stack', 'wp-photo-album-plus' ) .
1754
  ': ' .
1755
  '<span' .
1756
+ ' id="magickstack-' . strval( intval( $id ) ). '"' .
1757
  ' style="color:blue;"' .
1758
  ' >' .
1759
  sanitize_text_field( $magickstack ) .
1765
  ' onclick="wppaTryMagick( ' . strval( intval( $id ) ) . ', \'magickundo\' )"' .
1766
  ' value="' . esc_attr( __( 'Undo', 'wp-photo-album-plus' ) ) . '"' .
1767
  ' title="' . esc_attr( __( 'Undo last Magick command', 'wp-photo-album-plus' ) ) . '"' .
1768
+ ' style="' . ( $magickstack ? 'display:inline;' : 'display:none;' ) . '"' .
1769
  ' />' .
1770
  '</td>' .
1771
  '</tr>';
1778
  '<img' .
1779
  ' id="fs-img-' . $id . '"' .
1780
  ' ' . ( wppa_switch( 'lazy' ) && $count > '1' ? 'data-' : '' ) . 'src="' . wppa_get_photo_url( $id ) . '"' .
1781
+ ' style="float:left;max-width:100%;" ' .
1782
  ( wppa_switch( 'lazy' ) && $count > '1' ? ' class="wppa-lazy"' : '' ) .
1783
  ' />' .
1784
+
1785
+ '<script>
1786
+ window.addEventListener("DOMContentLoaded", function () {
1787
+ var image = document.querySelector("#fs-img-' . $id . '");
1788
+ var button = document.getElementById("button-' . $id . '");
1789
+
1790
+ wppaCropper['.$id.'] = new Cropper(image, {
1791
+
1792
+ ready: function (event) {
1793
+ wppaCropper['.$id.'].zoomTo(1);
1794
+ },
1795
+
1796
+ crop: function (event) {
1797
+ },
1798
+
1799
+ zoomable: false,
1800
+ viewMode: 2,
1801
+ background: false,
1802
+
1803
+ zoom: function (event) {
1804
+ if (event.detail.oldRatio === 1) {
1805
+ event.preventDefault();
1806
+ }
1807
+ },
1808
+ });
1809
+
1810
+ button.onclick = function () {
1811
+ var data = wppaCropper['.$id.'].getData(true);
1812
+ var value=data.width+"x"+data.height+(data.x<0?"-":"+")+data.x+(data.y<0?"-":"+")+data.y;
1813
+ wppaTryMagick( "' . $id . '", \'crop\', value );
1814
+ };
1815
+ });
1816
+
1817
+ </script>' .
1818
+ '<style>.cropper-drag-box{background-color:transparent;}</style>' .
1819
  '</td>' .
1820
  '</tr>';
1821
 
1846
  ' type="text"' .
1847
  ' style="width:100%;"' .
1848
  ' id="pname-' . $id . '"' .
1849
+ ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'name\', this.value);"' .
 
1850
  ' value="' . esc_attr( stripslashes( $name ) ) . '"' .
1851
  ' />
1852
  <br />
1898
  '<td>' .
1899
  '<textarea' .
1900
  ' style="width:100%;height:60px;"' .
1901
+ ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'description\', this.value)"' .
 
1902
  ' >' .
1903
  esc_textarea( stripslashes( $description ) ) .
1904
  '</textarea>' .
1937
  ' id="tags-' . $id . '"' .
1938
  ' type="text"' .
1939
  ' style="width:100%;"' .
1940
+ ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'tags\', this.value)"' .
1941
  ' value="' . $tags . '"' .
1942
  ( $allowed ? '' : ' readonly="readonly"' ) .
1943
  ' />' .
1993
  ' type="text"' .
1994
  ' style="width:100%;"' .
1995
  ' id="custom_' . $key . '-' . $id . '"' .
1996
+ ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'custom_' . $key . '\', this.value);"' .
 
1997
  ' value="' . esc_attr( stripslashes( $custom_data[$key] ) ) . '"' .
1998
  '/>' .
1999
  '</td>' .
2035
  ' type="text"' .
2036
  ' id="pislink-' . $id . '"' .
2037
  ' style="width:100%;"' .
2038
+ ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'linkurl\', this.value)"' .
 
2039
  ' value="' . esc_attr( $linkurl ) . '"' .
2040
  ' />' .
2041
  '</td>' .
2042
  '<td>' .
2043
  '<select' .
2044
  ' id="pistarget-' . $id . '"' .
2045
+ ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'linktarget\', this.value)"' .
2046
  ' >' .
2047
  '<option' .
2048
  ' value="_self"' .
2075
  '<input' .
2076
  ' type="text"' .
2077
  ' style="width:100%;"' .
2078
+ ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'linktitle\', this.value)"' .
 
2079
  ' value="' . esc_attr( $linktitle ) . '"' .
2080
  ' />';
2081
  if ( current_user_can( 'wppa_settings' ) ) {
2103
  '<input' .
2104
  ' type="text"' .
2105
  ' style="width:100%;"' .
2106
+ ' onchange="wppaAjaxUpdatePhoto( ' . $id . ', \'alt\', this.value)"' .
 
2107
  ' value="' . esc_attr( $alt ) . '"' .
2108
  ' />' .
2109
  '</td>' .
2642
 
2643
  if ( jQuery('#confirm-move').attr('checked') != 'checked' || confirm( query ) ) {
2644
  jQuery( '#moving-' + id ).html( '<?php _e( 'Moving...', 'wp-photo-album-plus' ) ?>' );
2645
+ wppaAjaxUpdatePhoto( id, 'moveto', jQuery( '#target-' + id ).val(), false, '<td colspan="8" >', '</td>' );
2646
  }
2647
  }
2648
 
2909
  <!-- Name, size, move -->
2910
  <!-- Name -->
2911
  <td style="width:25%;" >
2912
+ <input type="text" style="width:300px;" id="pname-<?php echo $photo['id'] ?>" onchange="wppaAjaxUpdatePhoto( <?php echo $photo['id'] ?>, 'name', this.value);" value="<?php echo esc_attr( stripslashes( $photo['name'] ) ) ?>" />
2913
  <!-- Size -->
2914
  <?php
2915
  if ( wppa_is_video( $photo['id'] ) ) {
2958
  </td>
2959
  <!-- Description -->
2960
  <td style="width:25%;" >
2961
+ <textarea class="wppa-bulk-dec" style="height:50px; width:100%" onchange="wppaAjaxUpdatePhoto( <?php echo $photo['id'] ?>, 'description', this.value)" ><?php echo( esc_textarea( stripslashes( $photo['description'] ) ) ) ?></textarea>
2962
  </td>
2963
  <!-- Status -->
2964
  <td>
2965
  <?php if ( current_user_can( 'wppa_admin' ) || current_user_can( 'wppa_moderate' ) ) { ?>
2966
+ <select id="status-<?php echo $photo['id'] ?>" onchange="wppaAjaxUpdatePhoto( <?php echo $photo['id'] ?>, 'status', this.value); wppaPhotoStatusChange( <?php echo $photo['id'] ?> ); ">
2967
  <option value="pending" <?php if ( $photo['status']=='pending' ) echo 'selected="selected"'?> ><?php _e( 'Pending' , 'wp-photo-album-plus') ?></option>
2968
  <option value="publish" <?php if ( $photo['status']=='publish' ) echo 'selected="selected"'?> ><?php _e( 'Publish' , 'wp-photo-album-plus') ?></option>
2969
  <?php if ( wppa_switch( 'ext_status_restricted' ) && ! wppa_user_is( 'administrator' ) ) $dis = ' disabled'; else $dis = ''; ?>
2991
  <?php echo $photo['owner'] ?>
2992
  </td>
2993
  <!-- Remark -->
2994
+ <td id="remark-<?php echo $photo['id'] ?>" style="width:25%;" >
2995
  <?php _e( 'Not modified' , 'wp-photo-album-plus') ?>
2996
  <script type="text/javascript" >wppaPhotoStatusChange( <?php echo $photo['id'] ?> )</script>
2997
  </td>
wppa-photo-files.php CHANGED
@@ -2,7 +2,7 @@
2
  /* wppa-photo-files.php
3
  *
4
  * Functions used to create/manipulate photofiles
5
- * Version 7.1.10
6
  *
7
  */
8
 
@@ -400,6 +400,15 @@ wppa_log('dbg', 'make called with'.$file.' '.$id.' '.$ext.' '.$do_thumb. ' exist
400
  wppa_create_thumbnail( $id );
401
  }
402
 
 
 
 
 
 
 
 
 
 
403
  // Clear (super)cache
404
  wppa_clear_cache();
405
  return true;
@@ -409,6 +418,11 @@ wppa_log('dbg', 'make called with'.$file.' '.$id.' '.$ext.' '.$do_thumb. ' exist
409
  // Create thubnail
410
  function wppa_create_thumbnail( $id, $use_source = true ) {
411
 
 
 
 
 
 
412
  if ( $use_source && ! wppa_switch( 'watermark_thumbs' ) ) {
413
 
414
  // Try o1 source
2
  /* wppa-photo-files.php
3
  *
4
  * Functions used to create/manipulate photofiles
5
+ * Version 7.2.03
6
  *
7
  */
8
 
400
  wppa_create_thumbnail( $id );
401
  }
402
 
403
+ // Reset sizes
404
+ wppa_get_photox( $id, true );
405
+ wppa_get_photoy( $id, true );
406
+ wppa_get_thumbx( $id, true );
407
+ wppa_get_thumby( $id, true );
408
+
409
+ // Clear magickstack
410
+ wppa_update_photo( array( 'id' => $id, 'magickstack' => '' ) );
411
+
412
  // Clear (super)cache
413
  wppa_clear_cache();
414
  return true;
418
  // Create thubnail
419
  function wppa_create_thumbnail( $id, $use_source = true ) {
420
 
421
+ $locked = wppa_get_photo_item( $id, 'thumblock' );
422
+ if ( $locked ) {
423
+ return false;
424
+ }
425
+
426
  if ( $use_source && ! wppa_switch( 'watermark_thumbs' ) ) {
427
 
428
  // Try o1 source
wppa-setup.php CHANGED
@@ -3,7 +3,7 @@
3
  * Package: wp-photo-album-plus
4
  *
5
  * Contains all the setup stuff
6
- * Version 7.2.01
7
  *
8
  */
9
 
@@ -113,6 +113,7 @@ global $wppa_error;
113
  panorama smallint(5) NOT NULL default '0',
114
  sname text NOT NULL,
115
  dlcount bigint(20) NOT NULL default '0',
 
116
  PRIMARY KEY (id),
117
  KEY albumkey (album),
118
  KEY statuskey (status(6))
@@ -614,6 +615,10 @@ global $wppa_error;
614
  if ( $old_rev <= '7102' ) {
615
  wppa_rename_setting( 'wppa_thumb_area_size', 'wppa_area_size' );
616
  }
 
 
 
 
617
  }
618
 
619
  // Set Defaults
3
  * Package: wp-photo-album-plus
4
  *
5
  * Contains all the setup stuff
6
+ * Version 7.2.03
7
  *
8
  */
9
 
113
  panorama smallint(5) NOT NULL default '0',
114
  sname text NOT NULL,
115
  dlcount bigint(20) NOT NULL default '0',
116
+ thumblock smallint(5) default '0',
117
  PRIMARY KEY (id),
118
  KEY albumkey (album),
119
  KEY statuskey (status(6))
615
  if ( $old_rev <= '7102' ) {
616
  wppa_rename_setting( 'wppa_thumb_area_size', 'wppa_area_size' );
617
  }
618
+
619
+ if ( $old_rev <= '7203' ) {
620
+ $wpdb->query( "UPDATE $wpdb->wppa_albums SET timestamp = modified WHERE timestamp = ''" );
621
+ }
622
  }
623
 
624
  // Set Defaults
wppa-wpdb-insert.php CHANGED
@@ -3,7 +3,7 @@
3
  * Package: wp-photo-album-plus
4
  *
5
  * Contains low-level wpdb routines that add new records
6
- * Version 7.2.00
7
  *
8
  */
9
 
@@ -282,6 +282,7 @@ global $wpdb;
282
  'panorama' => '0',
283
  'sname' => wppa_sanitize_album_photo_name( isset( $args['name'] ) ? $args['name'] : '' ),
284
  'dlcount' => '0',
 
285
  ) );
286
 
287
  if ( $args['scheduledtm'] ) $args['status'] = 'scheduled';
@@ -329,9 +330,10 @@ global $wpdb;
329
  indexdtm,
330
  panorama,
331
  sname,
332
- dlcount
 
333
  )
334
- VALUES ( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s )",
335
  $args['id'],
336
  $args['album'],
337
  $args['ext'],
@@ -364,7 +366,8 @@ global $wpdb;
364
  $args['indexdtm'],
365
  $args['panorama'],
366
  $args['sname'],
367
- $args['dlcount']
 
368
  );
369
  $iret = $wpdb->query( $query );
370
 
3
  * Package: wp-photo-album-plus
4
  *
5
  * Contains low-level wpdb routines that add new records
6
+ * Version 7.2.03
7
  *
8
  */
9
 
282
  'panorama' => '0',
283
  'sname' => wppa_sanitize_album_photo_name( isset( $args['name'] ) ? $args['name'] : '' ),
284
  'dlcount' => '0',
285
+ 'thumblock' => '0',
286
  ) );
287
 
288
  if ( $args['scheduledtm'] ) $args['status'] = 'scheduled';
330
  indexdtm,
331
  panorama,
332
  sname,
333
+ dlcount,
334
+ thumblock
335
  )
336
+ VALUES ( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s )",
337
  $args['id'],
338
  $args['album'],
339
  $args['ext'],
366
  $args['indexdtm'],
367
  $args['panorama'],
368
  $args['sname'],
369
+ $args['dlcount'],
370
+ $args['thumblock']
371
  );
372
  $iret = $wpdb->query( $query );
373
 
wppa-wpdb-update.php CHANGED
@@ -3,7 +3,7 @@
3
  * Package: wp-photo-album-plus
4
  *
5
  * Contains low-level wpdb routines that update records
6
- * Version 7.2.00
7
  *
8
  */
9
 
@@ -55,6 +55,11 @@ global $wpdb;
55
  $itemvalue = time();
56
  }
57
  $doit = true;
 
 
 
 
 
58
  break;
59
  case 'cats':
60
  $itemvalue = wppa_sanitize_tags( $itemvalue );
@@ -248,6 +253,10 @@ global $wpdb;
248
  $itemvalue = strval( intval( $itemvalue ) );
249
  $doit = true;
250
  break;
 
 
 
 
251
 
252
  default:
253
  wppa_log( 'Error', 'Not implemented in wppa_update_photo(): '.$itemname );
3
  * Package: wp-photo-album-plus
4
  *
5
  * Contains low-level wpdb routines that update records
6
+ * Version 7.2.03
7
  *
8
  */
9
 
55
  $itemvalue = time();
56
  }
57
  $doit = true;
58
+ // Spurious issue exists after migration that timestamp is empty
59
+ $t = $wpdb->get_var( $wpdb->prepare( "SELECT timestamp FROM $wpdb->wppa_albums WHERE id = %d", $args['id'] ) );
60
+ if ( ! $t ) {
61
+ $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->wppa_albums SET timestamp = modified WHERE id = %d", $args['id'] ) );
62
+ }
63
  break;
64
  case 'cats':
65
  $itemvalue = wppa_sanitize_tags( $itemvalue );
253
  $itemvalue = strval( intval( $itemvalue ) );
254
  $doit = true;
255
  break;
256
+ case 'thumblock':
257
+ $itemvalue = $itemvalue ? '1' : '0';
258
+ $doit = true;
259
+ break;
260
 
261
  default:
262
  wppa_log( 'Error', 'Not implemented in wppa_update_photo(): '.$itemname );
wppa.php CHANGED
@@ -2,7 +2,7 @@
2
  /*
3
  * Plugin Name: WP Photo Album Plus
4
  * Description: Easily manage and display your photo albums and slideshows within your WordPress site.
5
- * Version: 7.2.02.005
6
  * Author: J.N. Breetvelt a.k.a. OpaJaap
7
  * Author URI: http://wppa.opajaap.nl/
8
  * Plugin URI: http://wordpress.org/extend/plugins/wp-photo-album-plus/
@@ -22,8 +22,8 @@ global $wpdb;
22
  global $wp_version;
23
 
24
  /* WPPA GLOBALS */
25
- global $wppa_revno; $wppa_revno = '7202'; // WPPA db version
26
- global $wppa_api_version; $wppa_api_version = '7.2.02.005'; // WPPA software version
27
 
28
  /* Init page js data */
29
  global $wppa_js_page_data; $wppa_js_page_data = '';
2
  /*
3
  * Plugin Name: WP Photo Album Plus
4
  * Description: Easily manage and display your photo albums and slideshows within your WordPress site.
5
+ * Version: 7.2.03.006
6
  * Author: J.N. Breetvelt a.k.a. OpaJaap
7
  * Author URI: http://wppa.opajaap.nl/
8
  * Plugin URI: http://wordpress.org/extend/plugins/wp-photo-album-plus/
22
  global $wp_version;
23
 
24
  /* WPPA GLOBALS */
25
+ global $wppa_revno; $wppa_revno = '7203'; // WPPA db version
26
+ global $wppa_api_version; $wppa_api_version = '7.2.03.006'; // WPPA software version
27
 
28
  /* Init page js data */
29
  global $wppa_js_page_data; $wppa_js_page_data = '';