MailPoet Newsletters (New) - Version 3.0.5

Version Description

  • 2017-10-10 =
  • Added: images can now be aligned left, center or right in email designer;
Download this release

Release Info

Developer wysija
Plugin Icon 128x128 MailPoet Newsletters (New)
Version 3.0.5
Comparing to
See all releases

Code changes from version 3.0.4 to 3.0.5

assets/js/{admin.5545d8c1.js → admin.790800b0.js} RENAMED
@@ -36986,11 +36986,11 @@ webpackJsonp([0],[
36986
  var percentage_opened_display = _mailpoet2['default'].Num.toLocaleFixed(percentage_opened, 1);
36987
  var percentage_unsubscribed_display = _mailpoet2['default'].Num.toLocaleFixed(percentage_unsubscribed, 1);
36988
 
36989
- var show_stats_timeout = undefined,
36990
- newsletter_date = undefined,
36991
- sent_hours_ago = undefined,
36992
- too_early_for_stats = undefined,
36993
- show_kb_link = undefined;
36994
  if (current_time !== undefined) {
36995
  // standard emails and post notifications:
36996
  // display green box for newsletters that were just sent
@@ -38846,7 +38846,7 @@ webpackJsonp([0],[
38846
  jQuery('#mailpoet_sending_method_setup').fadeIn();
38847
  }
38848
  },
38849
- tabs: function (tabStr, section) {
38850
  // set default tab
38851
  var tab = tabStr || 'mta';
38852
 
@@ -38882,6 +38882,7 @@ webpackJsonp([0],[
38882
  });
38883
  }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
38884
 
 
38885
  /***/ },
38886
  /* 535 */
38887
  /***/ function(module, exports, __webpack_require__) {
@@ -41131,7 +41132,7 @@ webpackJsonp([0],[
41131
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (
41132
  MailPoet
41133
  ) {
41134
-
41135
  function eventHandler() {
41136
  if (confirm(MailPoet.I18n.t('reinstallConfirmation'))) {
41137
  MailPoet.trackEvent(
@@ -41162,12 +41163,13 @@ webpackJsonp([0],[
41162
  return false;
41163
  }
41164
 
41165
- var element = document.getElementById('mailpoet_reinstall');
41166
  if (element) {
41167
  element.addEventListener('click', eventHandler, false);
41168
  }
41169
  }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
41170
 
 
41171
  /***/ },
41172
  /* 542 */
41173
  /***/ function(module, exports, __webpack_require__) {
@@ -41180,8 +41182,7 @@ webpackJsonp([0],[
41180
  __webpack_require__(543),
41181
  __webpack_require__(544),
41182
  __webpack_require__(545),
41183
- __webpack_require__(297),
41184
- __webpack_require__(287)
41185
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (
41186
  Backbone,
41187
  _,
@@ -41190,16 +41191,16 @@ webpackJsonp([0],[
41190
  Handlebars,
41191
  Papa,
41192
  AsyncQueue,
41193
- Moment,
41194
- select2
41195
  ) {
41196
  if (!jQuery('#mailpoet_subscribers_import').length) {
41197
  return;
41198
  }
41199
  jQuery(document).ready(function () {
 
41200
  jQuery('input[name="select_method"]').attr('checked', false);
41201
  // configure router
41202
- var router = new (Backbone.Router.extend({
41203
  routes: {
41204
  '': 'home',
41205
  step1: 'step1',
@@ -41222,8 +41223,20 @@ webpackJsonp([0],[
41222
  * STEP 1 (upload or copy/paste)
41223
  */
41224
  router.on('route:step1', function () {
 
 
 
 
 
 
 
 
 
 
 
 
41225
  // set or reset temporary validation rule on all columns
41226
- window.mailpoetColumns = jQuery.map(window.mailpoetColumns, function (column, columnIndex) {
41227
  var col = column;
41228
  col.validation_rule = false;
41229
  return col;
@@ -41235,36 +41248,34 @@ webpackJsonp([0],[
41235
  }
41236
 
41237
  // render process button for each method
41238
- var methodProcessContainerTemplate =
41239
  Handlebars.compile(jQuery('#method_process_template').html());
41240
  jQuery('.mailpoet_method_process').html(methodProcessContainerTemplate());
41241
 
41242
  // define reusable variables
41243
- var currentStepE = jQuery(location.hash),
41244
- methodSelectionElement = jQuery('#select_method'),
41245
- pasteInputElement = jQuery('#paste_input'),
41246
- pasteInputPlaceholderElement =
41247
- pasteInputElement.data('placeholder').replace(/\\n/g, '\n'),
41248
- pasteProcessButtonElement =
41249
- jQuery('#method_paste > div.mailpoet_method_process')
41250
- .find('a.mailpoet_process'),
41251
- mailChimpKeyInputElement = jQuery('#mailchimp_key'),
41252
- mailChimpKeyVerifyButtonElement = jQuery('#mailchimp_key_verify'),
41253
- mailChimpListsContainerElement = jQuery('#mailchimp_lists'),
41254
- mailChimpProcessButtonElement =
41255
- jQuery('#method_mailchimp > div.mailpoet_method_process')
41256
- .find('a.mailpoet_process'),
41257
- uploadElement = jQuery('#file_local'),
41258
- uploadProcessButtonElement =
41259
- jQuery('#method_file > div.mailpoet_method_process')
41260
- .find('a.mailpoet_process');
41261
 
41262
  // define method change behavior
41263
  methodSelectionElement.change(function () {
 
 
41264
  MailPoet.Notice.hide();
41265
- var available_methods = jQuery(':radio[name="select_method"]'),
41266
- selected_method =
41267
- available_methods.index(available_methods.filter(':checked'));
41268
  // hide all methods
41269
  currentStepE.find('.inside')
41270
  .children('div[id^="method_"]')
@@ -41303,9 +41314,9 @@ webpackJsonp([0],[
41303
  });
41304
 
41305
  pasteProcessButtonElement.click(function () {
 
41306
  MailPoet.Notice.hide();
41307
  // get an approximate size of textarea paste in bytes
41308
- var pasteSize = encodeURI(pasteInputElement.val()).split(/%..|./).length - 1;
41309
  if (pasteSize > window.maxPostSizeBytes) {
41310
  MailPoet.Notice.error(MailPoet.I18n.t('maxPostSizeNotice'));
41311
  return;
@@ -41321,8 +41332,8 @@ webpackJsonp([0],[
41321
  * CSV file
41322
  */
41323
  uploadElement.change(function () {
41324
- MailPoet.Notice.hide();
41325
  var ext = this.value.match(/\.(.+)$/);
 
41326
  if (ext === null || ext[1].toLowerCase() !== 'csv') {
41327
  this.value = '';
41328
  MailPoet.Notice.error(MailPoet.I18n.t('wrongFileFormat'));
@@ -41406,7 +41417,7 @@ webpackJsonp([0],[
41406
  api_key: mailChimpKeyInputElement.val(),
41407
  lists: mailChimpListsContainerElement.find('select').val()
41408
  }
41409
- }).always(function (response) {
41410
  MailPoet.Modal.loading(false);
41411
  }).done(function (response) {
41412
  window.importData.step1 = response.data;
@@ -41466,48 +41477,48 @@ webpackJsonp([0],[
41466
  }
41467
 
41468
  function parseCSV(isFile) {
41469
- var processedSubscribers = [],
41470
- parsedEmails = [],
41471
- duplicateEmails = [],
41472
- invalidEmails = [],
41473
- emailColumnPosition = null,
41474
- columnCount = null,
41475
- isHeaderFound = false,
41476
- advancedOptionHeader = true,
41477
- advancedOptionDelimiter = '',
41478
- advancedOptionNewline = '',
41479
- advancedOptionComments = false,
41480
- // trim spaces, commas, periods,
41481
- // single/double quotes and convert to lowercase
41482
- detectAndCleanupEmail = function (emailString) {
41483
- var test;
41484
- // decode HTML entities
41485
- var email = jQuery('<div />').html(emailString).text();
41486
- email = email
41487
- .toLowerCase()
41488
- // left/right trim spaces, punctuation (e.g., " 'email@email.com'; ")
41489
- // right trim non-printable characters (e.g., "email@email.com�")
41490
- .replace(/^["';.,\s]+|[^\x20-\x7E]+$|["';.,_\s]+$/g, '')
41491
- // remove spaces (e.g., "email @ email . com")
41492
- // remove urlencoded characters
41493
- .replace(/\s+|%\d+|,+/g, '');
41494
- // detect e-mails that will be otherwise rejected by email regex
41495
- test = /<(.*?)>/.exec(email);
41496
- if (test) {
41497
- // is the email inside angle brackets (e.g., 'some@email.com <some@email.com>')?
41498
- email = test[1].trim();
41499
- }
41500
- test = /mailto:(?:\s+)?(.*)/.exec(email);
41501
- if (test) {
41502
- // is the email in 'mailto:email' format?
41503
- email = test[1].trim();
41504
- }
41505
- // test for valid characters using WP's rule (https://core.trac.wordpress.org/browser/tags/4.7.3/src/wp-includes/formatting.php#L2902)
41506
- if (!/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.\-@]+$/.test(email)) {
41507
- return false;
41508
- }
41509
- return email;
41510
- };
41511
 
41512
  return {
41513
  skipEmptyLines: true,
@@ -41519,11 +41530,18 @@ webpackJsonp([0],[
41519
  MailPoet.Notice.error(MailPoet.I18n.t('dataProcessingError'));
41520
  },
41521
  complete: function (CSV) {
41522
- for (var rowCount in CSV.data) {
41523
- var rowData = CSV.data[rowCount].map(function (el) {
 
 
 
 
 
 
 
41524
  return el.trim();
41525
  });
41526
- var rowColumnCount = rowData.length;
41527
  // set the number of row elements based on the first non-empty row
41528
  if (columnCount === null) {
41529
  columnCount = rowColumnCount;
@@ -41537,14 +41555,14 @@ webpackJsonp([0],[
41537
  // determine position of email address inside an array; this is
41538
  // done once and then email regex is run just on that element for each row
41539
  if (emailColumnPosition === null) {
41540
- for (var column in rowData) {
41541
- var email = detectAndCleanupEmail(rowData[column]);
41542
  if (emailColumnPosition === null
41543
- && window.emailRegex.test(email)) {
41544
  emailColumnPosition = column;
41545
- parsedEmails[email] = true; // add current e-mail to an object index
41546
- rowData[column] = email;
41547
- processedSubscribers[email] = rowData;
41548
  }
41549
  }
41550
  if (emailColumnPosition === null
@@ -41555,7 +41573,7 @@ webpackJsonp([0],[
41555
  }
41556
  }
41557
  else if (rowData[emailColumnPosition] !== '') {
41558
- var email = detectAndCleanupEmail(rowData[emailColumnPosition]);
41559
  if (_.has(parsedEmails, email)) {
41560
  duplicateEmails.push(email);
41561
  }
@@ -41599,7 +41617,7 @@ webpackJsonp([0],[
41599
  }
41600
  else {
41601
  MailPoet.Modal.loading(false);
41602
- var errorNotice = MailPoet.I18n.t('noValidRecords');
41603
  errorNotice = errorNotice.replace('[link]', MailPoet.I18n.t('csvKBLink'));
41604
  errorNotice = errorNotice.replace('[/link]', '</a>');
41605
  MailPoet.Notice.error(errorNotice);
@@ -41610,37 +41628,41 @@ webpackJsonp([0],[
41610
  });
41611
 
41612
  router.on('route:step2', function () {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41613
  if (typeof (window.importData.step1) === 'undefined') {
41614
  router.navigate('step1', { trigger: true });
41615
  return;
41616
  }
41617
  // define reusable variables
41618
- var nextStepButton = jQuery('#step2_process'),
41619
- previousStepButton = jQuery('#return_to_step1'),
41620
  // create a copy of subscribers object for further manipulation
41621
- subscribers = jQuery.extend(true, {}, window.importData.step1),
41622
- subscribersDataTemplate =
41623
- Handlebars
41624
- .compile(jQuery('#subscribers_data_template')
41625
- .html()),
41626
- subscribersDataTemplatePartial =
41627
- Handlebars
41628
- .compile(jQuery('#subscribers_data_template_partial')
41629
- .html()),
41630
- subscribersDataParseResultsTemplate =
41631
- Handlebars
41632
- .compile(jQuery('#subscribers_data_parse_results_template')
41633
- .html()),
41634
- segmentSelectElement = jQuery('#mailpoet_segments_select'),
41635
- maxRowsToShow = 10,
41636
- filler = '. . .',
41637
  // create an array of filler data with the same number of
41638
  // elements as in the subscribers' data row
41639
- fillerArray = Array.apply(
41640
- null,
41641
- new Array(subscribers.subscribers[0].length)
41642
- ).map(String.prototype.valueOf, filler),
41643
- fillerPosition;
41644
 
41645
  showCurrentStep();
41646
 
@@ -41652,12 +41674,12 @@ webpackJsonp([0],[
41652
  if (subscribers.invalid.length || subscribers.duplicate.length) {
41653
  // count repeating e-mails inside duplicate array and present them in
41654
  // 'email (xN)' format
41655
- var duplicates = {};
41656
  subscribers.duplicate.forEach(function (email) {
41657
  duplicates[email] = (duplicates[email] || 0) + 1;
41658
  });
41659
  subscribers.duplicate = [];
41660
- for (var email in duplicates) {
41661
  if (duplicates[email] > 1) {
41662
  subscribers.duplicate.push(email + ' (x' + duplicates[email] + ')');
41663
  }
@@ -41666,7 +41688,7 @@ webpackJsonp([0],[
41666
  }
41667
  }
41668
 
41669
- var import_results = {
41670
  notice: MailPoet.I18n.t('importNoticeSkipped').replace(
41671
  '%1$s',
41672
  '<strong>' + (subscribers.invalid.length + subscribers.duplicate.length) + '</strong>'
@@ -41771,13 +41793,14 @@ webpackJsonp([0],[
41771
  description: segmentDescription
41772
  }
41773
  }).done(function (response) {
 
41774
  window.mailpoetSegments.push({
41775
  id: response.data.id,
41776
  name: response.data.name,
41777
  subscriberCount: 0
41778
  });
41779
 
41780
- var selected_values = segmentSelectElement.val();
41781
  if (selected_values === null) {
41782
  selected_values = [response.data.id];
41783
  } else {
@@ -41814,20 +41837,25 @@ webpackJsonp([0],[
41814
  Handlebars.registerHelper(
41815
  'show_and_match_columns',
41816
  function (subscribers, options) {
41817
- var displayedColumns = [],
41818
- displayedColumnsIds = [];
 
 
 
 
 
41819
  // go through all elements of the first row in subscribers data
41820
- for (var i in subscribers.subscribers[0]) {
41821
- var columnData = subscribers.subscribers[0][i],
41822
- columnId = 'ignore'; // set default column type
41823
  // if the column is not undefined and has a valid e-mail, set type as email
41824
  if (columnData % 1 !== 0 && window.emailRegex.test(columnData)) {
41825
  columnId = 'email';
41826
  } else if (subscribers.header) {
41827
- var headerName = subscribers.header[i],
41828
- headerNameMatch = window.mailpoetColumns.map(function (el) {
41829
- return el.name;
41830
- }).indexOf(headerName);
41831
  // set column type using header
41832
  if (headerNameMatch !== -1) {
41833
  columnId = window.mailpoetColumns[headerNameMatch].id;
@@ -41905,8 +41933,8 @@ webpackJsonp([0],[
41905
  }
41906
  })
41907
  .on('select2:selecting', function (selectEvent) {
41908
- var selectElement = this,
41909
- selectedOptionId = selectEvent.params.args.data.id;
41910
  // CREATE CUSTOM FIELD
41911
  if (selectedOptionId === 'create') {
41912
  selectEvent.preventDefault();
@@ -41915,7 +41943,7 @@ webpackJsonp([0],[
41915
  title: MailPoet.I18n.t('addNewField'),
41916
  template: jQuery('#form_template_field_form').html()
41917
  });
41918
- jQuery('#form_field_new').parsley().on('form:submit', function (parsley) {
41919
  // get data
41920
  var data = jQuery(this.$element).serializeObject();
41921
 
@@ -41979,8 +42007,8 @@ webpackJsonp([0],[
41979
  // check for duplicate values in all select options
41980
  jQuery('select.mailpoet_subscribers_column_data_match')
41981
  .each(function () {
41982
- var element = this,
41983
- elementId = jQuery(element).val();
41984
  // if another column has the same value and it's not an 'ignore', prompt user
41985
  if (elementId === selectedOptionId
41986
  && elementId !== 'ignore') {
@@ -41996,28 +42024,34 @@ webpackJsonp([0],[
41996
  }
41997
  })
41998
  .on('select2:select', function (selectEvent) {
41999
- var selectElement = this,
42000
- selectedOptionId = selectEvent.params.data.id;
42001
  jQuery(selectElement).data('column-id', selectedOptionId);
42002
  filterSubscribers();
42003
  });
42004
 
42005
  // filter subscribers' data to detect dates, emails, etc.
42006
  function filterSubscribers() {
 
 
 
42007
  jQuery(
42008
  '[data-id="notice_invalidEmail"], [data-id="notice_invalidDate"]')
42009
  .remove();
42010
- var subscribersClone = jQuery.extend(true, {}, subscribers),
42011
- preventNextStep = false,
42012
- displayedColumns = jQuery.map(
42013
- jQuery('.mailpoet_subscribers_column_data_match'), function (element, elementIndex) {
42014
- var columnId = jQuery(element).data('column-id');
42015
- var validationRule = jQuery(element).data('validation-rule');
42016
- jQuery(element).val(columnId).trigger('change');
42017
- return { id: columnId, index: elementIndex, validationRule: validationRule, element: element };
42018
- });
42019
  // iterate through the object of mailpoet columns
42020
- jQuery.map(window.mailpoetColumns, function (column, columnIndex) {
 
 
 
 
 
42021
  // check if the column id matches the selected id of one of the
42022
  // subscriber's data columns
42023
  var matchedColumn = _.find(displayedColumns, function (data) { return data.id === column.id; });
@@ -42041,7 +42075,7 @@ webpackJsonp([0],[
42041
  }
42042
  // DATE filter: if column type is date, check if we can recognize it
42043
  if (column.type === 'date' && matchedColumn) {
42044
- var allowedDateFormats = [
42045
  Moment.ISO_8601,
42046
  'YYYY/MM/DD',
42047
  'MM/DD/YYYY',
@@ -42052,8 +42086,8 @@ webpackJsonp([0],[
42052
  'YYYY/MM',
42053
  'YYYY'
42054
  ];
42055
- var firstRowData = subscribersClone.subscribers[0][matchedColumn.index];
42056
- var validationRule = false;
42057
  // check if date exists
42058
  if (firstRowData.trim() === '') {
42059
  subscribersClone.subscribers[0][matchedColumn.index] =
@@ -42064,10 +42098,10 @@ webpackJsonp([0],[
42064
  preventNextStep = true;
42065
  }
42066
  else {
42067
- for (var format in allowedDateFormats) {
42068
- var testedFormat = allowedDateFormats[format];
42069
  if (Moment(firstRowData, testedFormat, true).isValid()) {
42070
- var validationRule = (typeof (testedFormat) === 'function') ?
42071
  'datetime' :
42072
  testedFormat;
42073
  // set validation on the column element
@@ -42082,8 +42116,8 @@ webpackJsonp([0],[
42082
  jQuery.map(subscribersClone.subscribers, function (dataSubscribers, index) {
42083
  var data = dataSubscribers;
42084
  var rowData = data[matchedColumn.index];
42085
- if (index === fillerPosition || rowData.trim() === '') return;
42086
  var date = Moment(rowData, testedFormat, true);
 
42087
  // validate date
42088
  if (date.isValid()) {
42089
  data[matchedColumn.index] = new Handlebars.SafeString(
@@ -42142,33 +42176,35 @@ webpackJsonp([0],[
42142
  });
42143
 
42144
  nextStepButton.off().on('click', function () {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42145
  if (jQuery(this).hasClass('button-disabled')) {
42146
  return;
42147
  }
42148
  MailPoet.Modal.loading(true);
42149
-
42150
- var columns = {},
42151
- queue = new jQuery.AsyncQueue(),
42152
- batchNumber = 0,
42153
- batchSize = 2000,
42154
- timestamp = Date.now() / 1000,
42155
- subscribers = [],
42156
- importResults = {
42157
- created: 0,
42158
- updated: 0,
42159
- errors: [],
42160
- segments: []
42161
- },
42162
- splitSubscribers = function (subscribers, size) {
42163
- return subscribers.reduce(function (res, item, index) {
42164
- if (index % size === 0) {
42165
- res.push([]);
42166
- }
42167
- res[res.length - 1].push(item);
42168
- return res;
42169
- }, []);
42170
- },
42171
- subscribers = splitSubscribers(window.importData.step1.subscribers, batchSize);
42172
 
42173
  _.each(jQuery('select.mailpoet_subscribers_column_data_match'),
42174
  function (column, columnIndex) {
@@ -42239,6 +42275,9 @@ webpackJsonp([0],[
42239
  });
42240
 
42241
  router.on('route:step3', function () {
 
 
 
42242
  if (typeof (window.importData.step2) === 'undefined') {
42243
  router.navigate('step2', { trigger: true });
42244
  return;
@@ -42257,25 +42296,23 @@ webpackJsonp([0],[
42257
  });
42258
 
42259
  // display statistics
42260
- var subscribersDataImportResultsTemplate =
42261
- Handlebars
42262
- .compile(jQuery('#subscribers_data_import_results_template')
42263
- .html()),
42264
- exportMenuElement = jQuery('span.mailpoet_export'),
42265
- importResults = {
42266
- created: (window.importData.step2.created)
42267
- ? MailPoet.I18n.t('subscribersCreated')
42268
- .replace('%1$s', '<strong>' + window.importData.step2.created.toLocaleString() + '</strong>')
42269
- .replace('%2$s', '"' + window.importData.step2.segments.join('", "') + '"')
42270
- : false,
42271
- updated: (window.importData.step2.updated)
42272
- ? MailPoet.I18n.t('subscribersUpdated')
42273
- .replace('%1$s', '<strong>' + window.importData.step2.updated.toLocaleString() + '</strong>')
42274
- .replace('%2$s', '"' + window.importData.step2.segments.join('", "') + '"')
42275
- : false,
42276
- no_action: (!window.importData.step2.created && !window.importData.step2.updated),
42277
- added_to_segment_with_welcome_notification: window.importData.step2.added_to_segment_with_welcome_notification
42278
- };
42279
 
42280
  jQuery('#subscribers_data_import_results')
42281
  .html(subscribersDataImportResultsTemplate(importResults))
@@ -42412,97 +42449,103 @@ webpackJsonp([0],[
42412
  __webpack_require__(278),
42413
  __webpack_require__(273),
42414
  __webpack_require__(274),
42415
- __webpack_require__(543),
42416
- __webpack_require__(287)
42417
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (
42418
  _,
42419
  jQuery,
42420
  MailPoet,
42421
- Handlebars,
42422
- select2
42423
  ) {
42424
  if (!jQuery('#mailpoet_subscribers_export').length) {
42425
  return;
42426
  }
42427
  jQuery(document).ready(function () {
 
 
 
 
 
 
 
42428
  if (!window.exportData.segments) {
42429
  return;
42430
  }
42431
- var subscribers_export_template =
42432
  Handlebars.compile(jQuery('#mailpoet_subscribers_export_template').html());
42433
 
42434
  // render template
42435
  jQuery('#mailpoet_subscribers_export > div.inside').html(subscribers_export_template(window.exportData));
42436
 
42437
  // define reusable variables
42438
- var segmentsContainerElement = jQuery('#export_lists'),
42439
- subscriberFieldsContainerElement = jQuery('#export_columns'),
42440
- exportConfirmedOptionElement = jQuery(':radio[name="option_confirmed"]'),
42441
- groupBySegmentOptionElement = jQuery(':checkbox[name="option_group_by_list"]'),
42442
- nextStepButton = jQuery('a.mailpoet_export_process'),
42443
- renderSegmentsAndFields = function (container, data) {
42444
- if (container.data('select2')) {
42445
- container
42446
- .html('')
42447
- .select2('destroy');
42448
- }
42449
  container
42450
- .select2({
42451
- data: data,
42452
- width: '20em',
42453
- templateResult: function (item) {
42454
- return (item.subscriberCount > 0)
42455
- ? item.name + ' (' + parseInt(item.subscriberCount).toLocaleString() + ')'
42456
- : item.name;
42457
- },
42458
- templateSelection: function (item) {
42459
- return (item.subscriberCount > 0)
42460
- ? item.name + ' (' + parseInt(item.subscriberCount).toLocaleString() + ')'
42461
- : item.name;
42462
- }
42463
- })
42464
- .on('select2:selecting', function (selectEvent) {
42465
- var selectElement = this,
42466
- selectedOptionId = selectEvent.params.args.data.id,
42467
- fieldsToExclude = [
42468
- 'select',
42469
- 'deselect'
42470
- ];
42471
- if (_.contains(fieldsToExclude, selectedOptionId)) {
42472
- selectEvent.preventDefault();
42473
- if (selectedOptionId === 'deselect') {
42474
- jQuery(selectElement).val('').trigger('change');
42475
- } else {
42476
- var allOptions = [];
42477
- _.each(container.find('option'), function (field) {
42478
- if (!_.contains(fieldsToExclude, field.value)) {
42479
- allOptions.push(field.value);
42480
- }
42481
- });
42482
- jQuery(selectElement).val(allOptions).trigger('change');
42483
- }
42484
- jQuery(selectElement).select2('close');
42485
- }
42486
- })
42487
- .on('change', function () {
42488
- if ((window.exportData.segments && segmentsContainerElement.select2('data').length && subscriberFieldsContainerElement.select2('data').length)
42489
- ||
42490
- (!window.exportData.segments && subscriberFieldsContainerElement.select2('data').length)
42491
- ) {
42492
- toggleNextStepButton('on');
42493
- }
42494
- else {
42495
- toggleNextStepButton('off');
42496
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
42497
 
42498
- if (segmentsContainerElement.select2('data').length > 1 && window.exportData.groupBySegmentOption) {
42499
- jQuery('.mailpoet_group_by_list').show();
42500
- }
42501
- else if (window.exportData.groupBySegmentOption) {
42502
- jQuery('.mailpoet_group_by_list').hide();
42503
- }
42504
- });
42505
- };
42506
 
42507
  // set confirmed subscribers export option to false
42508
  window.exportData.exportConfirmedOption = false;
@@ -42541,11 +42584,12 @@ webpackJsonp([0],[
42541
  }
42542
 
42543
  nextStepButton.click(function () {
 
42544
  if (jQuery(this).hasClass('button-disabled')) {
42545
  return;
42546
  }
42547
  MailPoet.Modal.loading(true);
42548
- var exportFormat = jQuery(':radio[name="option_format"]:checked').val();
42549
  MailPoet.Ajax.post({
42550
  api_version: window.mailpoet_api_version,
42551
  endpoint: 'ImportExport',
@@ -42557,7 +42601,7 @@ webpackJsonp([0],[
42557
  segments: (window.exportData.segments) ? segmentsContainerElement.val() : false,
42558
  subscriber_fields: subscriberFieldsContainerElement.val()
42559
  })
42560
- }).always(function (response) {
42561
  MailPoet.Modal.loading(false);
42562
  }).done(function (response) {
42563
  var resultMessage = MailPoet.I18n.t('exportMessage')
36986
  var percentage_opened_display = _mailpoet2['default'].Num.toLocaleFixed(percentage_opened, 1);
36987
  var percentage_unsubscribed_display = _mailpoet2['default'].Num.toLocaleFixed(percentage_unsubscribed, 1);
36988
 
36989
+ var show_stats_timeout = undefined;
36990
+ var newsletter_date = undefined;
36991
+ var sent_hours_ago = undefined;
36992
+ var too_early_for_stats = undefined;
36993
+ var show_kb_link = undefined;
36994
  if (current_time !== undefined) {
36995
  // standard emails and post notifications:
36996
  // display green box for newsletters that were just sent
38846
  jQuery('#mailpoet_sending_method_setup').fadeIn();
38847
  }
38848
  },
38849
+ tabs: function (tabStr) {
38850
  // set default tab
38851
  var tab = tabStr || 'mta';
38852
 
38882
  });
38883
  }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
38884
 
38885
+
38886
  /***/ },
38887
  /* 535 */
38888
  /***/ function(module, exports, __webpack_require__) {
41132
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (
41133
  MailPoet
41134
  ) {
41135
+ var element;
41136
  function eventHandler() {
41137
  if (confirm(MailPoet.I18n.t('reinstallConfirmation'))) {
41138
  MailPoet.trackEvent(
41163
  return false;
41164
  }
41165
 
41166
+ element = document.getElementById('mailpoet_reinstall');
41167
  if (element) {
41168
  element.addEventListener('click', eventHandler, false);
41169
  }
41170
  }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
41171
 
41172
+
41173
  /***/ },
41174
  /* 542 */
41175
  /***/ function(module, exports, __webpack_require__) {
41182
  __webpack_require__(543),
41183
  __webpack_require__(544),
41184
  __webpack_require__(545),
41185
+ __webpack_require__(297)
 
41186
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (
41187
  Backbone,
41188
  _,
41191
  Handlebars,
41192
  Papa,
41193
  AsyncQueue,
41194
+ Moment
 
41195
  ) {
41196
  if (!jQuery('#mailpoet_subscribers_import').length) {
41197
  return;
41198
  }
41199
  jQuery(document).ready(function () {
41200
+ var router;
41201
  jQuery('input[name="select_method"]').attr('checked', false);
41202
  // configure router
41203
+ router = new (Backbone.Router.extend({
41204
  routes: {
41205
  '': 'home',
41206
  step1: 'step1',
41223
  * STEP 1 (upload or copy/paste)
41224
  */
41225
  router.on('route:step1', function () {
41226
+ var methodProcessContainerTemplate;
41227
+ var currentStepE;
41228
+ var methodSelectionElement;
41229
+ var pasteInputElement;
41230
+ var pasteInputPlaceholderElement;
41231
+ var pasteProcessButtonElement;
41232
+ var mailChimpKeyInputElement;
41233
+ var mailChimpKeyVerifyButtonElement;
41234
+ var mailChimpListsContainerElement;
41235
+ var mailChimpProcessButtonElement;
41236
+ var uploadElement;
41237
+ var uploadProcessButtonElement;
41238
  // set or reset temporary validation rule on all columns
41239
+ window.mailpoetColumns = jQuery.map(window.mailpoetColumns, function (column) {
41240
  var col = column;
41241
  col.validation_rule = false;
41242
  return col;
41248
  }
41249
 
41250
  // render process button for each method
41251
+ methodProcessContainerTemplate =
41252
  Handlebars.compile(jQuery('#method_process_template').html());
41253
  jQuery('.mailpoet_method_process').html(methodProcessContainerTemplate());
41254
 
41255
  // define reusable variables
41256
+ currentStepE = jQuery(location.hash);
41257
+ methodSelectionElement = jQuery('#select_method');
41258
+ pasteInputElement = jQuery('#paste_input');
41259
+ pasteInputPlaceholderElement =
41260
+ pasteInputElement.data('placeholder').replace(/\\n/g, '\n');
41261
+ pasteProcessButtonElement =
41262
+ jQuery('#method_paste > div.mailpoet_method_process')
41263
+ .find('a.mailpoet_process');
41264
+ mailChimpKeyInputElement = jQuery('#mailchimp_key');
41265
+ mailChimpKeyVerifyButtonElement = jQuery('#mailchimp_key_verify');
41266
+ mailChimpListsContainerElement = jQuery('#mailchimp_lists');
41267
+ mailChimpProcessButtonElement = jQuery('#method_mailchimp > div.mailpoet_method_process')
41268
+ .find('a.mailpoet_process');
41269
+ uploadElement = jQuery('#file_local');
41270
+ uploadProcessButtonElement =
41271
+ jQuery('#method_file > div.mailpoet_method_process')
41272
+ .find('a.mailpoet_process');
 
41273
 
41274
  // define method change behavior
41275
  methodSelectionElement.change(function () {
41276
+ var available_methods = jQuery(':radio[name="select_method"]');
41277
+ var selected_method = available_methods.index(available_methods.filter(':checked'));
41278
  MailPoet.Notice.hide();
 
 
 
41279
  // hide all methods
41280
  currentStepE.find('.inside')
41281
  .children('div[id^="method_"]')
41314
  });
41315
 
41316
  pasteProcessButtonElement.click(function () {
41317
+ var pasteSize = encodeURI(pasteInputElement.val()).split(/%..|./).length - 1;
41318
  MailPoet.Notice.hide();
41319
  // get an approximate size of textarea paste in bytes
 
41320
  if (pasteSize > window.maxPostSizeBytes) {
41321
  MailPoet.Notice.error(MailPoet.I18n.t('maxPostSizeNotice'));
41322
  return;
41332
  * CSV file
41333
  */
41334
  uploadElement.change(function () {
 
41335
  var ext = this.value.match(/\.(.+)$/);
41336
+ MailPoet.Notice.hide();
41337
  if (ext === null || ext[1].toLowerCase() !== 'csv') {
41338
  this.value = '';
41339
  MailPoet.Notice.error(MailPoet.I18n.t('wrongFileFormat'));
41417
  api_key: mailChimpKeyInputElement.val(),
41418
  lists: mailChimpListsContainerElement.find('select').val()
41419
  }
41420
+ }).always(function () {
41421
  MailPoet.Modal.loading(false);
41422
  }).done(function (response) {
41423
  window.importData.step1 = response.data;
41477
  }
41478
 
41479
  function parseCSV(isFile) {
41480
+ var processedSubscribers = [];
41481
+ var parsedEmails = [];
41482
+ var duplicateEmails = [];
41483
+ var invalidEmails = [];
41484
+ var emailColumnPosition = null;
41485
+ var columnCount = null;
41486
+ var isHeaderFound = false;
41487
+ var advancedOptionHeader = true;
41488
+ var advancedOptionDelimiter = '';
41489
+ var advancedOptionNewline = '';
41490
+ var advancedOptionComments = false;
41491
+ // trim spaces, commas, periods,
41492
+ // single/double quotes and convert to lowercase
41493
+ var detectAndCleanupEmail = function (emailString) {
41494
+ var test;
41495
+ // decode HTML entities
41496
+ var email = jQuery('<div />').html(emailString).text();
41497
+ email = email
41498
+ .toLowerCase()
41499
+ // left/right trim spaces, punctuation (e.g., " 'email@email.com'; ")
41500
+ // right trim non-printable characters (e.g., "email@email.com�")
41501
+ .replace(/^["';.,\s]+|[^\x20-\x7E]+$|["';.,_\s]+$/g, '')
41502
+ // remove spaces (e.g., "email @ email . com")
41503
+ // remove urlencoded characters
41504
+ .replace(/\s+|%\d+|,+/g, '');
41505
+ // detect e-mails that will be otherwise rejected by email regex
41506
+ test = /<(.*?)>/.exec(email);
41507
+ if (test) {
41508
+ // is the email inside angle brackets (e.g., 'some@email.com <some@email.com>')?
41509
+ email = test[1].trim();
41510
+ }
41511
+ test = /mailto:(?:\s+)?(.*)/.exec(email);
41512
+ if (test) {
41513
+ // is the email in 'mailto:email' format?
41514
+ email = test[1].trim();
41515
+ }
41516
+ // test for valid characters using WP's rule (https://core.trac.wordpress.org/browser/tags/4.7.3/src/wp-includes/formatting.php#L2902)
41517
+ if (!/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.\-@]+$/.test(email)) {
41518
+ return false;
41519
+ }
41520
+ return email;
41521
+ };
41522
 
41523
  return {
41524
  skipEmptyLines: true,
41530
  MailPoet.Notice.error(MailPoet.I18n.t('dataProcessingError'));
41531
  },
41532
  complete: function (CSV) {
41533
+ var email;
41534
+ var emailAddress;
41535
+ var column;
41536
+ var rowCount;
41537
+ var rowData;
41538
+ var rowColumnCount;
41539
+ var errorNotice;
41540
+ for (rowCount in CSV.data) {
41541
+ rowData = CSV.data[rowCount].map(function (el) {
41542
  return el.trim();
41543
  });
41544
+ rowColumnCount = rowData.length;
41545
  // set the number of row elements based on the first non-empty row
41546
  if (columnCount === null) {
41547
  columnCount = rowColumnCount;
41555
  // determine position of email address inside an array; this is
41556
  // done once and then email regex is run just on that element for each row
41557
  if (emailColumnPosition === null) {
41558
+ for (column in rowData) {
41559
+ emailAddress = detectAndCleanupEmail(rowData[column]);
41560
  if (emailColumnPosition === null
41561
+ && window.emailRegex.test(emailAddress)) {
41562
  emailColumnPosition = column;
41563
+ parsedEmails[emailAddress] = true; // add current e-mail to an object index
41564
+ rowData[column] = emailAddress;
41565
+ processedSubscribers[emailAddress] = rowData;
41566
  }
41567
  }
41568
  if (emailColumnPosition === null
41573
  }
41574
  }
41575
  else if (rowData[emailColumnPosition] !== '') {
41576
+ email = detectAndCleanupEmail(rowData[emailColumnPosition]);
41577
  if (_.has(parsedEmails, email)) {
41578
  duplicateEmails.push(email);
41579
  }
41617
  }
41618
  else {
41619
  MailPoet.Modal.loading(false);
41620
+ errorNotice = MailPoet.I18n.t('noValidRecords');
41621
  errorNotice = errorNotice.replace('[link]', MailPoet.I18n.t('csvKBLink'));
41622
  errorNotice = errorNotice.replace('[/link]', '</a>');
41623
  MailPoet.Notice.error(errorNotice);
41628
  });
41629
 
41630
  router.on('route:step2', function () {
41631
+ var nextStepButton;
41632
+ var previousStepButton;
41633
+ var subscribers;
41634
+ var subscribersDataTemplate;
41635
+ var subscribersDataTemplatePartial;
41636
+ var subscribersDataParseResultsTemplate;
41637
+ var segmentSelectElement;
41638
+ var maxRowsToShow;
41639
+ var filler;
41640
+ var fillerArray;
41641
+ var fillerPosition;
41642
+ var import_results;
41643
+ var duplicates;
41644
+ var email;
41645
  if (typeof (window.importData.step1) === 'undefined') {
41646
  router.navigate('step1', { trigger: true });
41647
  return;
41648
  }
41649
  // define reusable variables
41650
+ nextStepButton = jQuery('#step2_process');
41651
+ previousStepButton = jQuery('#return_to_step1');
41652
  // create a copy of subscribers object for further manipulation
41653
+ subscribers = jQuery.extend(true, {}, window.importData.step1);
41654
+ subscribersDataTemplate = Handlebars.compile(jQuery('#subscribers_data_template').html());
41655
+ subscribersDataTemplatePartial = Handlebars.compile(jQuery('#subscribers_data_template_partial').html());
41656
+ subscribersDataParseResultsTemplate = Handlebars.compile(jQuery('#subscribers_data_parse_results_template').html());
41657
+ segmentSelectElement = jQuery('#mailpoet_segments_select');
41658
+ maxRowsToShow = 10;
41659
+ filler = '. . .';
 
 
 
 
 
 
 
 
 
41660
  // create an array of filler data with the same number of
41661
  // elements as in the subscribers' data row
41662
+ fillerArray = Array.apply(
41663
+ null,
41664
+ new Array(subscribers.subscribers[0].length)
41665
+ ).map(String.prototype.valueOf, filler);
 
41666
 
41667
  showCurrentStep();
41668
 
41674
  if (subscribers.invalid.length || subscribers.duplicate.length) {
41675
  // count repeating e-mails inside duplicate array and present them in
41676
  // 'email (xN)' format
41677
+ duplicates = {};
41678
  subscribers.duplicate.forEach(function (email) {
41679
  duplicates[email] = (duplicates[email] || 0) + 1;
41680
  });
41681
  subscribers.duplicate = [];
41682
+ for (email in duplicates) {
41683
  if (duplicates[email] > 1) {
41684
  subscribers.duplicate.push(email + ' (x' + duplicates[email] + ')');
41685
  }
41688
  }
41689
  }
41690
 
41691
+ import_results = {
41692
  notice: MailPoet.I18n.t('importNoticeSkipped').replace(
41693
  '%1$s',
41694
  '<strong>' + (subscribers.invalid.length + subscribers.duplicate.length) + '</strong>'
41793
  description: segmentDescription
41794
  }
41795
  }).done(function (response) {
41796
+ var selected_values;
41797
  window.mailpoetSegments.push({
41798
  id: response.data.id,
41799
  name: response.data.name,
41800
  subscriberCount: 0
41801
  });
41802
 
41803
+ selected_values = segmentSelectElement.val();
41804
  if (selected_values === null) {
41805
  selected_values = [response.data.id];
41806
  } else {
41837
  Handlebars.registerHelper(
41838
  'show_and_match_columns',
41839
  function (subscribers, options) {
41840
+ var displayedColumns = [];
41841
+ var displayedColumnsIds = [];
41842
+ var i;
41843
+ var columnData;
41844
+ var columnId;
41845
+ var headerName;
41846
+ var headerNameMatch;
41847
  // go through all elements of the first row in subscribers data
41848
+ for (i in subscribers.subscribers[0]) {
41849
+ columnData = subscribers.subscribers[0][i];
41850
+ columnId = 'ignore'; // set default column type
41851
  // if the column is not undefined and has a valid e-mail, set type as email
41852
  if (columnData % 1 !== 0 && window.emailRegex.test(columnData)) {
41853
  columnId = 'email';
41854
  } else if (subscribers.header) {
41855
+ headerName = subscribers.header[i];
41856
+ headerNameMatch = window.mailpoetColumns.map(function (el) {
41857
+ return el.name;
41858
+ }).indexOf(headerName);
41859
  // set column type using header
41860
  if (headerNameMatch !== -1) {
41861
  columnId = window.mailpoetColumns[headerNameMatch].id;
41933
  }
41934
  })
41935
  .on('select2:selecting', function (selectEvent) {
41936
+ var selectElement = this;
41937
+ var selectedOptionId = selectEvent.params.args.data.id;
41938
  // CREATE CUSTOM FIELD
41939
  if (selectedOptionId === 'create') {
41940
  selectEvent.preventDefault();
41943
  title: MailPoet.I18n.t('addNewField'),
41944
  template: jQuery('#form_template_field_form').html()
41945
  });
41946
+ jQuery('#form_field_new').parsley().on('form:submit', function () {
41947
  // get data
41948
  var data = jQuery(this.$element).serializeObject();
41949
 
42007
  // check for duplicate values in all select options
42008
  jQuery('select.mailpoet_subscribers_column_data_match')
42009
  .each(function () {
42010
+ var element = this;
42011
+ var elementId = jQuery(element).val();
42012
  // if another column has the same value and it's not an 'ignore', prompt user
42013
  if (elementId === selectedOptionId
42014
  && elementId !== 'ignore') {
42024
  }
42025
  })
42026
  .on('select2:select', function (selectEvent) {
42027
+ var selectElement = this;
42028
+ var selectedOptionId = selectEvent.params.data.id;
42029
  jQuery(selectElement).data('column-id', selectedOptionId);
42030
  filterSubscribers();
42031
  });
42032
 
42033
  // filter subscribers' data to detect dates, emails, etc.
42034
  function filterSubscribers() {
42035
+ var subscribersClone = jQuery.extend(true, {}, subscribers);
42036
+ var preventNextStep = false;
42037
+ var displayedColumns;
42038
  jQuery(
42039
  '[data-id="notice_invalidEmail"], [data-id="notice_invalidDate"]')
42040
  .remove();
42041
+ displayedColumns = jQuery.map(
42042
+ jQuery('.mailpoet_subscribers_column_data_match'), function (element, elementIndex) {
42043
+ var columnId = jQuery(element).data('column-id');
42044
+ var validationRule = jQuery(element).data('validation-rule');
42045
+ jQuery(element).val(columnId).trigger('change');
42046
+ return { id: columnId, index: elementIndex, validationRule: validationRule, element: element };
42047
+ });
 
 
42048
  // iterate through the object of mailpoet columns
42049
+ jQuery.map(window.mailpoetColumns, function (column) {
42050
+ var firstRowData;
42051
+ var validationRule;
42052
+ var testedFormat;
42053
+ var format;
42054
+ var allowedDateFormats;
42055
  // check if the column id matches the selected id of one of the
42056
  // subscriber's data columns
42057
  var matchedColumn = _.find(displayedColumns, function (data) { return data.id === column.id; });
42075
  }
42076
  // DATE filter: if column type is date, check if we can recognize it
42077
  if (column.type === 'date' && matchedColumn) {
42078
+ allowedDateFormats = [
42079
  Moment.ISO_8601,
42080
  'YYYY/MM/DD',
42081
  'MM/DD/YYYY',
42086
  'YYYY/MM',
42087
  'YYYY'
42088
  ];
42089
+ firstRowData = subscribersClone.subscribers[0][matchedColumn.index];
42090
+ validationRule = false;
42091
  // check if date exists
42092
  if (firstRowData.trim() === '') {
42093
  subscribersClone.subscribers[0][matchedColumn.index] =
42098
  preventNextStep = true;
42099
  }
42100
  else {
42101
+ for (format in allowedDateFormats) {
42102
+ testedFormat = allowedDateFormats[format];
42103
  if (Moment(firstRowData, testedFormat, true).isValid()) {
42104
+ validationRule = (typeof (testedFormat) === 'function') ?
42105
  'datetime' :
42106
  testedFormat;
42107
  // set validation on the column element
42116
  jQuery.map(subscribersClone.subscribers, function (dataSubscribers, index) {
42117
  var data = dataSubscribers;
42118
  var rowData = data[matchedColumn.index];
 
42119
  var date = Moment(rowData, testedFormat, true);
42120
+ if (index === fillerPosition || rowData.trim() === '') return;
42121
  // validate date
42122
  if (date.isValid()) {
42123
  data[matchedColumn.index] = new Handlebars.SafeString(
42176
  });
42177
 
42178
  nextStepButton.off().on('click', function () {
42179
+ var columns = {};
42180
+ var queue = new jQuery.AsyncQueue();
42181
+ var batchNumber = 0;
42182
+ var batchSize = 2000;
42183
+ var timestamp = Date.now() / 1000;
42184
+ var subscribers = [];
42185
+ var importResults = {
42186
+ created: 0,
42187
+ updated: 0,
42188
+ errors: [],
42189
+ segments: []
42190
+ };
42191
+ var subscribers;
42192
+ var splitSubscribers;
42193
+
42194
  if (jQuery(this).hasClass('button-disabled')) {
42195
  return;
42196
  }
42197
  MailPoet.Modal.loading(true);
42198
+ splitSubscribers = function (subscribers, size) {
42199
+ return subscribers.reduce(function (res, item, index) {
42200
+ if (index % size === 0) {
42201
+ res.push([]);
42202
+ }
42203
+ res[res.length - 1].push(item);
42204
+ return res;
42205
+ }, []);
42206
+ };
42207
+ subscribers = splitSubscribers(window.importData.step1.subscribers, batchSize);
 
 
 
 
 
 
 
 
 
 
 
 
 
42208
 
42209
  _.each(jQuery('select.mailpoet_subscribers_column_data_match'),
42210
  function (column, columnIndex) {
42275
  });
42276
 
42277
  router.on('route:step3', function () {
42278
+ var subscribersDataImportResultsTemplate;
42279
+ var exportMenuElement;
42280
+ var importResults;
42281
  if (typeof (window.importData.step2) === 'undefined') {
42282
  router.navigate('step2', { trigger: true });
42283
  return;
42296
  });
42297
 
42298
  // display statistics
42299
+ subscribersDataImportResultsTemplate =
42300
+ Handlebars.compile(jQuery('#subscribers_data_import_results_template').html());
42301
+ exportMenuElement = jQuery('span.mailpoet_export');
42302
+ importResults = {
42303
+ created: (window.importData.step2.created)
42304
+ ? MailPoet.I18n.t('subscribersCreated')
42305
+ .replace('%1$s', '<strong>' + window.importData.step2.created.toLocaleString() + '</strong>')
42306
+ .replace('%2$s', '"' + window.importData.step2.segments.join('", "') + '"')
42307
+ : false,
42308
+ updated: (window.importData.step2.updated)
42309
+ ? MailPoet.I18n.t('subscribersUpdated')
42310
+ .replace('%1$s', '<strong>' + window.importData.step2.updated.toLocaleString() + '</strong>')
42311
+ .replace('%2$s', '"' + window.importData.step2.segments.join('", "') + '"')
42312
+ : false,
42313
+ no_action: (!window.importData.step2.created && !window.importData.step2.updated),
42314
+ added_to_segment_with_welcome_notification: window.importData.step2.added_to_segment_with_welcome_notification
42315
+ };
 
 
42316
 
42317
  jQuery('#subscribers_data_import_results')
42318
  .html(subscribersDataImportResultsTemplate(importResults))
42449
  __webpack_require__(278),
42450
  __webpack_require__(273),
42451
  __webpack_require__(274),
42452
+ __webpack_require__(543)
 
42453
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (
42454
  _,
42455
  jQuery,
42456
  MailPoet,
42457
+ Handlebars
 
42458
  ) {
42459
  if (!jQuery('#mailpoet_subscribers_export').length) {
42460
  return;
42461
  }
42462
  jQuery(document).ready(function () {
42463
+ var segmentsContainerElement;
42464
+ var subscriberFieldsContainerElement;
42465
+ var exportConfirmedOptionElement;
42466
+ var groupBySegmentOptionElement;
42467
+ var nextStepButton;
42468
+ var renderSegmentsAndFields;
42469
+ var subscribers_export_template;
42470
  if (!window.exportData.segments) {
42471
  return;
42472
  }
42473
+ subscribers_export_template =
42474
  Handlebars.compile(jQuery('#mailpoet_subscribers_export_template').html());
42475
 
42476
  // render template
42477
  jQuery('#mailpoet_subscribers_export > div.inside').html(subscribers_export_template(window.exportData));
42478
 
42479
  // define reusable variables
42480
+ segmentsContainerElement = jQuery('#export_lists');
42481
+ subscriberFieldsContainerElement = jQuery('#export_columns');
42482
+ exportConfirmedOptionElement = jQuery(':radio[name="option_confirmed"]');
42483
+ groupBySegmentOptionElement = jQuery(':checkbox[name="option_group_by_list"]');
42484
+ nextStepButton = jQuery('a.mailpoet_export_process');
42485
+ renderSegmentsAndFields = function (container, data) {
42486
+ if (container.data('select2')) {
 
 
 
 
42487
  container
42488
+ .html('')
42489
+ .select2('destroy');
42490
+ }
42491
+ container
42492
+ .select2({
42493
+ data: data,
42494
+ width: '20em',
42495
+ templateResult: function (item) {
42496
+ return (item.subscriberCount > 0)
42497
+ ? item.name + ' (' + parseInt(item.subscriberCount).toLocaleString() + ')'
42498
+ : item.name;
42499
+ },
42500
+ templateSelection: function (item) {
42501
+ return (item.subscriberCount > 0)
42502
+ ? item.name + ' (' + parseInt(item.subscriberCount).toLocaleString() + ')'
42503
+ : item.name;
42504
+ }
42505
+ })
42506
+ .on('select2:selecting', function (selectEvent) {
42507
+ var selectElement = this;
42508
+ var selectedOptionId = selectEvent.params.args.data.id;
42509
+ var fieldsToExclude = [
42510
+ 'select',
42511
+ 'deselect'
42512
+ ];
42513
+ var allOptions;
42514
+ if (_.contains(fieldsToExclude, selectedOptionId)) {
42515
+ selectEvent.preventDefault();
42516
+ if (selectedOptionId === 'deselect') {
42517
+ jQuery(selectElement).val('').trigger('change');
42518
+ } else {
42519
+ allOptions = [];
42520
+ _.each(container.find('option'), function (field) {
42521
+ if (!_.contains(fieldsToExclude, field.value)) {
42522
+ allOptions.push(field.value);
42523
+ }
42524
+ });
42525
+ jQuery(selectElement).val(allOptions).trigger('change');
 
 
 
 
 
 
 
 
42526
  }
42527
+ jQuery(selectElement).select2('close');
42528
+ }
42529
+ })
42530
+ .on('change', function () {
42531
+ if ((window.exportData.segments && segmentsContainerElement.select2('data').length && subscriberFieldsContainerElement.select2('data').length)
42532
+ ||
42533
+ (!window.exportData.segments && subscriberFieldsContainerElement.select2('data').length)
42534
+ ) {
42535
+ toggleNextStepButton('on');
42536
+ }
42537
+ else {
42538
+ toggleNextStepButton('off');
42539
+ }
42540
 
42541
+ if (segmentsContainerElement.select2('data').length > 1 && window.exportData.groupBySegmentOption) {
42542
+ jQuery('.mailpoet_group_by_list').show();
42543
+ }
42544
+ else if (window.exportData.groupBySegmentOption) {
42545
+ jQuery('.mailpoet_group_by_list').hide();
42546
+ }
42547
+ });
42548
+ };
42549
 
42550
  // set confirmed subscribers export option to false
42551
  window.exportData.exportConfirmedOption = false;
42584
  }
42585
 
42586
  nextStepButton.click(function () {
42587
+ var exportFormat;
42588
  if (jQuery(this).hasClass('button-disabled')) {
42589
  return;
42590
  }
42591
  MailPoet.Modal.loading(true);
42592
+ exportFormat = jQuery(':radio[name="option_format"]:checked').val();
42593
  MailPoet.Ajax.post({
42594
  api_version: window.mailpoet_api_version,
42595
  endpoint: 'ImportExport',
42601
  segments: (window.exportData.segments) ? segmentsContainerElement.val() : false,
42602
  subscriber_fields: subscriberFieldsContainerElement.val()
42603
  })
42604
+ }).always(function () {
42605
  MailPoet.Modal.loading(false);
42606
  }).done(function (response) {
42607
  var resultMessage = MailPoet.I18n.t('exportMessage')
assets/js/{admin_vendor.6c010053.js → admin_vendor.dda60c3b.js} RENAMED
@@ -28919,8 +28919,8 @@ webpackJsonp([1],[
28919
  });
28920
  },
28921
  handleSelectItem: function handleSelectItem(id, is_checked) {
28922
- var selected_ids = this.state.selected_ids,
28923
- selection = false;
28924
 
28925
  if (is_checked) {
28926
  selected_ids = _jquery2['default'].merge(selected_ids, [id]);
28919
  });
28920
  },
28921
  handleSelectItem: function handleSelectItem(id, is_checked) {
28922
+ var selected_ids = this.state.selected_ids;
28923
+ var selection = false;
28924
 
28925
  if (is_checked) {
28926
  selected_ids = _jquery2['default'].merge(selected_ids, [id]);
assets/js/{form_editor.c4bc7e0b.js → form_editor.d94aebf3.js} RENAMED
@@ -30,6 +30,10 @@ webpackJsonp([2],{
30
 
31
  'use strict';
32
 
 
 
 
 
33
  Event.cacheDelegated = {};
34
  Object.extend(document, (function () {
35
  var cache = Event.cacheDelegated;
@@ -53,18 +57,21 @@ webpackJsonp([2],{
53
  }
54
 
55
  function destroyWrapper(selector, eventName, handler) {
 
56
  var c = getCacheForSelector(selector);
57
  if (!c[eventName]) return false;
58
- var wrapper = findWrapper(selector, eventName, handler);
59
  c[eventName] = c[eventName].without(wrapper);
60
  return wrapper;
61
  }
62
 
63
  function createWrapper(selector, eventName, handler, context) {
64
- var wrapper, c = getWrappersForSelector(selector, eventName);
 
 
65
  if (c.pluck('handler').include(handler)) return false;
66
  wrapper = function (event) {
67
- var element = event.findElement(selector);
68
  if (element) handler.call(context || element, event, element);
69
  };
70
  wrapper.handler = handler;
@@ -72,13 +79,14 @@ webpackJsonp([2],{
72
  return wrapper;
73
  }
74
  return {
75
- delegate: function (selector, eventName, handler, context) {
76
  var wrapper = createWrapper.apply(null, arguments);
77
  if (wrapper) document.observe(eventName, wrapper);
78
  return document;
79
  },
80
- stopDelegating: function (selector, eventName, handler) {
81
  var length = arguments.length;
 
82
  switch (length) {
83
  case 2:
84
  getWrappersForSelector(selector, eventName).each(function (wrapper) {
@@ -96,7 +104,7 @@ webpackJsonp([2],{
96
  });
97
  break;
98
  default:
99
- var wrapper = destroyWrapper.apply(null, arguments);
100
  if (wrapper) document.stopObserving(eventName, wrapper);
101
  }
102
  return document;
@@ -104,7 +112,7 @@ webpackJsonp([2],{
104
  };
105
  })());
106
 
107
- var Observable = (function () {
108
  function getEventName(nameA, namespace) {
109
  var name = nameA.substring(2);
110
  if (namespace) name = namespace + ':' + name;
@@ -112,8 +120,8 @@ webpackJsonp([2],{
112
  }
113
 
114
  function getHandlers(klass) {
115
- var proto = klass.prototype,
116
- namespace = proto.namespace;
117
  return Object.keys(proto).grep(/^on/).inject(window.$H(), function (handlers, name) {
118
  if (name === 'onDomLoaded') return handlers;
119
  handlers.set(getEventName(name, namespace), getWrapper(proto[name], klass));
@@ -134,9 +142,9 @@ webpackJsonp([2],{
134
  }
135
  return {
136
  observe: function (selector) {
 
137
  if (!this.handlers) this.handlers = {};
138
  if (this.handlers[selector]) return;
139
- var klass = this;
140
  if (this.prototype.onDomLoaded) {
141
  if (document.loaded) {
142
  onDomLoad(selector, klass);
@@ -169,8 +177,9 @@ webpackJsonp([2],{
169
  return proceed(drop);
170
  }),
171
  show: function (point, element) {
 
 
172
  if (!this.drops.length) return;
173
- var drop, affected = [];
174
  this.drops.each(function (drop) {
175
  if (window.Droppables.isAffected(point, element, drop)) affected.push(drop);
176
  });
@@ -182,13 +191,13 @@ webpackJsonp([2],{
182
  if (drop !== this.last_active) window.Droppables.activate(drop, element);
183
  }
184
  },
185
- displayArea: function (draggable) {
186
  if (!this.drops.length) return;
187
 
188
  // hide controls when displaying drop areas.
189
  WysijaForm.hideBlockControls();
190
 
191
- this.drops.each(function (drop, iterator) {
192
  if (drop.element.hasClassName('block_placeholder')) {
193
  drop.element.addClassName('active');
194
  }
@@ -196,7 +205,7 @@ webpackJsonp([2],{
196
  },
197
  hideArea: function () {
198
  if (!this.drops.length) return;
199
- this.drops.each(function (drop, iterator) {
200
  if (drop.element.hasClassName('block_placeholder')) {
201
  drop.element.removeClassName('active');
202
  } else if (drop.element.hasClassName('image_placeholder')) {
@@ -218,7 +227,7 @@ webpackJsonp([2],{
218
  - set a maximum number of items to be stored
219
 
220
  */
221
- var WysijaHistory = {
222
  container: 'mailpoet_form_history',
223
  size: 30,
224
  enqueue: function (element) {
@@ -262,7 +271,7 @@ webpackJsonp([2],{
262
  };
263
 
264
  /* MailPoet Form */
265
- var WysijaForm = {
266
  version: '0.7',
267
  options: {
268
  container: 'mailpoet_form_container',
@@ -315,6 +324,7 @@ webpackJsonp([2],{
315
  });
316
  },
317
  load: function (data) {
 
318
  if (data === undefined) return;
319
 
320
  // load body
@@ -325,7 +335,7 @@ webpackJsonp([2],{
325
  });
326
 
327
  // load settings
328
- var settings_elements = window.$('mailpoet_form_settings').getElements();
329
  settings_elements.each(function (setting) {
330
  // skip lists
331
  if (setting.name === 'segments') {
@@ -347,13 +357,13 @@ webpackJsonp([2],{
347
  }
348
  },
349
  save: function () {
350
- var position = 1,
351
- data = {
352
- name: window.$F('mailpoet_form_name'),
353
- settings: window.$('mailpoet_form_settings').serialize(true),
354
- body: [],
355
- styles: (window.MailPoet.CodeEditor !== undefined) ? window.MailPoet.CodeEditor.getValue() : null
356
- };
357
  // body
358
  WysijaForm.getBlocks().each(function (b) {
359
  var block_data = (typeof (b.block['save']) === 'function') ? b.block.save() : null;
@@ -424,6 +434,7 @@ webpackJsonp([2],{
424
  return data;
425
  },
426
  toggleWidgets: function () {
 
427
  window.$$('a[wysija_unique="1"]').invoke('removeClassName', 'disabled');
428
 
429
  // loop through each unique field already inserted in the editor and disable its toolbar equivalent
@@ -434,7 +445,7 @@ webpackJsonp([2],{
434
  }
435
  });
436
 
437
- var hasSegmentSelection = WysijaForm.hasSegmentSelection();
438
 
439
  if (hasSegmentSelection) {
440
  window.$('mailpoet_form_segments').writeAttribute('required', false).disable();
@@ -449,8 +460,9 @@ webpackJsonp([2],{
449
  },
450
  isSegmentSelectionValid: function () {
451
  var segment_selection = window.$$('#' + WysijaForm.options.editor + ' [wysija_id="segments"]')[0];
 
452
  if (segment_selection !== undefined) {
453
- var block = WysijaForm.get(segment_selection).block.getData();
454
  return (
455
  (block.params.values !== undefined)
456
  &&
@@ -460,10 +472,12 @@ webpackJsonp([2],{
460
  return false;
461
  },
462
  setBlockPositions: function (event, target) {
 
 
 
463
  // release dragging lock
464
  WysijaForm.locks.dragging = false;
465
 
466
- var index = 1;
467
  WysijaForm.getBlocks().each(function (container) {
468
  container.setPosition(index++);
469
  // remove z-index value to avoid issues when resizing images
@@ -476,8 +490,8 @@ webpackJsonp([2],{
476
 
477
  if (target !== undefined) {
478
  // get placeholders (previous placeholder matches the placeholder linked to the next block)
479
- var block_placeholder = window.$(target.element.readAttribute('wysija_placeholder')),
480
- previous_placeholder = target.element.previous('.block_placeholder');
481
 
482
  if (block_placeholder !== null) {
483
  // put block placeholder before the current block
@@ -502,23 +516,17 @@ webpackJsonp([2],{
502
  },
503
  setSettingsPosition: function () {
504
  // get viewport offsets and dimensions
505
- var viewportHeight = document.viewport.getHeight(),
506
- blockPadding = 5;
507
 
508
  window.$(WysijaForm.options.container).select('.wysija_settings').each(function (element) {
509
  // get parent dimensions and position
510
- var parentDim = element.up('.mailpoet_form_block').getDimensions(),
511
- parentPos = element.up('.mailpoet_form_block').cumulativeOffset(),
512
- is_visible = (parentPos.top <= (WysijaForm.scroll.top + viewportHeight)),
513
- buttonMargin = 5,
514
- relativeTop = buttonMargin;
515
 
516
  if (is_visible) {
517
- // desired position is set to center of viewport
518
- var absoluteTop = parseInt(WysijaForm.scroll.top + ((viewportHeight / 2) - (element.getHeight() / 2)), 10),
519
- parentTop = parseInt(parentPos.top - blockPadding, 10),
520
- parentBottom = parseInt(parentPos.top + parentDim.height - blockPadding, 10);
521
-
522
  // always center
523
  relativeTop = parseInt((parentDim.height / 2) - (element.getHeight() / 2), 10);
524
  }
@@ -542,9 +550,10 @@ webpackJsonp([2],{
542
 
543
  },
544
  setToolbarPosition: function () {
 
545
  WysijaForm.initToolbarPosition();
546
 
547
- var position = {
548
  top: WysijaForm.toolbar.y + 'px',
549
  visibility: 'visible'
550
  };
@@ -608,10 +617,12 @@ webpackJsonp([2],{
608
  instances: {},
609
  get: function (element, typ) {
610
  var type = typ;
 
 
611
  if (type === undefined) type = 'block';
612
  // identify element
613
- var id = element.identify();
614
- var instance = WysijaForm.instances[id] || new WysijaForm[type.capitalize().camelize()](id);
615
 
616
  WysijaForm.instances[id] = instance;
617
  return instance;
@@ -659,8 +670,8 @@ webpackJsonp([2],{
659
  },
660
  encodeURIComponent: function (str) {
661
  // check if it's a url and if so, prevent encoding of protocol
662
- var regexp = new RegExp(/^http[s]?:\/\//),
663
- protocol = regexp.exec(str);
664
 
665
  if (protocol === null) {
666
  // this is not a url so encode the whole thing
@@ -703,13 +714,13 @@ webpackJsonp([2],{
703
  },
704
  STYLES: new window.Template('position: absolute; top: #{top}px; left: #{left}px;'),
705
  cloneElement: function () {
706
- var clone = this.element.clone(),
707
- offset = this.element.cumulativeOffset(),
708
- list = this.getList(),
709
- styles = this.STYLES.evaluate({
710
- top: offset.top - list.scrollTop,
711
- left: offset.left - list.scrollLeft
712
- });
713
  clone.setStyle(styles);
714
 
715
  clone.addClassName('mailpoet_form_widget');
@@ -790,15 +801,17 @@ webpackJsonp([2],{
790
  }
791
  },
792
  makeBlockDroppable: function () {
 
793
  if (this.isBlockDroppableEnabled() === false) {
794
- var block_placeholder = this.getBlockDroppable();
795
  window.Droppables.add(block_placeholder.identify(), WysijaForm.blockDropOptions);
796
  block_placeholder.addClassName('enabled');
797
  }
798
  },
799
  removeBlockDroppable: function () {
 
800
  if (this.isBlockDroppableEnabled()) {
801
- var block_placeholder = this.getBlockDroppable();
802
  window.Droppables.remove(block_placeholder.identify());
803
  block_placeholder.removeClassName('enabled');
804
  }
@@ -830,6 +843,7 @@ webpackJsonp([2],{
830
  return this.element.down('.wysija_controls');
831
  },
832
  setupControls: function () {
 
833
  // enable controls
834
  this.controls = this.getControls();
835
 
@@ -880,9 +894,8 @@ webpackJsonp([2],{
880
  if (this.settingsButton !== null) {
881
  this.settingsButton.observe('click', function (event) {
882
  // TODO: refactor
883
- var block = window.$(event.target).up('.mailpoet_form_block') || null;
884
  if (block !== null) {
885
- var field = WysijaForm.getFieldData(block);
886
  this.editSettings();
887
  }
888
  }.bind(this));
@@ -928,18 +941,23 @@ webpackJsonp([2],{
928
  /* Invoked on item dropped */
929
  WysijaForm.Block.create = function (createBlock, target) {
930
  var block = createBlock;
 
 
 
 
 
931
  if (window.$('form_template_' + block.type) === null) {
932
  return false;
933
  }
934
 
935
- var body = window.$(WysijaForm.options.body),
936
- block_template = window.Handlebars.compile(window.$('form_template_block').innerHTML),
937
- template = window.Handlebars.compile(window.$('form_template_' + block.type).innerHTML),
938
- output = '';
939
 
940
  if (block.type === 'segment') {
941
  if (block.params.values === undefined) {
942
- var settings_segments = window.jQuery('#mailpoet_form_segments').val();
943
  if (settings_segments !== null && settings_segments.length > 0) {
944
  block.params.values = window.mailpoet_segments.filter(function (segment) {
945
  return (settings_segments.indexOf(segment.id) !== -1);
@@ -959,14 +977,13 @@ webpackJsonp([2],{
959
  }
960
 
961
  // if the drop target was the bottom placeholder
962
- var element = null;
963
  if (target.identify() === 'block_placeholder') {
964
  // insert block at the bottom
965
- element = body.insert(output);
966
  // block = body.childElements().last();
967
  } else {
968
  // insert block before the drop target
969
- element = target.insert({
970
  before: output
971
  });
972
  // block = target.previous('.mailpoet_form_block');
@@ -1007,8 +1024,8 @@ webpackJsonp([2],{
1007
  this.setupControls();
1008
  },
1009
  save: function () {
1010
- info('widget -> save');
1011
  var data = this.getData();
 
1012
 
1013
  if (data.element !== undefined) {
1014
  delete data.element;
@@ -1017,8 +1034,8 @@ webpackJsonp([2],{
1017
  return data;
1018
  },
1019
  setData: function (data) {
1020
- var current_data = this.getData(),
1021
- params = window.$H(current_data.params).merge(data.params).toObject();
1022
 
1023
  // update type if it changed
1024
  if (data.type !== undefined && data.type !== current_data.type) {
@@ -1043,16 +1060,20 @@ webpackJsonp([2],{
1043
  this.removeBlock();
1044
  },
1045
  redraw: function (data) {
 
 
 
 
1046
  // set parameters
1047
  this.setData(data);
1048
- var options = this.getData();
1049
  // redraw block
1050
- var block_template = window.Handlebars.compile(window.$('form_template_block').innerHTML),
1051
- template = window.Handlebars.compile(window.$('form_template_' + options.type).innerHTML),
1052
- data = window.$H(options).merge({
1053
- template: template(options)
1054
- }).toObject();
1055
- this.element.replace(block_template(data));
1056
 
1057
  WysijaForm.init();
1058
  },
@@ -1084,8 +1105,8 @@ webpackJsonp([2],{
1084
  var noop = function () {};
1085
  var methods = ['assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'markTimeline', 'profile', 'profileEnd', 'markTimeline', 'table', 'time', 'timeEnd', 'timeStamp', 'trace', 'warn'];
1086
  var length = methods.length;
1087
- window.console = {};
1088
  var console = {};
 
1089
  while (length--) {
1090
  console[methods[length]] = noop;
1091
  }
30
 
31
  'use strict';
32
 
33
+ var Observable;
34
+ var WysijaHistory;
35
+ var WysijaForm;
36
+
37
  Event.cacheDelegated = {};
38
  Object.extend(document, (function () {
39
  var cache = Event.cacheDelegated;
57
  }
58
 
59
  function destroyWrapper(selector, eventName, handler) {
60
+ var wrapper;
61
  var c = getCacheForSelector(selector);
62
  if (!c[eventName]) return false;
63
+ wrapper = findWrapper(selector, eventName, handler);
64
  c[eventName] = c[eventName].without(wrapper);
65
  return wrapper;
66
  }
67
 
68
  function createWrapper(selector, eventName, handler, context) {
69
+ var wrapper;
70
+ var element;
71
+ var c = getWrappersForSelector(selector, eventName);
72
  if (c.pluck('handler').include(handler)) return false;
73
  wrapper = function (event) {
74
+ element = event.findElement(selector);
75
  if (element) handler.call(context || element, event, element);
76
  };
77
  wrapper.handler = handler;
79
  return wrapper;
80
  }
81
  return {
82
+ delegate: function (selector, eventName) {
83
  var wrapper = createWrapper.apply(null, arguments);
84
  if (wrapper) document.observe(eventName, wrapper);
85
  return document;
86
  },
87
+ stopDelegating: function (selector, eventName) {
88
  var length = arguments.length;
89
+ var wrapper;
90
  switch (length) {
91
  case 2:
92
  getWrappersForSelector(selector, eventName).each(function (wrapper) {
104
  });
105
  break;
106
  default:
107
+ wrapper = destroyWrapper.apply(null, arguments);
108
  if (wrapper) document.stopObserving(eventName, wrapper);
109
  }
110
  return document;
112
  };
113
  })());
114
 
115
+ Observable = (function () {
116
  function getEventName(nameA, namespace) {
117
  var name = nameA.substring(2);
118
  if (namespace) name = namespace + ':' + name;
120
  }
121
 
122
  function getHandlers(klass) {
123
+ var proto = klass.prototype;
124
+ var namespace = proto.namespace;
125
  return Object.keys(proto).grep(/^on/).inject(window.$H(), function (handlers, name) {
126
  if (name === 'onDomLoaded') return handlers;
127
  handlers.set(getEventName(name, namespace), getWrapper(proto[name], klass));
142
  }
143
  return {
144
  observe: function (selector) {
145
+ var klass = this;
146
  if (!this.handlers) this.handlers = {};
147
  if (this.handlers[selector]) return;
 
148
  if (this.prototype.onDomLoaded) {
149
  if (document.loaded) {
150
  onDomLoad(selector, klass);
177
  return proceed(drop);
178
  }),
179
  show: function (point, element) {
180
+ var drop;
181
+ var affected = [];
182
  if (!this.drops.length) return;
 
183
  this.drops.each(function (drop) {
184
  if (window.Droppables.isAffected(point, element, drop)) affected.push(drop);
185
  });
191
  if (drop !== this.last_active) window.Droppables.activate(drop, element);
192
  }
193
  },
194
+ displayArea: function () {
195
  if (!this.drops.length) return;
196
 
197
  // hide controls when displaying drop areas.
198
  WysijaForm.hideBlockControls();
199
 
200
+ this.drops.each(function (drop) {
201
  if (drop.element.hasClassName('block_placeholder')) {
202
  drop.element.addClassName('active');
203
  }
205
  },
206
  hideArea: function () {
207
  if (!this.drops.length) return;
208
+ this.drops.each(function (drop) {
209
  if (drop.element.hasClassName('block_placeholder')) {
210
  drop.element.removeClassName('active');
211
  } else if (drop.element.hasClassName('image_placeholder')) {
227
  - set a maximum number of items to be stored
228
 
229
  */
230
+ WysijaHistory = {
231
  container: 'mailpoet_form_history',
232
  size: 30,
233
  enqueue: function (element) {
271
  };
272
 
273
  /* MailPoet Form */
274
+ WysijaForm = {
275
  version: '0.7',
276
  options: {
277
  container: 'mailpoet_form_container',
324
  });
325
  },
326
  load: function (data) {
327
+ var settings_elements;
328
  if (data === undefined) return;
329
 
330
  // load body
335
  });
336
 
337
  // load settings
338
+ settings_elements = window.$('mailpoet_form_settings').getElements();
339
  settings_elements.each(function (setting) {
340
  // skip lists
341
  if (setting.name === 'segments') {
357
  }
358
  },
359
  save: function () {
360
+ var position = 1;
361
+ var data = {
362
+ name: window.$F('mailpoet_form_name'),
363
+ settings: window.$('mailpoet_form_settings').serialize(true),
364
+ body: [],
365
+ styles: (window.MailPoet.CodeEditor !== undefined) ? window.MailPoet.CodeEditor.getValue() : null
366
+ };
367
  // body
368
  WysijaForm.getBlocks().each(function (b) {
369
  var block_data = (typeof (b.block['save']) === 'function') ? b.block.save() : null;
434
  return data;
435
  },
436
  toggleWidgets: function () {
437
+ var hasSegmentSelection;
438
  window.$$('a[wysija_unique="1"]').invoke('removeClassName', 'disabled');
439
 
440
  // loop through each unique field already inserted in the editor and disable its toolbar equivalent
445
  }
446
  });
447
 
448
+ hasSegmentSelection = WysijaForm.hasSegmentSelection();
449
 
450
  if (hasSegmentSelection) {
451
  window.$('mailpoet_form_segments').writeAttribute('required', false).disable();
460
  },
461
  isSegmentSelectionValid: function () {
462
  var segment_selection = window.$$('#' + WysijaForm.options.editor + ' [wysija_id="segments"]')[0];
463
+ var block;
464
  if (segment_selection !== undefined) {
465
+ block = WysijaForm.get(segment_selection).block.getData();
466
  return (
467
  (block.params.values !== undefined)
468
  &&
472
  return false;
473
  },
474
  setBlockPositions: function (event, target) {
475
+ var index = 1;
476
+ var block_placeholder;
477
+ var previous_placeholder;
478
  // release dragging lock
479
  WysijaForm.locks.dragging = false;
480
 
 
481
  WysijaForm.getBlocks().each(function (container) {
482
  container.setPosition(index++);
483
  // remove z-index value to avoid issues when resizing images
490
 
491
  if (target !== undefined) {
492
  // get placeholders (previous placeholder matches the placeholder linked to the next block)
493
+ block_placeholder = window.$(target.element.readAttribute('wysija_placeholder'));
494
+ previous_placeholder = target.element.previous('.block_placeholder');
495
 
496
  if (block_placeholder !== null) {
497
  // put block placeholder before the current block
516
  },
517
  setSettingsPosition: function () {
518
  // get viewport offsets and dimensions
519
+ var viewportHeight = document.viewport.getHeight();
 
520
 
521
  window.$(WysijaForm.options.container).select('.wysija_settings').each(function (element) {
522
  // get parent dimensions and position
523
+ var parentDim = element.up('.mailpoet_form_block').getDimensions();
524
+ var parentPos = element.up('.mailpoet_form_block').cumulativeOffset();
525
+ var is_visible = (parentPos.top <= (WysijaForm.scroll.top + viewportHeight));
526
+ var buttonMargin = 5;
527
+ var relativeTop = buttonMargin;
528
 
529
  if (is_visible) {
 
 
 
 
 
530
  // always center
531
  relativeTop = parseInt((parentDim.height / 2) - (element.getHeight() / 2), 10);
532
  }
550
 
551
  },
552
  setToolbarPosition: function () {
553
+ var position;
554
  WysijaForm.initToolbarPosition();
555
 
556
+ position = {
557
  top: WysijaForm.toolbar.y + 'px',
558
  visibility: 'visible'
559
  };
617
  instances: {},
618
  get: function (element, typ) {
619
  var type = typ;
620
+ var id;
621
+ var instance;
622
  if (type === undefined) type = 'block';
623
  // identify element
624
+ id = element.identify();
625
+ instance = WysijaForm.instances[id] || new WysijaForm[type.capitalize().camelize()](id);
626
 
627
  WysijaForm.instances[id] = instance;
628
  return instance;
670
  },
671
  encodeURIComponent: function (str) {
672
  // check if it's a url and if so, prevent encoding of protocol
673
+ var regexp = new RegExp(/^http[s]?:\/\//);
674
+ var protocol = regexp.exec(str);
675
 
676
  if (protocol === null) {
677
  // this is not a url so encode the whole thing
714
  },
715
  STYLES: new window.Template('position: absolute; top: #{top}px; left: #{left}px;'),
716
  cloneElement: function () {
717
+ var clone = this.element.clone();
718
+ var offset = this.element.cumulativeOffset();
719
+ var list = this.getList();
720
+ var styles = this.STYLES.evaluate({
721
+ top: offset.top - list.scrollTop,
722
+ left: offset.left - list.scrollLeft
723
+ });
724
  clone.setStyle(styles);
725
 
726
  clone.addClassName('mailpoet_form_widget');
801
  }
802
  },
803
  makeBlockDroppable: function () {
804
+ var block_placeholder;
805
  if (this.isBlockDroppableEnabled() === false) {
806
+ block_placeholder = this.getBlockDroppable();
807
  window.Droppables.add(block_placeholder.identify(), WysijaForm.blockDropOptions);
808
  block_placeholder.addClassName('enabled');
809
  }
810
  },
811
  removeBlockDroppable: function () {
812
+ var block_placeholder;
813
  if (this.isBlockDroppableEnabled()) {
814
+ block_placeholder = this.getBlockDroppable();
815
  window.Droppables.remove(block_placeholder.identify());
816
  block_placeholder.removeClassName('enabled');
817
  }
843
  return this.element.down('.wysija_controls');
844
  },
845
  setupControls: function () {
846
+ var block;
847
  // enable controls
848
  this.controls = this.getControls();
849
 
894
  if (this.settingsButton !== null) {
895
  this.settingsButton.observe('click', function (event) {
896
  // TODO: refactor
897
+ block = window.$(event.target).up('.mailpoet_form_block') || null;
898
  if (block !== null) {
 
899
  this.editSettings();
900
  }
901
  }.bind(this));
941
  /* Invoked on item dropped */
942
  WysijaForm.Block.create = function (createBlock, target) {
943
  var block = createBlock;
944
+ var body;
945
+ var block_template;
946
+ var template;
947
+ var output;
948
+ var settings_segments;
949
  if (window.$('form_template_' + block.type) === null) {
950
  return false;
951
  }
952
 
953
+ body = window.$(WysijaForm.options.body);
954
+ block_template = window.Handlebars.compile(window.$('form_template_block').innerHTML);
955
+ template = window.Handlebars.compile(window.$('form_template_' + block.type).innerHTML);
956
+ output = '';
957
 
958
  if (block.type === 'segment') {
959
  if (block.params.values === undefined) {
960
+ settings_segments = window.jQuery('#mailpoet_form_segments').val();
961
  if (settings_segments !== null && settings_segments.length > 0) {
962
  block.params.values = window.mailpoet_segments.filter(function (segment) {
963
  return (settings_segments.indexOf(segment.id) !== -1);
977
  }
978
 
979
  // if the drop target was the bottom placeholder
 
980
  if (target.identify() === 'block_placeholder') {
981
  // insert block at the bottom
982
+ body.insert(output);
983
  // block = body.childElements().last();
984
  } else {
985
  // insert block before the drop target
986
+ target.insert({
987
  before: output
988
  });
989
  // block = target.previous('.mailpoet_form_block');
1024
  this.setupControls();
1025
  },
1026
  save: function () {
 
1027
  var data = this.getData();
1028
+ info('widget -> save');
1029
 
1030
  if (data.element !== undefined) {
1031
  delete data.element;
1034
  return data;
1035
  },
1036
  setData: function (data) {
1037
+ var current_data = this.getData();
1038
+ var params = window.$H(current_data.params).merge(data.params).toObject();
1039
 
1040
  // update type if it changed
1041
  if (data.type !== undefined && data.type !== current_data.type) {
1060
  this.removeBlock();
1061
  },
1062
  redraw: function (data) {
1063
+ var options;
1064
+ var block_template;
1065
+ var template;
1066
+ var params;
1067
  // set parameters
1068
  this.setData(data);
1069
+ options = this.getData();
1070
  // redraw block
1071
+ block_template = window.Handlebars.compile(window.$('form_template_block').innerHTML);
1072
+ template = window.Handlebars.compile(window.$('form_template_' + options.type).innerHTML);
1073
+ params = window.$H(options).merge({
1074
+ template: template(options)
1075
+ }).toObject();
1076
+ this.element.replace(block_template(params));
1077
 
1078
  WysijaForm.init();
1079
  },
1105
  var noop = function () {};
1106
  var methods = ['assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'markTimeline', 'profile', 'profileEnd', 'markTimeline', 'table', 'time', 'timeEnd', 'timeStamp', 'trace', 'warn'];
1107
  var length = methods.length;
 
1108
  var console = {};
1109
+ window.console = {};
1110
  while (length--) {
1111
  console[methods[length]] = noop;
1112
  }
assets/js/lib/mailpoet_shortcodes/plugin.js CHANGED
@@ -10,31 +10,33 @@
10
 
11
  /* jshint unused:false */
12
  /* global tinymce:true */
13
- tinymce.PluginManager.add('mailpoet_shortcodes', function (editor, url) {
14
  var appendLabelAndClose = function (shortcode) {
15
- editor.insertContent(shortcode);
16
- editor.windowManager.close();
17
- },
18
- generateOnClickFunc = function (shortcode) {
19
- return function () {
20
- appendLabelAndClose(shortcode);
21
- };
22
  };
 
23
 
24
  editor.addButton('mailpoet_shortcodes', {
25
  icon: 'mailpoet_shortcodes',
26
  onclick: function () {
27
- var shortcodes = [],
28
- configShortcodes = editor.settings.mailpoet_shortcodes;
 
 
29
 
30
- for (var segment in configShortcodes) {
31
  if (configShortcodes.hasOwnProperty(segment)) {
32
  shortcodes.push({
33
  type: 'label',
34
  text: segment
35
  });
36
 
37
- for (var i = 0; i < configShortcodes[segment].length; i += 1) {
38
  shortcodes.push({
39
  type: 'button',
40
  text: configShortcodes[segment][i].text,
10
 
11
  /* jshint unused:false */
12
  /* global tinymce:true */
13
+ tinymce.PluginManager.add('mailpoet_shortcodes', function (editor) {
14
  var appendLabelAndClose = function (shortcode) {
15
+ editor.insertContent(shortcode);
16
+ editor.windowManager.close();
17
+ };
18
+ var generateOnClickFunc = function (shortcode) {
19
+ return function () {
20
+ appendLabelAndClose(shortcode);
 
21
  };
22
+ };
23
 
24
  editor.addButton('mailpoet_shortcodes', {
25
  icon: 'mailpoet_shortcodes',
26
  onclick: function () {
27
+ var shortcodes = [];
28
+ var configShortcodes = editor.settings.mailpoet_shortcodes;
29
+ var segment;
30
+ var i;
31
 
32
+ for (segment in configShortcodes) {
33
  if (configShortcodes.hasOwnProperty(segment)) {
34
  shortcodes.push({
35
  type: 'label',
36
  text: segment
37
  });
38
 
39
+ for (i = 0; i < configShortcodes[segment].length; i += 1) {
40
  shortcodes.push({
41
  type: 'button',
42
  text: configShortcodes[segment][i].text,
assets/js/{mailpoet.0fdbdb38.js → mailpoet.122cc57f.js} RENAMED
@@ -49865,11 +49865,10 @@ webpackJsonp([3],[
49865
  if (xhr.responseJSON) {
49866
  return xhr.responseJSON;
49867
  }
49868
- var message = errorMessage.replace('%d', xhr.status);
49869
  return {
49870
  errors: [
49871
  {
49872
- message: message
49873
  }
49874
  ]
49875
  };
@@ -49917,21 +49916,23 @@ webpackJsonp([3],[
49917
  };
49918
  },
49919
  request: function (method, options) {
49920
- // set options
 
 
49921
  this.init(options);
49922
 
49923
- // set request params
49924
- var params = this.getParams();
49925
 
49926
- // remove null values from the data object
49927
  if (_.isObject(params.data)) {
49928
  params.data = _.pick(params.data, function (value) {
49929
  return (value !== null);
49930
  });
49931
  }
49932
 
49933
- // ajax request
49934
- var deferred = jQuery.post(
49935
  this.options.url,
49936
  params,
49937
  null,
@@ -49997,9 +49998,10 @@ webpackJsonp([3],[
49997
  },
49998
  format: function (date, opts) {
49999
  var options = opts || {};
 
50000
  this.init(options);
50001
 
50002
- var momentDate = Moment(date, this.convertFormat(options.parseFormat));
50003
  if (options.offset === 0) momentDate = momentDate.utc();
50004
  return momentDate.format(this.convertFormat(this.options.format));
50005
  },
@@ -50025,6 +50027,11 @@ webpackJsonp([3],[
50025
  });
50026
  },
50027
  convertFormat: function (format) {
 
 
 
 
 
50028
  var format_mappings = {
50029
  date: {
50030
  d: 'DD',
@@ -50094,12 +50101,11 @@ webpackJsonp([3],[
50094
 
50095
  if (!format || format.length <= 0) return format;
50096
 
50097
- var replacements = format_mappings['date'];
50098
-
50099
- var convertedFormat = [];
50100
- var escapeToken = false;
50101
 
50102
- for (var index = 0, token = ''; format.charAt(index); index += 1) {
50103
  token = format.charAt(index);
50104
  if (escapeToken === true) {
50105
  convertedFormat.push('[' + token + ']');
@@ -50274,6 +50280,7 @@ webpackJsonp([3],[
50274
  }
50275
  },
50276
  init: function (options) {
 
50277
  if (this.initialized === true) {
50278
  this.close();
50279
  }
@@ -50292,7 +50299,7 @@ webpackJsonp([3],[
50292
  if (this.options.type !== null) {
50293
  // insert modal depending on its type
50294
  if (this.options.type === 'popup') {
50295
- var modal = this.compileTemplate(
50296
  this.templates[this.options.type]
50297
  );
50298
  // create modal
@@ -50336,7 +50343,7 @@ webpackJsonp([3],[
50336
 
50337
  return this;
50338
  },
50339
- initOverlay: function (toggle) {
50340
  if (jQuery('#mailpoet_modal_overlay').length === 0) {
50341
  // insert overlay into the DOM
50342
  jQuery('body').append(this.templates.overlay);
@@ -50501,20 +50508,21 @@ webpackJsonp([3],[
50501
  return this;
50502
  },
50503
  setPosition: function () {
 
 
 
 
50504
  switch (this.options.type) {
50505
  case 'popup':
50506
- var screenWidth = jQuery(window).width(),
50507
- screenHeight = jQuery(window).height(),
50508
- modalWidth = jQuery('.mailpoet_' + this.options.type + '_wrapper').width(),
50509
- modalHeight = jQuery('.mailpoet_' + this.options.type + '_wrapper').height();
50510
 
50511
- var top = Math.max(48, parseInt((screenHeight / 2) - (modalHeight / 2))),
50512
- left = Math.max(0, parseInt((screenWidth / 2) - (modalWidth / 2)));
50513
-
50514
- // set position of popup depending on screen dimensions.
50515
  jQuery('#mailpoet_popup').css({
50516
- top: top,
50517
- left: left
50518
  });
50519
  break;
50520
  case 'panel':
@@ -50594,7 +50602,7 @@ webpackJsonp([3],[
50594
  .removeClass('mailpoet_modal_highlight');
50595
  return this;
50596
  },
50597
- hideModal: function (callback) {
50598
  // set modal as closed
50599
  this.opened = false;
50600
 
@@ -50609,7 +50617,7 @@ webpackJsonp([3],[
50609
 
50610
  return this;
50611
  },
50612
- showOverlay: function (force) {
50613
  jQuery('#mailpoet_modal_overlay').show();
50614
  return this;
50615
  },
@@ -50854,6 +50862,8 @@ webpackJsonp([3],[
50854
  return this;
50855
  },
50856
  createNotice: function () {
 
 
50857
  // clone element
50858
  this.element = jQuery('#mailpoet_notice_' + this.options.type).clone();
50859
 
@@ -50869,7 +50879,6 @@ webpackJsonp([3],[
50869
  this.element.removeAttr('id');
50870
 
50871
  // insert notice after its parent
50872
- var positionAfter;
50873
  if (typeof this.options.positionAfter === 'object') {
50874
  positionAfter = this.options.positionAfter;
50875
  } else if (typeof this.options.positionAfter === 'string') {
@@ -50880,7 +50889,7 @@ webpackJsonp([3],[
50880
  positionAfter.after(this.element);
50881
 
50882
  // setup onClose callback
50883
- var onClose = null;
50884
  if (this.options.onClose !== null) {
50885
  onClose = this.options.onClose;
50886
  }
@@ -50984,12 +50993,13 @@ webpackJsonp([3],[
50984
  }
50985
  },
50986
  hide: function (all) {
 
50987
  if (all !== undefined && all === true) {
50988
  // all notices
50989
  jQuery('.mailpoet_notice:not([id])').trigger('close');
50990
  } else if (all !== undefined && jQuery.isArray(all)) {
50991
  // array of ids
50992
- for (var id in all) {
50993
  jQuery('[data-id="' + all[id] + '"]').trigger('close');
50994
  }
50995
  } if (all !== undefined) {
@@ -51078,20 +51088,20 @@ webpackJsonp([3],[
51078
  * http://benalman.com/about/license/
51079
  */
51080
  $.fn.serializeObject = function (coerce) {
51081
- var obj = {},
51082
- coerce_types = { true: !0, false: !1, null: null };
51083
 
51084
  // Iterate over all name=value pairs.
51085
  $.each(this.serializeArray(), function (j, v) {
51086
- var key = v.name,
51087
- val = v.value,
51088
- cur = obj,
51089
- i = 0,
51090
-
51091
- // If key is more complex than 'foo', like 'a[]' or 'a[b][c]', split it
51092
- // into its component parts.
51093
- keys = key.split(']['),
51094
- keys_last = keys.length - 1;
51095
 
51096
  // If the first keys part contains [ and the last ends with ], then []
51097
  // are correctly balanced.
@@ -51161,6 +51171,7 @@ webpackJsonp([3],[
51161
  return $;
51162
  }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
51163
 
 
51164
  /***/ },
51165
  /* 559 */
51166
  /***/ function(module, exports, __webpack_require__) {
49865
  if (xhr.responseJSON) {
49866
  return xhr.responseJSON;
49867
  }
 
49868
  return {
49869
  errors: [
49870
  {
49871
+ message: errorMessage.replace('%d', xhr.status)
49872
  }
49873
  ]
49874
  };
49916
  };
49917
  },
49918
  request: function (method, options) {
49919
+ var params;
49920
+ var deferred;
49921
+ // set options
49922
  this.init(options);
49923
 
49924
+ // set request params
49925
+ params = this.getParams();
49926
 
49927
+ // remove null values from the data object
49928
  if (_.isObject(params.data)) {
49929
  params.data = _.pick(params.data, function (value) {
49930
  return (value !== null);
49931
  });
49932
  }
49933
 
49934
+ // ajax request
49935
+ deferred = jQuery.post(
49936
  this.options.url,
49937
  params,
49938
  null,
49998
  },
49999
  format: function (date, opts) {
50000
  var options = opts || {};
50001
+ var momentDate;
50002
  this.init(options);
50003
 
50004
+ momentDate = Moment(date, this.convertFormat(options.parseFormat));
50005
  if (options.offset === 0) momentDate = momentDate.utc();
50006
  return momentDate.format(this.convertFormat(this.options.format));
50007
  },
50027
  });
50028
  },
50029
  convertFormat: function (format) {
50030
+ var replacements;
50031
+ var convertedFormat;
50032
+ var escapeToken;
50033
+ var index;
50034
+ var token;
50035
  var format_mappings = {
50036
  date: {
50037
  d: 'DD',
50101
 
50102
  if (!format || format.length <= 0) return format;
50103
 
50104
+ replacements = format_mappings['date'];
50105
+ convertedFormat = [];
50106
+ escapeToken = false;
 
50107
 
50108
+ for (index = 0, token = ''; format.charAt(index); index += 1) {
50109
  token = format.charAt(index);
50110
  if (escapeToken === true) {
50111
  convertedFormat.push('[' + token + ']');
50280
  }
50281
  },
50282
  init: function (options) {
50283
+ var modal;
50284
  if (this.initialized === true) {
50285
  this.close();
50286
  }
50299
  if (this.options.type !== null) {
50300
  // insert modal depending on its type
50301
  if (this.options.type === 'popup') {
50302
+ modal = this.compileTemplate(
50303
  this.templates[this.options.type]
50304
  );
50305
  // create modal
50343
 
50344
  return this;
50345
  },
50346
+ initOverlay: function () {
50347
  if (jQuery('#mailpoet_modal_overlay').length === 0) {
50348
  // insert overlay into the DOM
50349
  jQuery('body').append(this.templates.overlay);
50508
  return this;
50509
  },
50510
  setPosition: function () {
50511
+ var screenWidth;
50512
+ var screenHeight;
50513
+ var modalWidth;
50514
+ var modalHeight;
50515
  switch (this.options.type) {
50516
  case 'popup':
50517
+ screenWidth = jQuery(window).width();
50518
+ screenHeight = jQuery(window).height();
50519
+ modalWidth = jQuery('.mailpoet_'+ this.options.type +'_wrapper').width();
50520
+ modalHeight = jQuery('.mailpoet_'+ this.options.type +'_wrapper').height();
50521
 
50522
+ // set position of popup depending on screen dimensions.
 
 
 
50523
  jQuery('#mailpoet_popup').css({
50524
+ top: Math.max(48, parseInt((screenHeight / 2) - (modalHeight / 2))),
50525
+ left: Math.max(0, parseInt((screenWidth / 2) - (modalWidth / 2)))
50526
  });
50527
  break;
50528
  case 'panel':
50602
  .removeClass('mailpoet_modal_highlight');
50603
  return this;
50604
  },
50605
+ hideModal: function () {
50606
  // set modal as closed
50607
  this.opened = false;
50608
 
50617
 
50618
  return this;
50619
  },
50620
+ showOverlay: function () {
50621
  jQuery('#mailpoet_modal_overlay').show();
50622
  return this;
50623
  },
50862
  return this;
50863
  },
50864
  createNotice: function () {
50865
+ var onClose;
50866
+ var positionAfter;
50867
  // clone element
50868
  this.element = jQuery('#mailpoet_notice_' + this.options.type).clone();
50869
 
50879
  this.element.removeAttr('id');
50880
 
50881
  // insert notice after its parent
 
50882
  if (typeof this.options.positionAfter === 'object') {
50883
  positionAfter = this.options.positionAfter;
50884
  } else if (typeof this.options.positionAfter === 'string') {
50889
  positionAfter.after(this.element);
50890
 
50891
  // setup onClose callback
50892
+ onClose = null;
50893
  if (this.options.onClose !== null) {
50894
  onClose = this.options.onClose;
50895
  }
50993
  }
50994
  },
50995
  hide: function (all) {
50996
+ var id;
50997
  if (all !== undefined && all === true) {
50998
  // all notices
50999
  jQuery('.mailpoet_notice:not([id])').trigger('close');
51000
  } else if (all !== undefined && jQuery.isArray(all)) {
51001
  // array of ids
51002
+ for (id in all) {
51003
  jQuery('[data-id="' + all[id] + '"]').trigger('close');
51004
  }
51005
  } if (all !== undefined) {
51088
  * http://benalman.com/about/license/
51089
  */
51090
  $.fn.serializeObject = function (coerce) {
51091
+ var obj = {};
51092
+ var coerce_types = { true: !0, false: !1, null: null };
51093
 
51094
  // Iterate over all name=value pairs.
51095
  $.each(this.serializeArray(), function (j, v) {
51096
+ var key = v.name;
51097
+ var val = v.value;
51098
+ var cur = obj;
51099
+ var i = 0;
51100
+
51101
+ // If key is more complex than 'foo', like 'a[]' or 'a[b][c]', split it
51102
+ // into its component parts.
51103
+ var keys = key.split('][');
51104
+ var keys_last = keys.length - 1;
51105
 
51106
  // If the first keys part contains [ and the last ends with ], then []
51107
  // are correctly balanced.
51171
  return $;
51172
  }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
51173
 
51174
+
51175
  /***/ },
51176
  /* 559 */
51177
  /***/ function(module, exports, __webpack_require__) {
assets/js/manifest.json CHANGED
@@ -1,10 +1,10 @@
1
  {
2
  "mp2migrator.js": "mp2migrator.e755af46.js",
3
- "public.js": "public.6e3f442a.js",
4
- "admin.js": "admin.5545d8c1.js",
5
- "admin_vendor.js": "admin_vendor.6c010053.js",
6
- "form_editor.js": "form_editor.c4bc7e0b.js",
7
- "mailpoet.js": "mailpoet.0fdbdb38.js",
8
- "newsletter_editor.js": "newsletter_editor.29b8231c.js",
9
- "vendor.js": "vendor.3c88b878.js"
10
  }
1
  {
2
  "mp2migrator.js": "mp2migrator.e755af46.js",
3
+ "public.js": "public.fecfa135.js",
4
+ "admin.js": "admin.790800b0.js",
5
+ "admin_vendor.js": "admin_vendor.dda60c3b.js",
6
+ "form_editor.js": "form_editor.d94aebf3.js",
7
+ "mailpoet.js": "mailpoet.122cc57f.js",
8
+ "newsletter_editor.js": "newsletter_editor.7394c278.js",
9
+ "vendor.js": "vendor.b37906c4.js"
10
  }
assets/js/{newsletter_editor.29b8231c.js → newsletter_editor.7394c278.js} RENAMED
@@ -1,6 +1,6 @@
1
  webpackJsonp([4],{
2
 
3
- /***/ 579:
4
  /***/ function(module, exports, __webpack_require__) {
5
 
6
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
@@ -103,7 +103,7 @@ webpackJsonp([4],{
103
  });
104
  };
105
 
106
- App.on('start', function (App, options) {
107
  // Prefetch post types
108
  Module.getPostTypes();
109
  });
@@ -131,13 +131,14 @@ webpackJsonp([4],{
131
  __webpack_require__(572);
132
  __webpack_require__(573);
133
  __webpack_require__(574);
 
134
  __webpack_require__(576);
135
  __webpack_require__(577);
136
- __webpack_require__(578);
137
  __webpack_require__(580);
138
  __webpack_require__(581);
139
- __webpack_require__(582);
140
- __webpack_require__(579);
141
  __webpack_require__(585);
142
  __webpack_require__(586);
143
  __webpack_require__(587);
@@ -158,8 +159,7 @@ webpackJsonp([4],{
158
  __webpack_require__(602);
159
  __webpack_require__(603);
160
  __webpack_require__(604);
161
- __webpack_require__(605);
162
- module.exports = __webpack_require__(606);
163
 
164
 
165
  /***/ },
@@ -9439,11 +9439,10 @@ webpackJsonp([4],{
9439
  if (xhr.responseJSON) {
9440
  return xhr.responseJSON;
9441
  }
9442
- var message = errorMessage.replace('%d', xhr.status);
9443
  return {
9444
  errors: [
9445
  {
9446
- message: message
9447
  }
9448
  ]
9449
  };
@@ -9491,21 +9490,23 @@ webpackJsonp([4],{
9491
  };
9492
  },
9493
  request: function (method, options) {
9494
- // set options
 
 
9495
  this.init(options);
9496
 
9497
- // set request params
9498
- var params = this.getParams();
9499
 
9500
- // remove null values from the data object
9501
  if (_.isObject(params.data)) {
9502
  params.data = _.pick(params.data, function (value) {
9503
  return (value !== null);
9504
  });
9505
  }
9506
 
9507
- // ajax request
9508
- var deferred = jQuery.post(
9509
  this.options.url,
9510
  params,
9511
  null,
@@ -9645,6 +9646,7 @@ webpackJsonp([4],{
9645
  }
9646
  },
9647
  init: function (options) {
 
9648
  if (this.initialized === true) {
9649
  this.close();
9650
  }
@@ -9663,7 +9665,7 @@ webpackJsonp([4],{
9663
  if (this.options.type !== null) {
9664
  // insert modal depending on its type
9665
  if (this.options.type === 'popup') {
9666
- var modal = this.compileTemplate(
9667
  this.templates[this.options.type]
9668
  );
9669
  // create modal
@@ -9707,7 +9709,7 @@ webpackJsonp([4],{
9707
 
9708
  return this;
9709
  },
9710
- initOverlay: function (toggle) {
9711
  if (jQuery('#mailpoet_modal_overlay').length === 0) {
9712
  // insert overlay into the DOM
9713
  jQuery('body').append(this.templates.overlay);
@@ -9872,20 +9874,21 @@ webpackJsonp([4],{
9872
  return this;
9873
  },
9874
  setPosition: function () {
 
 
 
 
9875
  switch (this.options.type) {
9876
  case 'popup':
9877
- var screenWidth = jQuery(window).width(),
9878
- screenHeight = jQuery(window).height(),
9879
- modalWidth = jQuery('.mailpoet_' + this.options.type + '_wrapper').width(),
9880
- modalHeight = jQuery('.mailpoet_' + this.options.type + '_wrapper').height();
9881
-
9882
- var top = Math.max(48, parseInt((screenHeight / 2) - (modalHeight / 2))),
9883
- left = Math.max(0, parseInt((screenWidth / 2) - (modalWidth / 2)));
9884
 
9885
- // set position of popup depending on screen dimensions.
9886
  jQuery('#mailpoet_popup').css({
9887
- top: top,
9888
- left: left
9889
  });
9890
  break;
9891
  case 'panel':
@@ -9965,7 +9968,7 @@ webpackJsonp([4],{
9965
  .removeClass('mailpoet_modal_highlight');
9966
  return this;
9967
  },
9968
- hideModal: function (callback) {
9969
  // set modal as closed
9970
  this.opened = false;
9971
 
@@ -9980,7 +9983,7 @@ webpackJsonp([4],{
9980
 
9981
  return this;
9982
  },
9983
- showOverlay: function (force) {
9984
  jQuery('#mailpoet_modal_overlay').show();
9985
  return this;
9986
  },
@@ -10226,6 +10229,8 @@ webpackJsonp([4],{
10226
  return this;
10227
  },
10228
  createNotice: function () {
 
 
10229
  // clone element
10230
  this.element = jQuery('#mailpoet_notice_' + this.options.type).clone();
10231
 
@@ -10241,7 +10246,6 @@ webpackJsonp([4],{
10241
  this.element.removeAttr('id');
10242
 
10243
  // insert notice after its parent
10244
- var positionAfter;
10245
  if (typeof this.options.positionAfter === 'object') {
10246
  positionAfter = this.options.positionAfter;
10247
  } else if (typeof this.options.positionAfter === 'string') {
@@ -10252,7 +10256,7 @@ webpackJsonp([4],{
10252
  positionAfter.after(this.element);
10253
 
10254
  // setup onClose callback
10255
- var onClose = null;
10256
  if (this.options.onClose !== null) {
10257
  onClose = this.options.onClose;
10258
  }
@@ -10356,12 +10360,13 @@ webpackJsonp([4],{
10356
  }
10357
  },
10358
  hide: function (all) {
 
10359
  if (all !== undefined && all === true) {
10360
  // all notices
10361
  jQuery('.mailpoet_notice:not([id])').trigger('close');
10362
  } else if (all !== undefined && jQuery.isArray(all)) {
10363
  // array of ids
10364
- for (var id in all) {
10365
  jQuery('[data-id="' + all[id] + '"]').trigger('close');
10366
  }
10367
  } if (all !== undefined) {
@@ -27597,15 +27602,15 @@ webpackJsonp([4],{
27597
  */
27598
 
27599
  (function (root, factory) {
 
 
 
27600
  if (true) {
27601
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(562), __webpack_require__(563), __webpack_require__(278)], __WEBPACK_AMD_DEFINE_RESULT__ = function (Marionette, Radio, _) {
27602
  return factory(Marionette, Radio, _);
27603
  }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
27604
  }
27605
  else if (typeof exports !== 'undefined') {
27606
- var Marionette = require('backbone.marionette');
27607
- var Radio = require('backbone.radio');
27608
- var _ = require('underscore');
27609
  module.exports = factory(Marionette, Radio, _);
27610
  }
27611
  else {
@@ -27630,12 +27635,8 @@ webpackJsonp([4],{
27630
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
27631
  __webpack_require__(535),
27632
  __webpack_require__(562),
27633
- __webpack_require__(563),
27634
- __webpack_require__(273),
27635
- __webpack_require__(278),
27636
- __webpack_require__(543),
27637
- __webpack_require__(575)
27638
- ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Backbone, Marionette, BackboneRadio, jQuery, _, Handlebars) {
27639
  var Radio = BackboneRadio;
27640
 
27641
  var AppView = Marionette.View.extend({
@@ -27675,7 +27676,7 @@ webpackJsonp([4],{
27675
 
27676
  /***/ },
27677
 
27678
- /***/ 576:
27679
  /***/ function(module, exports, __webpack_require__) {
27680
 
27681
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
@@ -27719,7 +27720,7 @@ webpackJsonp([4],{
27719
 
27720
  /***/ },
27721
 
27722
- /***/ 577:
27723
  /***/ function(module, exports, __webpack_require__) {
27724
 
27725
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
@@ -27795,17 +27796,19 @@ webpackJsonp([4],{
27795
 
27796
  App.on('before:start', function (App, options) {
27797
  var Application = App;
 
 
27798
  // Expose style methods to global application
27799
  Application.getGlobalStyles = Module.getGlobalStyles;
27800
  Application.setGlobalStyles = Module.setGlobalStyles;
27801
  Application.getAvailableStyles = Module.getAvailableStyles;
27802
 
27803
- var body = options.newsletter.body;
27804
- var globalStyles = (_.has(body, 'globalStyles')) ? body.globalStyles : {};
27805
  this.setGlobalStyles(globalStyles);
27806
  });
27807
 
27808
- App.on('start', function (App, options) {
27809
  var stylesView = new Module.StylesView({ model: App.getGlobalStyles() });
27810
  App._appView.showChildView('stylesRegion', stylesView);
27811
  });
@@ -27816,19 +27819,18 @@ webpackJsonp([4],{
27816
 
27817
  /***/ },
27818
 
27819
- /***/ 578:
27820
  /***/ function(module, exports, __webpack_require__) {
27821
 
27822
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
27823
  __webpack_require__(574),
27824
- __webpack_require__(579),
27825
  __webpack_require__(274),
27826
  __webpack_require__(535),
27827
  __webpack_require__(562),
27828
  __webpack_require__(564),
27829
  __webpack_require__(278),
27830
- __webpack_require__(273),
27831
- __webpack_require__(567)
27832
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (
27833
  App,
27834
  CommunicationComponent,
@@ -27837,14 +27839,13 @@ webpackJsonp([4],{
27837
  Marionette,
27838
  SuperModel,
27839
  _,
27840
- jQuery,
27841
- StickyKit
27842
  ) {
27843
 
27844
  'use strict';
27845
 
27846
  var Module = {};
27847
-
27848
  // Widget handlers for use to create new content blocks via drag&drop
27849
  Module._contentWidgets = new (Backbone.Collection.extend({
27850
  model: SuperModel.extend({
@@ -27873,7 +27874,7 @@ webpackJsonp([4],{
27873
  Module.registerLayoutWidget = function (widget) { return Module._layoutWidgets.add(widget); };
27874
  Module.getLayoutWidgets = function () { return Module._layoutWidgets; };
27875
 
27876
- var SidebarView = Marionette.View.extend({
27877
  getTemplate: function () { return window.templates.sidebar; },
27878
  regions: {
27879
  contentRegion: '.mailpoet_content_region',
@@ -27883,8 +27884,8 @@ webpackJsonp([4],{
27883
  },
27884
  events: {
27885
  'click .mailpoet_sidebar_region h3, .mailpoet_sidebar_region .handlediv': function (event) {
27886
- var $openRegion = this.$el.find('.mailpoet_sidebar_region:not(.closed)'),
27887
- $targetRegion = this.$el.find(event.target).closest('.mailpoet_sidebar_region');
27888
 
27889
  $openRegion.find('.mailpoet_region_content').velocity(
27890
  'slideUp',
@@ -27911,7 +27912,7 @@ webpackJsonp([4],{
27911
  }
27912
  }
27913
  },
27914
- initialize: function (options) {
27915
  jQuery(window)
27916
  .on('resize', this.updateHorizontalScroll.bind(this))
27917
  .on('scroll', this.updateHorizontalScroll.bind(this));
@@ -27934,9 +27935,8 @@ webpackJsonp([4],{
27934
  // position of the sidebar would be scrollable and not fixed
27935
  // partially out of visible screen
27936
  this.$el.parent().each(function () {
27937
- var calculated_left, self;
27938
-
27939
- self = jQuery(this);
27940
 
27941
  if (self.css('position') === 'fixed') {
27942
  calculated_left = self.parent().offset().left - jQuery(window).scrollLeft();
@@ -28092,7 +28092,7 @@ webpackJsonp([4],{
28092
  previewUrl: response.meta.preview_url
28093
  });
28094
 
28095
- var view = this.previewView.render();
28096
  this.previewView.$el.css('height', '100%');
28097
 
28098
  MailPoet.Modal.popup({
@@ -28145,7 +28145,7 @@ webpackJsonp([4],{
28145
  App.getChannel().request('save').always(function () {
28146
  CommunicationComponent.previewNewsletter(data).always(function () {
28147
  MailPoet.Modal.loading(false);
28148
- }).done(function (response) {
28149
  MailPoet.Notice.success(
28150
  MailPoet.I18n.t('newsletterPreviewSent'),
28151
  { scroll: true }
@@ -28184,7 +28184,7 @@ webpackJsonp([4],{
28184
  }
28185
  });
28186
 
28187
- App.on('before:start', function (App, options) {
28188
  var Application = App;
28189
  Application.registerWidget = Module.registerWidget;
28190
  Application.getWidgets = Module.getWidgets;
@@ -28192,9 +28192,8 @@ webpackJsonp([4],{
28192
  Application.getLayoutWidgets = Module.getLayoutWidgets;
28193
  });
28194
 
28195
- App.on('start', function (App, options) {
28196
- var stylesModel = App.getGlobalStyles(),
28197
- sidebarView = new SidebarView();
28198
 
28199
  App._appView.showChildView('sidebarRegion', sidebarView);
28200
 
@@ -28222,7 +28221,7 @@ webpackJsonp([4],{
28222
 
28223
  /***/ },
28224
 
28225
- /***/ 580:
28226
  /***/ function(module, exports, __webpack_require__) {
28227
 
28228
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
@@ -28240,7 +28239,7 @@ webpackJsonp([4],{
28240
  // handled by other components.
28241
  Module.NewsletterModel = SuperModel.extend({
28242
  whitelisted: ['id', 'subject', 'preheader'],
28243
- initialize: function (options) {
28244
  this.on('change', function () {
28245
  App.getChannel().trigger('autoSave');
28246
  });
@@ -28336,7 +28335,7 @@ webpackJsonp([4],{
28336
 
28337
  /***/ },
28338
 
28339
- /***/ 581:
28340
  /***/ function(module, exports, __webpack_require__) {
28341
 
28342
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
@@ -28370,7 +28369,7 @@ webpackJsonp([4],{
28370
  }
28371
  });
28372
 
28373
- App.on('start', function (App, options) {
28374
  App._appView.showChildView('headingRegion', new Module.HeadingView({ model: App.getNewsletter() }));
28375
  MailPoet.helpTooltip.show(document.getElementById('tooltip-designer-subject-line'), {
28376
  tooltipId: 'tooltip-designer-subject-line-ti',
@@ -28389,12 +28388,12 @@ webpackJsonp([4],{
28389
 
28390
  /***/ },
28391
 
28392
- /***/ 582:
28393
  /***/ function(module, exports, __webpack_require__) {
28394
 
28395
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
28396
  __webpack_require__(574),
28397
- __webpack_require__(579),
28398
  __webpack_require__(274),
28399
  __webpack_require__(556),
28400
  __webpack_require__(535),
@@ -28402,7 +28401,7 @@ webpackJsonp([4],{
28402
  __webpack_require__(273),
28403
  __webpack_require__(568),
28404
  __webpack_require__(569),
28405
- __webpack_require__(583),
28406
  __webpack_require__(278),
28407
  __webpack_require__(273)
28408
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (
@@ -28422,8 +28421,8 @@ webpackJsonp([4],{
28422
 
28423
  'use strict';
28424
 
28425
- var Module = {},
28426
- saveTimeout;
28427
 
28428
  // Save editor contents to server
28429
  Module.save = function () {
@@ -28470,10 +28469,9 @@ webpackJsonp([4],{
28470
  // Temporary workaround for html2canvas-alpha2.
28471
  // Removes 1px left transparent border from resulting canvas.
28472
 
28473
- var oldContext = oldCanvas.getContext('2d'),
28474
- newCanvas = document.createElement('canvas'),
28475
- newContext = newCanvas.getContext('2d'),
28476
- leftBorderWidth = 1;
28477
 
28478
  newCanvas.width = oldCanvas.width;
28479
  newCanvas.height = oldCanvas.height;
@@ -28489,8 +28487,7 @@ webpackJsonp([4],{
28489
  };
28490
 
28491
  Module.saveTemplate = function (options) {
28492
- var that = this,
28493
- promise = jQuery.Deferred();
28494
 
28495
  promise.then(function (thumbnail) {
28496
  var data = _.extend(options || {}, {
@@ -28516,7 +28513,6 @@ webpackJsonp([4],{
28516
  };
28517
 
28518
  Module.exportTemplate = function (options) {
28519
- var that = this;
28520
  return Module.getThumbnail(
28521
  jQuery('#mailpoet_editor_content > .mailpoet_block').get(0)
28522
  ).then(function (thumbnail) {
@@ -28549,7 +28545,7 @@ webpackJsonp([4],{
28549
  'click .mailpoet_save_export': 'toggleExportTemplate',
28550
  'click .mailpoet_export_template': 'exportTemplate'
28551
  },
28552
- initialize: function (options) {
28553
  App.getChannel().on('beforeEditorSave', this.beforeSave, this);
28554
  App.getChannel().on('afterEditorSave', this.afterSave, this);
28555
  },
@@ -28564,7 +28560,7 @@ webpackJsonp([4],{
28564
  // TODO: Add a loading animation instead
28565
  this.$('.mailpoet_autosaved_at').text(MailPoet.I18n.t('saving'));
28566
  },
28567
- afterSave: function (json, response) {
28568
  this.validateNewsletter(json);
28569
  // Update 'Last saved timer'
28570
  this.$('.mailpoet_editor_last_saved').removeClass('mailpoet_hidden');
@@ -28586,9 +28582,9 @@ webpackJsonp([4],{
28586
  this.$('.mailpoet_save_as_template_container').addClass('mailpoet_hidden');
28587
  },
28588
  saveAsTemplate: function () {
28589
- var templateName = this.$('.mailpoet_save_as_template_name').val(),
28590
- templateDescription = this.$('.mailpoet_save_as_template_description').val(),
28591
- that = this;
28592
 
28593
  if (templateName === '') {
28594
  MailPoet.Notice.error(
@@ -28642,9 +28638,9 @@ webpackJsonp([4],{
28642
  this.$('.mailpoet_export_template_container').addClass('mailpoet_hidden');
28643
  },
28644
  exportTemplate: function () {
28645
- var templateName = this.$('.mailpoet_export_template_name').val(),
28646
- templateDescription = this.$('.mailpoet_export_template_description').val(),
28647
- that = this;
28648
 
28649
  if (templateName === '') {
28650
  MailPoet.Notice.error(
@@ -28679,18 +28675,19 @@ webpackJsonp([4],{
28679
  this.hideOptionContents();
28680
  if (!this.$('.mailpoet_save_next').hasClass('button-disabled')) {
28681
  Module._cancelAutosave();
28682
- Module.save().done(function (response) {
28683
  window.location.href = App.getConfig().get('urls.send');
28684
  });
28685
  }
28686
  },
28687
  validateNewsletter: function (jsonObject) {
 
28688
  if (!App._contentContainer.isValid()) {
28689
  this.showValidationError(App._contentContainer.validationError);
28690
  return;
28691
  }
28692
 
28693
- var contents = JSON.stringify(jsonObject);
28694
  if (App.getConfig().get('validation.validateUnsubscribeLinkPresent') &&
28695
  contents.indexOf('[link:subscription_unsubscribe_url]') < 0 &&
28696
  contents.indexOf('[link:subscription_unsubscribe]') < 0) {
@@ -28734,9 +28731,11 @@ webpackJsonp([4],{
28734
  };
28735
 
28736
  Module.beforeExitWithUnsavedChanges = function (e) {
 
 
28737
  if (saveTimeout) {
28738
- var message = MailPoet.I18n.t('unsavedChangesWillBeLost');
28739
- var event = e || window.event;
28740
 
28741
  if (event) {
28742
  event.returnValue = message;
@@ -28746,7 +28745,7 @@ webpackJsonp([4],{
28746
  }
28747
  };
28748
 
28749
- App.on('before:start', function (App, options) {
28750
  var Application = App;
28751
  Application.save = Module.save;
28752
  Application.getChannel().on('autoSave', Module.autoSave);
@@ -28756,7 +28755,7 @@ webpackJsonp([4],{
28756
  Application.getChannel().reply('save', Application.save);
28757
  });
28758
 
28759
- App.on('start', function (App, options) {
28760
  var saveView = new Module.SaveView();
28761
  App._appView.showChildView('bottomRegion', saveView);
28762
  });
@@ -28767,15 +28766,15 @@ webpackJsonp([4],{
28767
 
28768
  /***/ },
28769
 
28770
- /***/ 583:
28771
  /***/ function(module, exports, __webpack_require__) {
28772
 
28773
- /* WEBPACK VAR INJECTION */(function(global) {module.exports = global["html2canvas"] = __webpack_require__(584);
28774
  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
28775
 
28776
  /***/ },
28777
 
28778
- /***/ 584:
28779
  /***/ function(module, exports, __webpack_require__) {
28780
 
28781
  var require;var require;/* WEBPACK VAR INJECTION */(function(global) {/*
@@ -33316,7 +33315,7 @@ webpackJsonp([4],{
33316
 
33317
  /***/ },
33318
 
33319
- /***/ 585:
33320
  /***/ function(module, exports, __webpack_require__) {
33321
 
33322
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -33342,7 +33341,7 @@ webpackJsonp([4],{
33342
 
33343
  /***/ },
33344
 
33345
- /***/ 586:
33346
  /***/ function(module, exports, __webpack_require__) {
33347
 
33348
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -33352,16 +33351,16 @@ webpackJsonp([4],{
33352
  */
33353
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
33354
  __webpack_require__(562),
33355
- __webpack_require__(585),
33356
  __webpack_require__(274),
33357
  __webpack_require__(566)
33358
- ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Marionette, BehaviorsLookup, MailPoet, Spectrum) {
33359
  var BL = BehaviorsLookup;
33360
 
33361
  BL.ColorPickerBehavior = Marionette.Behavior.extend({
33362
  onRender: function () {
33363
- var that = this,
33364
- preferredFormat = 'hex6';
33365
  this.view.$('.mailpoet_color').each(function () {
33366
  var $input = that.view.$(this);
33367
  var updateColorInput = function (color) {
@@ -33396,7 +33395,7 @@ webpackJsonp([4],{
33396
 
33397
  /***/ },
33398
 
33399
- /***/ 587:
33400
  /***/ function(module, exports, __webpack_require__) {
33401
 
33402
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;
@@ -33411,7 +33410,7 @@ webpackJsonp([4],{
33411
  __webpack_require__(562),
33412
  __webpack_require__(278),
33413
  __webpack_require__(273),
33414
- __webpack_require__(585),
33415
  __webpack_require__(565)
33416
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Marionette, _, jQuery, BL, interact) {
33417
  var BehaviorsLookup = BL;
@@ -33426,11 +33425,11 @@ webpackJsonp([4],{
33426
  this.addDropZone();
33427
  }
33428
  },
33429
- addDropZone: function (_event) {
33430
- var that = this,
33431
- view = this.view,
33432
- domElement = that.$el.get(0),
33433
- acceptableElementSelector;
33434
 
33435
  // TODO: Extract this limitation code to be controlled from containers
33436
  if (this.view.renderOptions.depth === 0) {
@@ -33448,11 +33447,11 @@ webpackJsonp([4],{
33448
  interact(domElement).dropzone({
33449
  accept: acceptableElementSelector,
33450
  overlap: 'pointer', // Mouse pointer denotes location of a droppable
33451
- ondragenter: function (event) {
33452
  // 1. Visually mark block as active for dropping
33453
  view.$el.addClass('mailpoet_drop_active');
33454
  },
33455
- ondragleave: function (event) {
33456
  // 1. Remove visual markings of active dropping container
33457
  // 2. Remove visual markings of drop position visualization
33458
  that.cleanup();
@@ -33464,20 +33463,26 @@ webpackJsonp([4],{
33464
  // 3b. If insertion is special, compute position (which side) and which cell the insertion belongs to
33465
  // 4. If insertion at that position is not visualized, display position visualization there, remove other visualizations from this container
33466
  var dropPosition = that.getDropPosition(
33467
- event.dragmove.pageX,
33468
- event.dragmove.pageY,
33469
- view.$el,
33470
- view.model.get('orientation'),
33471
- view.model.get('blocks').length
33472
- ),
33473
- element = view.$el,
33474
- markerWidth = '',
33475
- markerHeight = '',
33476
- containerOffset = element.offset(),
33477
- viewCollection = that.getCollection(),
33478
- marker, targetModel, targetView, targetElement,
33479
- topOffset, leftOffset, isLastBlockInsertion,
33480
- $targetBlock, margin;
 
 
 
 
 
 
33481
 
33482
  if (dropPosition === undefined) return;
33483
 
@@ -33579,15 +33584,19 @@ webpackJsonp([4],{
33579
  // 4. Perform cleanup actions
33580
 
33581
  var dropPosition = that.getDropPosition(
33582
- event.dragEvent.pageX,
33583
- event.dragEvent.pageY,
33584
- view.$el,
33585
- view.model.get('orientation'),
33586
- view.model.get('blocks').length
33587
- ),
33588
- droppableModel = event.draggable.getDropModel(),
33589
- viewCollection = that.getCollection(),
33590
- droppedView, droppedModel, index, tempCollection, tempCollection2;
 
 
 
 
33591
 
33592
  if (dropPosition === undefined) return;
33593
 
@@ -33611,7 +33620,7 @@ webpackJsonp([4],{
33611
  } else {
33612
  // Special insertion by replacing target block with collection
33613
  // and inserting dropModel into that
33614
- var tempModel = viewCollection.at(dropPosition.index);
33615
 
33616
  tempCollection = new (window.EditorApplication.getBlockTypeModel('container'))({
33617
  orientation: (view.model.get('orientation') === 'vertical') ? 'horizontal' : 'vertical'
@@ -33673,26 +33682,30 @@ webpackJsonp([4],{
33673
  this.view.$('.mailpoet_drop_marker').remove();
33674
  },
33675
  getDropPosition: function (eventX, eventY, is_unsafe) {
33676
- var SPECIAL_AREA_INSERTION_WIDTH = 0.00, // Disable special insertion. Default: 0.3
33677
 
33678
- element = this.view.$el,
33679
- orientation = this.view.model.get('orientation'),
33680
 
33681
- elementOffset = element.offset(),
33682
- elementPageX = elementOffset.left,
33683
- elementPageY = elementOffset.top,
33684
- elementWidth = element.outerWidth(true),
33685
- elementHeight = element.outerHeight(true),
33686
 
33687
- relativeX = eventX - elementPageX,
33688
- relativeY = eventY - elementPageY,
33689
 
33690
- relativeOffset, elementLength,
 
33691
 
33692
- canAcceptNormalInsertion = this._canAcceptNormalInsertion(),
33693
- canAcceptSpecialInsertion = this._canAcceptSpecialInsertion(),
33694
 
33695
- insertionType, index, position, indexAndPosition;
 
 
 
33696
 
33697
  var unsafe = !!is_unsafe;
33698
 
@@ -33760,12 +33773,14 @@ webpackJsonp([4],{
33760
  // target element if event happens on the second half of the element.
33761
  // Halves depend on orientation.
33762
 
33763
- var index = this._computeCellIndex(eventX, eventY),
33764
- // TODO: Handle case when there are no children, container is empty
33765
- targetView = this.getChildren().findByModel(this.getCollection().at(index)),
33766
- orientation = this.view.model.get('orientation'),
33767
- element = targetView.$el,
33768
- eventOffset, closeOffset, elementDimension;
 
 
33769
 
33770
  if (orientation === 'vertical') {
33771
  eventOffset = eventY;
@@ -33795,39 +33810,40 @@ webpackJsonp([4],{
33795
  return this._computeCellIndex(eventX, eventY);
33796
  },
33797
  _computeCellIndex: function (eventX, eventY) {
33798
- var orientation = this.view.model.get('orientation'),
33799
- eventOffset = (orientation === 'vertical') ? eventY : eventX,
33800
- resultView = this.getChildren().find(function (view) {
33801
- var element = view.$el,
33802
- closeOffset, farOffset;
33803
-
33804
- if (orientation === 'vertical') {
33805
- closeOffset = element.offset().top;
33806
- farOffset = element.outerHeight(true);
33807
- } else {
33808
- closeOffset = element.offset().left;
33809
- farOffset = element.outerWidth(true);
33810
- }
33811
- farOffset += closeOffset;
 
33812
 
33813
- return closeOffset <= eventOffset && eventOffset <= farOffset;
33814
- });
33815
 
33816
  var index = (typeof resultView === 'object') ? resultView._index : 0;
33817
 
33818
  return index;
33819
  },
33820
  _canAcceptNormalInsertion: function () {
33821
- var orientation = this.view.model.get('orientation'),
33822
- depth = this.view.renderOptions.depth,
33823
- childCount = this.getChildren().length;
33824
  // Note that depth is zero indexed. Root container has depth=0
33825
  return orientation === 'vertical' || (orientation === 'horizontal' && depth === 1 && childCount < this.options.columnLimit);
33826
  },
33827
  _canAcceptSpecialInsertion: function () {
33828
- var orientation = this.view.model.get('orientation'),
33829
- depth = this.view.renderOptions.depth,
33830
- childCount = this.getChildren().length;
33831
  return depth === 0 || (depth === 1 && orientation === 'horizontal' && childCount <= this.options.columnLimit);
33832
  },
33833
  getCollectionView: function () {
@@ -33845,7 +33861,7 @@ webpackJsonp([4],{
33845
 
33846
  /***/ },
33847
 
33848
- /***/ 588:
33849
  /***/ function(module, exports, __webpack_require__) {
33850
 
33851
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -33858,7 +33874,7 @@ webpackJsonp([4],{
33858
  __webpack_require__(562),
33859
  __webpack_require__(278),
33860
  __webpack_require__(273),
33861
- __webpack_require__(585),
33862
  __webpack_require__(565)
33863
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Marionette, _, jQuery, BehaviorsLookup, interact) {
33864
  var BL = BehaviorsLookup;
@@ -33878,12 +33894,12 @@ webpackJsonp([4],{
33878
  throw "Missing 'drop' function for DraggableBehavior";
33879
  },
33880
 
33881
- onDrop: function (model, view) {},
33882
- testAttachToInstance: function (model, view) { return true; }
33883
  },
33884
  onRender: function () {
33885
- var that = this,
33886
- interactable;
33887
 
33888
  // Give instances more control over whether Draggable should be applied
33889
  if (!this.options.testAttachToInstance(this.view.model, this.view)) return;
@@ -33899,16 +33915,19 @@ webpackJsonp([4],{
33899
 
33900
  onstart: function (startEvent) {
33901
  var event = startEvent;
 
 
 
 
 
33902
 
33903
  if (that.options.cloneOriginal === true) {
33904
  // Use substitution instead of a clone
33905
- var tempClone = (_.isFunction(that.options.onDragSubstituteBy)) ? that.options.onDragSubstituteBy(that) : undefined,
33906
- // Or use a clone
33907
- clone = tempClone || event.target.cloneNode(true),
33908
-
33909
- $original = jQuery(event.target),
33910
- $clone = jQuery(clone),
33911
- centerXOffset, centerYOffset, parentOffset;
33912
 
33913
  $clone.addClass('mailpoet_droppable_active');
33914
  $clone.css('position', 'absolute');
@@ -33935,10 +33954,10 @@ webpackJsonp([4],{
33935
  },
33936
  // call this function on every dragmove event
33937
  onmove: function (event) {
33938
- var target = event.target,
33939
- // keep the dragged position in the data-x/data-y attributes
33940
- x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx,
33941
- y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
33942
 
33943
  // translate the element
33944
  target.style.transform = 'translate(' + x + 'px, ' + y + 'px)';
@@ -33997,7 +34016,7 @@ webpackJsonp([4],{
33997
 
33998
  /***/ },
33999
 
34000
- /***/ 589:
34001
  /***/ function(module, exports, __webpack_require__) {
34002
 
34003
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -34007,7 +34026,7 @@ webpackJsonp([4],{
34007
  */
34008
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
34009
  __webpack_require__(562),
34010
- __webpack_require__(585)
34011
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Marionette, BehaviorsLookup) {
34012
  var BL = BehaviorsLookup;
34013
 
@@ -34030,7 +34049,7 @@ webpackJsonp([4],{
34030
 
34031
  /***/ },
34032
 
34033
- /***/ 590:
34034
  /***/ function(module, exports, __webpack_require__) {
34035
 
34036
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -34040,7 +34059,7 @@ webpackJsonp([4],{
34040
  */
34041
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
34042
  __webpack_require__(562),
34043
- __webpack_require__(585)
34044
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Marionette, BehaviorsLookup) {
34045
  var BL = BehaviorsLookup;
34046
 
@@ -34063,7 +34082,7 @@ webpackJsonp([4],{
34063
 
34064
  /***/ },
34065
 
34066
- /***/ 591:
34067
  /***/ function(module, exports, __webpack_require__) {
34068
 
34069
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -34073,7 +34092,7 @@ webpackJsonp([4],{
34073
  */
34074
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
34075
  __webpack_require__(562),
34076
- __webpack_require__(585),
34077
  __webpack_require__(565)
34078
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Marionette, BehaviorsLookup, interact) {
34079
  var BL = BehaviorsLookup;
@@ -34087,8 +34106,8 @@ webpackJsonp([4],{
34087
  maxLength: Infinity,
34088
  modelField: 'styles.block.height',
34089
  onResize: function (event) {
34090
- var currentLength = parseFloat(this.view.model.get(this.options.modelField)),
34091
- newLength = currentLength + this.options.transformationFunction(event.dy);
34092
  newLength = Math.min(this.options.maxLength, Math.max(this.options.minLength, newLength));
34093
  this.view.model.set(this.options.modelField, newLength + 'px');
34094
  }
@@ -34105,8 +34124,8 @@ webpackJsonp([4],{
34105
  }
34106
  },
34107
  attachResize: function () {
34108
- var domElement = (this.options.elementSelector === null) ? this.view.$el.get(0) : this.view.$(this.options.elementSelector).get(0),
34109
- that = this;
34110
  interact(domElement).resizable({
34111
  // axis: 'y',
34112
  edges: {
@@ -34116,7 +34135,7 @@ webpackJsonp([4],{
34116
  bottom: (typeof this.options.resizeHandleSelector === 'string') ? this.view.$(this.options.resizeHandleSelector).get(0) : this.options.resizeHandleSelector
34117
  }
34118
  })
34119
- .on('resizestart', function (event) {
34120
  that.isBeingResized = true;
34121
  that.$el.addClass('mailpoet_resize_active');
34122
  })
@@ -34124,7 +34143,7 @@ webpackJsonp([4],{
34124
  var onResize = that.options.onResize.bind(that);
34125
  return onResize(event);
34126
  })
34127
- .on('resizeend', function (event) {
34128
  that.isBeingResized = null;
34129
  that.$el.removeClass('mailpoet_resize_active');
34130
  });
@@ -34145,7 +34164,7 @@ webpackJsonp([4],{
34145
 
34146
  /***/ },
34147
 
34148
- /***/ 592:
34149
  /***/ function(module, exports, __webpack_require__) {
34150
 
34151
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -34156,7 +34175,7 @@ webpackJsonp([4],{
34156
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
34157
  __webpack_require__(562),
34158
  __webpack_require__(278),
34159
- __webpack_require__(585)
34160
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Marionette, _, BehaviorsLookup) {
34161
  var BL = BehaviorsLookup;
34162
 
@@ -34174,9 +34193,9 @@ webpackJsonp([4],{
34174
  ui.item.removeData('previousIndex');
34175
  },
34176
  update: function (event, ui) {
34177
- var previousIndex = ui.item.data('previousIndex'),
34178
- newIndex = ui.item.index(),
34179
- model = collection.at(previousIndex);
34180
 
34181
  // Replicate DOM changes. Move target model to a new position
34182
  // within the collection
@@ -34193,7 +34212,7 @@ webpackJsonp([4],{
34193
 
34194
  /***/ },
34195
 
34196
- /***/ 593:
34197
  /***/ function(module, exports, __webpack_require__) {
34198
 
34199
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -34204,7 +34223,7 @@ webpackJsonp([4],{
34204
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
34205
  __webpack_require__(562),
34206
  __webpack_require__(273),
34207
- __webpack_require__(585)
34208
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Marionette, jQuery, BehaviorsLookup) {
34209
  var BL = BehaviorsLookup;
34210
 
@@ -34232,7 +34251,7 @@ webpackJsonp([4],{
34232
 
34233
  /***/ },
34234
 
34235
- /***/ 594:
34236
  /***/ function(module, exports, __webpack_require__) {
34237
 
34238
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -34243,7 +34262,7 @@ webpackJsonp([4],{
34243
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
34244
  __webpack_require__(562),
34245
  __webpack_require__(278),
34246
- __webpack_require__(585)
34247
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Marionette, _, BehaviorsLookup) {
34248
  var BL = BehaviorsLookup;
34249
 
@@ -34279,7 +34298,7 @@ webpackJsonp([4],{
34279
  relative_urls: false,
34280
  remove_script_host: false,
34281
  convert_urls: true,
34282
- urlconverter_callback: function (url, node, on_save, name) {
34283
  if (url.match(/\[.+\]/g)) {
34284
  // Do not convert URLs with shortcodes
34285
  return url;
@@ -34294,7 +34313,7 @@ webpackJsonp([4],{
34294
  plugins: this.options.plugins,
34295
 
34296
  setup: function (editor) {
34297
- editor.on('change', function (e) {
34298
  that.view.triggerMethod('text:editor:change', editor.getContent());
34299
  });
34300
 
@@ -34308,12 +34327,12 @@ webpackJsonp([4],{
34308
  }
34309
  });
34310
 
34311
- editor.on('focus', function (e) {
34312
  that.view.triggerMethod('text:editor:focus');
34313
  that._isActivationClick = true;
34314
  });
34315
 
34316
- editor.on('blur', function (e) {
34317
  that.view.triggerMethod('text:editor:blur');
34318
  });
34319
  }
@@ -34325,7 +34344,7 @@ webpackJsonp([4],{
34325
 
34326
  /***/ },
34327
 
34328
- /***/ 595:
34329
  /***/ function(module, exports, __webpack_require__) {
34330
 
34331
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -34342,17 +34361,16 @@ webpackJsonp([4],{
34342
  __webpack_require__(273),
34343
  __webpack_require__(274),
34344
  __webpack_require__(555)
34345
- ], __WEBPACK_AMD_DEFINE_RESULT__ = function (App, Marionette, SuperModel, _, jQuery, MailPoet, Modal) {
34346
 
34347
  'use strict';
34348
 
34349
- var Module = {},
34350
- AugmentedView = Marionette.View.extend({});
34351
 
34352
  Module.BlockModel = SuperModel.extend({
34353
  stale: [], // Attributes to be removed upon saving
34354
  initialize: function () {
34355
- var that = this;
34356
  this.on('change', function () {
34357
  App.getChannel().trigger('autoSave');
34358
  });
@@ -34398,7 +34416,8 @@ webpackJsonp([4],{
34398
  options.dragBehavior.view.model.destroy();
34399
  },
34400
  onDragSubstituteBy: function (behavior) {
34401
- var WidgetView, node;
 
34402
  // When block is being dragged, display the widget icon instead.
34403
  // This will create an instance of block's widget view and
34404
  // use it's rendered DOM element instead of the content block
@@ -34428,13 +34447,13 @@ webpackJsonp([4],{
34428
  this.on('dom:refresh', this.showBlock, this);
34429
  this._isFirstRender = true;
34430
  },
34431
- showTools: function (_event) {
34432
  if (!this.showingToolsDisabled) {
34433
  this.$('> .mailpoet_tools').addClass('mailpoet_display_tools');
34434
  this.toolsView.triggerMethod('showTools');
34435
  }
34436
  },
34437
- hideTools: function (e) {
34438
  this.$('> .mailpoet_tools').removeClass('mailpoet_display_tools');
34439
  this.toolsView.triggerMethod('hideTools');
34440
  },
@@ -34570,8 +34589,9 @@ webpackJsonp([4],{
34570
  ColorPickerBehavior: {}
34571
  },
34572
  initialize: function (params) {
 
34573
  this.model.trigger('startEditing');
34574
- var panelParams = {
34575
  element: this.$el,
34576
  template: '',
34577
  position: 'right',
@@ -34592,7 +34612,7 @@ webpackJsonp([4],{
34592
  model: this.model.toJSON()
34593
  };
34594
  },
34595
- close: function (event) {
34596
  this.destroy();
34597
  },
34598
  changeField: function (field, event) {
@@ -34640,7 +34660,7 @@ webpackJsonp([4],{
34640
 
34641
  /***/ },
34642
 
34643
- /***/ 596:
34644
  /***/ function(module, exports, __webpack_require__) {
34645
 
34646
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -34654,14 +34674,14 @@ webpackJsonp([4],{
34654
  __webpack_require__(278),
34655
  __webpack_require__(273),
34656
  __webpack_require__(574),
34657
- __webpack_require__(595)
34658
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Backbone, Marionette, _, jQuery, App, BaseBlock) {
34659
 
34660
  'use strict';
34661
 
34662
- var Module = {},
34663
- base = BaseBlock,
34664
- BlockCollection;
34665
 
34666
  BlockCollection = Backbone.Collection.extend({
34667
  model: base.BlockModel,
@@ -34669,7 +34689,6 @@ webpackJsonp([4],{
34669
  this.on('add change remove', function () { App.getChannel().trigger('autoSave'); });
34670
  },
34671
  parse: function (response) {
34672
- var self = this;
34673
  return _.map(response, function (block) {
34674
  var Type = App.getBlockTypeModel(block.type);
34675
  // TODO: If type has no registered model, use a backup one
@@ -34711,7 +34730,7 @@ webpackJsonp([4],{
34711
  return response;
34712
  },
34713
  getChildren: function () {
34714
- var models = this.get('blocks').map(function (model, index, list) {
34715
  return [model, model.getChildren()];
34716
  });
34717
 
@@ -34766,7 +34785,8 @@ webpackJsonp([4],{
34766
  options.dragBehavior.view.model.destroy();
34767
  },
34768
  onDragSubstituteBy: function (behavior) {
34769
- var WidgetView, node;
 
34770
  // When block is being dragged, display the widget icon instead.
34771
  // This will create an instance of block's widget view and
34772
  // use it's rendered DOM element instead of the content block
@@ -34835,24 +34855,24 @@ webpackJsonp([4],{
34835
  }
34836
  },
34837
  toggleEditingLayer: function (event) {
34838
- var that = this,
34839
- $toggleButton = this.$('> .mailpoet_tools .mailpoet_newsletter_layer_selector'),
34840
- $overlay = jQuery('.mailpoet_layer_overlay'),
34841
- $container = this.$('> .mailpoet_container'),
34842
- enableContainerLayer = function () {
34843
- that.$el.addClass('mailpoet_container_layer_active');
34844
- $toggleButton.addClass('mailpoet_container_layer_active');
34845
- $container.addClass('mailpoet_layer_highlight');
34846
- $overlay.click(disableContainerLayer);
34847
- $overlay.show();
34848
- },
34849
- disableContainerLayer = function () {
34850
- that.$el.removeClass('mailpoet_container_layer_active');
34851
- $toggleButton.removeClass('mailpoet_container_layer_active');
34852
- $container.removeClass('mailpoet_layer_highlight');
34853
- $overlay.hide();
34854
- $overlay.off('click');
34855
- };
34856
  if ($toggleButton.hasClass('mailpoet_container_layer_active')) {
34857
  disableContainerLayer();
34858
  } else {
@@ -34981,7 +35001,7 @@ webpackJsonp([4],{
34981
  }
34982
  });
34983
 
34984
- App.on('before:start', function (App, options) {
34985
  App.registerBlockType('container', {
34986
  blockModel: Module.ContainerBlockModel,
34987
  blockView: Module.ContainerBlockView
@@ -35012,7 +35032,7 @@ webpackJsonp([4],{
35012
 
35013
  /***/ },
35014
 
35015
- /***/ 597:
35016
  /***/ function(module, exports, __webpack_require__) {
35017
 
35018
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -35020,7 +35040,7 @@ webpackJsonp([4],{
35020
  */
35021
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
35022
  __webpack_require__(574),
35023
- __webpack_require__(595),
35024
  __webpack_require__(274),
35025
  __webpack_require__(278),
35026
  __webpack_require__(273)
@@ -35028,8 +35048,8 @@ webpackJsonp([4],{
35028
 
35029
  'use strict';
35030
 
35031
- var Module = {},
35032
- base = BaseBlock;
35033
 
35034
  Module.ButtonBlockModel = base.BlockModel.extend({
35035
  defaults: function () {
@@ -35149,7 +35169,7 @@ webpackJsonp([4],{
35149
  }
35150
  });
35151
 
35152
- App.on('before:start', function (App, options) {
35153
  App.registerBlockType('button', {
35154
  blockModel: Module.ButtonBlockModel,
35155
  blockView: Module.ButtonBlockView
@@ -35168,7 +35188,7 @@ webpackJsonp([4],{
35168
 
35169
  /***/ },
35170
 
35171
- /***/ 598:
35172
  /***/ function(module, exports, __webpack_require__) {
35173
 
35174
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -35176,7 +35196,7 @@ webpackJsonp([4],{
35176
  */
35177
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
35178
  __webpack_require__(574),
35179
- __webpack_require__(595),
35180
  __webpack_require__(278),
35181
  __webpack_require__(274),
35182
  __webpack_require__(273)
@@ -35184,9 +35204,9 @@ webpackJsonp([4],{
35184
 
35185
  'use strict';
35186
 
35187
- var Module = {},
35188
- base = BaseBlock,
35189
- ImageWidgetView;
35190
 
35191
  Module.ImageBlockModel = base.BlockModel.extend({
35192
  defaults: function () {
@@ -35221,8 +35241,8 @@ webpackJsonp([4],{
35221
  elementSelector: '.mailpoet_image',
35222
  resizeHandleSelector: '.mailpoet_image_resize_handle',
35223
  onResize: function (event) {
35224
- var corner = this.$('.mailpoet_image').offset(),
35225
- width = event.pageX - corner.left;
35226
  this.view.model.set('width', width + 'px');
35227
  }
35228
  },
@@ -35300,13 +35320,16 @@ webpackJsonp([4],{
35300
  }
35301
  },
35302
  showMediaManager: function () {
 
 
 
35303
  if (this._mediaManager) {
35304
  this._mediaManager.resetSelections();
35305
  this._mediaManager.open();
35306
  return;
35307
  }
35308
 
35309
- var MediaManager = window.wp.media.view.MediaFrame.Select.extend({
35310
 
35311
  initialize: function () {
35312
  window.wp.media.view.MediaFrame.prototype.initialize.apply(this, arguments);
@@ -35369,6 +35392,7 @@ webpackJsonp([4],{
35369
  },
35370
 
35371
  bindHandlers: function () {
 
35372
  // from Select
35373
  this.on('router:create:browse', this.createRouter, this);
35374
  this.on('router:render:browse', this.browseRouter, this);
@@ -35383,7 +35407,7 @@ webpackJsonp([4],{
35383
 
35384
  this.on('updateExcluded', this.browseContent, this);
35385
 
35386
- var handlers = {
35387
  content: {
35388
  embed: 'embedContent',
35389
  'edit-selection': 'editSelectionContent'
@@ -35417,9 +35441,9 @@ webpackJsonp([4],{
35417
  },
35418
 
35419
  editSelectionContent: function () {
35420
- var state = this.state(),
35421
- selection = state.get('selection'),
35422
- view;
35423
 
35424
  view = new window.wp.media.view.AttachmentsBrowser({
35425
  controller: this,
@@ -35475,8 +35499,8 @@ webpackJsonp([4],{
35475
  requires: { selection: true },
35476
 
35477
  click: function () {
35478
- var state = controller.state(),
35479
- selection = state.get('selection');
35480
 
35481
  controller.close();
35482
  state.trigger('insert', selection).reset();
@@ -35494,46 +35518,42 @@ webpackJsonp([4],{
35494
 
35495
  });
35496
 
35497
- var theFrame = new MediaManager({
35498
- id: 'mailpoet-media-manager',
35499
- frame: 'select',
35500
- title: 'Select image',
35501
- editing: false,
35502
- multiple: false,
35503
- library: {
35504
- type: 'image'
35505
- },
35506
- displaySettings: false,
35507
- button: {
35508
- text: 'Select'
35509
- }
35510
- }),
35511
- that = this;
35512
  this._mediaManager = theFrame;
35513
 
35514
  this._mediaManager.on('insert', function () {
35515
  // Append media manager image selections to Images tab
35516
  var selection = theFrame.state().get('selection');
35517
  selection.each(function (attachment) {
35518
- var sizes = attachment.get('sizes'),
35519
- // Following advice from Becs, the target width should
35520
- // be a double of one column width to render well on
35521
- // retina screen devices
35522
- targetImageWidth = 1320,
35523
-
35524
- // For main image use the size, that's closest to being 660px in width
35525
- sizeKeys = _.keys(sizes),
35526
-
35527
- // Pick the width that is closest to target width
35528
- increasingByWidthDifference = _.sortBy(
35529
- _.keys(sizes),
35530
- function (size) { return Math.abs(targetImageWidth - sizes[size].width); }
35531
- ),
35532
- bestWidth = sizes[_.first(increasingByWidthDifference)].width,
35533
- imagesOfBestWidth = _.filter(_.values(sizes), function (size) { return size.width === bestWidth; }),
35534
-
35535
- // Maximize the height if there are multiple images with same width
35536
- mainSize = _.max(imagesOfBestWidth, function (size) { return size.height; });
35537
 
35538
  that.model.set({
35539
  height: mainSize.height + 'px',
@@ -35586,7 +35606,7 @@ webpackJsonp([4],{
35586
  });
35587
  Module.ImageWidgetView = ImageWidgetView;
35588
 
35589
- App.on('before:start', function (App, options) {
35590
  App.registerBlockType('image', {
35591
  blockModel: Module.ImageBlockModel,
35592
  blockView: Module.ImageBlockView
@@ -35605,7 +35625,7 @@ webpackJsonp([4],{
35605
 
35606
  /***/ },
35607
 
35608
- /***/ 599:
35609
  /***/ function(module, exports, __webpack_require__) {
35610
 
35611
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -35613,16 +35633,15 @@ webpackJsonp([4],{
35613
  */
35614
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
35615
  __webpack_require__(574),
35616
- __webpack_require__(595),
35617
  __webpack_require__(278),
35618
- __webpack_require__(273),
35619
- __webpack_require__(274)
35620
- ], __WEBPACK_AMD_DEFINE_RESULT__ = function (App, BaseBlock, _, jQuery, MailPoet) {
35621
 
35622
  'use strict';
35623
 
35624
- var Module = {},
35625
- base = BaseBlock;
35626
 
35627
  Module.DividerBlockModel = base.BlockModel.extend({
35628
  defaults: function () {
@@ -35659,8 +35678,8 @@ webpackJsonp([4],{
35659
  }, base.BlockView.prototype.behaviors),
35660
  onDragSubstituteBy: function () { return Module.DividerWidgetView; },
35661
  initialize: function () {
35662
- base.BlockView.prototype.initialize.apply(this, arguments);
35663
  var that = this;
 
35664
 
35665
  // Listen for attempts to change all dividers in one go
35666
  this._replaceDividerHandler = function (data) { that.model.set(data); that.model.trigger('applyToAll'); };
@@ -35729,7 +35748,7 @@ webpackJsonp([4],{
35729
  repaintDividerStyleOptions: function () {
35730
  this.$('.mailpoet_field_divider_style > div').css('border-top-color', this.model.get('styles.block.borderColor'));
35731
  },
35732
- applyToAll: function (event) {
35733
  App.getChannel().trigger('replaceAllDividers', this.model.toJSON());
35734
  },
35735
  updateValueAndCall: function (fieldToUpdate, callable, event) {
@@ -35749,7 +35768,7 @@ webpackJsonp([4],{
35749
  }
35750
  }
35751
  });
35752
- App.on('before:start', function (App, options) {
35753
  App.registerBlockType('divider', {
35754
  blockModel: Module.DividerBlockModel,
35755
  blockView: Module.DividerBlockView
@@ -35768,7 +35787,7 @@ webpackJsonp([4],{
35768
 
35769
  /***/ },
35770
 
35771
- /***/ 600:
35772
  /***/ function(module, exports, __webpack_require__) {
35773
 
35774
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -35776,15 +35795,15 @@ webpackJsonp([4],{
35776
  */
35777
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
35778
  __webpack_require__(574),
35779
- __webpack_require__(595),
35780
  __webpack_require__(278),
35781
  __webpack_require__(274)
35782
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (App, BaseBlock, _, MailPoet) {
35783
 
35784
  'use strict';
35785
 
35786
- var Module = {},
35787
- base = BaseBlock;
35788
 
35789
  Module.TextBlockModel = base.BlockModel.extend({
35790
  defaults: function () {
@@ -35867,7 +35886,7 @@ webpackJsonp([4],{
35867
  }
35868
  });
35869
 
35870
- App.on('before:start', function (App, options) {
35871
  App.registerBlockType('text', {
35872
  blockModel: Module.TextBlockModel,
35873
  blockView: Module.TextBlockView
@@ -35887,7 +35906,7 @@ webpackJsonp([4],{
35887
 
35888
  /***/ },
35889
 
35890
- /***/ 601:
35891
  /***/ function(module, exports, __webpack_require__) {
35892
 
35893
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -35895,14 +35914,14 @@ webpackJsonp([4],{
35895
  */
35896
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
35897
  __webpack_require__(574),
35898
- __webpack_require__(595),
35899
  __webpack_require__(278)
35900
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (App, BaseBlock, _) {
35901
 
35902
  'use strict';
35903
 
35904
- var Module = {},
35905
- base = BaseBlock;
35906
 
35907
  Module.SpacerBlockModel = base.BlockModel.extend({
35908
  defaults: function () {
@@ -35979,7 +35998,7 @@ webpackJsonp([4],{
35979
  }
35980
  });
35981
 
35982
- App.on('before:start', function (App, options) {
35983
  App.registerBlockType('spacer', {
35984
  blockModel: Module.SpacerBlockModel,
35985
  blockView: Module.SpacerBlockView
@@ -35998,7 +36017,7 @@ webpackJsonp([4],{
35998
 
35999
  /***/ },
36000
 
36001
- /***/ 602:
36002
  /***/ function(module, exports, __webpack_require__) {
36003
 
36004
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -36006,15 +36025,15 @@ webpackJsonp([4],{
36006
  */
36007
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
36008
  __webpack_require__(574),
36009
- __webpack_require__(595),
36010
  __webpack_require__(278),
36011
  __webpack_require__(274)
36012
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (App, BaseBlock, _, MailPoet) {
36013
 
36014
  'use strict';
36015
 
36016
- var Module = {},
36017
- base = BaseBlock;
36018
 
36019
  Module.FooterBlockModel = base.BlockModel.extend({
36020
  defaults: function () {
@@ -36113,7 +36132,7 @@ webpackJsonp([4],{
36113
  }
36114
  });
36115
 
36116
- App.on('before:start', function (App, options) {
36117
  App.registerBlockType('footer', {
36118
  blockModel: Module.FooterBlockModel,
36119
  blockView: Module.FooterBlockView
@@ -36132,7 +36151,7 @@ webpackJsonp([4],{
36132
 
36133
  /***/ },
36134
 
36135
- /***/ 603:
36136
  /***/ function(module, exports, __webpack_require__) {
36137
 
36138
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -36140,15 +36159,15 @@ webpackJsonp([4],{
36140
  */
36141
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
36142
  __webpack_require__(574),
36143
- __webpack_require__(595),
36144
  __webpack_require__(278),
36145
  __webpack_require__(274)
36146
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (App, BaseBlock, _, MailPoet) {
36147
 
36148
  'use strict';
36149
 
36150
- var Module = {},
36151
- base = BaseBlock;
36152
 
36153
  Module.HeaderBlockModel = base.BlockModel.extend({
36154
  defaults: function () {
@@ -36247,7 +36266,7 @@ webpackJsonp([4],{
36247
  }
36248
  });
36249
 
36250
- App.on('before:start', function (App, options) {
36251
  App.registerBlockType('header', {
36252
  blockModel: Module.HeaderBlockModel,
36253
  blockView: Module.HeaderBlockView
@@ -36266,7 +36285,7 @@ webpackJsonp([4],{
36266
 
36267
  /***/ },
36268
 
36269
- /***/ 604:
36270
  /***/ function(module, exports, __webpack_require__) {
36271
 
36272
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -36279,10 +36298,10 @@ webpackJsonp([4],{
36279
  */
36280
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
36281
  __webpack_require__(574),
36282
- __webpack_require__(595),
36283
- __webpack_require__(597),
36284
- __webpack_require__(599),
36285
- __webpack_require__(579),
36286
  __webpack_require__(274),
36287
  __webpack_require__(564),
36288
  __webpack_require__(278),
@@ -36301,8 +36320,8 @@ webpackJsonp([4],{
36301
 
36302
  'use strict';
36303
 
36304
- var Module = {},
36305
- base = BaseBlock;
36306
 
36307
  Module.ALCSupervisor = SuperModel.extend({
36308
  initialize: function () {
@@ -36314,12 +36333,13 @@ webpackJsonp([4],{
36314
  );
36315
  },
36316
  refresh: function () {
 
36317
  var models = App.findModels(function (model) {
36318
  return model.get('type') === 'automatedLatestContent';
36319
  }) || [];
36320
 
36321
  if (models.length === 0) return;
36322
- var blocks = _.map(models, function (model) {
36323
  return model.toJSON();
36324
  });
36325
 
@@ -36331,8 +36351,8 @@ webpackJsonp([4],{
36331
  _.each(
36332
  _.zip(models, renderedBlocks),
36333
  function (args) {
36334
- var model = args[0],
36335
- contents = args[1];
36336
  model.trigger('refreshPosts', contents);
36337
  }
36338
  );
@@ -36421,12 +36441,12 @@ webpackJsonp([4],{
36421
  }),
36422
  onDragSubstituteBy: function () { return Module.AutomatedLatestContentWidgetView; },
36423
  onRender: function () {
36424
- var ContainerView = App.getBlockTypeView('container'),
36425
- renderOptions = {
36426
- disableTextEditor: true,
36427
- disableDragAndDrop: true,
36428
- emptyContainerMessage: MailPoet.I18n.t('noPostsToDisplay')
36429
- };
36430
  this.toolsView = new Module.AutomatedLatestContentBlockToolsView({ model: this.model });
36431
  this.showChildView('toolsRegion', this.toolsView);
36432
  this.showChildView('postsRegion', new ContainerView({ model: this.model.get('_container'), renderOptions: renderOptions }));
@@ -36484,12 +36504,13 @@ webpackJsonp([4],{
36484
  },
36485
  transport: function (options, success, failure) {
36486
  var taxonomies;
 
36487
  var promise = CommunicationComponent.getTaxonomies(
36488
  that.model.get('contentType')
36489
  ).then(function (tax) {
36490
  taxonomies = tax;
36491
  // Fetch available terms based on the list of taxonomies already fetched
36492
- var promise = CommunicationComponent.getTerms({
36493
  search: options.data.term,
36494
  taxonomies: _.keys(taxonomies)
36495
  }).then(function (terms) {
@@ -36498,7 +36519,7 @@ webpackJsonp([4],{
36498
  terms: terms
36499
  };
36500
  });
36501
- return promise;
36502
  });
36503
 
36504
  promise.then(success);
@@ -36535,9 +36556,9 @@ webpackJsonp([4],{
36535
  }
36536
  }).trigger('change');
36537
  },
36538
- toggleDisplayOptions: function (event) {
36539
- var el = this.$('.mailpoet_automated_latest_content_display_options'),
36540
- showControl = this.$('.mailpoet_automated_latest_content_show_display_options');
36541
  if (el.hasClass('mailpoet_closed')) {
36542
  el.removeClass('mailpoet_closed');
36543
  showControl.addClass('mailpoet_hidden');
@@ -36546,7 +36567,7 @@ webpackJsonp([4],{
36546
  showControl.removeClass('mailpoet_hidden');
36547
  }
36548
  },
36549
- showButtonSettings: function (event) {
36550
  var buttonModule = ButtonBlock;
36551
  (new buttonModule.ButtonBlockSettingsView({
36552
  model: this.model.get('readMoreButton'),
@@ -36557,7 +36578,7 @@ webpackJsonp([4],{
36557
  }
36558
  })).render();
36559
  },
36560
- showDividerSettings: function (event) {
36561
  var dividerModule = DividerBlock;
36562
  (new dividerModule.DividerBlockSettingsView({
36563
  model: this.model.get('divider'),
@@ -36620,8 +36641,8 @@ webpackJsonp([4],{
36620
  this.changeField('titleFormat', event);
36621
  },
36622
  _updateContentTypes: function (postTypes) {
36623
- var select = this.$('.mailpoet_automated_latest_content_content_type'),
36624
- selectedValue = this.model.get('contentType');
36625
 
36626
  select.find('option').remove();
36627
  _.each(postTypes, function (type) {
@@ -36649,7 +36670,7 @@ webpackJsonp([4],{
36649
  }
36650
  });
36651
 
36652
- App.on('before:start', function (App, options) {
36653
  App.registerBlockType('automatedLatestContent', {
36654
  blockModel: Module.AutomatedLatestContentBlockModel,
36655
  blockView: Module.AutomatedLatestContentBlockView
@@ -36662,7 +36683,7 @@ webpackJsonp([4],{
36662
  });
36663
  });
36664
 
36665
- App.on('start', function (App, options) {
36666
  var Application = App;
36667
  Application._ALCSupervisor = new Module.ALCSupervisor();
36668
  Application._ALCSupervisor.refresh();
@@ -36674,7 +36695,7 @@ webpackJsonp([4],{
36674
 
36675
  /***/ },
36676
 
36677
- /***/ 605:
36678
  /***/ function(module, exports, __webpack_require__) {
36679
 
36680
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -36697,10 +36718,10 @@ webpackJsonp([4],{
36697
  __webpack_require__(273),
36698
  __webpack_require__(274),
36699
  __webpack_require__(574),
36700
- __webpack_require__(579),
36701
- __webpack_require__(595),
36702
- __webpack_require__(597),
36703
- __webpack_require__(599),
36704
  __webpack_require__(287)
36705
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (
36706
  Backbone,
@@ -36718,8 +36739,13 @@ webpackJsonp([4],{
36718
 
36719
  'use strict';
36720
 
36721
- var Module = {},
36722
- base = BaseBlock;
 
 
 
 
 
36723
 
36724
  Module.PostsBlockModel = base.BlockModel.extend({
36725
  stale: ['_selectedPosts', '_availablePosts', '_transformedPosts'],
@@ -36768,10 +36794,9 @@ webpackJsonp([4],{
36768
  };
36769
  },
36770
  initialize: function () {
36771
- var that = this,
36772
- POST_REFRESH_DELAY_MS = 500,
36773
- refreshAvailablePosts = _.debounce(this.fetchAvailablePosts.bind(this), POST_REFRESH_DELAY_MS),
36774
- refreshTransformedPosts = _.debounce(this._refreshTransformedPosts.bind(this), POST_REFRESH_DELAY_MS);
36775
 
36776
  // Attach Radio.Requests API primarily for highlighting
36777
  _.extend(this, Radio.Requests);
@@ -36799,9 +36824,9 @@ webpackJsonp([4],{
36799
  });
36800
  },
36801
  _loadMorePosts: function () {
36802
- var that = this,
36803
- postCount = this.get('_availablePosts').length,
36804
- nextOffset = this.get('offset') + Number(this.get('amount'));
36805
 
36806
  if (postCount === 0 || postCount < nextOffset) {
36807
  // No more posts to load
@@ -36820,8 +36845,8 @@ webpackJsonp([4],{
36820
  });
36821
  },
36822
  _refreshTransformedPosts: function () {
36823
- var that = this,
36824
- data = this.toJSON();
36825
 
36826
  data.posts = this.get('_selectedPosts').pluck('ID');
36827
 
@@ -36837,10 +36862,9 @@ webpackJsonp([4],{
36837
  });
36838
  },
36839
  _insertSelectedPosts: function () {
36840
- var that = this,
36841
- data = this.toJSON(),
36842
- index = this.collection.indexOf(this),
36843
- collection = this.collection;
36844
 
36845
  data.posts = this.get('_selectedPosts').pluck('ID');
36846
 
@@ -36869,17 +36893,19 @@ webpackJsonp([4],{
36869
  this.model.reply('blockView', this.notifyAboutSelf, this);
36870
  },
36871
  onRender: function () {
 
 
36872
  if (!this.getRegion('toolsRegion').hasView()) {
36873
  this.showChildView('toolsRegion', this.toolsView);
36874
  }
36875
  this.trigger('showSettings');
36876
 
36877
- var ContainerView = App.getBlockTypeView('container'),
36878
- renderOptions = {
36879
- disableTextEditor: true,
36880
- disableDragAndDrop: true,
36881
- emptyContainerMessage: MailPoet.I18n.t('noPostsToDisplay')
36882
- };
36883
  this.showChildView('postsRegion', new ContainerView({ model: this.model.get('_transformedPosts'), renderOptions: renderOptions }));
36884
  },
36885
  notifyAboutSelf: function () {
@@ -36916,8 +36942,8 @@ webpackJsonp([4],{
36916
  this.displayOptionsView = new PostsDisplayOptionsSettingsView({ model: this.model });
36917
  },
36918
  onRender: function () {
36919
- var that = this,
36920
- blockView = this.model.request('blockView');
36921
 
36922
  this.showChildView('selectionRegion', this.selectionView);
36923
  this.showChildView('displayOptionsRegion', this.displayOptionsView);
@@ -36962,7 +36988,7 @@ webpackJsonp([4],{
36962
  }
36963
  });
36964
 
36965
- var PostsSelectionCollectionView = Marionette.CollectionView.extend({
36966
  className: 'mailpoet_post_scroll_container',
36967
  childView: function () { return SinglePostSelectionSettingsView; },
36968
  emptyView: function () { return EmptyPostSelectionSettingsView; },
@@ -36986,7 +37012,7 @@ webpackJsonp([4],{
36986
  }
36987
  });
36988
 
36989
- var PostSelectionSettingsView = Marionette.View.extend({
36990
  getTemplate: function () { return window.templates.postSelectionPostsBlockSettings; },
36991
  regions: {
36992
  posts: '.mailpoet_post_selection_container'
@@ -37013,9 +37039,10 @@ webpackJsonp([4],{
37013
  }
37014
  },
37015
  onRender: function () {
 
37016
  // Dynamically update available post types
37017
  CommunicationComponent.getPostTypes().done(_.bind(this._updateContentTypes, this));
37018
- var postsView = new PostsSelectionCollectionView({
37019
  collection: this.model.get('_availablePosts'),
37020
  blockModel: this.model
37021
  });
@@ -37037,12 +37064,13 @@ webpackJsonp([4],{
37037
  },
37038
  transport: function (options, success, failure) {
37039
  var taxonomies;
 
37040
  var promise = CommunicationComponent.getTaxonomies(
37041
  that.model.get('contentType')
37042
  ).then(function (tax) {
37043
  taxonomies = tax;
37044
  // Fetch available terms based on the list of taxonomies already fetched
37045
- var promise = CommunicationComponent.getTerms({
37046
  search: options.data.term,
37047
  taxonomies: _.keys(taxonomies)
37048
  }).then(function (terms) {
@@ -37051,7 +37079,7 @@ webpackJsonp([4],{
37051
  terms: terms
37052
  };
37053
  });
37054
- return promise;
37055
  });
37056
 
37057
  promise.then(success);
@@ -37092,8 +37120,8 @@ webpackJsonp([4],{
37092
  this.model.set(field, jQuery(event.target).val());
37093
  },
37094
  _updateContentTypes: function (postTypes) {
37095
- var select = this.$('.mailpoet_settings_posts_content_type'),
37096
- selectedValue = this.model.get('contentType');
37097
 
37098
  select.find('option').remove();
37099
  _.each(postTypes, function (type) {
@@ -37106,11 +37134,11 @@ webpackJsonp([4],{
37106
  }
37107
  });
37108
 
37109
- var EmptyPostSelectionSettingsView = Marionette.View.extend({
37110
  getTemplate: function () { return window.templates.emptyPostPostsBlockSettings; }
37111
  });
37112
 
37113
- var SinglePostSelectionSettingsView = Marionette.View.extend({
37114
  getTemplate: function () { return window.templates.singlePostPostsBlockSettings; },
37115
  events: function () {
37116
  return {
@@ -37127,8 +37155,8 @@ webpackJsonp([4],{
37127
  this.blockModel = options.blockModel;
37128
  },
37129
  postSelectionChange: function (event) {
37130
- var checkBox = jQuery(event.target),
37131
- selectedPostsCollection = this.blockModel.get('_selectedPosts');
37132
  if (checkBox.prop('checked')) {
37133
  selectedPostsCollection.add(this.model);
37134
  } else {
@@ -37137,7 +37165,7 @@ webpackJsonp([4],{
37137
  }
37138
  });
37139
 
37140
- var PostsDisplayOptionsSettingsView = base.BlockSettingsView.extend({
37141
  getTemplate: function () { return window.templates.displayOptionsPostsBlockSettings; },
37142
  events: function () {
37143
  return {
@@ -37167,7 +37195,7 @@ webpackJsonp([4],{
37167
  model: this.model.toJSON()
37168
  };
37169
  },
37170
- showButtonSettings: function (event) {
37171
  var buttonModule = ButtonBlock;
37172
  (new buttonModule.ButtonBlockSettingsView({
37173
  model: this.model.get('readMoreButton'),
@@ -37178,7 +37206,7 @@ webpackJsonp([4],{
37178
  }
37179
  })).render();
37180
  },
37181
- showDividerSettings: function (event) {
37182
  var dividerModule = DividerBlock;
37183
  (new dividerModule.DividerBlockSettingsView({
37184
  model: this.model.get('divider'),
@@ -37254,7 +37282,7 @@ webpackJsonp([4],{
37254
  }
37255
  });
37256
 
37257
- App.on('before:start', function (App, options) {
37258
  App.registerBlockType('posts', {
37259
  blockModel: Module.PostsBlockModel,
37260
  blockView: Module.PostsBlockView
@@ -37273,7 +37301,7 @@ webpackJsonp([4],{
37273
 
37274
  /***/ },
37275
 
37276
- /***/ 606:
37277
  /***/ function(module, exports, __webpack_require__) {
37278
 
37279
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -37281,7 +37309,7 @@ webpackJsonp([4],{
37281
  */
37282
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
37283
  __webpack_require__(574),
37284
- __webpack_require__(595),
37285
  __webpack_require__(535),
37286
  __webpack_require__(562),
37287
  __webpack_require__(564),
@@ -37291,12 +37319,13 @@ webpackJsonp([4],{
37291
 
37292
  'use strict';
37293
 
37294
- var Module = {},
37295
- base = BaseBlock,
37296
- SocialBlockSettingsIconSelectorView,
37297
- SocialBlockSettingsIconView,
37298
- SocialBlockSettingsIconCollectionView,
37299
- SocialBlockSettingsStylesView;
 
37300
 
37301
  Module.SocialIconModel = SuperModel.extend({
37302
  defaults: function () {
@@ -37311,12 +37340,12 @@ webpackJsonp([4],{
37311
  text: defaultValues.get('title')
37312
  };
37313
  },
37314
- initialize: function (options) {
37315
  var that = this;
37316
  // Make model swap to default values for that type when iconType changes
37317
  this.on('change:iconType', function () {
37318
- var defaultValues = App.getConfig().get('socialIcons').get(that.get('iconType')),
37319
- iconSet = that.collection.iconBlockModel.getIconSet();
37320
  this.set({
37321
  link: defaultValues.get('defaultLink'),
37322
  image: iconSet.get(that.get('iconType')),
@@ -37361,7 +37390,7 @@ webpackJsonp([4],{
37361
  }
37362
  });
37363
 
37364
- var SocialIconView = Marionette.View.extend({
37365
  tagName: 'span',
37366
  getTemplate: function () { return window.templates.socialIconBlock; },
37367
  modelEvents: {
@@ -37453,10 +37482,10 @@ webpackJsonp([4],{
37453
  }
37454
  },
37455
  templateContext: function () {
37456
- var icons = App.getConfig().get('socialIcons'),
37457
- // Construct icon type list of format [{iconType: 'type', title: 'Title'}, ...]
37458
- availableIconTypes = _.map(_.keys(icons.attributes), function (key) { return { iconType: key, title: icons.get(key).get('title') }; }),
37459
- allIconSets = App.getAvailableStyles().get('socialIconSets');
37460
  return _.extend({}, base.BlockView.prototype.templateContext.apply(this, arguments), {
37461
  iconTypes: availableIconTypes,
37462
  currentType: icons.get(this.model.get('iconType')).toJSON(),
@@ -37575,7 +37604,7 @@ webpackJsonp([4],{
37575
  }
37576
  });
37577
 
37578
- App.on('before:start', function (App, options) {
37579
  App.registerBlockType('social', {
37580
  blockModel: Module.SocialBlockModel,
37581
  blockView: Module.SocialBlockView
1
  webpackJsonp([4],{
2
 
3
+ /***/ 578:
4
  /***/ function(module, exports, __webpack_require__) {
5
 
6
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
103
  });
104
  };
105
 
106
+ App.on('start', function () {
107
  // Prefetch post types
108
  Module.getPostTypes();
109
  });
131
  __webpack_require__(572);
132
  __webpack_require__(573);
133
  __webpack_require__(574);
134
+ __webpack_require__(575);
135
  __webpack_require__(576);
136
  __webpack_require__(577);
137
+ __webpack_require__(579);
138
  __webpack_require__(580);
139
  __webpack_require__(581);
140
+ __webpack_require__(578);
141
+ __webpack_require__(584);
142
  __webpack_require__(585);
143
  __webpack_require__(586);
144
  __webpack_require__(587);
159
  __webpack_require__(602);
160
  __webpack_require__(603);
161
  __webpack_require__(604);
162
+ module.exports = __webpack_require__(605);
 
163
 
164
 
165
  /***/ },
9439
  if (xhr.responseJSON) {
9440
  return xhr.responseJSON;
9441
  }
 
9442
  return {
9443
  errors: [
9444
  {
9445
+ message: errorMessage.replace('%d', xhr.status)
9446
  }
9447
  ]
9448
  };
9490
  };
9491
  },
9492
  request: function (method, options) {
9493
+ var params;
9494
+ var deferred;
9495
+ // set options
9496
  this.init(options);
9497
 
9498
+ // set request params
9499
+ params = this.getParams();
9500
 
9501
+ // remove null values from the data object
9502
  if (_.isObject(params.data)) {
9503
  params.data = _.pick(params.data, function (value) {
9504
  return (value !== null);
9505
  });
9506
  }
9507
 
9508
+ // ajax request
9509
+ deferred = jQuery.post(
9510
  this.options.url,
9511
  params,
9512
  null,
9646
  }
9647
  },
9648
  init: function (options) {
9649
+ var modal;
9650
  if (this.initialized === true) {
9651
  this.close();
9652
  }
9665
  if (this.options.type !== null) {
9666
  // insert modal depending on its type
9667
  if (this.options.type === 'popup') {
9668
+ modal = this.compileTemplate(
9669
  this.templates[this.options.type]
9670
  );
9671
  // create modal
9709
 
9710
  return this;
9711
  },
9712
+ initOverlay: function () {
9713
  if (jQuery('#mailpoet_modal_overlay').length === 0) {
9714
  // insert overlay into the DOM
9715
  jQuery('body').append(this.templates.overlay);
9874
  return this;
9875
  },
9876
  setPosition: function () {
9877
+ var screenWidth;
9878
+ var screenHeight;
9879
+ var modalWidth;
9880
+ var modalHeight;
9881
  switch (this.options.type) {
9882
  case 'popup':
9883
+ screenWidth = jQuery(window).width();
9884
+ screenHeight = jQuery(window).height();
9885
+ modalWidth = jQuery('.mailpoet_'+ this.options.type +'_wrapper').width();
9886
+ modalHeight = jQuery('.mailpoet_'+ this.options.type +'_wrapper').height();
 
 
 
9887
 
9888
+ // set position of popup depending on screen dimensions.
9889
  jQuery('#mailpoet_popup').css({
9890
+ top: Math.max(48, parseInt((screenHeight / 2) - (modalHeight / 2))),
9891
+ left: Math.max(0, parseInt((screenWidth / 2) - (modalWidth / 2)))
9892
  });
9893
  break;
9894
  case 'panel':
9968
  .removeClass('mailpoet_modal_highlight');
9969
  return this;
9970
  },
9971
+ hideModal: function () {
9972
  // set modal as closed
9973
  this.opened = false;
9974
 
9983
 
9984
  return this;
9985
  },
9986
+ showOverlay: function () {
9987
  jQuery('#mailpoet_modal_overlay').show();
9988
  return this;
9989
  },
10229
  return this;
10230
  },
10231
  createNotice: function () {
10232
+ var onClose;
10233
+ var positionAfter;
10234
  // clone element
10235
  this.element = jQuery('#mailpoet_notice_' + this.options.type).clone();
10236
 
10246
  this.element.removeAttr('id');
10247
 
10248
  // insert notice after its parent
 
10249
  if (typeof this.options.positionAfter === 'object') {
10250
  positionAfter = this.options.positionAfter;
10251
  } else if (typeof this.options.positionAfter === 'string') {
10256
  positionAfter.after(this.element);
10257
 
10258
  // setup onClose callback
10259
+ onClose = null;
10260
  if (this.options.onClose !== null) {
10261
  onClose = this.options.onClose;
10262
  }
10360
  }
10361
  },
10362
  hide: function (all) {
10363
+ var id;
10364
  if (all !== undefined && all === true) {
10365
  // all notices
10366
  jQuery('.mailpoet_notice:not([id])').trigger('close');
10367
  } else if (all !== undefined && jQuery.isArray(all)) {
10368
  // array of ids
10369
+ for (id in all) {
10370
  jQuery('[data-id="' + all[id] + '"]').trigger('close');
10371
  }
10372
  } if (all !== undefined) {
27602
  */
27603
 
27604
  (function (root, factory) {
27605
+ var Marionette = __webpack_require__(562);
27606
+ var Radio = __webpack_require__(563);
27607
+ var _ = __webpack_require__(278);
27608
  if (true) {
27609
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(562), __webpack_require__(563), __webpack_require__(278)], __WEBPACK_AMD_DEFINE_RESULT__ = function (Marionette, Radio, _) {
27610
  return factory(Marionette, Radio, _);
27611
  }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
27612
  }
27613
  else if (typeof exports !== 'undefined') {
 
 
 
27614
  module.exports = factory(Marionette, Radio, _);
27615
  }
27616
  else {
27635
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
27636
  __webpack_require__(535),
27637
  __webpack_require__(562),
27638
+ __webpack_require__(563)
27639
+ ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Backbone, Marionette, BackboneRadio) {
 
 
 
 
27640
  var Radio = BackboneRadio;
27641
 
27642
  var AppView = Marionette.View.extend({
27676
 
27677
  /***/ },
27678
 
27679
+ /***/ 575:
27680
  /***/ function(module, exports, __webpack_require__) {
27681
 
27682
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
27720
 
27721
  /***/ },
27722
 
27723
+ /***/ 576:
27724
  /***/ function(module, exports, __webpack_require__) {
27725
 
27726
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
27796
 
27797
  App.on('before:start', function (App, options) {
27798
  var Application = App;
27799
+ var body;
27800
+ var globalStyles;
27801
  // Expose style methods to global application
27802
  Application.getGlobalStyles = Module.getGlobalStyles;
27803
  Application.setGlobalStyles = Module.setGlobalStyles;
27804
  Application.getAvailableStyles = Module.getAvailableStyles;
27805
 
27806
+ body = options.newsletter.body;
27807
+ globalStyles = (_.has(body, 'globalStyles')) ? body.globalStyles : {};
27808
  this.setGlobalStyles(globalStyles);
27809
  });
27810
 
27811
+ App.on('start', function (App) {
27812
  var stylesView = new Module.StylesView({ model: App.getGlobalStyles() });
27813
  App._appView.showChildView('stylesRegion', stylesView);
27814
  });
27819
 
27820
  /***/ },
27821
 
27822
+ /***/ 577:
27823
  /***/ function(module, exports, __webpack_require__) {
27824
 
27825
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
27826
  __webpack_require__(574),
27827
+ __webpack_require__(578),
27828
  __webpack_require__(274),
27829
  __webpack_require__(535),
27830
  __webpack_require__(562),
27831
  __webpack_require__(564),
27832
  __webpack_require__(278),
27833
+ __webpack_require__(273)
 
27834
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (
27835
  App,
27836
  CommunicationComponent,
27839
  Marionette,
27840
  SuperModel,
27841
  _,
27842
+ jQuery
 
27843
  ) {
27844
 
27845
  'use strict';
27846
 
27847
  var Module = {};
27848
+ var SidebarView;
27849
  // Widget handlers for use to create new content blocks via drag&drop
27850
  Module._contentWidgets = new (Backbone.Collection.extend({
27851
  model: SuperModel.extend({
27874
  Module.registerLayoutWidget = function (widget) { return Module._layoutWidgets.add(widget); };
27875
  Module.getLayoutWidgets = function () { return Module._layoutWidgets; };
27876
 
27877
+ SidebarView = Marionette.View.extend({
27878
  getTemplate: function () { return window.templates.sidebar; },
27879
  regions: {
27880
  contentRegion: '.mailpoet_content_region',
27884
  },
27885
  events: {
27886
  'click .mailpoet_sidebar_region h3, .mailpoet_sidebar_region .handlediv': function (event) {
27887
+ var $openRegion = this.$el.find('.mailpoet_sidebar_region:not(.closed)');
27888
+ var $targetRegion = this.$el.find(event.target).closest('.mailpoet_sidebar_region');
27889
 
27890
  $openRegion.find('.mailpoet_region_content').velocity(
27891
  'slideUp',
27912
  }
27913
  }
27914
  },
27915
+ initialize: function () {
27916
  jQuery(window)
27917
  .on('resize', this.updateHorizontalScroll.bind(this))
27918
  .on('scroll', this.updateHorizontalScroll.bind(this));
27935
  // position of the sidebar would be scrollable and not fixed
27936
  // partially out of visible screen
27937
  this.$el.parent().each(function () {
27938
+ var calculated_left;
27939
+ var self = jQuery(this);
 
27940
 
27941
  if (self.css('position') === 'fixed') {
27942
  calculated_left = self.parent().offset().left - jQuery(window).scrollLeft();
28092
  previewUrl: response.meta.preview_url
28093
  });
28094
 
28095
+ this.previewView.render();
28096
  this.previewView.$el.css('height', '100%');
28097
 
28098
  MailPoet.Modal.popup({
28145
  App.getChannel().request('save').always(function () {
28146
  CommunicationComponent.previewNewsletter(data).always(function () {
28147
  MailPoet.Modal.loading(false);
28148
+ }).done(function () {
28149
  MailPoet.Notice.success(
28150
  MailPoet.I18n.t('newsletterPreviewSent'),
28151
  { scroll: true }
28184
  }
28185
  });
28186
 
28187
+ App.on('before:start', function (App) {
28188
  var Application = App;
28189
  Application.registerWidget = Module.registerWidget;
28190
  Application.getWidgets = Module.getWidgets;
28192
  Application.getLayoutWidgets = Module.getLayoutWidgets;
28193
  });
28194
 
28195
+ App.on('start', function (App) {
28196
+ var sidebarView = new SidebarView();
 
28197
 
28198
  App._appView.showChildView('sidebarRegion', sidebarView);
28199
 
28221
 
28222
  /***/ },
28223
 
28224
+ /***/ 579:
28225
  /***/ function(module, exports, __webpack_require__) {
28226
 
28227
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
28239
  // handled by other components.
28240
  Module.NewsletterModel = SuperModel.extend({
28241
  whitelisted: ['id', 'subject', 'preheader'],
28242
+ initialize: function () {
28243
  this.on('change', function () {
28244
  App.getChannel().trigger('autoSave');
28245
  });
28335
 
28336
  /***/ },
28337
 
28338
+ /***/ 580:
28339
  /***/ function(module, exports, __webpack_require__) {
28340
 
28341
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
28369
  }
28370
  });
28371
 
28372
+ App.on('start', function (App) {
28373
  App._appView.showChildView('headingRegion', new Module.HeadingView({ model: App.getNewsletter() }));
28374
  MailPoet.helpTooltip.show(document.getElementById('tooltip-designer-subject-line'), {
28375
  tooltipId: 'tooltip-designer-subject-line-ti',
28388
 
28389
  /***/ },
28390
 
28391
+ /***/ 581:
28392
  /***/ function(module, exports, __webpack_require__) {
28393
 
28394
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
28395
  __webpack_require__(574),
28396
+ __webpack_require__(578),
28397
  __webpack_require__(274),
28398
  __webpack_require__(556),
28399
  __webpack_require__(535),
28401
  __webpack_require__(273),
28402
  __webpack_require__(568),
28403
  __webpack_require__(569),
28404
+ __webpack_require__(582),
28405
  __webpack_require__(278),
28406
  __webpack_require__(273)
28407
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (
28421
 
28422
  'use strict';
28423
 
28424
+ var Module = {};
28425
+ var saveTimeout;
28426
 
28427
  // Save editor contents to server
28428
  Module.save = function () {
28469
  // Temporary workaround for html2canvas-alpha2.
28470
  // Removes 1px left transparent border from resulting canvas.
28471
 
28472
+ var newCanvas = document.createElement('canvas');
28473
+ var newContext = newCanvas.getContext('2d');
28474
+ var leftBorderWidth = 1;
 
28475
 
28476
  newCanvas.width = oldCanvas.width;
28477
  newCanvas.height = oldCanvas.height;
28487
  };
28488
 
28489
  Module.saveTemplate = function (options) {
28490
+ var promise = jQuery.Deferred();
 
28491
 
28492
  promise.then(function (thumbnail) {
28493
  var data = _.extend(options || {}, {
28513
  };
28514
 
28515
  Module.exportTemplate = function (options) {
 
28516
  return Module.getThumbnail(
28517
  jQuery('#mailpoet_editor_content > .mailpoet_block').get(0)
28518
  ).then(function (thumbnail) {
28545
  'click .mailpoet_save_export': 'toggleExportTemplate',
28546
  'click .mailpoet_export_template': 'exportTemplate'
28547
  },
28548
+ initialize: function () {
28549
  App.getChannel().on('beforeEditorSave', this.beforeSave, this);
28550
  App.getChannel().on('afterEditorSave', this.afterSave, this);
28551
  },
28560
  // TODO: Add a loading animation instead
28561
  this.$('.mailpoet_autosaved_at').text(MailPoet.I18n.t('saving'));
28562
  },
28563
+ afterSave: function (json) {
28564
  this.validateNewsletter(json);
28565
  // Update 'Last saved timer'
28566
  this.$('.mailpoet_editor_last_saved').removeClass('mailpoet_hidden');
28582
  this.$('.mailpoet_save_as_template_container').addClass('mailpoet_hidden');
28583
  },
28584
  saveAsTemplate: function () {
28585
+ var templateName = this.$('.mailpoet_save_as_template_name').val();
28586
+ var templateDescription = this.$('.mailpoet_save_as_template_description').val();
28587
+ var that = this;
28588
 
28589
  if (templateName === '') {
28590
  MailPoet.Notice.error(
28638
  this.$('.mailpoet_export_template_container').addClass('mailpoet_hidden');
28639
  },
28640
  exportTemplate: function () {
28641
+ var templateName = this.$('.mailpoet_export_template_name').val();
28642
+ var templateDescription = this.$('.mailpoet_export_template_description').val();
28643
+ var that = this;
28644
 
28645
  if (templateName === '') {
28646
  MailPoet.Notice.error(
28675
  this.hideOptionContents();
28676
  if (!this.$('.mailpoet_save_next').hasClass('button-disabled')) {
28677
  Module._cancelAutosave();
28678
+ Module.save().done(function () {
28679
  window.location.href = App.getConfig().get('urls.send');
28680
  });
28681
  }
28682
  },
28683
  validateNewsletter: function (jsonObject) {
28684
+ var contents;
28685
  if (!App._contentContainer.isValid()) {
28686
  this.showValidationError(App._contentContainer.validationError);
28687
  return;
28688
  }
28689
 
28690
+ contents = JSON.stringify(jsonObject);
28691
  if (App.getConfig().get('validation.validateUnsubscribeLinkPresent') &&
28692
  contents.indexOf('[link:subscription_unsubscribe_url]') < 0 &&
28693
  contents.indexOf('[link:subscription_unsubscribe]') < 0) {
28731
  };
28732
 
28733
  Module.beforeExitWithUnsavedChanges = function (e) {
28734
+ var message;
28735
+ var event;
28736
  if (saveTimeout) {
28737
+ message = MailPoet.I18n.t('unsavedChangesWillBeLost');
28738
+ event = e || window.event;
28739
 
28740
  if (event) {
28741
  event.returnValue = message;
28745
  }
28746
  };
28747
 
28748
+ App.on('before:start', function (App) {
28749
  var Application = App;
28750
  Application.save = Module.save;
28751
  Application.getChannel().on('autoSave', Module.autoSave);
28755
  Application.getChannel().reply('save', Application.save);
28756
  });
28757
 
28758
+ App.on('start', function (App) {
28759
  var saveView = new Module.SaveView();
28760
  App._appView.showChildView('bottomRegion', saveView);
28761
  });
28766
 
28767
  /***/ },
28768
 
28769
+ /***/ 582:
28770
  /***/ function(module, exports, __webpack_require__) {
28771
 
28772
+ /* WEBPACK VAR INJECTION */(function(global) {module.exports = global["html2canvas"] = __webpack_require__(583);
28773
  /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
28774
 
28775
  /***/ },
28776
 
28777
+ /***/ 583:
28778
  /***/ function(module, exports, __webpack_require__) {
28779
 
28780
  var require;var require;/* WEBPACK VAR INJECTION */(function(global) {/*
33315
 
33316
  /***/ },
33317
 
33318
+ /***/ 584:
33319
  /***/ function(module, exports, __webpack_require__) {
33320
 
33321
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
33341
 
33342
  /***/ },
33343
 
33344
+ /***/ 585:
33345
  /***/ function(module, exports, __webpack_require__) {
33346
 
33347
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
33351
  */
33352
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
33353
  __webpack_require__(562),
33354
+ __webpack_require__(584),
33355
  __webpack_require__(274),
33356
  __webpack_require__(566)
33357
+ ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Marionette, BehaviorsLookup, MailPoet) {
33358
  var BL = BehaviorsLookup;
33359
 
33360
  BL.ColorPickerBehavior = Marionette.Behavior.extend({
33361
  onRender: function () {
33362
+ var that = this;
33363
+ var preferredFormat = 'hex6';
33364
  this.view.$('.mailpoet_color').each(function () {
33365
  var $input = that.view.$(this);
33366
  var updateColorInput = function (color) {
33395
 
33396
  /***/ },
33397
 
33398
+ /***/ 586:
33399
  /***/ function(module, exports, __webpack_require__) {
33400
 
33401
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;
33410
  __webpack_require__(562),
33411
  __webpack_require__(278),
33412
  __webpack_require__(273),
33413
+ __webpack_require__(584),
33414
  __webpack_require__(565)
33415
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Marionette, _, jQuery, BL, interact) {
33416
  var BehaviorsLookup = BL;
33425
  this.addDropZone();
33426
  }
33427
  },
33428
+ addDropZone: function () {
33429
+ var that = this;
33430
+ var view = this.view;
33431
+ var domElement = that.$el.get(0);
33432
+ var acceptableElementSelector;
33433
 
33434
  // TODO: Extract this limitation code to be controlled from containers
33435
  if (this.view.renderOptions.depth === 0) {
33447
  interact(domElement).dropzone({
33448
  accept: acceptableElementSelector,
33449
  overlap: 'pointer', // Mouse pointer denotes location of a droppable
33450
+ ondragenter: function () {
33451
  // 1. Visually mark block as active for dropping
33452
  view.$el.addClass('mailpoet_drop_active');
33453
  },
33454
+ ondragleave: function () {
33455
  // 1. Remove visual markings of active dropping container
33456
  // 2. Remove visual markings of drop position visualization
33457
  that.cleanup();
33463
  // 3b. If insertion is special, compute position (which side) and which cell the insertion belongs to
33464
  // 4. If insertion at that position is not visualized, display position visualization there, remove other visualizations from this container
33465
  var dropPosition = that.getDropPosition(
33466
+ event.dragmove.pageX,
33467
+ event.dragmove.pageY,
33468
+ view.$el,
33469
+ view.model.get('orientation'),
33470
+ view.model.get('blocks').length
33471
+ );
33472
+ var element = view.$el;
33473
+ var markerWidth = '';
33474
+ var markerHeight = '';
33475
+ var containerOffset = element.offset();
33476
+ var viewCollection = that.getCollection();
33477
+ var marker;
33478
+ var targetModel;
33479
+ var targetView;
33480
+ var targetElement;
33481
+ var topOffset;
33482
+ var leftOffset;
33483
+ var isLastBlockInsertion;
33484
+ var $targetBlock;
33485
+ var margin;
33486
 
33487
  if (dropPosition === undefined) return;
33488
 
33584
  // 4. Perform cleanup actions
33585
 
33586
  var dropPosition = that.getDropPosition(
33587
+ event.dragEvent.pageX,
33588
+ event.dragEvent.pageY,
33589
+ view.$el,
33590
+ view.model.get('orientation'),
33591
+ view.model.get('blocks').length
33592
+ );
33593
+ var droppableModel = event.draggable.getDropModel();
33594
+ var viewCollection = that.getCollection();
33595
+ var droppedView;
33596
+ var index;
33597
+ var tempCollection;
33598
+ var tempCollection2;
33599
+ var tempModel;
33600
 
33601
  if (dropPosition === undefined) return;
33602
 
33620
  } else {
33621
  // Special insertion by replacing target block with collection
33622
  // and inserting dropModel into that
33623
+ tempModel = viewCollection.at(dropPosition.index);
33624
 
33625
  tempCollection = new (window.EditorApplication.getBlockTypeModel('container'))({
33626
  orientation: (view.model.get('orientation') === 'vertical') ? 'horizontal' : 'vertical'
33682
  this.view.$('.mailpoet_drop_marker').remove();
33683
  },
33684
  getDropPosition: function (eventX, eventY, is_unsafe) {
33685
+ var SPECIAL_AREA_INSERTION_WIDTH = 0.00; // Disable special insertion. Default: 0.3
33686
 
33687
+ var element = this.view.$el;
33688
+ var orientation = this.view.model.get('orientation');
33689
 
33690
+ var elementOffset = element.offset();
33691
+ var elementPageX = elementOffset.left;
33692
+ var elementPageY = elementOffset.top;
33693
+ var elementWidth = element.outerWidth(true);
33694
+ var elementHeight = element.outerHeight(true);
33695
 
33696
+ var relativeX = eventX - elementPageX;
33697
+ var relativeY = eventY - elementPageY;
33698
 
33699
+ var relativeOffset;
33700
+ var elementLength;
33701
 
33702
+ var canAcceptNormalInsertion = this._canAcceptNormalInsertion();
33703
+ var canAcceptSpecialInsertion = this._canAcceptSpecialInsertion();
33704
 
33705
+ var insertionType;
33706
+ var index;
33707
+ var position;
33708
+ var indexAndPosition;
33709
 
33710
  var unsafe = !!is_unsafe;
33711
 
33773
  // target element if event happens on the second half of the element.
33774
  // Halves depend on orientation.
33775
 
33776
+ var index = this._computeCellIndex(eventX, eventY);
33777
+ // TODO: Handle case when there are no children, container is empty
33778
+ var targetView = this.getChildren().findByModel(this.getCollection().at(index));
33779
+ var orientation = this.view.model.get('orientation');
33780
+ var element = targetView.$el;
33781
+ var eventOffset;
33782
+ var closeOffset;
33783
+ var elementDimension;
33784
 
33785
  if (orientation === 'vertical') {
33786
  eventOffset = eventY;
33810
  return this._computeCellIndex(eventX, eventY);
33811
  },
33812
  _computeCellIndex: function (eventX, eventY) {
33813
+ var orientation = this.view.model.get('orientation');
33814
+ var eventOffset = (orientation === 'vertical') ? eventY : eventX;
33815
+ var resultView = this.getChildren().find(function (view) {
33816
+ var element = view.$el;
33817
+ var closeOffset;
33818
+ var farOffset;
33819
+
33820
+ if (orientation === 'vertical') {
33821
+ closeOffset = element.offset().top;
33822
+ farOffset = element.outerHeight(true);
33823
+ } else {
33824
+ closeOffset = element.offset().left;
33825
+ farOffset = element.outerWidth(true);
33826
+ }
33827
+ farOffset += closeOffset;
33828
 
33829
+ return closeOffset <= eventOffset && eventOffset <= farOffset;
33830
+ });
33831
 
33832
  var index = (typeof resultView === 'object') ? resultView._index : 0;
33833
 
33834
  return index;
33835
  },
33836
  _canAcceptNormalInsertion: function () {
33837
+ var orientation = this.view.model.get('orientation');
33838
+ var depth = this.view.renderOptions.depth;
33839
+ var childCount = this.getChildren().length;
33840
  // Note that depth is zero indexed. Root container has depth=0
33841
  return orientation === 'vertical' || (orientation === 'horizontal' && depth === 1 && childCount < this.options.columnLimit);
33842
  },
33843
  _canAcceptSpecialInsertion: function () {
33844
+ var orientation = this.view.model.get('orientation');
33845
+ var depth = this.view.renderOptions.depth;
33846
+ var childCount = this.getChildren().length;
33847
  return depth === 0 || (depth === 1 && orientation === 'horizontal' && childCount <= this.options.columnLimit);
33848
  },
33849
  getCollectionView: function () {
33861
 
33862
  /***/ },
33863
 
33864
+ /***/ 587:
33865
  /***/ function(module, exports, __webpack_require__) {
33866
 
33867
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
33874
  __webpack_require__(562),
33875
  __webpack_require__(278),
33876
  __webpack_require__(273),
33877
+ __webpack_require__(584),
33878
  __webpack_require__(565)
33879
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Marionette, _, jQuery, BehaviorsLookup, interact) {
33880
  var BL = BehaviorsLookup;
33894
  throw "Missing 'drop' function for DraggableBehavior";
33895
  },
33896
 
33897
+ onDrop: function () {},
33898
+ testAttachToInstance: function () { return true; }
33899
  },
33900
  onRender: function () {
33901
+ var that = this;
33902
+ var interactable;
33903
 
33904
  // Give instances more control over whether Draggable should be applied
33905
  if (!this.options.testAttachToInstance(this.view.model, this.view)) return;
33915
 
33916
  onstart: function (startEvent) {
33917
  var event = startEvent;
33918
+ var centerXOffset;
33919
+ var centerYOffset;
33920
+ var tempClone;
33921
+ var clone;
33922
+ var $clone;
33923
 
33924
  if (that.options.cloneOriginal === true) {
33925
  // Use substitution instead of a clone
33926
+ tempClone = (_.isFunction(that.options.onDragSubstituteBy)) ? that.options.onDragSubstituteBy(that) : undefined;
33927
+ // Or use a clone
33928
+ clone = tempClone || event.target.cloneNode(true);
33929
+ jQuery(event.target);
33930
+ $clone = jQuery(clone);
 
 
33931
 
33932
  $clone.addClass('mailpoet_droppable_active');
33933
  $clone.css('position', 'absolute');
33954
  },
33955
  // call this function on every dragmove event
33956
  onmove: function (event) {
33957
+ var target = event.target;
33958
+ // keep the dragged position in the data-x/data-y attributes
33959
+ var x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
33960
+ var y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
33961
 
33962
  // translate the element
33963
  target.style.transform = 'translate(' + x + 'px, ' + y + 'px)';
34016
 
34017
  /***/ },
34018
 
34019
+ /***/ 588:
34020
  /***/ function(module, exports, __webpack_require__) {
34021
 
34022
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
34026
  */
34027
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
34028
  __webpack_require__(562),
34029
+ __webpack_require__(584)
34030
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Marionette, BehaviorsLookup) {
34031
  var BL = BehaviorsLookup;
34032
 
34049
 
34050
  /***/ },
34051
 
34052
+ /***/ 589:
34053
  /***/ function(module, exports, __webpack_require__) {
34054
 
34055
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
34059
  */
34060
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
34061
  __webpack_require__(562),
34062
+ __webpack_require__(584)
34063
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Marionette, BehaviorsLookup) {
34064
  var BL = BehaviorsLookup;
34065
 
34082
 
34083
  /***/ },
34084
 
34085
+ /***/ 590:
34086
  /***/ function(module, exports, __webpack_require__) {
34087
 
34088
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
34092
  */
34093
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
34094
  __webpack_require__(562),
34095
+ __webpack_require__(584),
34096
  __webpack_require__(565)
34097
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Marionette, BehaviorsLookup, interact) {
34098
  var BL = BehaviorsLookup;
34106
  maxLength: Infinity,
34107
  modelField: 'styles.block.height',
34108
  onResize: function (event) {
34109
+ var currentLength = parseFloat(this.view.model.get(this.options.modelField));
34110
+ var newLength = currentLength + this.options.transformationFunction(event.dy);
34111
  newLength = Math.min(this.options.maxLength, Math.max(this.options.minLength, newLength));
34112
  this.view.model.set(this.options.modelField, newLength + 'px');
34113
  }
34124
  }
34125
  },
34126
  attachResize: function () {
34127
+ var domElement = (this.options.elementSelector === null) ? this.view.$el.get(0) : this.view.$(this.options.elementSelector).get(0);
34128
+ var that = this;
34129
  interact(domElement).resizable({
34130
  // axis: 'y',
34131
  edges: {
34135
  bottom: (typeof this.options.resizeHandleSelector === 'string') ? this.view.$(this.options.resizeHandleSelector).get(0) : this.options.resizeHandleSelector
34136
  }
34137
  })
34138
+ .on('resizestart', function () {
34139
  that.isBeingResized = true;
34140
  that.$el.addClass('mailpoet_resize_active');
34141
  })
34143
  var onResize = that.options.onResize.bind(that);
34144
  return onResize(event);
34145
  })
34146
+ .on('resizeend', function () {
34147
  that.isBeingResized = null;
34148
  that.$el.removeClass('mailpoet_resize_active');
34149
  });
34164
 
34165
  /***/ },
34166
 
34167
+ /***/ 591:
34168
  /***/ function(module, exports, __webpack_require__) {
34169
 
34170
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
34175
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
34176
  __webpack_require__(562),
34177
  __webpack_require__(278),
34178
+ __webpack_require__(584)
34179
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Marionette, _, BehaviorsLookup) {
34180
  var BL = BehaviorsLookup;
34181
 
34193
  ui.item.removeData('previousIndex');
34194
  },
34195
  update: function (event, ui) {
34196
+ var previousIndex = ui.item.data('previousIndex');
34197
+ var newIndex = ui.item.index();
34198
+ var model = collection.at(previousIndex);
34199
 
34200
  // Replicate DOM changes. Move target model to a new position
34201
  // within the collection
34212
 
34213
  /***/ },
34214
 
34215
+ /***/ 592:
34216
  /***/ function(module, exports, __webpack_require__) {
34217
 
34218
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
34223
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
34224
  __webpack_require__(562),
34225
  __webpack_require__(273),
34226
+ __webpack_require__(584)
34227
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Marionette, jQuery, BehaviorsLookup) {
34228
  var BL = BehaviorsLookup;
34229
 
34251
 
34252
  /***/ },
34253
 
34254
+ /***/ 593:
34255
  /***/ function(module, exports, __webpack_require__) {
34256
 
34257
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
34262
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
34263
  __webpack_require__(562),
34264
  __webpack_require__(278),
34265
+ __webpack_require__(584)
34266
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Marionette, _, BehaviorsLookup) {
34267
  var BL = BehaviorsLookup;
34268
 
34298
  relative_urls: false,
34299
  remove_script_host: false,
34300
  convert_urls: true,
34301
+ urlconverter_callback: function (url) {
34302
  if (url.match(/\[.+\]/g)) {
34303
  // Do not convert URLs with shortcodes
34304
  return url;
34313
  plugins: this.options.plugins,
34314
 
34315
  setup: function (editor) {
34316
+ editor.on('change', function () {
34317
  that.view.triggerMethod('text:editor:change', editor.getContent());
34318
  });
34319
 
34327
  }
34328
  });
34329
 
34330
+ editor.on('focus', function () {
34331
  that.view.triggerMethod('text:editor:focus');
34332
  that._isActivationClick = true;
34333
  });
34334
 
34335
+ editor.on('blur', function () {
34336
  that.view.triggerMethod('text:editor:blur');
34337
  });
34338
  }
34344
 
34345
  /***/ },
34346
 
34347
+ /***/ 594:
34348
  /***/ function(module, exports, __webpack_require__) {
34349
 
34350
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
34361
  __webpack_require__(273),
34362
  __webpack_require__(274),
34363
  __webpack_require__(555)
34364
+ ], __WEBPACK_AMD_DEFINE_RESULT__ = function (App, Marionette, SuperModel, _, jQuery, MailPoet) {
34365
 
34366
  'use strict';
34367
 
34368
+ var Module = {};
34369
+ var AugmentedView = Marionette.View.extend({});
34370
 
34371
  Module.BlockModel = SuperModel.extend({
34372
  stale: [], // Attributes to be removed upon saving
34373
  initialize: function () {
 
34374
  this.on('change', function () {
34375
  App.getChannel().trigger('autoSave');
34376
  });
34416
  options.dragBehavior.view.model.destroy();
34417
  },
34418
  onDragSubstituteBy: function (behavior) {
34419
+ var WidgetView;
34420
+ var node;
34421
  // When block is being dragged, display the widget icon instead.
34422
  // This will create an instance of block's widget view and
34423
  // use it's rendered DOM element instead of the content block
34447
  this.on('dom:refresh', this.showBlock, this);
34448
  this._isFirstRender = true;
34449
  },
34450
+ showTools: function () {
34451
  if (!this.showingToolsDisabled) {
34452
  this.$('> .mailpoet_tools').addClass('mailpoet_display_tools');
34453
  this.toolsView.triggerMethod('showTools');
34454
  }
34455
  },
34456
+ hideTools: function () {
34457
  this.$('> .mailpoet_tools').removeClass('mailpoet_display_tools');
34458
  this.toolsView.triggerMethod('hideTools');
34459
  },
34589
  ColorPickerBehavior: {}
34590
  },
34591
  initialize: function (params) {
34592
+ var panelParams;
34593
  this.model.trigger('startEditing');
34594
+ panelParams = {
34595
  element: this.$el,
34596
  template: '',
34597
  position: 'right',
34612
  model: this.model.toJSON()
34613
  };
34614
  },
34615
+ close: function () {
34616
  this.destroy();
34617
  },
34618
  changeField: function (field, event) {
34660
 
34661
  /***/ },
34662
 
34663
+ /***/ 595:
34664
  /***/ function(module, exports, __webpack_require__) {
34665
 
34666
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
34674
  __webpack_require__(278),
34675
  __webpack_require__(273),
34676
  __webpack_require__(574),
34677
+ __webpack_require__(594)
34678
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (Backbone, Marionette, _, jQuery, App, BaseBlock) {
34679
 
34680
  'use strict';
34681
 
34682
+ var Module = {};
34683
+ var base = BaseBlock;
34684
+ var BlockCollection;
34685
 
34686
  BlockCollection = Backbone.Collection.extend({
34687
  model: base.BlockModel,
34689
  this.on('add change remove', function () { App.getChannel().trigger('autoSave'); });
34690
  },
34691
  parse: function (response) {
 
34692
  return _.map(response, function (block) {
34693
  var Type = App.getBlockTypeModel(block.type);
34694
  // TODO: If type has no registered model, use a backup one
34730
  return response;
34731
  },
34732
  getChildren: function () {
34733
+ var models = this.get('blocks').map(function (model) {
34734
  return [model, model.getChildren()];
34735
  });
34736
 
34785
  options.dragBehavior.view.model.destroy();
34786
  },
34787
  onDragSubstituteBy: function (behavior) {
34788
+ var WidgetView;
34789
+ var node;
34790
  // When block is being dragged, display the widget icon instead.
34791
  // This will create an instance of block's widget view and
34792
  // use it's rendered DOM element instead of the content block
34855
  }
34856
  },
34857
  toggleEditingLayer: function (event) {
34858
+ var that = this;
34859
+ var $toggleButton = this.$('> .mailpoet_tools .mailpoet_newsletter_layer_selector');
34860
+ var $overlay = jQuery('.mailpoet_layer_overlay');
34861
+ var $container = this.$('> .mailpoet_container');
34862
+ var enableContainerLayer = function () {
34863
+ that.$el.addClass('mailpoet_container_layer_active');
34864
+ $toggleButton.addClass('mailpoet_container_layer_active');
34865
+ $container.addClass('mailpoet_layer_highlight');
34866
+ $overlay.click(disableContainerLayer);
34867
+ $overlay.show();
34868
+ };
34869
+ var disableContainerLayer = function () {
34870
+ that.$el.removeClass('mailpoet_container_layer_active');
34871
+ $toggleButton.removeClass('mailpoet_container_layer_active');
34872
+ $container.removeClass('mailpoet_layer_highlight');
34873
+ $overlay.hide();
34874
+ $overlay.off('click');
34875
+ };
34876
  if ($toggleButton.hasClass('mailpoet_container_layer_active')) {
34877
  disableContainerLayer();
34878
  } else {
35001
  }
35002
  });
35003
 
35004
+ App.on('before:start', function (App) {
35005
  App.registerBlockType('container', {
35006
  blockModel: Module.ContainerBlockModel,
35007
  blockView: Module.ContainerBlockView
35032
 
35033
  /***/ },
35034
 
35035
+ /***/ 596:
35036
  /***/ function(module, exports, __webpack_require__) {
35037
 
35038
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
35040
  */
35041
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
35042
  __webpack_require__(574),
35043
+ __webpack_require__(594),
35044
  __webpack_require__(274),
35045
  __webpack_require__(278),
35046
  __webpack_require__(273)
35048
 
35049
  'use strict';
35050
 
35051
+ var Module = {};
35052
+ var base = BaseBlock;
35053
 
35054
  Module.ButtonBlockModel = base.BlockModel.extend({
35055
  defaults: function () {
35169
  }
35170
  });
35171
 
35172
+ App.on('before:start', function (App) {
35173
  App.registerBlockType('button', {
35174
  blockModel: Module.ButtonBlockModel,
35175
  blockView: Module.ButtonBlockView
35188
 
35189
  /***/ },
35190
 
35191
+ /***/ 597:
35192
  /***/ function(module, exports, __webpack_require__) {
35193
 
35194
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
35196
  */
35197
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
35198
  __webpack_require__(574),
35199
+ __webpack_require__(594),
35200
  __webpack_require__(278),
35201
  __webpack_require__(274),
35202
  __webpack_require__(273)
35204
 
35205
  'use strict';
35206
 
35207
+ var Module = {};
35208
+ var base = BaseBlock;
35209
+ var ImageWidgetView;
35210
 
35211
  Module.ImageBlockModel = base.BlockModel.extend({
35212
  defaults: function () {
35241
  elementSelector: '.mailpoet_image',
35242
  resizeHandleSelector: '.mailpoet_image_resize_handle',
35243
  onResize: function (event) {
35244
+ var corner = this.$('.mailpoet_image').offset();
35245
+ var width = event.pageX - corner.left;
35246
  this.view.model.set('width', width + 'px');
35247
  }
35248
  },
35320
  }
35321
  },
35322
  showMediaManager: function () {
35323
+ var that = this;
35324
+ var MediaManager;
35325
+ var theFrame;
35326
  if (this._mediaManager) {
35327
  this._mediaManager.resetSelections();
35328
  this._mediaManager.open();
35329
  return;
35330
  }
35331
 
35332
+ MediaManager = window.wp.media.view.MediaFrame.Select.extend({
35333
 
35334
  initialize: function () {
35335
  window.wp.media.view.MediaFrame.prototype.initialize.apply(this, arguments);
35392
  },
35393
 
35394
  bindHandlers: function () {
35395
+ var handlers;
35396
  // from Select
35397
  this.on('router:create:browse', this.createRouter, this);
35398
  this.on('router:render:browse', this.browseRouter, this);
35407
 
35408
  this.on('updateExcluded', this.browseContent, this);
35409
 
35410
+ handlers = {
35411
  content: {
35412
  embed: 'embedContent',
35413
  'edit-selection': 'editSelectionContent'
35441
  },
35442
 
35443
  editSelectionContent: function () {
35444
+ var state = this.state();
35445
+ var selection = state.get('selection');
35446
+ var view;
35447
 
35448
  view = new window.wp.media.view.AttachmentsBrowser({
35449
  controller: this,
35499
  requires: { selection: true },
35500
 
35501
  click: function () {
35502
+ var state = controller.state();
35503
+ var selection = state.get('selection');
35504
 
35505
  controller.close();
35506
  state.trigger('insert', selection).reset();
35518
 
35519
  });
35520
 
35521
+ theFrame = new MediaManager({
35522
+ id: 'mailpoet-media-manager',
35523
+ frame: 'select',
35524
+ title: 'Select image',
35525
+ editing: false,
35526
+ multiple: false,
35527
+ library: {
35528
+ type: 'image'
35529
+ },
35530
+ displaySettings: false,
35531
+ button: {
35532
+ text: 'Select'
35533
+ }
35534
+ });
 
35535
  this._mediaManager = theFrame;
35536
 
35537
  this._mediaManager.on('insert', function () {
35538
  // Append media manager image selections to Images tab
35539
  var selection = theFrame.state().get('selection');
35540
  selection.each(function (attachment) {
35541
+ var sizes = attachment.get('sizes');
35542
+ // Following advice from Becs, the target width should
35543
+ // be a double of one column width to render well on
35544
+ // retina screen devices
35545
+ var targetImageWidth = 1320;
35546
+
35547
+ // Pick the width that is closest to target width
35548
+ var increasingByWidthDifference = _.sortBy(
35549
+ _.keys(sizes),
35550
+ function (size) { return Math.abs(targetImageWidth - sizes[size].width); }
35551
+ );
35552
+ var bestWidth = sizes[_.first(increasingByWidthDifference)].width;
35553
+ var imagesOfBestWidth = _.filter(_.values(sizes), function (size) { return size.width === bestWidth; });
35554
+
35555
+ // Maximize the height if there are multiple images with same width
35556
+ var mainSize = _.max(imagesOfBestWidth, function (size) { return size.height; });
 
 
 
35557
 
35558
  that.model.set({
35559
  height: mainSize.height + 'px',
35606
  });
35607
  Module.ImageWidgetView = ImageWidgetView;
35608
 
35609
+ App.on('before:start', function (App) {
35610
  App.registerBlockType('image', {
35611
  blockModel: Module.ImageBlockModel,
35612
  blockView: Module.ImageBlockView
35625
 
35626
  /***/ },
35627
 
35628
+ /***/ 598:
35629
  /***/ function(module, exports, __webpack_require__) {
35630
 
35631
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
35633
  */
35634
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
35635
  __webpack_require__(574),
35636
+ __webpack_require__(594),
35637
  __webpack_require__(278),
35638
+ __webpack_require__(273)
35639
+ ], __WEBPACK_AMD_DEFINE_RESULT__ = function (App, BaseBlock, _, jQuery) {
 
35640
 
35641
  'use strict';
35642
 
35643
+ var Module = {};
35644
+ var base = BaseBlock;
35645
 
35646
  Module.DividerBlockModel = base.BlockModel.extend({
35647
  defaults: function () {
35678
  }, base.BlockView.prototype.behaviors),
35679
  onDragSubstituteBy: function () { return Module.DividerWidgetView; },
35680
  initialize: function () {
 
35681
  var that = this;
35682
+ base.BlockView.prototype.initialize.apply(this, arguments);
35683
 
35684
  // Listen for attempts to change all dividers in one go
35685
  this._replaceDividerHandler = function (data) { that.model.set(data); that.model.trigger('applyToAll'); };
35748
  repaintDividerStyleOptions: function () {
35749
  this.$('.mailpoet_field_divider_style > div').css('border-top-color', this.model.get('styles.block.borderColor'));
35750
  },
35751
+ applyToAll: function () {
35752
  App.getChannel().trigger('replaceAllDividers', this.model.toJSON());
35753
  },
35754
  updateValueAndCall: function (fieldToUpdate, callable, event) {
35768
  }
35769
  }
35770
  });
35771
+ App.on('before:start', function (App) {
35772
  App.registerBlockType('divider', {
35773
  blockModel: Module.DividerBlockModel,
35774
  blockView: Module.DividerBlockView
35787
 
35788
  /***/ },
35789
 
35790
+ /***/ 599:
35791
  /***/ function(module, exports, __webpack_require__) {
35792
 
35793
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
35795
  */
35796
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
35797
  __webpack_require__(574),
35798
+ __webpack_require__(594),
35799
  __webpack_require__(278),
35800
  __webpack_require__(274)
35801
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (App, BaseBlock, _, MailPoet) {
35802
 
35803
  'use strict';
35804
 
35805
+ var Module = {};
35806
+ var base = BaseBlock;
35807
 
35808
  Module.TextBlockModel = base.BlockModel.extend({
35809
  defaults: function () {
35886
  }
35887
  });
35888
 
35889
+ App.on('before:start', function (App) {
35890
  App.registerBlockType('text', {
35891
  blockModel: Module.TextBlockModel,
35892
  blockView: Module.TextBlockView
35906
 
35907
  /***/ },
35908
 
35909
+ /***/ 600:
35910
  /***/ function(module, exports, __webpack_require__) {
35911
 
35912
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
35914
  */
35915
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
35916
  __webpack_require__(574),
35917
+ __webpack_require__(594),
35918
  __webpack_require__(278)
35919
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (App, BaseBlock, _) {
35920
 
35921
  'use strict';
35922
 
35923
+ var Module = {};
35924
+ var base = BaseBlock;
35925
 
35926
  Module.SpacerBlockModel = base.BlockModel.extend({
35927
  defaults: function () {
35998
  }
35999
  });
36000
 
36001
+ App.on('before:start', function (App) {
36002
  App.registerBlockType('spacer', {
36003
  blockModel: Module.SpacerBlockModel,
36004
  blockView: Module.SpacerBlockView
36017
 
36018
  /***/ },
36019
 
36020
+ /***/ 601:
36021
  /***/ function(module, exports, __webpack_require__) {
36022
 
36023
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
36025
  */
36026
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
36027
  __webpack_require__(574),
36028
+ __webpack_require__(594),
36029
  __webpack_require__(278),
36030
  __webpack_require__(274)
36031
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (App, BaseBlock, _, MailPoet) {
36032
 
36033
  'use strict';
36034
 
36035
+ var Module = {};
36036
+ var base = BaseBlock;
36037
 
36038
  Module.FooterBlockModel = base.BlockModel.extend({
36039
  defaults: function () {
36132
  }
36133
  });
36134
 
36135
+ App.on('before:start', function (App) {
36136
  App.registerBlockType('footer', {
36137
  blockModel: Module.FooterBlockModel,
36138
  blockView: Module.FooterBlockView
36151
 
36152
  /***/ },
36153
 
36154
+ /***/ 602:
36155
  /***/ function(module, exports, __webpack_require__) {
36156
 
36157
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
36159
  */
36160
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
36161
  __webpack_require__(574),
36162
+ __webpack_require__(594),
36163
  __webpack_require__(278),
36164
  __webpack_require__(274)
36165
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (App, BaseBlock, _, MailPoet) {
36166
 
36167
  'use strict';
36168
 
36169
+ var Module = {};
36170
+ var base = BaseBlock;
36171
 
36172
  Module.HeaderBlockModel = base.BlockModel.extend({
36173
  defaults: function () {
36266
  }
36267
  });
36268
 
36269
+ App.on('before:start', function (App) {
36270
  App.registerBlockType('header', {
36271
  blockModel: Module.HeaderBlockModel,
36272
  blockView: Module.HeaderBlockView
36285
 
36286
  /***/ },
36287
 
36288
+ /***/ 603:
36289
  /***/ function(module, exports, __webpack_require__) {
36290
 
36291
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
36298
  */
36299
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
36300
  __webpack_require__(574),
36301
+ __webpack_require__(594),
36302
+ __webpack_require__(596),
36303
+ __webpack_require__(598),
36304
+ __webpack_require__(578),
36305
  __webpack_require__(274),
36306
  __webpack_require__(564),
36307
  __webpack_require__(278),
36320
 
36321
  'use strict';
36322
 
36323
+ var Module = {};
36324
+ var base = BaseBlock;
36325
 
36326
  Module.ALCSupervisor = SuperModel.extend({
36327
  initialize: function () {
36333
  );
36334
  },
36335
  refresh: function () {
36336
+ var blocks;
36337
  var models = App.findModels(function (model) {
36338
  return model.get('type') === 'automatedLatestContent';
36339
  }) || [];
36340
 
36341
  if (models.length === 0) return;
36342
+ blocks = _.map(models, function (model) {
36343
  return model.toJSON();
36344
  });
36345
 
36351
  _.each(
36352
  _.zip(models, renderedBlocks),
36353
  function (args) {
36354
+ var model = args[0];
36355
+ var contents = args[1];
36356
  model.trigger('refreshPosts', contents);
36357
  }
36358
  );
36441
  }),
36442
  onDragSubstituteBy: function () { return Module.AutomatedLatestContentWidgetView; },
36443
  onRender: function () {
36444
+ var ContainerView = App.getBlockTypeView('container');
36445
+ var renderOptions = {
36446
+ disableTextEditor: true,
36447
+ disableDragAndDrop: true,
36448
+ emptyContainerMessage: MailPoet.I18n.t('noPostsToDisplay')
36449
+ };
36450
  this.toolsView = new Module.AutomatedLatestContentBlockToolsView({ model: this.model });
36451
  this.showChildView('toolsRegion', this.toolsView);
36452
  this.showChildView('postsRegion', new ContainerView({ model: this.model.get('_container'), renderOptions: renderOptions }));
36504
  },
36505
  transport: function (options, success, failure) {
36506
  var taxonomies;
36507
+ var termsPromise;
36508
  var promise = CommunicationComponent.getTaxonomies(
36509
  that.model.get('contentType')
36510
  ).then(function (tax) {
36511
  taxonomies = tax;
36512
  // Fetch available terms based on the list of taxonomies already fetched
36513
+ termsPromise = CommunicationComponent.getTerms({
36514
  search: options.data.term,
36515
  taxonomies: _.keys(taxonomies)
36516
  }).then(function (terms) {
36519
  terms: terms
36520
  };
36521
  });
36522
+ return termsPromise;
36523
  });
36524
 
36525
  promise.then(success);
36556
  }
36557
  }).trigger('change');
36558
  },
36559
+ toggleDisplayOptions: function () {
36560
+ var el = this.$('.mailpoet_automated_latest_content_display_options');
36561
+ var showControl = this.$('.mailpoet_automated_latest_content_show_display_options');
36562
  if (el.hasClass('mailpoet_closed')) {
36563
  el.removeClass('mailpoet_closed');
36564
  showControl.addClass('mailpoet_hidden');
36567
  showControl.removeClass('mailpoet_hidden');
36568
  }
36569
  },
36570
+ showButtonSettings: function () {
36571
  var buttonModule = ButtonBlock;
36572
  (new buttonModule.ButtonBlockSettingsView({
36573
  model: this.model.get('readMoreButton'),
36578
  }
36579
  })).render();
36580
  },
36581
+ showDividerSettings: function () {
36582
  var dividerModule = DividerBlock;
36583
  (new dividerModule.DividerBlockSettingsView({
36584
  model: this.model.get('divider'),
36641
  this.changeField('titleFormat', event);
36642
  },
36643
  _updateContentTypes: function (postTypes) {
36644
+ var select = this.$('.mailpoet_automated_latest_content_content_type');
36645
+ var selectedValue = this.model.get('contentType');
36646
 
36647
  select.find('option').remove();
36648
  _.each(postTypes, function (type) {
36670
  }
36671
  });
36672
 
36673
+ App.on('before:start', function (App) {
36674
  App.registerBlockType('automatedLatestContent', {
36675
  blockModel: Module.AutomatedLatestContentBlockModel,
36676
  blockView: Module.AutomatedLatestContentBlockView
36683
  });
36684
  });
36685
 
36686
+ App.on('start', function (App) {
36687
  var Application = App;
36688
  Application._ALCSupervisor = new Module.ALCSupervisor();
36689
  Application._ALCSupervisor.refresh();
36695
 
36696
  /***/ },
36697
 
36698
+ /***/ 604:
36699
  /***/ function(module, exports, __webpack_require__) {
36700
 
36701
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
36718
  __webpack_require__(273),
36719
  __webpack_require__(274),
36720
  __webpack_require__(574),
36721
+ __webpack_require__(578),
36722
+ __webpack_require__(594),
36723
+ __webpack_require__(596),
36724
+ __webpack_require__(598),
36725
  __webpack_require__(287)
36726
  ], __WEBPACK_AMD_DEFINE_RESULT__ = function (
36727
  Backbone,
36739
 
36740
  'use strict';
36741
 
36742
+ var Module = {};
36743
+ var base = BaseBlock;
36744
+ var PostsDisplayOptionsSettingsView;
36745
+ var SinglePostSelectionSettingsView;
36746
+ var EmptyPostSelectionSettingsView;
36747
+ var PostSelectionSettingsView;
36748
+ var PostsSelectionCollectionView;
36749
 
36750
  Module.PostsBlockModel = base.BlockModel.extend({
36751
  stale: ['_selectedPosts', '_availablePosts', '_transformedPosts'],
36794
  };
36795
  },
36796
  initialize: function () {
36797
+ var POST_REFRESH_DELAY_MS = 500;
36798
+ var refreshAvailablePosts = _.debounce(this.fetchAvailablePosts.bind(this), POST_REFRESH_DELAY_MS);
36799
+ var refreshTransformedPosts = _.debounce(this._refreshTransformedPosts.bind(this), POST_REFRESH_DELAY_MS);
 
36800
 
36801
  // Attach Radio.Requests API primarily for highlighting
36802
  _.extend(this, Radio.Requests);
36824
  });
36825
  },
36826
  _loadMorePosts: function () {
36827
+ var that = this;
36828
+ var postCount = this.get('_availablePosts').length;
36829
+ var nextOffset = this.get('offset') + Number(this.get('amount'));
36830
 
36831
  if (postCount === 0 || postCount < nextOffset) {
36832
  // No more posts to load
36845
  });
36846
  },
36847
  _refreshTransformedPosts: function () {
36848
+ var that = this;
36849
+ var data = this.toJSON();
36850
 
36851
  data.posts = this.get('_selectedPosts').pluck('ID');
36852
 
36862
  });
36863
  },
36864
  _insertSelectedPosts: function () {
36865
+ var data = this.toJSON();
36866
+ var index = this.collection.indexOf(this);
36867
+ var collection = this.collection;
 
36868
 
36869
  data.posts = this.get('_selectedPosts').pluck('ID');
36870
 
36893
  this.model.reply('blockView', this.notifyAboutSelf, this);
36894
  },
36895
  onRender: function () {
36896
+ var ContainerView;
36897
+ var renderOptions;
36898
  if (!this.getRegion('toolsRegion').hasView()) {
36899
  this.showChildView('toolsRegion', this.toolsView);
36900
  }
36901
  this.trigger('showSettings');
36902
 
36903
+ ContainerView = App.getBlockTypeView('container');
36904
+ renderOptions = {
36905
+ disableTextEditor: true,
36906
+ disableDragAndDrop: true,
36907
+ emptyContainerMessage: MailPoet.I18n.t('noPostsToDisplay')
36908
+ };
36909
  this.showChildView('postsRegion', new ContainerView({ model: this.model.get('_transformedPosts'), renderOptions: renderOptions }));
36910
  },
36911
  notifyAboutSelf: function () {
36942
  this.displayOptionsView = new PostsDisplayOptionsSettingsView({ model: this.model });
36943
  },
36944
  onRender: function () {
36945
+ var that = this;
36946
+ this.model.request('blockView');
36947
 
36948
  this.showChildView('selectionRegion', this.selectionView);
36949
  this.showChildView('displayOptionsRegion', this.displayOptionsView);
36988
  }
36989
  });
36990
 
36991
+ PostsSelectionCollectionView = Marionette.CollectionView.extend({
36992
  className: 'mailpoet_post_scroll_container',
36993
  childView: function () { return SinglePostSelectionSettingsView; },
36994
  emptyView: function () { return EmptyPostSelectionSettingsView; },
37012
  }
37013
  });
37014
 
37015
+ PostSelectionSettingsView = Marionette.View.extend({
37016
  getTemplate: function () { return window.templates.postSelectionPostsBlockSettings; },
37017
  regions: {
37018
  posts: '.mailpoet_post_selection_container'
37039
  }
37040
  },
37041
  onRender: function () {
37042
+ var postsView;
37043
  // Dynamically update available post types
37044
  CommunicationComponent.getPostTypes().done(_.bind(this._updateContentTypes, this));
37045
+ postsView = new PostsSelectionCollectionView({
37046
  collection: this.model.get('_availablePosts'),
37047
  blockModel: this.model
37048
  });
37064
  },
37065
  transport: function (options, success, failure) {
37066
  var taxonomies;
37067
+ var termsPromise;
37068
  var promise = CommunicationComponent.getTaxonomies(
37069
  that.model.get('contentType')
37070
  ).then(function (tax) {
37071
  taxonomies = tax;
37072
  // Fetch available terms based on the list of taxonomies already fetched
37073
+ termsPromise = CommunicationComponent.getTerms({
37074
  search: options.data.term,
37075
  taxonomies: _.keys(taxonomies)
37076
  }).then(function (terms) {
37079
  terms: terms
37080
  };
37081
  });
37082
+ return termsPromise;
37083
  });
37084
 
37085
  promise.then(success);
37120
  this.model.set(field, jQuery(event.target).val());
37121
  },
37122
  _updateContentTypes: function (postTypes) {
37123
+ var select = this.$('.mailpoet_settings_posts_content_type');
37124
+ var selectedValue = this.model.get('contentType');
37125
 
37126
  select.find('option').remove();
37127
  _.each(postTypes, function (type) {
37134
  }
37135
  });
37136
 
37137
+ EmptyPostSelectionSettingsView = Marionette.View.extend({
37138
  getTemplate: function () { return window.templates.emptyPostPostsBlockSettings; }
37139
  });
37140
 
37141
+ SinglePostSelectionSettingsView = Marionette.View.extend({
37142
  getTemplate: function () { return window.templates.singlePostPostsBlockSettings; },
37143
  events: function () {
37144
  return {
37155
  this.blockModel = options.blockModel;
37156
  },
37157
  postSelectionChange: function (event) {
37158
+ var checkBox = jQuery(event.target);
37159
+ var selectedPostsCollection = this.blockModel.get('_selectedPosts');
37160
  if (checkBox.prop('checked')) {
37161
  selectedPostsCollection.add(this.model);
37162
  } else {
37165
  }
37166
  });
37167
 
37168
+ PostsDisplayOptionsSettingsView = base.BlockSettingsView.extend({
37169
  getTemplate: function () { return window.templates.displayOptionsPostsBlockSettings; },
37170
  events: function () {
37171
  return {
37195
  model: this.model.toJSON()
37196
  };
37197
  },
37198
+ showButtonSettings: function () {
37199
  var buttonModule = ButtonBlock;
37200
  (new buttonModule.ButtonBlockSettingsView({
37201
  model: this.model.get('readMoreButton'),
37206
  }
37207
  })).render();
37208
  },
37209
+ showDividerSettings: function () {
37210
  var dividerModule = DividerBlock;
37211
  (new dividerModule.DividerBlockSettingsView({
37212
  model: this.model.get('divider'),
37282
  }
37283
  });
37284
 
37285
+ App.on('before:start', function (App) {
37286
  App.registerBlockType('posts', {
37287
  blockModel: Module.PostsBlockModel,
37288
  blockView: Module.PostsBlockView
37301
 
37302
  /***/ },
37303
 
37304
+ /***/ 605:
37305
  /***/ function(module, exports, __webpack_require__) {
37306
 
37307
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
37309
  */
37310
  !(__WEBPACK_AMD_DEFINE_ARRAY__ = [
37311
  __webpack_require__(574),
37312
+ __webpack_require__(594),
37313
  __webpack_require__(535),
37314
  __webpack_require__(562),
37315
  __webpack_require__(564),
37319
 
37320
  'use strict';
37321
 
37322
+ var Module = {};
37323
+ var base = BaseBlock;
37324
+ var SocialBlockSettingsIconSelectorView;
37325
+ var SocialBlockSettingsIconView;
37326
+ var SocialBlockSettingsIconCollectionView;
37327
+ var SocialBlockSettingsStylesView;
37328
+ var SocialIconView;
37329
 
37330
  Module.SocialIconModel = SuperModel.extend({
37331
  defaults: function () {
37340
  text: defaultValues.get('title')
37341
  };
37342
  },
37343
+ initialize: function () {
37344
  var that = this;
37345
  // Make model swap to default values for that type when iconType changes
37346
  this.on('change:iconType', function () {
37347
+ var defaultValues = App.getConfig().get('socialIcons').get(that.get('iconType'));
37348
+ var iconSet = that.collection.iconBlockModel.getIconSet();
37349
  this.set({
37350
  link: defaultValues.get('defaultLink'),
37351
  image: iconSet.get(that.get('iconType')),
37390
  }
37391
  });
37392
 
37393
+ SocialIconView = Marionette.View.extend({
37394
  tagName: 'span',
37395
  getTemplate: function () { return window.templates.socialIconBlock; },
37396
  modelEvents: {
37482
  }
37483
  },
37484
  templateContext: function () {
37485
+ var icons = App.getConfig().get('socialIcons');
37486
+ // Construct icon type list of format [{iconType: 'type', title: 'Title'}, ...]
37487
+ var availableIconTypes = _.map(_.keys(icons.attributes), function (key) { return { iconType: key, title: icons.get(key).get('title') }; });
37488
+ var allIconSets = App.getAvailableStyles().get('socialIconSets');
37489
  return _.extend({}, base.BlockView.prototype.templateContext.apply(this, arguments), {
37490
  iconTypes: availableIconTypes,
37491
  currentType: icons.get(this.model.get('iconType')).toJSON(),
37604
  }
37605
  });
37606
 
37607
+ App.on('before:start', function (App) {
37608
  App.registerBlockType('social', {
37609
  blockModel: Module.SocialBlockModel,
37610
  blockView: Module.SocialBlockView
assets/js/public.6e3f442a.js DELETED
@@ -1,4493 +0,0 @@
1
- /******/ (function(modules) { // webpackBootstrap
2
- /******/ // The module cache
3
- /******/ var installedModules = {};
4
-
5
- /******/ // The require function
6
- /******/ function __webpack_require__(moduleId) {
7
-
8
- /******/ // Check if module is in cache
9
- /******/ if(installedModules[moduleId])
10
- /******/ return installedModules[moduleId].exports;
11
-
12
- /******/ // Create a new module (and put it into the cache)
13
- /******/ var module = installedModules[moduleId] = {
14
- /******/ exports: {},
15
- /******/ id: moduleId,
16
- /******/ loaded: false
17
- /******/ };
18
-
19
- /******/ // Execute the module function
20
- /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
21
-
22
- /******/ // Flag the module as loaded
23
- /******/ module.loaded = true;
24
-
25
- /******/ // Return the exports of the module
26
- /******/ return module.exports;
27
- /******/ }
28
-
29
-
30
- /******/ // expose the modules object (__webpack_modules__)
31
- /******/ __webpack_require__.m = modules;
32
-
33
- /******/ // expose the module cache
34
- /******/ __webpack_require__.c = installedModules;
35
-
36
- /******/ // __webpack_public_path__
37
- /******/ __webpack_require__.p = "";
38
-
39
- /******/ // Load entry module and return exports
40
- /******/ return __webpack_require__(0);
41
- /******/ })
42
- /************************************************************************/
43
- /******/ ([
44
- /* 0 */
45
- /***/ function(module, exports, __webpack_require__) {
46
-
47
- __webpack_require__(1);
48
- __webpack_require__(2);
49
- __webpack_require__(3);
50
- __webpack_require__(7);
51
- __webpack_require__(8);
52
- module.exports = __webpack_require__(9);
53
-
54
-
55
- /***/ },
56
- /* 1 */
57
- /***/ function(module, exports, __webpack_require__) {
58
-
59
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function () {
60
- // A placeholder for MailPoet object
61
- var MailPoet = {};
62
-
63
- // Expose MailPoet globally
64
- window.MailPoet = MailPoet;
65
-
66
- return MailPoet;
67
- }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
68
-
69
-
70
- /***/ },
71
- /* 2 */
72
- /***/ function(module, exports, __webpack_require__) {
73
-
74
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
75
- __webpack_require__(1)
76
- ], __WEBPACK_AMD_DEFINE_RESULT__ = function (
77
- mp
78
- ) {
79
- 'use strict';
80
-
81
- var MailPoet = mp;
82
-
83
- var translations = {};
84
-
85
- MailPoet.I18n = {
86
- add: function (key, value) {
87
- translations[key] = value;
88
- },
89
- t: function (key) {
90
- return translations[key] || 'TRANSLATION "%$1s" NOT FOUND'.replace('%$1s', key);
91
- },
92
- all: function () {
93
- return translations;
94
- }
95
- };
96
-
97
- }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
98
-
99
-
100
- /***/ },
101
- /* 3 */
102
- /***/ function(module, exports, __webpack_require__) {
103
-
104
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function requestFailed(errorMessage, xhr) {
105
- if (xhr.responseJSON) {
106
- return xhr.responseJSON;
107
- }
108
- var message = errorMessage.replace('%d', xhr.status);
109
- return {
110
- errors: [
111
- {
112
- message: message
113
- }
114
- ]
115
- };
116
- }
117
-
118
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(1), __webpack_require__(4), __webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = function (mp, jQuery, _) {
119
- var MailPoet = mp;
120
-
121
- MailPoet.Ajax = {
122
- version: 0.5,
123
- options: {},
124
- defaults: {
125
- url: null,
126
- api_version: null,
127
- endpoint: null,
128
- action: null,
129
- token: null,
130
- data: {}
131
- },
132
- post: function (options) {
133
- return this.request('post', options);
134
- },
135
- init: function (options) {
136
- // merge options
137
- this.options = jQuery.extend({}, this.defaults, options);
138
-
139
- // set default url
140
- if (this.options.url === null) {
141
- this.options.url = window.ajaxurl;
142
- }
143
-
144
- // set default token
145
- if (this.options.token === null) {
146
- this.options.token = window.mailpoet_token;
147
- }
148
- },
149
- getParams: function () {
150
- return {
151
- action: 'mailpoet',
152
- api_version: this.options.api_version,
153
- token: this.options.token,
154
- endpoint: this.options.endpoint,
155
- method: this.options.action,
156
- data: this.options.data || {}
157
- };
158
- },
159
- request: function (method, options) {
160
- // set options
161
- this.init(options);
162
-
163
- // set request params
164
- var params = this.getParams();
165
-
166
- // remove null values from the data object
167
- if (_.isObject(params.data)) {
168
- params.data = _.pick(params.data, function (value) {
169
- return (value !== null);
170
- });
171
- }
172
-
173
- // ajax request
174
- var deferred = jQuery.post(
175
- this.options.url,
176
- params,
177
- null,
178
- 'json'
179
- ).then(function (data) {
180
- return data;
181
- }, _.partial(requestFailed, MailPoet.I18n.t('ajaxFailedErrorMessage')));
182
-
183
- // clear options
184
- this.options = {};
185
-
186
- return deferred;
187
- }
188
- };
189
- }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
190
-
191
-
192
- /***/ },
193
- /* 4 */
194
- /***/ function(module, exports) {
195
-
196
- module.exports = jQuery;
197
-
198
- /***/ },
199
- /* 5 */
200
- /***/ function(module, exports, __webpack_require__) {
201
-
202
- /* WEBPACK VAR INJECTION */(function(global) {module.exports = global["_"] = __webpack_require__(6);
203
- /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
204
-
205
- /***/ },
206
- /* 6 */
207
- /***/ function(module, exports, __webpack_require__) {
208
-
209
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// Underscore.js 1.8.3
210
- // http://underscorejs.org
211
- // (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
212
- // Underscore may be freely distributed under the MIT license.
213
-
214
- (function() {
215
-
216
- // Baseline setup
217
- // --------------
218
-
219
- // Establish the root object, `window` in the browser, or `exports` on the server.
220
- var root = this;
221
-
222
- // Save the previous value of the `_` variable.
223
- var previousUnderscore = root._;
224
-
225
- // Save bytes in the minified (but not gzipped) version:
226
- var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
227
-
228
- // Create quick reference variables for speed access to core prototypes.
229
- var
230
- push = ArrayProto.push,
231
- slice = ArrayProto.slice,
232
- toString = ObjProto.toString,
233
- hasOwnProperty = ObjProto.hasOwnProperty;
234
-
235
- // All **ECMAScript 5** native function implementations that we hope to use
236
- // are declared here.
237
- var
238
- nativeIsArray = Array.isArray,
239
- nativeKeys = Object.keys,
240
- nativeBind = FuncProto.bind,
241
- nativeCreate = Object.create;
242
-
243
- // Naked function reference for surrogate-prototype-swapping.
244
- var Ctor = function(){};
245
-
246
- // Create a safe reference to the Underscore object for use below.
247
- var _ = function(obj) {
248
- if (obj instanceof _) return obj;
249
- if (!(this instanceof _)) return new _(obj);
250
- this._wrapped = obj;
251
- };
252
-
253
- // Export the Underscore object for **Node.js**, with
254
- // backwards-compatibility for the old `require()` API. If we're in
255
- // the browser, add `_` as a global object.
256
- if (true) {
257
- if (typeof module !== 'undefined' && module.exports) {
258
- exports = module.exports = _;
259
- }
260
- exports._ = _;
261
- } else {
262
- root._ = _;
263
- }
264
-
265
- // Current version.
266
- _.VERSION = '1.8.3';
267
-
268
- // Internal function that returns an efficient (for current engines) version
269
- // of the passed-in callback, to be repeatedly applied in other Underscore
270
- // functions.
271
- var optimizeCb = function(func, context, argCount) {
272
- if (context === void 0) return func;
273
- switch (argCount == null ? 3 : argCount) {
274
- case 1: return function(value) {
275
- return func.call(context, value);
276
- };
277
- case 2: return function(value, other) {
278
- return func.call(context, value, other);
279
- };
280
- case 3: return function(value, index, collection) {
281
- return func.call(context, value, index, collection);
282
- };
283
- case 4: return function(accumulator, value, index, collection) {
284
- return func.call(context, accumulator, value, index, collection);
285
- };
286
- }
287
- return function() {
288
- return func.apply(context, arguments);
289
- };
290
- };
291
-
292
- // A mostly-internal function to generate callbacks that can be applied
293
- // to each element in a collection, returning the desired result — either
294
- // identity, an arbitrary callback, a property matcher, or a property accessor.
295
- var cb = function(value, context, argCount) {
296
- if (value == null) return _.identity;
297
- if (_.isFunction(value)) return optimizeCb(value, context, argCount);
298
- if (_.isObject(value)) return _.matcher(value);
299
- return _.property(value);
300
- };
301
- _.iteratee = function(value, context) {
302
- return cb(value, context, Infinity);
303
- };
304
-
305
- // An internal function for creating assigner functions.
306
- var createAssigner = function(keysFunc, undefinedOnly) {
307
- return function(obj) {
308
- var length = arguments.length;
309
- if (length < 2 || obj == null) return obj;
310
- for (var index = 1; index < length; index++) {
311
- var source = arguments[index],
312
- keys = keysFunc(source),
313
- l = keys.length;
314
- for (var i = 0; i < l; i++) {
315
- var key = keys[i];
316
- if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
317
- }
318
- }
319
- return obj;
320
- };
321
- };
322
-
323
- // An internal function for creating a new object that inherits from another.
324
- var baseCreate = function(prototype) {
325
- if (!_.isObject(prototype)) return {};
326
- if (nativeCreate) return nativeCreate(prototype);
327
- Ctor.prototype = prototype;
328
- var result = new Ctor;
329
- Ctor.prototype = null;
330
- return result;
331
- };
332
-
333
- var property = function(key) {
334
- return function(obj) {
335
- return obj == null ? void 0 : obj[key];
336
- };
337
- };
338
-
339
- // Helper for collection methods to determine whether a collection
340
- // should be iterated as an array or as an object
341
- // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
342
- // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
343
- var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
344
- var getLength = property('length');
345
- var isArrayLike = function(collection) {
346
- var length = getLength(collection);
347
- return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
348
- };
349
-
350
- // Collection Functions
351
- // --------------------
352
-
353
- // The cornerstone, an `each` implementation, aka `forEach`.
354
- // Handles raw objects in addition to array-likes. Treats all
355
- // sparse array-likes as if they were dense.
356
- _.each = _.forEach = function(obj, iteratee, context) {
357
- iteratee = optimizeCb(iteratee, context);
358
- var i, length;
359
- if (isArrayLike(obj)) {
360
- for (i = 0, length = obj.length; i < length; i++) {
361
- iteratee(obj[i], i, obj);
362
- }
363
- } else {
364
- var keys = _.keys(obj);
365
- for (i = 0, length = keys.length; i < length; i++) {
366
- iteratee(obj[keys[i]], keys[i], obj);
367
- }
368
- }
369
- return obj;
370
- };
371
-
372
- // Return the results of applying the iteratee to each element.
373
- _.map = _.collect = function(obj, iteratee, context) {
374
- iteratee = cb(iteratee, context);
375
- var keys = !isArrayLike(obj) && _.keys(obj),
376
- length = (keys || obj).length,
377
- results = Array(length);
378
- for (var index = 0; index < length; index++) {
379
- var currentKey = keys ? keys[index] : index;
380
- results[index] = iteratee(obj[currentKey], currentKey, obj);
381
- }
382
- return results;
383
- };
384
-
385
- // Create a reducing function iterating left or right.
386
- function createReduce(dir) {
387
- // Optimized iterator function as using arguments.length
388
- // in the main function will deoptimize the, see #1991.
389
- function iterator(obj, iteratee, memo, keys, index, length) {
390
- for (; index >= 0 && index < length; index += dir) {
391
- var currentKey = keys ? keys[index] : index;
392
- memo = iteratee(memo, obj[currentKey], currentKey, obj);
393
- }
394
- return memo;
395
- }
396
-
397
- return function(obj, iteratee, memo, context) {
398
- iteratee = optimizeCb(iteratee, context, 4);
399
- var keys = !isArrayLike(obj) && _.keys(obj),
400
- length = (keys || obj).length,
401
- index = dir > 0 ? 0 : length - 1;
402
- // Determine the initial value if none is provided.
403
- if (arguments.length < 3) {
404
- memo = obj[keys ? keys[index] : index];
405
- index += dir;
406
- }
407
- return iterator(obj, iteratee, memo, keys, index, length);
408
- };
409
- }
410
-
411
- // **Reduce** builds up a single result from a list of values, aka `inject`,
412
- // or `foldl`.
413
- _.reduce = _.foldl = _.inject = createReduce(1);
414
-
415
- // The right-associative version of reduce, also known as `foldr`.
416
- _.reduceRight = _.foldr = createReduce(-1);
417
-
418
- // Return the first value which passes a truth test. Aliased as `detect`.
419
- _.find = _.detect = function(obj, predicate, context) {
420
- var key;
421
- if (isArrayLike(obj)) {
422
- key = _.findIndex(obj, predicate, context);
423
- } else {
424
- key = _.findKey(obj, predicate, context);
425
- }
426
- if (key !== void 0 && key !== -1) return obj[key];
427
- };
428
-
429
- // Return all the elements that pass a truth test.
430
- // Aliased as `select`.
431
- _.filter = _.select = function(obj, predicate, context) {
432
- var results = [];
433
- predicate = cb(predicate, context);
434
- _.each(obj, function(value, index, list) {
435
- if (predicate(value, index, list)) results.push(value);
436
- });
437
- return results;
438
- };
439
-
440
- // Return all the elements for which a truth test fails.
441
- _.reject = function(obj, predicate, context) {
442
- return _.filter(obj, _.negate(cb(predicate)), context);
443
- };
444
-
445
- // Determine whether all of the elements match a truth test.
446
- // Aliased as `all`.
447
- _.every = _.all = function(obj, predicate, context) {
448
- predicate = cb(predicate, context);
449
- var keys = !isArrayLike(obj) && _.keys(obj),
450
- length = (keys || obj).length;
451
- for (var index = 0; index < length; index++) {
452
- var currentKey = keys ? keys[index] : index;
453
- if (!predicate(obj[currentKey], currentKey, obj)) return false;
454
- }
455
- return true;
456
- };
457
-
458
- // Determine if at least one element in the object matches a truth test.
459
- // Aliased as `any`.
460
- _.some = _.any = function(obj, predicate, context) {
461
- predicate = cb(predicate, context);
462
- var keys = !isArrayLike(obj) && _.keys(obj),
463
- length = (keys || obj).length;
464
- for (var index = 0; index < length; index++) {
465
- var currentKey = keys ? keys[index] : index;
466
- if (predicate(obj[currentKey], currentKey, obj)) return true;
467
- }
468
- return false;
469
- };
470
-
471
- // Determine if the array or object contains a given item (using `===`).
472
- // Aliased as `includes` and `include`.
473
- _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) {
474
- if (!isArrayLike(obj)) obj = _.values(obj);
475
- if (typeof fromIndex != 'number' || guard) fromIndex = 0;
476
- return _.indexOf(obj, item, fromIndex) >= 0;
477
- };
478
-
479
- // Invoke a method (with arguments) on every item in a collection.
480
- _.invoke = function(obj, method) {
481
- var args = slice.call(arguments, 2);
482
- var isFunc = _.isFunction(method);
483
- return _.map(obj, function(value) {
484
- var func = isFunc ? method : value[method];
485
- return func == null ? func : func.apply(value, args);
486
- });
487
- };
488
-
489
- // Convenience version of a common use case of `map`: fetching a property.
490
- _.pluck = function(obj, key) {
491
- return _.map(obj, _.property(key));
492
- };
493
-
494
- // Convenience version of a common use case of `filter`: selecting only objects
495
- // containing specific `key:value` pairs.
496
- _.where = function(obj, attrs) {
497
- return _.filter(obj, _.matcher(attrs));
498
- };
499
-
500
- // Convenience version of a common use case of `find`: getting the first object
501
- // containing specific `key:value` pairs.
502
- _.findWhere = function(obj, attrs) {
503
- return _.find(obj, _.matcher(attrs));
504
- };
505
-
506
- // Return the maximum element (or element-based computation).
507
- _.max = function(obj, iteratee, context) {
508
- var result = -Infinity, lastComputed = -Infinity,
509
- value, computed;
510
- if (iteratee == null && obj != null) {
511
- obj = isArrayLike(obj) ? obj : _.values(obj);
512
- for (var i = 0, length = obj.length; i < length; i++) {
513
- value = obj[i];
514
- if (value > result) {
515
- result = value;
516
- }
517
- }
518
- } else {
519
- iteratee = cb(iteratee, context);
520
- _.each(obj, function(value, index, list) {
521
- computed = iteratee(value, index, list);
522
- if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
523
- result = value;
524
- lastComputed = computed;
525
- }
526
- });
527
- }
528
- return result;
529
- };
530
-
531
- // Return the minimum element (or element-based computation).
532
- _.min = function(obj, iteratee, context) {
533
- var result = Infinity, lastComputed = Infinity,
534
- value, computed;
535
- if (iteratee == null && obj != null) {
536
- obj = isArrayLike(obj) ? obj : _.values(obj);
537
- for (var i = 0, length = obj.length; i < length; i++) {
538
- value = obj[i];
539
- if (value < result) {
540
- result = value;
541
- }
542
- }
543
- } else {
544
- iteratee = cb(iteratee, context);
545
- _.each(obj, function(value, index, list) {
546
- computed = iteratee(value, index, list);
547
- if (computed < lastComputed || computed === Infinity && result === Infinity) {
548
- result = value;
549
- lastComputed = computed;
550
- }
551
- });
552
- }
553
- return result;
554
- };
555
-
556
- // Shuffle a collection, using the modern version of the
557
- // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
558
- _.shuffle = function(obj) {
559
- var set = isArrayLike(obj) ? obj : _.values(obj);
560
- var length = set.length;
561
- var shuffled = Array(length);
562
- for (var index = 0, rand; index < length; index++) {
563
- rand = _.random(0, index);
564
- if (rand !== index) shuffled[index] = shuffled[rand];
565
- shuffled[rand] = set[index];
566
- }
567
- return shuffled;
568
- };
569
-
570
- // Sample **n** random values from a collection.
571
- // If **n** is not specified, returns a single random element.
572
- // The internal `guard` argument allows it to work with `map`.
573
- _.sample = function(obj, n, guard) {
574
- if (n == null || guard) {
575
- if (!isArrayLike(obj)) obj = _.values(obj);
576
- return obj[_.random(obj.length - 1)];
577
- }
578
- return _.shuffle(obj).slice(0, Math.max(0, n));
579
- };
580
-
581
- // Sort the object's values by a criterion produced by an iteratee.
582
- _.sortBy = function(obj, iteratee, context) {
583
- iteratee = cb(iteratee, context);
584
- return _.pluck(_.map(obj, function(value, index, list) {
585
- return {
586
- value: value,
587
- index: index,
588
- criteria: iteratee(value, index, list)
589
- };
590
- }).sort(function(left, right) {
591
- var a = left.criteria;
592
- var b = right.criteria;
593
- if (a !== b) {
594
- if (a > b || a === void 0) return 1;
595
- if (a < b || b === void 0) return -1;
596
- }
597
- return left.index - right.index;
598
- }), 'value');
599
- };
600
-
601
- // An internal function used for aggregate "group by" operations.
602
- var group = function(behavior) {
603
- return function(obj, iteratee, context) {
604
- var result = {};
605
- iteratee = cb(iteratee, context);
606
- _.each(obj, function(value, index) {
607
- var key = iteratee(value, index, obj);
608
- behavior(result, value, key);
609
- });
610
- return result;
611
- };
612
- };
613
-
614
- // Groups the object's values by a criterion. Pass either a string attribute
615
- // to group by, or a function that returns the criterion.
616
- _.groupBy = group(function(result, value, key) {
617
- if (_.has(result, key)) result[key].push(value); else result[key] = [value];
618
- });
619
-
620
- // Indexes the object's values by a criterion, similar to `groupBy`, but for
621
- // when you know that your index values will be unique.
622
- _.indexBy = group(function(result, value, key) {
623
- result[key] = value;
624
- });
625
-
626
- // Counts instances of an object that group by a certain criterion. Pass
627
- // either a string attribute to count by, or a function that returns the
628
- // criterion.
629
- _.countBy = group(function(result, value, key) {
630
- if (_.has(result, key)) result[key]++; else result[key] = 1;
631
- });
632
-
633
- // Safely create a real, live array from anything iterable.
634
- _.toArray = function(obj) {
635
- if (!obj) return [];
636
- if (_.isArray(obj)) return slice.call(obj);
637
- if (isArrayLike(obj)) return _.map(obj, _.identity);
638
- return _.values(obj);
639
- };
640
-
641
- // Return the number of elements in an object.
642
- _.size = function(obj) {
643
- if (obj == null) return 0;
644
- return isArrayLike(obj) ? obj.length : _.keys(obj).length;
645
- };
646
-
647
- // Split a collection into two arrays: one whose elements all satisfy the given
648
- // predicate, and one whose elements all do not satisfy the predicate.
649
- _.partition = function(obj, predicate, context) {
650
- predicate = cb(predicate, context);
651
- var pass = [], fail = [];
652
- _.each(obj, function(value, key, obj) {
653
- (predicate(value, key, obj) ? pass : fail).push(value);
654
- });
655
- return [pass, fail];
656
- };
657
-
658
- // Array Functions
659
- // ---------------
660
-
661
- // Get the first element of an array. Passing **n** will return the first N
662
- // values in the array. Aliased as `head` and `take`. The **guard** check
663
- // allows it to work with `_.map`.
664
- _.first = _.head = _.take = function(array, n, guard) {
665
- if (array == null) return void 0;
666
- if (n == null || guard) return array[0];
667
- return _.initial(array, array.length - n);
668
- };
669
-
670
- // Returns everything but the last entry of the array. Especially useful on
671
- // the arguments object. Passing **n** will return all the values in
672
- // the array, excluding the last N.
673
- _.initial = function(array, n, guard) {
674
- return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
675
- };
676
-
677
- // Get the last element of an array. Passing **n** will return the last N
678
- // values in the array.
679
- _.last = function(array, n, guard) {
680
- if (array == null) return void 0;
681
- if (n == null || guard) return array[array.length - 1];
682
- return _.rest(array, Math.max(0, array.length - n));
683
- };
684
-
685
- // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
686
- // Especially useful on the arguments object. Passing an **n** will return
687
- // the rest N values in the array.
688
- _.rest = _.tail = _.drop = function(array, n, guard) {
689
- return slice.call(array, n == null || guard ? 1 : n);
690
- };
691
-
692
- // Trim out all falsy values from an array.
693
- _.compact = function(array) {
694
- return _.filter(array, _.identity);
695
- };
696
-
697
- // Internal implementation of a recursive `flatten` function.
698
- var flatten = function(input, shallow, strict, startIndex) {
699
- var output = [], idx = 0;
700
- for (var i = startIndex || 0, length = getLength(input); i < length; i++) {
701
- var value = input[i];
702
- if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
703
- //flatten current level of array or arguments object
704
- if (!shallow) value = flatten(value, shallow, strict);
705
- var j = 0, len = value.length;
706
- output.length += len;
707
- while (j < len) {
708
- output[idx++] = value[j++];
709
- }
710
- } else if (!strict) {
711
- output[idx++] = value;
712
- }
713
- }
714
- return output;
715
- };
716
-
717
- // Flatten out an array, either recursively (by default), or just one level.
718
- _.flatten = function(array, shallow) {
719
- return flatten(array, shallow, false);
720
- };
721
-
722
- // Return a version of the array that does not contain the specified value(s).
723
- _.without = function(array) {
724
- return _.difference(array, slice.call(arguments, 1));
725
- };
726
-
727
- // Produce a duplicate-free version of the array. If the array has already
728
- // been sorted, you have the option of using a faster algorithm.
729
- // Aliased as `unique`.
730
- _.uniq = _.unique = function(array, isSorted, iteratee, context) {
731
- if (!_.isBoolean(isSorted)) {
732
- context = iteratee;
733
- iteratee = isSorted;
734
- isSorted = false;
735
- }
736
- if (iteratee != null) iteratee = cb(iteratee, context);
737
- var result = [];
738
- var seen = [];
739
- for (var i = 0, length = getLength(array); i < length; i++) {
740
- var value = array[i],
741
- computed = iteratee ? iteratee(value, i, array) : value;
742
- if (isSorted) {
743
- if (!i || seen !== computed) result.push(value);
744
- seen = computed;
745
- } else if (iteratee) {
746
- if (!_.contains(seen, computed)) {
747
- seen.push(computed);
748
- result.push(value);
749
- }
750
- } else if (!_.contains(result, value)) {
751
- result.push(value);
752
- }
753
- }
754
- return result;
755
- };
756
-
757
- // Produce an array that contains the union: each distinct element from all of
758
- // the passed-in arrays.
759
- _.union = function() {
760
- return _.uniq(flatten(arguments, true, true));
761
- };
762
-
763
- // Produce an array that contains every item shared between all the
764
- // passed-in arrays.
765
- _.intersection = function(array) {
766
- var result = [];
767
- var argsLength = arguments.length;
768
- for (var i = 0, length = getLength(array); i < length; i++) {
769
- var item = array[i];
770
- if (_.contains(result, item)) continue;
771
- for (var j = 1; j < argsLength; j++) {
772
- if (!_.contains(arguments[j], item)) break;
773
- }
774
- if (j === argsLength) result.push(item);
775
- }
776
- return result;
777
- };
778
-
779
- // Take the difference between one array and a number of other arrays.
780
- // Only the elements present in just the first array will remain.
781
- _.difference = function(array) {
782
- var rest = flatten(arguments, true, true, 1);
783
- return _.filter(array, function(value){
784
- return !_.contains(rest, value);
785
- });
786
- };
787
-
788
- // Zip together multiple lists into a single array -- elements that share
789
- // an index go together.
790
- _.zip = function() {
791
- return _.unzip(arguments);
792
- };
793
-
794
- // Complement of _.zip. Unzip accepts an array of arrays and groups
795
- // each array's elements on shared indices
796
- _.unzip = function(array) {
797
- var length = array && _.max(array, getLength).length || 0;
798
- var result = Array(length);
799
-
800
- for (var index = 0; index < length; index++) {
801
- result[index] = _.pluck(array, index);
802
- }
803
- return result;
804
- };
805
-
806
- // Converts lists into objects. Pass either a single array of `[key, value]`
807
- // pairs, or two parallel arrays of the same length -- one of keys, and one of
808
- // the corresponding values.
809
- _.object = function(list, values) {
810
- var result = {};
811
- for (var i = 0, length = getLength(list); i < length; i++) {
812
- if (values) {
813
- result[list[i]] = values[i];
814
- } else {
815
- result[list[i][0]] = list[i][1];
816
- }
817
- }
818
- return result;
819
- };
820
-
821
- // Generator function to create the findIndex and findLastIndex functions
822
- function createPredicateIndexFinder(dir) {
823
- return function(array, predicate, context) {
824
- predicate = cb(predicate, context);
825
- var length = getLength(array);
826
- var index = dir > 0 ? 0 : length - 1;
827
- for (; index >= 0 && index < length; index += dir) {
828
- if (predicate(array[index], index, array)) return index;
829
- }
830
- return -1;
831
- };
832
- }
833
-
834
- // Returns the first index on an array-like that passes a predicate test
835
- _.findIndex = createPredicateIndexFinder(1);
836
- _.findLastIndex = createPredicateIndexFinder(-1);
837
-
838
- // Use a comparator function to figure out the smallest index at which
839
- // an object should be inserted so as to maintain order. Uses binary search.
840
- _.sortedIndex = function(array, obj, iteratee, context) {
841
- iteratee = cb(iteratee, context, 1);
842
- var value = iteratee(obj);
843
- var low = 0, high = getLength(array);
844
- while (low < high) {
845
- var mid = Math.floor((low + high) / 2);
846
- if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
847
- }
848
- return low;
849
- };
850
-
851
- // Generator function to create the indexOf and lastIndexOf functions
852
- function createIndexFinder(dir, predicateFind, sortedIndex) {
853
- return function(array, item, idx) {
854
- var i = 0, length = getLength(array);
855
- if (typeof idx == 'number') {
856
- if (dir > 0) {
857
- i = idx >= 0 ? idx : Math.max(idx + length, i);
858
- } else {
859
- length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
860
- }
861
- } else if (sortedIndex && idx && length) {
862
- idx = sortedIndex(array, item);
863
- return array[idx] === item ? idx : -1;
864
- }
865
- if (item !== item) {
866
- idx = predicateFind(slice.call(array, i, length), _.isNaN);
867
- return idx >= 0 ? idx + i : -1;
868
- }
869
- for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
870
- if (array[idx] === item) return idx;
871
- }
872
- return -1;
873
- };
874
- }
875
-
876
- // Return the position of the first occurrence of an item in an array,
877
- // or -1 if the item is not included in the array.
878
- // If the array is large and already in sort order, pass `true`
879
- // for **isSorted** to use binary search.
880
- _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);
881
- _.lastIndexOf = createIndexFinder(-1, _.findLastIndex);
882
-
883
- // Generate an integer Array containing an arithmetic progression. A port of
884
- // the native Python `range()` function. See
885
- // [the Python documentation](http://docs.python.org/library/functions.html#range).
886
- _.range = function(start, stop, step) {
887
- if (stop == null) {
888
- stop = start || 0;
889
- start = 0;
890
- }
891
- step = step || 1;
892
-
893
- var length = Math.max(Math.ceil((stop - start) / step), 0);
894
- var range = Array(length);
895
-
896
- for (var idx = 0; idx < length; idx++, start += step) {
897
- range[idx] = start;
898
- }
899
-
900
- return range;
901
- };
902
-
903
- // Function (ahem) Functions
904
- // ------------------
905
-
906
- // Determines whether to execute a function as a constructor
907
- // or a normal function with the provided arguments
908
- var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
909
- if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
910
- var self = baseCreate(sourceFunc.prototype);
911
- var result = sourceFunc.apply(self, args);
912
- if (_.isObject(result)) return result;
913
- return self;
914
- };
915
-
916
- // Create a function bound to a given object (assigning `this`, and arguments,
917
- // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
918
- // available.
919
- _.bind = function(func, context) {
920
- if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
921
- if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
922
- var args = slice.call(arguments, 2);
923
- var bound = function() {
924
- return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));
925
- };
926
- return bound;
927
- };
928
-
929
- // Partially apply a function by creating a version that has had some of its
930
- // arguments pre-filled, without changing its dynamic `this` context. _ acts
931
- // as a placeholder, allowing any combination of arguments to be pre-filled.
932
- _.partial = function(func) {
933
- var boundArgs = slice.call(arguments, 1);
934
- var bound = function() {
935
- var position = 0, length = boundArgs.length;
936
- var args = Array(length);
937
- for (var i = 0; i < length; i++) {
938
- args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
939
- }
940
- while (position < arguments.length) args.push(arguments[position++]);
941
- return executeBound(func, bound, this, this, args);
942
- };
943
- return bound;
944
- };
945
-
946
- // Bind a number of an object's methods to that object. Remaining arguments
947
- // are the method names to be bound. Useful for ensuring that all callbacks
948
- // defined on an object belong to it.
949
- _.bindAll = function(obj) {
950
- var i, length = arguments.length, key;
951
- if (length <= 1) throw new Error('bindAll must be passed function names');
952
- for (i = 1; i < length; i++) {
953
- key = arguments[i];
954
- obj[key] = _.bind(obj[key], obj);
955
- }
956
- return obj;
957
- };
958
-
959
- // Memoize an expensive function by storing its results.
960
- _.memoize = function(func, hasher) {
961
- var memoize = function(key) {
962
- var cache = memoize.cache;
963
- var address = '' + (hasher ? hasher.apply(this, arguments) : key);
964
- if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
965
- return cache[address];
966
- };
967
- memoize.cache = {};
968
- return memoize;
969
- };
970
-
971
- // Delays a function for the given number of milliseconds, and then calls
972
- // it with the arguments supplied.
973
- _.delay = function(func, wait) {
974
- var args = slice.call(arguments, 2);
975
- return setTimeout(function(){
976
- return func.apply(null, args);
977
- }, wait);
978
- };
979
-
980
- // Defers a function, scheduling it to run after the current call stack has
981
- // cleared.
982
- _.defer = _.partial(_.delay, _, 1);
983
-
984
- // Returns a function, that, when invoked, will only be triggered at most once
985
- // during a given window of time. Normally, the throttled function will run
986
- // as much as it can, without ever going more than once per `wait` duration;
987
- // but if you'd like to disable the execution on the leading edge, pass
988
- // `{leading: false}`. To disable execution on the trailing edge, ditto.
989
- _.throttle = function(func, wait, options) {
990
- var context, args, result;
991
- var timeout = null;
992
- var previous = 0;
993
- if (!options) options = {};
994
- var later = function() {
995
- previous = options.leading === false ? 0 : _.now();
996
- timeout = null;
997
- result = func.apply(context, args);
998
- if (!timeout) context = args = null;
999
- };
1000
- return function() {
1001
- var now = _.now();
1002
- if (!previous && options.leading === false) previous = now;
1003
- var remaining = wait - (now - previous);
1004
- context = this;
1005
- args = arguments;
1006
- if (remaining <= 0 || remaining > wait) {
1007
- if (timeout) {
1008
- clearTimeout(timeout);
1009
- timeout = null;
1010
- }
1011
- previous = now;
1012
- result = func.apply(context, args);
1013
- if (!timeout) context = args = null;
1014
- } else if (!timeout && options.trailing !== false) {
1015
- timeout = setTimeout(later, remaining);
1016
- }
1017
- return result;
1018
- };
1019
- };
1020
-
1021
- // Returns a function, that, as long as it continues to be invoked, will not
1022
- // be triggered. The function will be called after it stops being called for
1023
- // N milliseconds. If `immediate` is passed, trigger the function on the
1024
- // leading edge, instead of the trailing.
1025
- _.debounce = function(func, wait, immediate) {
1026
- var timeout, args, context, timestamp, result;
1027
-
1028
- var later = function() {
1029
- var last = _.now() - timestamp;
1030
-
1031
- if (last < wait && last >= 0) {
1032
- timeout = setTimeout(later, wait - last);
1033
- } else {
1034
- timeout = null;
1035
- if (!immediate) {
1036
- result = func.apply(context, args);
1037
- if (!timeout) context = args = null;
1038
- }
1039
- }
1040
- };
1041
-
1042
- return function() {
1043
- context = this;
1044
- args = arguments;
1045
- timestamp = _.now();
1046
- var callNow = immediate && !timeout;
1047
- if (!timeout) timeout = setTimeout(later, wait);
1048
- if (callNow) {
1049
- result = func.apply(context, args);
1050
- context = args = null;
1051
- }
1052
-
1053
- return result;
1054
- };
1055
- };
1056
-
1057
- // Returns the first function passed as an argument to the second,
1058
- // allowing you to adjust arguments, run code before and after, and
1059
- // conditionally execute the original function.
1060
- _.wrap = function(func, wrapper) {
1061
- return _.partial(wrapper, func);
1062
- };
1063
-
1064
- // Returns a negated version of the passed-in predicate.
1065
- _.negate = function(predicate) {
1066
- return function() {
1067
- return !predicate.apply(this, arguments);
1068
- };
1069
- };
1070
-
1071
- // Returns a function that is the composition of a list of functions, each
1072
- // consuming the return value of the function that follows.
1073
- _.compose = function() {
1074
- var args = arguments;
1075
- var start = args.length - 1;
1076
- return function() {
1077
- var i = start;
1078
- var result = args[start].apply(this, arguments);
1079
- while (i--) result = args[i].call(this, result);
1080
- return result;
1081
- };
1082
- };
1083
-
1084
- // Returns a function that will only be executed on and after the Nth call.
1085
- _.after = function(times, func) {
1086
- return function() {
1087
- if (--times < 1) {
1088
- return func.apply(this, arguments);
1089
- }
1090
- };
1091
- };
1092
-
1093
- // Returns a function that will only be executed up to (but not including) the Nth call.
1094
- _.before = function(times, func) {
1095
- var memo;
1096
- return function() {
1097
- if (--times > 0) {
1098
- memo = func.apply(this, arguments);
1099
- }
1100
- if (times <= 1) func = null;
1101
- return memo;
1102
- };
1103
- };
1104
-
1105
- // Returns a function that will be executed at most one time, no matter how
1106
- // often you call it. Useful for lazy initialization.
1107
- _.once = _.partial(_.before, 2);
1108
-
1109
- // Object Functions
1110
- // ----------------
1111
-
1112
- // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
1113
- var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
1114
- var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
1115
- 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
1116
-
1117
- function collectNonEnumProps(obj, keys) {
1118
- var nonEnumIdx = nonEnumerableProps.length;
1119
- var constructor = obj.constructor;
1120
- var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;
1121
-
1122
- // Constructor is a special case.
1123
- var prop = 'constructor';
1124
- if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
1125
-
1126
- while (nonEnumIdx--) {
1127
- prop = nonEnumerableProps[nonEnumIdx];
1128
- if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
1129
- keys.push(prop);
1130
- }
1131
- }
1132
- }
1133
-
1134
- // Retrieve the names of an object's own properties.
1135
- // Delegates to **ECMAScript 5**'s native `Object.keys`
1136
- _.keys = function(obj) {
1137
- if (!_.isObject(obj)) return [];
1138
- if (nativeKeys) return nativeKeys(obj);
1139
- var keys = [];
1140
- for (var key in obj) if (_.has(obj, key)) keys.push(key);
1141
- // Ahem, IE < 9.
1142
- if (hasEnumBug) collectNonEnumProps(obj, keys);
1143
- return keys;
1144
- };
1145
-
1146
- // Retrieve all the property names of an object.
1147
- _.allKeys = function(obj) {
1148
- if (!_.isObject(obj)) return [];
1149
- var keys = [];
1150
- for (var key in obj) keys.push(key);
1151
- // Ahem, IE < 9.
1152
- if (hasEnumBug) collectNonEnumProps(obj, keys);
1153
- return keys;
1154
- };
1155
-
1156
- // Retrieve the values of an object's properties.
1157
- _.values = function(obj) {
1158
- var keys = _.keys(obj);
1159
- var length = keys.length;
1160
- var values = Array(length);
1161
- for (var i = 0; i < length; i++) {
1162
- values[i] = obj[keys[i]];
1163
- }
1164
- return values;
1165
- };
1166
-
1167
- // Returns the results of applying the iteratee to each element of the object
1168
- // In contrast to _.map it returns an object
1169
- _.mapObject = function(obj, iteratee, context) {
1170
- iteratee = cb(iteratee, context);
1171
- var keys = _.keys(obj),
1172
- length = keys.length,
1173
- results = {},
1174
- currentKey;
1175
- for (var index = 0; index < length; index++) {
1176
- currentKey = keys[index];
1177
- results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
1178
- }
1179
- return results;
1180
- };
1181
-
1182
- // Convert an object into a list of `[key, value]` pairs.
1183
- _.pairs = function(obj) {
1184
- var keys = _.keys(obj);
1185
- var length = keys.length;
1186
- var pairs = Array(length);
1187
- for (var i = 0; i < length; i++) {
1188
- pairs[i] = [keys[i], obj[keys[i]]];
1189
- }
1190
- return pairs;
1191
- };
1192
-
1193
- // Invert the keys and values of an object. The values must be serializable.
1194
- _.invert = function(obj) {
1195
- var result = {};
1196
- var keys = _.keys(obj);
1197
- for (var i = 0, length = keys.length; i < length; i++) {
1198
- result[obj[keys[i]]] = keys[i];
1199
- }
1200
- return result;
1201
- };
1202
-
1203
- // Return a sorted list of the function names available on the object.
1204
- // Aliased as `methods`
1205
- _.functions = _.methods = function(obj) {
1206
- var names = [];
1207
- for (var key in obj) {
1208
- if (_.isFunction(obj[key])) names.push(key);
1209
- }
1210
- return names.sort();
1211
- };
1212
-
1213
- // Extend a given object with all the properties in passed-in object(s).
1214
- _.extend = createAssigner(_.allKeys);
1215
-
1216
- // Assigns a given object with all the own properties in the passed-in object(s)
1217
- // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
1218
- _.extendOwn = _.assign = createAssigner(_.keys);
1219
-
1220
- // Returns the first key on an object that passes a predicate test
1221
- _.findKey = function(obj, predicate, context) {
1222
- predicate = cb(predicate, context);
1223
- var keys = _.keys(obj), key;
1224
- for (var i = 0, length = keys.length; i < length; i++) {
1225
- key = keys[i];
1226
- if (predicate(obj[key], key, obj)) return key;
1227
- }
1228
- };
1229
-
1230
- // Return a copy of the object only containing the whitelisted properties.
1231
- _.pick = function(object, oiteratee, context) {
1232
- var result = {}, obj = object, iteratee, keys;
1233
- if (obj == null) return result;
1234
- if (_.isFunction(oiteratee)) {
1235
- keys = _.allKeys(obj);
1236
- iteratee = optimizeCb(oiteratee, context);
1237
- } else {
1238
- keys = flatten(arguments, false, false, 1);
1239
- iteratee = function(value, key, obj) { return key in obj; };
1240
- obj = Object(obj);
1241
- }
1242
- for (var i = 0, length = keys.length; i < length; i++) {
1243
- var key = keys[i];
1244
- var value = obj[key];
1245
- if (iteratee(value, key, obj)) result[key] = value;
1246
- }
1247
- return result;
1248
- };
1249
-
1250
- // Return a copy of the object without the blacklisted properties.
1251
- _.omit = function(obj, iteratee, context) {
1252
- if (_.isFunction(iteratee)) {
1253
- iteratee = _.negate(iteratee);
1254
- } else {
1255
- var keys = _.map(flatten(arguments, false, false, 1), String);
1256
- iteratee = function(value, key) {
1257
- return !_.contains(keys, key);
1258
- };
1259
- }
1260
- return _.pick(obj, iteratee, context);
1261
- };
1262
-
1263
- // Fill in a given object with default properties.
1264
- _.defaults = createAssigner(_.allKeys, true);
1265
-
1266
- // Creates an object that inherits from the given prototype object.
1267
- // If additional properties are provided then they will be added to the
1268
- // created object.
1269
- _.create = function(prototype, props) {
1270
- var result = baseCreate(prototype);
1271
- if (props) _.extendOwn(result, props);
1272
- return result;
1273
- };
1274
-
1275
- // Create a (shallow-cloned) duplicate of an object.
1276
- _.clone = function(obj) {
1277
- if (!_.isObject(obj)) return obj;
1278
- return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
1279
- };
1280
-
1281
- // Invokes interceptor with the obj, and then returns obj.
1282
- // The primary purpose of this method is to "tap into" a method chain, in
1283
- // order to perform operations on intermediate results within the chain.
1284
- _.tap = function(obj, interceptor) {
1285
- interceptor(obj);
1286
- return obj;
1287
- };
1288
-
1289
- // Returns whether an object has a given set of `key:value` pairs.
1290
- _.isMatch = function(object, attrs) {
1291
- var keys = _.keys(attrs), length = keys.length;
1292
- if (object == null) return !length;
1293
- var obj = Object(object);
1294
- for (var i = 0; i < length; i++) {
1295
- var key = keys[i];
1296
- if (attrs[key] !== obj[key] || !(key in obj)) return false;
1297
- }
1298
- return true;
1299
- };
1300
-
1301
-
1302
- // Internal recursive comparison function for `isEqual`.
1303
- var eq = function(a, b, aStack, bStack) {
1304
- // Identical objects are equal. `0 === -0`, but they aren't identical.
1305
- // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
1306
- if (a === b) return a !== 0 || 1 / a === 1 / b;
1307
- // A strict comparison is necessary because `null == undefined`.
1308
- if (a == null || b == null) return a === b;
1309
- // Unwrap any wrapped objects.
1310
- if (a instanceof _) a = a._wrapped;
1311
- if (b instanceof _) b = b._wrapped;
1312
- // Compare `[[Class]]` names.
1313
- var className = toString.call(a);
1314
- if (className !== toString.call(b)) return false;
1315
- switch (className) {
1316
- // Strings, numbers, regular expressions, dates, and booleans are compared by value.
1317
- case '[object RegExp]':
1318
- // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
1319
- case '[object String]':
1320
- // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
1321
- // equivalent to `new String("5")`.
1322
- return '' + a === '' + b;
1323
- case '[object Number]':
1324
- // `NaN`s are equivalent, but non-reflexive.
1325
- // Object(NaN) is equivalent to NaN
1326
- if (+a !== +a) return +b !== +b;
1327
- // An `egal` comparison is performed for other numeric values.
1328
- return +a === 0 ? 1 / +a === 1 / b : +a === +b;
1329
- case '[object Date]':
1330
- case '[object Boolean]':
1331
- // Coerce dates and booleans to numeric primitive values. Dates are compared by their
1332
- // millisecond representations. Note that invalid dates with millisecond representations
1333
- // of `NaN` are not equivalent.
1334
- return +a === +b;
1335
- }
1336
-
1337
- var areArrays = className === '[object Array]';
1338
- if (!areArrays) {
1339
- if (typeof a != 'object' || typeof b != 'object') return false;
1340
-
1341
- // Objects with different constructors are not equivalent, but `Object`s or `Array`s
1342
- // from different frames are.
1343
- var aCtor = a.constructor, bCtor = b.constructor;
1344
- if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
1345
- _.isFunction(bCtor) && bCtor instanceof bCtor)
1346
- && ('constructor' in a && 'constructor' in b)) {
1347
- return false;
1348
- }
1349
- }
1350
- // Assume equality for cyclic structures. The algorithm for detecting cyclic
1351
- // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
1352
-
1353
- // Initializing stack of traversed objects.
1354
- // It's done here since we only need them for objects and arrays comparison.
1355
- aStack = aStack || [];
1356
- bStack = bStack || [];
1357
- var length = aStack.length;
1358
- while (length--) {
1359
- // Linear search. Performance is inversely proportional to the number of
1360
- // unique nested structures.
1361
- if (aStack[length] === a) return bStack[length] === b;
1362
- }
1363
-
1364
- // Add the first object to the stack of traversed objects.
1365
- aStack.push(a);
1366
- bStack.push(b);
1367
-
1368
- // Recursively compare objects and arrays.
1369
- if (areArrays) {
1370
- // Compare array lengths to determine if a deep comparison is necessary.
1371
- length = a.length;
1372
- if (length !== b.length) return false;
1373
- // Deep compare the contents, ignoring non-numeric properties.
1374
- while (length--) {
1375
- if (!eq(a[length], b[length], aStack, bStack)) return false;
1376
- }
1377
- } else {
1378
- // Deep compare objects.
1379
- var keys = _.keys(a), key;
1380
- length = keys.length;
1381
- // Ensure that both objects contain the same number of properties before comparing deep equality.
1382
- if (_.keys(b).length !== length) return false;
1383
- while (length--) {
1384
- // Deep compare each member
1385
- key = keys[length];
1386
- if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
1387
- }
1388
- }
1389
- // Remove the first object from the stack of traversed objects.
1390
- aStack.pop();
1391
- bStack.pop();
1392
- return true;
1393
- };
1394
-
1395
- // Perform a deep comparison to check if two objects are equal.
1396
- _.isEqual = function(a, b) {
1397
- return eq(a, b);
1398
- };
1399
-
1400
- // Is a given array, string, or object empty?
1401
- // An "empty" object has no enumerable own-properties.
1402
- _.isEmpty = function(obj) {
1403
- if (obj == null) return true;
1404
- if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
1405
- return _.keys(obj).length === 0;
1406
- };
1407
-
1408
- // Is a given value a DOM element?
1409
- _.isElement = function(obj) {
1410
- return !!(obj && obj.nodeType === 1);
1411
- };
1412
-
1413
- // Is a given value an array?
1414
- // Delegates to ECMA5's native Array.isArray
1415
- _.isArray = nativeIsArray || function(obj) {
1416
- return toString.call(obj) === '[object Array]';
1417
- };
1418
-
1419
- // Is a given variable an object?
1420
- _.isObject = function(obj) {
1421
- var type = typeof obj;
1422
- return type === 'function' || type === 'object' && !!obj;
1423
- };
1424
-
1425
- // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
1426
- _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
1427
- _['is' + name] = function(obj) {
1428
- return toString.call(obj) === '[object ' + name + ']';
1429
- };
1430
- });
1431
-
1432
- // Define a fallback version of the method in browsers (ahem, IE < 9), where
1433
- // there isn't any inspectable "Arguments" type.
1434
- if (!_.isArguments(arguments)) {
1435
- _.isArguments = function(obj) {
1436
- return _.has(obj, 'callee');
1437
- };
1438
- }
1439
-
1440
- // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
1441
- // IE 11 (#1621), and in Safari 8 (#1929).
1442
- if (typeof /./ != 'function' && typeof Int8Array != 'object') {
1443
- _.isFunction = function(obj) {
1444
- return typeof obj == 'function' || false;
1445
- };
1446
- }
1447
-
1448
- // Is a given object a finite number?
1449
- _.isFinite = function(obj) {
1450
- return isFinite(obj) && !isNaN(parseFloat(obj));
1451
- };
1452
-
1453
- // Is the given value `NaN`? (NaN is the only number which does not equal itself).
1454
- _.isNaN = function(obj) {
1455
- return _.isNumber(obj) && obj !== +obj;
1456
- };
1457
-
1458
- // Is a given value a boolean?
1459
- _.isBoolean = function(obj) {
1460
- return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
1461
- };
1462
-
1463
- // Is a given value equal to null?
1464
- _.isNull = function(obj) {
1465
- return obj === null;
1466
- };
1467
-
1468
- // Is a given variable undefined?
1469
- _.isUndefined = function(obj) {
1470
- return obj === void 0;
1471
- };
1472
-
1473
- // Shortcut function for checking if an object has a given property directly
1474
- // on itself (in other words, not on a prototype).
1475
- _.has = function(obj, key) {
1476
- return obj != null && hasOwnProperty.call(obj, key);
1477
- };
1478
-
1479
- // Utility Functions
1480
- // -----------------
1481
-
1482
- // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
1483
- // previous owner. Returns a reference to the Underscore object.
1484
- _.noConflict = function() {
1485
- root._ = previousUnderscore;
1486
- return this;
1487
- };
1488
-
1489
- // Keep the identity function around for default iteratees.
1490
- _.identity = function(value) {
1491
- return value;
1492
- };
1493
-
1494
- // Predicate-generating functions. Often useful outside of Underscore.
1495
- _.constant = function(value) {
1496
- return function() {
1497
- return value;
1498
- };
1499
- };
1500
-
1501
- _.noop = function(){};
1502
-
1503
- _.property = property;
1504
-
1505
- // Generates a function for a given object that returns a given property.
1506
- _.propertyOf = function(obj) {
1507
- return obj == null ? function(){} : function(key) {
1508
- return obj[key];
1509
- };
1510
- };
1511
-
1512
- // Returns a predicate for checking whether an object has a given set of
1513
- // `key:value` pairs.
1514
- _.matcher = _.matches = function(attrs) {
1515
- attrs = _.extendOwn({}, attrs);
1516
- return function(obj) {
1517
- return _.isMatch(obj, attrs);
1518
- };
1519
- };
1520
-
1521
- // Run a function **n** times.
1522
- _.times = function(n, iteratee, context) {
1523
- var accum = Array(Math.max(0, n));
1524
- iteratee = optimizeCb(iteratee, context, 1);
1525
- for (var i = 0; i < n; i++) accum[i] = iteratee(i);
1526
- return accum;
1527
- };
1528
-
1529
- // Return a random integer between min and max (inclusive).
1530
- _.random = function(min, max) {
1531
- if (max == null) {
1532
- max = min;
1533
- min = 0;
1534
- }
1535
- return min + Math.floor(Math.random() * (max - min + 1));
1536
- };
1537
-
1538
- // A (possibly faster) way to get the current timestamp as an integer.
1539
- _.now = Date.now || function() {
1540
- return new Date().getTime();
1541
- };
1542
-
1543
- // List of HTML entities for escaping.
1544
- var escapeMap = {
1545
- '&': '&amp;',
1546
- '<': '&lt;',
1547
- '>': '&gt;',
1548
- '"': '&quot;',
1549
- "'": '&#x27;',
1550
- '`': '&#x60;'
1551
- };
1552
- var unescapeMap = _.invert(escapeMap);
1553
-
1554
- // Functions for escaping and unescaping strings to/from HTML interpolation.
1555
- var createEscaper = function(map) {
1556
- var escaper = function(match) {
1557
- return map[match];
1558
- };
1559
- // Regexes for identifying a key that needs to be escaped
1560
- var source = '(?:' + _.keys(map).join('|') + ')';
1561
- var testRegexp = RegExp(source);
1562
- var replaceRegexp = RegExp(source, 'g');
1563
- return function(string) {
1564
- string = string == null ? '' : '' + string;
1565
- return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
1566
- };
1567
- };
1568
- _.escape = createEscaper(escapeMap);
1569
- _.unescape = createEscaper(unescapeMap);
1570
-
1571
- // If the value of the named `property` is a function then invoke it with the
1572
- // `object` as context; otherwise, return it.
1573
- _.result = function(object, property, fallback) {
1574
- var value = object == null ? void 0 : object[property];
1575
- if (value === void 0) {
1576
- value = fallback;
1577
- }
1578
- return _.isFunction(value) ? value.call(object) : value;
1579
- };
1580
-
1581
- // Generate a unique integer id (unique within the entire client session).
1582
- // Useful for temporary DOM ids.
1583
- var idCounter = 0;
1584
- _.uniqueId = function(prefix) {
1585
- var id = ++idCounter + '';
1586
- return prefix ? prefix + id : id;
1587
- };
1588
-
1589
- // By default, Underscore uses ERB-style template delimiters, change the
1590
- // following template settings to use alternative delimiters.
1591
- _.templateSettings = {
1592
- evaluate : /<%([\s\S]+?)%>/g,
1593
- interpolate : /<%=([\s\S]+?)%>/g,
1594
- escape : /<%-([\s\S]+?)%>/g
1595
- };
1596
-
1597
- // When customizing `templateSettings`, if you don't want to define an
1598
- // interpolation, evaluation or escaping regex, we need one that is
1599
- // guaranteed not to match.
1600
- var noMatch = /(.)^/;
1601
-
1602
- // Certain characters need to be escaped so that they can be put into a
1603
- // string literal.
1604
- var escapes = {
1605
- "'": "'",
1606
- '\\': '\\',
1607
- '\r': 'r',
1608
- '\n': 'n',
1609
- '\u2028': 'u2028',
1610
- '\u2029': 'u2029'
1611
- };
1612
-
1613
- var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
1614
-
1615
- var escapeChar = function(match) {
1616
- return '\\' + escapes[match];
1617
- };
1618
-
1619
- // JavaScript micro-templating, similar to John Resig's implementation.
1620
- // Underscore templating handles arbitrary delimiters, preserves whitespace,
1621
- // and correctly escapes quotes within interpolated code.
1622
- // NB: `oldSettings` only exists for backwards compatibility.
1623
- _.template = function(text, settings, oldSettings) {
1624
- if (!settings && oldSettings) settings = oldSettings;
1625
- settings = _.defaults({}, settings, _.templateSettings);
1626
-
1627
- // Combine delimiters into one regular expression via alternation.
1628
- var matcher = RegExp([
1629
- (settings.escape || noMatch).source,
1630
- (settings.interpolate || noMatch).source,
1631
- (settings.evaluate || noMatch).source
1632
- ].join('|') + '|$', 'g');
1633
-
1634
- // Compile the template source, escaping string literals appropriately.
1635
- var index = 0;
1636
- var source = "__p+='";
1637
- text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
1638
- source += text.slice(index, offset).replace(escaper, escapeChar);
1639
- index = offset + match.length;
1640
-
1641
- if (escape) {
1642
- source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
1643
- } else if (interpolate) {
1644
- source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
1645
- } else if (evaluate) {
1646
- source += "';\n" + evaluate + "\n__p+='";
1647
- }
1648
-
1649
- // Adobe VMs need the match returned to produce the correct offest.
1650
- return match;
1651
- });
1652
- source += "';\n";
1653
-
1654
- // If a variable is not specified, place data values in local scope.
1655
- if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
1656
-
1657
- source = "var __t,__p='',__j=Array.prototype.join," +
1658
- "print=function(){__p+=__j.call(arguments,'');};\n" +
1659
- source + 'return __p;\n';
1660
-
1661
- try {
1662
- var render = new Function(settings.variable || 'obj', '_', source);
1663
- } catch (e) {
1664
- e.source = source;
1665
- throw e;
1666
- }
1667
-
1668
- var template = function(data) {
1669
- return render.call(this, data, _);
1670
- };
1671
-
1672
- // Provide the compiled source as a convenience for precompilation.
1673
- var argument = settings.variable || 'obj';
1674
- template.source = 'function(' + argument + '){\n' + source + '}';
1675
-
1676
- return template;
1677
- };
1678
-
1679
- // Add a "chain" function. Start chaining a wrapped Underscore object.
1680
- _.chain = function(obj) {
1681
- var instance = _(obj);
1682
- instance._chain = true;
1683
- return instance;
1684
- };
1685
-
1686
- // OOP
1687
- // ---------------
1688
- // If Underscore is called as a function, it returns a wrapped object that
1689
- // can be used OO-style. This wrapper holds altered versions of all the
1690
- // underscore functions. Wrapped objects may be chained.
1691
-
1692
- // Helper function to continue chaining intermediate results.
1693
- var result = function(instance, obj) {
1694
- return instance._chain ? _(obj).chain() : obj;
1695
- };
1696
-
1697
- // Add your own custom functions to the Underscore object.
1698
- _.mixin = function(obj) {
1699
- _.each(_.functions(obj), function(name) {
1700
- var func = _[name] = obj[name];
1701
- _.prototype[name] = function() {
1702
- var args = [this._wrapped];
1703
- push.apply(args, arguments);
1704
- return result(this, func.apply(_, args));
1705
- };
1706
- });
1707
- };
1708
-
1709
- // Add all of the Underscore functions to the wrapper object.
1710
- _.mixin(_);
1711
-
1712
- // Add all mutator Array functions to the wrapper.
1713
- _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
1714
- var method = ArrayProto[name];
1715
- _.prototype[name] = function() {
1716
- var obj = this._wrapped;
1717
- method.apply(obj, arguments);
1718
- if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
1719
- return result(this, obj);
1720
- };
1721
- });
1722
-
1723
- // Add all accessor Array functions to the wrapper.
1724
- _.each(['concat', 'join', 'slice'], function(name) {
1725
- var method = ArrayProto[name];
1726
- _.prototype[name] = function() {
1727
- return result(this, method.apply(this._wrapped, arguments));
1728
- };
1729
- });
1730
-
1731
- // Extracts the result from a wrapped and chained object.
1732
- _.prototype.value = function() {
1733
- return this._wrapped;
1734
- };
1735
-
1736
- // Provide unwrapping proxy for some methods used in engine operations
1737
- // such as arithmetic and JSON stringification.
1738
- _.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
1739
-
1740
- _.prototype.toString = function() {
1741
- return '' + this._wrapped;
1742
- };
1743
-
1744
- // AMD registration happens at the end for compatibility with AMD loaders
1745
- // that may not enforce next-turn semantics on modules. Even though general
1746
- // practice for AMD registration is to be anonymous, underscore registers
1747
- // as a named module because, like jQuery, it is a base library that is
1748
- // popular enough to be bundled in a third party lib, but not be part of
1749
- // an AMD load request. Those cases could generate an error when an
1750
- // anonymous define() is called outside of a loader request.
1751
- if (true) {
1752
- !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() {
1753
- return _;
1754
- }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1755
- }
1756
- }.call(this));
1757
-
1758
-
1759
- /***/ },
1760
- /* 7 */
1761
- /***/ function(module, exports, __webpack_require__) {
1762
-
1763
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(1)], __WEBPACK_AMD_DEFINE_RESULT__ = function (mp) {
1764
- 'use strict';
1765
-
1766
- var MailPoet = mp;
1767
- MailPoet.Iframe = {
1768
- marginY: 20,
1769
- autoSize: function (iframe) {
1770
- if (!iframe) return;
1771
-
1772
- this.setSize(
1773
- iframe,
1774
- iframe.contentWindow.document.body.scrollHeight
1775
- );
1776
- },
1777
- setSize: function (sizeIframe, i) {
1778
- var iframe = sizeIframe;
1779
- if (!iframe) return;
1780
-
1781
- iframe.style.height = (
1782
- parseInt(i, 10) + this.marginY
1783
- ) + 'px';
1784
- }
1785
- };
1786
-
1787
- return MailPoet;
1788
- }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1789
-
1790
-
1791
- /***/ },
1792
- /* 8 */
1793
- /***/ function(module, exports, __webpack_require__) {
1794
-
1795
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
1796
- __webpack_require__(4)
1797
- ], __WEBPACK_AMD_DEFINE_RESULT__ = function (
1798
- jQuery
1799
- ) {
1800
- var $ = jQuery;
1801
- // Combination of jQuery.deparam and jQuery.serializeObject by Ben Alman.
1802
- /*!
1803
- * jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010
1804
- * http://benalman.com/projects/jquery-bbq-plugin/
1805
- *
1806
- * Copyright (c) 2010 "Cowboy" Ben Alman
1807
- * Dual licensed under the MIT and GPL licenses.
1808
- * http://benalman.com/about/license/
1809
- */
1810
- /*!
1811
- * jQuery serializeObject - v0.2 - 1/20/2010
1812
- * http://benalman.com/projects/jquery-misc-plugins/
1813
- *
1814
- * Copyright (c) 2010 "Cowboy" Ben Alman
1815
- * Dual licensed under the MIT and GPL licenses.
1816
- * http://benalman.com/about/license/
1817
- */
1818
- $.fn.serializeObject = function (coerce) {
1819
- var obj = {},
1820
- coerce_types = { true: !0, false: !1, null: null };
1821
-
1822
- // Iterate over all name=value pairs.
1823
- $.each(this.serializeArray(), function (j, v) {
1824
- var key = v.name,
1825
- val = v.value,
1826
- cur = obj,
1827
- i = 0,
1828
-
1829
- // If key is more complex than 'foo', like 'a[]' or 'a[b][c]', split it
1830
- // into its component parts.
1831
- keys = key.split(']['),
1832
- keys_last = keys.length - 1;
1833
-
1834
- // If the first keys part contains [ and the last ends with ], then []
1835
- // are correctly balanced.
1836
- if (/\[/.test(keys[0]) && /\]$/.test(keys[keys_last])) {
1837
- // Remove the trailing ] from the last keys part.
1838
- keys[keys_last] = keys[keys_last].replace(/\]$/, '');
1839
-
1840
- // Split first keys part into two parts on the [ and add them back onto
1841
- // the beginning of the keys array.
1842
- keys = keys.shift().split('[').concat(keys);
1843
-
1844
- keys_last = keys.length - 1;
1845
- } else {
1846
- // Basic 'foo' style key.
1847
- keys_last = 0;
1848
- }
1849
-
1850
- // Coerce values.
1851
- if (coerce) {
1852
- val = val && !isNaN(val) ? +val // number
1853
- : val === 'undefined' ? undefined // undefined
1854
- : coerce_types[val] !== undefined ? coerce_types[val] // true, false, null
1855
- : val; // string
1856
- }
1857
-
1858
- if (keys_last) {
1859
- // Complex key, build deep object structure based on a few rules:
1860
- // * The 'cur' pointer starts at the object top-level.
1861
- // * [] = array push (n is set to array length), [n] = array if n is
1862
- // numeric, otherwise object.
1863
- // * If at the last keys part, set the value.
1864
- // * For each keys part, if the current level is undefined create an
1865
- // object or array based on the type of the next keys part.
1866
- // * Move the 'cur' pointer to the next level.
1867
- // * Rinse & repeat.
1868
- for (; i <= keys_last; i++) {
1869
- key = keys[i] === '' ? cur.length : keys[i];
1870
- cur[key] = i < keys_last
1871
- ? cur[key] || (keys[i + 1] && isNaN(keys[i + 1]) ? {} : [])
1872
- : val;
1873
- cur = cur[key];
1874
- }
1875
-
1876
- } else {
1877
- // Simple key, even simpler rules, since only scalars and shallow
1878
- // arrays are allowed.
1879
-
1880
- if ($.isArray(obj[key])) {
1881
- // val is already an array, so push on the next value.
1882
- obj[key].push(val);
1883
-
1884
- } else if (obj[key] !== undefined) {
1885
- // val isn't an array, but since a second value has been specified,
1886
- // convert val into an array.
1887
- obj[key] = [obj[key], val];
1888
-
1889
- } else {
1890
- // val is a scalar.
1891
- obj[key] = val;
1892
- }
1893
- }
1894
- });
1895
-
1896
- return obj;
1897
- };
1898
-
1899
- return $;
1900
- }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1901
-
1902
- /***/ },
1903
- /* 9 */
1904
- /***/ function(module, exports, __webpack_require__) {
1905
-
1906
- var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
1907
- __webpack_require__(1),
1908
- __webpack_require__(4),
1909
- __webpack_require__(10)
1910
- ], __WEBPACK_AMD_DEFINE_RESULT__ = function (
1911
- MailPoet,
1912
- jQuery,
1913
- Parsley
1914
- ) {
1915
- jQuery(function ($) {
1916
- function isSameDomain(url) {
1917
- var link = document.createElement('a');
1918
- link.href = url;
1919
- return (window.location.hostname === link.hostname);
1920
- }
1921
-
1922
- $(function () {
1923
- // setup form validation
1924
- $('form.mailpoet_form').each(function () {
1925
- var form = $(this);
1926
-
1927
- form.parsley().on('form:validated', function (parsley) {
1928
- // clear messages
1929
- form.find('.mailpoet_message > p').hide();
1930
-
1931
- // resize iframe
1932
- if (window.frameElement !== null) {
1933
- MailPoet.Iframe.autoSize(window.frameElement);
1934
- }
1935
- });
1936
-
1937
- form.parsley().on('form:submit', function (parsley) {
1938
- var form_data = form.serializeObject() || {};
1939
- // check if we're on the same domain
1940
- if (isSameDomain(window.MailPoetForm.ajax_url) === false) {
1941
- // non ajax post request
1942
- return true;
1943
- } else {
1944
- // ajax request
1945
- MailPoet.Ajax.post({
1946
- url: window.MailPoetForm.ajax_url,
1947
- token: form_data.token,
1948
- api_version: form_data.api_version,
1949
- endpoint: 'subscribers',
1950
- action: 'subscribe',
1951
- data: form_data.data
1952
- }).fail(function (response) {
1953
- form.find('.mailpoet_validate_error').html(
1954
- response.errors.map(function (error) {
1955
- return error.message;
1956
- }).join('<br />')
1957
- ).show();
1958
- }).done(function (response) {
1959
- // successfully subscribed
1960
- if (
1961
- response.meta !== undefined
1962
- && response.meta.redirect_url !== undefined
1963
- ) {
1964
- // go to page
1965
- window.location.href = response.meta.redirect_url;
1966
- } else {
1967
- // display success message
1968
- form.find('.mailpoet_validate_success').show();
1969
- }
1970
-
1971
- // reset form
1972
- form.trigger('reset');
1973
- // reset validation
1974
- parsley.reset();
1975
-
1976
- // resize iframe
1977
- if (
1978
- window.frameElement !== null
1979
- && MailPoet !== undefined
1980
- && MailPoet['Iframe']
1981
- ) {
1982
- MailPoet.Iframe.autoSize(window.frameElement);
1983
- }
1984
- });
1985
- }
1986
- return false;
1987
- });
1988
- });
1989
- });
1990
- });
1991
- }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1992
-
1993
- /***/ },
1994
- /* 10 */
1995
- /***/ function(module, exports, __webpack_require__) {
1996
-
1997
- /* WEBPACK VAR INJECTION */(function(global) {/*!
1998
- * Parsley.js
1999
- * Version 2.8.0 - built Wed, Sep 13th 2017, 11:04 pm
2000
- * http://parsleyjs.org
2001
- * Guillaume Potier - <guillaume@wisembly.com>
2002
- * Marc-Andre Lafortune - <petroselinum@marc-andre.ca>
2003
- * MIT Licensed
2004
- */
2005
-
2006
- // The source code below is generated by babel as
2007
- // Parsley is written in ECMAScript 6
2008
- //
2009
- var _slice = Array.prototype.slice;
2010
-
2011
- var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();
2012
-
2013
- var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
2014
-
2015
- function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }
2016
-
2017
- (function (global, factory) {
2018
- true ? module.exports = factory(__webpack_require__(4)) : typeof define === 'function' && define.amd ? define(['jquery'], factory) : global.parsley = factory(global.jQuery);
2019
- })(this, function ($) {
2020
- 'use strict';
2021
-
2022
- var globalID = 1;
2023
- var pastWarnings = {};
2024
-
2025
- var Utils = {
2026
- // Parsley DOM-API
2027
- // returns object from dom attributes and values
2028
- attr: function attr(element, namespace, obj) {
2029
- var i;
2030
- var attribute;
2031
- var attributes;
2032
- var regex = new RegExp('^' + namespace, 'i');
2033
-
2034
- if ('undefined' === typeof obj) obj = {};else {
2035
- // Clear all own properties. This won't affect prototype's values
2036
- for (i in obj) {
2037
- if (obj.hasOwnProperty(i)) delete obj[i];
2038
- }
2039
- }
2040
-
2041
- if (!element) return obj;
2042
-
2043
- attributes = element.attributes;
2044
- for (i = attributes.length; i--;) {
2045
- attribute = attributes[i];
2046
-
2047
- if (attribute && attribute.specified && regex.test(attribute.name)) {
2048
- obj[this.camelize(attribute.name.slice(namespace.length))] = this.deserializeValue(attribute.value);
2049
- }
2050
- }
2051
-
2052
- return obj;
2053
- },
2054
-
2055
- checkAttr: function checkAttr(element, namespace, _checkAttr) {
2056
- return element.hasAttribute(namespace + _checkAttr);
2057
- },
2058
-
2059
- setAttr: function setAttr(element, namespace, attr, value) {
2060
- element.setAttribute(this.dasherize(namespace + attr), String(value));
2061
- },
2062
-
2063
- getType: function getType(element) {
2064
- return element.getAttribute('type') || 'text';
2065
- },
2066
-
2067
- generateID: function generateID() {
2068
- return '' + globalID++;
2069
- },
2070
-
2071
- /** Third party functions **/
2072
- deserializeValue: function deserializeValue(value) {
2073
- var num;
2074
-
2075
- try {
2076
- return value ? value == "true" || (value == "false" ? false : value == "null" ? null : !isNaN(num = Number(value)) ? num : /^[\[\{]/.test(value) ? JSON.parse(value) : value) : value;
2077
- } catch (e) {
2078
- return value;
2079
- }
2080
- },
2081
-
2082
- // Zepto camelize function
2083
- camelize: function camelize(str) {
2084
- return str.replace(/-+(.)?/g, function (match, chr) {
2085
- return chr ? chr.toUpperCase() : '';
2086
- });
2087
- },
2088
-
2089
- // Zepto dasherize function
2090
- dasherize: function dasherize(str) {
2091
- return str.replace(/::/g, '/').replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2').replace(/([a-z\d])([A-Z])/g, '$1_$2').replace(/_/g, '-').toLowerCase();
2092
- },
2093
-
2094
- warn: function warn() {
2095
- var _window$console;
2096
-
2097
- if (window.console && 'function' === typeof window.console.warn) (_window$console = window.console).warn.apply(_window$console, arguments);
2098
- },
2099
-
2100
- warnOnce: function warnOnce(msg) {
2101
- if (!pastWarnings[msg]) {
2102
- pastWarnings[msg] = true;
2103
- this.warn.apply(this, arguments);
2104
- }
2105
- },
2106
-
2107
- _resetWarnings: function _resetWarnings() {
2108
- pastWarnings = {};
2109
- },
2110
-
2111
- trimString: function trimString(string) {
2112
- return string.replace(/^\s+|\s+$/g, '');
2113
- },
2114
-
2115
- parse: {
2116
- date: function date(string) {
2117
- var parsed = string.match(/^(\d{4,})-(\d\d)-(\d\d)$/);
2118
- if (!parsed) return null;
2119
-
2120
- var _parsed$map = parsed.map(function (x) {
2121
- return parseInt(x, 10);
2122
- });
2123
-
2124
- var _parsed$map2 = _slicedToArray(_parsed$map, 4);
2125
-
2126
- var _ = _parsed$map2[0];
2127
- var year = _parsed$map2[1];
2128
- var month = _parsed$map2[2];
2129
- var day = _parsed$map2[3];
2130
-
2131
- var date = new Date(year, month - 1, day);
2132
- if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) return null;
2133
- return date;
2134
- },
2135
- string: function string(_string) {
2136
- return _string;
2137
- },
2138
- integer: function integer(string) {
2139
- if (isNaN(string)) return null;
2140
- return parseInt(string, 10);
2141
- },
2142
- number: function number(string) {
2143
- if (isNaN(string)) throw null;
2144
- return parseFloat(string);
2145
- },
2146
- 'boolean': function _boolean(string) {
2147
- return !/^\s*false\s*$/i.test(string);
2148
- },
2149
- object: function object(string) {
2150
- return Utils.deserializeValue(string);
2151
- },
2152
- regexp: function regexp(_regexp) {
2153
- var flags = '';
2154
-
2155
- // Test if RegExp is literal, if not, nothing to be done, otherwise, we need to isolate flags and pattern
2156
- if (/^\/.*\/(?:[gimy]*)$/.test(_regexp)) {
2157
- // Replace the regexp literal string with the first match group: ([gimy]*)
2158
- // If no flag is present, this will be a blank string
2159
- flags = _regexp.replace(/.*\/([gimy]*)$/, '$1');
2160
- // Again, replace the regexp literal string with the first match group:
2161
- // everything excluding the opening and closing slashes and the flags
2162
- _regexp = _regexp.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1');
2163
- } else {
2164
- // Anchor regexp:
2165
- _regexp = '^' + _regexp + '$';
2166
- }
2167
- return new RegExp(_regexp, flags);
2168
- }
2169
- },
2170
-
2171
- parseRequirement: function parseRequirement(requirementType, string) {
2172
- var converter = this.parse[requirementType || 'string'];
2173
- if (!converter) throw 'Unknown requirement specification: "' + requirementType + '"';
2174
- var converted = converter(string);
2175
- if (converted === null) throw 'Requirement is not a ' + requirementType + ': "' + string + '"';
2176
- return converted;
2177
- },
2178
-
2179
- namespaceEvents: function namespaceEvents(events, namespace) {
2180
- events = this.trimString(events || '').split(/\s+/);
2181
- if (!events[0]) return '';
2182
- return $.map(events, function (evt) {
2183
- return evt + '.' + namespace;
2184
- }).join(' ');
2185
- },
2186
-
2187
- difference: function difference(array, remove) {
2188
- // This is O(N^2), should be optimized
2189
- var result = [];
2190
- $.each(array, function (_, elem) {
2191
- if (remove.indexOf(elem) == -1) result.push(elem);
2192
- });
2193
- return result;
2194
- },
2195
-
2196
- // Alter-ego to native Promise.all, but for jQuery
2197
- all: function all(promises) {
2198
- // jQuery treats $.when() and $.when(singlePromise) differently; let's avoid that and add spurious elements
2199
- return $.when.apply($, _toConsumableArray(promises).concat([42, 42]));
2200
- },
2201
-
2202
- // Object.create polyfill, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Polyfill
2203
- objectCreate: Object.create || (function () {
2204
- var Object = function Object() {};
2205
- return function (prototype) {
2206
- if (arguments.length > 1) {
2207
- throw Error('Second argument not supported');
2208
- }
2209
- if (typeof prototype != 'object') {
2210
- throw TypeError('Argument must be an object');
2211
- }
2212
- Object.prototype = prototype;
2213
- var result = new Object();
2214
- Object.prototype = null;
2215
- return result;
2216
- };
2217
- })(),
2218
-
2219
- _SubmitSelector: 'input[type="submit"], button:submit'
2220
- };
2221
-
2222
- // All these options could be overriden and specified directly in DOM using
2223
- // `data-parsley-` default DOM-API
2224
- // eg: `inputs` can be set in DOM using `data-parsley-inputs="input, textarea"`
2225
- // eg: `data-parsley-stop-on-first-failing-constraint="false"`
2226
-
2227
- var Defaults = {
2228
- // ### General
2229
-
2230
- // Default data-namespace for DOM API
2231
- namespace: 'data-parsley-',
2232
-
2233
- // Supported inputs by default
2234
- inputs: 'input, textarea, select',
2235
-
2236
- // Excluded inputs by default
2237
- excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden]',
2238
-
2239
- // Stop validating field on highest priority failing constraint
2240
- priorityEnabled: true,
2241
-
2242
- // ### Field only
2243
-
2244
- // identifier used to group together inputs (e.g. radio buttons...)
2245
- multiple: null,
2246
-
2247
- // identifier (or array of identifiers) used to validate only a select group of inputs
2248
- group: null,
2249
-
2250
- // ### UI
2251
- // Enable\Disable error messages
2252
- uiEnabled: true,
2253
-
2254
- // Key events threshold before validation
2255
- validationThreshold: 3,
2256
-
2257
- // Focused field on form validation error. 'first'|'last'|'none'
2258
- focus: 'first',
2259
-
2260
- // event(s) that will trigger validation before first failure. eg: `input`...
2261
- trigger: false,
2262
-
2263
- // event(s) that will trigger validation after first failure.
2264
- triggerAfterFailure: 'input',
2265
-
2266
- // Class that would be added on every failing validation Parsley field
2267
- errorClass: 'parsley-error',
2268
-
2269
- // Same for success validation
2270
- successClass: 'parsley-success',
2271
-
2272
- // Return the `$element` that will receive these above success or error classes
2273
- // Could also be (and given directly from DOM) a valid selector like `'#div'`
2274
- classHandler: function classHandler(Field) {},
2275
-
2276
- // Return the `$element` where errors will be appended
2277
- // Could also be (and given directly from DOM) a valid selector like `'#div'`
2278
- errorsContainer: function errorsContainer(Field) {},
2279
-
2280
- // ul elem that would receive errors' list
2281
- errorsWrapper: '<ul class="parsley-errors-list"></ul>',
2282
-
2283
- // li elem that would receive error message
2284
- errorTemplate: '<li></li>'
2285
- };
2286
-
2287
- var Base = function Base() {
2288
- this.__id__ = Utils.generateID();
2289
- };
2290
-
2291
- Base.prototype = {
2292
- asyncSupport: true, // Deprecated
2293
-
2294
- _pipeAccordingToValidationResult: function _pipeAccordingToValidationResult() {
2295
- var _this = this;
2296
-
2297
- var pipe = function pipe() {
2298
- var r = $.Deferred();
2299
- if (true !== _this.validationResult) r.reject();
2300
- return r.resolve().promise();
2301
- };
2302
- return [pipe, pipe];
2303
- },
2304
-
2305
- actualizeOptions: function actualizeOptions() {
2306
- Utils.attr(this.element, this.options.namespace, this.domOptions);
2307
- if (this.parent && this.parent.actualizeOptions) this.parent.actualizeOptions();
2308
- return this;
2309
- },
2310
-
2311
- _resetOptions: function _resetOptions(initOptions) {
2312
- this.domOptions = Utils.objectCreate(this.parent.options);
2313
- this.options = Utils.objectCreate(this.domOptions);
2314
- // Shallow copy of ownProperties of initOptions:
2315
- for (var i in initOptions) {
2316
- if (initOptions.hasOwnProperty(i)) this.options[i] = initOptions[i];
2317
- }
2318
- this.actualizeOptions();
2319
- },
2320
-
2321
- _listeners: null,
2322
-
2323
- // Register a callback for the given event name
2324
- // Callback is called with context as the first argument and the `this`
2325
- // The context is the current parsley instance, or window.Parsley if global
2326
- // A return value of `false` will interrupt the calls
2327
- on: function on(name, fn) {
2328
- this._listeners = this._listeners || {};
2329
- var queue = this._listeners[name] = this._listeners[name] || [];
2330
- queue.push(fn);
2331
-
2332
- return this;
2333
- },
2334
-
2335
- // Deprecated. Use `on` instead
2336
- subscribe: function subscribe(name, fn) {
2337
- $.listenTo(this, name.toLowerCase(), fn);
2338
- },
2339
-
2340
- // Unregister a callback (or all if none is given) for the given event name
2341
- off: function off(name, fn) {
2342
- var queue = this._listeners && this._listeners[name];
2343
- if (queue) {
2344
- if (!fn) {
2345
- delete this._listeners[name];
2346
- } else {
2347
- for (var i = queue.length; i--;) if (queue[i] === fn) queue.splice(i, 1);
2348
- }
2349
- }
2350
- return this;
2351
- },
2352
-
2353
- // Deprecated. Use `off`
2354
- unsubscribe: function unsubscribe(name, fn) {
2355
- $.unsubscribeTo(this, name.toLowerCase());
2356
- },
2357
-
2358
- // Trigger an event of the given name
2359
- // A return value of `false` interrupts the callback chain
2360
- // Returns false if execution was interrupted
2361
- trigger: function trigger(name, target, extraArg) {
2362
- target = target || this;
2363
- var queue = this._listeners && this._listeners[name];
2364
- var result;
2365
- var parentResult;
2366
- if (queue) {
2367
- for (var i = queue.length; i--;) {
2368
- result = queue[i].call(target, target, extraArg);
2369
- if (result === false) return result;
2370
- }
2371
- }
2372
- if (this.parent) {
2373
- return this.parent.trigger(name, target, extraArg);
2374
- }
2375
- return true;
2376
- },
2377
-
2378
- asyncIsValid: function asyncIsValid(group, force) {
2379
- Utils.warnOnce("asyncIsValid is deprecated; please use whenValid instead");
2380
- return this.whenValid({ group: group, force: force });
2381
- },
2382
-
2383
- _findRelated: function _findRelated() {
2384
- return this.options.multiple ? $(this.parent.element.querySelectorAll('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]')) : this.$element;
2385
- }
2386
- };
2387
-
2388
- var convertArrayRequirement = function convertArrayRequirement(string, length) {
2389
- var m = string.match(/^\s*\[(.*)\]\s*$/);
2390
- if (!m) throw 'Requirement is not an array: "' + string + '"';
2391
- var values = m[1].split(',').map(Utils.trimString);
2392
- if (values.length !== length) throw 'Requirement has ' + values.length + ' values when ' + length + ' are needed';
2393
- return values;
2394
- };
2395
-
2396
- var convertExtraOptionRequirement = function convertExtraOptionRequirement(requirementSpec, string, extraOptionReader) {
2397
- var main = null;
2398
- var extra = {};
2399
- for (var key in requirementSpec) {
2400
- if (key) {
2401
- var value = extraOptionReader(key);
2402
- if ('string' === typeof value) value = Utils.parseRequirement(requirementSpec[key], value);
2403
- extra[key] = value;
2404
- } else {
2405
- main = Utils.parseRequirement(requirementSpec[key], string);
2406
- }
2407
- }
2408
- return [main, extra];
2409
- };
2410
-
2411
- // A Validator needs to implement the methods `validate` and `parseRequirements`
2412
-
2413
- var Validator = function Validator(spec) {
2414
- $.extend(true, this, spec);
2415
- };
2416
-
2417
- Validator.prototype = {
2418
- // Returns `true` iff the given `value` is valid according the given requirements.
2419
- validate: function validate(value, requirementFirstArg) {
2420
- if (this.fn) {
2421
- // Legacy style validator
2422
-
2423
- if (arguments.length > 3) // If more args then value, requirement, instance...
2424
- requirementFirstArg = [].slice.call(arguments, 1, -1); // Skip first arg (value) and last (instance), combining the rest
2425
- return this.fn(value, requirementFirstArg);
2426
- }
2427
-
2428
- if (Array.isArray(value)) {
2429
- if (!this.validateMultiple) throw 'Validator `' + this.name + '` does not handle multiple values';
2430
- return this.validateMultiple.apply(this, arguments);
2431
- } else {
2432
- var instance = arguments[arguments.length - 1];
2433
- if (this.validateDate && instance._isDateInput()) {
2434
- arguments[0] = Utils.parse.date(arguments[0]);
2435
- if (arguments[0] === null) return false;
2436
- return this.validateDate.apply(this, arguments);
2437
- }
2438
- if (this.validateNumber) {
2439
- if (isNaN(value)) return false;
2440
- arguments[0] = parseFloat(arguments[0]);
2441
- return this.validateNumber.apply(this, arguments);
2442
- }
2443
- if (this.validateString) {
2444
- return this.validateString.apply(this, arguments);
2445
- }
2446
- throw 'Validator `' + this.name + '` only handles multiple values';
2447
- }
2448
- },
2449
-
2450
- // Parses `requirements` into an array of arguments,
2451
- // according to `this.requirementType`
2452
- parseRequirements: function parseRequirements(requirements, extraOptionReader) {
2453
- if ('string' !== typeof requirements) {
2454
- // Assume requirement already parsed
2455
- // but make sure we return an array
2456
- return Array.isArray(requirements) ? requirements : [requirements];
2457
- }
2458
- var type = this.requirementType;
2459
- if (Array.isArray(type)) {
2460
- var values = convertArrayRequirement(requirements, type.length);
2461
- for (var i = 0; i < values.length; i++) values[i] = Utils.parseRequirement(type[i], values[i]);
2462
- return values;
2463
- } else if ($.isPlainObject(type)) {
2464
- return convertExtraOptionRequirement(type, requirements, extraOptionReader);
2465
- } else {
2466
- return [Utils.parseRequirement(type, requirements)];
2467
- }
2468
- },
2469
- // Defaults:
2470
- requirementType: 'string',
2471
-
2472
- priority: 2
2473
-
2474
- };
2475
-
2476
- var ValidatorRegistry = function ValidatorRegistry(validators, catalog) {
2477
- this.__class__ = 'ValidatorRegistry';
2478
-
2479
- // Default Parsley locale is en
2480
- this.locale = 'en';
2481
-
2482
- this.init(validators || {}, catalog || {});
2483
- };
2484
-
2485
- var typeTesters = {
2486
- email: /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i,
2487
-
2488
- // Follow https://www.w3.org/TR/html5/infrastructure.html#floating-point-numbers
2489
- number: /^-?(\d*\.)?\d+(e[-+]?\d+)?$/i,
2490
-
2491
- integer: /^-?\d+$/,
2492
-
2493
- digits: /^\d+$/,
2494
-
2495
- alphanum: /^\w+$/i,
2496
-
2497
- date: {
2498
- test: function test(value) {
2499
- return Utils.parse.date(value) !== null;
2500
- }
2501
- },
2502
-
2503
- url: new RegExp("^" +
2504
- // protocol identifier
2505
- "(?:(?:https?|ftp)://)?" + // ** mod: make scheme optional
2506
- // user:pass authentication
2507
- "(?:\\S+(?::\\S*)?@)?" + "(?:" +
2508
- // IP address exclusion
2509
- // private & local networks
2510
- // "(?!(?:10|127)(?:\\.\\d{1,3}){3})" + // ** mod: allow local networks
2511
- // "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" + // ** mod: allow local networks
2512
- // "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" + // ** mod: allow local networks
2513
- // IP address dotted notation octets
2514
- // excludes loopback network 0.0.0.0
2515
- // excludes reserved space >= 224.0.0.0
2516
- // excludes network & broacast addresses
2517
- // (first & last IP address of each class)
2518
- "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" + "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" + "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" + "|" +
2519
- // host name
2520
- '(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)' +
2521
- // domain name
2522
- '(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*' +
2523
- // TLD identifier
2524
- '(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))' + ")" +
2525
- // port number
2526
- "(?::\\d{2,5})?" +
2527
- // resource path
2528
- "(?:/\\S*)?" + "$", 'i')
2529
- };
2530
- typeTesters.range = typeTesters.number;
2531
-
2532
- // See http://stackoverflow.com/a/10454560/8279
2533
- var decimalPlaces = function decimalPlaces(num) {
2534
- var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
2535
- if (!match) {
2536
- return 0;
2537
- }
2538
- return Math.max(0,
2539
- // Number of digits right of decimal point.
2540
- (match[1] ? match[1].length : 0) - (
2541
- // Adjust for scientific notation.
2542
- match[2] ? +match[2] : 0));
2543
- };
2544
-
2545
- // parseArguments('number', ['1', '2']) => [1, 2]
2546
- var ValidatorRegistry__parseArguments = function ValidatorRegistry__parseArguments(type, args) {
2547
- return args.map(Utils.parse[type]);
2548
- };
2549
- // operatorToValidator returns a validating function for an operator function, applied to the given type
2550
- var ValidatorRegistry__operatorToValidator = function ValidatorRegistry__operatorToValidator(type, operator) {
2551
- return function (value) {
2552
- for (var _len = arguments.length, requirementsAndInput = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
2553
- requirementsAndInput[_key - 1] = arguments[_key];
2554
- }
2555
-
2556
- requirementsAndInput.pop(); // Get rid of `input` argument
2557
- return operator.apply(undefined, [value].concat(_toConsumableArray(ValidatorRegistry__parseArguments(type, requirementsAndInput))));
2558
- };
2559
- };
2560
-
2561
- var ValidatorRegistry__comparisonOperator = function ValidatorRegistry__comparisonOperator(operator) {
2562
- return {
2563
- validateDate: ValidatorRegistry__operatorToValidator('date', operator),
2564
- validateNumber: ValidatorRegistry__operatorToValidator('number', operator),
2565
- requirementType: operator.length <= 2 ? 'string' : ['string', 'string'], // Support operators with a 1 or 2 requirement(s)
2566
- priority: 30
2567
- };
2568
- };
2569
-
2570
- ValidatorRegistry.prototype = {
2571
- init: function init(validators, catalog) {
2572
- this.catalog = catalog;
2573
- // Copy prototype's validators:
2574
- this.validators = _extends({}, this.validators);
2575
-
2576
- for (var name in validators) this.addValidator(name, validators[name].fn, validators[name].priority);
2577
-
2578
- window.Parsley.trigger('parsley:validator:init');
2579
- },
2580
-
2581
- // Set new messages locale if we have dictionary loaded in ParsleyConfig.i18n
2582
- setLocale: function setLocale(locale) {
2583
- if ('undefined' === typeof this.catalog[locale]) throw new Error(locale + ' is not available in the catalog');
2584
-
2585
- this.locale = locale;
2586
-
2587
- return this;
2588
- },
2589
-
2590
- // Add a new messages catalog for a given locale. Set locale for this catalog if set === `true`
2591
- addCatalog: function addCatalog(locale, messages, set) {
2592
- if ('object' === typeof messages) this.catalog[locale] = messages;
2593
-
2594
- if (true === set) return this.setLocale(locale);
2595
-
2596
- return this;
2597
- },
2598
-
2599
- // Add a specific message for a given constraint in a given locale
2600
- addMessage: function addMessage(locale, name, message) {
2601
- if ('undefined' === typeof this.catalog[locale]) this.catalog[locale] = {};
2602
-
2603
- this.catalog[locale][name] = message;
2604
-
2605
- return this;
2606
- },
2607
-
2608
- // Add messages for a given locale
2609
- addMessages: function addMessages(locale, nameMessageObject) {
2610
- for (var name in nameMessageObject) this.addMessage(locale, name, nameMessageObject[name]);
2611
-
2612
- return this;
2613
- },
2614
-
2615
- // Add a new validator
2616
- //
2617
- // addValidator('custom', {
2618
- // requirementType: ['integer', 'integer'],
2619
- // validateString: function(value, from, to) {},
2620
- // priority: 22,
2621
- // messages: {
2622
- // en: "Hey, that's no good",
2623
- // fr: "Aye aye, pas bon du tout",
2624
- // }
2625
- // })
2626
- //
2627
- // Old API was addValidator(name, function, priority)
2628
- //
2629
- addValidator: function addValidator(name, arg1, arg2) {
2630
- if (this.validators[name]) Utils.warn('Validator "' + name + '" is already defined.');else if (Defaults.hasOwnProperty(name)) {
2631
- Utils.warn('"' + name + '" is a restricted keyword and is not a valid validator name.');
2632
- return;
2633
- }
2634
- return this._setValidator.apply(this, arguments);
2635
- },
2636
-
2637
- hasValidator: function hasValidator(name) {
2638
- return !!this.validators[name];
2639
- },
2640
-
2641
- updateValidator: function updateValidator(name, arg1, arg2) {
2642
- if (!this.validators[name]) {
2643
- Utils.warn('Validator "' + name + '" is not already defined.');
2644
- return this.addValidator.apply(this, arguments);
2645
- }
2646
- return this._setValidator.apply(this, arguments);
2647
- },
2648
-
2649
- removeValidator: function removeValidator(name) {
2650
- if (!this.validators[name]) Utils.warn('Validator "' + name + '" is not defined.');
2651
-
2652
- delete this.validators[name];
2653
-
2654
- return this;
2655
- },
2656
-
2657
- _setValidator: function _setValidator(name, validator, priority) {
2658
- if ('object' !== typeof validator) {
2659
- // Old style validator, with `fn` and `priority`
2660
- validator = {
2661
- fn: validator,
2662
- priority: priority
2663
- };
2664
- }
2665
- if (!validator.validate) {
2666
- validator = new Validator(validator);
2667
- }
2668
- this.validators[name] = validator;
2669
-
2670
- for (var locale in validator.messages || {}) this.addMessage(locale, name, validator.messages[locale]);
2671
-
2672
- return this;
2673
- },
2674
-
2675
- getErrorMessage: function getErrorMessage(constraint) {
2676
- var message;
2677
-
2678
- // Type constraints are a bit different, we have to match their requirements too to find right error message
2679
- if ('type' === constraint.name) {
2680
- var typeMessages = this.catalog[this.locale][constraint.name] || {};
2681
- message = typeMessages[constraint.requirements];
2682
- } else message = this.formatMessage(this.catalog[this.locale][constraint.name], constraint.requirements);
2683
-
2684
- return message || this.catalog[this.locale].defaultMessage || this.catalog.en.defaultMessage;
2685
- },
2686
-
2687
- // Kind of light `sprintf()` implementation
2688
- formatMessage: function formatMessage(string, parameters) {
2689
- if ('object' === typeof parameters) {
2690
- for (var i in parameters) string = this.formatMessage(string, parameters[i]);
2691
-
2692
- return string;
2693
- }
2694
-
2695
- return 'string' === typeof string ? string.replace(/%s/i, parameters) : '';
2696
- },
2697
-
2698
- // Here is the Parsley default validators list.
2699
- // A validator is an object with the following key values:
2700
- // - priority: an integer
2701
- // - requirement: 'string' (default), 'integer', 'number', 'regexp' or an Array of these
2702
- // - validateString, validateMultiple, validateNumber: functions returning `true`, `false` or a promise
2703
- // Alternatively, a validator can be a function that returns such an object
2704
- //
2705
- validators: {
2706
- notblank: {
2707
- validateString: function validateString(value) {
2708
- return (/\S/.test(value)
2709
- );
2710
- },
2711
- priority: 2
2712
- },
2713
- required: {
2714
- validateMultiple: function validateMultiple(values) {
2715
- return values.length > 0;
2716
- },
2717
- validateString: function validateString(value) {
2718
- return (/\S/.test(value)
2719
- );
2720
- },
2721
- priority: 512
2722
- },
2723
- type: {
2724
- validateString: function validateString(value, type) {
2725
- var _ref = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
2726
-
2727
- var _ref$step = _ref.step;
2728
- var step = _ref$step === undefined ? 'any' : _ref$step;
2729
- var _ref$base = _ref.base;
2730
- var base = _ref$base === undefined ? 0 : _ref$base;
2731
-
2732
- var tester = typeTesters[type];
2733
- if (!tester) {
2734
- throw new Error('validator type `' + type + '` is not supported');
2735
- }
2736
- if (!tester.test(value)) return false;
2737
- if ('number' === type) {
2738
- if (!/^any$/i.test(step || '')) {
2739
- var nb = Number(value);
2740
- var decimals = Math.max(decimalPlaces(step), decimalPlaces(base));
2741
- if (decimalPlaces(nb) > decimals) // Value can't have too many decimals
2742
- return false;
2743
- // Be careful of rounding errors by using integers.
2744
- var toInt = function toInt(f) {
2745
- return Math.round(f * Math.pow(10, decimals));
2746
- };
2747
- if ((toInt(nb) - toInt(base)) % toInt(step) != 0) return false;
2748
- }
2749
- }
2750
- return true;
2751
- },
2752
- requirementType: {
2753
- '': 'string',
2754
- step: 'string',
2755
- base: 'number'
2756
- },
2757
- priority: 256
2758
- },
2759
- pattern: {
2760
- validateString: function validateString(value, regexp) {
2761
- return regexp.test(value);
2762
- },
2763
- requirementType: 'regexp',
2764
- priority: 64
2765
- },
2766
- minlength: {
2767
- validateString: function validateString(value, requirement) {
2768
- return value.length >= requirement;
2769
- },
2770
- requirementType: 'integer',
2771
- priority: 30
2772
- },
2773
- maxlength: {
2774
- validateString: function validateString(value, requirement) {
2775
- return value.length <= requirement;
2776
- },
2777
- requirementType: 'integer',
2778
- priority: 30
2779
- },
2780
- length: {
2781
- validateString: function validateString(value, min, max) {
2782
- return value.length >= min && value.length <= max;
2783
- },
2784
- requirementType: ['integer', 'integer'],
2785
- priority: 30
2786
- },
2787
- mincheck: {
2788
- validateMultiple: function validateMultiple(values, requirement) {
2789
- return values.length >= requirement;
2790
- },
2791
- requirementType: 'integer',
2792
- priority: 30
2793
- },
2794
- maxcheck: {
2795
- validateMultiple: function validateMultiple(values, requirement) {
2796
- return values.length <= requirement;
2797
- },
2798
- requirementType: 'integer',
2799
- priority: 30
2800
- },
2801
- check: {
2802
- validateMultiple: function validateMultiple(values, min, max) {
2803
- return values.length >= min && values.length <= max;
2804
- },
2805
- requirementType: ['integer', 'integer'],
2806
- priority: 30
2807
- },
2808
- min: ValidatorRegistry__comparisonOperator(function (value, requirement) {
2809
- return value >= requirement;
2810
- }),
2811
- max: ValidatorRegistry__comparisonOperator(function (value, requirement) {
2812
- return value <= requirement;
2813
- }),
2814
- range: ValidatorRegistry__comparisonOperator(function (value, min, max) {
2815
- return value >= min && value <= max;
2816
- }),
2817
- equalto: {
2818
- validateString: function validateString(value, refOrValue) {
2819
- var $reference = $(refOrValue);
2820
- if ($reference.length) return value === $reference.val();else return value === refOrValue;
2821
- },
2822
- priority: 256
2823
- }
2824
- }
2825
- };
2826
-
2827
- var UI = {};
2828
-
2829
- var diffResults = function diffResults(newResult, oldResult, deep) {
2830
- var added = [];
2831
- var kept = [];
2832
-
2833
- for (var i = 0; i < newResult.length; i++) {
2834
- var found = false;
2835
-
2836
- for (var j = 0; j < oldResult.length; j++) if (newResult[i].assert.name === oldResult[j].assert.name) {
2837
- found = true;
2838
- break;
2839
- }
2840
-
2841
- if (found) kept.push(newResult[i]);else added.push(newResult[i]);
2842
- }
2843
-
2844
- return {
2845
- kept: kept,
2846
- added: added,
2847
- removed: !deep ? diffResults(oldResult, newResult, true).added : []
2848
- };
2849
- };
2850
-
2851
- UI.Form = {
2852
-
2853
- _actualizeTriggers: function _actualizeTriggers() {
2854
- var _this2 = this;
2855
-
2856
- this.$element.on('submit.Parsley', function (evt) {
2857
- _this2.onSubmitValidate(evt);
2858
- });
2859
- this.$element.on('click.Parsley', Utils._SubmitSelector, function (evt) {
2860
- _this2.onSubmitButton(evt);
2861
- });
2862
-
2863
- // UI could be disabled
2864
- if (false === this.options.uiEnabled) return;
2865
-
2866
- this.element.setAttribute('novalidate', '');
2867
- },
2868
-
2869
- focus: function focus() {
2870
- this._focusedField = null;
2871
-
2872
- if (true === this.validationResult || 'none' === this.options.focus) return null;
2873
-
2874
- for (var i = 0; i < this.fields.length; i++) {
2875
- var field = this.fields[i];
2876
- if (true !== field.validationResult && field.validationResult.length > 0 && 'undefined' === typeof field.options.noFocus) {
2877
- this._focusedField = field.$element;
2878
- if ('first' === this.options.focus) break;
2879
- }
2880
- }
2881
-
2882
- if (null === this._focusedField) return null;
2883
-
2884
- return this._focusedField.focus();
2885
- },
2886
-
2887
- _destroyUI: function _destroyUI() {
2888
- // Reset all event listeners
2889
- this.$element.off('.Parsley');
2890
- }
2891
-
2892
- };
2893
-
2894
- UI.Field = {
2895
-
2896
- _reflowUI: function _reflowUI() {
2897
- this._buildUI();
2898
-
2899
- // If this field doesn't have an active UI don't bother doing something
2900
- if (!this._ui) return;
2901
-
2902
- // Diff between two validation results
2903
- var diff = diffResults(this.validationResult, this._ui.lastValidationResult);
2904
-
2905
- // Then store current validation result for next reflow
2906
- this._ui.lastValidationResult = this.validationResult;
2907
-
2908
- // Handle valid / invalid / none field class
2909
- this._manageStatusClass();
2910
-
2911
- // Add, remove, updated errors messages
2912
- this._manageErrorsMessages(diff);
2913
-
2914
- // Triggers impl
2915
- this._actualizeTriggers();
2916
-
2917
- // If field is not valid for the first time, bind keyup trigger to ease UX and quickly inform user
2918
- if ((diff.kept.length || diff.added.length) && !this._failedOnce) {
2919
- this._failedOnce = true;
2920
- this._actualizeTriggers();
2921
- }
2922
- },
2923
-
2924
- // Returns an array of field's error message(s)
2925
- getErrorsMessages: function getErrorsMessages() {
2926
- // No error message, field is valid
2927
- if (true === this.validationResult) return [];
2928
-
2929
- var messages = [];
2930
-
2931
- for (var i = 0; i < this.validationResult.length; i++) messages.push(this.validationResult[i].errorMessage || this._getErrorMessage(this.validationResult[i].assert));
2932
-
2933
- return messages;
2934
- },
2935
-
2936
- // It's a goal of Parsley that this method is no longer required [#1073]
2937
- addError: function addError(name) {
2938
- var _ref2 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
2939
-
2940
- var message = _ref2.message;
2941
- var assert = _ref2.assert;
2942
- var _ref2$updateClass = _ref2.updateClass;
2943
- var updateClass = _ref2$updateClass === undefined ? true : _ref2$updateClass;
2944
-
2945
- this._buildUI();
2946
- this._addError(name, { message: message, assert: assert });
2947
-
2948
- if (updateClass) this._errorClass();
2949
- },
2950
-
2951
- // It's a goal of Parsley that this method is no longer required [#1073]
2952
- updateError: function updateError(name) {
2953
- var _ref3 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
2954
-
2955
- var message = _ref3.message;
2956
- var assert = _ref3.assert;
2957
- var _ref3$updateClass = _ref3.updateClass;
2958
- var updateClass = _ref3$updateClass === undefined ? true : _ref3$updateClass;
2959
-
2960
- this._buildUI();
2961
- this._updateError(name, { message: message, assert: assert });
2962
-
2963
- if (updateClass) this._errorClass();
2964
- },
2965
-
2966
- // It's a goal of Parsley that this method is no longer required [#1073]
2967
- removeError: function removeError(name) {
2968
- var _ref4 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
2969
-
2970
- var _ref4$updateClass = _ref4.updateClass;
2971
- var updateClass = _ref4$updateClass === undefined ? true : _ref4$updateClass;
2972
-
2973
- this._buildUI();
2974
- this._removeError(name);
2975
-
2976
- // edge case possible here: remove a standard Parsley error that is still failing in this.validationResult
2977
- // but highly improbable cuz' manually removing a well Parsley handled error makes no sense.
2978
- if (updateClass) this._manageStatusClass();
2979
- },
2980
-
2981
- _manageStatusClass: function _manageStatusClass() {
2982
- if (this.hasConstraints() && this.needsValidation() && true === this.validationResult) this._successClass();else if (this.validationResult.length > 0) this._errorClass();else this._resetClass();
2983
- },
2984
-
2985
- _manageErrorsMessages: function _manageErrorsMessages(diff) {
2986
- if ('undefined' !== typeof this.options.errorsMessagesDisabled) return;
2987
-
2988
- // Case where we have errorMessage option that configure an unique field error message, regardless failing validators
2989
- if ('undefined' !== typeof this.options.errorMessage) {
2990
- if (diff.added.length || diff.kept.length) {
2991
- this._insertErrorWrapper();
2992
-
2993
- if (0 === this._ui.$errorsWrapper.find('.parsley-custom-error-message').length) this._ui.$errorsWrapper.append($(this.options.errorTemplate).addClass('parsley-custom-error-message'));
2994
-
2995
- return this._ui.$errorsWrapper.addClass('filled').find('.parsley-custom-error-message').html(this.options.errorMessage);
2996
- }
2997
-
2998
- return this._ui.$errorsWrapper.removeClass('filled').find('.parsley-custom-error-message').remove();
2999
- }
3000
-
3001
- // Show, hide, update failing constraints messages
3002
- for (var i = 0; i < diff.removed.length; i++) this._removeError(diff.removed[i].assert.name);
3003
-
3004
- for (i = 0; i < diff.added.length; i++) this._addError(diff.added[i].assert.name, { message: diff.added[i].errorMessage, assert: diff.added[i].assert });
3005
-
3006
- for (i = 0; i < diff.kept.length; i++) this._updateError(diff.kept[i].assert.name, { message: diff.kept[i].errorMessage, assert: diff.kept[i].assert });
3007
- },
3008
-
3009
- _addError: function _addError(name, _ref5) {
3010
- var message = _ref5.message;
3011
- var assert = _ref5.assert;
3012
-
3013
- this._insertErrorWrapper();
3014
- this._ui.$errorsWrapper.addClass('filled').append($(this.options.errorTemplate).addClass('parsley-' + name).html(message || this._getErrorMessage(assert)));
3015
- },
3016
-
3017
- _updateError: function _updateError(name, _ref6) {
3018
- var message = _ref6.message;
3019
- var assert = _ref6.assert;
3020
-
3021
- this._ui.$errorsWrapper.addClass('filled').find('.parsley-' + name).html(message || this._getErrorMessage(assert));
3022
- },
3023
-
3024
- _removeError: function _removeError(name) {
3025
- this._ui.$errorsWrapper.removeClass('filled').find('.parsley-' + name).remove();
3026
- },
3027
-
3028
- _getErrorMessage: function _getErrorMessage(constraint) {
3029
- var customConstraintErrorMessage = constraint.name + 'Message';
3030
-
3031
- if ('undefined' !== typeof this.options[customConstraintErrorMessage]) return window.Parsley.formatMessage(this.options[customConstraintErrorMessage], constraint.requirements);
3032
-
3033
- return window.Parsley.getErrorMessage(constraint);
3034
- },
3035
-
3036
- _buildUI: function _buildUI() {
3037
- // UI could be already built or disabled
3038
- if (this._ui || false === this.options.uiEnabled) return;
3039
-
3040
- var _ui = {};
3041
-
3042
- // Give field its Parsley id in DOM
3043
- this.element.setAttribute(this.options.namespace + 'id', this.__id__);
3044
-
3045
- /** Generate important UI elements and store them in this **/
3046
- // $errorClassHandler is the $element that woul have parsley-error and parsley-success classes
3047
- _ui.$errorClassHandler = this._manageClassHandler();
3048
-
3049
- // $errorsWrapper is a div that would contain the various field errors, it will be appended into $errorsContainer
3050
- _ui.errorsWrapperId = 'parsley-id-' + (this.options.multiple ? 'multiple-' + this.options.multiple : this.__id__);
3051
- _ui.$errorsWrapper = $(this.options.errorsWrapper).attr('id', _ui.errorsWrapperId);
3052
-
3053
- // ValidationResult UI storage to detect what have changed bwt two validations, and update DOM accordingly
3054
- _ui.lastValidationResult = [];
3055
- _ui.validationInformationVisible = false;
3056
-
3057
- // Store it in this for later
3058
- this._ui = _ui;
3059
- },
3060
-
3061
- // Determine which element will have `parsley-error` and `parsley-success` classes
3062
- _manageClassHandler: function _manageClassHandler() {
3063
- // Class handled could also be determined by function given in Parsley options
3064
- if ('string' === typeof this.options.classHandler && $(this.options.classHandler).length) return $(this.options.classHandler);
3065
-
3066
- // Class handled could also be determined by function given in Parsley options
3067
- var $handlerFunction = this.options.classHandler;
3068
-
3069
- // It might also be the function name of a global function
3070
- if ('string' === typeof this.options.classHandler && 'function' === typeof window[this.options.classHandler]) $handlerFunction = window[this.options.classHandler];
3071
-
3072
- if ('function' === typeof $handlerFunction) {
3073
- var $handler = $handlerFunction.call(this, this);
3074
-
3075
- // If this function returned a valid existing DOM element, go for it
3076
- if ('undefined' !== typeof $handler && $handler.length) return $handler;
3077
- } else if ('object' === typeof $handlerFunction && $handlerFunction instanceof jQuery && $handlerFunction.length) {
3078
- return $handlerFunction;
3079
- } else if ($handlerFunction) {
3080
- Utils.warn('The class handler `' + $handlerFunction + '` does not exist in DOM nor as a global JS function');
3081
- }
3082
-
3083
- return this._inputHolder();
3084
- },
3085
-
3086
- _inputHolder: function _inputHolder() {
3087
- // if simple element (input, texatrea, select...) it will perfectly host the classes and precede the error container
3088
- if (!this.options.multiple || this.element.nodeName === 'SELECT') return this.$element;
3089
-
3090
- // But if multiple element (radio, checkbox), that would be their parent
3091
- return this.$element.parent();
3092
- },
3093
-
3094
- _insertErrorWrapper: function _insertErrorWrapper() {
3095
- var $errorsContainer = this.options.errorsContainer;
3096
-
3097
- // Nothing to do if already inserted
3098
- if (0 !== this._ui.$errorsWrapper.parent().length) return this._ui.$errorsWrapper.parent();
3099
-
3100
- if ('string' === typeof $errorsContainer) {
3101
- if ($($errorsContainer).length) return $($errorsContainer).append(this._ui.$errorsWrapper);else if ('function' === typeof window[$errorsContainer]) $errorsContainer = window[$errorsContainer];else Utils.warn('The errors container `' + $errorsContainer + '` does not exist in DOM nor as a global JS function');
3102
- }
3103
-
3104
- if ('function' === typeof $errorsContainer) $errorsContainer = $errorsContainer.call(this, this);
3105
-
3106
- if ('object' === typeof $errorsContainer && $errorsContainer.length) return $errorsContainer.append(this._ui.$errorsWrapper);
3107
-
3108
- return this._inputHolder().after(this._ui.$errorsWrapper);
3109
- },
3110
-
3111
- _actualizeTriggers: function _actualizeTriggers() {
3112
- var _this3 = this;
3113
-
3114
- var $toBind = this._findRelated();
3115
- var trigger;
3116
-
3117
- // Remove Parsley events already bound on this field
3118
- $toBind.off('.Parsley');
3119
- if (this._failedOnce) $toBind.on(Utils.namespaceEvents(this.options.triggerAfterFailure, 'Parsley'), function () {
3120
- _this3._validateIfNeeded();
3121
- });else if (trigger = Utils.namespaceEvents(this.options.trigger, 'Parsley')) {
3122
- $toBind.on(trigger, function (event) {
3123
- _this3._validateIfNeeded(event);
3124
- });
3125
- }
3126
- },
3127
-
3128
- _validateIfNeeded: function _validateIfNeeded(event) {
3129
- var _this4 = this;
3130
-
3131
- // For keyup, keypress, keydown, input... events that could be a little bit obstrusive
3132
- // do not validate if val length < min threshold on first validation. Once field have been validated once and info
3133
- // about success or failure have been displayed, always validate with this trigger to reflect every yalidation change.
3134
- if (event && /key|input/.test(event.type)) if (!(this._ui && this._ui.validationInformationVisible) && this.getValue().length <= this.options.validationThreshold) return;
3135
-
3136
- if (this.options.debounce) {
3137
- window.clearTimeout(this._debounced);
3138
- this._debounced = window.setTimeout(function () {
3139
- return _this4.validate();
3140
- }, this.options.debounce);
3141
- } else this.validate();
3142
- },
3143
-
3144
- _resetUI: function _resetUI() {
3145
- // Reset all event listeners
3146
- this._failedOnce = false;
3147
- this._actualizeTriggers();
3148
-
3149
- // Nothing to do if UI never initialized for this field
3150
- if ('undefined' === typeof this._ui) return;
3151
-
3152
- // Reset all errors' li
3153
- this._ui.$errorsWrapper.removeClass('filled').children().remove();
3154
-
3155
- // Reset validation class
3156
- this._resetClass();
3157
-
3158
- // Reset validation flags and last validation result
3159
- this._ui.lastValidationResult = [];
3160
- this._ui.validationInformationVisible = false;
3161
- },
3162
-
3163
- _destroyUI: function _destroyUI() {
3164
- this._resetUI();
3165
-
3166
- if ('undefined' !== typeof this._ui) this._ui.$errorsWrapper.remove();
3167
-
3168
- delete this._ui;
3169
- },
3170
-
3171
- _successClass: function _successClass() {
3172
- this._ui.validationInformationVisible = true;
3173
- this._ui.$errorClassHandler.removeClass(this.options.errorClass).addClass(this.options.successClass);
3174
- },
3175
- _errorClass: function _errorClass() {
3176
- this._ui.validationInformationVisible = true;
3177
- this._ui.$errorClassHandler.removeClass(this.options.successClass).addClass(this.options.errorClass);
3178
- },
3179
- _resetClass: function _resetClass() {
3180
- this._ui.$errorClassHandler.removeClass(this.options.successClass).removeClass(this.options.errorClass);
3181
- }
3182
- };
3183
-
3184
- var Form = function Form(element, domOptions, options) {
3185
- this.__class__ = 'Form';
3186
-
3187
- this.element = element;
3188
- this.$element = $(element);
3189
- this.domOptions = domOptions;
3190
- this.options = options;
3191
- this.parent = window.Parsley;
3192
-
3193
- this.fields = [];
3194
- this.validationResult = null;
3195
- };
3196
-
3197
- var Form__statusMapping = { pending: null, resolved: true, rejected: false };
3198
-
3199
- Form.prototype = {
3200
- onSubmitValidate: function onSubmitValidate(event) {
3201
- var _this5 = this;
3202
-
3203
- // This is a Parsley generated submit event, do not validate, do not prevent, simply exit and keep normal behavior
3204
- if (true === event.parsley) return;
3205
-
3206
- // If we didn't come here through a submit button, use the first one in the form
3207
- var submitSource = this._submitSource || this.$element.find(Utils._SubmitSelector)[0];
3208
- this._submitSource = null;
3209
- this.$element.find('.parsley-synthetic-submit-button').prop('disabled', true);
3210
- if (submitSource && null !== submitSource.getAttribute('formnovalidate')) return;
3211
-
3212
- window.Parsley._remoteCache = {};
3213
-
3214
- var promise = this.whenValidate({ event: event });
3215
-
3216
- if ('resolved' === promise.state() && false !== this._trigger('submit')) {
3217
- // All good, let event go through. We make this distinction because browsers
3218
- // differ in their handling of `submit` being called from inside a submit event [#1047]
3219
- } else {
3220
- // Rejected or pending: cancel this submit
3221
- event.stopImmediatePropagation();
3222
- event.preventDefault();
3223
- if ('pending' === promise.state()) promise.done(function () {
3224
- _this5._submit(submitSource);
3225
- });
3226
- }
3227
- },
3228
-
3229
- onSubmitButton: function onSubmitButton(event) {
3230
- this._submitSource = event.currentTarget;
3231
- },
3232
- // internal
3233
- // _submit submits the form, this time without going through the validations.
3234
- // Care must be taken to "fake" the actual submit button being clicked.
3235
- _submit: function _submit(submitSource) {
3236
- if (false === this._trigger('submit')) return;
3237
- // Add submit button's data
3238
- if (submitSource) {
3239
- var $synthetic = this.$element.find('.parsley-synthetic-submit-button').prop('disabled', false);
3240
- if (0 === $synthetic.length) $synthetic = $('<input class="parsley-synthetic-submit-button" type="hidden">').appendTo(this.$element);
3241
- $synthetic.attr({
3242
- name: submitSource.getAttribute('name'),
3243
- value: submitSource.getAttribute('value')
3244
- });
3245
- }
3246
-
3247
- this.$element.trigger(_extends($.Event('submit'), { parsley: true }));
3248
- },
3249
-
3250
- // Performs validation on fields while triggering events.
3251
- // @returns `true` if all validations succeeds, `false`
3252
- // if a failure is immediately detected, or `null`
3253
- // if dependant on a promise.
3254
- // Consider using `whenValidate` instead.
3255
- validate: function validate(options) {
3256
- if (arguments.length >= 1 && !$.isPlainObject(options)) {
3257
- Utils.warnOnce('Calling validate on a parsley form without passing arguments as an object is deprecated.');
3258
-
3259
- var _arguments = _slice.call(arguments);
3260
-
3261
- var group = _arguments[0];
3262
- var force = _arguments[1];
3263
- var event = _arguments[2];
3264
-
3265
- options = { group: group, force: force, event: event };
3266
- }
3267
- return Form__statusMapping[this.whenValidate(options).state()];
3268
- },
3269
-
3270
- whenValidate: function whenValidate() {
3271
- var _Utils$all$done$fail$always,
3272
- _this6 = this;
3273
-
3274
- var _ref7 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
3275
-
3276
- var group = _ref7.group;
3277
- var force = _ref7.force;
3278
- var event = _ref7.event;
3279
-
3280
- this.submitEvent = event;
3281
- if (event) {
3282
- this.submitEvent = _extends({}, event, { preventDefault: function preventDefault() {
3283
- Utils.warnOnce("Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`");
3284
- _this6.validationResult = false;
3285
- } });
3286
- }
3287
- this.validationResult = true;
3288
-
3289
- // fire validate event to eventually modify things before every validation
3290
- this._trigger('validate');
3291
-
3292
- // Refresh form DOM options and form's fields that could have changed
3293
- this._refreshFields();
3294
-
3295
- var promises = this._withoutReactualizingFormOptions(function () {
3296
- return $.map(_this6.fields, function (field) {
3297
- return field.whenValidate({ force: force, group: group });
3298
- });
3299
- });
3300
-
3301
- return (_Utils$all$done$fail$always = Utils.all(promises).done(function () {
3302
- _this6._trigger('success');
3303
- }).fail(function () {
3304
- _this6.validationResult = false;
3305
- _this6.focus();
3306
- _this6._trigger('error');
3307
- }).always(function () {
3308
- _this6._trigger('validated');
3309
- })).pipe.apply(_Utils$all$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult()));
3310
- },
3311
-
3312
- // Iterate over refreshed fields, and stop on first failure.
3313
- // Returns `true` if all fields are valid, `false` if a failure is detected
3314
- // or `null` if the result depends on an unresolved promise.
3315
- // Prefer using `whenValid` instead.
3316
- isValid: function isValid(options) {
3317
- if (arguments.length >= 1 && !$.isPlainObject(options)) {
3318
- Utils.warnOnce('Calling isValid on a parsley form without passing arguments as an object is deprecated.');
3319
-
3320
- var _arguments2 = _slice.call(arguments);
3321
-
3322
- var group = _arguments2[0];
3323
- var force = _arguments2[1];
3324
-
3325
- options = { group: group, force: force };
3326
- }
3327
- return Form__statusMapping[this.whenValid(options).state()];
3328
- },
3329
-
3330
- // Iterate over refreshed fields and validate them.
3331
- // Returns a promise.
3332
- // A validation that immediately fails will interrupt the validations.
3333
- whenValid: function whenValid() {
3334
- var _this7 = this;
3335
-
3336
- var _ref8 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
3337
-
3338
- var group = _ref8.group;
3339
- var force = _ref8.force;
3340
-
3341
- this._refreshFields();
3342
-
3343
- var promises = this._withoutReactualizingFormOptions(function () {
3344
- return $.map(_this7.fields, function (field) {
3345
- return field.whenValid({ group: group, force: force });
3346
- });
3347
- });
3348
- return Utils.all(promises);
3349
- },
3350
-
3351
- refresh: function refresh() {
3352
- this._refreshFields();
3353
- return this;
3354
- },
3355
-
3356
- // Reset UI
3357
- reset: function reset() {
3358
- // Form case: emit a reset event for each field
3359
- for (var i = 0; i < this.fields.length; i++) this.fields[i].reset();
3360
-
3361
- this._trigger('reset');
3362
- },
3363
-
3364
- // Destroy Parsley instance (+ UI)
3365
- destroy: function destroy() {
3366
- // Field case: emit destroy event to clean UI and then destroy stored instance
3367
- this._destroyUI();
3368
-
3369
- // Form case: destroy all its fields and then destroy stored instance
3370
- for (var i = 0; i < this.fields.length; i++) this.fields[i].destroy();
3371
-
3372
- this.$element.removeData('Parsley');
3373
- this._trigger('destroy');
3374
- },
3375
-
3376
- _refreshFields: function _refreshFields() {
3377
- return this.actualizeOptions()._bindFields();
3378
- },
3379
-
3380
- _bindFields: function _bindFields() {
3381
- var _this8 = this;
3382
-
3383
- var oldFields = this.fields;
3384
-
3385
- this.fields = [];
3386
- this.fieldsMappedById = {};
3387
-
3388
- this._withoutReactualizingFormOptions(function () {
3389
- _this8.$element.find(_this8.options.inputs).not(_this8.options.excluded).each(function (_, element) {
3390
- var fieldInstance = new window.Parsley.Factory(element, {}, _this8);
3391
-
3392
- // Only add valid and not excluded `Field` and `FieldMultiple` children
3393
- if (('Field' === fieldInstance.__class__ || 'FieldMultiple' === fieldInstance.__class__) && true !== fieldInstance.options.excluded) {
3394
- var uniqueId = fieldInstance.__class__ + '-' + fieldInstance.__id__;
3395
- if ('undefined' === typeof _this8.fieldsMappedById[uniqueId]) {
3396
- _this8.fieldsMappedById[uniqueId] = fieldInstance;
3397
- _this8.fields.push(fieldInstance);
3398
- }
3399
- }
3400
- });
3401
-
3402
- $.each(Utils.difference(oldFields, _this8.fields), function (_, field) {
3403
- field.reset();
3404
- });
3405
- });
3406
- return this;
3407
- },
3408
-
3409
- // Internal only.
3410
- // Looping on a form's fields to do validation or similar
3411
- // will trigger reactualizing options on all of them, which
3412
- // in turn will reactualize the form's options.
3413
- // To avoid calling actualizeOptions so many times on the form
3414
- // for nothing, _withoutReactualizingFormOptions temporarily disables
3415
- // the method actualizeOptions on this form while `fn` is called.
3416
- _withoutReactualizingFormOptions: function _withoutReactualizingFormOptions(fn) {
3417
- var oldActualizeOptions = this.actualizeOptions;
3418
- this.actualizeOptions = function () {
3419
- return this;
3420
- };
3421
- var result = fn();
3422
- this.actualizeOptions = oldActualizeOptions;
3423
- return result;
3424
- },
3425
-
3426
- // Internal only.
3427
- // Shortcut to trigger an event
3428
- // Returns true iff event is not interrupted and default not prevented.
3429
- _trigger: function _trigger(eventName) {
3430
- return this.trigger('form:' + eventName);
3431
- }
3432
-
3433
- };
3434
-
3435
- var Constraint = function Constraint(parsleyField, name, requirements, priority, isDomConstraint) {
3436
- var validatorSpec = window.Parsley._validatorRegistry.validators[name];
3437
- var validator = new Validator(validatorSpec);
3438
- priority = priority || parsleyField.options[name + 'Priority'] || validator.priority;
3439
- isDomConstraint = true === isDomConstraint;
3440
-
3441
- _extends(this, {
3442
- validator: validator,
3443
- name: name,
3444
- requirements: requirements,
3445
- priority: priority,
3446
- isDomConstraint: isDomConstraint
3447
- });
3448
- this._parseRequirements(parsleyField.options);
3449
- };
3450
-
3451
- var capitalize = function capitalize(str) {
3452
- var cap = str[0].toUpperCase();
3453
- return cap + str.slice(1);
3454
- };
3455
-
3456
- Constraint.prototype = {
3457
- validate: function validate(value, instance) {
3458
- var _validator;
3459
-
3460
- return (_validator = this.validator).validate.apply(_validator, [value].concat(_toConsumableArray(this.requirementList), [instance]));
3461
- },
3462
-
3463
- _parseRequirements: function _parseRequirements(options) {
3464
- var _this9 = this;
3465
-
3466
- this.requirementList = this.validator.parseRequirements(this.requirements, function (key) {
3467
- return options[_this9.name + capitalize(key)];
3468
- });
3469
- }
3470
- };
3471
-
3472
- var Field = function Field(field, domOptions, options, parsleyFormInstance) {
3473
- this.__class__ = 'Field';
3474
-
3475
- this.element = field;
3476
- this.$element = $(field);
3477
-
3478
- // Set parent if we have one
3479
- if ('undefined' !== typeof parsleyFormInstance) {
3480
- this.parent = parsleyFormInstance;
3481
- }
3482
-
3483
- this.options = options;
3484
- this.domOptions = domOptions;
3485
-
3486
- // Initialize some properties
3487
- this.constraints = [];
3488
- this.constraintsByName = {};
3489
- this.validationResult = true;
3490
-
3491
- // Bind constraints
3492
- this._bindConstraints();
3493
- };
3494
-
3495
- var parsley_field__statusMapping = { pending: null, resolved: true, rejected: false };
3496
-
3497
- Field.prototype = {
3498
- // # Public API
3499
- // Validate field and trigger some events for mainly `UI`
3500
- // @returns `true`, an array of the validators that failed, or
3501
- // `null` if validation is not finished. Prefer using whenValidate
3502
- validate: function validate(options) {
3503
- if (arguments.length >= 1 && !$.isPlainObject(options)) {
3504
- Utils.warnOnce('Calling validate on a parsley field without passing arguments as an object is deprecated.');
3505
- options = { options: options };
3506
- }
3507
- var promise = this.whenValidate(options);
3508
- if (!promise) // If excluded with `group` option
3509
- return true;
3510
- switch (promise.state()) {
3511
- case 'pending':
3512
- return null;
3513
- case 'resolved':
3514
- return true;
3515
- case 'rejected':
3516
- return this.validationResult;
3517
- }
3518
- },
3519
-
3520
- // Validate field and trigger some events for mainly `UI`
3521
- // @returns a promise that succeeds only when all validations do
3522
- // or `undefined` if field is not in the given `group`.
3523
- whenValidate: function whenValidate() {
3524
- var _whenValid$always$done$fail$always,
3525
- _this10 = this;
3526
-
3527
- var _ref9 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
3528
-
3529
- var force = _ref9.force;
3530
- var group = _ref9.group;
3531
-
3532
- // do not validate a field if not the same as given validation group
3533
- this.refresh();
3534
- if (group && !this._isInGroup(group)) return;
3535
-
3536
- this.value = this.getValue();
3537
-
3538
- // Field Validate event. `this.value` could be altered for custom needs
3539
- this._trigger('validate');
3540
-
3541
- return (_whenValid$always$done$fail$always = this.whenValid({ force: force, value: this.value, _refreshed: true }).always(function () {
3542
- _this10._reflowUI();
3543
- }).done(function () {
3544
- _this10._trigger('success');
3545
- }).fail(function () {
3546
- _this10._trigger('error');
3547
- }).always(function () {
3548
- _this10._trigger('validated');
3549
- })).pipe.apply(_whenValid$always$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult()));
3550
- },
3551
-
3552
- hasConstraints: function hasConstraints() {
3553
- return 0 !== this.constraints.length;
3554
- },
3555
-
3556
- // An empty optional field does not need validation
3557
- needsValidation: function needsValidation(value) {
3558
- if ('undefined' === typeof value) value = this.getValue();
3559
-
3560
- // If a field is empty and not required, it is valid
3561
- // Except if `data-parsley-validate-if-empty` explicitely added, useful for some custom validators
3562
- if (!value.length && !this._isRequired() && 'undefined' === typeof this.options.validateIfEmpty) return false;
3563
-
3564
- return true;
3565
- },
3566
-
3567
- _isInGroup: function _isInGroup(group) {
3568
- if (Array.isArray(this.options.group)) return -1 !== $.inArray(group, this.options.group);
3569
- return this.options.group === group;
3570
- },
3571
-
3572
- // Just validate field. Do not trigger any event.
3573
- // Returns `true` iff all constraints pass, `false` if there are failures,
3574
- // or `null` if the result can not be determined yet (depends on a promise)
3575
- // See also `whenValid`.
3576
- isValid: function isValid(options) {
3577
- if (arguments.length >= 1 && !$.isPlainObject(options)) {
3578
- Utils.warnOnce('Calling isValid on a parsley field without passing arguments as an object is deprecated.');
3579
-
3580
- var _arguments3 = _slice.call(arguments);
3581
-
3582
- var force = _arguments3[0];
3583
- var value = _arguments3[1];
3584
-
3585
- options = { force: force, value: value };
3586
- }
3587
- var promise = this.whenValid(options);
3588
- if (!promise) // Excluded via `group`
3589
- return true;
3590
- return parsley_field__statusMapping[promise.state()];
3591
- },
3592
-
3593
- // Just validate field. Do not trigger any event.
3594
- // @returns a promise that succeeds only when all validations do
3595
- // or `undefined` if the field is not in the given `group`.
3596
- // The argument `force` will force validation of empty fields.
3597
- // If a `value` is given, it will be validated instead of the value of the input.
3598
- whenValid: function whenValid() {
3599
- var _this11 = this;
3600
-
3601
- var _ref10 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
3602
-
3603
- var _ref10$force = _ref10.force;
3604
- var force = _ref10$force === undefined ? false : _ref10$force;
3605
- var value = _ref10.value;
3606
- var group = _ref10.group;
3607
- var _refreshed = _ref10._refreshed;
3608
-
3609
- // Recompute options and rebind constraints to have latest changes
3610
- if (!_refreshed) this.refresh();
3611
- // do not validate a field if not the same as given validation group
3612
- if (group && !this._isInGroup(group)) return;
3613
-
3614
- this.validationResult = true;
3615
-
3616
- // A field without constraint is valid
3617
- if (!this.hasConstraints()) return $.when();
3618
-
3619
- // Value could be passed as argument, needed to add more power to 'field:validate'
3620
- if ('undefined' === typeof value || null === value) value = this.getValue();
3621
-
3622
- if (!this.needsValidation(value) && true !== force) return $.when();
3623
-
3624
- var groupedConstraints = this._getGroupedConstraints();
3625
- var promises = [];
3626
- $.each(groupedConstraints, function (_, constraints) {
3627
- // Process one group of constraints at a time, we validate the constraints
3628
- // and combine the promises together.
3629
- var promise = Utils.all($.map(constraints, function (constraint) {
3630
- return _this11._validateConstraint(value, constraint);
3631
- }));
3632
- promises.push(promise);
3633
- if (promise.state() === 'rejected') return false; // Interrupt processing if a group has already failed
3634
- });
3635
- return Utils.all(promises);
3636
- },
3637
-
3638
- // @returns a promise
3639
- _validateConstraint: function _validateConstraint(value, constraint) {
3640
- var _this12 = this;
3641
-
3642
- var result = constraint.validate(value, this);
3643
- // Map false to a failed promise
3644
- if (false === result) result = $.Deferred().reject();
3645
- // Make sure we return a promise and that we record failures
3646
- return Utils.all([result]).fail(function (errorMessage) {
3647
- if (!(_this12.validationResult instanceof Array)) _this12.validationResult = [];
3648
- _this12.validationResult.push({
3649
- assert: constraint,
3650
- errorMessage: 'string' === typeof errorMessage && errorMessage
3651
- });
3652
- });
3653
- },
3654
-
3655
- // @returns Parsley field computed value that could be overrided or configured in DOM
3656
- getValue: function getValue() {
3657
- var value;
3658
-
3659
- // Value could be overriden in DOM or with explicit options
3660
- if ('function' === typeof this.options.value) value = this.options.value(this);else if ('undefined' !== typeof this.options.value) value = this.options.value;else value = this.$element.val();
3661
-
3662
- // Handle wrong DOM or configurations
3663
- if ('undefined' === typeof value || null === value) return '';
3664
-
3665
- return this._handleWhitespace(value);
3666
- },
3667
-
3668
- // Reset UI
3669
- reset: function reset() {
3670
- this._resetUI();
3671
- return this._trigger('reset');
3672
- },
3673
-
3674
- // Destroy Parsley instance (+ UI)
3675
- destroy: function destroy() {
3676
- // Field case: emit destroy event to clean UI and then destroy stored instance
3677
- this._destroyUI();
3678
- this.$element.removeData('Parsley');
3679
- this.$element.removeData('FieldMultiple');
3680
- this._trigger('destroy');
3681
- },
3682
-
3683
- // Actualize options and rebind constraints
3684
- refresh: function refresh() {
3685
- this._refreshConstraints();
3686
- return this;
3687
- },
3688
-
3689
- _refreshConstraints: function _refreshConstraints() {
3690
- return this.actualizeOptions()._bindConstraints();
3691
- },
3692
-
3693
- refreshConstraints: function refreshConstraints() {
3694
- Utils.warnOnce("Parsley's refreshConstraints is deprecated. Please use refresh");
3695
- return this.refresh();
3696
- },
3697
-
3698
- /**
3699
- * Add a new constraint to a field
3700
- *
3701
- * @param {String} name
3702
- * @param {Mixed} requirements optional
3703
- * @param {Number} priority optional
3704
- * @param {Boolean} isDomConstraint optional
3705
- */
3706
- addConstraint: function addConstraint(name, requirements, priority, isDomConstraint) {
3707
-
3708
- if (window.Parsley._validatorRegistry.validators[name]) {
3709
- var constraint = new Constraint(this, name, requirements, priority, isDomConstraint);
3710
-
3711
- // if constraint already exist, delete it and push new version
3712
- if ('undefined' !== this.constraintsByName[constraint.name]) this.removeConstraint(constraint.name);
3713
-
3714
- this.constraints.push(constraint);
3715
- this.constraintsByName[constraint.name] = constraint;
3716
- }
3717
-
3718
- return this;
3719
- },
3720
-
3721
- // Remove a constraint
3722
- removeConstraint: function removeConstraint(name) {
3723
- for (var i = 0; i < this.constraints.length; i++) if (name === this.constraints[i].name) {
3724
- this.constraints.splice(i, 1);
3725
- break;
3726
- }
3727
- delete this.constraintsByName[name];
3728
- return this;
3729
- },
3730
-
3731
- // Update a constraint (Remove + re-add)
3732
- updateConstraint: function updateConstraint(name, parameters, priority) {
3733
- return this.removeConstraint(name).addConstraint(name, parameters, priority);
3734
- },
3735
-
3736
- // # Internals
3737
-
3738
- // Internal only.
3739
- // Bind constraints from config + options + DOM
3740
- _bindConstraints: function _bindConstraints() {
3741
- var constraints = [];
3742
- var constraintsByName = {};
3743
-
3744
- // clean all existing DOM constraints to only keep javascript user constraints
3745
- for (var i = 0; i < this.constraints.length; i++) if (false === this.constraints[i].isDomConstraint) {
3746
- constraints.push(this.constraints[i]);
3747
- constraintsByName[this.constraints[i].name] = this.constraints[i];
3748
- }
3749
-
3750
- this.constraints = constraints;
3751
- this.constraintsByName = constraintsByName;
3752
-
3753
- // then re-add Parsley DOM-API constraints
3754
- for (var name in this.options) this.addConstraint(name, this.options[name], undefined, true);
3755
-
3756
- // finally, bind special HTML5 constraints
3757
- return this._bindHtml5Constraints();
3758
- },
3759
-
3760
- // Internal only.
3761
- // Bind specific HTML5 constraints to be HTML5 compliant
3762
- _bindHtml5Constraints: function _bindHtml5Constraints() {
3763
- // html5 required
3764
- if (null !== this.element.getAttribute('required')) this.addConstraint('required', true, undefined, true);
3765
-
3766
- // html5 pattern
3767
- if (null !== this.element.getAttribute('pattern')) this.addConstraint('pattern', this.element.getAttribute('pattern'), undefined, true);
3768
-
3769
- // range
3770
- var min = this.element.getAttribute('min');
3771
- var max = this.element.getAttribute('max');
3772
- if (null !== min && null !== max) this.addConstraint('range', [min, max], undefined, true);
3773
-
3774
- // HTML5 min
3775
- else if (null !== min) this.addConstraint('min', min, undefined, true);
3776
-
3777
- // HTML5 max
3778
- else if (null !== max) this.addConstraint('max', max, undefined, true);
3779
-
3780
- // length
3781
- if (null !== this.element.getAttribute('minlength') && null !== this.element.getAttribute('maxlength')) this.addConstraint('length', [this.element.getAttribute('minlength'), this.element.getAttribute('maxlength')], undefined, true);
3782
-
3783
- // HTML5 minlength
3784
- else if (null !== this.element.getAttribute('minlength')) this.addConstraint('minlength', this.element.getAttribute('minlength'), undefined, true);
3785
-
3786
- // HTML5 maxlength
3787
- else if (null !== this.element.getAttribute('maxlength')) this.addConstraint('maxlength', this.element.getAttribute('maxlength'), undefined, true);
3788
-
3789
- // html5 types
3790
- var type = Utils.getType(this.element);
3791
-
3792
- // Small special case here for HTML5 number: integer validator if step attribute is undefined or an integer value, number otherwise
3793
- if ('number' === type) {
3794
- return this.addConstraint('type', ['number', {
3795
- step: this.element.getAttribute('step') || '1',
3796
- base: min || this.element.getAttribute('value')
3797
- }], undefined, true);
3798
- // Regular other HTML5 supported types
3799
- } else if (/^(email|url|range|date)$/i.test(type)) {
3800
- return this.addConstraint('type', type, undefined, true);
3801
- }
3802
- return this;
3803
- },
3804
-
3805
- // Internal only.
3806
- // Field is required if have required constraint without `false` value
3807
- _isRequired: function _isRequired() {
3808
- if ('undefined' === typeof this.constraintsByName.required) return false;
3809
-
3810
- return false !== this.constraintsByName.required.requirements;
3811
- },
3812
-
3813
- // Internal only.
3814
- // Shortcut to trigger an event
3815
- _trigger: function _trigger(eventName) {
3816
- return this.trigger('field:' + eventName);
3817
- },
3818
-
3819
- // Internal only
3820
- // Handles whitespace in a value
3821
- // Use `data-parsley-whitespace="squish"` to auto squish input value
3822
- // Use `data-parsley-whitespace="trim"` to auto trim input value
3823
- _handleWhitespace: function _handleWhitespace(value) {
3824
- if (true === this.options.trimValue) Utils.warnOnce('data-parsley-trim-value="true" is deprecated, please use data-parsley-whitespace="trim"');
3825
-
3826
- if ('squish' === this.options.whitespace) value = value.replace(/\s{2,}/g, ' ');
3827
-
3828
- if ('trim' === this.options.whitespace || 'squish' === this.options.whitespace || true === this.options.trimValue) value = Utils.trimString(value);
3829
-
3830
- return value;
3831
- },
3832
-
3833
- _isDateInput: function _isDateInput() {
3834
- var c = this.constraintsByName.type;
3835
- return c && c.requirements === 'date';
3836
- },
3837
-
3838
- // Internal only.
3839
- // Returns the constraints, grouped by descending priority.
3840
- // The result is thus an array of arrays of constraints.
3841
- _getGroupedConstraints: function _getGroupedConstraints() {
3842
- if (false === this.options.priorityEnabled) return [this.constraints];
3843
-
3844
- var groupedConstraints = [];
3845
- var index = {};
3846
-
3847
- // Create array unique of priorities
3848
- for (var i = 0; i < this.constraints.length; i++) {
3849
- var p = this.constraints[i].priority;
3850
- if (!index[p]) groupedConstraints.push(index[p] = []);
3851
- index[p].push(this.constraints[i]);
3852
- }
3853
- // Sort them by priority DESC
3854
- groupedConstraints.sort(function (a, b) {
3855
- return b[0].priority - a[0].priority;
3856
- });
3857
-
3858
- return groupedConstraints;
3859
- }
3860
-
3861
- };
3862
-
3863
- var parsley_field = Field;
3864
-
3865
- var Multiple = function Multiple() {
3866
- this.__class__ = 'FieldMultiple';
3867
- };
3868
-
3869
- Multiple.prototype = {
3870
- // Add new `$element` sibling for multiple field
3871
- addElement: function addElement($element) {
3872
- this.$elements.push($element);
3873
-
3874
- return this;
3875
- },
3876
-
3877
- // See `Field._refreshConstraints()`
3878
- _refreshConstraints: function _refreshConstraints() {
3879
- var fieldConstraints;
3880
-
3881
- this.constraints = [];
3882
-
3883
- // Select multiple special treatment
3884
- if (this.element.nodeName === 'SELECT') {
3885
- this.actualizeOptions()._bindConstraints();
3886
-
3887
- return this;
3888
- }
3889
-
3890
- // Gather all constraints for each input in the multiple group
3891
- for (var i = 0; i < this.$elements.length; i++) {
3892
-
3893
- // Check if element have not been dynamically removed since last binding
3894
- if (!$('html').has(this.$elements[i]).length) {
3895
- this.$elements.splice(i, 1);
3896
- continue;
3897
- }
3898
-
3899
- fieldConstraints = this.$elements[i].data('FieldMultiple')._refreshConstraints().constraints;
3900
-
3901
- for (var j = 0; j < fieldConstraints.length; j++) this.addConstraint(fieldConstraints[j].name, fieldConstraints[j].requirements, fieldConstraints[j].priority, fieldConstraints[j].isDomConstraint);
3902
- }
3903
-
3904
- return this;
3905
- },
3906
-
3907
- // See `Field.getValue()`
3908
- getValue: function getValue() {
3909
- // Value could be overriden in DOM
3910
- if ('function' === typeof this.options.value) return this.options.value(this);else if ('undefined' !== typeof this.options.value) return this.options.value;
3911
-
3912
- // Radio input case
3913
- if (this.element.nodeName === 'INPUT') {
3914
- var type = Utils.getType(this.element);
3915
- if (type === 'radio') return this._findRelated().filter(':checked').val() || '';
3916
-
3917
- // checkbox input case
3918
- if (type === 'checkbox') {
3919
- var values = [];
3920
-
3921
- this._findRelated().filter(':checked').each(function () {
3922
- values.push($(this).val());
3923
- });
3924
-
3925
- return values;
3926
- }
3927
- }
3928
-
3929
- // Select multiple case
3930
- if (this.element.nodeName === 'SELECT' && null === this.$element.val()) return [];
3931
-
3932
- // Default case that should never happen
3933
- return this.$element.val();
3934
- },
3935
-
3936
- _init: function _init() {
3937
- this.$elements = [this.$element];
3938
-
3939
- return this;
3940
- }
3941
- };
3942
-
3943
- var Factory = function Factory(element, options, parsleyFormInstance) {
3944
- this.element = element;
3945
- this.$element = $(element);
3946
-
3947
- // If the element has already been bound, returns its saved Parsley instance
3948
- var savedparsleyFormInstance = this.$element.data('Parsley');
3949
- if (savedparsleyFormInstance) {
3950
-
3951
- // If the saved instance has been bound without a Form parent and there is one given in this call, add it
3952
- if ('undefined' !== typeof parsleyFormInstance && savedparsleyFormInstance.parent === window.Parsley) {
3953
- savedparsleyFormInstance.parent = parsleyFormInstance;
3954
- savedparsleyFormInstance._resetOptions(savedparsleyFormInstance.options);
3955
- }
3956
-
3957
- if ('object' === typeof options) {
3958
- _extends(savedparsleyFormInstance.options, options);
3959
- }
3960
-
3961
- return savedparsleyFormInstance;
3962
- }
3963
-
3964
- // Parsley must be instantiated with a DOM element or jQuery $element
3965
- if (!this.$element.length) throw new Error('You must bind Parsley on an existing element.');
3966
-
3967
- if ('undefined' !== typeof parsleyFormInstance && 'Form' !== parsleyFormInstance.__class__) throw new Error('Parent instance must be a Form instance');
3968
-
3969
- this.parent = parsleyFormInstance || window.Parsley;
3970
- return this.init(options);
3971
- };
3972
-
3973
- Factory.prototype = {
3974
- init: function init(options) {
3975
- this.__class__ = 'Parsley';
3976
- this.__version__ = '2.8.0';
3977
- this.__id__ = Utils.generateID();
3978
-
3979
- // Pre-compute options
3980
- this._resetOptions(options);
3981
-
3982
- // A Form instance is obviously a `<form>` element but also every node that is not an input and has the `data-parsley-validate` attribute
3983
- if (this.element.nodeName === 'FORM' || Utils.checkAttr(this.element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)) return this.bind('parsleyForm');
3984
-
3985
- // Every other element is bound as a `Field` or `FieldMultiple`
3986
- return this.isMultiple() ? this.handleMultiple() : this.bind('parsleyField');
3987
- },
3988
-
3989
- isMultiple: function isMultiple() {
3990
- var type = Utils.getType(this.element);
3991
- return type === 'radio' || type === 'checkbox' || this.element.nodeName === 'SELECT' && null !== this.element.getAttribute('multiple');
3992
- },
3993
-
3994
- // Multiples fields are a real nightmare :(
3995
- // Maybe some refactoring would be appreciated here...
3996
- handleMultiple: function handleMultiple() {
3997
- var _this13 = this;
3998
-
3999
- var name;
4000
- var multiple;
4001
- var parsleyMultipleInstance;
4002
-
4003
- // Handle multiple name
4004
- this.options.multiple = this.options.multiple || (name = this.element.getAttribute('name')) || this.element.getAttribute('id');
4005
-
4006
- // Special select multiple input
4007
- if (this.element.nodeName === 'SELECT' && null !== this.element.getAttribute('multiple')) {
4008
- this.options.multiple = this.options.multiple || this.__id__;
4009
- return this.bind('parsleyFieldMultiple');
4010
-
4011
- // Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it
4012
- } else if (!this.options.multiple) {
4013
- Utils.warn('To be bound by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.', this.$element);
4014
- return this;
4015
- }
4016
-
4017
- // Remove special chars
4018
- this.options.multiple = this.options.multiple.replace(/(:|\.|\[|\]|\{|\}|\$)/g, '');
4019
-
4020
- // Add proper `data-parsley-multiple` to siblings if we have a valid multiple name
4021
- if (name) {
4022
- $('input[name="' + name + '"]').each(function (i, input) {
4023
- var type = Utils.getType(input);
4024
- if (type === 'radio' || type === 'checkbox') input.setAttribute(_this13.options.namespace + 'multiple', _this13.options.multiple);
4025
- });
4026
- }
4027
-
4028
- // Check here if we don't already have a related multiple instance saved
4029
- var $previouslyRelated = this._findRelated();
4030
- for (var i = 0; i < $previouslyRelated.length; i++) {
4031
- parsleyMultipleInstance = $($previouslyRelated.get(i)).data('Parsley');
4032
- if ('undefined' !== typeof parsleyMultipleInstance) {
4033
-
4034
- if (!this.$element.data('FieldMultiple')) {
4035
- parsleyMultipleInstance.addElement(this.$element);
4036
- }
4037
-
4038
- break;
4039
- }
4040
- }
4041
-
4042
- // Create a secret Field instance for every multiple field. It will be stored in `data('FieldMultiple')`
4043
- // And will be useful later to access classic `Field` stuff while being in a `FieldMultiple` instance
4044
- this.bind('parsleyField', true);
4045
-
4046
- return parsleyMultipleInstance || this.bind('parsleyFieldMultiple');
4047
- },
4048
-
4049
- // Return proper `Form`, `Field` or `FieldMultiple`
4050
- bind: function bind(type, doNotStore) {
4051
- var parsleyInstance;
4052
-
4053
- switch (type) {
4054
- case 'parsleyForm':
4055
- parsleyInstance = $.extend(new Form(this.element, this.domOptions, this.options), new Base(), window.ParsleyExtend)._bindFields();
4056
- break;
4057
- case 'parsleyField':
4058
- parsleyInstance = $.extend(new parsley_field(this.element, this.domOptions, this.options, this.parent), new Base(), window.ParsleyExtend);
4059
- break;
4060
- case 'parsleyFieldMultiple':
4061
- parsleyInstance = $.extend(new parsley_field(this.element, this.domOptions, this.options, this.parent), new Multiple(), new Base(), window.ParsleyExtend)._init();
4062
- break;
4063
- default:
4064
- throw new Error(type + 'is not a supported Parsley type');
4065
- }
4066
-
4067
- if (this.options.multiple) Utils.setAttr(this.element, this.options.namespace, 'multiple', this.options.multiple);
4068
-
4069
- if ('undefined' !== typeof doNotStore) {
4070
- this.$element.data('FieldMultiple', parsleyInstance);
4071
-
4072
- return parsleyInstance;
4073
- }
4074
-
4075
- // Store the freshly bound instance in a DOM element for later access using jQuery `data()`
4076
- this.$element.data('Parsley', parsleyInstance);
4077
-
4078
- // Tell the world we have a new Form or Field instance!
4079
- parsleyInstance._actualizeTriggers();
4080
- parsleyInstance._trigger('init');
4081
-
4082
- return parsleyInstance;
4083
- }
4084
- };
4085
-
4086
- var vernums = $.fn.jquery.split('.');
4087
- if (parseInt(vernums[0]) <= 1 && parseInt(vernums[1]) < 8) {
4088
- throw "The loaded version of jQuery is too old. Please upgrade to 1.8.x or better.";
4089
- }
4090
- if (!vernums.forEach) {
4091
- Utils.warn('Parsley requires ES5 to run properly. Please include https://github.com/es-shims/es5-shim');
4092
- }
4093
- // Inherit `on`, `off` & `trigger` to Parsley:
4094
- var Parsley = _extends(new Base(), {
4095
- element: document,
4096
- $element: $(document),
4097
- actualizeOptions: null,
4098
- _resetOptions: null,
4099
- Factory: Factory,
4100
- version: '2.8.0'
4101
- });
4102
-
4103
- // Supplement Field and Form with Base
4104
- // This way, the constructors will have access to those methods
4105
- _extends(parsley_field.prototype, UI.Field, Base.prototype);
4106
- _extends(Form.prototype, UI.Form, Base.prototype);
4107
- // Inherit actualizeOptions and _resetOptions:
4108
- _extends(Factory.prototype, Base.prototype);
4109
-
4110
- // ### jQuery API
4111
- // `$('.elem').parsley(options)` or `$('.elem').psly(options)`
4112
- $.fn.parsley = $.fn.psly = function (options) {
4113
- if (this.length > 1) {
4114
- var instances = [];
4115
-
4116
- this.each(function () {
4117
- instances.push($(this).parsley(options));
4118
- });
4119
-
4120
- return instances;
4121
- }
4122
-
4123
- // Return undefined if applied to non existing DOM element
4124
- if (this.length == 0) {
4125
- return;
4126
- }
4127
-
4128
- return new Factory(this[0], options);
4129
- };
4130
-
4131
- // ### Field and Form extension
4132
- // Ensure the extension is now defined if it wasn't previously
4133
- if ('undefined' === typeof window.ParsleyExtend) window.ParsleyExtend = {};
4134
-
4135
- // ### Parsley config
4136
- // Inherit from ParsleyDefault, and copy over any existing values
4137
- Parsley.options = _extends(Utils.objectCreate(Defaults), window.ParsleyConfig);
4138
- window.ParsleyConfig = Parsley.options; // Old way of accessing global options
4139
-
4140
- // ### Globals
4141
- window.Parsley = window.psly = Parsley;
4142
- Parsley.Utils = Utils;
4143
- window.ParsleyUtils = {};
4144
- $.each(Utils, function (key, value) {
4145
- if ('function' === typeof value) {
4146
- window.ParsleyUtils[key] = function () {
4147
- Utils.warnOnce('Accessing `window.ParsleyUtils` is deprecated. Use `window.Parsley.Utils` instead.');
4148
- return Utils[key].apply(Utils, arguments);
4149
- };
4150
- }
4151
- });
4152
-
4153
- // ### Define methods that forward to the registry, and deprecate all access except through window.Parsley
4154
- var registry = window.Parsley._validatorRegistry = new ValidatorRegistry(window.ParsleyConfig.validators, window.ParsleyConfig.i18n);
4155
- window.ParsleyValidator = {};
4156
- $.each('setLocale addCatalog addMessage addMessages getErrorMessage formatMessage addValidator updateValidator removeValidator hasValidator'.split(' '), function (i, method) {
4157
- window.Parsley[method] = function () {
4158
- return registry[method].apply(registry, arguments);
4159
- };
4160
- window.ParsleyValidator[method] = function () {
4161
- var _window$Parsley;
4162
-
4163
- Utils.warnOnce('Accessing the method \'' + method + '\' through Validator is deprecated. Simply call \'window.Parsley.' + method + '(...)\'');
4164
- return (_window$Parsley = window.Parsley)[method].apply(_window$Parsley, arguments);
4165
- };
4166
- });
4167
-
4168
- // ### UI
4169
- // Deprecated global object
4170
- window.Parsley.UI = UI;
4171
- window.ParsleyUI = {
4172
- removeError: function removeError(instance, name, doNotUpdateClass) {
4173
- var updateClass = true !== doNotUpdateClass;
4174
- Utils.warnOnce('Accessing UI is deprecated. Call \'removeError\' on the instance directly. Please comment in issue 1073 as to your need to call this method.');
4175
- return instance.removeError(name, { updateClass: updateClass });
4176
- },
4177
- getErrorsMessages: function getErrorsMessages(instance) {
4178
- Utils.warnOnce('Accessing UI is deprecated. Call \'getErrorsMessages\' on the instance directly.');
4179
- return instance.getErrorsMessages();
4180
- }
4181
- };
4182
- $.each('addError updateError'.split(' '), function (i, method) {
4183
- window.ParsleyUI[method] = function (instance, name, message, assert, doNotUpdateClass) {
4184
- var updateClass = true !== doNotUpdateClass;
4185
- Utils.warnOnce('Accessing UI is deprecated. Call \'' + method + '\' on the instance directly. Please comment in issue 1073 as to your need to call this method.');
4186
- return instance[method](name, { message: message, assert: assert, updateClass: updateClass });
4187
- };
4188
- });
4189
-
4190
- // ### PARSLEY auto-binding
4191
- // Prevent it by setting `ParsleyConfig.autoBind` to `false`
4192
- if (false !== window.ParsleyConfig.autoBind) {
4193
- $(function () {
4194
- // Works only on `data-parsley-validate`.
4195
- if ($('[data-parsley-validate]').length) $('[data-parsley-validate]').parsley();
4196
- });
4197
- }
4198
-
4199
- var o = $({});
4200
- var deprecated = function deprecated() {
4201
- Utils.warnOnce("Parsley's pubsub module is deprecated; use the 'on' and 'off' methods on parsley instances or window.Parsley");
4202
- };
4203
-
4204
- // Returns an event handler that calls `fn` with the arguments it expects
4205
- function adapt(fn, context) {
4206
- // Store to allow unbinding
4207
- if (!fn.parsleyAdaptedCallback) {
4208
- fn.parsleyAdaptedCallback = function () {
4209
- var args = Array.prototype.slice.call(arguments, 0);
4210
- args.unshift(this);
4211
- fn.apply(context || o, args);
4212
- };
4213
- }
4214
- return fn.parsleyAdaptedCallback;
4215
- }
4216
-
4217
- var eventPrefix = 'parsley:';
4218
- // Converts 'parsley:form:validate' into 'form:validate'
4219
- function eventName(name) {
4220
- if (name.lastIndexOf(eventPrefix, 0) === 0) return name.substr(eventPrefix.length);
4221
- return name;
4222
- }
4223
-
4224
- // $.listen is deprecated. Use Parsley.on instead.
4225
- $.listen = function (name, callback) {
4226
- var context;
4227
- deprecated();
4228
- if ('object' === typeof arguments[1] && 'function' === typeof arguments[2]) {
4229
- context = arguments[1];
4230
- callback = arguments[2];
4231
- }
4232
-
4233
- if ('function' !== typeof callback) throw new Error('Wrong parameters');
4234
-
4235
- window.Parsley.on(eventName(name), adapt(callback, context));
4236
- };
4237
-
4238
- $.listenTo = function (instance, name, fn) {
4239
- deprecated();
4240
- if (!(instance instanceof parsley_field) && !(instance instanceof Form)) throw new Error('Must give Parsley instance');
4241
-
4242
- if ('string' !== typeof name || 'function' !== typeof fn) throw new Error('Wrong parameters');
4243
-
4244
- instance.on(eventName(name), adapt(fn));
4245
- };
4246
-
4247
- $.unsubscribe = function (name, fn) {
4248
- deprecated();
4249
- if ('string' !== typeof name || 'function' !== typeof fn) throw new Error('Wrong arguments');
4250
- window.Parsley.off(eventName(name), fn.parsleyAdaptedCallback);
4251
- };
4252
-
4253
- $.unsubscribeTo = function (instance, name) {
4254
- deprecated();
4255
- if (!(instance instanceof parsley_field) && !(instance instanceof Form)) throw new Error('Must give Parsley instance');
4256
- instance.off(eventName(name));
4257
- };
4258
-
4259
- $.unsubscribeAll = function (name) {
4260
- deprecated();
4261
- window.Parsley.off(eventName(name));
4262
- $('form,input,textarea,select').each(function () {
4263
- var instance = $(this).data('Parsley');
4264
- if (instance) {
4265
- instance.off(eventName(name));
4266
- }
4267
- });
4268
- };
4269
-
4270
- // $.emit is deprecated. Use jQuery events instead.
4271
- $.emit = function (name, instance) {
4272
- var _instance;
4273
-
4274
- deprecated();
4275
- var instanceGiven = instance instanceof parsley_field || instance instanceof Form;
4276
- var args = Array.prototype.slice.call(arguments, instanceGiven ? 2 : 1);
4277
- args.unshift(eventName(name));
4278
- if (!instanceGiven) {
4279
- instance = window.Parsley;
4280
- }
4281
- (_instance = instance).trigger.apply(_instance, _toConsumableArray(args));
4282
- };
4283
-
4284
- var pubsub = {};
4285
-
4286
- $.extend(true, Parsley, {
4287
- asyncValidators: {
4288
- 'default': {
4289
- fn: function fn(xhr) {
4290
- // By default, only status 2xx are deemed successful.
4291
- // Note: we use status instead of state() because responses with status 200
4292
- // but invalid messages (e.g. an empty body for content type set to JSON) will
4293
- // result in state() === 'rejected'.
4294
- return xhr.status >= 200 && xhr.status < 300;
4295
- },
4296
- url: false
4297
- },
4298
- reverse: {
4299
- fn: function fn(xhr) {
4300
- // If reverse option is set, a failing ajax request is considered successful
4301
- return xhr.status < 200 || xhr.status >= 300;
4302
- },
4303
- url: false
4304
- }
4305
- },
4306
-
4307
- addAsyncValidator: function addAsyncValidator(name, fn, url, options) {
4308
- Parsley.asyncValidators[name] = {
4309
- fn: fn,
4310
- url: url || false,
4311
- options: options || {}
4312
- };
4313
-
4314
- return this;
4315
- }
4316
-
4317
- });
4318
-
4319
- Parsley.addValidator('remote', {
4320
- requirementType: {
4321
- '': 'string',
4322
- 'validator': 'string',
4323
- 'reverse': 'boolean',
4324
- 'options': 'object'
4325
- },
4326
-
4327
- validateString: function validateString(value, url, options, instance) {
4328
- var data = {};
4329
- var ajaxOptions;
4330
- var csr;
4331
- var validator = options.validator || (true === options.reverse ? 'reverse' : 'default');
4332
-
4333
- if ('undefined' === typeof Parsley.asyncValidators[validator]) throw new Error('Calling an undefined async validator: `' + validator + '`');
4334
-
4335
- url = Parsley.asyncValidators[validator].url || url;
4336
-
4337
- // Fill current value
4338
- if (url.indexOf('{value}') > -1) {
4339
- url = url.replace('{value}', encodeURIComponent(value));
4340
- } else {
4341
- data[instance.element.getAttribute('name') || instance.element.getAttribute('id')] = value;
4342
- }
4343
-
4344
- // Merge options passed in from the function with the ones in the attribute
4345
- var remoteOptions = $.extend(true, options.options || {}, Parsley.asyncValidators[validator].options);
4346
-
4347
- // All `$.ajax(options)` could be overridden or extended directly from DOM in `data-parsley-remote-options`
4348
- ajaxOptions = $.extend(true, {}, {
4349
- url: url,
4350
- data: data,
4351
- type: 'GET'
4352
- }, remoteOptions);
4353
-
4354
- // Generate store key based on ajax options
4355
- instance.trigger('field:ajaxoptions', instance, ajaxOptions);
4356
-
4357
- csr = $.param(ajaxOptions);
4358
-
4359
- // Initialise querry cache
4360
- if ('undefined' === typeof Parsley._remoteCache) Parsley._remoteCache = {};
4361
-
4362
- // Try to retrieve stored xhr
4363
- var xhr = Parsley._remoteCache[csr] = Parsley._remoteCache[csr] || $.ajax(ajaxOptions);
4364
-
4365
- var handleXhr = function handleXhr() {
4366
- var result = Parsley.asyncValidators[validator].fn.call(instance, xhr, url, options);
4367
- if (!result) // Map falsy results to rejected promise
4368
- result = $.Deferred().reject();
4369
- return $.when(result);
4370
- };
4371
-
4372
- return xhr.then(handleXhr, handleXhr);
4373
- },
4374
-
4375
- priority: -1
4376
- });
4377
-
4378
- Parsley.on('form:submit', function () {
4379
- Parsley._remoteCache = {};
4380
- });
4381
-
4382
- Base.prototype.addAsyncValidator = function () {
4383
- Utils.warnOnce('Accessing the method `addAsyncValidator` through an instance is deprecated. Simply call `Parsley.addAsyncValidator(...)`');
4384
- return Parsley.addAsyncValidator.apply(Parsley, arguments);
4385
- };
4386
-
4387
- // This is included with the Parsley library itself,
4388
- // thus there is no use in adding it to your project.
4389
- Parsley.addMessages('en', {
4390
- defaultMessage: "This value seems to be invalid.",
4391
- type: {
4392
- email: "This value should be a valid email.",
4393
- url: "This value should be a valid url.",
4394
- number: "This value should be a valid number.",
4395
- integer: "This value should be a valid integer.",
4396
- digits: "This value should be digits.",
4397
- alphanum: "This value should be alphanumeric."
4398
- },
4399
- notblank: "This value should not be blank.",
4400
- required: "This value is required.",
4401
- pattern: "This value seems to be invalid.",
4402
- min: "This value should be greater than or equal to %s.",
4403
- max: "This value should be lower than or equal to %s.",
4404
- range: "This value should be between %s and %s.",
4405
- minlength: "This value is too short. It should have %s characters or more.",
4406
- maxlength: "This value is too long. It should have %s characters or fewer.",
4407
- length: "This value length is invalid. It should be between %s and %s characters long.",
4408
- mincheck: "You must select at least %s choices.",
4409
- maxcheck: "You must select %s choices or fewer.",
4410
- check: "You must select between %s and %s choices.",
4411
- equalto: "This value should be the same."
4412
- });
4413
-
4414
- Parsley.setLocale('en');
4415
-
4416
- /**
4417
- * inputevent - Alleviate browser bugs for input events
4418
- * https://github.com/marcandre/inputevent
4419
- * @version v0.0.3 - (built Thu, Apr 14th 2016, 5:58 pm)
4420
- * @author Marc-Andre Lafortune <github@marc-andre.ca>
4421
- * @license MIT
4422
- */
4423
-
4424
- function InputEvent() {
4425
- var _this14 = this;
4426
-
4427
- var globals = window || global;
4428
-
4429
- // Slightly odd way construct our object. This way methods are force bound.
4430
- // Used to test for duplicate library.
4431
- _extends(this, {
4432
-
4433
- // For browsers that do not support isTrusted, assumes event is native.
4434
- isNativeEvent: function isNativeEvent(evt) {
4435
- return evt.originalEvent && evt.originalEvent.isTrusted !== false;
4436
- },
4437
-
4438
- fakeInputEvent: function fakeInputEvent(evt) {
4439
- if (_this14.isNativeEvent(evt)) {
4440
- $(evt.target).trigger('input');
4441
- }
4442
- },
4443
-
4444
- misbehaves: function misbehaves(evt) {
4445
- if (_this14.isNativeEvent(evt)) {
4446
- _this14.behavesOk(evt);
4447
- $(document).on('change.inputevent', evt.data.selector, _this14.fakeInputEvent);
4448
- _this14.fakeInputEvent(evt);
4449
- }
4450
- },
4451
-
4452
- behavesOk: function behavesOk(evt) {
4453
- if (_this14.isNativeEvent(evt)) {
4454
- $(document) // Simply unbinds the testing handler
4455
- .off('input.inputevent', evt.data.selector, _this14.behavesOk).off('change.inputevent', evt.data.selector, _this14.misbehaves);
4456
- }
4457
- },
4458
-
4459
- // Bind the testing handlers
4460
- install: function install() {
4461
- if (globals.inputEventPatched) {
4462
- return;
4463
- }
4464
- globals.inputEventPatched = '0.0.3';
4465
- var _arr = ['select', 'input[type="checkbox"]', 'input[type="radio"]', 'input[type="file"]'];
4466
- for (var _i = 0; _i < _arr.length; _i++) {
4467
- var selector = _arr[_i];
4468
- $(document).on('input.inputevent', selector, { selector: selector }, _this14.behavesOk).on('change.inputevent', selector, { selector: selector }, _this14.misbehaves);
4469
- }
4470
- },
4471
-
4472
- uninstall: function uninstall() {
4473
- delete globals.inputEventPatched;
4474
- $(document).off('.inputevent');
4475
- }
4476
-
4477
- });
4478
- };
4479
-
4480
- var inputevent = new InputEvent();
4481
-
4482
- inputevent.install();
4483
-
4484
- var parsley = Parsley;
4485
-
4486
- return parsley;
4487
- });
4488
- //# sourceMappingURL=parsley.js.map
4489
-
4490
- /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
4491
-
4492
- /***/ }
4493
- /******/ ]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/js/public.fecfa135.js ADDED
@@ -0,0 +1,1995 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /******/ (function(modules) { // webpackBootstrap
2
+ /******/ // The module cache
3
+ /******/ var installedModules = {};
4
+
5
+ /******/ // The require function
6
+ /******/ function __webpack_require__(moduleId) {
7
+
8
+ /******/ // Check if module is in cache
9
+ /******/ if(installedModules[moduleId])
10
+ /******/ return installedModules[moduleId].exports;
11
+
12
+ /******/ // Create a new module (and put it into the cache)
13
+ /******/ var module = installedModules[moduleId] = {
14
+ /******/ exports: {},
15
+ /******/ id: moduleId,
16
+ /******/ loaded: false
17
+ /******/ };
18
+
19
+ /******/ // Execute the module function
20
+ /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
21
+
22
+ /******/ // Flag the module as loaded
23
+ /******/ module.loaded = true;
24
+
25
+ /******/ // Return the exports of the module
26
+ /******/ return module.exports;
27
+ /******/ }
28
+
29
+
30
+ /******/ // expose the modules object (__webpack_modules__)
31
+ /******/ __webpack_require__.m = modules;
32
+
33
+ /******/ // expose the module cache
34
+ /******/ __webpack_require__.c = installedModules;
35
+
36
+ /******/ // __webpack_public_path__
37
+ /******/ __webpack_require__.p = "";
38
+
39
+ /******/ // Load entry module and return exports
40
+ /******/ return __webpack_require__(0);
41
+ /******/ })
42
+ /************************************************************************/
43
+ /******/ ([
44
+ /* 0 */
45
+ /***/ function(module, exports, __webpack_require__) {
46
+
47
+ __webpack_require__(1);
48
+ __webpack_require__(2);
49
+ __webpack_require__(3);
50
+ __webpack_require__(7);
51
+ __webpack_require__(8);
52
+ module.exports = __webpack_require__(9);
53
+
54
+
55
+ /***/ },
56
+ /* 1 */
57
+ /***/ function(module, exports, __webpack_require__) {
58
+
59
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function () {
60
+ // A placeholder for MailPoet object
61
+ var MailPoet = {};
62
+
63
+ // Expose MailPoet globally
64
+ window.MailPoet = MailPoet;
65
+
66
+ return MailPoet;
67
+ }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
68
+
69
+
70
+ /***/ },
71
+ /* 2 */
72
+ /***/ function(module, exports, __webpack_require__) {
73
+
74
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
75
+ __webpack_require__(1)
76
+ ], __WEBPACK_AMD_DEFINE_RESULT__ = function (
77
+ mp
78
+ ) {
79
+ 'use strict';
80
+
81
+ var MailPoet = mp;
82
+
83
+ var translations = {};
84
+
85
+ MailPoet.I18n = {
86
+ add: function (key, value) {
87
+ translations[key] = value;
88
+ },
89
+ t: function (key) {
90
+ return translations[key] || 'TRANSLATION "%$1s" NOT FOUND'.replace('%$1s', key);
91
+ },
92
+ all: function () {
93
+ return translations;
94
+ }
95
+ };
96
+
97
+ }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
98
+
99
+
100
+ /***/ },
101
+ /* 3 */
102
+ /***/ function(module, exports, __webpack_require__) {
103
+
104
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function requestFailed(errorMessage, xhr) {
105
+ if (xhr.responseJSON) {
106
+ return xhr.responseJSON;
107
+ }
108
+ return {
109
+ errors: [
110
+ {
111
+ message: errorMessage.replace('%d', xhr.status)
112
+ }
113
+ ]
114
+ };
115
+ }
116
+
117
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(1), __webpack_require__(4), __webpack_require__(5)], __WEBPACK_AMD_DEFINE_RESULT__ = function (mp, jQuery, _) {
118
+ var MailPoet = mp;
119
+
120
+ MailPoet.Ajax = {
121
+ version: 0.5,
122
+ options: {},
123
+ defaults: {
124
+ url: null,
125
+ api_version: null,
126
+ endpoint: null,
127
+ action: null,
128
+ token: null,
129
+ data: {}
130
+ },
131
+ post: function (options) {
132
+ return this.request('post', options);
133
+ },
134
+ init: function (options) {
135
+ // merge options
136
+ this.options = jQuery.extend({}, this.defaults, options);
137
+
138
+ // set default url
139
+ if (this.options.url === null) {
140
+ this.options.url = window.ajaxurl;
141
+ }
142
+
143
+ // set default token
144
+ if (this.options.token === null) {
145
+ this.options.token = window.mailpoet_token;
146
+ }
147
+ },
148
+ getParams: function () {
149
+ return {
150
+ action: 'mailpoet',
151
+ api_version: this.options.api_version,
152
+ token: this.options.token,
153
+ endpoint: this.options.endpoint,
154
+ method: this.options.action,
155
+ data: this.options.data || {}
156
+ };
157
+ },
158
+ request: function (method, options) {
159
+ var params;
160
+ var deferred;
161
+ // set options
162
+ this.init(options);
163
+
164
+ // set request params
165
+ params = this.getParams();
166
+
167
+ // remove null values from the data object
168
+ if (_.isObject(params.data)) {
169
+ params.data = _.pick(params.data, function (value) {
170
+ return (value !== null);
171
+ });
172
+ }
173
+
174
+ // ajax request
175
+ deferred = jQuery.post(
176
+ this.options.url,
177
+ params,
178
+ null,
179
+ 'json'
180
+ ).then(function (data) {
181
+ return data;
182
+ }, _.partial(requestFailed, MailPoet.I18n.t('ajaxFailedErrorMessage')));
183
+
184
+ // clear options
185
+ this.options = {};
186
+
187
+ return deferred;
188
+ }
189
+ };
190
+ }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
191
+
192
+
193
+ /***/ },
194
+ /* 4 */
195
+ /***/ function(module, exports) {
196
+
197
+ module.exports = jQuery;
198
+
199
+ /***/ },
200
+ /* 5 */
201
+ /***/ function(module, exports, __webpack_require__) {
202
+
203
+ /* WEBPACK VAR INJECTION */(function(global) {module.exports = global["_"] = __webpack_require__(6);
204
+ /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
205
+
206
+ /***/ },
207
+ /* 6 */
208
+ /***/ function(module, exports, __webpack_require__) {
209
+
210
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// Underscore.js 1.8.3
211
+ // http://underscorejs.org
212
+ // (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
213
+ // Underscore may be freely distributed under the MIT license.
214
+
215
+ (function() {
216
+
217
+ // Baseline setup
218
+ // --------------
219
+
220
+ // Establish the root object, `window` in the browser, or `exports` on the server.
221
+ var root = this;
222
+
223
+ // Save the previous value of the `_` variable.
224
+ var previousUnderscore = root._;
225
+
226
+ // Save bytes in the minified (but not gzipped) version:
227
+ var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
228
+
229
+ // Create quick reference variables for speed access to core prototypes.
230
+ var
231
+ push = ArrayProto.push,
232
+ slice = ArrayProto.slice,
233
+ toString = ObjProto.toString,
234
+ hasOwnProperty = ObjProto.hasOwnProperty;
235
+
236
+ // All **ECMAScript 5** native function implementations that we hope to use
237
+ // are declared here.
238
+ var
239
+ nativeIsArray = Array.isArray,
240
+ nativeKeys = Object.keys,
241
+ nativeBind = FuncProto.bind,
242
+ nativeCreate = Object.create;
243
+
244
+ // Naked function reference for surrogate-prototype-swapping.
245
+ var Ctor = function(){};
246
+
247
+ // Create a safe reference to the Underscore object for use below.
248
+ var _ = function(obj) {
249
+ if (obj instanceof _) return obj;
250
+ if (!(this instanceof _)) return new _(obj);
251
+ this._wrapped = obj;
252
+ };
253
+
254
+ // Export the Underscore object for **Node.js**, with
255
+ // backwards-compatibility for the old `require()` API. If we're in
256
+ // the browser, add `_` as a global object.
257
+ if (true) {
258
+ if (typeof module !== 'undefined' && module.exports) {
259
+ exports = module.exports = _;
260
+ }
261
+ exports._ = _;
262
+ } else {
263
+ root._ = _;
264
+ }
265
+
266
+ // Current version.
267
+ _.VERSION = '1.8.3';
268
+
269
+ // Internal function that returns an efficient (for current engines) version
270
+ // of the passed-in callback, to be repeatedly applied in other Underscore
271
+ // functions.
272
+ var optimizeCb = function(func, context, argCount) {
273
+ if (context === void 0) return func;
274
+ switch (argCount == null ? 3 : argCount) {
275
+ case 1: return function(value) {
276
+ return func.call(context, value);
277
+ };
278
+ case 2: return function(value, other) {
279
+ return func.call(context, value, other);
280
+ };
281
+ case 3: return function(value, index, collection) {
282
+ return func.call(context, value, index, collection);
283
+ };
284
+ case 4: return function(accumulator, value, index, collection) {
285
+ return func.call(context, accumulator, value, index, collection);
286
+ };
287
+ }
288
+ return function() {
289
+ return func.apply(context, arguments);
290
+ };
291
+ };
292
+
293
+ // A mostly-internal function to generate callbacks that can be applied
294
+ // to each element in a collection, returning the desired result — either
295
+ // identity, an arbitrary callback, a property matcher, or a property accessor.
296
+ var cb = function(value, context, argCount) {
297
+ if (value == null) return _.identity;
298
+ if (_.isFunction(value)) return optimizeCb(value, context, argCount);
299
+ if (_.isObject(value)) return _.matcher(value);
300
+ return _.property(value);
301
+ };
302
+ _.iteratee = function(value, context) {
303
+ return cb(value, context, Infinity);
304
+ };
305
+
306
+ // An internal function for creating assigner functions.
307
+ var createAssigner = function(keysFunc, undefinedOnly) {
308
+ return function(obj) {
309
+ var length = arguments.length;
310
+ if (length < 2 || obj == null) return obj;
311
+ for (var index = 1; index < length; index++) {
312
+ var source = arguments[index],
313
+ keys = keysFunc(source),
314
+ l = keys.length;
315
+ for (var i = 0; i < l; i++) {
316
+ var key = keys[i];
317
+ if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key];
318
+ }
319
+ }
320
+ return obj;
321
+ };
322
+ };
323
+
324
+ // An internal function for creating a new object that inherits from another.
325
+ var baseCreate = function(prototype) {
326
+ if (!_.isObject(prototype)) return {};
327
+ if (nativeCreate) return nativeCreate(prototype);
328
+ Ctor.prototype = prototype;
329
+ var result = new Ctor;
330
+ Ctor.prototype = null;
331
+ return result;
332
+ };
333
+
334
+ var property = function(key) {
335
+ return function(obj) {
336
+ return obj == null ? void 0 : obj[key];
337
+ };
338
+ };
339
+
340
+ // Helper for collection methods to determine whether a collection
341
+ // should be iterated as an array or as an object
342
+ // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
343
+ // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
344
+ var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
345
+ var getLength = property('length');
346
+ var isArrayLike = function(collection) {
347
+ var length = getLength(collection);
348
+ return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
349
+ };
350
+
351
+ // Collection Functions
352
+ // --------------------
353
+
354
+ // The cornerstone, an `each` implementation, aka `forEach`.
355
+ // Handles raw objects in addition to array-likes. Treats all
356
+ // sparse array-likes as if they were dense.
357
+ _.each = _.forEach = function(obj, iteratee, context) {
358
+ iteratee = optimizeCb(iteratee, context);
359
+ var i, length;
360
+ if (isArrayLike(obj)) {
361
+ for (i = 0, length = obj.length; i < length; i++) {
362
+ iteratee(obj[i], i, obj);
363
+ }
364
+ } else {
365
+ var keys = _.keys(obj);
366
+ for (i = 0, length = keys.length; i < length; i++) {
367
+ iteratee(obj[keys[i]], keys[i], obj);
368
+ }
369
+ }
370
+ return obj;
371
+ };
372
+
373
+ // Return the results of applying the iteratee to each element.
374
+ _.map = _.collect = function(obj, iteratee, context) {
375
+ iteratee = cb(iteratee, context);
376
+ var keys = !isArrayLike(obj) && _.keys(obj),
377
+ length = (keys || obj).length,
378
+ results = Array(length);
379
+ for (var index = 0; index < length; index++) {
380
+ var currentKey = keys ? keys[index] : index;
381
+ results[index] = iteratee(obj[currentKey], currentKey, obj);
382
+ }
383
+ return results;
384
+ };
385
+
386
+ // Create a reducing function iterating left or right.
387
+ function createReduce(dir) {
388
+ // Optimized iterator function as using arguments.length
389
+ // in the main function will deoptimize the, see #1991.
390
+ function iterator(obj, iteratee, memo, keys, index, length) {
391
+ for (; index >= 0 && index < length; index += dir) {
392
+ var currentKey = keys ? keys[index] : index;
393
+ memo = iteratee(memo, obj[currentKey], currentKey, obj);
394
+ }
395
+ return memo;
396
+ }
397
+
398
+ return function(obj, iteratee, memo, context) {
399
+ iteratee = optimizeCb(iteratee, context, 4);
400
+ var keys = !isArrayLike(obj) && _.keys(obj),
401
+ length = (keys || obj).length,
402
+ index = dir > 0 ? 0 : length - 1;
403
+ // Determine the initial value if none is provided.
404
+ if (arguments.length < 3) {
405
+ memo = obj[keys ? keys[index] : index];
406
+ index += dir;
407
+ }
408
+ return iterator(obj, iteratee, memo, keys, index, length);
409
+ };
410
+ }
411
+
412
+ // **Reduce** builds up a single result from a list of values, aka `inject`,
413
+ // or `foldl`.
414
+ _.reduce = _.foldl = _.inject = createReduce(1);
415
+
416
+ // The right-associative version of reduce, also known as `foldr`.
417
+ _.reduceRight = _.foldr = createReduce(-1);
418
+
419
+ // Return the first value which passes a truth test. Aliased as `detect`.
420
+ _.find = _.detect = function(obj, predicate, context) {
421
+ var key;
422
+ if (isArrayLike(obj)) {
423
+ key = _.findIndex(obj, predicate, context);
424
+ } else {
425
+ key = _.findKey(obj, predicate, context);
426
+ }
427
+ if (key !== void 0 && key !== -1) return obj[key];
428
+ };
429
+
430
+ // Return all the elements that pass a truth test.
431
+ // Aliased as `select`.
432
+ _.filter = _.select = function(obj, predicate, context) {
433
+ var results = [];
434
+ predicate = cb(predicate, context);
435
+ _.each(obj, function(value, index, list) {
436
+ if (predicate(value, index, list)) results.push(value);
437
+ });
438
+ return results;
439
+ };
440
+
441
+ // Return all the elements for which a truth test fails.
442
+ _.reject = function(obj, predicate, context) {
443
+ return _.filter(obj, _.negate(cb(predicate)), context);
444
+ };
445
+
446
+ // Determine whether all of the elements match a truth test.
447
+ // Aliased as `all`.
448
+ _.every = _.all = function(obj, predicate, context) {
449
+ predicate = cb(predicate, context);
450
+ var keys = !isArrayLike(obj) && _.keys(obj),
451
+ length = (keys || obj).length;
452
+ for (var index = 0; index < length; index++) {
453
+ var currentKey = keys ? keys[index] : index;
454
+ if (!predicate(obj[currentKey], currentKey, obj)) return false;
455
+ }
456
+ return true;
457
+ };
458
+
459
+ // Determine if at least one element in the object matches a truth test.
460
+ // Aliased as `any`.
461
+ _.some = _.any = function(obj, predicate, context) {
462
+ predicate = cb(predicate, context);
463
+ var keys = !isArrayLike(obj) && _.keys(obj),
464
+ length = (keys || obj).length;
465
+ for (var index = 0; index < length; index++) {
466
+ var currentKey = keys ? keys[index] : index;
467
+ if (predicate(obj[currentKey], currentKey, obj)) return true;
468
+ }
469
+ return false;
470
+ };
471
+
472
+ // Determine if the array or object contains a given item (using `===`).
473
+ // Aliased as `includes` and `include`.
474
+ _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) {
475
+ if (!isArrayLike(obj)) obj = _.values(obj);
476
+ if (typeof fromIndex != 'number' || guard) fromIndex = 0;
477
+ return _.indexOf(obj, item, fromIndex) >= 0;
478
+ };
479
+
480
+ // Invoke a method (with arguments) on every item in a collection.
481
+ _.invoke = function(obj, method) {
482
+ var args = slice.call(arguments, 2);
483
+ var isFunc = _.isFunction(method);
484
+ return _.map(obj, function(value) {
485
+ var func = isFunc ? method : value[method];
486
+ return func == null ? func : func.apply(value, args);
487
+ });
488
+ };
489
+
490
+ // Convenience version of a common use case of `map`: fetching a property.
491
+ _.pluck = function(obj, key) {
492
+ return _.map(obj, _.property(key));
493
+ };
494
+
495
+ // Convenience version of a common use case of `filter`: selecting only objects
496
+ // containing specific `key:value` pairs.
497
+ _.where = function(obj, attrs) {
498
+ return _.filter(obj, _.matcher(attrs));
499
+ };
500
+
501
+ // Convenience version of a common use case of `find`: getting the first object
502
+ // containing specific `key:value` pairs.
503
+ _.findWhere = function(obj, attrs) {
504
+ return _.find(obj, _.matcher(attrs));
505
+ };
506
+
507
+ // Return the maximum element (or element-based computation).
508
+ _.max = function(obj, iteratee, context) {
509
+ var result = -Infinity, lastComputed = -Infinity,
510
+ value, computed;
511
+ if (iteratee == null && obj != null) {
512
+ obj = isArrayLike(obj) ? obj : _.values(obj);
513
+ for (var i = 0, length = obj.length; i < length; i++) {
514
+ value = obj[i];
515
+ if (value > result) {
516
+ result = value;
517
+ }
518
+ }
519
+ } else {
520
+ iteratee = cb(iteratee, context);
521
+ _.each(obj, function(value, index, list) {
522
+ computed = iteratee(value, index, list);
523
+ if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
524
+ result = value;
525
+ lastComputed = computed;
526
+ }
527
+ });
528
+ }
529
+ return result;
530
+ };
531
+
532
+ // Return the minimum element (or element-based computation).
533
+ _.min = function(obj, iteratee, context) {
534
+ var result = Infinity, lastComputed = Infinity,
535
+ value, computed;
536
+ if (iteratee == null && obj != null) {
537
+ obj = isArrayLike(obj) ? obj : _.values(obj);
538
+ for (var i = 0, length = obj.length; i < length; i++) {
539
+ value = obj[i];
540
+ if (value < result) {
541
+ result = value;
542
+ }
543
+ }
544
+ } else {
545
+ iteratee = cb(iteratee, context);
546
+ _.each(obj, function(value, index, list) {
547
+ computed = iteratee(value, index, list);
548
+ if (computed < lastComputed || computed === Infinity && result === Infinity) {
549
+ result = value;
550
+ lastComputed = computed;
551
+ }
552
+ });
553
+ }
554
+ return result;
555
+ };
556
+
557
+ // Shuffle a collection, using the modern version of the
558
+ // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
559
+ _.shuffle = function(obj) {
560
+ var set = isArrayLike(obj) ? obj : _.values(obj);
561
+ var length = set.length;
562
+ var shuffled = Array(length);
563
+ for (var index = 0, rand; index < length; index++) {
564
+ rand = _.random(0, index);
565
+ if (rand !== index) shuffled[index] = shuffled[rand];
566
+ shuffled[rand] = set[index];
567
+ }
568
+ return shuffled;
569
+ };
570
+
571
+ // Sample **n** random values from a collection.
572
+ // If **n** is not specified, returns a single random element.
573
+ // The internal `guard` argument allows it to work with `map`.
574
+ _.sample = function(obj, n, guard) {
575
+ if (n == null || guard) {
576
+ if (!isArrayLike(obj)) obj = _.values(obj);
577
+ return obj[_.random(obj.length - 1)];
578
+ }
579
+ return _.shuffle(obj).slice(0, Math.max(0, n));
580
+ };
581
+
582
+ // Sort the object's values by a criterion produced by an iteratee.
583
+ _.sortBy = function(obj, iteratee, context) {
584
+ iteratee = cb(iteratee, context);
585
+ return _.pluck(_.map(obj, function(value, index, list) {
586
+ return {
587
+ value: value,
588
+ index: index,
589
+ criteria: iteratee(value, index, list)
590
+ };
591
+ }).sort(function(left, right) {
592
+ var a = left.criteria;
593
+ var b = right.criteria;
594
+ if (a !== b) {
595
+ if (a > b || a === void 0) return 1;
596
+ if (a < b || b === void 0) return -1;
597
+ }
598
+ return left.index - right.index;
599
+ }), 'value');
600
+ };
601
+
602
+ // An internal function used for aggregate "group by" operations.
603
+ var group = function(behavior) {
604
+ return function(obj, iteratee, context) {
605
+ var result = {};
606
+ iteratee = cb(iteratee, context);
607
+ _.each(obj, function(value, index) {
608
+ var key = iteratee(value, index, obj);
609
+ behavior(result, value, key);
610
+ });
611
+ return result;
612
+ };
613
+ };
614
+
615
+ // Groups the object's values by a criterion. Pass either a string attribute
616
+ // to group by, or a function that returns the criterion.
617
+ _.groupBy = group(function(result, value, key) {
618
+ if (_.has(result, key)) result[key].push(value); else result[key] = [value];
619
+ });
620
+
621
+ // Indexes the object's values by a criterion, similar to `groupBy`, but for
622
+ // when you know that your index values will be unique.
623
+ _.indexBy = group(function(result, value, key) {
624
+ result[key] = value;
625
+ });
626
+
627
+ // Counts instances of an object that group by a certain criterion. Pass
628
+ // either a string attribute to count by, or a function that returns the
629
+ // criterion.
630
+ _.countBy = group(function(result, value, key) {
631
+ if (_.has(result, key)) result[key]++; else result[key] = 1;
632
+ });
633
+
634
+ // Safely create a real, live array from anything iterable.
635
+ _.toArray = function(obj) {
636
+ if (!obj) return [];
637
+ if (_.isArray(obj)) return slice.call(obj);
638
+ if (isArrayLike(obj)) return _.map(obj, _.identity);
639
+ return _.values(obj);
640
+ };
641
+
642
+ // Return the number of elements in an object.
643
+ _.size = function(obj) {
644
+ if (obj == null) return 0;
645
+ return isArrayLike(obj) ? obj.length : _.keys(obj).length;
646
+ };
647
+
648
+ // Split a collection into two arrays: one whose elements all satisfy the given
649
+ // predicate, and one whose elements all do not satisfy the predicate.
650
+ _.partition = function(obj, predicate, context) {
651
+ predicate = cb(predicate, context);
652
+ var pass = [], fail = [];
653
+ _.each(obj, function(value, key, obj) {
654
+ (predicate(value, key, obj) ? pass : fail).push(value);
655
+ });
656
+ return [pass, fail];
657
+ };
658
+
659
+ // Array Functions
660
+ // ---------------
661
+
662
+ // Get the first element of an array. Passing **n** will return the first N
663
+ // values in the array. Aliased as `head` and `take`. The **guard** check
664
+ // allows it to work with `_.map`.
665
+ _.first = _.head = _.take = function(array, n, guard) {
666
+ if (array == null) return void 0;
667
+ if (n == null || guard) return array[0];
668
+ return _.initial(array, array.length - n);
669
+ };
670
+
671
+ // Returns everything but the last entry of the array. Especially useful on
672
+ // the arguments object. Passing **n** will return all the values in
673
+ // the array, excluding the last N.
674
+ _.initial = function(array, n, guard) {
675
+ return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
676
+ };
677
+
678
+ // Get the last element of an array. Passing **n** will return the last N
679
+ // values in the array.
680
+ _.last = function(array, n, guard) {
681
+ if (array == null) return void 0;
682
+ if (n == null || guard) return array[array.length - 1];
683
+ return _.rest(array, Math.max(0, array.length - n));
684
+ };
685
+
686
+ // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
687
+ // Especially useful on the arguments object. Passing an **n** will return
688
+ // the rest N values in the array.
689
+ _.rest = _.tail = _.drop = function(array, n, guard) {
690
+ return slice.call(array, n == null || guard ? 1 : n);
691
+ };
692
+
693
+ // Trim out all falsy values from an array.
694
+ _.compact = function(array) {
695
+ return _.filter(array, _.identity);
696
+ };
697
+
698
+ // Internal implementation of a recursive `flatten` function.
699
+ var flatten = function(input, shallow, strict, startIndex) {
700
+ var output = [], idx = 0;
701
+ for (var i = startIndex || 0, length = getLength(input); i < length; i++) {
702
+ var value = input[i];
703
+ if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
704
+ //flatten current level of array or arguments object
705
+ if (!shallow) value = flatten(value, shallow, strict);
706
+ var j = 0, len = value.length;
707
+ output.length += len;
708
+ while (j < len) {
709
+ output[idx++] = value[j++];
710
+ }
711
+ } else if (!strict) {
712
+ output[idx++] = value;
713
+ }
714
+ }
715
+ return output;
716
+ };
717
+
718
+ // Flatten out an array, either recursively (by default), or just one level.
719
+ _.flatten = function(array, shallow) {
720
+ return flatten(array, shallow, false);
721
+ };
722
+
723
+ // Return a version of the array that does not contain the specified value(s).
724
+ _.without = function(array) {
725
+ return _.difference(array, slice.call(arguments, 1));
726
+ };
727
+
728
+ // Produce a duplicate-free version of the array. If the array has already
729
+ // been sorted, you have the option of using a faster algorithm.
730
+ // Aliased as `unique`.
731
+ _.uniq = _.unique = function(array, isSorted, iteratee, context) {
732
+ if (!_.isBoolean(isSorted)) {
733
+ context = iteratee;
734
+ iteratee = isSorted;
735
+ isSorted = false;
736
+ }
737
+ if (iteratee != null) iteratee = cb(iteratee, context);
738
+ var result = [];
739
+ var seen = [];
740
+ for (var i = 0, length = getLength(array); i < length; i++) {
741
+ var value = array[i],
742
+ computed = iteratee ? iteratee(value, i, array) : value;
743
+ if (isSorted) {
744
+ if (!i || seen !== computed) result.push(value);
745
+ seen = computed;
746
+ } else if (iteratee) {
747
+ if (!_.contains(seen, computed)) {
748
+ seen.push(computed);
749
+ result.push(value);
750
+ }
751
+ } else if (!_.contains(result, value)) {
752
+ result.push(value);
753
+ }
754
+ }
755
+ return result;
756
+ };
757
+
758
+ // Produce an array that contains the union: each distinct element from all of
759
+ // the passed-in arrays.
760
+ _.union = function() {
761
+ return _.uniq(flatten(arguments, true, true));
762
+ };
763
+
764
+ // Produce an array that contains every item shared between all the
765
+ // passed-in arrays.
766
+ _.intersection = function(array) {
767
+ var result = [];
768
+ var argsLength = arguments.length;
769
+ for (var i = 0, length = getLength(array); i < length; i++) {
770
+ var item = array[i];
771
+ if (_.contains(result, item)) continue;
772
+ for (var j = 1; j < argsLength; j++) {
773
+ if (!_.contains(arguments[j], item)) break;
774
+ }
775
+ if (j === argsLength) result.push(item);
776
+ }
777
+ return result;
778
+ };
779
+
780
+ // Take the difference between one array and a number of other arrays.
781
+ // Only the elements present in just the first array will remain.
782
+ _.difference = function(array) {
783
+ var rest = flatten(arguments, true, true, 1);
784
+ return _.filter(array, function(value){
785
+ return !_.contains(rest, value);
786
+ });
787
+ };
788
+
789
+ // Zip together multiple lists into a single array -- elements that share
790
+ // an index go together.
791
+ _.zip = function() {
792
+ return _.unzip(arguments);
793
+ };
794
+
795
+ // Complement of _.zip. Unzip accepts an array of arrays and groups
796
+ // each array's elements on shared indices
797
+ _.unzip = function(array) {
798
+ var length = array && _.max(array, getLength).length || 0;
799
+ var result = Array(length);
800
+
801
+ for (var index = 0; index < length; index++) {
802
+ result[index] = _.pluck(array, index);
803
+ }
804
+ return result;
805
+ };
806
+
807
+ // Converts lists into objects. Pass either a single array of `[key, value]`
808
+ // pairs, or two parallel arrays of the same length -- one of keys, and one of
809
+ // the corresponding values.
810
+ _.object = function(list, values) {
811
+ var result = {};
812
+ for (var i = 0, length = getLength(list); i < length; i++) {
813
+ if (values) {
814
+ result[list[i]] = values[i];
815
+ } else {
816
+ result[list[i][0]] = list[i][1];
817
+ }
818
+ }
819
+ return result;
820
+ };
821
+
822
+ // Generator function to create the findIndex and findLastIndex functions
823
+ function createPredicateIndexFinder(dir) {
824
+ return function(array, predicate, context) {
825
+ predicate = cb(predicate, context);
826
+ var length = getLength(array);
827
+ var index = dir > 0 ? 0 : length - 1;
828
+ for (; index >= 0 && index < length; index += dir) {
829
+ if (predicate(array[index], index, array)) return index;
830
+ }
831
+ return -1;
832
+ };
833
+ }
834
+
835
+ // Returns the first index on an array-like that passes a predicate test
836
+ _.findIndex = createPredicateIndexFinder(1);
837
+ _.findLastIndex = createPredicateIndexFinder(-1);
838
+
839
+ // Use a comparator function to figure out the smallest index at which
840
+ // an object should be inserted so as to maintain order. Uses binary search.
841
+ _.sortedIndex = function(array, obj, iteratee, context) {
842
+ iteratee = cb(iteratee, context, 1);
843
+ var value = iteratee(obj);
844
+ var low = 0, high = getLength(array);
845
+ while (low < high) {
846
+ var mid = Math.floor((low + high) / 2);
847
+ if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
848
+ }
849
+ return low;
850
+ };
851
+
852
+ // Generator function to create the indexOf and lastIndexOf functions
853
+ function createIndexFinder(dir, predicateFind, sortedIndex) {
854
+ return function(array, item, idx) {
855
+ var i = 0, length = getLength(array);
856
+ if (typeof idx == 'number') {
857
+ if (dir > 0) {
858
+ i = idx >= 0 ? idx : Math.max(idx + length, i);
859
+ } else {
860
+ length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
861
+ }
862
+ } else if (sortedIndex && idx && length) {
863
+ idx = sortedIndex(array, item);
864
+ return array[idx] === item ? idx : -1;
865
+ }
866
+ if (item !== item) {
867
+ idx = predicateFind(slice.call(array, i, length), _.isNaN);
868
+ return idx >= 0 ? idx + i : -1;
869
+ }
870
+ for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
871
+ if (array[idx] === item) return idx;
872
+ }
873
+ return -1;
874
+ };
875
+ }
876
+
877
+ // Return the position of the first occurrence of an item in an array,
878
+ // or -1 if the item is not included in the array.
879
+ // If the array is large and already in sort order, pass `true`
880
+ // for **isSorted** to use binary search.
881
+ _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);
882
+ _.lastIndexOf = createIndexFinder(-1, _.findLastIndex);
883
+
884
+ // Generate an integer Array containing an arithmetic progression. A port of
885
+ // the native Python `range()` function. See
886
+ // [the Python documentation](http://docs.python.org/library/functions.html#range).
887
+ _.range = function(start, stop, step) {
888
+ if (stop == null) {
889
+ stop = start || 0;
890
+ start = 0;
891
+ }
892
+ step = step || 1;
893
+
894
+ var length = Math.max(Math.ceil((stop - start) / step), 0);
895
+ var range = Array(length);
896
+
897
+ for (var idx = 0; idx < length; idx++, start += step) {
898
+ range[idx] = start;
899
+ }
900
+
901
+ return range;
902
+ };
903
+
904
+ // Function (ahem) Functions
905
+ // ------------------
906
+
907
+ // Determines whether to execute a function as a constructor
908
+ // or a normal function with the provided arguments
909
+ var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
910
+ if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
911
+ var self = baseCreate(sourceFunc.prototype);
912
+ var result = sourceFunc.apply(self, args);
913
+ if (_.isObject(result)) return result;
914
+ return self;
915
+ };
916
+
917
+ // Create a function bound to a given object (assigning `this`, and arguments,
918
+ // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
919
+ // available.
920
+ _.bind = function(func, context) {
921
+ if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
922
+ if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
923
+ var args = slice.call(arguments, 2);
924
+ var bound = function() {
925
+ return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));
926
+ };
927
+ return bound;
928
+ };
929
+
930
+ // Partially apply a function by creating a version that has had some of its
931
+ // arguments pre-filled, without changing its dynamic `this` context. _ acts
932
+ // as a placeholder, allowing any combination of arguments to be pre-filled.
933
+ _.partial = function(func) {
934
+ var boundArgs = slice.call(arguments, 1);
935
+ var bound = function() {
936
+ var position = 0, length = boundArgs.length;
937
+ var args = Array(length);
938
+ for (var i = 0; i < length; i++) {
939
+ args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i];
940
+ }
941
+ while (position < arguments.length) args.push(arguments[position++]);
942
+ return executeBound(func, bound, this, this, args);
943
+ };
944
+ return bound;
945
+ };
946
+
947
+ // Bind a number of an object's methods to that object. Remaining arguments
948
+ // are the method names to be bound. Useful for ensuring that all callbacks
949
+ // defined on an object belong to it.
950
+ _.bindAll = function(obj) {
951
+ var i, length = arguments.length, key;
952
+ if (length <= 1) throw new Error('bindAll must be passed function names');
953
+ for (i = 1; i < length; i++) {
954
+ key = arguments[i];
955
+ obj[key] = _.bind(obj[key], obj);
956
+ }
957
+ return obj;
958
+ };
959
+
960
+ // Memoize an expensive function by storing its results.
961
+ _.memoize = function(func, hasher) {
962
+ var memoize = function(key) {
963
+ var cache = memoize.cache;
964
+ var address = '' + (hasher ? hasher.apply(this, arguments) : key);
965
+ if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
966
+ return cache[address];
967
+ };
968
+ memoize.cache = {};
969
+ return memoize;
970
+ };
971
+
972
+ // Delays a function for the given number of milliseconds, and then calls
973
+ // it with the arguments supplied.
974
+ _.delay = function(func, wait) {
975
+ var args = slice.call(arguments, 2);
976
+ return setTimeout(function(){
977
+ return func.apply(null, args);
978
+ }, wait);
979
+ };
980
+
981
+ // Defers a function, scheduling it to run after the current call stack has
982
+ // cleared.
983
+ _.defer = _.partial(_.delay, _, 1);
984
+
985
+ // Returns a function, that, when invoked, will only be triggered at most once
986
+ // during a given window of time. Normally, the throttled function will run
987
+ // as much as it can, without ever going more than once per `wait` duration;
988
+ // but if you'd like to disable the execution on the leading edge, pass
989
+ // `{leading: false}`. To disable execution on the trailing edge, ditto.
990
+ _.throttle = function(func, wait, options) {
991
+ var context, args, result;
992
+ var timeout = null;
993
+ var previous = 0;
994
+ if (!options) options = {};
995
+ var later = function() {
996
+ previous = options.leading === false ? 0 : _.now();
997
+ timeout = null;
998
+ result = func.apply(context, args);
999
+ if (!timeout) context = args = null;
1000
+ };
1001
+ return function() {
1002
+ var now = _.now();
1003
+ if (!previous && options.leading === false) previous = now;
1004
+ var remaining = wait - (now - previous);
1005
+ context = this;
1006
+ args = arguments;
1007
+ if (remaining <= 0 || remaining > wait) {
1008
+ if (timeout) {
1009
+ clearTimeout(timeout);
1010
+ timeout = null;
1011
+ }
1012
+ previous = now;
1013
+ result = func.apply(context, args);
1014
+ if (!timeout) context = args = null;
1015
+ } else if (!timeout && options.trailing !== false) {
1016
+ timeout = setTimeout(later, remaining);
1017
+ }
1018
+ return result;
1019
+ };
1020
+ };
1021
+
1022
+ // Returns a function, that, as long as it continues to be invoked, will not
1023
+ // be triggered. The function will be called after it stops being called for
1024
+ // N milliseconds. If `immediate` is passed, trigger the function on the
1025
+ // leading edge, instead of the trailing.
1026
+ _.debounce = function(func, wait, immediate) {
1027
+ var timeout, args, context, timestamp, result;
1028
+
1029
+ var later = function() {
1030
+ var last = _.now() - timestamp;
1031
+
1032
+ if (last < wait && last >= 0) {
1033
+ timeout = setTimeout(later, wait - last);
1034
+ } else {
1035
+ timeout = null;
1036
+ if (!immediate) {
1037
+ result = func.apply(context, args);
1038
+ if (!timeout) context = args = null;
1039
+ }
1040
+ }
1041
+ };
1042
+
1043
+ return function() {
1044
+ context = this;
1045
+ args = arguments;
1046
+ timestamp = _.now();
1047
+ var callNow = immediate && !timeout;
1048
+ if (!timeout) timeout = setTimeout(later, wait);
1049
+ if (callNow) {
1050
+ result = func.apply(context, args);
1051
+ context = args = null;
1052
+ }
1053
+
1054
+ return result;
1055
+ };
1056
+ };
1057
+
1058
+ // Returns the first function passed as an argument to the second,
1059
+ // allowing you to adjust arguments, run code before and after, and
1060
+ // conditionally execute the original function.
1061
+ _.wrap = function(func, wrapper) {
1062
+ return _.partial(wrapper, func);
1063
+ };
1064
+
1065
+ // Returns a negated version of the passed-in predicate.
1066
+ _.negate = function(predicate) {
1067
+ return function() {
1068
+ return !predicate.apply(this, arguments);
1069
+ };
1070
+ };
1071
+
1072
+ // Returns a function that is the composition of a list of functions, each
1073
+ // consuming the return value of the function that follows.
1074
+ _.compose = function() {
1075
+ var args = arguments;
1076
+ var start = args.length - 1;
1077
+ return function() {
1078
+ var i = start;
1079
+ var result = args[start].apply(this, arguments);
1080
+ while (i--) result = args[i].call(this, result);
1081
+ return result;
1082
+ };
1083
+ };
1084
+
1085
+ // Returns a function that will only be executed on and after the Nth call.
1086
+ _.after = function(times, func) {
1087
+ return function() {
1088
+ if (--times < 1) {
1089
+ return func.apply(this, arguments);
1090
+ }
1091
+ };
1092
+ };
1093
+
1094
+ // Returns a function that will only be executed up to (but not including) the Nth call.
1095
+ _.before = function(times, func) {
1096
+ var memo;
1097
+ return function() {
1098
+ if (--times > 0) {
1099
+ memo = func.apply(this, arguments);
1100
+ }
1101
+ if (times <= 1) func = null;
1102
+ return memo;
1103
+ };
1104
+ };
1105
+
1106
+ // Returns a function that will be executed at most one time, no matter how
1107
+ // often you call it. Useful for lazy initialization.
1108
+ _.once = _.partial(_.before, 2);
1109
+
1110
+ // Object Functions
1111
+ // ----------------
1112
+
1113
+ // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
1114
+ var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
1115
+ var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
1116
+ 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
1117
+
1118
+ function collectNonEnumProps(obj, keys) {
1119
+ var nonEnumIdx = nonEnumerableProps.length;
1120
+ var constructor = obj.constructor;
1121
+ var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;
1122
+
1123
+ // Constructor is a special case.
1124
+ var prop = 'constructor';
1125
+ if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
1126
+
1127
+ while (nonEnumIdx--) {
1128
+ prop = nonEnumerableProps[nonEnumIdx];
1129
+ if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
1130
+ keys.push(prop);
1131
+ }
1132
+ }
1133
+ }
1134
+
1135
+ // Retrieve the names of an object's own properties.
1136
+ // Delegates to **ECMAScript 5**'s native `Object.keys`
1137
+ _.keys = function(obj) {
1138
+ if (!_.isObject(obj)) return [];
1139
+ if (nativeKeys) return nativeKeys(obj);
1140
+ var keys = [];
1141
+ for (var key in obj) if (_.has(obj, key)) keys.push(key);
1142
+ // Ahem, IE < 9.
1143
+ if (hasEnumBug) collectNonEnumProps(obj, keys);
1144
+ return keys;
1145
+ };
1146
+
1147
+ // Retrieve all the property names of an object.
1148
+ _.allKeys = function(obj) {
1149
+ if (!_.isObject(obj)) return [];
1150
+ var keys = [];
1151
+ for (var key in obj) keys.push(key);
1152
+ // Ahem, IE < 9.
1153
+ if (hasEnumBug) collectNonEnumProps(obj, keys);
1154
+ return keys;
1155
+ };
1156
+
1157
+ // Retrieve the values of an object's properties.
1158
+ _.values = function(obj) {
1159
+ var keys = _.keys(obj);
1160
+ var length = keys.length;
1161
+ var values = Array(length);
1162
+ for (var i = 0; i < length; i++) {
1163
+ values[i] = obj[keys[i]];
1164
+ }
1165
+ return values;
1166
+ };
1167
+
1168
+ // Returns the results of applying the iteratee to each element of the object
1169
+ // In contrast to _.map it returns an object
1170
+ _.mapObject = function(obj, iteratee, context) {
1171
+ iteratee = cb(iteratee, context);
1172
+ var keys = _.keys(obj),
1173
+ length = keys.length,
1174
+ results = {},
1175
+ currentKey;
1176
+ for (var index = 0; index < length; index++) {
1177
+ currentKey = keys[index];
1178
+ results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
1179
+ }
1180
+ return results;
1181
+ };
1182
+
1183
+ // Convert an object into a list of `[key, value]` pairs.
1184
+ _.pairs = function(obj) {
1185
+ var keys = _.keys(obj);
1186
+ var length = keys.length;
1187
+ var pairs = Array(length);
1188
+ for (var i = 0; i < length; i++) {
1189
+ pairs[i] = [keys[i], obj[keys[i]]];
1190
+ }
1191
+ return pairs;
1192
+ };
1193
+
1194
+ // Invert the keys and values of an object. The values must be serializable.
1195
+ _.invert = function(obj) {
1196
+ var result = {};
1197
+ var keys = _.keys(obj);
1198
+ for (var i = 0, length = keys.length; i < length; i++) {
1199
+ result[obj[keys[i]]] = keys[i];
1200
+ }
1201
+ return result;
1202
+ };
1203
+
1204
+ // Return a sorted list of the function names available on the object.
1205
+ // Aliased as `methods`
1206
+ _.functions = _.methods = function(obj) {
1207
+ var names = [];
1208
+ for (var key in obj) {
1209
+ if (_.isFunction(obj[key])) names.push(key);
1210
+ }
1211
+ return names.sort();
1212
+ };
1213
+
1214
+ // Extend a given object with all the properties in passed-in object(s).
1215
+ _.extend = createAssigner(_.allKeys);
1216
+
1217
+ // Assigns a given object with all the own properties in the passed-in object(s)
1218
+ // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
1219
+ _.extendOwn = _.assign = createAssigner(_.keys);
1220
+
1221
+ // Returns the first key on an object that passes a predicate test
1222
+ _.findKey = function(obj, predicate, context) {
1223
+ predicate = cb(predicate, context);
1224
+ var keys = _.keys(obj), key;
1225
+ for (var i = 0, length = keys.length; i < length; i++) {
1226
+ key = keys[i];
1227
+ if (predicate(obj[key], key, obj)) return key;
1228
+ }
1229
+ };
1230
+
1231
+ // Return a copy of the object only containing the whitelisted properties.
1232
+ _.pick = function(object, oiteratee, context) {
1233
+ var result = {}, obj = object, iteratee, keys;
1234
+ if (obj == null) return result;
1235
+ if (_.isFunction(oiteratee)) {
1236
+ keys = _.allKeys(obj);
1237
+ iteratee = optimizeCb(oiteratee, context);
1238
+ } else {
1239
+ keys = flatten(arguments, false, false, 1);
1240
+ iteratee = function(value, key, obj) { return key in obj; };
1241
+ obj = Object(obj);
1242
+ }
1243
+ for (var i = 0, length = keys.length; i < length; i++) {
1244
+ var key = keys[i];
1245
+ var value = obj[key];
1246
+ if (iteratee(value, key, obj)) result[key] = value;
1247
+ }
1248
+ return result;
1249
+ };
1250
+
1251
+ // Return a copy of the object without the blacklisted properties.
1252
+ _.omit = function(obj, iteratee, context) {
1253
+ if (_.isFunction(iteratee)) {
1254
+ iteratee = _.negate(iteratee);
1255
+ } else {
1256
+ var keys = _.map(flatten(arguments, false, false, 1), String);
1257
+ iteratee = function(value, key) {
1258
+ return !_.contains(keys, key);
1259
+ };
1260
+ }
1261
+ return _.pick(obj, iteratee, context);
1262
+ };
1263
+
1264
+ // Fill in a given object with default properties.
1265
+ _.defaults = createAssigner(_.allKeys, true);
1266
+
1267
+ // Creates an object that inherits from the given prototype object.
1268
+ // If additional properties are provided then they will be added to the
1269
+ // created object.
1270
+ _.create = function(prototype, props) {
1271
+ var result = baseCreate(prototype);
1272
+ if (props) _.extendOwn(result, props);
1273
+ return result;
1274
+ };
1275
+
1276
+ // Create a (shallow-cloned) duplicate of an object.
1277
+ _.clone = function(obj) {
1278
+ if (!_.isObject(obj)) return obj;
1279
+ return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
1280
+ };
1281
+
1282
+ // Invokes interceptor with the obj, and then returns obj.
1283
+ // The primary purpose of this method is to "tap into" a method chain, in
1284
+ // order to perform operations on intermediate results within the chain.
1285
+ _.tap = function(obj, interceptor) {
1286
+ interceptor(obj);
1287
+ return obj;
1288
+ };
1289
+
1290
+ // Returns whether an object has a given set of `key:value` pairs.
1291
+ _.isMatch = function(object, attrs) {
1292
+ var keys = _.keys(attrs), length = keys.length;
1293
+ if (object == null) return !length;
1294
+ var obj = Object(object);
1295
+ for (var i = 0; i < length; i++) {
1296
+ var key = keys[i];
1297
+ if (attrs[key] !== obj[key] || !(key in obj)) return false;
1298
+ }
1299
+ return true;
1300
+ };
1301
+
1302
+
1303
+ // Internal recursive comparison function for `isEqual`.
1304
+ var eq = function(a, b, aStack, bStack) {
1305
+ // Identical objects are equal. `0 === -0`, but they aren't identical.
1306
+ // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
1307
+ if (a === b) return a !== 0 || 1 / a === 1 / b;
1308
+ // A strict comparison is necessary because `null == undefined`.
1309
+ if (a == null || b == null) return a === b;
1310
+ // Unwrap any wrapped objects.
1311
+ if (a instanceof _) a = a._wrapped;
1312
+ if (b instanceof _) b = b._wrapped;
1313
+ // Compare `[[Class]]` names.
1314
+ var className = toString.call(a);
1315
+ if (className !== toString.call(b)) return false;
1316
+ switch (className) {
1317
+ // Strings, numbers, regular expressions, dates, and booleans are compared by value.
1318
+ case '[object RegExp]':
1319
+ // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
1320
+ case '[object String]':
1321
+ // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
1322
+ // equivalent to `new String("5")`.
1323
+ return '' + a === '' + b;
1324
+ case '[object Number]':
1325
+ // `NaN`s are equivalent, but non-reflexive.
1326
+ // Object(NaN) is equivalent to NaN
1327
+ if (+a !== +a) return +b !== +b;
1328
+ // An `egal` comparison is performed for other numeric values.
1329
+ return +a === 0 ? 1 / +a === 1 / b : +a === +b;
1330
+ case '[object Date]':
1331
+ case '[object Boolean]':
1332
+ // Coerce dates and booleans to numeric primitive values. Dates are compared by their
1333
+ // millisecond representations. Note that invalid dates with millisecond representations
1334
+ // of `NaN` are not equivalent.
1335
+ return +a === +b;
1336
+ }
1337
+
1338
+ var areArrays = className === '[object Array]';
1339
+ if (!areArrays) {
1340
+ if (typeof a != 'object' || typeof b != 'object') return false;
1341
+
1342
+ // Objects with different constructors are not equivalent, but `Object`s or `Array`s
1343
+ // from different frames are.
1344
+ var aCtor = a.constructor, bCtor = b.constructor;
1345
+ if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
1346
+ _.isFunction(bCtor) && bCtor instanceof bCtor)
1347
+ && ('constructor' in a && 'constructor' in b)) {
1348
+ return false;
1349
+ }
1350
+ }
1351
+ // Assume equality for cyclic structures. The algorithm for detecting cyclic
1352
+ // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
1353
+
1354
+ // Initializing stack of traversed objects.
1355
+ // It's done here since we only need them for objects and arrays comparison.
1356
+ aStack = aStack || [];
1357
+ bStack = bStack || [];
1358
+ var length = aStack.length;
1359
+ while (length--) {
1360
+ // Linear search. Performance is inversely proportional to the number of
1361
+ // unique nested structures.
1362
+ if (aStack[length] === a) return bStack[length] === b;
1363
+ }
1364
+
1365
+ // Add the first object to the stack of traversed objects.
1366
+ aStack.push(a);
1367
+ bStack.push(b);
1368
+
1369
+ // Recursively compare objects and arrays.
1370
+ if (areArrays) {
1371
+ // Compare array lengths to determine if a deep comparison is necessary.
1372
+ length = a.length;
1373
+ if (length !== b.length) return false;
1374
+ // Deep compare the contents, ignoring non-numeric properties.
1375
+ while (length--) {
1376
+ if (!eq(a[length], b[length], aStack, bStack)) return false;
1377
+ }
1378
+ } else {
1379
+ // Deep compare objects.
1380
+ var keys = _.keys(a), key;
1381
+ length = keys.length;
1382
+ // Ensure that both objects contain the same number of properties before comparing deep equality.
1383
+ if (_.keys(b).length !== length) return false;
1384
+ while (length--) {
1385
+ // Deep compare each member
1386
+ key = keys[length];
1387
+ if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
1388
+ }
1389
+ }
1390
+ // Remove the first object from the stack of traversed objects.
1391
+ aStack.pop();
1392
+ bStack.pop();
1393
+ return true;
1394
+ };
1395
+
1396
+ // Perform a deep comparison to check if two objects are equal.
1397
+ _.isEqual = function(a, b) {
1398
+ return eq(a, b);
1399
+ };
1400
+
1401
+ // Is a given array, string, or object empty?
1402
+ // An "empty" object has no enumerable own-properties.
1403
+ _.isEmpty = function(obj) {
1404
+ if (obj == null) return true;
1405
+ if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
1406
+ return _.keys(obj).length === 0;
1407
+ };
1408
+
1409
+ // Is a given value a DOM element?
1410
+ _.isElement = function(obj) {
1411
+ return !!(obj && obj.nodeType === 1);
1412
+ };
1413
+
1414
+ // Is a given value an array?
1415
+ // Delegates to ECMA5's native Array.isArray
1416
+ _.isArray = nativeIsArray || function(obj) {
1417
+ return toString.call(obj) === '[object Array]';
1418
+ };
1419
+
1420
+ // Is a given variable an object?
1421
+ _.isObject = function(obj) {
1422
+ var type = typeof obj;
1423
+ return type === 'function' || type === 'object' && !!obj;
1424
+ };
1425
+
1426
+ // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError.
1427
+ _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) {
1428
+ _['is' + name] = function(obj) {
1429
+ return toString.call(obj) === '[object ' + name + ']';
1430
+ };
1431
+ });
1432
+
1433
+ // Define a fallback version of the method in browsers (ahem, IE < 9), where
1434
+ // there isn't any inspectable "Arguments" type.
1435
+ if (!_.isArguments(arguments)) {
1436
+ _.isArguments = function(obj) {
1437
+ return _.has(obj, 'callee');
1438
+ };
1439
+ }
1440
+
1441
+ // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
1442
+ // IE 11 (#1621), and in Safari 8 (#1929).
1443
+ if (typeof /./ != 'function' && typeof Int8Array != 'object') {
1444
+ _.isFunction = function(obj) {
1445
+ return typeof obj == 'function' || false;
1446
+ };
1447
+ }
1448
+
1449
+ // Is a given object a finite number?
1450
+ _.isFinite = function(obj) {
1451
+ return isFinite(obj) && !isNaN(parseFloat(obj));
1452
+ };
1453
+
1454
+ // Is the given value `NaN`? (NaN is the only number which does not equal itself).
1455
+ _.isNaN = function(obj) {
1456
+ return _.isNumber(obj) && obj !== +obj;
1457
+ };
1458
+
1459
+ // Is a given value a boolean?
1460
+ _.isBoolean = function(obj) {
1461
+ return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
1462
+ };
1463
+
1464
+ // Is a given value equal to null?
1465
+ _.isNull = function(obj) {
1466
+ return obj === null;
1467
+ };
1468
+
1469
+ // Is a given variable undefined?
1470
+ _.isUndefined = function(obj) {
1471
+ return obj === void 0;
1472
+ };
1473
+
1474
+ // Shortcut function for checking if an object has a given property directly
1475
+ // on itself (in other words, not on a prototype).
1476
+ _.has = function(obj, key) {
1477
+ return obj != null && hasOwnProperty.call(obj, key);
1478
+ };
1479
+
1480
+ // Utility Functions
1481
+ // -----------------
1482
+
1483
+ // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
1484
+ // previous owner. Returns a reference to the Underscore object.
1485
+ _.noConflict = function() {
1486
+ root._ = previousUnderscore;
1487
+ return this;
1488
+ };
1489
+
1490
+ // Keep the identity function around for default iteratees.
1491
+ _.identity = function(value) {
1492
+ return value;
1493
+ };
1494
+
1495
+ // Predicate-generating functions. Often useful outside of Underscore.
1496
+ _.constant = function(value) {
1497
+ return function() {
1498
+ return value;
1499
+ };
1500
+ };
1501
+
1502
+ _.noop = function(){};
1503
+
1504
+ _.property = property;
1505
+
1506
+ // Generates a function for a given object that returns a given property.
1507
+ _.propertyOf = function(obj) {
1508
+ return obj == null ? function(){} : function(key) {
1509
+ return obj[key];
1510
+ };
1511
+ };
1512
+
1513
+ // Returns a predicate for checking whether an object has a given set of
1514
+ // `key:value` pairs.
1515
+ _.matcher = _.matches = function(attrs) {
1516
+ attrs = _.extendOwn({}, attrs);
1517
+ return function(obj) {
1518
+ return _.isMatch(obj, attrs);
1519
+ };
1520
+ };
1521
+
1522
+ // Run a function **n** times.
1523
+ _.times = function(n, iteratee, context) {
1524
+ var accum = Array(Math.max(0, n));
1525
+ iteratee = optimizeCb(iteratee, context, 1);
1526
+ for (var i = 0; i < n; i++) accum[i] = iteratee(i);
1527
+ return accum;
1528
+ };
1529
+
1530
+ // Return a random integer between min and max (inclusive).
1531
+ _.random = function(min, max) {
1532
+ if (max == null) {
1533
+ max = min;
1534
+ min = 0;
1535
+ }
1536
+ return min + Math.floor(Math.random() * (max - min + 1));
1537
+ };
1538
+
1539
+ // A (possibly faster) way to get the current timestamp as an integer.
1540
+ _.now = Date.now || function() {
1541
+ return new Date().getTime();
1542
+ };
1543
+
1544
+ // List of HTML entities for escaping.
1545
+ var escapeMap = {
1546
+ '&': '&amp;',
1547
+ '<': '&lt;',
1548
+ '>': '&gt;',
1549
+ '"': '&quot;',
1550
+ "'": '&#x27;',
1551
+ '`': '&#x60;'
1552
+ };
1553
+ var unescapeMap = _.invert(escapeMap);
1554
+
1555
+ // Functions for escaping and unescaping strings to/from HTML interpolation.
1556
+ var createEscaper = function(map) {
1557
+ var escaper = function(match) {
1558
+ return map[match];
1559
+ };
1560
+ // Regexes for identifying a key that needs to be escaped
1561
+ var source = '(?:' + _.keys(map).join('|') + ')';
1562
+ var testRegexp = RegExp(source);
1563
+ var replaceRegexp = RegExp(source, 'g');
1564
+ return function(string) {
1565
+ string = string == null ? '' : '' + string;
1566
+ return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
1567
+ };
1568
+ };
1569
+ _.escape = createEscaper(escapeMap);
1570
+ _.unescape = createEscaper(unescapeMap);
1571
+
1572
+ // If the value of the named `property` is a function then invoke it with the
1573
+ // `object` as context; otherwise, return it.
1574
+ _.result = function(object, property, fallback) {
1575
+ var value = object == null ? void 0 : object[property];
1576
+ if (value === void 0) {
1577
+ value = fallback;
1578
+ }
1579
+ return _.isFunction(value) ? value.call(object) : value;
1580
+ };
1581
+
1582
+ // Generate a unique integer id (unique within the entire client session).
1583
+ // Useful for temporary DOM ids.
1584
+ var idCounter = 0;
1585
+ _.uniqueId = function(prefix) {
1586
+ var id = ++idCounter + '';
1587
+ return prefix ? prefix + id : id;
1588
+ };
1589
+
1590
+ // By default, Underscore uses ERB-style template delimiters, change the
1591
+ // following template settings to use alternative delimiters.
1592
+ _.templateSettings = {
1593
+ evaluate : /<%([\s\S]+?)%>/g,
1594
+ interpolate : /<%=([\s\S]+?)%>/g,
1595
+ escape : /<%-([\s\S]+?)%>/g
1596
+ };
1597
+
1598
+ // When customizing `templateSettings`, if you don't want to define an
1599
+ // interpolation, evaluation or escaping regex, we need one that is
1600
+ // guaranteed not to match.
1601
+ var noMatch = /(.)^/;
1602
+
1603
+ // Certain characters need to be escaped so that they can be put into a
1604
+ // string literal.
1605
+ var escapes = {
1606
+ "'": "'",
1607
+ '\\': '\\',
1608
+ '\r': 'r',
1609
+ '\n': 'n',
1610
+ '\u2028': 'u2028',
1611
+ '\u2029': 'u2029'
1612
+ };
1613
+
1614
+ var escaper = /\\|'|\r|\n|\u2028|\u2029/g;
1615
+
1616
+ var escapeChar = function(match) {
1617
+ return '\\' + escapes[match];
1618
+ };
1619
+
1620
+ // JavaScript micro-templating, similar to John Resig's implementation.
1621
+ // Underscore templating handles arbitrary delimiters, preserves whitespace,
1622
+ // and correctly escapes quotes within interpolated code.
1623
+ // NB: `oldSettings` only exists for backwards compatibility.
1624
+ _.template = function(text, settings, oldSettings) {
1625
+ if (!settings && oldSettings) settings = oldSettings;
1626
+ settings = _.defaults({}, settings, _.templateSettings);
1627
+
1628
+ // Combine delimiters into one regular expression via alternation.
1629
+ var matcher = RegExp([
1630
+ (settings.escape || noMatch).source,
1631
+ (settings.interpolate || noMatch).source,
1632
+ (settings.evaluate || noMatch).source
1633
+ ].join('|') + '|$', 'g');
1634
+
1635
+ // Compile the template source, escaping string literals appropriately.
1636
+ var index = 0;
1637
+ var source = "__p+='";
1638
+ text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
1639
+ source += text.slice(index, offset).replace(escaper, escapeChar);
1640
+ index = offset + match.length;
1641
+
1642
+ if (escape) {
1643
+ source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
1644
+ } else if (interpolate) {
1645
+ source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
1646
+ } else if (evaluate) {
1647
+ source += "';\n" + evaluate + "\n__p+='";
1648
+ }
1649
+
1650
+ // Adobe VMs need the match returned to produce the correct offest.
1651
+ return match;
1652
+ });
1653
+ source += "';\n";
1654
+
1655
+ // If a variable is not specified, place data values in local scope.
1656
+ if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
1657
+
1658
+ source = "var __t,__p='',__j=Array.prototype.join," +
1659
+ "print=function(){__p+=__j.call(arguments,'');};\n" +
1660
+ source + 'return __p;\n';
1661
+
1662
+ try {
1663
+ var render = new Function(settings.variable || 'obj', '_', source);
1664
+ } catch (e) {
1665
+ e.source = source;
1666
+ throw e;
1667
+ }
1668
+
1669
+ var template = function(data) {
1670
+ return render.call(this, data, _);
1671
+ };
1672
+
1673
+ // Provide the compiled source as a convenience for precompilation.
1674
+ var argument = settings.variable || 'obj';
1675
+ template.source = 'function(' + argument + '){\n' + source + '}';
1676
+
1677
+ return template;
1678
+ };
1679
+
1680
+ // Add a "chain" function. Start chaining a wrapped Underscore object.
1681
+ _.chain = function(obj) {
1682
+ var instance = _(obj);
1683
+ instance._chain = true;
1684
+ return instance;
1685
+ };
1686
+
1687
+ // OOP
1688
+ // ---------------
1689
+ // If Underscore is called as a function, it returns a wrapped object that
1690
+ // can be used OO-style. This wrapper holds altered versions of all the
1691
+ // underscore functions. Wrapped objects may be chained.
1692
+
1693
+ // Helper function to continue chaining intermediate results.
1694
+ var result = function(instance, obj) {
1695
+ return instance._chain ? _(obj).chain() : obj;
1696
+ };
1697
+
1698
+ // Add your own custom functions to the Underscore object.
1699
+ _.mixin = function(obj) {
1700
+ _.each(_.functions(obj), function(name) {
1701
+ var func = _[name] = obj[name];
1702
+ _.prototype[name] = function() {
1703
+ var args = [this._wrapped];
1704
+ push.apply(args, arguments);
1705
+ return result(this, func.apply(_, args));
1706
+ };
1707
+ });
1708
+ };
1709
+
1710
+ // Add all of the Underscore functions to the wrapper object.
1711
+ _.mixin(_);
1712
+
1713
+ // Add all mutator Array functions to the wrapper.
1714
+ _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
1715
+ var method = ArrayProto[name];
1716
+ _.prototype[name] = function() {
1717
+ var obj = this._wrapped;
1718
+ method.apply(obj, arguments);
1719
+ if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
1720
+ return result(this, obj);
1721
+ };
1722
+ });
1723
+
1724
+ // Add all accessor Array functions to the wrapper.
1725
+ _.each(['concat', 'join', 'slice'], function(name) {
1726
+ var method = ArrayProto[name];
1727
+ _.prototype[name] = function() {
1728
+ return result(this, method.apply(this._wrapped, arguments));
1729
+ };
1730
+ });
1731
+
1732
+ // Extracts the result from a wrapped and chained object.
1733
+ _.prototype.value = function() {
1734
+ return this._wrapped;
1735
+ };
1736
+
1737
+ // Provide unwrapping proxy for some methods used in engine operations
1738
+ // such as arithmetic and JSON stringification.
1739
+ _.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
1740
+
1741
+ _.prototype.toString = function() {
1742
+ return '' + this._wrapped;
1743
+ };
1744
+
1745
+ // AMD registration happens at the end for compatibility with AMD loaders
1746
+ // that may not enforce next-turn semantics on modules. Even though general
1747
+ // practice for AMD registration is to be anonymous, underscore registers
1748
+ // as a named module because, like jQuery, it is a base library that is
1749
+ // popular enough to be bundled in a third party lib, but not be part of
1750
+ // an AMD load request. Those cases could generate an error when an
1751
+ // anonymous define() is called outside of a loader request.
1752
+ if (true) {
1753
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() {
1754
+ return _;
1755
+ }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1756
+ }
1757
+ }.call(this));
1758
+
1759
+
1760
+ /***/ },
1761
+ /* 7 */
1762
+ /***/ function(module, exports, __webpack_require__) {
1763
+
1764
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(1)], __WEBPACK_AMD_DEFINE_RESULT__ = function (mp) {
1765
+ 'use strict';
1766
+
1767
+ var MailPoet = mp;
1768
+ MailPoet.Iframe = {
1769
+ marginY: 20,
1770
+ autoSize: function (iframe) {
1771
+ if (!iframe) return;
1772
+
1773
+ this.setSize(
1774
+ iframe,
1775
+ iframe.contentWindow.document.body.scrollHeight
1776
+ );
1777
+ },
1778
+ setSize: function (sizeIframe, i) {
1779
+ var iframe = sizeIframe;
1780
+ if (!iframe) return;
1781
+
1782
+ iframe.style.height = (
1783
+ parseInt(i, 10) + this.marginY
1784
+ ) + 'px';
1785
+ }
1786
+ };
1787
+
1788
+ return MailPoet;
1789
+ }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1790
+
1791
+
1792
+ /***/ },
1793
+ /* 8 */
1794
+ /***/ function(module, exports, __webpack_require__) {
1795
+
1796
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
1797
+ __webpack_require__(4)
1798
+ ], __WEBPACK_AMD_DEFINE_RESULT__ = function (
1799
+ jQuery
1800
+ ) {
1801
+ var $ = jQuery;
1802
+ // Combination of jQuery.deparam and jQuery.serializeObject by Ben Alman.
1803
+ /*!
1804
+ * jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010
1805
+ * http://benalman.com/projects/jquery-bbq-plugin/
1806
+ *
1807
+ * Copyright (c) 2010 "Cowboy" Ben Alman
1808
+ * Dual licensed under the MIT and GPL licenses.
1809
+ * http://benalman.com/about/license/
1810
+ */
1811
+ /*!
1812
+ * jQuery serializeObject - v0.2 - 1/20/2010
1813
+ * http://benalman.com/projects/jquery-misc-plugins/
1814
+ *
1815
+ * Copyright (c) 2010 "Cowboy" Ben Alman
1816
+ * Dual licensed under the MIT and GPL licenses.
1817
+ * http://benalman.com/about/license/
1818
+ */
1819
+ $.fn.serializeObject = function (coerce) {
1820
+ var obj = {};
1821
+ var coerce_types = { true: !0, false: !1, null: null };
1822
+
1823
+ // Iterate over all name=value pairs.
1824
+ $.each(this.serializeArray(), function (j, v) {
1825
+ var key = v.name;
1826
+ var val = v.value;
1827
+ var cur = obj;
1828
+ var i = 0;
1829
+
1830
+ // If key is more complex than 'foo', like 'a[]' or 'a[b][c]', split it
1831
+ // into its component parts.
1832
+ var keys = key.split('][');
1833
+ var keys_last = keys.length - 1;
1834
+
1835
+ // If the first keys part contains [ and the last ends with ], then []
1836
+ // are correctly balanced.
1837
+ if (/\[/.test(keys[0]) && /\]$/.test(keys[keys_last])) {
1838
+ // Remove the trailing ] from the last keys part.
1839
+ keys[keys_last] = keys[keys_last].replace(/\]$/, '');
1840
+
1841
+ // Split first keys part into two parts on the [ and add them back onto
1842
+ // the beginning of the keys array.
1843
+ keys = keys.shift().split('[').concat(keys);
1844
+
1845
+ keys_last = keys.length - 1;
1846
+ } else {
1847
+ // Basic 'foo' style key.
1848
+ keys_last = 0;
1849
+ }
1850
+
1851
+ // Coerce values.
1852
+ if (coerce) {
1853
+ val = val && !isNaN(val) ? +val // number
1854
+ : val === 'undefined' ? undefined // undefined
1855
+ : coerce_types[val] !== undefined ? coerce_types[val] // true, false, null
1856
+ : val; // string
1857
+ }
1858
+
1859
+ if (keys_last) {
1860
+ // Complex key, build deep object structure based on a few rules:
1861
+ // * The 'cur' pointer starts at the object top-level.
1862
+ // * [] = array push (n is set to array length), [n] = array if n is
1863
+ // numeric, otherwise object.
1864
+ // * If at the last keys part, set the value.
1865
+ // * For each keys part, if the current level is undefined create an
1866
+ // object or array based on the type of the next keys part.
1867
+ // * Move the 'cur' pointer to the next level.
1868
+ // * Rinse & repeat.
1869
+ for (; i <= keys_last; i++) {
1870
+ key = keys[i] === '' ? cur.length : keys[i];
1871
+ cur[key] = i < keys_last
1872
+ ? cur[key] || (keys[i + 1] && isNaN(keys[i + 1]) ? {} : [])
1873
+ : val;
1874
+ cur = cur[key];
1875
+ }
1876
+
1877
+ } else {
1878
+ // Simple key, even simpler rules, since only scalars and shallow
1879
+ // arrays are allowed.
1880
+
1881
+ if ($.isArray(obj[key])) {
1882
+ // val is already an array, so push on the next value.
1883
+ obj[key].push(val);
1884
+
1885
+ } else if (obj[key] !== undefined) {
1886
+ // val isn't an array, but since a second value has been specified,
1887
+ // convert val into an array.
1888
+ obj[key] = [obj[key], val];
1889
+
1890
+ } else {
1891
+ // val is a scalar.
1892
+ obj[key] = val;
1893
+ }
1894
+ }
1895
+ });
1896
+
1897
+ return obj;
1898
+ };
1899
+
1900
+ return $;
1901
+ }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1902
+
1903
+
1904
+ /***/ },
1905
+ /* 9 */
1906
+ /***/ function(module, exports, __webpack_require__) {
1907
+
1908
+ var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [
1909
+ __webpack_require__(1),
1910
+ __webpack_require__(4)
1911
+ ], __WEBPACK_AMD_DEFINE_RESULT__ = function (
1912
+ MailPoet,
1913
+ jQuery
1914
+ ) {
1915
+ jQuery(function ($) {
1916
+ function isSameDomain(url) {
1917
+ var link = document.createElement('a');
1918
+ link.href = url;
1919
+ return (window.location.hostname === link.hostname);
1920
+ }
1921
+
1922
+ $(function () {
1923
+ // setup form validation
1924
+ $('form.mailpoet_form').each(function () {
1925
+ var form = $(this);
1926
+
1927
+ form.parsley().on('form:validated', function () {
1928
+ // clear messages
1929
+ form.find('.mailpoet_message > p').hide();
1930
+
1931
+ // resize iframe
1932
+ if (window.frameElement !== null) {
1933
+ MailPoet.Iframe.autoSize(window.frameElement);
1934
+ }
1935
+ });
1936
+
1937
+ form.parsley().on('form:submit', function (parsley) {
1938
+ var form_data = form.serializeObject() || {};
1939
+ // check if we're on the same domain
1940
+ if (isSameDomain(window.MailPoetForm.ajax_url) === false) {
1941
+ // non ajax post request
1942
+ return true;
1943
+ } else {
1944
+ // ajax request
1945
+ MailPoet.Ajax.post({
1946
+ url: window.MailPoetForm.ajax_url,
1947
+ token: form_data.token,
1948
+ api_version: form_data.api_version,
1949
+ endpoint: 'subscribers',
1950
+ action: 'subscribe',
1951
+ data: form_data.data
1952
+ }).fail(function (response) {
1953
+ form.find('.mailpoet_validate_error').html(
1954
+ response.errors.map(function (error) {
1955
+ return error.message;
1956
+ }).join('<br />')
1957
+ ).show();
1958
+ }).done(function (response) {
1959
+ // successfully subscribed
1960
+ if (
1961
+ response.meta !== undefined
1962
+ && response.meta.redirect_url !== undefined
1963
+ ) {
1964
+ // go to page
1965
+ window.location.href = response.meta.redirect_url;
1966
+ } else {
1967
+ // display success message
1968
+ form.find('.mailpoet_validate_success').show();
1969
+ }
1970
+
1971
+ // reset form
1972
+ form.trigger('reset');
1973
+ // reset validation
1974
+ parsley.reset();
1975
+
1976
+ // resize iframe
1977
+ if (
1978
+ window.frameElement !== null
1979
+ && MailPoet !== undefined
1980
+ && MailPoet['Iframe']
1981
+ ) {
1982
+ MailPoet.Iframe.autoSize(window.frameElement);
1983
+ }
1984
+ });
1985
+ }
1986
+ return false;
1987
+ });
1988
+ });
1989
+ });
1990
+ });
1991
+ }.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
1992
+
1993
+
1994
+ /***/ }
1995
+ /******/ ]);
assets/js/{vendor.3c88b878.js → vendor.b37906c4.js} RENAMED
@@ -76,7 +76,7 @@
76
  /******/ script.charset = 'utf-8';
77
  /******/ script.async = true;
78
 
79
- /******/ script.src = __webpack_require__.p + "" + ({"0":"admin","1":"admin_vendor","2":"form_editor","3":"mailpoet","4":"newsletter_editor"}[chunkId]||chunkId) + "." + {"0":"5545d8c1","1":"6c010053","2":"c4bc7e0b","3":"0fdbdb38","4":"29b8231c"}[chunkId] + ".chunk.js";
80
  /******/ head.appendChild(script);
81
  /******/ }
82
  /******/ };
@@ -100,38 +100,40 @@
100
  /***/ function(module, exports, __webpack_require__) {
101
 
102
  __webpack_require__(543);
103
- __webpack_require__(575);
104
  module.exports = __webpack_require__(422);
105
 
106
 
107
  /***/ },
108
 
109
- /***/ 575:
110
  /***/ function(module, exports, __webpack_require__) {
111
 
112
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(543)], __WEBPACK_AMD_DEFINE_RESULT__ = function (Handlebars) {
113
  // Handlebars helpers
114
  Handlebars.registerHelper('concat', function () {
115
- var size = (arguments.length - 1),
116
- output = '';
117
- for (var i = 0; i < size; i++) {
 
118
  output += arguments[i];
119
  }
120
  return output;
121
  });
122
 
123
- Handlebars.registerHelper('number_format', function (value, block) {
124
  return Number(value).toLocaleString();
125
  });
126
  Handlebars.registerHelper('date_format', function (timestamp, block) {
 
127
  if (window.moment) {
128
  if (timestamp === undefined || isNaN(timestamp) || timestamp <= 0) {
129
  return;
130
  }
131
 
132
- // set date format
133
- var f = block.hash.format || 'MMM Do, YYYY';
134
- // check if we passed a timestamp
135
  if (parseInt(timestamp, 10) == timestamp) {
136
  return window.moment.unix(timestamp).format(f);
137
  } else {
@@ -170,25 +172,24 @@
170
  case '||':
171
  return (v1 || v2) ? options.fn(this) : options.inverse(this);
172
  case 'in':
173
- var values = v2.split(',');
174
  return (v2.indexOf(v1) !== -1) ? options.fn(this) : options.inverse(this);
175
  default:
176
  return options.inverse(this);
177
  }
178
  });
179
 
180
- Handlebars.registerHelper('nl2br', function (value, block) {
181
  return value.gsub('\n', '<br />');
182
  });
183
 
184
- Handlebars.registerHelper('json_encode', function (value, block) {
185
  return JSON.stringify(value);
186
  });
187
 
188
- Handlebars.registerHelper('json_decode', function (value, block) {
189
  return JSON.parse(value);
190
  });
191
- Handlebars.registerHelper('url', function (value, block) {
192
  var url = window.location.protocol + '//' + window.location.host + window.location.pathname;
193
 
194
  return url + value;
@@ -201,16 +202,17 @@
201
  return value;
202
  }
203
  });
204
- Handlebars.registerHelper('lookup', function (obj, field, options) {
205
  return obj && obj[field];
206
  });
207
 
208
 
209
- Handlebars.registerHelper('rsa_key', function (value, block) {
210
- // extract all lines into an array
 
211
  if (value === undefined) return '';
212
 
213
- var lines = value.trim().split('\n');
214
 
215
  // remove header & footer
216
  lines.shift();
@@ -220,7 +222,7 @@
220
  return lines.join('');
221
  });
222
 
223
- Handlebars.registerHelper('trim', function (value, block) {
224
  if (value === null || value === undefined) return '';
225
  return value.trim();
226
  });
@@ -237,10 +239,10 @@
237
  */
238
  Handlebars.registerHelper('ellipsis', function (str, limit, append) {
239
  var strAppend = append;
 
240
  if (strAppend === undefined) {
241
  strAppend = '';
242
  }
243
- var sanitized = str.replace(/(<([^>]+)>)/g, '');
244
  if (sanitized.length > limit) {
245
  return sanitized.substr(0, limit - strAppend.length) + strAppend;
246
  } else {
76
  /******/ script.charset = 'utf-8';
77
  /******/ script.async = true;
78
 
79
+ /******/ script.src = __webpack_require__.p + "" + ({"0":"admin","1":"admin_vendor","2":"form_editor","3":"mailpoet","4":"newsletter_editor"}[chunkId]||chunkId) + "." + {"0":"790800b0","1":"dda60c3b","2":"d94aebf3","3":"122cc57f","4":"7394c278"}[chunkId] + ".chunk.js";
80
  /******/ head.appendChild(script);
81
  /******/ }
82
  /******/ };
100
  /***/ function(module, exports, __webpack_require__) {
101
 
102
  __webpack_require__(543);
103
+ __webpack_require__(606);
104
  module.exports = __webpack_require__(422);
105
 
106
 
107
  /***/ },
108
 
109
+ /***/ 606:
110
  /***/ function(module, exports, __webpack_require__) {
111
 
112
  var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(543)], __WEBPACK_AMD_DEFINE_RESULT__ = function (Handlebars) {
113
  // Handlebars helpers
114
  Handlebars.registerHelper('concat', function () {
115
+ var size = (arguments.length - 1);
116
+ var output = '';
117
+ var i;
118
+ for (i = 0; i < size; i++) {
119
  output += arguments[i];
120
  }
121
  return output;
122
  });
123
 
124
+ Handlebars.registerHelper('number_format', function (value) {
125
  return Number(value).toLocaleString();
126
  });
127
  Handlebars.registerHelper('date_format', function (timestamp, block) {
128
+ var f;
129
  if (window.moment) {
130
  if (timestamp === undefined || isNaN(timestamp) || timestamp <= 0) {
131
  return;
132
  }
133
 
134
+ // set date format
135
+ f = block.hash.format || 'MMM Do, YYYY';
136
+ // check if we passed a timestamp
137
  if (parseInt(timestamp, 10) == timestamp) {
138
  return window.moment.unix(timestamp).format(f);
139
  } else {
172
  case '||':
173
  return (v1 || v2) ? options.fn(this) : options.inverse(this);
174
  case 'in':
 
175
  return (v2.indexOf(v1) !== -1) ? options.fn(this) : options.inverse(this);
176
  default:
177
  return options.inverse(this);
178
  }
179
  });
180
 
181
+ Handlebars.registerHelper('nl2br', function (value) {
182
  return value.gsub('\n', '<br />');
183
  });
184
 
185
+ Handlebars.registerHelper('json_encode', function (value) {
186
  return JSON.stringify(value);
187
  });
188
 
189
+ Handlebars.registerHelper('json_decode', function (value) {
190
  return JSON.parse(value);
191
  });
192
+ Handlebars.registerHelper('url', function (value) {
193
  var url = window.location.protocol + '//' + window.location.host + window.location.pathname;
194
 
195
  return url + value;
202
  return value;
203
  }
204
  });
205
+ Handlebars.registerHelper('lookup', function (obj, field) {
206
  return obj && obj[field];
207
  });
208
 
209
 
210
+ Handlebars.registerHelper('rsa_key', function (value) {
211
+ var lines;
212
+ // extract all lines into an array
213
  if (value === undefined) return '';
214
 
215
+ lines = value.trim().split('\n');
216
 
217
  // remove header & footer
218
  lines.shift();
222
  return lines.join('');
223
  });
224
 
225
+ Handlebars.registerHelper('trim', function (value) {
226
  if (value === null || value === undefined) return '';
227
  return value.trim();
228
  });
239
  */
240
  Handlebars.registerHelper('ellipsis', function (str, limit, append) {
241
  var strAppend = append;
242
+ var sanitized = str.replace(/(<([^>]+)>)/g, '');
243
  if (strAppend === undefined) {
244
  strAppend = '';
245
  }
 
246
  if (sanitized.length > limit) {
247
  return sanitized.substr(0, limit - strAppend.length) + strAppend;
248
  } else {
lang/mailpoet-da_DK.mo CHANGED
Binary file
lang/mailpoet-de_DE.mo CHANGED
Binary file
lang/mailpoet-en_GB.mo CHANGED
Binary file
lang/mailpoet-es_ES.mo CHANGED
Binary file
lang/mailpoet-fa_IR.mo CHANGED
Binary file
lang/mailpoet-fr_CA.mo CHANGED
Binary file
lang/mailpoet-fr_FR.mo CHANGED
Binary file
lang/mailpoet-it_IT.mo CHANGED
Binary file
lang/mailpoet-ja.mo CHANGED
Binary file
lang/mailpoet-nl_NL.mo CHANGED
Binary file
lang/mailpoet-pl_PL.mo CHANGED
Binary file
lang/mailpoet-pt_BR.mo CHANGED
Binary file
lang/mailpoet-pt_PT.mo CHANGED
Binary file
lang/mailpoet-ru_RU.mo CHANGED
Binary file
lang/mailpoet-sv_SE.mo CHANGED
Binary file
lang/mailpoet-tr_TR.mo CHANGED
Binary file
lang/mailpoet.pot CHANGED
@@ -4,7 +4,7 @@ msgid ""
4
  msgstr ""
5
  "Project-Id-Version: \n"
6
  "Report-Msgid-Bugs-To: http://support.mailpoet.com/\n"
7
- "POT-Creation-Date: 2017-10-05 11:47:37+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -30,7 +30,13 @@ msgstr ""
30
  msgid "Invalid API version."
31
  msgstr ""
32
 
33
- #: lib/API/JSON/API.php:60 lib/API/JSON/API.php:87
 
 
 
 
 
 
34
  msgid "Invalid API request."
35
  msgstr ""
36
 
@@ -1975,7 +1981,7 @@ msgstr ""
1975
  #: views/newsletter/templates/blocks/divider/settings.hbs:37
1976
  #: views/newsletter/templates/blocks/footer/settings.hbs:59
1977
  #: views/newsletter/templates/blocks/header/settings.hbs:59
1978
- #: views/newsletter/templates/blocks/image/settings.hbs:66
1979
  #: views/newsletter/templates/blocks/social/settings.hbs:6
1980
  #: views/newsletter/templates/blocks/spacer/settings.hbs:10
1981
  #: views/subscribers/importExport/import/step2.html:148
@@ -2719,6 +2725,7 @@ msgstr ""
2719
  #: views/newsletter/templates/blocks/button/settings.hbs:27
2720
  #: views/newsletter/templates/blocks/footer/settings.hbs:41
2721
  #: views/newsletter/templates/blocks/header/settings.hbs:41
 
2722
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:57
2723
  msgid "Left"
2724
  msgstr ""
@@ -2727,6 +2734,7 @@ msgstr ""
2727
  #: views/newsletter/templates/blocks/button/settings.hbs:33
2728
  #: views/newsletter/templates/blocks/footer/settings.hbs:47
2729
  #: views/newsletter/templates/blocks/header/settings.hbs:47
 
2730
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:63
2731
  msgid "Center"
2732
  msgstr ""
@@ -2735,6 +2743,7 @@ msgstr ""
2735
  #: views/newsletter/templates/blocks/button/settings.hbs:39
2736
  #: views/newsletter/templates/blocks/footer/settings.hbs:53
2737
  #: views/newsletter/templates/blocks/header/settings.hbs:53
 
2738
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:69
2739
  msgid "Right"
2740
  msgstr ""
@@ -2876,6 +2885,7 @@ msgid "Label"
2876
  msgstr ""
2877
 
2878
  #: views/newsletter/templates/blocks/button/settings.hbs:23
 
2879
  msgid "Alignment"
2880
  msgstr ""
2881
 
@@ -3000,7 +3010,7 @@ msgstr ""
3000
  msgid "Alternative text"
3001
  msgstr ""
3002
 
3003
- #: views/newsletter/templates/blocks/image/settings.hbs:62
3004
  msgid "Select another image"
3005
  msgstr ""
3006
 
4
  msgstr ""
5
  "Project-Id-Version: \n"
6
  "Report-Msgid-Bugs-To: http://support.mailpoet.com/\n"
7
+ "POT-Creation-Date: 2017-10-10 09:16:25+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
30
  msgid "Invalid API version."
31
  msgstr ""
32
 
33
+ #: lib/API/JSON/API.php:60
34
+ msgid ""
35
+ "Sorry, but we couldn't connect to the MailPoet server. Please refresh the "
36
+ "web page and try again."
37
+ msgstr ""
38
+
39
+ #: lib/API/JSON/API.php:87
40
  msgid "Invalid API request."
41
  msgstr ""
42
 
1981
  #: views/newsletter/templates/blocks/divider/settings.hbs:37
1982
  #: views/newsletter/templates/blocks/footer/settings.hbs:59
1983
  #: views/newsletter/templates/blocks/header/settings.hbs:59
1984
+ #: views/newsletter/templates/blocks/image/settings.hbs:87
1985
  #: views/newsletter/templates/blocks/social/settings.hbs:6
1986
  #: views/newsletter/templates/blocks/spacer/settings.hbs:10
1987
  #: views/subscribers/importExport/import/step2.html:148
2725
  #: views/newsletter/templates/blocks/button/settings.hbs:27
2726
  #: views/newsletter/templates/blocks/footer/settings.hbs:41
2727
  #: views/newsletter/templates/blocks/header/settings.hbs:41
2728
+ #: views/newsletter/templates/blocks/image/settings.hbs:65
2729
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:57
2730
  msgid "Left"
2731
  msgstr ""
2734
  #: views/newsletter/templates/blocks/button/settings.hbs:33
2735
  #: views/newsletter/templates/blocks/footer/settings.hbs:47
2736
  #: views/newsletter/templates/blocks/header/settings.hbs:47
2737
+ #: views/newsletter/templates/blocks/image/settings.hbs:71
2738
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:63
2739
  msgid "Center"
2740
  msgstr ""
2743
  #: views/newsletter/templates/blocks/button/settings.hbs:39
2744
  #: views/newsletter/templates/blocks/footer/settings.hbs:53
2745
  #: views/newsletter/templates/blocks/header/settings.hbs:53
2746
+ #: views/newsletter/templates/blocks/image/settings.hbs:77
2747
  #: views/newsletter/templates/blocks/posts/settingsDisplayOptions.hbs:69
2748
  msgid "Right"
2749
  msgstr ""
2885
  msgstr ""
2886
 
2887
  #: views/newsletter/templates/blocks/button/settings.hbs:23
2888
+ #: views/newsletter/templates/blocks/image/settings.hbs:61
2889
  msgid "Alignment"
2890
  msgstr ""
2891
 
3010
  msgid "Alternative text"
3011
  msgstr ""
3012
 
3013
+ #: views/newsletter/templates/blocks/image/settings.hbs:83
3014
  msgid "Select another image"
3015
  msgstr ""
3016
 
lib/API/JSON/API.php CHANGED
@@ -57,7 +57,7 @@ class API {
57
  $this->setRequestData($_POST);
58
 
59
  if($this->checkToken() === false) {
60
- $error_message = __('Invalid API request.', 'mailpoet');
61
  $error_response = $this->createErrorResponse(Error::UNAUTHORIZED, $error_message, Response::STATUS_UNAUTHORIZED);
62
  return $error_response->send();
63
  }
@@ -200,4 +200,4 @@ class API {
200
  );
201
  return $error_response;
202
  }
203
- }
57
  $this->setRequestData($_POST);
58
 
59
  if($this->checkToken() === false) {
60
+ $error_message = __('Sorry, but we couldn\'t connect to the MailPoet server. Please refresh the web page and try again.', 'mailpoet');
61
  $error_response = $this->createErrorResponse(Error::UNAUTHORIZED, $error_message, Response::STATUS_UNAUTHORIZED);
62
  return $error_response->send();
63
  }
200
  );
201
  return $error_response;
202
  }
203
+ }
lib/Newsletter/Renderer/Blocks/Image.php CHANGED
@@ -20,9 +20,13 @@ class Image {
20
  if(!empty($element['link'])) {
21
  $image_template = '<a href="' . $element['link'] . '">' . $image_template . '</a>';
22
  }
 
 
 
 
23
  $template = '
24
  <tr>
25
- <td class="mailpoet_image ' . (($element['fullWidth'] === false) ? 'mailpoet_padded_bottom mailpoet_padded_side' : '') . '" align="center" valign="top">
26
  ' . $image_template . '
27
  </td>
28
  </tr>';
20
  if(!empty($element['link'])) {
21
  $image_template = '<a href="' . $element['link'] . '">' . $image_template . '</a>';
22
  }
23
+ $align = 'center';
24
+ if(!empty($element['styles']['block']['textAlign']) && in_array($element['styles']['block']['textAlign'], array('left', 'right'))) {
25
+ $align = $element['styles']['block']['textAlign'];
26
+ }
27
  $template = '
28
  <tr>
29
+ <td class="mailpoet_image ' . (($element['fullWidth'] === false) ? 'mailpoet_padded_bottom mailpoet_padded_side' : '') . '" align="' . $align . '" valign="top">
30
  ' . $image_template . '
31
  </td>
32
  </tr>';
lib/npm-debug.log ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 0 info it worked if it ends with ok
2
+ 1 verbose cli [ '/home/flakas/.nvm/versions/node/v6.11.2/bin/node',
3
+ 1 verbose cli '/home/flakas/.nvm/versions/node/v6.11.2/bin/npm',
4
+ 1 verbose cli 'run',
5
+ 1 verbose cli 'lint5' ]
6
+ 2 info using npm@3.10.10
7
+ 3 info using node@v6.11.2
8
+ 4 verbose run-script [ 'prelint5', 'lint5', 'postlint5' ]
9
+ 5 info lifecycle @~prelint5: @
10
+ 6 silly lifecycle @~prelint5: no script for prelint5, continuing
11
+ 7 info lifecycle @~lint5: @
12
+ 8 verbose lifecycle @~lint5: unsafe-perm in lifecycle true
13
+ 9 verbose lifecycle @~lint5: PATH: /home/flakas/.nvm/versions/node/v6.11.2/lib/node_modules/npm/bin/node-gyp-bin:/var/www/mailpoet/node_modules/.bin:/home/flakas/.nvm/versions/node/v6.11.2/bin:/home/flakas/.cargo/bin:/home/flakas/.cargo/bin:/home/flakas/.cargo/bin:/home/flakas/.cargo/bin:/home/flakas/bin:/home/flakas/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/lib/jvm/java-8-oracle/bin:/usr/lib/jvm/java-8-oracle/db/bin:/usr/lib/jvm/java-8-oracle/jre/bin:/home/flakas/Android/Sdk/platform-platform-tools:/home/flakas/Android/Sdk/tools:/home/flakas/Android/Sdk/platform-platform-tools:/home/flakas/Android/Sdk/tools
14
+ 10 verbose lifecycle @~lint5: CWD: /var/www/mailpoet
15
+ 11 silly lifecycle @~lint5: Args: [ '-c',
16
+ 11 silly lifecycle 'eslint -c .eslintrc.es5.json --ignore-pattern helpscout.js --max-warnings 0 \'assets/js/src/**/*.js\'' ]
17
+ 12 silly lifecycle @~lint5: Returned: code: 1 signal: null
18
+ 13 info lifecycle @~lint5: Failed to exec lint5 script
19
+ 14 verbose stack Error: @ lint5: `eslint -c .eslintrc.es5.json --ignore-pattern helpscout.js --max-warnings 0 'assets/js/src/**/*.js'`
20
+ 14 verbose stack Exit status 1
21
+ 14 verbose stack at EventEmitter.<anonymous> (/home/flakas/.nvm/versions/node/v6.11.2/lib/node_modules/npm/lib/utils/lifecycle.js:255:16)
22
+ 14 verbose stack at emitTwo (events.js:106:13)
23
+ 14 verbose stack at EventEmitter.emit (events.js:191:7)
24
+ 14 verbose stack at ChildProcess.<anonymous> (/home/flakas/.nvm/versions/node/v6.11.2/lib/node_modules/npm/lib/utils/spawn.js:40:14)
25
+ 14 verbose stack at emitTwo (events.js:106:13)
26
+ 14 verbose stack at ChildProcess.emit (events.js:191:7)
27
+ 14 verbose stack at maybeClose (internal/child_process.js:891:16)
28
+ 14 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5)
29
+ 15 verbose pkgid @
30
+ 16 verbose cwd /var/www/mailpoet/lib
31
+ 17 error Linux 4.4.0-96-generic
32
+ 18 error argv "/home/flakas/.nvm/versions/node/v6.11.2/bin/node" "/home/flakas/.nvm/versions/node/v6.11.2/bin/npm" "run" "lint5"
33
+ 19 error node v6.11.2
34
+ 20 error npm v3.10.10
35
+ 21 error code ELIFECYCLE
36
+ 22 error @ lint5: `eslint -c .eslintrc.es5.json --ignore-pattern helpscout.js --max-warnings 0 'assets/js/src/**/*.js'`
37
+ 22 error Exit status 1
38
+ 23 error Failed at the @ lint5 script 'eslint -c .eslintrc.es5.json --ignore-pattern helpscout.js --max-warnings 0 'assets/js/src/**/*.js''.
39
+ 23 error Make sure you have the latest version of node.js and npm installed.
40
+ 23 error If you do, this is most likely a problem with the package,
41
+ 23 error not with npm itself.
42
+ 23 error Tell the author that this fails on your system:
43
+ 23 error eslint -c .eslintrc.es5.json --ignore-pattern helpscout.js --max-warnings 0 'assets/js/src/**/*.js'
44
+ 23 error You can get information on how to open an issue for this project with:
45
+ 23 error npm bugs
46
+ 23 error Or if that isn't available, you can get their info via:
47
+ 23 error npm owner ls
48
+ 23 error There is likely additional logging output above.
49
+ 24 verbose exit [ 1, true ]
mailpoet.php CHANGED
@@ -4,7 +4,7 @@ if(!defined('ABSPATH')) exit;
4
 
5
  /*
6
  * Plugin Name: MailPoet 3 (new)
7
- * Version: 3.0.4
8
  * Plugin URI: http://www.mailpoet.com
9
  * Description: Create and send newsletters, post notifications and welcome emails from your WordPress.
10
  * Author: MailPoet
@@ -20,7 +20,7 @@ if(!defined('ABSPATH')) exit;
20
  */
21
 
22
  $mailpoet_plugin = array(
23
- 'version' => '3.0.4',
24
  'filename' => __FILE__,
25
  'path' => dirname(__FILE__),
26
  'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',
4
 
5
  /*
6
  * Plugin Name: MailPoet 3 (new)
7
+ * Version: 3.0.5
8
  * Plugin URI: http://www.mailpoet.com
9
  * Description: Create and send newsletters, post notifications and welcome emails from your WordPress.
10
  * Author: MailPoet
20
  */
21
 
22
  $mailpoet_plugin = array(
23
+ 'version' => '3.0.5',
24
  'filename' => __FILE__,
25
  'path' => dirname(__FILE__),
26
  'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: newsletter, email, welcome email, post notification, autoresponder, signup
4
  Requires at least: 4.6
5
  Tested up to: 4.8
6
  Requires PHP: 5.3
7
- Stable tag: 3.0.4
8
  License: GPLv3
9
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
10
 
@@ -114,6 +114,9 @@ Stop by our [support site](https://www.mailpoet.com/support).
114
 
115
  == Changelog ==
116
 
 
 
 
117
  = 3.0.4 - 2017-10-05 =
118
  * Fixed: dividers and spacers' height can be changed on mouse drag again;
119
 
4
  Requires at least: 4.6
5
  Tested up to: 4.8
6
  Requires PHP: 5.3
7
+ Stable tag: 3.0.5
8
  License: GPLv3
9
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
10
 
114
 
115
  == Changelog ==
116
 
117
+ = 3.0.5 - 2017-10-10 =
118
+ * Added: images can now be aligned left, center or right in email designer;
119
+
120
  = 3.0.4 - 2017-10-05 =
121
  * Fixed: dividers and spacers' height can be changed on mouse drag again;
122
 
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInitf2ac8e42169d67a330e26bf73a90dd9b::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInitdb8f6f63fa515bda89036d7745fc67ea::getLoader();
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInitf2ac8e42169d67a330e26bf73a90dd9b
6
  {
7
  private static $loader;
8
 
@@ -19,15 +19,15 @@ class ComposerAutoloaderInitf2ac8e42169d67a330e26bf73a90dd9b
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInitf2ac8e42169d67a330e26bf73a90dd9b', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInitf2ac8e42169d67a330e26bf73a90dd9b', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
- call_user_func(\Composer\Autoload\ComposerStaticInitf2ac8e42169d67a330e26bf73a90dd9b::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
@@ -48,19 +48,19 @@ class ComposerAutoloaderInitf2ac8e42169d67a330e26bf73a90dd9b
48
  $loader->register(true);
49
 
50
  if ($useStaticLoader) {
51
- $includeFiles = Composer\Autoload\ComposerStaticInitf2ac8e42169d67a330e26bf73a90dd9b::$files;
52
  } else {
53
  $includeFiles = require __DIR__ . '/autoload_files.php';
54
  }
55
  foreach ($includeFiles as $fileIdentifier => $file) {
56
- composerRequiref2ac8e42169d67a330e26bf73a90dd9b($fileIdentifier, $file);
57
  }
58
 
59
  return $loader;
60
  }
61
  }
62
 
63
- function composerRequiref2ac8e42169d67a330e26bf73a90dd9b($fileIdentifier, $file)
64
  {
65
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
66
  require $file;
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInitdb8f6f63fa515bda89036d7745fc67ea
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInitdb8f6f63fa515bda89036d7745fc67ea', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInitdb8f6f63fa515bda89036d7745fc67ea', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
+ call_user_func(\Composer\Autoload\ComposerStaticInitdb8f6f63fa515bda89036d7745fc67ea::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
48
  $loader->register(true);
49
 
50
  if ($useStaticLoader) {
51
+ $includeFiles = Composer\Autoload\ComposerStaticInitdb8f6f63fa515bda89036d7745fc67ea::$files;
52
  } else {
53
  $includeFiles = require __DIR__ . '/autoload_files.php';
54
  }
55
  foreach ($includeFiles as $fileIdentifier => $file) {
56
+ composerRequiredb8f6f63fa515bda89036d7745fc67ea($fileIdentifier, $file);
57
  }
58
 
59
  return $loader;
60
  }
61
  }
62
 
63
+ function composerRequiredb8f6f63fa515bda89036d7745fc67ea($fileIdentifier, $file)
64
  {
65
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
66
  require $file;
vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInitf2ac8e42169d67a330e26bf73a90dd9b
8
  {
9
  public static $files = array (
10
  '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
@@ -836,10 +836,10 @@ class ComposerStaticInitf2ac8e42169d67a330e26bf73a90dd9b
836
  public static function getInitializer(ClassLoader $loader)
837
  {
838
  return \Closure::bind(function () use ($loader) {
839
- $loader->prefixLengthsPsr4 = ComposerStaticInitf2ac8e42169d67a330e26bf73a90dd9b::$prefixLengthsPsr4;
840
- $loader->prefixDirsPsr4 = ComposerStaticInitf2ac8e42169d67a330e26bf73a90dd9b::$prefixDirsPsr4;
841
- $loader->prefixesPsr0 = ComposerStaticInitf2ac8e42169d67a330e26bf73a90dd9b::$prefixesPsr0;
842
- $loader->classMap = ComposerStaticInitf2ac8e42169d67a330e26bf73a90dd9b::$classMap;
843
 
844
  }, null, ClassLoader::class);
845
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInitdb8f6f63fa515bda89036d7745fc67ea
8
  {
9
  public static $files = array (
10
  '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
836
  public static function getInitializer(ClassLoader $loader)
837
  {
838
  return \Closure::bind(function () use ($loader) {
839
+ $loader->prefixLengthsPsr4 = ComposerStaticInitdb8f6f63fa515bda89036d7745fc67ea::$prefixLengthsPsr4;
840
+ $loader->prefixDirsPsr4 = ComposerStaticInitdb8f6f63fa515bda89036d7745fc67ea::$prefixDirsPsr4;
841
+ $loader->prefixesPsr0 = ComposerStaticInitdb8f6f63fa515bda89036d7745fc67ea::$prefixesPsr0;
842
+ $loader->classMap = ComposerStaticInitdb8f6f63fa515bda89036d7745fc67ea::$classMap;
843
 
844
  }, null, ClassLoader::class);
845
  }
views/newsletter/templates/blocks/image/block.hbs CHANGED
@@ -1,5 +1,5 @@
1
  <div class="mailpoet_tools"></div>
2
- <div class="mailpoet_content" style="text-align: {{ model.styles.block.textAlign }}; width: {{model.width}}">
3
  <div class="mailpoet_image">
4
  <a href="{{ model.link }}" onClick="return false;">
5
  <img src="{{#ifCond model.src '!=' ''}}{{ model.src }}{{ else }}{{ imageMissingSrc }}{{/ifCond}}" alt="{{ model.alt }}" onerror="if(this.src != '{{ imageMissingSrc }}') {this.src = '{{ imageMissingSrc }}'; this.style.width='auto';}" width="{{model.width}}" />
1
  <div class="mailpoet_tools"></div>
2
+ <div class="mailpoet_content" style="{{#ifCond model.styles.block.textAlign '==' 'left'}}margin: 0 auto 0 0; {{/ifCond}}{{#ifCond model.styles.block.textAlign '==' 'center'}}margin: auto; {{/ifCond}}{{#ifCond model.styles.block.textAlign '==' 'right'}}margin: 0 0 0 auto; {{/ifCond}}width: {{model.width}}">
3
  <div class="mailpoet_image">
4
  <a href="{{ model.link }}" onClick="return false;">
5
  <img src="{{#ifCond model.src '!=' ''}}{{ model.src }}{{ else }}{{ imageMissingSrc }}{{/ifCond}}" alt="{{ model.alt }}" onerror="if(this.src != '{{ imageMissingSrc }}') {this.src = '{{ imageMissingSrc }}'; this.style.width='auto';}" width="{{model.width}}" />
views/newsletter/templates/blocks/image/settings.hbs CHANGED
@@ -27,23 +27,23 @@
27
  <label>
28
  <div class="mailpoet_form_field_title"><%= __('Width') %></div>
29
  <div class="mailpoet_form_field_input_option">
30
- <input
31
  class="mailpoet_input mailpoet_input_small mailpoet_field_image_width_input"
32
- name="image-width-input"
33
- type="number"
34
- value="{{getNumber model.width}}"
35
  min="36"
36
  max="660"
37
- step="2"
38
  /> px
39
- <input
40
- class="mailpoet_range mailpoet_range_small mailpoet_field_image_width"
41
- name="image-width"
42
- type="range"
43
- value="{{getNumber model.width}}"
44
  min="36"
45
  max="660"
46
- step="2"
47
  />
48
  </div>
49
  </label>
@@ -57,6 +57,27 @@
57
  <span id="tooltip-designer-full-width" class="tooltip-help-designer-full-width"></span>
58
  </div>
59
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  <hr />
61
  <div class="mailpoet_form_field">
62
  <input type="button" name="select-another-image" class="button button-secondary mailpoet_button_full mailpoet_field_image_select_another_image" value="<%= __('Select another image') | escape('html_attr') %>" />
27
  <label>
28
  <div class="mailpoet_form_field_title"><%= __('Width') %></div>
29
  <div class="mailpoet_form_field_input_option">
30
+ <input
31
  class="mailpoet_input mailpoet_input_small mailpoet_field_image_width_input"
32
+ name="image-width-input"
33
+ type="number"
34
+ value="{{getNumber model.width}}"
35
  min="36"
36
  max="660"
37
+ step="2"
38
  /> px
39
+ <input
40
+ class="mailpoet_range mailpoet_range_small mailpoet_field_image_width"
41
+ name="image-width"
42
+ type="range"
43
+ value="{{getNumber model.width}}"
44
  min="36"
45
  max="660"
46
+ step="2"
47
  />
48
  </div>
49
  </label>
57
  <span id="tooltip-designer-full-width" class="tooltip-help-designer-full-width"></span>
58
  </div>
59
  </div>
60
+ <div class="mailpoet_form_field">
61
+ <div class="mailpoet_form_field_title"><%= __('Alignment') %></div>
62
+ <div class="mailpoet_form_field_radio_option">
63
+ <label>
64
+ <input type="radio" name="alignment" class="mailpoet_field_image_alignment" value="left" {{#ifCond model.styles.block.textAlign '===' 'left'}}CHECKED{{/ifCond}}/>
65
+ <%= __('Left') %>
66
+ </label>
67
+ </div>
68
+ <div class="mailpoet_form_field_radio_option">
69
+ <label>
70
+ <input type="radio" name="alignment" class="mailpoet_field_image_alignment" value="center" {{#ifCond model.styles.block.textAlign '===' 'center'}}CHECKED{{/ifCond}}/>
71
+ <%= __('Center') %>
72
+ </label>
73
+ </div>
74
+ <div class="mailpoet_form_field_radio_option">
75
+ <label>
76
+ <input type="radio" name="alignment" class="mailpoet_field_image_alignment" value="right" {{#ifCond model.styles.block.textAlign '===' 'right'}}CHECKED{{/ifCond}}/>
77
+ <%= __('Right') %>
78
+ </label>
79
+ </div>
80
+ </div>
81
  <hr />
82
  <div class="mailpoet_form_field">
83
  <input type="button" name="select-another-image" class="button button-secondary mailpoet_button_full mailpoet_field_image_select_another_image" value="<%= __('Select another image') | escape('html_attr') %>" />