PluginProbe
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster / 1.7.9
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster v1.7.9
2.7.0 2.6.0 trunk 1.1.0 1.1.4 1.2.1 1.2.2 1.2.3 1.2.5 1.2.9 1.3.1 1.3.2 1.5.0 1.5.1 1.5.4 1.5.7 1.5.8 1.5.9 1.6.2 1.6.5 1.6.8 1.7.2 1.7.4 1.7.5 1.7.9 All 43 releases
sellkit / assets / dist / js / elementor-init.js

elementor-init.js in SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster 1.7.9, at assets/dist/js/elementor-init.js

4,929 lines 195.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2 "use strict";
3
4 Object.defineProperty(exports, "__esModule", {
5 value: true
6 });
7 exports["default"] = _default;
8
9 var _i18n = require("@wordpress/i18n");
10
11 /* eslint no-undef: 0 */
12 // Temporary turned off no undefined variable for localStorage
13 var $ = jQuery;
14 var wcCountries = JSON.parse(wc_country_select_params.countries);
15
16 function _default() {
17 $('body').addClass('contains-sellkit-checkout'); // General class to handle compatibility with other themes.
18
19 var parent = $('#sellkit-checkout-multistep-inner-wrap');
20 var sidebar = $('.sellkit-checkout-right-column');
21 var first = $('.sellkit-multistep-checkout-first');
22 var second = $('.sellkit-multistep-checkout-second');
23 var third = $('.sellkit-multistep-checkout-third');
24 var breadcrumb = $('.sellkit-checkout-widget-breadcrumb-desktop, .sellkit-checkout-widget-breadcrumb-mobile');
25 var billingMethodA = $('[name="billing-method"].sellkit-billing-method-a');
26
27 if (billingMethodA.length > 0 && billingMethodA[0].checked) {
28 billingMethodA[0].click();
29 }
30
31 if ('1' !== sellkit_elementor.wcNeedShipping || typeof sellkitCheckoutShipping !== 'undefined' && true === sellkitCheckoutShipping) {
32 third.show();
33 $('.sellkit-one-page-checkout-place-order').css('justify-content', 'flex-end');
34 }
35
36 $('.go-to-shipping').on('click', function () {
37 // Checks if required fields are filled.
38 var requiredFieldsError = checkRequiredFields();
39
40 if (true === requiredFieldsError) {
41 return;
42 }
43
44 secondStepHeader();
45 first.hide();
46
47 if ($('.sellkit-one-page-shipping-methods').children().length > 0) {
48 second.show();
49 } else {
50 third.show();
51 } //Fix Header & wrapper height.
52
53
54 parent.css('height', 'auto');
55 second.css('height', 'auto');
56 second.css('min-height', $('.sellkit-checkout-left-column').height());
57 $('.multistep-headers').css('height', 'auto'); // Manage Breadcrumb.
58
59 breadcrumb.find('.information').removeClass('current').addClass('blue-line');
60 breadcrumb.find('.shipping').addClass('current').removeClass('inactive');
61 });
62 $('.go-to-first').on('click', function () {
63 first.show();
64 third.hide();
65 second.hide();
66 parent.css('height', 'auto');
67 first.css('height', 'auto');
68 sidebar.css('background-color', 'transparent'); // Manage Breadcrumb.
69
70 breadcrumb.find('.information').removeClass('blue-line').addClass('current');
71 breadcrumb.find('.shipping, .payment').removeClass('current').removeClass('blue-line').addClass('inactive');
72 });
73 $('.go-to-payment').on('click', function () {
74 // Checks if required fields are filled.
75 var requiredFieldsError = checkRequiredFields();
76
77 if (true === requiredFieldsError) {
78 return;
79 }
80
81 secondStepHeader();
82 second.hide();
83 first.hide();
84 third.show();
85 $('.sellkit-one-page-checkout-payment-heading').css('margin-top', '0px');
86 sidebar.css('background-color', 'transparent'); //Fix Header & wrapper height.
87
88 parent.css('height', 'auto');
89 third.css('height', 'auto');
90 $('.multistep-headers').css('height', 'auto'); // Manage Breadcrumb.
91
92 breadcrumb.find('.shipping').addClass('blue-line').removeClass('current');
93 breadcrumb.find('.payment').addClass('current').removeClass('inactive');
94 });
95 $('.go-to-second , .go-to-second-header').on('click', function () {
96 // Checks if required fields are filled.
97 var requiredFieldsError = checkRequiredFields();
98
99 if (true === requiredFieldsError) {
100 return;
101 }
102
103 if ($('.sellkit-one-page-shipping-methods').children().length > 0) {
104 second.show();
105 first.hide();
106 } else {
107 second.hide();
108 first.show();
109 }
110
111 third.hide();
112 parent.css('height', 'auto');
113 second.css('height', 'auto');
114 second.css('height', $('.sellkit-checkout-left-column').height());
115 $('.multistep-headers').css('height', 'auto'); // Manage Breadcrumb.
116
117 breadcrumb.find('.shipping').addClass('current').removeClass('blue-line');
118 breadcrumb.find('.payment').removeClass('current').addClass('inactive');
119 }); //Inject login wrapper & functionality.
120
121 emailProcess();
122 LoginProcess(); // Billing method toggle.
123
124 manageBillingMethod(); // Mobile summary.
125
126 mobileSummary(); // Breadcrumb click management.
127
128 breadcrumbLinks(); // Fix shipping & billing fields space issue.
129
130 fixFieldSpaceIssue(); // Fields focus.
131
132 organizeFieldsonLoad();
133 fieldFocus();
134 jQuery(document).ajaxComplete(function () {
135 // Run after ajax
136 sellkitCheckoutUpdateCartItem();
137 applyCoupon();
138 couponToggle();
139 fixGatewayListUi();
140 }); // Fix the payment gateways divider issue.
141
142 fixGatewayListUi(); //Run when page loads.
143
144 sellkitCheckoutUpdateCartItem(); // Apply coupon.
145
146 applyCoupon(); // Coupon toggle.
147
148 couponToggle(); // Postal code autocomplete.
149
150 sellkitPostalCodeAutocomplete(); // Klarma checkout integration.
151
152 sellkitKlarmaIntegration(); // Fix state change issue on load.
153
154 fixStateIssueOnLoad(); // Shipping & billing country & state update on change
155
156 fixClientCountryOnReload(); // Configure bundled products.
157
158 sellkitCheckoutConfigureBundleProducts(); // Order bump.
159
160 sellkitCheckoutOrderBump(); // Sellkit after ajax call is completed.
161
162 sellkitAfterAjaxComplete(); // Load upsell steps with popup.
163
164 sellkitLoadUpsellSteps(); // Run some functions on page load when WooCommerce doing early ajax.
165
166 window.sellkitCheckoutMakeSureJsWorks = function () {
167 sellkitCheckoutUpdateCartItem();
168 applyCoupon();
169 couponToggle();
170 fixGatewayListUi();
171 };
172 }
173
174 var emailProcess = function emailProcess() {
175 var emailField = $('#billing_email');
176 var searchIcon = $('.jupiter-checkout-widget-email-search');
177 var errorText = $('.sellkit-checkout-widget-email-error');
178 var emptyError = $('.sellkit-checkout-widget-email-empty');
179 var passwordWrap = $('.sellkit-checkout-widget-password-field');
180 var passwordField = passwordWrap.find('#register_pass');
181 var usernameWrap = $('.sellkit-checkout-widget-username-field');
182 var usernameField = usernameWrap.find('input');
183 var loginBtn = $('.login-wrapper');
184 var createBox = $('.create-desc');
185 var createCheck = $('#createaccount');
186 emailField.on('keyup', function () {
187 var _this = this;
188
189 setTimeout(function () {
190 var emailAddress = $(_this).val();
191
192 if (_.isEmpty(emailAddress)) {
193 emptyError.show().css('display', 'inline-block');
194 errorText.hide();
195 createBox.css('display', 'none');
196 passwordWrap.addClass('login_hidden_section');
197 usernameWrap.addClass('login_hidden_section');
198 loginBtn.addClass('login_hidden_section');
199 searchIcon.hide();
200 return;
201 }
202
203 var check = validateEmailAddress(emailAddress);
204 $('#createaccount').prop('checked', false);
205
206 if (false === check) {
207 errorText.show().css('display', 'inline-block');
208 emptyError.hide();
209 createBox.css('display', 'none');
210 passwordWrap.addClass('login_hidden_section');
211 usernameWrap.addClass('login_hidden_section');
212 loginBtn.addClass('login_hidden_section');
213 searchIcon.hide();
214 return;
215 }
216
217 emptyError.hide();
218 errorText.hide();
219 searchIcon.show().css('display', 'inline-block');
220 wp.ajax.post({
221 action: 'sellkit_checkout_ajax_handler',
222 sub_action: 'search_for_email',
223 email: emailAddress,
224 dataType: 'json',
225 nonce: sellkit_elementor.nonce
226 }).done(function () {
227 successResultEmailCheck();
228 }).fail(function () {
229 errorResultEmailCheck();
230 });
231 }, 500);
232 });
233 usernameField.on('keyup', function () {
234 var _this2 = this;
235
236 setTimeout(function () {
237 var userValue = $(_this2).val();
238 wp.ajax.post({
239 action: 'sellkit_checkout_ajax_handler',
240 sub_action: 'search_for_username',
241 user: userValue,
242 dataType: 'json',
243 nonce: sellkit_elementor.nonce
244 }).done(function () {
245 $('.sellkit-checkout-widget-username-error').hide();
246 }).fail(function () {
247 $('.sellkit-checkout-widget-username-error').show();
248 });
249 }, 500);
250 }); // If user is going to create account show password and username fields if exists.
251
252 createCheck.on('click', function () {
253 if ($(this).is(':checked')) {
254 if (passwordField.length > 0) {
255 passwordWrap.removeClass('login_hidden_section');
256 }
257
258 if (usernameField.length > 0) {
259 usernameWrap.removeClass('login_hidden_section');
260 }
261 } else {
262 usernameWrap.addClass('login_hidden_section');
263 passwordWrap.addClass('login_hidden_section');
264 }
265 });
266
267 var successResultEmailCheck = function successResultEmailCheck() {
268 createBox.css('display', 'none');
269 passwordWrap.removeClass('login_hidden_section');
270 usernameWrap.addClass('login_hidden_section');
271 loginBtn.removeClass('login_hidden_section');
272 searchIcon.hide();
273 };
274
275 var errorResultEmailCheck = function errorResultEmailCheck() {
276 createBox.css('display', 'flex');
277 passwordWrap.addClass('login_hidden_section');
278 usernameWrap.addClass('login_hidden_section');
279 loginBtn.addClass('login_hidden_section');
280 searchIcon.hide();
281 };
282 };
283
284 var validateEmailAddress = function validateEmailAddress(emailAddress) {
285 var pattern = /^([a-z\d!#$%&'*+\-\/=?^_`{|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+(\.[a-z\d!#$%&'*+\-\/=?^_`{|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)*|"((([ \t]*\r\n)?[ \t]+)?([\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]))*(([ \t]*\r\n)?[ \t]+)?")@(([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;
286 return pattern.test(emailAddress);
287 };
288
289 var LoginProcess = function LoginProcess() {
290 var submitBtn = $('.login-submit');
291 var email = $('.login-mail');
292 var pass = $('.login-pass');
293 var result = $('.login-result');
294 submitBtn.on('click', function () {
295 if ('' === email.val() || '' === pass.val()) {
296 result.text((0, _i18n.__)('Both Field required.', 'sellkit')).css({
297 color: 'red'
298 });
299 return;
300 }
301
302 wp.ajax.post({
303 beforeSend: function beforeSend() {
304 $('.login-submit').css('opacity', '0.5');
305 },
306 action: 'sellkit_checkout_ajax_handler',
307 sub_action: 'auth_user',
308 email: email.val(),
309 pass: pass.val(),
310 nonce: sellkit_elementor.nonce
311 }).done(function () {
312 location.reload();
313 }).fail(function (response) {
314 $('.login-submit').css('opacity', '1');
315 $('.login-result').html(response).css({
316 color: 'red'
317 });
318 });
319 });
320 };
321
322 var secondStepHeader = function secondStepHeader() {
323 var email = $('#billing_email');
324 $('.multistep-headers > .info-a > div > .mail').text(email.val());
325 var countryValue = $('#shipping_country option:selected').text();
326 var state = $('#sellkit-shipping_state');
327 var postcode = $('#shipping_postcode');
328 var city = $('#shipping_city');
329 var addressA = $('#shipping_address_1');
330 var addressB = $('#shipping_address_2');
331 var finalAddress = postcode.val() ? ', ' + postcode.val() : '';
332 finalAddress += addressB.val() ? ', ' + addressB.val() : '';
333 finalAddress += addressA.val() ? ', ' + addressA.val() : '';
334 finalAddress += city.val() ? ', ' + city.val() : '';
335 finalAddress += state.val() ? ', ' + state.val() : '';
336 finalAddress += countryValue && !countryValue.includes('/') ? ', ' + countryValue : '';
337
338 if (',' === finalAddress.charAt(0)) {
339 finalAddress = finalAddress.substring(1);
340 }
341
342 $('.multistep-headers > .info-b > div > .address').text(finalAddress);
343 var method = $('#shipping_method').find('input[type=radio]:checked');
344 var methodTxt = method.siblings('.labels').text();
345 $('.multistep-headers > .info-c > div > .method').text(methodTxt);
346 };
347
348 var manageBillingMethod = function manageBillingMethod() {
349 var billingWrap = $('.sellkit-one-page-checkout-billing');
350 var methodA = billingWrap.find('.method-a');
351 var methodB = billingWrap.find('.method-b'); // Get shipping values.
352
353 var name = $('#shipping_first_name');
354 var last = $('#shipping_last_name');
355 var addressA = $('#shipping_address_1');
356 var addressB = $('#shipping_address_2');
357 var country = $('#shipping_country');
358 var state = $('#sellkit-shipping_state');
359 var postcode = $('#shipping_postcode');
360 var city = $('#shipping_city');
361 methodA.on('click', function () {
362 billingWrap.find('.woocommerce-billing-fields__field-wrapper').hide();
363 $('#billing_first_name').val(name.val());
364 $('#billing_last_name').val(last.val());
365 $('#billing_address_1').val(addressA.val());
366 $('#billing_address_2').val(addressB.val());
367 $('#billing_country').val(country.val()).trigger('change');
368 $('#sellkit-billing_state').val(state.val()).trigger('change');
369 $('#billing_postcode').val(postcode.val());
370 $('#billing_city').val(city.val());
371 });
372 methodB.on('click', function () {
373 $('.inner_wrapper').css('height', 'auto');
374 billingWrap.find('.woocommerce-billing-fields__field-wrapper').css('display', 'inline-table');
375 });
376 };
377
378 var mobileSummary = function mobileSummary() {
379 if ($(window).width() < 600) {
380 $('#order_review').addClass('sellkit-mobile-multistep-order-summary');
381 }
382
383 var toggleBtn = $('.summary_toggle > .title, .summary_toggle > i, .summary_toggle > .icon');
384 var wrap = $('.summary_toggle');
385 toggleBtn.on('click', function () {
386 $('#order_review').toggle();
387
388 if ('Hide order summary' === toggleBtn.text()) {
389 wrap.find('.title').text((0, _i18n.__)('Show order summary', 'sellkit'));
390 wrap.find('i').addClass('fa-chevron-down').removeClass('fa-chevron-up');
391 wrap.css('border-bottom-width', '0px');
392 } else {
393 wrap.find('.title').text((0, _i18n.__)('Hide order summary', 'sellkit'));
394 wrap.find('i').addClass('fa-chevron-up').removeClass('fa-chevron-down');
395 wrap.css('border-bottom-width', '1px');
396 }
397
398 var parent = $('#sellkit-checkout-multistep-inner-wrap');
399 parent.css('height', 'auto');
400 });
401 };
402
403 var fieldFocus = function fieldFocus() {
404 var $fields = $('.sellkit-checkout-local-fields').find('input, select, hidden, textarea, #sellkit-billing_state ,#sellkit-shipping_state, .validate-email');
405 $fields.each(function () {
406 var _this3 = this;
407
408 var miniTitle = $(this).parent().parent().parent().find('.mini-title');
409 var $thisValue = $(this).val(); // On load.
410
411 if (!_.isEmpty($thisValue)) {
412 $(this).addClass('filled').removeClass('empty');
413 miniTitle.css({
414 display: 'flex'
415 });
416 } // On change/focusOut
417
418
419 $(this).on('change input focusout', function (e) {
420 var changedValue = $(_this3).val();
421
422 if (changedValue || $(_this3).find('option').length) {
423 $(_this3).addClass('filled');
424 $(_this3).removeClass('empty');
425 $(_this3).parents('.sellkit-widget-checkout-fields').find('.mini-title').css('display', 'flex');
426 } else {
427 $(_this3).addClass('empty');
428 $(_this3).removeClass('filled');
429 $(_this3).parents('.sellkit-widget-checkout-fields').find('.mini-title').hide();
430 } // On focusout validate fields.
431
432
433 if ('focusout' === e.type) {
434 FieldsMiniTitles($(_this3), 'focusout');
435 var parent = $(_this3).parent().parent().parent(); // Required validation. return if required field rule is not followed.
436
437 if (parent.hasClass('validate-required')) {
438 if ('INPUT' === _this3.nodeName && 'checkbox' === $(_this3).attr('type')) {
439 if (!_this3.checked) {
440 parent.find('.sellkit-required-validation').css('display', 'inline-flex');
441 return;
442 }
443 }
444
445 if (_.isEmpty($(_this3).val())) {
446 parent.find('.sellkit-required-validation').css('display', 'inline-flex');
447 return;
448 }
449
450 parent.find('.sellkit-required-validation').css('display', 'none');
451 } // Required validation of this field if exists, passed successfully. now postcode validation.
452
453
454 if (parent.hasClass('sellkit-checkout-fields-validation-postcode')) {
455 var postcodeVal = $(_this3).val();
456
457 if (_.isEmpty(postcodeVal)) {
458 return;
459 } // Check field type to get related country value. we can't validate without country code.
460
461
462 var postcodeName = $(_this3).attr('name');
463 var postcodeCountry = $('#billing_country');
464
465 if (postcodeName.includes('shipping')) {
466 postcodeCountry = $('#shipping_country');
467 } // Keep validating only if country field is present.
468
469
470 if (!postcodeCountry.length) {
471 return;
472 }
473
474 var countryCode = postcodeCountry.val();
475
476 if (_.isEmpty(countryCode)) {
477 parent.find('.sellkit-checkout-field-global-errors').show().text((0, _i18n.__)('Please select a country.', 'sellkit'));
478 return;
479 } else {
480 // eslint-disable-line
481 parent.find('.sellkit-checkout-field-global-errors').hide().text('');
482 }
483
484 parent.find('.sellkit-checkout-field-global-errors').hide().text('');
485 postcodeValidation(postcodeVal, countryCode, $(_this3));
486 } // Phone validation using woocommerce way.
487
488
489 if (parent.hasClass('sellkit-checkout-fields-validation-phone')) {
490 var phone = $(_this3).val();
491
492 if (_.isEmpty(phone)) {
493 return;
494 }
495
496 phoneNumberValidation(phone, $(_this3));
497 }
498 }
499
500 if ('change' === e.type && ('billing_country' === $(_this3).attr('id') || 'shipping_country' === $(_this3).attr('id'))) {
501 var _countryCode = $(_this3).val();
502
503 var states = wcCountries[_countryCode];
504 var state = 'sellkit-shipping_state';
505
506 if ('billing_country' === $(_this3).attr('id')) {
507 state = 'sellkit-billing_state';
508 }
509
510 var stateField = document.getElementById(state);
511
512 if (_.isNull(stateField)) {
513 return;
514 }
515
516 $(stateField).empty();
517
518 for (var keys in states) {
519 var option = document.createElement('option');
520 option.value = keys;
521 option.innerHTML = states[keys];
522 stateField.appendChild(option);
523 }
524 }
525 });
526 });
527 };
528
529 var breadcrumbLinks = function breadcrumbLinks() {
530 var $parent = $('.sellkit-checkout-widget-breadcrumb-mobile, .sellkit-checkout-widget-breadcrumb-desktop');
531 var detector = $('.sellkit-multistep-checkout-first');
532 $parent.find('.information').on('click', function () {
533 $('.go-to-first').click();
534 });
535 $parent.find('.shipping').on('click', function () {
536 var display = detector.css('display');
537
538 if ('none' === display) {
539 $('.go-to-second').click();
540 } else {
541 $('.go-to-shipping').click();
542 }
543 });
544 $parent.find('.payment').on('click', function () {
545 $('.go-to-payment').click();
546 $('.information').removeClass('current').addClass('inactive, blue-line');
547 });
548 };
549
550 var fixFieldSpaceIssue = function fixFieldSpaceIssue() {
551 $(function () {
552 var shippingFields = $('#customer_details .sellkit-widget-checkout-fields');
553 shippingFields.each(function (index) {
554 if ($(shippingFields[index + 1]).length) {
555 var next = $(shippingFields[index + 1]).offset().top;
556 var current = $(shippingFields[index]).offset().top;
557
558 if (next > current) {
559 $(shippingFields[index]).addClass('sellkit-checkout-excluded-wrapper-fields');
560 }
561 } else {
562 $(shippingFields[index]).addClass('sellkit-checkout-excluded-wrapper-fields');
563 }
564 });
565 });
566 };
567
568 var organizeFieldsonLoad = function organizeFieldsonLoad() {
569 $(function () {
570 var fields = $('.sellkit-widget-checkout-fields').find('input, select, textarea');
571 fields.each(function () {
572 var tag = this.nodeName;
573
574 if ('SELECT' === tag) {
575 $(this).parent().parent().parent().addClass('sellkit-checkout-field-select');
576 }
577
578 FieldsMiniTitles($(this), 'load');
579 });
580 });
581 $(document).on('mousemove change', function (e) {
582 var fields = $('.sellkit-widget-checkout-fields').find('input, select, textarea');
583 fields.each(function () {
584 var tag = this.nodeName;
585
586 if ('SELECT' === tag) {
587 $(this).parent().parent().parent().addClass('sellkit-checkout-field-select');
588 }
589
590 FieldsMiniTitles($(this), e.type);
591 });
592 });
593 };
594
595 var FieldsMiniTitles = function FieldsMiniTitles(field, event) {
596 if (field.attr('multiple')) {
597 field.addClass('filled');
598 field.removeClass('empty');
599 field.parents('.sellkit-widget-checkout-fields').find('.mini-title').css('display', 'flex');
600 return;
601 }
602
603 if (_.isEmpty(field.val())) {
604 field.addClass('empty');
605 field.removeClass('filled');
606 field.parents('.sellkit-widget-checkout-fields').find('.mini-title').css('display', 'none');
607 } else {
608 field.addClass('filled');
609 field.removeClass('empty');
610 field.parents('.sellkit-widget-checkout-fields').find('.mini-title').css('display', 'flex');
611 } // Hide wrapper if field is hidden
612
613
614 if ('hidden' === field.attr('type')) {
615 field.parents('.sellkit-widget-checkout-fields').addClass('sellkit-hide-completely');
616 }
617
618 if ('change' !== event) {
619 return;
620 } // Hide Billing state wrapper when these fields are hidden.
621
622
623 if ('billing_country' === field.attr('id')) {
624 var $state = document.getElementById('sellkit-billing_state');
625
626 if (!_.isNull($state) && 'SELECT' === $state.nodeName && $('#sellkit-billing_state option').length < 1) {
627 var stateField = $('#sellkit-billing_state');
628 var parent = stateField.parent().parent().parent();
629 parent.removeClass('sellkit-checkout-field-select');
630 var placeholder = stateField.attr('placeholder');
631 var stateInput = document.createElement('input');
632 stateInput.setAttribute('type', 'text');
633 stateInput.setAttribute('id', 'sellkit-billing_state');
634 stateInput.setAttribute('name', 'billing_state');
635 stateInput.setAttribute('placeholder', placeholder); // Replace select field with text.
636
637 stateField.remove();
638 parent.find('.woocommerce-input-wrapper').append(stateInput);
639 }
640
641 var countryCode = field.val();
642 var states = wcCountries[countryCode];
643
644 if (!_.isNull($state) && 'INPUT' === $state.nodeName && !_.isEmpty(states)) {
645 var _stateField = $('#sellkit-billing_state');
646
647 var _placeholder = _stateField.attr('placeholder');
648
649 var _parent = _stateField.parent().parent().parent();
650
651 _parent.addClass('sellkit-checkout-field-select');
652
653 if (_.isUndefined(_placeholder) || _.isEmpty(_placeholder)) {
654 _placeholder = (0, _i18n.__)('State', 'sellkit');
655 } // Replace text field with select field.
656
657
658 _stateField.remove();
659
660 var stateSelect = document.createElement('select');
661 stateSelect.setAttribute('name', 'billing_state');
662 stateSelect.setAttribute('id', 'sellkit-billing_state');
663 stateSelect.setAttribute('placeholder', _placeholder);
664 stateSelect.addEventListener('change', function () {
665 sellkitSetAddressDetails();
666 });
667
668 for (var keys in states) {
669 var option = document.createElement('option');
670 option.value = keys;
671 option.innerHTML = states[keys];
672 stateSelect.appendChild(option);
673 }
674
675 _parent.find('.woocommerce-input-wrapper').append(stateSelect);
676 }
677 } // Remove select icon when field is text for the shipping/billing state fields.
678
679
680 if ('shipping_country' === field.attr('id')) {
681 var _$state = document.getElementById('sellkit-shipping_state');
682
683 if (!_.isNull(_$state) && 'SELECT' === _$state.nodeName && $('#sellkit-shipping_state option').length < 1) {
684 var _stateField2 = $('#sellkit-shipping_state');
685
686 var _parent2 = _stateField2.parent().parent().parent();
687
688 _parent2.removeClass('sellkit-checkout-field-select');
689
690 var _placeholder2 = _stateField2.attr('placeholder');
691
692 var _stateInput = document.createElement('input');
693
694 _stateInput.setAttribute('type', 'text');
695
696 _stateInput.setAttribute('id', 'sellkit-shipping_state');
697
698 _stateInput.setAttribute('name', 'shipping_state');
699
700 _stateInput.setAttribute('placeholder', _placeholder2); // Replace select field with text.
701
702
703 _stateField2.remove();
704
705 _parent2.find('.woocommerce-input-wrapper').append(_stateInput);
706 }
707
708 var _countryCode2 = field.val();
709
710 var _states = wcCountries[_countryCode2];
711
712 if (!_.isNull(_$state) && 'INPUT' === _$state.nodeName && !_.isEmpty(_states)) {
713 var _stateField3 = $('#sellkit-shipping_state');
714
715 var _placeholder3 = _stateField3.attr('placeholder');
716
717 var _parent3 = _stateField3.parent().parent().parent();
718
719 _parent3.addClass('sellkit-checkout-field-select');
720
721 if (_.isUndefined(_placeholder3) || _.isEmpty(_placeholder3)) {
722 _placeholder3 = (0, _i18n.__)('State', 'sellkit');
723 } // Replace text field with select field.
724
725
726 _stateField3.remove();
727
728 var _stateSelect = document.createElement('select');
729
730 _stateSelect.setAttribute('name', 'shipping_state');
731
732 _stateSelect.setAttribute('id', 'sellkit-shipping_state');
733
734 _stateSelect.setAttribute('placeholder', _placeholder3);
735
736 _stateSelect.addEventListener('change', function () {
737 sellkitSetAddressDetails();
738 });
739
740 for (var _keys in _states) {
741 var _option = document.createElement('option');
742
743 _option.value = _keys;
744 _option.innerHTML = _states[_keys];
745
746 _stateSelect.appendChild(_option);
747 }
748
749 _parent3.find('.woocommerce-input-wrapper').append(_stateSelect);
750 }
751 }
752 };
753 /**
754 * Change cart item quantity.
755 *
756 * @since 1.2.5
757 */
758
759
760 var sellkitCheckoutUpdateCartItem = function sellkitCheckoutUpdateCartItem() {
761 $('.sellkit-one-page-checkout-product-qty').off('change').on('change', function () {
762 $(this).attr('readonly', true);
763 wp.ajax.post({
764 action: 'sellkit_checkout_ajax_handler',
765 sub_action: 'change_cart_item_qty',
766 qty: $(this).val(),
767 id: $(this).attr('data-id'),
768 mode: 'edit',
769 related_checkout: $('#sellkit_current_page_id').val(),
770 nonce: sellkit_elementor.nonce
771 }).always(function () {
772 $(document.body).trigger('update_checkout');
773 $('.sellkit-one-page-checkout-product-qty').attr('readonly', false);
774 });
775 });
776 var paymentMethod = $('.sellkit-one-page-checkout-payment-methods').find('input[name=payment_method]:checked');
777 paymentMethod.parent().parent().next().show();
778 $('.sellkit-one-page-pay-method').on('click', function () {
779 $('.sellkit_payment_box').hide();
780 $(this).parent().parent().next().show();
781 });
782 var count = $('.sellkit-checkout-widget-order-summary-tfoot').children().length;
783
784 if (count <= 3) {
785 $('.cart-subtotal td').css('padding-bottom', '8px');
786 $('.cart-subtotal th').css('padding-bottom', '8px');
787 }
788 };
789 /**
790 * Apply a coupon.
791 *
792 * @since 1.2.5
793 */
794
795
796 var applyCoupon = function applyCoupon() {
797 $('.sellkit-apply-coupon').off('click').on('click', function () {
798 wp.ajax.post({
799 beforeSend: function beforeSend() {
800 $('.jx-apply-coupon').css('opacity', 0.5);
801 },
802 action: 'sellkit_checkout_ajax_handler',
803 sub_action: 'apply_coupon',
804 code: jQuery('.sellkit-custom-coupon-form').find('.jx-coupon').val(),
805 nonce: sellkit_elementor.nonce
806 }).done(function () {
807 $(document.body).trigger('update_checkout');
808 $('.jx-apply-coupon').css('opacity', 1);
809 }).fail(function () {
810 $('.jx-apply-coupon').css('opacity', 1);
811 });
812 });
813 };
814 /**
815 * Toggle coupon form on click event.
816 *
817 * @since 1.2.5
818 */
819
820
821 var couponToggle = function couponToggle() {
822 if ($('.sellkit-coupon-toggle').length) {
823 $('.sellkit-custom-coupon-form').css('display', 'none');
824 }
825
826 $('.sellkit-coupon-toggle').off('click').on('click', function () {
827 var direction = 'row';
828 var status = $('.sellkit-custom-coupon-form').css('display');
829 var displayValue = '';
830
831 if ($(window).width() < 600) {
832 direction = 'column';
833 }
834
835 if ('none' === status) {
836 displayValue = 'inline-flex';
837 } else {
838 displayValue = 'none';
839 }
840
841 $('.sellkit-custom-coupon-form').css({
842 display: displayValue,
843 flexDirection: direction
844 });
845 });
846 };
847 /**
848 * Validate postcode in WooCommerce way.
849 *
850 * @param {string} postcode
851 * @param {string} country
852 * @param {Object} element
853 */
854
855
856 var postcodeValidation = function postcodeValidation(postcode, country, element) {
857 var parentElement = element.attr('id');
858 wp.ajax.post({
859 action: 'sellkit_checkout_ajax_handler',
860 sub_action: 'validate_postcode',
861 post_code: postcode,
862 country_code: country,
863 parent: parentElement,
864 nonce: sellkit_elementor.nonce
865 }).done(function (response) {
866 var field = $('#' + response);
867 var parent = field.parent().parent().parent();
868 parent.find('.sellkit-checkout-field-global-errors').hide().text('');
869 }).fail(function (response) {
870 var field = $('#' + response);
871 var parent = field.parent().parent().parent();
872 parent.find('.sellkit-checkout-field-global-errors').show().text((0, _i18n.__)('Postcode is not valid.', 'sellkit'));
873 });
874 };
875 /**
876 * Validate phone number in WooCommerce way.
877 *
878 * @param {string} phone
879 * @param {Object} element
880 */
881
882
883 var phoneNumberValidation = function phoneNumberValidation(phone, element) {
884 var parentElement = element.attr('id');
885 wp.ajax.post({
886 action: 'sellkit_checkout_ajax_handler',
887 sub_action: 'validate_phone_number',
888 phone_number: phone,
889 parent: parentElement,
890 nonce: sellkit_elementor.nonce
891 }).done(function (response) {
892 var field = $('#' + response);
893 var parent = field.parent().parent().parent();
894 parent.find('.sellkit-checkout-field-global-errors').hide().text('');
895 }).fail(function (response) {
896 var field = $('#' + response);
897 var parent = field.parent().parent().parent();
898 parent.find('.sellkit-checkout-field-global-errors').show().text((0, _i18n.__)('Phone number is not valid.', 'sellkit'));
899 });
900 };
901 /**
902 * Auto populate city and state fields using postcode by getting information from third api : https://api.zippopotam.us/.
903 *
904 * @since 1.2.5
905 */
906
907
908 var sellkitPostalCodeAutocomplete = function sellkitPostalCodeAutocomplete() {
909 $('.post_code_autocomplete').find('input').on('paste focusout', function () {
910 var postcode = $(this).val();
911 var country = $('#shipping_country').val();
912 var state = $('#sellkit-shipping_state');
913 var city = $('#shipping_city');
914 var parent = $(this).parent().parent().parent();
915
916 if ('billing_postcode' === $(this).attr('id')) {
917 country = $('#billing_country').val();
918 state = $('#sellkit-billing_state');
919 city = $('#billing_city');
920 }
921
922 if (_.isEmpty(postcode) || _.isEmpty(country)) {
923 return;
924 }
925
926 wp.ajax.post({
927 action: 'sellkit_checkout_ajax_handler',
928 sub_action: 'sellkit_state_lookup_by_postcode',
929 country_value: country,
930 postcode_value: postcode,
931 nonce: sellkit_elementor.nonce
932 }).done(function (response) {
933 setError('');
934 var body = response;
935 var placeCity = body.places[0]['place name'];
936 var placeState = body.places[0]['state abbreviation'];
937 var countryResponse = body['country abbreviation'];
938
939 if (_.isEmpty(placeState)) {
940 placeState = body.places[0].state;
941 }
942
943 var countries = ['DE', 'TR', 'BD', 'DO', 'GB', 'GT', 'JP', 'TH', 'ZA'];
944
945 if (countries.includes(countryResponse)) {
946 placeState = fixConflictWooCommerceStatesWithApi(countryResponse, placeState, body);
947 }
948
949 setFields(placeCity, placeState);
950 }).fail(function (response) {
951 setError(response);
952 });
953
954 var setFields = function setFields(placeCity, placeState) {
955 state.val(placeState).addClass('filled');
956 city.val(placeCity).addClass('filled');
957
958 if (null === state.val() && 'SELECT' === state[0].nodeName) {
959 state.prop('selectedIndex', 0);
960 }
961 };
962
963 var setError = function setError(response) {
964 parent.find('.sellkit-checkout-field-global-errors').text(response);
965 };
966 });
967 };
968 /**
969 * Fix some countries states conflict between WooCommerce and https://api.zippopotam.us/.
970 *
971 * @param {string} country response country.
972 * @param {string} state response state.
973 * @param {Object} body response body.
974 * @return {string} state.
975 */
976
977
978 var fixConflictWooCommerceStatesWithApi = function fixConflictWooCommerceStatesWithApi(country, state, body) {
979 switch (country) {
980 case 'TR':
981 // Turkey.
982 state = 'TR' + state;
983 break;
984
985 case 'DE':
986 // Germany.
987 state = 'DE-' + state;
988 break;
989
990 case 'BD':
991 // Bangladesh.
992 state = sellkitCheckoutCountryFixAutoPopulate(state, country, body);
993 break;
994
995 case 'DO':
996 // Dominican Republic. Api has no proper response. we select first option
997 state = 'DO-01';
998 break;
999
1000 case 'GB':
1001 // United kingdom.
1002 state = body.places[0].state;
1003 break;
1004
1005 case 'GT':
1006 // Guatemala.
1007 state = 'GT-AV';
1008 break;
1009
1010 case 'JP':
1011 // Japan.
1012 state = sellkitCheckoutCountryFixAutoPopulate(state, country, body);
1013 break;
1014
1015 case 'TH':
1016 // Thailand.
1017 state = sellkitCheckoutCountryFixAutoPopulate(state, country, body);
1018 break;
1019
1020 case 'ZA':
1021 // South Africa. API has no proper response. we select first option.
1022 state = 'EC';
1023 break;
1024
1025 default:
1026 return state;
1027 }
1028
1029 return state;
1030 };
1031 /**
1032 * Integration with Klarma checkout gateway.
1033 *
1034 * @since 1.2.5
1035 */
1036
1037
1038 var sellkitKlarmaIntegration = function sellkitKlarmaIntegration() {
1039 $(document).ready(function () {
1040 $('#sellkit-klarna-pay-button').on('click', function () {
1041 $('#payment_method_kco').trigger('click');
1042 });
1043 });
1044 };
1045 /**
1046 * Save client state and country on change event.
1047 *
1048 * @since 1.2.5
1049 */
1050
1051
1052 var fixClientCountryOnReload = function fixClientCountryOnReload() {
1053 $('#shipping_country, #billing_country, #sellkit-shipping_state, #sellkit-billing_state').on('change', function () {
1054 sellkitSetAddressDetails();
1055 });
1056 };
1057 /**
1058 * Ajax to save user state and country for both shipping and billing section if those fields are present.
1059 *
1060 * @since 1.2.5
1061 */
1062
1063
1064 var sellkitSetAddressDetails = function sellkitSetAddressDetails() {
1065 wp.ajax.post({
1066 action: 'sellkit_checkout_ajax_handler',
1067 sub_action: 'set_customer_details_ajax',
1068 country: document.querySelector('#billing_country') ? document.getElementById('billing_country').value : '',
1069 state: document.querySelector('#sellkit-billing_state') ? document.getElementById('sellkit-billing_state').value : '',
1070 shipping_country: document.querySelector('#shipping_country') ? document.getElementById('shipping_country').value : '',
1071 shipping_state: document.querySelector('#sellkit-shipping_state') ? document.getElementById('sellkit-shipping_state').value : '',
1072 nonce: sellkit_elementor.nonce
1073 }).always(function () {
1074 $(document.body).trigger('update_checkout');
1075 });
1076 };
1077 /**
1078 * On page load set shipping and billing state & country values.
1079 *
1080 * @since 1.2.5
1081 */
1082
1083
1084 var fixStateIssueOnLoad = function fixStateIssueOnLoad() {
1085 var primaryValue = '';
1086
1087 if (document.querySelector('#shipping_country')) {
1088 primaryValue = $('#shipping_country').val();
1089 $('#shipping_country').val($('#shipping_country option:eq(1)').val());
1090 $('#shipping_country').val(primaryValue).trigger('change');
1091 }
1092
1093 if (document.querySelector('#billing_country')) {
1094 primaryValue = $('#billing_country').val();
1095 $('#billing_country').val($('#billing_country option:eq(1)').val());
1096 $('#billing_country').val(primaryValue).trigger('change');
1097 }
1098 };
1099 /**
1100 * Modify cart items when bundle products are present.
1101 *
1102 * @since 1.2.5
1103 */
1104
1105
1106 var sellkitCheckoutConfigureBundleProducts = function sellkitCheckoutConfigureBundleProducts() {
1107 bundleProductOnQuantityChange();
1108 var radioProducts = $('.sellkit-checkout-bundle-item');
1109 radioProducts.off('change').on('change', function () {
1110 var addType = $(this).attr('type'); // On bundle product change, modify bump too.
1111
1112 $('.sellkit-checkout-bump-order-products').each(function () {
1113 if ($(this).is(':checked') && 'radio' === addType) {
1114 $(this).trigger('click');
1115 }
1116 });
1117 var product = $(this).val();
1118 var quantity = $(this).parent().parent().find('.sellkit-checkout-single-bundle-item-quantity').val();
1119 var checkout = $('#sellkit_current_page_id').val();
1120 var modifyType = 'add';
1121
1122 if (false === $(this).is(':checked')) {
1123 modifyType = 'remove';
1124 }
1125
1126 wp.ajax.post({
1127 action: 'sellkit_checkout_ajax_handler',
1128 sub_action: 'sellkit_checkout_modify_cart_by_bundle_products',
1129 id: product,
1130 qty: quantity,
1131 checkout_id: checkout,
1132 type: addType,
1133 modify: modifyType,
1134 nonce: sellkit_elementor.nonce
1135 }).always(function () {
1136 $(document.body).trigger('update_checkout');
1137 });
1138 });
1139 };
1140 /**
1141 * Change cart item quantity on bundle product quantity change.
1142 *
1143 * @since 1.3.1
1144 */
1145
1146
1147 var bundleProductOnQuantityChange = function bundleProductOnQuantityChange() {
1148 $('.sellkit-checkout-single-bundle-item-quantity').on('change', function () {
1149 var productCartKey = $(this).attr('data-id');
1150 var quantity = $(this).val();
1151
1152 if (false === $(this).parent().parent().find('.sellkit-checkout-bundle-item').is(':checked')) {
1153 return;
1154 }
1155
1156 wp.ajax.post({
1157 action: 'sellkit_checkout_ajax_handler',
1158 sub_action: 'sellkit_checkout_modify_cart_by_bundle_products',
1159 key: productCartKey,
1160 qty: quantity,
1161 nonce: sellkit_elementor.nonce
1162 }).always(function () {
1163 $(document.body).trigger('update_checkout');
1164 });
1165 });
1166 };
1167 /**
1168 * Manage to add or remove a bump product from cart.
1169 *
1170 * @since 1.2.5
1171 */
1172
1173
1174 var sellkitCheckoutOrderBump = function sellkitCheckoutOrderBump() {
1175 $('.sellkit-checkout-bump-order-products').on('click', function () {
1176 var subAction;
1177
1178 if ($(this).is(':checked')) {
1179 subAction = 'add';
1180 } else {
1181 subAction = 'remove';
1182 }
1183
1184 wp.ajax.post({
1185 action: 'sellkit_checkout_ajax_handler',
1186 sub_action: 'change_cart_item_qty',
1187 qty: $(this).attr('data-qty'),
1188 id: $(this).val(),
1189 mode: subAction,
1190 related_checkout: $('#sellkit_current_page_id').val(),
1191 nonce: sellkit_elementor.nonce
1192 }).always(function () {
1193 $(document.body).trigger('update_checkout');
1194 });
1195 });
1196 };
1197 /**
1198 * Checks if a required field is not filled.
1199 *
1200 * @return {boolean} state of error.
1201 * @since 1.2.5
1202 */
1203
1204
1205 var checkRequiredFields = function checkRequiredFields() {
1206 var fields = document.querySelectorAll('#sellkit-checkout-widget-shipping-fields > .validate-required');
1207 var error = false; // Let's check email field first.
1208
1209 if (_.isEmpty($('#billing_email').val())) {
1210 $('.sellkit-checkout-widget-email-empty').css('display', 'block');
1211 return true;
1212 } // Hide warning after filling email field.
1213
1214
1215 $('.sellkit-checkout-widget-email-empty').css('display', 'none');
1216
1217 if (fields.length < 1) {
1218 return error;
1219 }
1220
1221 fields.forEach(function (item) {
1222 var target = $(item).find('input, select, textarea').val();
1223
1224 if ('' === target) {
1225 error = true;
1226 $(item).find('.sellkit-required-validation').css('display', 'inline-flex');
1227 }
1228 });
1229 return error;
1230 };
1231 /**
1232 * Loop through WooCommerce states and replace api returned value.
1233 *
1234 * @param {string} state
1235 * @param {string} countryAbbreviated
1236 * @param {Object} body
1237 * @return {string} state value.
1238 * @since 1.2.5
1239 */
1240
1241
1242 var sellkitCheckoutCountryFixAutoPopulate = function sellkitCheckoutCountryFixAutoPopulate(state, countryAbbreviated, body) {
1243 var value = '';
1244 var country = '';
1245
1246 if ('BD' === countryAbbreviated) {
1247 country = wcCountries.BD;
1248 }
1249
1250 if ('JP' === countryAbbreviated) {
1251 country = wcCountries.JP;
1252 state = state.substring(0, state.length - 3);
1253 }
1254
1255 if ('TH' === countryAbbreviated) {
1256 value = 'TH-37';
1257 country = wcCountries.TH;
1258 state = body.places[0].state;
1259 }
1260
1261 for (var key in country) {
1262 if (state === country[key]) {
1263 value = key;
1264 }
1265 }
1266
1267 return value;
1268 };
1269
1270 var sellkitAfterAjaxComplete = function sellkitAfterAjaxComplete() {
1271 $('#place_order').on('click', function () {
1272 var count = 0;
1273 var transfer = setInterval(function () {
1274 count += 1;
1275
1276 if ($('.wc_payment_method > .woocommerce-NoticeGroup-checkout').length > 0) {
1277 // Remove notice from payment area and move it to top of page( default error area ).
1278 var notice = $('.wc_payment_method').find('.woocommerce-NoticeGroup-checkout').html();
1279 $('.wc_payment_method').find('.woocommerce-NoticeGroup-checkout').remove();
1280 $('.woocommerce-notices-wrapper').first().append(notice);
1281 $(document.body).animate({
1282 scrollTop: $('.woocommerce-notices-wrapper').offset().top - 100
1283 }, 500); // Stop interval.
1284
1285 clearInterval(transfer);
1286 }
1287
1288 if (count > 20) {
1289 clearInterval(transfer);
1290 }
1291 }, 500);
1292 });
1293 };
1294 /**
1295 * Hide payment gateways <hr> divider properly after ajax calls.
1296 * This could not be done with css.
1297 *
1298 * @since 1.5.4
1299 */
1300
1301
1302 var fixGatewayListUi = function fixGatewayListUi() {
1303 $('.wc_payment_methods hr.sellkit-checkout-widget-divider').each(function (index, item) {
1304 $(item).css('display', $(item).prevAll('li').first().css('display'));
1305 });
1306 };
1307 /**
1308 * Prevents checkout form from being submitted before checking upsell offers.
1309 *
1310 * @since 1.6.2
1311 */
1312
1313
1314 var sellkitLoadUpsellSteps = function sellkitLoadUpsellSteps() {
1315 $('form.checkout').on('checkout_place_order', function () {
1316 if ($('#sellkit_funnel_has_upsell').length > 0 && 'upsell' === $('#sellkit_funnel_has_upsell').val()) {
1317 sellkitCallUpsell();
1318 return false;
1319 }
1320
1321 return true;
1322 });
1323 };
1324 /**
1325 * After press place order button, call ajax to make decision for popups.
1326 *
1327 * @since 1.6.2
1328 */
1329
1330
1331 var sellkitCallUpsell = function sellkitCallUpsell() {
1332 var loadingIcon = function loadingIcon() {
1333 var icon = sellkit_elementor.url.assets + 'img/spinner.png',
1334 img = document.createElement('img');
1335 img.setAttribute('src', icon);
1336 img.setAttribute('width', '35px');
1337 img.setAttribute('class', 'sellkit-upsell-downsell-preloader');
1338 return img;
1339 };
1340
1341 var onEmpty = function onEmpty() {
1342 $('body').css('overflow', 'auto');
1343 $('.sellkit_funnel_upsell_popup').css('display', 'none');
1344 $('#sellkit_funnel_has_upsell').val('done');
1345 $('#place_order').trigger('click');
1346 };
1347
1348 var loadNew = function loadNew(data) {
1349 $('body').css('overflow', 'hidden');
1350 $('.sellkit-upsell-popup').css('display', 'none');
1351 $('#sellkit_funnel_popup_step_id').val(data.next_id);
1352 $('.sellkit_funnel_upsell_popup').css({
1353 'z-index': '100',
1354 display: 'none'
1355 });
1356 $('.sellkit_funnel_upsell_popup_' + data.next_id).css({
1357 'z-index': 101,
1358 display: 'block'
1359 });
1360 };
1361
1362 var onSuccess = function onSuccess(data) {
1363 setTimeout(function () {
1364 if ('thankyou' === data.next_type) {
1365 onEmpty();
1366 }
1367
1368 if ('upsell' === data.next_type || 'downsell' === data.next_type) {
1369 loadNew(data);
1370 sellkitUpsellOperation();
1371 }
1372 }, 1000);
1373 };
1374
1375 var sellkitUpsellOperation = function sellkitUpsellOperation() {
1376 $('.sellkit_funnel_upsell_popup .sellkit-upsell-accept-button').off().on('click', function () {
1377 var parent = $(this).parents('.sellkit_funnel_upsell_popup'),
1378 upsellId = parent.find('.identify').val(),
1379 checkoutId = $('#sellkit_current_page_id').val();
1380 $('.sellkit-upsell-popup').css('display', 'flex');
1381 parent.find('.sellkit-upsell-updating').addClass('active');
1382 wp.ajax.post({
1383 action: 'sellkit_checkout_ajax_handler',
1384 sub_action: 'perform_upsell_accept_button',
1385 upsell_id: upsellId,
1386 checkout_id: checkoutId,
1387 nonce: sellkit_elementor.nonce
1388 }).done(function (data) {
1389 $(document.body).trigger('update_checkout');
1390 parent.find('.sellkit-upsell-updating').removeClass('active');
1391 parent.find('.sellkit-upsell-accepted').addClass('active');
1392 onSuccess(data);
1393 }).fail(function (data) {
1394 // eslint-disable-next-line no-console
1395 console.error(data);
1396 });
1397 });
1398 $('.sellkit_funnel_upsell_popup .sellkit-upsell-reject-button').off().on('click', function () {
1399 var parent = $(this).parents('.sellkit_funnel_upsell_popup'),
1400 upsellId = parent.find('.identify').val(),
1401 icon = loadingIcon();
1402 parent.find('.sellkit-upsell-downsell-preloader').remove();
1403 $(icon).insertAfter(parent.find('.sellkit-accept-reject-button-widget .sellkit-upsell-reject-button'));
1404 wp.ajax.post({
1405 action: 'sellkit_checkout_ajax_handler',
1406 sub_action: 'perform_upsell_reject_button',
1407 upsell_id: upsellId,
1408 nonce: sellkit_elementor.nonce
1409 }).done(function (data) {
1410 onSuccess(data);
1411 }).fail(function (data) {
1412 // eslint-disable-next-line no-console
1413 console.error(data);
1414 });
1415 });
1416 };
1417
1418 var stepId = $('#sellkit_current_page_id').val(),
1419 img = loadingIcon();
1420 $('button[type=submit]').find('img').remove();
1421 $('button[type=submit]').append(img);
1422 wp.ajax.post({
1423 action: 'sellkit_checkout_ajax_handler',
1424 sub_action: 'call_funnel_popups',
1425 step: stepId,
1426 nonce: sellkit_elementor.nonce
1427 }).done(function (data) {
1428 onSuccess(data);
1429 $('button[type=submit]').find('img').remove();
1430 }).fail(function (data) {
1431 // eslint-disable-next-line no-console
1432 console.error(data);
1433 $('button[type=submit]').find('img').remove();
1434 });
1435 };
1436
1437 },{"@wordpress/i18n":15}],2:[function(require,module,exports){
1438 "use strict";
1439
1440 (function ($) {
1441 var SellkitFrontend = function SellkitFrontend() {
1442 var widgets = {
1443 'sellkit-product-images.default': require('./product-images')["default"],
1444 'sellkit-checkout.default': require('./checkout')["default"],
1445 'sellkit-optin.default': require('./optin/optin')["default"]
1446 };
1447
1448 function elementorInit() {
1449 for (var widget in widgets) {
1450 elementorFrontend.hooks.addAction("frontend/element_ready/".concat(widget), widgets[widget]);
1451 }
1452 }
1453
1454 this.init = function () {
1455 $(window).on('elementor/frontend/init', elementorInit);
1456 };
1457
1458 this.init();
1459 };
1460
1461 window.sellkitFrontend = new SellkitFrontend();
1462 })(jQuery);
1463
1464 },{"./checkout":1,"./optin/optin":3,"./product-images":6}],3:[function(require,module,exports){
1465 "use strict";
1466
1467 var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
1468
1469 Object.defineProperty(exports, "__esModule", {
1470 value: true
1471 });
1472 exports["default"] = _default;
1473
1474 var _intelligentTel = _interopRequireDefault(require("./submodules/intelligent-tel"));
1475
1476 var _fieldValidation = _interopRequireDefault(require("./submodules/field-validation"));
1477
1478 var _i18n = require("@wordpress/i18n");
1479
1480 var Optin = elementorModules.frontend.handlers.Base.extend({
1481 form: null,
1482 onInit: function onInit() {
1483 this.form = this.$element.find('form.sellkit-optin'); // Register submit listener.
1484
1485 this.form.on('submit', this.onSubmit.bind(this)); // Initialize ITI for tel fields.
1486
1487 _intelligentTel["default"].initializeITI(this.form); // AutoComplete address fields.
1488
1489
1490 jQuery(document).ready(this.autoCompleteAddress.bind(this)); // Initialize flatpickr for data and time fields.
1491
1492 this.initializeFlatpickr();
1493 },
1494 onSubmit: function onSubmit(event) {
1495 var _this = this;
1496
1497 event.preventDefault();
1498
1499 if (!this.checkSaveState()) {
1500 return;
1501 }
1502
1503 this.clearAllNotices();
1504 this.form.css('opacity', 0.5);
1505
1506 var validated = _fieldValidation["default"].validateFormFields(this.form);
1507
1508 if (!validated) {
1509 this.form.css('opacity', 1);
1510 return;
1511 }
1512
1513 wp.ajax.send('sellkit_optin_frontend', {
1514 data: this.prepareFormData(),
1515 type: 'POST',
1516 dataType: 'json',
1517 processData: false,
1518 contentType: false,
1519 success: this.onSuccess,
1520 error: this.onFailure,
1521 complete: function complete() {
1522 return _this.form.css('opacity', 1);
1523 }
1524 });
1525 },
1526 checkSaveState: function checkSaveState() {
1527 if (!this.isEdit) {
1528 return true;
1529 }
1530
1531 var btn = jQuery(elementor.panel.el).find('button#elementor-panel-saver-button-publish');
1532
1533 if (!btn.length || btn.hasClass('elementor-disabled')) {
1534 return true;
1535 }
1536
1537 var adminErrorsNode = "\n\t\t\t<div class=\"sellkit-optin-admin-alert\" role=\"alert\">\n\t\t\t\t<span class=\"title\">\n\t\t\t\t\tPlease first update/publish the changes.\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t";
1538 this.form.before(adminErrorsNode);
1539 return false;
1540 },
1541 clearAllNotices: function clearAllNotices() {
1542 var form = this.form; // Reset everything.
1543
1544 form.parent().find('.sellkit-optin-response').remove();
1545 form.parent().find('.sellkit-optin-admin-alert').remove();
1546 form.parent().removeClass('sellkit-optin-error');
1547 form.parent().removeClass('sellkit-optin-success');
1548 },
1549 prepareFormData: function prepareFormData() {
1550 _intelligentTel["default"].fixTelBeforeSubmit(this.form);
1551
1552 var formData = new FormData(this.form[0]);
1553 var entries = Array.from(formData.entries()); // Unify nonsingular formData entries ( happens for checkbox or multiselection select fields ) .
1554
1555 entries.forEach(function (entry, i) {
1556 var value = entry[1];
1557 entries.forEach(function (_entry, _i) {
1558 if (_i !== i && _entry[0] === entry[0]) {
1559 value += ", ".concat(_entry[1]);
1560 formData["delete"](_entry[0]);
1561 }
1562 });
1563 formData.set(entry[0], value);
1564 });
1565 formData.append('referrer', location.toString());
1566 formData.append('action', 'sellkit_optin_frontend');
1567 formData.append('nonce', window.sellkit_elementor.nonce); // To make _POST content compatible with sellkit_funnel() functionality and let it find the funnel data.
1568
1569 formData.append('sellkit_current_page_id', formData.get('post_id'));
1570 return formData;
1571 },
1572 onSuccess: function onSuccess(response) {
1573 var form = this.form; // Success Message.
1574
1575 form.trigger('reset');
1576 form.parent().addClass('sellkit-optin-success');
1577 form.after("<div class=\"sellkit-optin-response\">".concat(response.message, "</div>")); // Admin Error Messages.
1578
1579 this.printAdminErrors(response.admin_errors); // Download.
1580
1581 if (response.downloadURL) {
1582 window.open(response.downloadURL, '_blank');
1583 } // Redirect.
1584
1585
1586 if (!jQuery.isEmptyObject(response.redirectURL)) {
1587 window.location.href = response.redirectURL;
1588 }
1589 },
1590 onFailure: function onFailure(response) {
1591 var form = this.form;
1592 form.parent().removeClass('sellkit-optin-success');
1593 form.parent().addClass('sellkit-optin-error'); // Handle user error messages.
1594
1595 if (!_.isEmpty(response.errors)) {
1596 _.each(response.errors, function (error) {
1597 form.after("<div class=\"sellkit-optin-response\">".concat(error, "</div>"));
1598 });
1599 } // Admin Error Messages.
1600
1601
1602 this.printAdminErrors(response.admin_errors);
1603 },
1604 printAdminErrors: function printAdminErrors(errors) {
1605 if (_.isEmpty(errors)) {
1606 return;
1607 }
1608
1609 var errorList = '';
1610
1611 _.each(errors, function (error) {
1612 errorList += "<li>".concat(error, "</li>");
1613 });
1614
1615 var adminErrorsNode = "\n\t\t\t<div class=\"sellkit-optin-admin-alert\" role=\"alert\">\n\t\t\t\t<span class=\"title\">\n\t\t\t\t\t".concat((0, _i18n.__)('Following messages are visible only for admin users.', 'sellkit'), "\n\t\t\t\t</span>\n\t\t\t\t<div class=\"description\">\n\t\t\t\t\t<ul> ").concat(errorList, " </ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t");
1616 this.form.before(adminErrorsNode);
1617 },
1618 initializeFlatpickr: function initializeFlatpickr() {
1619 var dateField = this.form.find('.flatpickr[type=text]');
1620 var customLocale = dateField.data('locale');
1621 var locale = {
1622 firstDayOfWeek: 1
1623 };
1624
1625 if (!_.isUndefined(customLocale) && 'default' !== customLocale) {
1626 locale = customLocale;
1627 }
1628
1629 dateField.flatpickr({
1630 locale: locale,
1631 minuteIncrement: 1
1632 });
1633 },
1634 autoCompleteAddress: function autoCompleteAddress() {
1635 var addressFields = this.form.find('input[data-type="address"]');
1636 var google = this.isEdit ? window.parent.google : window.google;
1637
1638 if (!addressFields.length || !google) {
1639 return;
1640 }
1641
1642 _.each(addressFields, function (input) {
1643 new google.maps.places.Autocomplete(input, {
1644 types: ['geocode'],
1645 fields: ['address_components']
1646 });
1647 });
1648 }
1649 });
1650
1651 function _default($scope) {
1652 new Optin({
1653 $element: $scope
1654 });
1655 }
1656
1657 },{"./submodules/field-validation":4,"./submodules/intelligent-tel":5,"@babel/runtime/helpers/interopRequireDefault":8,"@wordpress/i18n":15}],4:[function(require,module,exports){
1658 "use strict";
1659
1660 Object.defineProperty(exports, "__esModule", {
1661 value: true
1662 });
1663 exports["default"] = void 0;
1664 var _default = {
1665 messageRequired: '',
1666 messageError: '',
1667 validateFormFields: function validateFormFields(form) {
1668 var _this = this;
1669
1670 this.getCustomMessages(form);
1671 var formData = form.find('[name^="fields"]');
1672 var result = true;
1673
1674 _.each(formData, function (field) {
1675 var message = _this.getValidationMessage(field);
1676
1677 if (!_.isEmpty(message)) {
1678 result = false;
1679 }
1680
1681 _this.toggleFieldMessage(field, message);
1682 });
1683
1684 this.toggleFinalMessage(form, result);
1685 return result;
1686 },
1687 getValidationMessage: function getValidationMessage(target) {
1688 var type = target.dataset.type;
1689 var validity = target.validity;
1690 var i18n = window.sellkitOptinValidationsTranslations;
1691 var message = '';
1692
1693 if (validity.valueMissing || target.required && _.isEmpty(target.value)) {
1694 message = this.messageRequired;
1695 return message;
1696 }
1697
1698 switch (type) {
1699 case 'email':
1700 if (validity.typeMismatch || validity.patternMismatch) {
1701 message = i18n.general.invalidEmail;
1702 }
1703
1704 break;
1705
1706 case 'tel':
1707 var isITI = target.hasAttribute('data-iti-tel');
1708
1709 if (isITI) {
1710 var validationMessages = i18n.itiValidation;
1711 var inputItiInstance = window.intlTelInputGlobals.getInstance(target);
1712 var itiValidationCode = inputItiInstance.getValidationError();
1713 var areaCodeRequired = target.hasAttribute('data-iti-area-required');
1714 var mustBeTelType = target.getAttribute('data-iti-tel-type');
1715 var telType = "".concat(inputItiInstance.getNumberType());
1716
1717 switch (itiValidationCode) {
1718 case 1:
1719 message = validationMessages.invalidCountryCode;
1720 break;
1721
1722 case 2:
1723 message = validationMessages.tooShort;
1724 break;
1725
1726 case 3:
1727 message = validationMessages.tooLong;
1728 break;
1729
1730 case 4:
1731 message = areaCodeRequired ? validationMessages.areaCodeMissing : '';
1732 break;
1733
1734 case 5:
1735 message = validationMessages.invalidLength;
1736 break;
1737
1738 case -99:
1739 message = validationMessages.invalidGeneral;
1740 break;
1741
1742 case 0:
1743 default:
1744 if ('all' !== mustBeTelType && telType !== mustBeTelType) {
1745 message = validationMessages.typeMismatch[mustBeTelType];
1746 }
1747
1748 }
1749
1750 break;
1751 }
1752
1753 if (validity.typeMismatch || validity.patternMismatch) {
1754 message = i18n.general.invalidPhone;
1755 }
1756
1757 break;
1758
1759 case 'number':
1760 if (validity.typeMismatch || validity.patternMismatch) {
1761 message = i18n.general.invalidNumber;
1762 break;
1763 }
1764
1765 if (validity.rangeOverflow) {
1766 message = i18n.general.invalidMaxValue.replace('MAX_VALUE', target.max);
1767 break;
1768 }
1769
1770 if (validity.rangeUnderflow) {
1771 message = i18n.general.invalidMinValue.replace('MIN_VALUE', target.min);
1772 }
1773
1774 break;
1775 }
1776
1777 return message;
1778 },
1779 toggleFieldMessage: function toggleFieldMessage(field, message) {
1780 var fieldGroup = jQuery(field).closest('.sellkit-field-group');
1781 fieldGroup.removeClass('sellkit-field-invalid');
1782 fieldGroup.find('small').remove();
1783
1784 if (!_.isEmpty(message)) {
1785 fieldGroup.addClass('sellkit-field-invalid');
1786 fieldGroup.append("<small class=\"sellkit-optin-text\">".concat(message, "</small>"));
1787 }
1788 },
1789 toggleFinalMessage: function toggleFinalMessage(form, validationResult) {
1790 form.parent().toggleClass('sellkit-optin-error', !validationResult);
1791 form.parent().toggleClass('sellkit-optin-success', validationResult);
1792 form.parent().find('.sellkit-optin-response').remove();
1793
1794 if (true === validationResult) {
1795 return;
1796 }
1797
1798 form.after("<div class=\"sellkit-optin-response\">".concat(this.messageError, "</div>"));
1799 },
1800 getCustomMessages: function getCustomMessages(form) {
1801 var messagesRaw = form.attr('data-messages');
1802
1803 if (!_.isEmpty(messagesRaw)) {
1804 var messages = JSON.parse(messagesRaw);
1805 this.messageError = messages.error;
1806 this.messageRequired = messages.required;
1807 return;
1808 }
1809
1810 this.messageError = window.sellkitOptinValidationsTranslations.general.errorExists;
1811 this.messageRequired = window.sellkitOptinValidationsTranslations.general.required;
1812 }
1813 };
1814 exports["default"] = _default;
1815
1816 },{}],5:[function(require,module,exports){
1817 "use strict";
1818
1819 Object.defineProperty(exports, "__esModule", {
1820 value: true
1821 });
1822 exports["default"] = void 0;
1823 var _default = {
1824 initializeITI: function initializeITI(form) {
1825 var _this = this;
1826
1827 var itiTelFields = form.find('input[data-iti-tel]');
1828
1829 if (!itiTelFields.length) {
1830 return;
1831 }
1832
1833 if (!window.itiCountry) {
1834 jQuery.get('https://ipwho.is/', function () {}, 'json').always(function (response) {
1835 window.itiCountry = response && response.country_code ? response.country_code.toLowerCase() : 'us';
1836
1837 _this.setupTelFields(itiTelFields);
1838 });
1839 } else {
1840 this.setupTelFields(itiTelFields);
1841 }
1842 },
1843 setupTelFields: function setupTelFields(itiTelFields) {
1844 var iti = require('intl-tel-input');
1845
1846 if (!iti) {
1847 return;
1848 }
1849
1850 var allCountries = window.intlTelInputGlobals.getCountryData().map(function (item) {
1851 return item.iso2;
1852 });
1853 var numberTypes = ['FIXED_LINE', 'MOBILE', 'FIXED_LINE_OR_MOBILE', 'TOLL_FREE', 'PREMIUM_RATE', 'SHARED_COST', 'VOIP', 'PERSONAL_NUMBER', 'PAGER', 'UAN', 'VOICEMAIL'];
1854
1855 _.each(itiTelFields, function (input) {
1856 var allowDropdown = input.hasAttribute('data-iti-allow-dropdown');
1857 var countriesAttr = input.getAttribute('data-iti-country-include');
1858 var countries = countriesAttr ? countriesAttr.split(' ') : null;
1859 var isCountriesSet = countries && countries.length;
1860 var ipDetect = input.hasAttribute('data-iti-ip-detect');
1861 var placeHolderAttr = input.getAttribute('data-iti-tel-type');
1862 var args = {
1863 allowDropdown: allowDropdown,
1864 utilsScript: 'https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.16/js/utils.min.js',
1865 separateDialCode: true,
1866 placeholderNumberType: 'all' === placeHolderAttr ? 'MOBILE' : numberTypes[+placeHolderAttr],
1867 onlyCountries: isCountriesSet ? countries : allCountries,
1868 initialCountry: '',
1869 geoIpLookup: null
1870 };
1871
1872 if (ipDetect) {
1873 args.initialCountry = isCountriesSet && !countries.includes(window.itiCountry) ? countries[0] : 'auto';
1874
1875 args.geoIpLookup = function (success) {
1876 return success(window.itiCountry);
1877 };
1878 }
1879
1880 iti(input, args);
1881 });
1882 },
1883 fixTelBeforeSubmit: function fixTelBeforeSubmit(form) {
1884 var itiTelFields = form.find('input[data-iti-tel]');
1885
1886 _.each(itiTelFields, function (input) {
1887 var internationalize = input.hasAttribute('data-iti-internationalize');
1888
1889 if (internationalize) {
1890 var itiInstance = window.intlTelInputGlobals.getInstance(input);
1891 input.value = itiInstance.getNumber();
1892 }
1893 });
1894 }
1895 };
1896 exports["default"] = _default;
1897
1898 },{"intl-tel-input":19}],6:[function(require,module,exports){
1899 "use strict";
1900
1901 Object.defineProperty(exports, "__esModule", {
1902 value: true
1903 });
1904 exports["default"] = _default;
1905 var ProductImages = elementorModules.frontend.handlers.Base.extend({
1906 onInit: function onInit() {
1907 elementorModules.frontend.handlers.Base.prototype.onInit.apply(this, arguments);
1908
1909 if (document.body.classList.contains('elementor-editor-active')) {
1910 this.$element.find('.woocommerce-product-gallery').wc_product_gallery();
1911 }
1912
1913 var self = this;
1914
1915 if (typeof window.elementor === 'undefined') {
1916 return;
1917 }
1918
1919 window.elementor.channels.editor.on('change', function (controlView) {
1920 self.onElementChange(controlView.model.get('name'), controlView);
1921 });
1922 this.handleThumbnailBorderRadius(this.getElementSettings('thumbnail_border_radius'));
1923 },
1924 onElementChange: function onElementChange(propertyName, controlView) {
1925 if ('thumbnail_border_radius' === propertyName) {
1926 var borderRadius = controlView.container.settings.get('thumbnail_border_radius');
1927 this.handleThumbnailBorderRadius(borderRadius);
1928 }
1929 },
1930 handleThumbnailBorderRadius: function handleThumbnailBorderRadius(borderRadius) {
1931 var unit = borderRadius.unit;
1932 this.$element.find('.flex-control-nav li').css({
1933 'border-radius': borderRadius.top + unit + ' ' + borderRadius.right + unit + ' ' + borderRadius.bottom + unit + ' ' + borderRadius.left + unit
1934 });
1935 },
1936 bindEvents: function bindEvents() {
1937 this.$element.find('.woocommerce-product-gallery__image a').on('click', function (e) {
1938 e.stopImmediatePropagation();
1939 e.preventDefault();
1940 });
1941 }
1942 });
1943
1944 function _default($scope) {
1945 new ProductImages({
1946 $element: $scope
1947 });
1948 }
1949
1950 },{}],7:[function(require,module,exports){
1951 function _defineProperty(obj, key, value) {
1952 if (key in obj) {
1953 Object.defineProperty(obj, key, {
1954 value: value,
1955 enumerable: true,
1956 configurable: true,
1957 writable: true
1958 });
1959 } else {
1960 obj[key] = value;
1961 }
1962
1963 return obj;
1964 }
1965
1966 module.exports = _defineProperty;
1967 },{}],8:[function(require,module,exports){
1968 function _interopRequireDefault(obj) {
1969 return obj && obj.__esModule ? obj : {
1970 "default": obj
1971 };
1972 }
1973
1974 module.exports = _interopRequireDefault;
1975 },{}],9:[function(require,module,exports){
1976 'use strict';
1977
1978 function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
1979
1980 var postfix = _interopDefault(require('@tannin/postfix'));
1981 var evaluate = _interopDefault(require('@tannin/evaluate'));
1982
1983 /**
1984 * Given a C expression, returns a function which can be called to evaluate its
1985 * result.
1986 *
1987 * @example
1988 *
1989 * ```js
1990 * import compile from '@tannin/compile';
1991 *
1992 * const evaluate = compile( 'n > 1' );
1993 *
1994 * evaluate( { n: 2 } );
1995 * // ⇒ true
1996 * ```
1997 *
1998 * @param {string} expression C expression.
1999 *
2000 * @return {(variables?:{[variable:string]:*})=>*} Compiled evaluator.
2001 */
2002 function compile( expression ) {
2003 var terms = postfix( expression );
2004
2005 return function( variables ) {
2006 return evaluate( terms, variables );
2007 };
2008 }
2009
2010 module.exports = compile;
2011
2012 },{"@tannin/evaluate":10,"@tannin/postfix":12}],10:[function(require,module,exports){
2013 'use strict';
2014
2015 /**
2016 * Operator callback functions.
2017 *
2018 * @type {Object}
2019 */
2020 var OPERATORS = {
2021 '!': function( a ) {
2022 return ! a;
2023 },
2024 '*': function( a, b ) {
2025 return a * b;
2026 },
2027 '/': function( a, b ) {
2028 return a / b;
2029 },
2030 '%': function( a, b ) {
2031 return a % b;
2032 },
2033 '+': function( a, b ) {
2034 return a + b;
2035 },
2036 '-': function( a, b ) {
2037 return a - b;
2038 },
2039 '<': function( a, b ) {
2040 return a < b;
2041 },
2042 '<=': function( a, b ) {
2043 return a <= b;
2044 },
2045 '>': function( a, b ) {
2046 return a > b;
2047 },
2048 '>=': function( a, b ) {
2049 return a >= b;
2050 },
2051 '==': function( a, b ) {
2052 return a === b;
2053 },
2054 '!=': function( a, b ) {
2055 return a !== b;
2056 },
2057 '&&': function( a, b ) {
2058 return a && b;
2059 },
2060 '||': function( a, b ) {
2061 return a || b;
2062 },
2063 '?:': function( a, b, c ) {
2064 if ( a ) {
2065 throw b;
2066 }
2067
2068 return c;
2069 },
2070 };
2071
2072 /**
2073 * Given an array of postfix terms and operand variables, returns the result of
2074 * the postfix evaluation.
2075 *
2076 * @example
2077 *
2078 * ```js
2079 * import evaluate from '@tannin/evaluate';
2080 *
2081 * // 3 + 4 * 5 / 6 ⇒ '3 4 5 * 6 / +'
2082 * const terms = [ '3', '4', '5', '*', '6', '/', '+' ];
2083 *
2084 * evaluate( terms, {} );
2085 * // ⇒ 6.333333333333334
2086 * ```
2087 *
2088 * @param {string[]} postfix Postfix terms.
2089 * @param {Object} variables Operand variables.
2090 *
2091 * @return {*} Result of evaluation.
2092 */
2093 function evaluate( postfix, variables ) {
2094 var stack = [],
2095 i, j, args, getOperatorResult, term, value;
2096
2097 for ( i = 0; i < postfix.length; i++ ) {
2098 term = postfix[ i ];
2099
2100 getOperatorResult = OPERATORS[ term ];
2101 if ( getOperatorResult ) {
2102 // Pop from stack by number of function arguments.
2103 j = getOperatorResult.length;
2104 args = Array( j );
2105 while ( j-- ) {
2106 args[ j ] = stack.pop();
2107 }
2108
2109 try {
2110 value = getOperatorResult.apply( null, args );
2111 } catch ( earlyReturn ) {
2112 return earlyReturn;
2113 }
2114 } else if ( variables.hasOwnProperty( term ) ) {
2115 value = variables[ term ];
2116 } else {
2117 value = +term;
2118 }
2119
2120 stack.push( value );
2121 }
2122
2123 return stack[ 0 ];
2124 }
2125
2126 module.exports = evaluate;
2127
2128 },{}],11:[function(require,module,exports){
2129 'use strict';
2130
2131 function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
2132
2133 var compile = _interopDefault(require('@tannin/compile'));
2134
2135 /**
2136 * Given a C expression, returns a function which, when called with a value,
2137 * evaluates the result with the value assumed to be the "n" variable of the
2138 * expression. The result will be coerced to its numeric equivalent.
2139 *
2140 * @param {string} expression C expression.
2141 *
2142 * @return {Function} Evaluator function.
2143 */
2144 function pluralForms( expression ) {
2145 var evaluate = compile( expression );
2146
2147 return function( n ) {
2148 return +evaluate( { n: n } );
2149 };
2150 }
2151
2152 module.exports = pluralForms;
2153
2154 },{"@tannin/compile":9}],12:[function(require,module,exports){
2155 'use strict';
2156
2157 var PRECEDENCE, OPENERS, TERMINATORS, PATTERN;
2158
2159 /**
2160 * Operator precedence mapping.
2161 *
2162 * @type {Object}
2163 */
2164 PRECEDENCE = {
2165 '(': 9,
2166 '!': 8,
2167 '*': 7,
2168 '/': 7,
2169 '%': 7,
2170 '+': 6,
2171 '-': 6,
2172 '<': 5,
2173 '<=': 5,
2174 '>': 5,
2175 '>=': 5,
2176 '==': 4,
2177 '!=': 4,
2178 '&&': 3,
2179 '||': 2,
2180 '?': 1,
2181 '?:': 1,
2182 };
2183
2184 /**
2185 * Characters which signal pair opening, to be terminated by terminators.
2186 *
2187 * @type {string[]}
2188 */
2189 OPENERS = [ '(', '?' ];
2190
2191 /**
2192 * Characters which signal pair termination, the value an array with the
2193 * opener as its first member. The second member is an optional operator
2194 * replacement to push to the stack.
2195 *
2196 * @type {string[]}
2197 */
2198 TERMINATORS = {
2199 ')': [ '(' ],
2200 ':': [ '?', '?:' ],
2201 };
2202
2203 /**
2204 * Pattern matching operators and openers.
2205 *
2206 * @type {RegExp}
2207 */
2208 PATTERN = /<=|>=|==|!=|&&|\|\||\?:|\(|!|\*|\/|%|\+|-|<|>|\?|\)|:/;
2209
2210 /**
2211 * Given a C expression, returns the equivalent postfix (Reverse Polish)
2212 * notation terms as an array.
2213 *
2214 * If a postfix string is desired, simply `.join( ' ' )` the result.
2215 *
2216 * @example
2217 *
2218 * ```js
2219 * import postfix from '@tannin/postfix';
2220 *
2221 * postfix( 'n > 1' );
2222 * // ⇒ [ 'n', '1', '>' ]
2223 * ```
2224 *
2225 * @param {string} expression C expression.
2226 *
2227 * @return {string[]} Postfix terms.
2228 */
2229 function postfix( expression ) {
2230 var terms = [],
2231 stack = [],
2232 match, operator, term, element;
2233
2234 while ( ( match = expression.match( PATTERN ) ) ) {
2235 operator = match[ 0 ];
2236
2237 // Term is the string preceding the operator match. It may contain
2238 // whitespace, and may be empty (if operator is at beginning).
2239 term = expression.substr( 0, match.index ).trim();
2240 if ( term ) {
2241 terms.push( term );
2242 }
2243
2244 while ( ( element = stack.pop() ) ) {
2245 if ( TERMINATORS[ operator ] ) {
2246 if ( TERMINATORS[ operator ][ 0 ] === element ) {
2247 // Substitution works here under assumption that because
2248 // the assigned operator will no longer be a terminator, it
2249 // will be pushed to the stack during the condition below.
2250 operator = TERMINATORS[ operator ][ 1 ] || operator;
2251 break;
2252 }
2253 } else if ( OPENERS.indexOf( element ) >= 0 || PRECEDENCE[ element ] < PRECEDENCE[ operator ] ) {
2254 // Push to stack if either an opener or when pop reveals an
2255 // element of lower precedence.
2256 stack.push( element );
2257 break;
2258 }
2259
2260 // For each popped from stack, push to terms.
2261 terms.push( element );
2262 }
2263
2264 if ( ! TERMINATORS[ operator ] ) {
2265 stack.push( operator );
2266 }
2267
2268 // Slice matched fragment from expression to continue match.
2269 expression = expression.substr( match.index + operator.length );
2270 }
2271
2272 // Push remainder of operand, if exists, to terms.
2273 expression = expression.trim();
2274 if ( expression ) {
2275 terms.push( expression );
2276 }
2277
2278 // Pop remaining items from stack into terms.
2279 return terms.concat( stack.reverse() );
2280 }
2281
2282 module.exports = postfix;
2283
2284 },{}],13:[function(require,module,exports){
2285 "use strict";
2286
2287 var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
2288
2289 Object.defineProperty(exports, "__esModule", {
2290 value: true
2291 });
2292 exports.createI18n = void 0;
2293
2294 var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
2295
2296 var _tannin = _interopRequireDefault(require("tannin"));
2297
2298 function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
2299
2300 function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
2301
2302 /**
2303 * @typedef {Record<string,any>} LocaleData
2304 */
2305
2306 /**
2307 * Default locale data to use for Tannin domain when not otherwise provided.
2308 * Assumes an English plural forms expression.
2309 *
2310 * @type {LocaleData}
2311 */
2312 var DEFAULT_LOCALE_DATA = {
2313 '': {
2314 /** @param {number} n */
2315 plural_forms: function plural_forms(n) {
2316 return n === 1 ? 0 : 1;
2317 }
2318 }
2319 };
2320 /**
2321 * An i18n instance
2322 *
2323 * @typedef {Object} I18n
2324 * @property {Function} setLocaleData Merges locale data into the Tannin instance by domain. Accepts data in a
2325 * Jed-formatted JSON object shape.
2326 * @property {Function} __ Retrieve the translation of text.
2327 * @property {Function} _x Retrieve translated string with gettext context.
2328 * @property {Function} _n Translates and retrieves the singular or plural form based on the supplied
2329 * number.
2330 * @property {Function} _nx Translates and retrieves the singular or plural form based on the supplied
2331 * number, with gettext context.
2332 * @property {Function} isRTL Check if current locale is RTL.
2333 */
2334
2335 /**
2336 * Create an i18n instance
2337 *
2338 * @param {LocaleData} [initialData] Locale data configuration.
2339 * @param {string} [initialDomain] Domain for which configuration applies.
2340 * @return {I18n} I18n instance
2341 */
2342
2343 var createI18n = function createI18n(initialData, initialDomain) {
2344 /**
2345 * The underlying instance of Tannin to which exported functions interface.
2346 *
2347 * @type {Tannin}
2348 */
2349 var tannin = new _tannin.default({});
2350 /**
2351 * Merges locale data into the Tannin instance by domain. Accepts data in a
2352 * Jed-formatted JSON object shape.
2353 *
2354 * @see http://messageformat.github.io/Jed/
2355 *
2356 * @param {LocaleData} [data] Locale data configuration.
2357 * @param {string} [domain] Domain for which configuration applies.
2358 */
2359
2360 var setLocaleData = function setLocaleData(data) {
2361 var domain = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'default';
2362 tannin.data[domain] = _objectSpread({}, DEFAULT_LOCALE_DATA, {}, tannin.data[domain], {}, data); // Populate default domain configuration (supported locale date which omits
2363 // a plural forms expression).
2364
2365 tannin.data[domain][''] = _objectSpread({}, DEFAULT_LOCALE_DATA[''], {}, tannin.data[domain]['']);
2366 };
2367 /**
2368 * Wrapper for Tannin's `dcnpgettext`. Populates default locale data if not
2369 * otherwise previously assigned.
2370 *
2371 * @param {string|undefined} domain Domain to retrieve the translated text.
2372 * @param {string|undefined} context Context information for the translators.
2373 * @param {string} single Text to translate if non-plural. Used as
2374 * fallback return value on a caught error.
2375 * @param {string} [plural] The text to be used if the number is
2376 * plural.
2377 * @param {number} [number] The number to compare against to use
2378 * either the singular or plural form.
2379 *
2380 * @return {string} The translated string.
2381 */
2382
2383
2384 var dcnpgettext = function dcnpgettext() {
2385 var domain = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'default';
2386 var context = arguments.length > 1 ? arguments[1] : undefined;
2387 var single = arguments.length > 2 ? arguments[2] : undefined;
2388 var plural = arguments.length > 3 ? arguments[3] : undefined;
2389 var number = arguments.length > 4 ? arguments[4] : undefined;
2390
2391 if (!tannin.data[domain]) {
2392 setLocaleData(undefined, domain);
2393 }
2394
2395 return tannin.dcnpgettext(domain, context, single, plural, number);
2396 };
2397 /**
2398 * Retrieve the translation of text.
2399 *
2400 * @see https://developer.wordpress.org/reference/functions/__/
2401 *
2402 * @param {string} text Text to translate.
2403 * @param {string} [domain] Domain to retrieve the translated text.
2404 *
2405 * @return {string} Translated text.
2406 */
2407
2408
2409 var __ = function __(text, domain) {
2410 return dcnpgettext(domain, undefined, text);
2411 };
2412 /**
2413 * Retrieve translated string with gettext context.
2414 *
2415 * @see https://developer.wordpress.org/reference/functions/_x/
2416 *
2417 * @param {string} text Text to translate.
2418 * @param {string} context Context information for the translators.
2419 * @param {string} [domain] Domain to retrieve the translated text.
2420 *
2421 * @return {string} Translated context string without pipe.
2422 */
2423
2424
2425 var _x = function _x(text, context, domain) {
2426 return dcnpgettext(domain, context, text);
2427 };
2428 /**
2429 * Translates and retrieves the singular or plural form based on the supplied
2430 * number.
2431 *
2432 * @see https://developer.wordpress.org/reference/functions/_n/
2433 *
2434 * @param {string} single The text to be used if the number is singular.
2435 * @param {string} plural The text to be used if the number is plural.
2436 * @param {number} number The number to compare against to use either the
2437 * singular or plural form.
2438 * @param {string} [domain] Domain to retrieve the translated text.
2439 *
2440 * @return {string} The translated singular or plural form.
2441 */
2442
2443
2444 var _n = function _n(single, plural, number, domain) {
2445 return dcnpgettext(domain, undefined, single, plural, number);
2446 };
2447 /**
2448 * Translates and retrieves the singular or plural form based on the supplied
2449 * number, with gettext context.
2450 *
2451 * @see https://developer.wordpress.org/reference/functions/_nx/
2452 *
2453 * @param {string} single The text to be used if the number is singular.
2454 * @param {string} plural The text to be used if the number is plural.
2455 * @param {number} number The number to compare against to use either the
2456 * singular or plural form.
2457 * @param {string} context Context information for the translators.
2458 * @param {string} [domain] Domain to retrieve the translated text.
2459 *
2460 * @return {string} The translated singular or plural form.
2461 */
2462
2463
2464 var _nx = function _nx(single, plural, number, context, domain) {
2465 return dcnpgettext(domain, context, single, plural, number);
2466 };
2467 /**
2468 * Check if current locale is RTL.
2469 *
2470 * **RTL (Right To Left)** is a locale property indicating that text is written from right to left.
2471 * For example, the `he` locale (for Hebrew) specifies right-to-left. Arabic (ar) is another common
2472 * language written RTL. The opposite of RTL, LTR (Left To Right) is used in other languages,
2473 * including English (`en`, `en-US`, `en-GB`, etc.), Spanish (`es`), and French (`fr`).
2474 *
2475 * @return {boolean} Whether locale is RTL.
2476 */
2477
2478
2479 var isRTL = function isRTL() {
2480 return 'rtl' === _x('ltr', 'text direction');
2481 };
2482
2483 if (initialData) {
2484 setLocaleData(initialData, initialDomain);
2485 }
2486
2487 return {
2488 setLocaleData: setLocaleData,
2489 __: __,
2490 _x: _x,
2491 _n: _n,
2492 _nx: _nx,
2493 isRTL: isRTL
2494 };
2495 };
2496
2497 exports.createI18n = createI18n;
2498
2499 },{"@babel/runtime/helpers/defineProperty":7,"@babel/runtime/helpers/interopRequireDefault":8,"tannin":22}],14:[function(require,module,exports){
2500 "use strict";
2501
2502 Object.defineProperty(exports, "__esModule", {
2503 value: true
2504 });
2505 exports.isRTL = exports._nx = exports._n = exports._x = exports.__ = exports.setLocaleData = void 0;
2506
2507 var _createI18n = require("./create-i18n");
2508
2509 /**
2510 * Internal dependencies
2511 */
2512 var i18n = (0, _createI18n.createI18n)();
2513 /*
2514 * Comments in this file are duplicated from ./i18n due to
2515 * https://github.com/WordPress/gutenberg/pull/20318#issuecomment-590837722
2516 */
2517
2518 /**
2519 * @typedef {import('./create-i18n').LocaleData} LocaleData
2520 */
2521
2522 /**
2523 * Merges locale data into the Tannin instance by domain. Accepts data in a
2524 * Jed-formatted JSON object shape.
2525 *
2526 * @see http://messageformat.github.io/Jed/
2527 *
2528 * @param {LocaleData} [data] Locale data configuration.
2529 * @param {string} [domain] Domain for which configuration applies.
2530 */
2531
2532 var setLocaleData = i18n.setLocaleData.bind(i18n);
2533 /**
2534 * Retrieve the translation of text.
2535 *
2536 * @see https://developer.wordpress.org/reference/functions/__/
2537 *
2538 * @param {string} text Text to translate.
2539 * @param {string} [domain] Domain to retrieve the translated text.
2540 *
2541 * @return {string} Translated text.
2542 */
2543
2544 exports.setLocaleData = setLocaleData;
2545
2546 var __ = i18n.__.bind(i18n);
2547 /**
2548 * Retrieve translated string with gettext context.
2549 *
2550 * @see https://developer.wordpress.org/reference/functions/_x/
2551 *
2552 * @param {string} text Text to translate.
2553 * @param {string} context Context information for the translators.
2554 * @param {string} [domain] Domain to retrieve the translated text.
2555 *
2556 * @return {string} Translated context string without pipe.
2557 */
2558
2559
2560 exports.__ = __;
2561
2562 var _x = i18n._x.bind(i18n);
2563 /**
2564 * Translates and retrieves the singular or plural form based on the supplied
2565 * number.
2566 *
2567 * @see https://developer.wordpress.org/reference/functions/_n/
2568 *
2569 * @param {string} single The text to be used if the number is singular.
2570 * @param {string} plural The text to be used if the number is plural.
2571 * @param {number} number The number to compare against to use either the
2572 * singular or plural form.
2573 * @param {string} [domain] Domain to retrieve the translated text.
2574 *
2575 * @return {string} The translated singular or plural form.
2576 */
2577
2578
2579 exports._x = _x;
2580
2581 var _n = i18n._n.bind(i18n);
2582 /**
2583 * Translates and retrieves the singular or plural form based on the supplied
2584 * number, with gettext context.
2585 *
2586 * @see https://developer.wordpress.org/reference/functions/_nx/
2587 *
2588 * @param {string} single The text to be used if the number is singular.
2589 * @param {string} plural The text to be used if the number is plural.
2590 * @param {number} number The number to compare against to use either the
2591 * singular or plural form.
2592 * @param {string} context Context information for the translators.
2593 * @param {string} [domain] Domain to retrieve the translated text.
2594 *
2595 * @return {string} The translated singular or plural form.
2596 */
2597
2598
2599 exports._n = _n;
2600
2601 var _nx = i18n._nx.bind(i18n);
2602 /**
2603 * Check if current locale is RTL.
2604 *
2605 * **RTL (Right To Left)** is a locale property indicating that text is written from right to left.
2606 * For example, the `he` locale (for Hebrew) specifies right-to-left. Arabic (ar) is another common
2607 * language written RTL. The opposite of RTL, LTR (Left To Right) is used in other languages,
2608 * including English (`en`, `en-US`, `en-GB`, etc.), Spanish (`es`), and French (`fr`).
2609 *
2610 * @return {boolean} Whether locale is RTL.
2611 */
2612
2613
2614 exports._nx = _nx;
2615 var isRTL = i18n.isRTL.bind(i18n);
2616 exports.isRTL = isRTL;
2617
2618 },{"./create-i18n":13}],15:[function(require,module,exports){
2619 "use strict";
2620
2621 Object.defineProperty(exports, "__esModule", {
2622 value: true
2623 });
2624 var _exportNames = {
2625 sprintf: true,
2626 setLocaleData: true,
2627 __: true,
2628 _x: true,
2629 _n: true,
2630 _nx: true,
2631 isRTL: true
2632 };
2633 Object.defineProperty(exports, "sprintf", {
2634 enumerable: true,
2635 get: function get() {
2636 return _sprintf.sprintf;
2637 }
2638 });
2639 Object.defineProperty(exports, "setLocaleData", {
2640 enumerable: true,
2641 get: function get() {
2642 return _defaultI18n.setLocaleData;
2643 }
2644 });
2645 Object.defineProperty(exports, "__", {
2646 enumerable: true,
2647 get: function get() {
2648 return _defaultI18n.__;
2649 }
2650 });
2651 Object.defineProperty(exports, "_x", {
2652 enumerable: true,
2653 get: function get() {
2654 return _defaultI18n._x;
2655 }
2656 });
2657 Object.defineProperty(exports, "_n", {
2658 enumerable: true,
2659 get: function get() {
2660 return _defaultI18n._n;
2661 }
2662 });
2663 Object.defineProperty(exports, "_nx", {
2664 enumerable: true,
2665 get: function get() {
2666 return _defaultI18n._nx;
2667 }
2668 });
2669 Object.defineProperty(exports, "isRTL", {
2670 enumerable: true,
2671 get: function get() {
2672 return _defaultI18n.isRTL;
2673 }
2674 });
2675
2676 var _sprintf = require("./sprintf");
2677
2678 var _createI18n = require("./create-i18n");
2679
2680 Object.keys(_createI18n).forEach(function (key) {
2681 if (key === "default" || key === "__esModule") return;
2682 if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
2683 Object.defineProperty(exports, key, {
2684 enumerable: true,
2685 get: function get() {
2686 return _createI18n[key];
2687 }
2688 });
2689 });
2690
2691 var _defaultI18n = require("./default-i18n");
2692
2693 },{"./create-i18n":13,"./default-i18n":14,"./sprintf":16}],16:[function(require,module,exports){
2694 "use strict";
2695
2696 var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
2697
2698 Object.defineProperty(exports, "__esModule", {
2699 value: true
2700 });
2701 exports.sprintf = sprintf;
2702
2703 var _memize = _interopRequireDefault(require("memize"));
2704
2705 var _sprintfJs = _interopRequireDefault(require("sprintf-js"));
2706
2707 /**
2708 * External dependencies
2709 */
2710
2711 /**
2712 * Log to console, once per message; or more precisely, per referentially equal
2713 * argument set. Because Jed throws errors, we log these to the console instead
2714 * to avoid crashing the application.
2715 *
2716 * @param {...*} args Arguments to pass to `console.error`
2717 */
2718 var logErrorOnce = (0, _memize.default)(console.error); // eslint-disable-line no-console
2719
2720 /**
2721 * Returns a formatted string. If an error occurs in applying the format, the
2722 * original format string is returned.
2723 *
2724 * @param {string} format The format of the string to generate.
2725 * @param {...*} args Arguments to apply to the format.
2726 *
2727 * @see http://www.diveintojavascript.com/projects/javascript-sprintf
2728 *
2729 * @return {string} The formatted string.
2730 */
2731
2732 function sprintf(format) {
2733 try {
2734 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
2735 args[_key - 1] = arguments[_key];
2736 }
2737
2738 return _sprintfJs.default.sprintf.apply(_sprintfJs.default, [format].concat(args));
2739 } catch (error) {
2740 logErrorOnce('sprintf error: \n\n' + error.toString());
2741 return format;
2742 }
2743 }
2744
2745 },{"@babel/runtime/helpers/interopRequireDefault":8,"memize":20,"sprintf-js":17}],17:[function(require,module,exports){
2746 /* global window, exports, define */
2747
2748 !function() {
2749 'use strict'
2750
2751 var re = {
2752 not_string: /[^s]/,
2753 not_bool: /[^t]/,
2754 not_type: /[^T]/,
2755 not_primitive: /[^v]/,
2756 number: /[diefg]/,
2757 numeric_arg: /[bcdiefguxX]/,
2758 json: /[j]/,
2759 not_json: /[^j]/,
2760 text: /^[^\x25]+/,
2761 modulo: /^\x25{2}/,
2762 placeholder: /^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,
2763 key: /^([a-z_][a-z_\d]*)/i,
2764 key_access: /^\.([a-z_][a-z_\d]*)/i,
2765 index_access: /^\[(\d+)\]/,
2766 sign: /^[+-]/
2767 }
2768
2769 function sprintf(key) {
2770 // `arguments` is not an array, but should be fine for this call
2771 return sprintf_format(sprintf_parse(key), arguments)
2772 }
2773
2774 function vsprintf(fmt, argv) {
2775 return sprintf.apply(null, [fmt].concat(argv || []))
2776 }
2777
2778 function sprintf_format(parse_tree, argv) {
2779 var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, ph, pad, pad_character, pad_length, is_positive, sign
2780 for (i = 0; i < tree_length; i++) {
2781 if (typeof parse_tree[i] === 'string') {
2782 output += parse_tree[i]
2783 }
2784 else if (typeof parse_tree[i] === 'object') {
2785 ph = parse_tree[i] // convenience purposes only
2786 if (ph.keys) { // keyword argument
2787 arg = argv[cursor]
2788 for (k = 0; k < ph.keys.length; k++) {
2789 if (arg == undefined) {
2790 throw new Error(sprintf('[sprintf] Cannot access property "%s" of undefined value "%s"', ph.keys[k], ph.keys[k-1]))
2791 }
2792 arg = arg[ph.keys[k]]
2793 }
2794 }
2795 else if (ph.param_no) { // positional argument (explicit)
2796 arg = argv[ph.param_no]
2797 }
2798 else { // positional argument (implicit)
2799 arg = argv[cursor++]
2800 }
2801
2802 if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) {
2803 arg = arg()
2804 }
2805
2806 if (re.numeric_arg.test(ph.type) && (typeof arg !== 'number' && isNaN(arg))) {
2807 throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg))
2808 }
2809
2810 if (re.number.test(ph.type)) {
2811 is_positive = arg >= 0
2812 }
2813
2814 switch (ph.type) {
2815 case 'b':
2816 arg = parseInt(arg, 10).toString(2)
2817 break
2818 case 'c':
2819 arg = String.fromCharCode(parseInt(arg, 10))
2820 break
2821 case 'd':
2822 case 'i':
2823 arg = parseInt(arg, 10)
2824 break
2825 case 'j':
2826 arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0)
2827 break
2828 case 'e':
2829 arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential()
2830 break
2831 case 'f':
2832 arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg)
2833 break
2834 case 'g':
2835 arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg)
2836 break
2837 case 'o':
2838 arg = (parseInt(arg, 10) >>> 0).toString(8)
2839 break
2840 case 's':
2841 arg = String(arg)
2842 arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
2843 break
2844 case 't':
2845 arg = String(!!arg)
2846 arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
2847 break
2848 case 'T':
2849 arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase()
2850 arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
2851 break
2852 case 'u':
2853 arg = parseInt(arg, 10) >>> 0
2854 break
2855 case 'v':
2856 arg = arg.valueOf()
2857 arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
2858 break
2859 case 'x':
2860 arg = (parseInt(arg, 10) >>> 0).toString(16)
2861 break
2862 case 'X':
2863 arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase()
2864 break
2865 }
2866 if (re.json.test(ph.type)) {
2867 output += arg
2868 }
2869 else {
2870 if (re.number.test(ph.type) && (!is_positive || ph.sign)) {
2871 sign = is_positive ? '+' : '-'
2872 arg = arg.toString().replace(re.sign, '')
2873 }
2874 else {
2875 sign = ''
2876 }
2877 pad_character = ph.pad_char ? ph.pad_char === '0' ? '0' : ph.pad_char.charAt(1) : ' '
2878 pad_length = ph.width - (sign + arg).length
2879 pad = ph.width ? (pad_length > 0 ? pad_character.repeat(pad_length) : '') : ''
2880 output += ph.align ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg)
2881 }
2882 }
2883 }
2884 return output
2885 }
2886
2887 var sprintf_cache = Object.create(null)
2888
2889 function sprintf_parse(fmt) {
2890 if (sprintf_cache[fmt]) {
2891 return sprintf_cache[fmt]
2892 }
2893
2894 var _fmt = fmt, match, parse_tree = [], arg_names = 0
2895 while (_fmt) {
2896 if ((match = re.text.exec(_fmt)) !== null) {
2897 parse_tree.push(match[0])
2898 }
2899 else if ((match = re.modulo.exec(_fmt)) !== null) {
2900 parse_tree.push('%')
2901 }
2902 else if ((match = re.placeholder.exec(_fmt)) !== null) {
2903 if (match[2]) {
2904 arg_names |= 1
2905 var field_list = [], replacement_field = match[2], field_match = []
2906 if ((field_match = re.key.exec(replacement_field)) !== null) {
2907 field_list.push(field_match[1])
2908 while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
2909 if ((field_match = re.key_access.exec(replacement_field)) !== null) {
2910 field_list.push(field_match[1])
2911 }
2912 else if ((field_match = re.index_access.exec(replacement_field)) !== null) {
2913 field_list.push(field_match[1])
2914 }
2915 else {
2916 throw new SyntaxError('[sprintf] failed to parse named argument key')
2917 }
2918 }
2919 }
2920 else {
2921 throw new SyntaxError('[sprintf] failed to parse named argument key')
2922 }
2923 match[2] = field_list
2924 }
2925 else {
2926 arg_names |= 2
2927 }
2928 if (arg_names === 3) {
2929 throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported')
2930 }
2931
2932 parse_tree.push(
2933 {
2934 placeholder: match[0],
2935 param_no: match[1],
2936 keys: match[2],
2937 sign: match[3],
2938 pad_char: match[4],
2939 align: match[5],
2940 width: match[6],
2941 precision: match[7],
2942 type: match[8]
2943 }
2944 )
2945 }
2946 else {
2947 throw new SyntaxError('[sprintf] unexpected placeholder')
2948 }
2949 _fmt = _fmt.substring(match[0].length)
2950 }
2951 return sprintf_cache[fmt] = parse_tree
2952 }
2953
2954 /**
2955 * export to either browser or node.js
2956 */
2957 /* eslint-disable quote-props */
2958 if (typeof exports !== 'undefined') {
2959 exports['sprintf'] = sprintf
2960 exports['vsprintf'] = vsprintf
2961 }
2962 if (typeof window !== 'undefined') {
2963 window['sprintf'] = sprintf
2964 window['vsprintf'] = vsprintf
2965
2966 if (typeof define === 'function' && define['amd']) {
2967 define(function() {
2968 return {
2969 'sprintf': sprintf,
2970 'vsprintf': vsprintf
2971 }
2972 })
2973 }
2974 }
2975 /* eslint-enable quote-props */
2976 }(); // eslint-disable-line
2977
2978 },{}],18:[function(require,module,exports){
2979 /*
2980 * International Telephone Input v17.0.16
2981 * https://github.com/jackocnr/intl-tel-input.git
2982 * Licensed under the MIT license
2983 */
2984
2985 // wrap in UMD
2986 (function(factory) {
2987 if (typeof module === "object" && module.exports) module.exports = factory(); else window.intlTelInput = factory();
2988 })(function(undefined) {
2989 "use strict";
2990 return function() {
2991 // Array of country objects for the flag dropdown.
2992 // Here is the criteria for the plugin to support a given country/territory
2993 // - It has an iso2 code: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
2994 // - It has it's own country calling code (it is not a sub-region of another country): https://en.wikipedia.org/wiki/List_of_country_calling_codes
2995 // - It has a flag in the region-flags project: https://github.com/behdad/region-flags/tree/gh-pages/png
2996 // - It is supported by libphonenumber (it must be listed on this page): https://github.com/googlei18n/libphonenumber/blob/master/resources/ShortNumberMetadata.xml
2997 // Each country array has the following information:
2998 // [
2999 // Country name,
3000 // iso2 code,
3001 // International dial code,
3002 // Order (if >1 country with same dial code),
3003 // Area codes
3004 // ]
3005 var allCountries = [ [ "Afghanistan (‫افغانستان‬‎)", "af", "93" ], [ "Albania (Shqipëri)", "al", "355" ], [ "Algeria (‫الجزائر‬‎)", "dz", "213" ], [ "American Samoa", "as", "1", 5, [ "684" ] ], [ "Andorra", "ad", "376" ], [ "Angola", "ao", "244" ], [ "Anguilla", "ai", "1", 6, [ "264" ] ], [ "Antigua and Barbuda", "ag", "1", 7, [ "268" ] ], [ "Argentina", "ar", "54" ], [ "Armenia (Հայաստան)", "am", "374" ], [ "Aruba", "aw", "297" ], [ "Ascension Island", "ac", "247" ], [ "Australia", "au", "61", 0 ], [ "Austria (Österreich)", "at", "43" ], [ "Azerbaijan (Azərbaycan)", "az", "994" ], [ "Bahamas", "bs", "1", 8, [ "242" ] ], [ "Bahrain (‫البحرين‬‎)", "bh", "973" ], [ "Bangladesh (বাংলাদেশ)", "bd", "880" ], [ "Barbados", "bb", "1", 9, [ "246" ] ], [ "Belarus (Беларусь)", "by", "375" ], [ "Belgium (België)", "be", "32" ], [ "Belize", "bz", "501" ], [ "Benin (Bénin)", "bj", "229" ], [ "Bermuda", "bm", "1", 10, [ "441" ] ], [ "Bhutan (འབྲུག)", "bt", "975" ], [ "Bolivia", "bo", "591" ], [ "Bosnia and Herzegovina (Босна и Херцеговина)", "ba", "387" ], [ "Botswana", "bw", "267" ], [ "Brazil (Brasil)", "br", "55" ], [ "British Indian Ocean Territory", "io", "246" ], [ "British Virgin Islands", "vg", "1", 11, [ "284" ] ], [ "Brunei", "bn", "673" ], [ "Bulgaria (България)", "bg", "359" ], [ "Burkina Faso", "bf", "226" ], [ "Burundi (Uburundi)", "bi", "257" ], [ "Cambodia (កម្ពុជា)", "kh", "855" ], [ "Cameroon (Cameroun)", "cm", "237" ], [ "Canada", "ca", "1", 1, [ "204", "226", "236", "249", "250", "289", "306", "343", "365", "387", "403", "416", "418", "431", "437", "438", "450", "506", "514", "519", "548", "579", "581", "587", "604", "613", "639", "647", "672", "705", "709", "742", "778", "780", "782", "807", "819", "825", "867", "873", "902", "905" ] ], [ "Cape Verde (Kabu Verdi)", "cv", "238" ], [ "Caribbean Netherlands", "bq", "599", 1, [ "3", "4", "7" ] ], [ "Cayman Islands", "ky", "1", 12, [ "345" ] ], [ "Central African Republic (République centrafricaine)", "cf", "236" ], [ "Chad (Tchad)", "td", "235" ], [ "Chile", "cl", "56" ], [ "China (中国)", "cn", "86" ], [ "Christmas Island", "cx", "61", 2, [ "89164" ] ], [ "Cocos (Keeling) Islands", "cc", "61", 1, [ "89162" ] ], [ "Colombia", "co", "57" ], [ "Comoros (‫جزر الق�
3006 ر‬‎)", "km", "269" ], [ "Congo (DRC) (Jamhuri ya Kidemokrasia ya Kongo)", "cd", "243" ], [ "Congo (Republic) (Congo-Brazzaville)", "cg", "242" ], [ "Cook Islands", "ck", "682" ], [ "Costa Rica", "cr", "506" ], [ "Côte d’Ivoire", "ci", "225" ], [ "Croatia (Hrvatska)", "hr", "385" ], [ "Cuba", "cu", "53" ], [ "Curaçao", "cw", "599", 0 ], [ "Cyprus (Κύπρος)", "cy", "357" ], [ "Czech Republic (Česká republika)", "cz", "420" ], [ "Denmark (Danmark)", "dk", "45" ], [ "Djibouti", "dj", "253" ], [ "Dominica", "dm", "1", 13, [ "767" ] ], [ "Dominican Republic (República Dominicana)", "do", "1", 2, [ "809", "829", "849" ] ], [ "Ecuador", "ec", "593" ], [ "Egypt (‫�
3007 صر‬‎)", "eg", "20" ], [ "El Salvador", "sv", "503" ], [ "Equatorial Guinea (Guinea Ecuatorial)", "gq", "240" ], [ "Eritrea", "er", "291" ], [ "Estonia (Eesti)", "ee", "372" ], [ "Eswatini", "sz", "268" ], [ "Ethiopia", "et", "251" ], [ "Falkland Islands (Islas Malvinas)", "fk", "500" ], [ "Faroe Islands (Føroyar)", "fo", "298" ], [ "Fiji", "fj", "679" ], [ "Finland (Suomi)", "fi", "358", 0 ], [ "France", "fr", "33" ], [ "French Guiana (Guyane française)", "gf", "594" ], [ "French Polynesia (Polynésie française)", "pf", "689" ], [ "Gabon", "ga", "241" ], [ "Gambia", "gm", "220" ], [ "Georgia (საქართველო)", "ge", "995" ], [ "Germany (Deutschland)", "de", "49" ], [ "Ghana (Gaana)", "gh", "233" ], [ "Gibraltar", "gi", "350" ], [ "Greece (Ελλάδα)", "gr", "30" ], [ "Greenland (Kalaallit Nunaat)", "gl", "299" ], [ "Grenada", "gd", "1", 14, [ "473" ] ], [ "Guadeloupe", "gp", "590", 0 ], [ "Guam", "gu", "1", 15, [ "671" ] ], [ "Guatemala", "gt", "502" ], [ "Guernsey", "gg", "44", 1, [ "1481", "7781", "7839", "7911" ] ], [ "Guinea (Guinée)", "gn", "224" ], [ "Guinea-Bissau (Guiné Bissau)", "gw", "245" ], [ "Guyana", "gy", "592" ], [ "Haiti", "ht", "509" ], [ "Honduras", "hn", "504" ], [ "Hong Kong (香港)", "hk", "852" ], [ "Hungary (Magyarország)", "hu", "36" ], [ "Iceland (Ísland)", "is", "354" ], [ "India (भारत)", "in", "91" ], [ "Indonesia", "id", "62" ], [ "Iran (‫ایران‬‎)", "ir", "98" ], [ "Iraq (‫العراق‬‎)", "iq", "964" ], [ "Ireland", "ie", "353" ], [ "Isle of Man", "im", "44", 2, [ "1624", "74576", "7524", "7924", "7624" ] ], [ "Israel (‫ישראל‬‎)", "il", "972" ], [ "Italy (Italia)", "it", "39", 0 ], [ "Jamaica", "jm", "1", 4, [ "876", "658" ] ], [ "Japan (日本)", "jp", "81" ], [ "Jersey", "je", "44", 3, [ "1534", "7509", "7700", "7797", "7829", "7937" ] ], [ "Jordan (‫الأردن‬‎)", "jo", "962" ], [ "Kazakhstan (Каза�
3008 стан)", "kz", "7", 1, [ "33", "7" ] ], [ "Kenya", "ke", "254" ], [ "Kiribati", "ki", "686" ], [ "Kosovo", "xk", "383" ], [ "Kuwait (‫الكويت‬‎)", "kw", "965" ], [ "Kyrgyzstan (Кыргызстан)", "kg", "996" ], [ "Laos (ລາວ)", "la", "856" ], [ "Latvia (Latvija)", "lv", "371" ], [ "Lebanon (‫لبنان‬‎)", "lb", "961" ], [ "Lesotho", "ls", "266" ], [ "Liberia", "lr", "231" ], [ "Libya (‫ليبيا‬‎)", "ly", "218" ], [ "Liechtenstein", "li", "423" ], [ "Lithuania (Lietuva)", "lt", "370" ], [ "Luxembourg", "lu", "352" ], [ "Macau (澳門)", "mo", "853" ], [ "North Macedonia (Македонија)", "mk", "389" ], [ "Madagascar (Madagasikara)", "mg", "261" ], [ "Malawi", "mw", "265" ], [ "Malaysia", "my", "60" ], [ "Maldives", "mv", "960" ], [ "Mali", "ml", "223" ], [ "Malta", "mt", "356" ], [ "Marshall Islands", "mh", "692" ], [ "Martinique", "mq", "596" ], [ "Mauritania (‫�
3009 وريتانيا‬‎)", "mr", "222" ], [ "Mauritius (Moris)", "mu", "230" ], [ "Mayotte", "yt", "262", 1, [ "269", "639" ] ], [ "Mexico (México)", "mx", "52" ], [ "Micronesia", "fm", "691" ], [ "Moldova (Republica Moldova)", "md", "373" ], [ "Monaco", "mc", "377" ], [ "Mongolia (Монгол)", "mn", "976" ], [ "Montenegro (Crna Gora)", "me", "382" ], [ "Montserrat", "ms", "1", 16, [ "664" ] ], [ "Morocco (‫ال�
3010 غرب‬‎)", "ma", "212", 0 ], [ "Mozambique (Moçambique)", "mz", "258" ], [ "Myanmar (Burma) (မြန်မာ)", "mm", "95" ], [ "Namibia (Namibië)", "na", "264" ], [ "Nauru", "nr", "674" ], [ "Nepal (नेपाल)", "np", "977" ], [ "Netherlands (Nederland)", "nl", "31" ], [ "New Caledonia (Nouvelle-Calédonie)", "nc", "687" ], [ "New Zealand", "nz", "64" ], [ "Nicaragua", "ni", "505" ], [ "Niger (Nijar)", "ne", "227" ], [ "Nigeria", "ng", "234" ], [ "Niue", "nu", "683" ], [ "Norfolk Island", "nf", "672" ], [ "North Korea (조선 민주주의 인민 공화국)", "kp", "850" ], [ "Northern Mariana Islands", "mp", "1", 17, [ "670" ] ], [ "Norway (Norge)", "no", "47", 0 ], [ "Oman (‫عُ�
3011 ان‬‎)", "om", "968" ], [ "Pakistan (‫پاکستان‬‎)", "pk", "92" ], [ "Palau", "pw", "680" ], [ "Palestine (‫فلسطين‬‎)", "ps", "970" ], [ "Panama (Panamá)", "pa", "507" ], [ "Papua New Guinea", "pg", "675" ], [ "Paraguay", "py", "595" ], [ "Peru (Perú)", "pe", "51" ], [ "Philippines", "ph", "63" ], [ "Poland (Polska)", "pl", "48" ], [ "Portugal", "pt", "351" ], [ "Puerto Rico", "pr", "1", 3, [ "787", "939" ] ], [ "Qatar (‫قطر‬‎)", "qa", "974" ], [ "Réunion (La Réunion)", "re", "262", 0 ], [ "Romania (România)", "ro", "40" ], [ "Russia (Россия)", "ru", "7", 0 ], [ "Rwanda", "rw", "250" ], [ "Saint Barthélemy", "bl", "590", 1 ], [ "Saint Helena", "sh", "290" ], [ "Saint Kitts and Nevis", "kn", "1", 18, [ "869" ] ], [ "Saint Lucia", "lc", "1", 19, [ "758" ] ], [ "Saint Martin (Saint-Martin (partie française))", "mf", "590", 2 ], [ "Saint Pierre and Miquelon (Saint-Pierre-et-Miquelon)", "pm", "508" ], [ "Saint Vincent and the Grenadines", "vc", "1", 20, [ "784" ] ], [ "Samoa", "ws", "685" ], [ "San Marino", "sm", "378" ], [ "São Tomé and Príncipe (São Tomé e Príncipe)", "st", "239" ], [ "Saudi Arabia (‫ال�
3012
3013 لكة العربية السعودية‬‎)", "sa", "966" ], [ "Senegal (Sénégal)", "sn", "221" ], [ "Serbia (Србија)", "rs", "381" ], [ "Seychelles", "sc", "248" ], [ "Sierra Leone", "sl", "232" ], [ "Singapore", "sg", "65" ], [ "Sint Maarten", "sx", "1", 21, [ "721" ] ], [ "Slovakia (Slovensko)", "sk", "421" ], [ "Slovenia (Slovenija)", "si", "386" ], [ "Solomon Islands", "sb", "677" ], [ "Somalia (Soomaaliya)", "so", "252" ], [ "South Africa", "za", "27" ], [ "South Korea (대한민국)", "kr", "82" ], [ "South Sudan (‫جنوب السودان‬‎)", "ss", "211" ], [ "Spain (España)", "es", "34" ], [ "Sri Lanka (ශ්‍රී ලංකාව)", "lk", "94" ], [ "Sudan (‫السودان‬‎)", "sd", "249" ], [ "Suriname", "sr", "597" ], [ "Svalbard and Jan Mayen", "sj", "47", 1, [ "79" ] ], [ "Sweden (Sverige)", "se", "46" ], [ "Switzerland (Schweiz)", "ch", "41" ], [ "Syria (‫سوريا‬‎)", "sy", "963" ], [ "Taiwan (台灣)", "tw", "886" ], [ "Tajikistan", "tj", "992" ], [ "Tanzania", "tz", "255" ], [ "Thailand (ไทย)", "th", "66" ], [ "Timor-Leste", "tl", "670" ], [ "Togo", "tg", "228" ], [ "Tokelau", "tk", "690" ], [ "Tonga", "to", "676" ], [ "Trinidad and Tobago", "tt", "1", 22, [ "868" ] ], [ "Tunisia (‫تونس‬‎)", "tn", "216" ], [ "Turkey (Türkiye)", "tr", "90" ], [ "Turkmenistan", "tm", "993" ], [ "Turks and Caicos Islands", "tc", "1", 23, [ "649" ] ], [ "Tuvalu", "tv", "688" ], [ "U.S. Virgin Islands", "vi", "1", 24, [ "340" ] ], [ "Uganda", "ug", "256" ], [ "Ukraine (Україна)", "ua", "380" ], [ "United Arab Emirates (‫الإ�
3014 ارات العربية ال�
3015 تحدة‬‎)", "ae", "971" ], [ "United Kingdom", "gb", "44", 0 ], [ "United States", "us", "1", 0 ], [ "Uruguay", "uy", "598" ], [ "Uzbekistan (Oʻzbekiston)", "uz", "998" ], [ "Vanuatu", "vu", "678" ], [ "Vatican City (Città del Vaticano)", "va", "39", 1, [ "06698" ] ], [ "Venezuela", "ve", "58" ], [ "Vietnam (Việt Nam)", "vn", "84" ], [ "Wallis and Futuna (Wallis-et-Futuna)", "wf", "681" ], [ "Western Sahara (‫الصحراء الغربية‬‎)", "eh", "212", 1, [ "5288", "5289" ] ], [ "Yemen (‫الي�
3016 ن‬‎)", "ye", "967" ], [ "Zambia", "zm", "260" ], [ "Zimbabwe", "zw", "263" ], [ "�
3017 land Islands", "ax", "358", 1, [ "18" ] ] ];
3018 // loop over all of the countries above, restructuring the data to be objects with named keys
3019 for (var i = 0; i < allCountries.length; i++) {
3020 var c = allCountries[i];
3021 allCountries[i] = {
3022 name: c[0],
3023 iso2: c[1],
3024 dialCode: c[2],
3025 priority: c[3] || 0,
3026 areaCodes: c[4] || null
3027 };
3028 }
3029 "use strict";
3030 function _classCallCheck(instance, Constructor) {
3031 if (!(instance instanceof Constructor)) {
3032 throw new TypeError("Cannot call a class as a function");
3033 }
3034 }
3035 function _defineProperties(target, props) {
3036 for (var i = 0; i < props.length; i++) {
3037 var descriptor = props[i];
3038 descriptor.enumerable = descriptor.enumerable || false;
3039 descriptor.configurable = true;
3040 if ("value" in descriptor) descriptor.writable = true;
3041 Object.defineProperty(target, descriptor.key, descriptor);
3042 }
3043 }
3044 function _createClass(Constructor, protoProps, staticProps) {
3045 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
3046 if (staticProps) _defineProperties(Constructor, staticProps);
3047 return Constructor;
3048 }
3049 var intlTelInputGlobals = {
3050 getInstance: function getInstance(input) {
3051 var id = input.getAttribute("data-intl-tel-input-id");
3052 return window.intlTelInputGlobals.instances[id];
3053 },
3054 instances: {},
3055 // using a global like this allows us to mock it in the tests
3056 documentReady: function documentReady() {
3057 return document.readyState === "complete";
3058 }
3059 };
3060 if (typeof window === "object") window.intlTelInputGlobals = intlTelInputGlobals;
3061 // these vars persist through all instances of the plugin
3062 var id = 0;
3063 var defaults = {
3064 // whether or not to allow the dropdown
3065 allowDropdown: true,
3066 // if there is just a dial code in the input: remove it on blur
3067 autoHideDialCode: true,
3068 // add a placeholder in the input with an example number for the selected country
3069 autoPlaceholder: "polite",
3070 // modify the parentClass
3071 customContainer: "",
3072 // modify the auto placeholder
3073 customPlaceholder: null,
3074 // append menu to specified element
3075 dropdownContainer: null,
3076 // don't display these countries
3077 excludeCountries: [],
3078 // format the input value during initialisation and on setNumber
3079 formatOnDisplay: true,
3080 // geoIp lookup function
3081 geoIpLookup: null,
3082 // inject a hidden input with this name, and on submit, populate it with the result of getNumber
3083 hiddenInput: "",
3084 // initial country
3085 initialCountry: "",
3086 // localized country names e.g. { 'de': 'Deutschland' }
3087 localizedCountries: null,
3088 // don't insert international dial codes
3089 nationalMode: true,
3090 // display only these countries
3091 onlyCountries: [],
3092 // number type to use for placeholders
3093 placeholderNumberType: "MOBILE",
3094 // the countries at the top of the list. defaults to united states and united kingdom
3095 preferredCountries: [ "us", "gb" ],
3096 // display the country dial code next to the selected flag so it's not part of the typed number
3097 separateDialCode: false,
3098 // specify the path to the libphonenumber script to enable validation/formatting
3099 utilsScript: ""
3100 };
3101 // https://en.wikipedia.org/wiki/List_of_North_American_Numbering_Plan_area_codes#Non-geographic_area_codes
3102 var regionlessNanpNumbers = [ "800", "822", "833", "844", "855", "866", "877", "880", "881", "882", "883", "884", "885", "886", "887", "888", "889" ];
3103 // utility function to iterate over an object. can't use Object.entries or native forEach because
3104 // of IE11
3105 var forEachProp = function forEachProp(obj, callback) {
3106 var keys = Object.keys(obj);
3107 for (var i = 0; i < keys.length; i++) {
3108 callback(keys[i], obj[keys[i]]);
3109 }
3110 };
3111 // run a method on each instance of the plugin
3112 var forEachInstance = function forEachInstance(method) {
3113 forEachProp(window.intlTelInputGlobals.instances, function(key) {
3114 window.intlTelInputGlobals.instances[key][method]();
3115 });
3116 };
3117 // this is our plugin class that we will create an instance of
3118 // eslint-disable-next-line no-unused-vars
3119 var Iti = /*#__PURE__*/
3120 function() {
3121 function Iti(input, options) {
3122 var _this = this;
3123 _classCallCheck(this, Iti);
3124 this.id = id++;
3125 this.telInput = input;
3126 this.activeItem = null;
3127 this.highlightedItem = null;
3128 // process specified options / defaults
3129 // alternative to Object.assign, which isn't supported by IE11
3130 var customOptions = options || {};
3131 this.options = {};
3132 forEachProp(defaults, function(key, value) {
3133 _this.options[key] = customOptions.hasOwnProperty(key) ? customOptions[key] : value;
3134 });
3135 this.hadInitialPlaceholder = Boolean(input.getAttribute("placeholder"));
3136 }
3137 _createClass(Iti, [ {
3138 key: "_init",
3139 value: function _init() {
3140 var _this2 = this;
3141 // if in nationalMode, disable options relating to dial codes
3142 if (this.options.nationalMode) this.options.autoHideDialCode = false;
3143 // if separateDialCode then doesn't make sense to A) insert dial code into input
3144 // (autoHideDialCode), and B) display national numbers (because we're displaying the country
3145 // dial code next to them)
3146 if (this.options.separateDialCode) {
3147 this.options.autoHideDialCode = this.options.nationalMode = false;
3148 }
3149 // we cannot just test screen size as some smartphones/website meta tags will report desktop
3150 // resolutions
3151 // Note: for some reason jasmine breaks if you put this in the main Plugin function with the
3152 // rest of these declarations
3153 // Note: to target Android Mobiles (and not Tablets), we must find 'Android' and 'Mobile'
3154 this.isMobile = /Android.+Mobile|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
3155 if (this.isMobile) {
3156 // trigger the mobile dropdown css
3157 document.body.classList.add("iti-mobile");
3158 // on mobile, we want a full screen dropdown, so we must append it to the body
3159 if (!this.options.dropdownContainer) this.options.dropdownContainer = document.body;
3160 }
3161 // these promises get resolved when their individual requests complete
3162 // this way the dev can do something like iti.promise.then(...) to know when all requests are
3163 // complete
3164 if (typeof Promise !== "undefined") {
3165 var autoCountryPromise = new Promise(function(resolve, reject) {
3166 _this2.resolveAutoCountryPromise = resolve;
3167 _this2.rejectAutoCountryPromise = reject;
3168 });
3169 var utilsScriptPromise = new Promise(function(resolve, reject) {
3170 _this2.resolveUtilsScriptPromise = resolve;
3171 _this2.rejectUtilsScriptPromise = reject;
3172 });
3173 this.promise = Promise.all([ autoCountryPromise, utilsScriptPromise ]);
3174 } else {
3175 // prevent errors when Promise doesn't exist
3176 this.resolveAutoCountryPromise = this.rejectAutoCountryPromise = function() {};
3177 this.resolveUtilsScriptPromise = this.rejectUtilsScriptPromise = function() {};
3178 }
3179 // in various situations there could be no country selected initially, but we need to be able
3180 // to assume this variable exists
3181 this.selectedCountryData = {};
3182 // process all the data: onlyCountries, excludeCountries, preferredCountries etc
3183 this._processCountryData();
3184 // generate the markup
3185 this._generateMarkup();
3186 // set the initial state of the input value and the selected flag
3187 this._setInitialState();
3188 // start all of the event listeners: autoHideDialCode, input keydown, selectedFlag click
3189 this._initListeners();
3190 // utils script, and auto country
3191 this._initRequests();
3192 }
3193 }, {
3194 key: "_processCountryData",
3195 value: function _processCountryData() {
3196 // process onlyCountries or excludeCountries array if present
3197 this._processAllCountries();
3198 // process the countryCodes map
3199 this._processCountryCodes();
3200 // process the preferredCountries
3201 this._processPreferredCountries();
3202 // translate countries according to localizedCountries option
3203 if (this.options.localizedCountries) this._translateCountriesByLocale();
3204 // sort countries by name
3205 if (this.options.onlyCountries.length || this.options.localizedCountries) {
3206 this.countries.sort(this._countryNameSort);
3207 }
3208 }
3209 }, {
3210 key: "_addCountryCode",
3211 value: function _addCountryCode(iso2, countryCode, priority) {
3212 if (countryCode.length > this.countryCodeMaxLen) {
3213 this.countryCodeMaxLen = countryCode.length;
3214 }
3215 if (!this.countryCodes.hasOwnProperty(countryCode)) {
3216 this.countryCodes[countryCode] = [];
3217 }
3218 // bail if we already have this country for this countryCode
3219 for (var i = 0; i < this.countryCodes[countryCode].length; i++) {
3220 if (this.countryCodes[countryCode][i] === iso2) return;
3221 }
3222 // check for undefined as 0 is falsy
3223 var index = priority !== undefined ? priority : this.countryCodes[countryCode].length;
3224 this.countryCodes[countryCode][index] = iso2;
3225 }
3226 }, {
3227 key: "_processAllCountries",
3228 value: function _processAllCountries() {
3229 if (this.options.onlyCountries.length) {
3230 var lowerCaseOnlyCountries = this.options.onlyCountries.map(function(country) {
3231 return country.toLowerCase();
3232 });
3233 this.countries = allCountries.filter(function(country) {
3234 return lowerCaseOnlyCountries.indexOf(country.iso2) > -1;
3235 });
3236 } else if (this.options.excludeCountries.length) {
3237 var lowerCaseExcludeCountries = this.options.excludeCountries.map(function(country) {
3238 return country.toLowerCase();
3239 });
3240 this.countries = allCountries.filter(function(country) {
3241 return lowerCaseExcludeCountries.indexOf(country.iso2) === -1;
3242 });
3243 } else {
3244 this.countries = allCountries;
3245 }
3246 }
3247 }, {
3248 key: "_translateCountriesByLocale",
3249 value: function _translateCountriesByLocale() {
3250 for (var i = 0; i < this.countries.length; i++) {
3251 var iso = this.countries[i].iso2.toLowerCase();
3252 if (this.options.localizedCountries.hasOwnProperty(iso)) {
3253 this.countries[i].name = this.options.localizedCountries[iso];
3254 }
3255 }
3256 }
3257 }, {
3258 key: "_countryNameSort",
3259 value: function _countryNameSort(a, b) {
3260 return a.name.localeCompare(b.name);
3261 }
3262 }, {
3263 key: "_processCountryCodes",
3264 value: function _processCountryCodes() {
3265 this.countryCodeMaxLen = 0;
3266 // here we store just dial codes
3267 this.dialCodes = {};
3268 // here we store "country codes" (both dial codes and their area codes)
3269 this.countryCodes = {};
3270 // first: add dial codes
3271 for (var i = 0; i < this.countries.length; i++) {
3272 var c = this.countries[i];
3273 if (!this.dialCodes[c.dialCode]) this.dialCodes[c.dialCode] = true;
3274 this._addCountryCode(c.iso2, c.dialCode, c.priority);
3275 }
3276 // next: add area codes
3277 // this is a second loop over countries, to make sure we have all of the "root" countries
3278 // already in the map, so that we can access them, as each time we add an area code substring
3279 // to the map, we also need to include the "root" country's code, as that also matches
3280 for (var _i = 0; _i < this.countries.length; _i++) {
3281 var _c = this.countries[_i];
3282 // area codes
3283 if (_c.areaCodes) {
3284 var rootCountryCode = this.countryCodes[_c.dialCode][0];
3285 // for each area code
3286 for (var j = 0; j < _c.areaCodes.length; j++) {
3287 var areaCode = _c.areaCodes[j];
3288 // for each digit in the area code to add all partial matches as well
3289 for (var k = 1; k < areaCode.length; k++) {
3290 var partialDialCode = _c.dialCode + areaCode.substr(0, k);
3291 // start with the root country, as that also matches this dial code
3292 this._addCountryCode(rootCountryCode, partialDialCode);
3293 this._addCountryCode(_c.iso2, partialDialCode);
3294 }
3295 // add the full area code
3296 this._addCountryCode(_c.iso2, _c.dialCode + areaCode);
3297 }
3298 }
3299 }
3300 }
3301 }, {
3302 key: "_processPreferredCountries",
3303 value: function _processPreferredCountries() {
3304 this.preferredCountries = [];
3305 for (var i = 0; i < this.options.preferredCountries.length; i++) {
3306 var countryCode = this.options.preferredCountries[i].toLowerCase();
3307 var countryData = this._getCountryData(countryCode, false, true);
3308 if (countryData) this.preferredCountries.push(countryData);
3309 }
3310 }
3311 }, {
3312 key: "_createEl",
3313 value: function _createEl(name, attrs, container) {
3314 var el = document.createElement(name);
3315 if (attrs) forEachProp(attrs, function(key, value) {
3316 return el.setAttribute(key, value);
3317 });
3318 if (container) container.appendChild(el);
3319 return el;
3320 }
3321 }, {
3322 key: "_generateMarkup",
3323 value: function _generateMarkup() {
3324 // if autocomplete does not exist on the element and its form, then
3325 // prevent autocomplete as there's no safe, cross-browser event we can react to, so it can
3326 // easily put the plugin in an inconsistent state e.g. the wrong flag selected for the
3327 // autocompleted number, which on submit could mean wrong number is saved (esp in nationalMode)
3328 if (!this.telInput.hasAttribute("autocomplete") && !(this.telInput.form && this.telInput.form.hasAttribute("autocomplete"))) {
3329 this.telInput.setAttribute("autocomplete", "off");
3330 }
3331 // containers (mostly for positioning)
3332 var parentClass = "iti";
3333 if (this.options.allowDropdown) parentClass += " iti--allow-dropdown";
3334 if (this.options.separateDialCode) parentClass += " iti--separate-dial-code";
3335 if (this.options.customContainer) {
3336 parentClass += " ";
3337 parentClass += this.options.customContainer;
3338 }
3339 var wrapper = this._createEl("div", {
3340 "class": parentClass
3341 });
3342 this.telInput.parentNode.insertBefore(wrapper, this.telInput);
3343 this.flagsContainer = this._createEl("div", {
3344 "class": "iti__flag-container"
3345 }, wrapper);
3346 wrapper.appendChild(this.telInput);
3347 // selected flag (displayed to left of input)
3348 this.selectedFlag = this._createEl("div", {
3349 "class": "iti__selected-flag",
3350 role: "combobox",
3351 "aria-controls": "iti-".concat(this.id, "__country-listbox"),
3352 "aria-owns": "iti-".concat(this.id, "__country-listbox"),
3353 "aria-expanded": "false"
3354 }, this.flagsContainer);
3355 this.selectedFlagInner = this._createEl("div", {
3356 "class": "iti__flag"
3357 }, this.selectedFlag);
3358 if (this.options.separateDialCode) {
3359 this.selectedDialCode = this._createEl("div", {
3360 "class": "iti__selected-dial-code"
3361 }, this.selectedFlag);
3362 }
3363 if (this.options.allowDropdown) {
3364 // make element focusable and tab navigable
3365 this.selectedFlag.setAttribute("tabindex", "0");
3366 this.dropdownArrow = this._createEl("div", {
3367 "class": "iti__arrow"
3368 }, this.selectedFlag);
3369 // country dropdown: preferred countries, then divider, then all countries
3370 this.countryList = this._createEl("ul", {
3371 "class": "iti__country-list iti__hide",
3372 id: "iti-".concat(this.id, "__country-listbox"),
3373 role: "listbox",
3374 "aria-label": "List of countries"
3375 });
3376 if (this.preferredCountries.length) {
3377 this._appendListItems(this.preferredCountries, "iti__preferred", true);
3378 this._createEl("li", {
3379 "class": "iti__divider",
3380 role: "separator",
3381 "aria-disabled": "true"
3382 }, this.countryList);
3383 }
3384 this._appendListItems(this.countries, "iti__standard");
3385 // create dropdownContainer markup
3386 if (this.options.dropdownContainer) {
3387 this.dropdown = this._createEl("div", {
3388 "class": "iti iti--container"
3389 });
3390 this.dropdown.appendChild(this.countryList);
3391 } else {
3392 this.flagsContainer.appendChild(this.countryList);
3393 }
3394 }
3395 if (this.options.hiddenInput) {
3396 var hiddenInputName = this.options.hiddenInput;
3397 var name = this.telInput.getAttribute("name");
3398 if (name) {
3399 var i = name.lastIndexOf("[");
3400 // if input name contains square brackets, then give the hidden input the same name,
3401 // replacing the contents of the last set of brackets with the given hiddenInput name
3402 if (i !== -1) hiddenInputName = "".concat(name.substr(0, i), "[").concat(hiddenInputName, "]");
3403 }
3404 this.hiddenInput = this._createEl("input", {
3405 type: "hidden",
3406 name: hiddenInputName
3407 });
3408 wrapper.appendChild(this.hiddenInput);
3409 }
3410 }
3411 }, {
3412 key: "_appendListItems",
3413 value: function _appendListItems(countries, className, preferred) {
3414 // we create so many DOM elements, it is faster to build a temp string
3415 // and then add everything to the DOM in one go at the end
3416 var tmp = "";
3417 // for each country
3418 for (var i = 0; i < countries.length; i++) {
3419 var c = countries[i];
3420 var idSuffix = preferred ? "-preferred" : "";
3421 // open the list item
3422 tmp += "<li class='iti__country ".concat(className, "' tabIndex='-1' id='iti-").concat(this.id, "__item-").concat(c.iso2).concat(idSuffix, "' role='option' data-dial-code='").concat(c.dialCode, "' data-country-code='").concat(c.iso2, "' aria-selected='false'>");
3423 // add the flag
3424 tmp += "<div class='iti__flag-box'><div class='iti__flag iti__".concat(c.iso2, "'></div></div>");
3425 // and the country name and dial code
3426 tmp += "<span class='iti__country-name'>".concat(c.name, "</span>");
3427 tmp += "<span class='iti__dial-code'>+".concat(c.dialCode, "</span>");
3428 // close the list item
3429 tmp += "</li>";
3430 }
3431 this.countryList.insertAdjacentHTML("beforeend", tmp);
3432 }
3433 }, {
3434 key: "_setInitialState",
3435 value: function _setInitialState() {
3436 // fix firefox bug: when first load page (with input with value set to number with intl dial
3437 // code) and initialising plugin removes the dial code from the input, then refresh page,
3438 // and we try to init plugin again but this time on number without dial code so get grey flag
3439 var attributeValue = this.telInput.getAttribute("value");
3440 var inputValue = this.telInput.value;
3441 var useAttribute = attributeValue && attributeValue.charAt(0) === "+" && (!inputValue || inputValue.charAt(0) !== "+");
3442 var val = useAttribute ? attributeValue : inputValue;
3443 var dialCode = this._getDialCode(val);
3444 var isRegionlessNanp = this._isRegionlessNanp(val);
3445 var _this$options = this.options, initialCountry = _this$options.initialCountry, nationalMode = _this$options.nationalMode, autoHideDialCode = _this$options.autoHideDialCode, separateDialCode = _this$options.separateDialCode;
3446 // if we already have a dial code, and it's not a regionlessNanp, we can go ahead and set the
3447 // flag, else fall back to the default country
3448 if (dialCode && !isRegionlessNanp) {
3449 this._updateFlagFromNumber(val);
3450 } else if (initialCountry !== "auto") {
3451 // see if we should select a flag
3452 if (initialCountry) {
3453 this._setFlag(initialCountry.toLowerCase());
3454 } else {
3455 if (dialCode && isRegionlessNanp) {
3456 // has intl dial code, is regionless nanp, and no initialCountry, so default to US
3457 this._setFlag("us");
3458 } else {
3459 // no dial code and no initialCountry, so default to first in list
3460 this.defaultCountry = this.preferredCountries.length ? this.preferredCountries[0].iso2 : this.countries[0].iso2;
3461 if (!val) {
3462 this._setFlag(this.defaultCountry);
3463 }
3464 }
3465 }
3466 // if empty and no nationalMode and no autoHideDialCode then insert the default dial code
3467 if (!val && !nationalMode && !autoHideDialCode && !separateDialCode) {
3468 this.telInput.value = "+".concat(this.selectedCountryData.dialCode);
3469 }
3470 }
3471 // NOTE: if initialCountry is set to auto, that will be handled separately
3472 // format - note this wont be run after _updateDialCode as that's only called if no val
3473 if (val) this._updateValFromNumber(val);
3474 }
3475 }, {
3476 key: "_initListeners",
3477 value: function _initListeners() {
3478 this._initKeyListeners();
3479 if (this.options.autoHideDialCode) this._initBlurListeners();
3480 if (this.options.allowDropdown) this._initDropdownListeners();
3481 if (this.hiddenInput) this._initHiddenInputListener();
3482 }
3483 }, {
3484 key: "_initHiddenInputListener",
3485 value: function _initHiddenInputListener() {
3486 var _this3 = this;
3487 this._handleHiddenInputSubmit = function() {
3488 _this3.hiddenInput.value = _this3.getNumber();
3489 };
3490 if (this.telInput.form) this.telInput.form.addEventListener("submit", this._handleHiddenInputSubmit);
3491 }
3492 }, {
3493 key: "_getClosestLabel",
3494 value: function _getClosestLabel() {
3495 var el = this.telInput;
3496 while (el && el.tagName !== "LABEL") {
3497 el = el.parentNode;
3498 }
3499 return el;
3500 }
3501 }, {
3502 key: "_initDropdownListeners",
3503 value: function _initDropdownListeners() {
3504 var _this4 = this;
3505 // hack for input nested inside label (which is valid markup): clicking the selected-flag to
3506 // open the dropdown would then automatically trigger a 2nd click on the input which would
3507 // close it again
3508 this._handleLabelClick = function(e) {
3509 // if the dropdown is closed, then focus the input, else ignore the click
3510 if (_this4.countryList.classList.contains("iti__hide")) _this4.telInput.focus(); else e.preventDefault();
3511 };
3512 var label = this._getClosestLabel();
3513 if (label) label.addEventListener("click", this._handleLabelClick);
3514 // toggle country dropdown on click
3515 this._handleClickSelectedFlag = function() {
3516 // only intercept this event if we're opening the dropdown
3517 // else let it bubble up to the top ("click-off-to-close" listener)
3518 // we cannot just stopPropagation as it may be needed to close another instance
3519 if (_this4.countryList.classList.contains("iti__hide") && !_this4.telInput.disabled && !_this4.telInput.readOnly) {
3520 _this4._showDropdown();
3521 }
3522 };
3523 this.selectedFlag.addEventListener("click", this._handleClickSelectedFlag);
3524 // open dropdown list if currently focused
3525 this._handleFlagsContainerKeydown = function(e) {
3526 var isDropdownHidden = _this4.countryList.classList.contains("iti__hide");
3527 if (isDropdownHidden && [ "ArrowUp", "Up", "ArrowDown", "Down", " ", "Enter" ].indexOf(e.key) !== -1) {
3528 // prevent form from being submitted if "ENTER" was pressed
3529 e.preventDefault();
3530 // prevent event from being handled again by document
3531 e.stopPropagation();
3532 _this4._showDropdown();
3533 }
3534 // allow navigation from dropdown to input on TAB
3535 if (e.key === "Tab") _this4._closeDropdown();
3536 };
3537 this.flagsContainer.addEventListener("keydown", this._handleFlagsContainerKeydown);
3538 }
3539 }, {
3540 key: "_initRequests",
3541 value: function _initRequests() {
3542 var _this5 = this;
3543 // if the user has specified the path to the utils script, fetch it on window.load, else resolve
3544 if (this.options.utilsScript && !window.intlTelInputUtils) {
3545 // if the plugin is being initialised after the window.load event has already been fired
3546 if (window.intlTelInputGlobals.documentReady()) {
3547 window.intlTelInputGlobals.loadUtils(this.options.utilsScript);
3548 } else {
3549 // wait until the load event so we don't block any other requests e.g. the flags image
3550 window.addEventListener("load", function() {
3551 window.intlTelInputGlobals.loadUtils(_this5.options.utilsScript);
3552 });
3553 }
3554 } else this.resolveUtilsScriptPromise();
3555 if (this.options.initialCountry === "auto") this._loadAutoCountry(); else this.resolveAutoCountryPromise();
3556 }
3557 }, {
3558 key: "_loadAutoCountry",
3559 value: function _loadAutoCountry() {
3560 // 3 options:
3561 // 1) already loaded (we're done)
3562 // 2) not already started loading (start)
3563 // 3) already started loading (do nothing - just wait for loading callback to fire)
3564 if (window.intlTelInputGlobals.autoCountry) {
3565 this.handleAutoCountry();
3566 } else if (!window.intlTelInputGlobals.startedLoadingAutoCountry) {
3567 // don't do this twice!
3568 window.intlTelInputGlobals.startedLoadingAutoCountry = true;
3569 if (typeof this.options.geoIpLookup === "function") {
3570 this.options.geoIpLookup(function(countryCode) {
3571 window.intlTelInputGlobals.autoCountry = countryCode.toLowerCase();
3572 // tell all instances the auto country is ready
3573 // TODO: this should just be the current instances
3574 // UPDATE: use setTimeout in case their geoIpLookup function calls this callback straight
3575 // away (e.g. if they have already done the geo ip lookup somewhere else). Using
3576 // setTimeout means that the current thread of execution will finish before executing
3577 // this, which allows the plugin to finish initialising.
3578 setTimeout(function() {
3579 return forEachInstance("handleAutoCountry");
3580 });
3581 }, function() {
3582 return forEachInstance("rejectAutoCountryPromise");
3583 });
3584 }
3585 }
3586 }
3587 }, {
3588 key: "_initKeyListeners",
3589 value: function _initKeyListeners() {
3590 var _this6 = this;
3591 // update flag on keyup
3592 this._handleKeyupEvent = function() {
3593 if (_this6._updateFlagFromNumber(_this6.telInput.value)) {
3594 _this6._triggerCountryChange();
3595 }
3596 };
3597 this.telInput.addEventListener("keyup", this._handleKeyupEvent);
3598 // update flag on cut/paste events (now supported in all major browsers)
3599 this._handleClipboardEvent = function() {
3600 // hack because "paste" event is fired before input is updated
3601 setTimeout(_this6._handleKeyupEvent);
3602 };
3603 this.telInput.addEventListener("cut", this._handleClipboardEvent);
3604 this.telInput.addEventListener("paste", this._handleClipboardEvent);
3605 }
3606 }, {
3607 key: "_cap",
3608 value: function _cap(number) {
3609 var max = this.telInput.getAttribute("maxlength");
3610 return max && number.length > max ? number.substr(0, max) : number;
3611 }
3612 }, {
3613 key: "_initBlurListeners",
3614 value: function _initBlurListeners() {
3615 var _this7 = this;
3616 // on blur or form submit: if just a dial code then remove it
3617 this._handleSubmitOrBlurEvent = function() {
3618 _this7._removeEmptyDialCode();
3619 };
3620 if (this.telInput.form) this.telInput.form.addEventListener("submit", this._handleSubmitOrBlurEvent);
3621 this.telInput.addEventListener("blur", this._handleSubmitOrBlurEvent);
3622 }
3623 }, {
3624 key: "_removeEmptyDialCode",
3625 value: function _removeEmptyDialCode() {
3626 if (this.telInput.value.charAt(0) === "+") {
3627 var numeric = this._getNumeric(this.telInput.value);
3628 // if just a plus, or if just a dial code
3629 if (!numeric || this.selectedCountryData.dialCode === numeric) {
3630 this.telInput.value = "";
3631 }
3632 }
3633 }
3634 }, {
3635 key: "_getNumeric",
3636 value: function _getNumeric(s) {
3637 return s.replace(/\D/g, "");
3638 }
3639 }, {
3640 key: "_trigger",
3641 value: function _trigger(name) {
3642 // have to use old school document.createEvent as IE11 doesn't support `new Event()` syntax
3643 var e = document.createEvent("Event");
3644 e.initEvent(name, true, true);
3645 // can bubble, and is cancellable
3646 this.telInput.dispatchEvent(e);
3647 }
3648 }, {
3649 key: "_showDropdown",
3650 value: function _showDropdown() {
3651 this.countryList.classList.remove("iti__hide");
3652 this.selectedFlag.setAttribute("aria-expanded", "true");
3653 this._setDropdownPosition();
3654 // update highlighting and scroll to active list item
3655 if (this.activeItem) {
3656 this._highlightListItem(this.activeItem, false);
3657 this._scrollTo(this.activeItem, true);
3658 }
3659 // bind all the dropdown-related listeners: mouseover, click, click-off, keydown
3660 this._bindDropdownListeners();
3661 // update the arrow
3662 this.dropdownArrow.classList.add("iti__arrow--up");
3663 this._trigger("open:countrydropdown");
3664 }
3665 }, {
3666 key: "_toggleClass",
3667 value: function _toggleClass(el, className, shouldHaveClass) {
3668 if (shouldHaveClass && !el.classList.contains(className)) el.classList.add(className); else if (!shouldHaveClass && el.classList.contains(className)) el.classList.remove(className);
3669 }
3670 }, {
3671 key: "_setDropdownPosition",
3672 value: function _setDropdownPosition() {
3673 var _this8 = this;
3674 if (this.options.dropdownContainer) {
3675 this.options.dropdownContainer.appendChild(this.dropdown);
3676 }
3677 if (!this.isMobile) {
3678 var pos = this.telInput.getBoundingClientRect();
3679 // windowTop from https://stackoverflow.com/a/14384091/217866
3680 var windowTop = window.pageYOffset || document.documentElement.scrollTop;
3681 var inputTop = pos.top + windowTop;
3682 var dropdownHeight = this.countryList.offsetHeight;
3683 // dropdownFitsBelow = (dropdownBottom < windowBottom)
3684 var dropdownFitsBelow = inputTop + this.telInput.offsetHeight + dropdownHeight < windowTop + window.innerHeight;
3685 var dropdownFitsAbove = inputTop - dropdownHeight > windowTop;
3686 // by default, the dropdown will be below the input. If we want to position it above the
3687 // input, we add the dropup class.
3688 this._toggleClass(this.countryList, "iti__country-list--dropup", !dropdownFitsBelow && dropdownFitsAbove);
3689 // if dropdownContainer is enabled, calculate postion
3690 if (this.options.dropdownContainer) {
3691 // by default the dropdown will be directly over the input because it's not in the flow.
3692 // If we want to position it below, we need to add some extra top value.
3693 var extraTop = !dropdownFitsBelow && dropdownFitsAbove ? 0 : this.telInput.offsetHeight;
3694 // calculate placement
3695 this.dropdown.style.top = "".concat(inputTop + extraTop, "px");
3696 this.dropdown.style.left = "".concat(pos.left + document.body.scrollLeft, "px");
3697 // close menu on window scroll
3698 this._handleWindowScroll = function() {
3699 return _this8._closeDropdown();
3700 };
3701 window.addEventListener("scroll", this._handleWindowScroll);
3702 }
3703 }
3704 }
3705 }, {
3706 key: "_getClosestListItem",
3707 value: function _getClosestListItem(target) {
3708 var el = target;
3709 while (el && el !== this.countryList && !el.classList.contains("iti__country")) {
3710 el = el.parentNode;
3711 }
3712 // if we reached the countryList element, then return null
3713 return el === this.countryList ? null : el;
3714 }
3715 }, {
3716 key: "_bindDropdownListeners",
3717 value: function _bindDropdownListeners() {
3718 var _this9 = this;
3719 // when mouse over a list item, just highlight that one
3720 // we add the class "highlight", so if they hit "enter" we know which one to select
3721 this._handleMouseoverCountryList = function(e) {
3722 // handle event delegation, as we're listening for this event on the countryList
3723 var listItem = _this9._getClosestListItem(e.target);
3724 if (listItem) _this9._highlightListItem(listItem, false);
3725 };
3726 this.countryList.addEventListener("mouseover", this._handleMouseoverCountryList);
3727 // listen for country selection
3728 this._handleClickCountryList = function(e) {
3729 var listItem = _this9._getClosestListItem(e.target);
3730 if (listItem) _this9._selectListItem(listItem);
3731 };
3732 this.countryList.addEventListener("click", this._handleClickCountryList);
3733 // click off to close
3734 // (except when this initial opening click is bubbling up)
3735 // we cannot just stopPropagation as it may be needed to close another instance
3736 var isOpening = true;
3737 this._handleClickOffToClose = function() {
3738 if (!isOpening) _this9._closeDropdown();
3739 isOpening = false;
3740 };
3741 document.documentElement.addEventListener("click", this._handleClickOffToClose);
3742 // listen for up/down scrolling, enter to select, or letters to jump to country name.
3743 // use keydown as keypress doesn't fire for non-char keys and we want to catch if they
3744 // just hit down and hold it to scroll down (no keyup event).
3745 // listen on the document because that's where key events are triggered if no input has focus
3746 var query = "";
3747 var queryTimer = null;
3748 this._handleKeydownOnDropdown = function(e) {
3749 // prevent down key from scrolling the whole page,
3750 // and enter key from submitting a form etc
3751 e.preventDefault();
3752 // up and down to navigate
3753 if (e.key === "ArrowUp" || e.key === "Up" || e.key === "ArrowDown" || e.key === "Down") _this9._handleUpDownKey(e.key); else if (e.key === "Enter") _this9._handleEnterKey(); else if (e.key === "Escape") _this9._closeDropdown(); else if (/^[a-zA-ZÀ-ÿа-яА-Я ]$/.test(e.key)) {
3754 // jump to countries that start with the query string
3755 if (queryTimer) clearTimeout(queryTimer);
3756 query += e.key.toLowerCase();
3757 _this9._searchForCountry(query);
3758 // if the timer hits 1 second, reset the query
3759 queryTimer = setTimeout(function() {
3760 query = "";
3761 }, 1e3);
3762 }
3763 };
3764 document.addEventListener("keydown", this._handleKeydownOnDropdown);
3765 }
3766 }, {
3767 key: "_handleUpDownKey",
3768 value: function _handleUpDownKey(key) {
3769 var next = key === "ArrowUp" || key === "Up" ? this.highlightedItem.previousElementSibling : this.highlightedItem.nextElementSibling;
3770 if (next) {
3771 // skip the divider
3772 if (next.classList.contains("iti__divider")) {
3773 next = key === "ArrowUp" || key === "Up" ? next.previousElementSibling : next.nextElementSibling;
3774 }
3775 this._highlightListItem(next, true);
3776 }
3777 }
3778 }, {
3779 key: "_handleEnterKey",
3780 value: function _handleEnterKey() {
3781 if (this.highlightedItem) this._selectListItem(this.highlightedItem);
3782 }
3783 }, {
3784 key: "_searchForCountry",
3785 value: function _searchForCountry(query) {
3786 for (var i = 0; i < this.countries.length; i++) {
3787 if (this._startsWith(this.countries[i].name, query)) {
3788 var listItem = this.countryList.querySelector("#iti-".concat(this.id, "__item-").concat(this.countries[i].iso2));
3789 // update highlighting and scroll
3790 this._highlightListItem(listItem, false);
3791 this._scrollTo(listItem, true);
3792 break;
3793 }
3794 }
3795 }
3796 }, {
3797 key: "_startsWith",
3798 value: function _startsWith(a, b) {
3799 return a.substr(0, b.length).toLowerCase() === b;
3800 }
3801 }, {
3802 key: "_updateValFromNumber",
3803 value: function _updateValFromNumber(originalNumber) {
3804 var number = originalNumber;
3805 if (this.options.formatOnDisplay && window.intlTelInputUtils && this.selectedCountryData) {
3806 var useNational = !this.options.separateDialCode && (this.options.nationalMode || number.charAt(0) !== "+");
3807 var _intlTelInputUtils$nu = intlTelInputUtils.numberFormat, NATIONAL = _intlTelInputUtils$nu.NATIONAL, INTERNATIONAL = _intlTelInputUtils$nu.INTERNATIONAL;
3808 var format = useNational ? NATIONAL : INTERNATIONAL;
3809 number = intlTelInputUtils.formatNumber(number, this.selectedCountryData.iso2, format);
3810 }
3811 number = this._beforeSetNumber(number);
3812 this.telInput.value = number;
3813 }
3814 }, {
3815 key: "_updateFlagFromNumber",
3816 value: function _updateFlagFromNumber(originalNumber) {
3817 // if we're in nationalMode and we already have US/Canada selected, make sure the number starts
3818 // with a +1 so _getDialCode will be able to extract the area code
3819 // update: if we dont yet have selectedCountryData, but we're here (trying to update the flag
3820 // from the number), that means we're initialising the plugin with a number that already has a
3821 // dial code, so fine to ignore this bit
3822 var number = originalNumber;
3823 var selectedDialCode = this.selectedCountryData.dialCode;
3824 var isNanp = selectedDialCode === "1";
3825 if (number && this.options.nationalMode && isNanp && number.charAt(0) !== "+") {
3826 if (number.charAt(0) !== "1") number = "1".concat(number);
3827 number = "+".concat(number);
3828 }
3829 // update flag if user types area code for another country
3830 if (this.options.separateDialCode && selectedDialCode && number.charAt(0) !== "+") {
3831 number = "+".concat(selectedDialCode).concat(number);
3832 }
3833 // try and extract valid dial code from input
3834 var dialCode = this._getDialCode(number, true);
3835 var numeric = this._getNumeric(number);
3836 var countryCode = null;
3837 if (dialCode) {
3838 var countryCodes = this.countryCodes[this._getNumeric(dialCode)];
3839 // check if the right country is already selected. this should be false if the number is
3840 // longer than the matched dial code because in this case we need to make sure that if
3841 // there are multiple country matches, that the first one is selected (note: we could
3842 // just check that here, but it requires the same loop that we already have later)
3843 var alreadySelected = countryCodes.indexOf(this.selectedCountryData.iso2) !== -1 && numeric.length <= dialCode.length - 1;
3844 var isRegionlessNanpNumber = selectedDialCode === "1" && this._isRegionlessNanp(numeric);
3845 // only update the flag if:
3846 // A) NOT (we currently have a NANP flag selected, and the number is a regionlessNanp)
3847 // AND
3848 // B) the right country is not already selected
3849 if (!isRegionlessNanpNumber && !alreadySelected) {
3850 // if using onlyCountries option, countryCodes[0] may be empty, so we must find the first
3851 // non-empty index
3852 for (var j = 0; j < countryCodes.length; j++) {
3853 if (countryCodes[j]) {
3854 countryCode = countryCodes[j];
3855 break;
3856 }
3857 }
3858 }
3859 } else if (number.charAt(0) === "+" && numeric.length) {
3860 // invalid dial code, so empty
3861 // Note: use getNumeric here because the number has not been formatted yet, so could contain
3862 // bad chars
3863 countryCode = "";
3864 } else if (!number || number === "+") {
3865 // empty, or just a plus, so default
3866 countryCode = this.defaultCountry;
3867 }
3868 if (countryCode !== null) {
3869 return this._setFlag(countryCode);
3870 }
3871 return false;
3872 }
3873 }, {
3874 key: "_isRegionlessNanp",
3875 value: function _isRegionlessNanp(number) {
3876 var numeric = this._getNumeric(number);
3877 if (numeric.charAt(0) === "1") {
3878 var areaCode = numeric.substr(1, 3);
3879 return regionlessNanpNumbers.indexOf(areaCode) !== -1;
3880 }
3881 return false;
3882 }
3883 }, {
3884 key: "_highlightListItem",
3885 value: function _highlightListItem(listItem, shouldFocus) {
3886 var prevItem = this.highlightedItem;
3887 if (prevItem) prevItem.classList.remove("iti__highlight");
3888 this.highlightedItem = listItem;
3889 this.highlightedItem.classList.add("iti__highlight");
3890 if (shouldFocus) this.highlightedItem.focus();
3891 }
3892 }, {
3893 key: "_getCountryData",
3894 value: function _getCountryData(countryCode, ignoreOnlyCountriesOption, allowFail) {
3895 var countryList = ignoreOnlyCountriesOption ? allCountries : this.countries;
3896 for (var i = 0; i < countryList.length; i++) {
3897 if (countryList[i].iso2 === countryCode) {
3898 return countryList[i];
3899 }
3900 }
3901 if (allowFail) {
3902 return null;
3903 }
3904 throw new Error("No country data for '".concat(countryCode, "'"));
3905 }
3906 }, {
3907 key: "_setFlag",
3908 value: function _setFlag(countryCode) {
3909 var prevCountry = this.selectedCountryData.iso2 ? this.selectedCountryData : {};
3910 // do this first as it will throw an error and stop if countryCode is invalid
3911 this.selectedCountryData = countryCode ? this._getCountryData(countryCode, false, false) : {};
3912 // update the defaultCountry - we only need the iso2 from now on, so just store that
3913 if (this.selectedCountryData.iso2) {
3914 this.defaultCountry = this.selectedCountryData.iso2;
3915 }
3916 this.selectedFlagInner.setAttribute("class", "iti__flag iti__".concat(countryCode));
3917 // update the selected country's title attribute
3918 var title = countryCode ? "".concat(this.selectedCountryData.name, ": +").concat(this.selectedCountryData.dialCode) : "Unknown";
3919 this.selectedFlag.setAttribute("title", title);
3920 if (this.options.separateDialCode) {
3921 var dialCode = this.selectedCountryData.dialCode ? "+".concat(this.selectedCountryData.dialCode) : "";
3922 this.selectedDialCode.innerHTML = dialCode;
3923 // offsetWidth is zero if input is in a hidden container during initialisation
3924 var selectedFlagWidth = this.selectedFlag.offsetWidth || this._getHiddenSelectedFlagWidth();
3925 // add 6px of padding after the grey selected-dial-code box, as this is what we use in the css
3926 this.telInput.style.paddingLeft = "".concat(selectedFlagWidth + 6, "px");
3927 }
3928 // and the input's placeholder
3929 this._updatePlaceholder();
3930 // update the active list item
3931 if (this.options.allowDropdown) {
3932 var prevItem = this.activeItem;
3933 if (prevItem) {
3934 prevItem.classList.remove("iti__active");
3935 prevItem.setAttribute("aria-selected", "false");
3936 }
3937 if (countryCode) {
3938 // check if there is a preferred item first, else fall back to standard
3939 var nextItem = this.countryList.querySelector("#iti-".concat(this.id, "__item-").concat(countryCode, "-preferred")) || this.countryList.querySelector("#iti-".concat(this.id, "__item-").concat(countryCode));
3940 nextItem.setAttribute("aria-selected", "true");
3941 nextItem.classList.add("iti__active");
3942 this.activeItem = nextItem;
3943 this.selectedFlag.setAttribute("aria-activedescendant", nextItem.getAttribute("id"));
3944 }
3945 }
3946 // return if the flag has changed or not
3947 return prevCountry.iso2 !== countryCode;
3948 }
3949 }, {
3950 key: "_getHiddenSelectedFlagWidth",
3951 value: function _getHiddenSelectedFlagWidth() {
3952 // to get the right styling to apply, all we need is a shallow clone of the container,
3953 // and then to inject a deep clone of the selectedFlag element
3954 var containerClone = this.telInput.parentNode.cloneNode();
3955 containerClone.style.visibility = "hidden";
3956 document.body.appendChild(containerClone);
3957 var flagsContainerClone = this.flagsContainer.cloneNode();
3958 containerClone.appendChild(flagsContainerClone);
3959 var selectedFlagClone = this.selectedFlag.cloneNode(true);
3960 flagsContainerClone.appendChild(selectedFlagClone);
3961 var width = selectedFlagClone.offsetWidth;
3962 containerClone.parentNode.removeChild(containerClone);
3963 return width;
3964 }
3965 }, {
3966 key: "_updatePlaceholder",
3967 value: function _updatePlaceholder() {
3968 var shouldSetPlaceholder = this.options.autoPlaceholder === "aggressive" || !this.hadInitialPlaceholder && this.options.autoPlaceholder === "polite";
3969 if (window.intlTelInputUtils && shouldSetPlaceholder) {
3970 var numberType = intlTelInputUtils.numberType[this.options.placeholderNumberType];
3971 var placeholder = this.selectedCountryData.iso2 ? intlTelInputUtils.getExampleNumber(this.selectedCountryData.iso2, this.options.nationalMode, numberType) : "";
3972 placeholder = this._beforeSetNumber(placeholder);
3973 if (typeof this.options.customPlaceholder === "function") {
3974 placeholder = this.options.customPlaceholder(placeholder, this.selectedCountryData);
3975 }
3976 this.telInput.setAttribute("placeholder", placeholder);
3977 }
3978 }
3979 }, {
3980 key: "_selectListItem",
3981 value: function _selectListItem(listItem) {
3982 // update selected flag and active list item
3983 var flagChanged = this._setFlag(listItem.getAttribute("data-country-code"));
3984 this._closeDropdown();
3985 this._updateDialCode(listItem.getAttribute("data-dial-code"), true);
3986 // focus the input
3987 this.telInput.focus();
3988 // put cursor at end - this fix is required for FF and IE11 (with nationalMode=false i.e. auto
3989 // inserting dial code), who try to put the cursor at the beginning the first time
3990 var len = this.telInput.value.length;
3991 this.telInput.setSelectionRange(len, len);
3992 if (flagChanged) {
3993 this._triggerCountryChange();
3994 }
3995 }
3996 }, {
3997 key: "_closeDropdown",
3998 value: function _closeDropdown() {
3999 this.countryList.classList.add("iti__hide");
4000 this.selectedFlag.setAttribute("aria-expanded", "false");
4001 // update the arrow
4002 this.dropdownArrow.classList.remove("iti__arrow--up");
4003 // unbind key events
4004 document.removeEventListener("keydown", this._handleKeydownOnDropdown);
4005 document.documentElement.removeEventListener("click", this._handleClickOffToClose);
4006 this.countryList.removeEventListener("mouseover", this._handleMouseoverCountryList);
4007 this.countryList.removeEventListener("click", this._handleClickCountryList);
4008 // remove menu from container
4009 if (this.options.dropdownContainer) {
4010 if (!this.isMobile) window.removeEventListener("scroll", this._handleWindowScroll);
4011 if (this.dropdown.parentNode) this.dropdown.parentNode.removeChild(this.dropdown);
4012 }
4013 this._trigger("close:countrydropdown");
4014 }
4015 }, {
4016 key: "_scrollTo",
4017 value: function _scrollTo(element, middle) {
4018 var container = this.countryList;
4019 // windowTop from https://stackoverflow.com/a/14384091/217866
4020 var windowTop = window.pageYOffset || document.documentElement.scrollTop;
4021 var containerHeight = container.offsetHeight;
4022 var containerTop = container.getBoundingClientRect().top + windowTop;
4023 var containerBottom = containerTop + containerHeight;
4024 var elementHeight = element.offsetHeight;
4025 var elementTop = element.getBoundingClientRect().top + windowTop;
4026 var elementBottom = elementTop + elementHeight;
4027 var newScrollTop = elementTop - containerTop + container.scrollTop;
4028 var middleOffset = containerHeight / 2 - elementHeight / 2;
4029 if (elementTop < containerTop) {
4030 // scroll up
4031 if (middle) newScrollTop -= middleOffset;
4032 container.scrollTop = newScrollTop;
4033 } else if (elementBottom > containerBottom) {
4034 // scroll down
4035 if (middle) newScrollTop += middleOffset;
4036 var heightDifference = containerHeight - elementHeight;
4037 container.scrollTop = newScrollTop - heightDifference;
4038 }
4039 }
4040 }, {
4041 key: "_updateDialCode",
4042 value: function _updateDialCode(newDialCodeBare, hasSelectedListItem) {
4043 var inputVal = this.telInput.value;
4044 // save having to pass this every time
4045 var newDialCode = "+".concat(newDialCodeBare);
4046 var newNumber;
4047 if (inputVal.charAt(0) === "+") {
4048 // there's a plus so we're dealing with a replacement (doesn't matter if nationalMode or not)
4049 var prevDialCode = this._getDialCode(inputVal);
4050 if (prevDialCode) {
4051 // current number contains a valid dial code, so replace it
4052 newNumber = inputVal.replace(prevDialCode, newDialCode);
4053 } else {
4054 // current number contains an invalid dial code, so ditch it
4055 // (no way to determine where the invalid dial code ends and the rest of the number begins)
4056 newNumber = newDialCode;
4057 }
4058 } else if (this.options.nationalMode || this.options.separateDialCode) {
4059 // don't do anything
4060 return;
4061 } else {
4062 // nationalMode is disabled
4063 if (inputVal) {
4064 // there is an existing value with no dial code: prefix the new dial code
4065 newNumber = newDialCode + inputVal;
4066 } else if (hasSelectedListItem || !this.options.autoHideDialCode) {
4067 // no existing value and either they've just selected a list item, or autoHideDialCode is
4068 // disabled: insert new dial code
4069 newNumber = newDialCode;
4070 } else {
4071 return;
4072 }
4073 }
4074 this.telInput.value = newNumber;
4075 }
4076 }, {
4077 key: "_getDialCode",
4078 value: function _getDialCode(number, includeAreaCode) {
4079 var dialCode = "";
4080 // only interested in international numbers (starting with a plus)
4081 if (number.charAt(0) === "+") {
4082 var numericChars = "";
4083 // iterate over chars
4084 for (var i = 0; i < number.length; i++) {
4085 var c = number.charAt(i);
4086 // if char is number (https://stackoverflow.com/a/8935649/217866)
4087 if (!isNaN(parseInt(c, 10))) {
4088 numericChars += c;
4089 // if current numericChars make a valid dial code
4090 if (includeAreaCode) {
4091 if (this.countryCodes[numericChars]) {
4092 // store the actual raw string (useful for matching later)
4093 dialCode = number.substr(0, i + 1);
4094 }
4095 } else {
4096 if (this.dialCodes[numericChars]) {
4097 dialCode = number.substr(0, i + 1);
4098 // if we're just looking for a dial code, we can break as soon as we find one
4099 break;
4100 }
4101 }
4102 // stop searching as soon as we can - in this case when we hit max len
4103 if (numericChars.length === this.countryCodeMaxLen) {
4104 break;
4105 }
4106 }
4107 }
4108 }
4109 return dialCode;
4110 }
4111 }, {
4112 key: "_getFullNumber",
4113 value: function _getFullNumber() {
4114 var val = this.telInput.value.trim();
4115 var dialCode = this.selectedCountryData.dialCode;
4116 var prefix;
4117 var numericVal = this._getNumeric(val);
4118 if (this.options.separateDialCode && val.charAt(0) !== "+" && dialCode && numericVal) {
4119 // when using separateDialCode, it is visible so is effectively part of the typed number
4120 prefix = "+".concat(dialCode);
4121 } else {
4122 prefix = "";
4123 }
4124 return prefix + val;
4125 }
4126 }, {
4127 key: "_beforeSetNumber",
4128 value: function _beforeSetNumber(originalNumber) {
4129 var number = originalNumber;
4130 if (this.options.separateDialCode) {
4131 var dialCode = this._getDialCode(number);
4132 // if there is a valid dial code
4133 if (dialCode) {
4134 // in case _getDialCode returned an area code as well
4135 dialCode = "+".concat(this.selectedCountryData.dialCode);
4136 // a lot of numbers will have a space separating the dial code and the main number, and
4137 // some NANP numbers will have a hyphen e.g. +1 684-733-1234 - in both cases we want to get
4138 // rid of it
4139 // NOTE: don't just trim all non-numerics as may want to preserve an open parenthesis etc
4140 var start = number[dialCode.length] === " " || number[dialCode.length] === "-" ? dialCode.length + 1 : dialCode.length;
4141 number = number.substr(start);
4142 }
4143 }
4144 return this._cap(number);
4145 }
4146 }, {
4147 key: "_triggerCountryChange",
4148 value: function _triggerCountryChange() {
4149 this._trigger("countrychange");
4150 }
4151 }, {
4152 key: "handleAutoCountry",
4153 value: function handleAutoCountry() {
4154 if (this.options.initialCountry === "auto") {
4155 // we must set this even if there is an initial val in the input: in case the initial val is
4156 // invalid and they delete it - they should see their auto country
4157 this.defaultCountry = window.intlTelInputGlobals.autoCountry;
4158 // if there's no initial value in the input, then update the flag
4159 if (!this.telInput.value) {
4160 this.setCountry(this.defaultCountry);
4161 }
4162 this.resolveAutoCountryPromise();
4163 }
4164 }
4165 }, {
4166 key: "handleUtils",
4167 value: function handleUtils() {
4168 // if the request was successful
4169 if (window.intlTelInputUtils) {
4170 // if there's an initial value in the input, then format it
4171 if (this.telInput.value) {
4172 this._updateValFromNumber(this.telInput.value);
4173 }
4174 this._updatePlaceholder();
4175 }
4176 this.resolveUtilsScriptPromise();
4177 }
4178 }, {
4179 key: "destroy",
4180 value: function destroy() {
4181 var form = this.telInput.form;
4182 if (this.options.allowDropdown) {
4183 // make sure the dropdown is closed (and unbind listeners)
4184 this._closeDropdown();
4185 this.selectedFlag.removeEventListener("click", this._handleClickSelectedFlag);
4186 this.flagsContainer.removeEventListener("keydown", this._handleFlagsContainerKeydown);
4187 // label click hack
4188 var label = this._getClosestLabel();
4189 if (label) label.removeEventListener("click", this._handleLabelClick);
4190 }
4191 // unbind hiddenInput listeners
4192 if (this.hiddenInput && form) form.removeEventListener("submit", this._handleHiddenInputSubmit);
4193 // unbind autoHideDialCode listeners
4194 if (this.options.autoHideDialCode) {
4195 if (form) form.removeEventListener("submit", this._handleSubmitOrBlurEvent);
4196 this.telInput.removeEventListener("blur", this._handleSubmitOrBlurEvent);
4197 }
4198 // unbind key events, and cut/paste events
4199 this.telInput.removeEventListener("keyup", this._handleKeyupEvent);
4200 this.telInput.removeEventListener("cut", this._handleClipboardEvent);
4201 this.telInput.removeEventListener("paste", this._handleClipboardEvent);
4202 // remove attribute of id instance: data-intl-tel-input-id
4203 this.telInput.removeAttribute("data-intl-tel-input-id");
4204 // remove markup (but leave the original input)
4205 var wrapper = this.telInput.parentNode;
4206 wrapper.parentNode.insertBefore(this.telInput, wrapper);
4207 wrapper.parentNode.removeChild(wrapper);
4208 delete window.intlTelInputGlobals.instances[this.id];
4209 }
4210 }, {
4211 key: "getExtension",
4212 value: function getExtension() {
4213 if (window.intlTelInputUtils) {
4214 return intlTelInputUtils.getExtension(this._getFullNumber(), this.selectedCountryData.iso2);
4215 }
4216 return "";
4217 }
4218 }, {
4219 key: "getNumber",
4220 value: function getNumber(format) {
4221 if (window.intlTelInputUtils) {
4222 var iso2 = this.selectedCountryData.iso2;
4223 return intlTelInputUtils.formatNumber(this._getFullNumber(), iso2, format);
4224 }
4225 return "";
4226 }
4227 }, {
4228 key: "getNumberType",
4229 value: function getNumberType() {
4230 if (window.intlTelInputUtils) {
4231 return intlTelInputUtils.getNumberType(this._getFullNumber(), this.selectedCountryData.iso2);
4232 }
4233 return -99;
4234 }
4235 }, {
4236 key: "getSelectedCountryData",
4237 value: function getSelectedCountryData() {
4238 return this.selectedCountryData;
4239 }
4240 }, {
4241 key: "getValidationError",
4242 value: function getValidationError() {
4243 if (window.intlTelInputUtils) {
4244 var iso2 = this.selectedCountryData.iso2;
4245 return intlTelInputUtils.getValidationError(this._getFullNumber(), iso2);
4246 }
4247 return -99;
4248 }
4249 }, {
4250 key: "isValidNumber",
4251 value: function isValidNumber() {
4252 var val = this._getFullNumber().trim();
4253 var countryCode = this.options.nationalMode ? this.selectedCountryData.iso2 : "";
4254 return window.intlTelInputUtils ? intlTelInputUtils.isValidNumber(val, countryCode) : null;
4255 }
4256 }, {
4257 key: "setCountry",
4258 value: function setCountry(originalCountryCode) {
4259 var countryCode = originalCountryCode.toLowerCase();
4260 // check if already selected
4261 if (!this.selectedFlagInner.classList.contains("iti__".concat(countryCode))) {
4262 this._setFlag(countryCode);
4263 this._updateDialCode(this.selectedCountryData.dialCode, false);
4264 this._triggerCountryChange();
4265 }
4266 }
4267 }, {
4268 key: "setNumber",
4269 value: function setNumber(number) {
4270 // we must update the flag first, which updates this.selectedCountryData, which is used for
4271 // formatting the number before displaying it
4272 var flagChanged = this._updateFlagFromNumber(number);
4273 this._updateValFromNumber(number);
4274 if (flagChanged) {
4275 this._triggerCountryChange();
4276 }
4277 }
4278 }, {
4279 key: "setPlaceholderNumberType",
4280 value: function setPlaceholderNumberType(type) {
4281 this.options.placeholderNumberType = type;
4282 this._updatePlaceholder();
4283 }
4284 } ]);
4285 return Iti;
4286 }();
4287 /********************
4288 * STATIC METHODS
4289 ********************/
4290 // get the country data object
4291 intlTelInputGlobals.getCountryData = function() {
4292 return allCountries;
4293 };
4294 // inject a <script> element to load utils.js
4295 var injectScript = function injectScript(path, handleSuccess, handleFailure) {
4296 // inject a new script element into the page
4297 var script = document.createElement("script");
4298 script.onload = function() {
4299 forEachInstance("handleUtils");
4300 if (handleSuccess) handleSuccess();
4301 };
4302 script.onerror = function() {
4303 forEachInstance("rejectUtilsScriptPromise");
4304 if (handleFailure) handleFailure();
4305 };
4306 script.className = "iti-load-utils";
4307 script.async = true;
4308 script.src = path;
4309 document.body.appendChild(script);
4310 };
4311 // load the utils script
4312 intlTelInputGlobals.loadUtils = function(path) {
4313 // 2 options:
4314 // 1) not already started loading (start)
4315 // 2) already started loading (do nothing - just wait for the onload callback to fire, which will
4316 // trigger handleUtils on all instances, invoking their resolveUtilsScriptPromise functions)
4317 if (!window.intlTelInputUtils && !window.intlTelInputGlobals.startedLoadingUtilsScript) {
4318 // only do this once
4319 window.intlTelInputGlobals.startedLoadingUtilsScript = true;
4320 // if we have promises, then return a promise
4321 if (typeof Promise !== "undefined") {
4322 return new Promise(function(resolve, reject) {
4323 return injectScript(path, resolve, reject);
4324 });
4325 }
4326 injectScript(path);
4327 }
4328 return null;
4329 };
4330 // default options
4331 intlTelInputGlobals.defaults = defaults;
4332 // version
4333 intlTelInputGlobals.version = "17.0.16";
4334 // convenience wrapper
4335 return function(input, options) {
4336 var iti = new Iti(input, options);
4337 iti._init();
4338 input.setAttribute("data-intl-tel-input-id", iti.id);
4339 window.intlTelInputGlobals.instances[iti.id] = iti;
4340 return iti;
4341 };
4342 }();
4343 });
4344 },{}],19:[function(require,module,exports){
4345 /**
4346 * Exposing intl-tel-input as a component
4347 */
4348 module.exports = require("./build/js/intlTelInput");
4349
4350 },{"./build/js/intlTelInput":18}],20:[function(require,module,exports){
4351 (function (process){
4352 /**
4353 * Memize options object.
4354 *
4355 * @typedef MemizeOptions
4356 *
4357 * @property {number} [maxSize] Maximum size of the cache.
4358 */
4359
4360 /**
4361 * Internal cache entry.
4362 *
4363 * @typedef MemizeCacheNode
4364 *
4365 * @property {?MemizeCacheNode|undefined} [prev] Previous node.
4366 * @property {?MemizeCacheNode|undefined} [next] Next node.
4367 * @property {Array<*>} args Function arguments for cache
4368 * entry.
4369 * @property {*} val Function result.
4370 */
4371
4372 /**
4373 * Properties of the enhanced function for controlling cache.
4374 *
4375 * @typedef MemizeMemoizedFunction
4376 *
4377 * @property {()=>void} clear Clear the cache.
4378 */
4379
4380 /**
4381 * Accepts a function to be memoized, and returns a new memoized function, with
4382 * optional options.
4383 *
4384 * @template {Function} F
4385 *
4386 * @param {F} fn Function to memoize.
4387 * @param {MemizeOptions} [options] Options object.
4388 *
4389 * @return {F & MemizeMemoizedFunction} Memoized function.
4390 */
4391 function memize( fn, options ) {
4392 var size = 0;
4393
4394 /** @type {?MemizeCacheNode|undefined} */
4395 var head;
4396
4397 /** @type {?MemizeCacheNode|undefined} */
4398 var tail;
4399
4400 options = options || {};
4401
4402 function memoized( /* ...args */ ) {
4403 var node = head,
4404 len = arguments.length,
4405 args, i;
4406
4407 searchCache: while ( node ) {
4408 // Perform a shallow equality test to confirm that whether the node
4409 // under test is a candidate for the arguments passed. Two arrays
4410 // are shallowly equal if their length matches and each entry is
4411 // strictly equal between the two sets. Avoid abstracting to a
4412 // function which could incur an arguments leaking deoptimization.
4413
4414 // Check whether node arguments match arguments length
4415 if ( node.args.length !== arguments.length ) {
4416 node = node.next;
4417 continue;
4418 }
4419
4420 // Check whether node arguments match arguments values
4421 for ( i = 0; i < len; i++ ) {
4422 if ( node.args[ i ] !== arguments[ i ] ) {
4423 node = node.next;
4424 continue searchCache;
4425 }
4426 }
4427
4428 // At this point we can assume we've found a match
4429
4430 // Surface matched node to head if not already
4431 if ( node !== head ) {
4432 // As tail, shift to previous. Must only shift if not also
4433 // head, since if both head and tail, there is no previous.
4434 if ( node === tail ) {
4435 tail = node.prev;
4436 }
4437
4438 // Adjust siblings to point to each other. If node was tail,
4439 // this also handles new tail's empty `next` assignment.
4440 /** @type {MemizeCacheNode} */ ( node.prev ).next = node.next;
4441 if ( node.next ) {
4442 node.next.prev = node.prev;
4443 }
4444
4445 node.next = head;
4446 node.prev = null;
4447 /** @type {MemizeCacheNode} */ ( head ).prev = node;
4448 head = node;
4449 }
4450
4451 // Return immediately
4452 return node.val;
4453 }
4454
4455 // No cached value found. Continue to insertion phase:
4456
4457 // Create a copy of arguments (avoid leaking deoptimization)
4458 args = new Array( len );
4459 for ( i = 0; i < len; i++ ) {
4460 args[ i ] = arguments[ i ];
4461 }
4462
4463 node = {
4464 args: args,
4465
4466 // Generate the result from original function
4467 val: fn.apply( null, args ),
4468 };
4469
4470 // Don't need to check whether node is already head, since it would
4471 // have been returned above already if it was
4472
4473 // Shift existing head down list
4474 if ( head ) {
4475 head.prev = node;
4476 node.next = head;
4477 } else {
4478 // If no head, follows that there's no tail (at initial or reset)
4479 tail = node;
4480 }
4481
4482 // Trim tail if we're reached max size and are pending cache insertion
4483 if ( size === /** @type {MemizeOptions} */ ( options ).maxSize ) {
4484 tail = /** @type {MemizeCacheNode} */ ( tail ).prev;
4485 /** @type {MemizeCacheNode} */ ( tail ).next = null;
4486 } else {
4487 size++;
4488 }
4489
4490 head = node;
4491
4492 return node.val;
4493 }
4494
4495 memoized.clear = function() {
4496 head = null;
4497 tail = null;
4498 size = 0;
4499 };
4500
4501 if ( process.env.NODE_ENV === 'test' ) {
4502 // Cache is not exposed in the public API, but used in tests to ensure
4503 // expected list progression
4504 memoized.getCache = function() {
4505 return [ head, tail, size ];
4506 };
4507 }
4508
4509 // Ignore reason: There's not a clear solution to create an intersection of
4510 // the function with additional properties, where the goal is to retain the
4511 // function signature of the incoming argument and add control properties
4512 // on the return value.
4513
4514 // @ts-ignore
4515 return memoized;
4516 }
4517
4518 module.exports = memize;
4519
4520 }).call(this,require('_process'))
4521 },{"_process":21}],21:[function(require,module,exports){
4522 // shim for using process in browser
4523 var process = module.exports = {};
4524
4525 // cached from whatever global is present so that test runners that stub it
4526 // don't break things. But we need to wrap it in a try catch in case it is
4527 // wrapped in strict mode code which doesn't define any globals. It's inside a
4528 // function because try/catches deoptimize in certain engines.
4529
4530 var cachedSetTimeout;
4531 var cachedClearTimeout;
4532
4533 function defaultSetTimout() {
4534 throw new Error('setTimeout has not been defined');
4535 }
4536 function defaultClearTimeout () {
4537 throw new Error('clearTimeout has not been defined');
4538 }
4539 (function () {
4540 try {
4541 if (typeof setTimeout === 'function') {
4542 cachedSetTimeout = setTimeout;
4543 } else {
4544 cachedSetTimeout = defaultSetTimout;
4545 }
4546 } catch (e) {
4547 cachedSetTimeout = defaultSetTimout;
4548 }
4549 try {
4550 if (typeof clearTimeout === 'function') {
4551 cachedClearTimeout = clearTimeout;
4552 } else {
4553 cachedClearTimeout = defaultClearTimeout;
4554 }
4555 } catch (e) {
4556 cachedClearTimeout = defaultClearTimeout;
4557 }
4558 } ())
4559 function runTimeout(fun) {
4560 if (cachedSetTimeout === setTimeout) {
4561 //normal enviroments in sane situations
4562 return setTimeout(fun, 0);
4563 }
4564 // if setTimeout wasn't available but was latter defined
4565 if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
4566 cachedSetTimeout = setTimeout;
4567 return setTimeout(fun, 0);
4568 }
4569 try {
4570 // when when somebody has screwed with setTimeout but no I.E. maddness
4571 return cachedSetTimeout(fun, 0);
4572 } catch(e){
4573 try {
4574 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
4575 return cachedSetTimeout.call(null, fun, 0);
4576 } catch(e){
4577 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
4578 return cachedSetTimeout.call(this, fun, 0);
4579 }
4580 }
4581
4582
4583 }
4584 function runClearTimeout(marker) {
4585 if (cachedClearTimeout === clearTimeout) {
4586 //normal enviroments in sane situations
4587 return clearTimeout(marker);
4588 }
4589 // if clearTimeout wasn't available but was latter defined
4590 if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
4591 cachedClearTimeout = clearTimeout;
4592 return clearTimeout(marker);
4593 }
4594 try {
4595 // when when somebody has screwed with setTimeout but no I.E. maddness
4596 return cachedClearTimeout(marker);
4597 } catch (e){
4598 try {
4599 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
4600 return cachedClearTimeout.call(null, marker);
4601 } catch (e){
4602 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
4603 // Some versions of I.E. have different rules for clearTimeout vs setTimeout
4604 return cachedClearTimeout.call(this, marker);
4605 }
4606 }
4607
4608
4609
4610 }
4611 var queue = [];
4612 var draining = false;
4613 var currentQueue;
4614 var queueIndex = -1;
4615
4616 function cleanUpNextTick() {
4617 if (!draining || !currentQueue) {
4618 return;
4619 }
4620 draining = false;
4621 if (currentQueue.length) {
4622 queue = currentQueue.concat(queue);
4623 } else {
4624 queueIndex = -1;
4625 }
4626 if (queue.length) {
4627 drainQueue();
4628 }
4629 }
4630
4631 function drainQueue() {
4632 if (draining) {
4633 return;
4634 }
4635 var timeout = runTimeout(cleanUpNextTick);
4636 draining = true;
4637
4638 var len = queue.length;
4639 while(len) {
4640 currentQueue = queue;
4641 queue = [];
4642 while (++queueIndex < len) {
4643 if (currentQueue) {
4644 currentQueue[queueIndex].run();
4645 }
4646 }
4647 queueIndex = -1;
4648 len = queue.length;
4649 }
4650 currentQueue = null;
4651 draining = false;
4652 runClearTimeout(timeout);
4653 }
4654
4655 process.nextTick = function (fun) {
4656 var args = new Array(arguments.length - 1);
4657 if (arguments.length > 1) {
4658 for (var i = 1; i < arguments.length; i++) {
4659 args[i - 1] = arguments[i];
4660 }
4661 }
4662 queue.push(new Item(fun, args));
4663 if (queue.length === 1 && !draining) {
4664 runTimeout(drainQueue);
4665 }
4666 };
4667
4668 // v8 likes predictible objects
4669 function Item(fun, array) {
4670 this.fun = fun;
4671 this.array = array;
4672 }
4673 Item.prototype.run = function () {
4674 this.fun.apply(null, this.array);
4675 };
4676 process.title = 'browser';
4677 process.browser = true;
4678 process.env = {};
4679 process.argv = [];
4680 process.version = ''; // empty string to avoid regexp issues
4681 process.versions = {};
4682
4683 function noop() {}
4684
4685 process.on = noop;
4686 process.addListener = noop;
4687 process.once = noop;
4688 process.off = noop;
4689 process.removeListener = noop;
4690 process.removeAllListeners = noop;
4691 process.emit = noop;
4692 process.prependListener = noop;
4693 process.prependOnceListener = noop;
4694
4695 process.listeners = function (name) { return [] }
4696
4697 process.binding = function (name) {
4698 throw new Error('process.binding is not supported');
4699 };
4700
4701 process.cwd = function () { return '/' };
4702 process.chdir = function (dir) {
4703 throw new Error('process.chdir is not supported');
4704 };
4705 process.umask = function() { return 0; };
4706
4707 },{}],22:[function(require,module,exports){
4708 'use strict';
4709
4710 function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
4711
4712 var pluralForms = _interopDefault(require('@tannin/plural-forms'));
4713
4714 /**
4715 * Tannin constructor options.
4716 *
4717 * @typedef {Object} TanninOptions
4718 *
4719 * @property {string} [contextDelimiter] Joiner in string lookup with context.
4720 * @property {Function} [onMissingKey] Callback to invoke when key missing.
4721 */
4722
4723 /**
4724 * Domain metadata.
4725 *
4726 * @typedef {Object} TanninDomainMetadata
4727 *
4728 * @property {string} [domain] Domain name.
4729 * @property {string} [lang] Language code.
4730 * @property {(string|Function)} [plural_forms] Plural forms expression or
4731 * function evaluator.
4732 */
4733
4734 /**
4735 * Domain translation pair respectively representing the singular and plural
4736 * translation.
4737 *
4738 * @typedef {[string,string]} TanninTranslation
4739 */
4740
4741 /**
4742 * Locale data domain. The key is used as reference for lookup, the value an
4743 * array of two string entries respectively representing the singular and plural
4744 * translation.
4745 *
4746 * @typedef {{[key:string]:TanninDomainMetadata|TanninTranslation,'':TanninDomainMetadata|TanninTranslation}} TanninLocaleDomain
4747 */
4748
4749 /**
4750 * Jed-formatted locale data.
4751 *
4752 * @see http://messageformat.github.io/Jed/
4753 *
4754 * @typedef {{[domain:string]:TanninLocaleDomain}} TanninLocaleData
4755 */
4756
4757 /**
4758 * Default Tannin constructor options.
4759 *
4760 * @type {TanninOptions}
4761 */
4762 var DEFAULT_OPTIONS = {
4763 contextDelimiter: '\u0004',
4764 onMissingKey: null,
4765 };
4766
4767 /**
4768 * Given a specific locale data's config `plural_forms` value, returns the
4769 * expression.
4770 *
4771 * @example
4772 *
4773 * ```
4774 * getPluralExpression( 'nplurals=2; plural=(n != 1);' ) === '(n != 1)'
4775 * ```
4776 *
4777 * @param {string} pf Locale data plural forms.
4778 *
4779 * @return {string} Plural forms expression.
4780 */
4781 function getPluralExpression( pf ) {
4782 var parts, i, part;
4783
4784 parts = pf.split( ';' );
4785
4786 for ( i = 0; i < parts.length; i++ ) {
4787 part = parts[ i ].trim();
4788 if ( part.indexOf( 'plural=' ) === 0 ) {
4789 return part.substr( 7 );
4790 }
4791 }
4792 }
4793
4794 /**
4795 * Tannin constructor.
4796 *
4797 * @class
4798 *
4799 * @param {TanninLocaleData} data Jed-formatted locale data.
4800 * @param {TanninOptions} [options] Tannin options.
4801 */
4802 function Tannin( data, options ) {
4803 var key;
4804
4805 /**
4806 * Jed-formatted locale data.
4807 *
4808 * @name Tannin#data
4809 * @type {TanninLocaleData}
4810 */
4811 this.data = data;
4812
4813 /**
4814 * Plural forms function cache, keyed by plural forms string.
4815 *
4816 * @name Tannin#pluralForms
4817 * @type {Object<string,Function>}
4818 */
4819 this.pluralForms = {};
4820
4821 /**
4822 * Effective options for instance, including defaults.
4823 *
4824 * @name Tannin#options
4825 * @type {TanninOptions}
4826 */
4827 this.options = {};
4828
4829 for ( key in DEFAULT_OPTIONS ) {
4830 this.options[ key ] = options !== undefined && key in options
4831 ? options[ key ]
4832 : DEFAULT_OPTIONS[ key ];
4833 }
4834 }
4835
4836 /**
4837 * Returns the plural form index for the given domain and value.
4838 *
4839 * @param {string} domain Domain on which to calculate plural form.
4840 * @param {number} n Value for which plural form is to be calculated.
4841 *
4842 * @return {number} Plural form index.
4843 */
4844 Tannin.prototype.getPluralForm = function( domain, n ) {
4845 var getPluralForm = this.pluralForms[ domain ],
4846 config, plural, pf;
4847
4848 if ( ! getPluralForm ) {
4849 config = this.data[ domain ][ '' ];
4850
4851 pf = (
4852 config[ 'Plural-Forms' ] ||
4853 config[ 'plural-forms' ] ||
4854 // Ignore reason: As known, there's no way to document the empty
4855 // string property on a key to guarantee this as metadata.
4856 // @ts-ignore
4857 config.plural_forms
4858 );
4859
4860 if ( typeof pf !== 'function' ) {
4861 plural = getPluralExpression(
4862 config[ 'Plural-Forms' ] ||
4863 config[ 'plural-forms' ] ||
4864 // Ignore reason: As known, there's no way to document the empty
4865 // string property on a key to guarantee this as metadata.
4866 // @ts-ignore
4867 config.plural_forms
4868 );
4869
4870 pf = pluralForms( plural );
4871 }
4872
4873 getPluralForm = this.pluralForms[ domain ] = pf;
4874 }
4875
4876 return getPluralForm( n );
4877 };
4878
4879 /**
4880 * Translate a string.
4881 *
4882 * @param {string} domain Translation domain.
4883 * @param {string|void} context Context distinguishing terms of the same name.
4884 * @param {string} singular Primary key for translation lookup.
4885 * @param {string=} plural Fallback value used for non-zero plural
4886 * form index.
4887 * @param {number=} n Value to use in calculating plural form.
4888 *
4889 * @return {string} Translated string.
4890 */
4891 Tannin.prototype.dcnpgettext = function( domain, context, singular, plural, n ) {
4892 var index, key, entry;
4893
4894 if ( n === undefined ) {
4895 // Default to singular.
4896 index = 0;
4897 } else {
4898 // Find index by evaluating plural form for value.
4899 index = this.getPluralForm( domain, n );
4900 }
4901
4902 key = singular;
4903
4904 // If provided, context is prepended to key with delimiter.
4905 if ( context ) {
4906 key = context + this.options.contextDelimiter + singular;
4907 }
4908
4909 entry = this.data[ domain ][ key ];
4910
4911 // Verify not only that entry exists, but that the intended index is within
4912 // range and non-empty.
4913 if ( entry && entry[ index ] ) {
4914 return entry[ index ];
4915 }
4916
4917 if ( this.options.onMissingKey ) {
4918 this.options.onMissingKey( singular, domain );
4919 }
4920
4921 // If entry not found, fall back to singular vs. plural with zero index
4922 // representing the singular value.
4923 return index === 0 ? singular : plural;
4924 };
4925
4926 module.exports = Tannin;
4927
4928 },{"@tannin/plural-forms":11}]},{},[2]);
4929