Plugin Directory

Changeset 3743261


Ignore:
Timestamp:
10/13/2026 08:22:04 AM (10 days ago)
Author:
wahid0003
Message:

Release 3.7.89

Location:
webappick-pdf-invoice-for-woocommerce
Files:
40 edited
1 copied

Legend:

Unmodified
Added
Removed
  • webappick-pdf-invoice-for-woocommerce/tags/3.7.89/README.txt

    r3722380 r3743261  
    55Requires at least: 3.6
    66Tested up to: 7.1
    7 Stable tag: 3.7.88
     7Stable tag: 3.7.89
    88Requires PHP: 7.4
    99License: GPLv2 or later
    … …  
    309309Help us & the WordPress community, translate the plugin [here](https://translate.wordpress.org/projects/wp-plugins/webappick-pdf-invoice-for-woocommerce/)
    310310
     311= 3.7.89  ( October 13, 2026 ) =
     312* Security: Sanitized the order, product and order item meta field settings before saving.
     313* Security: Added ZIP entry validation for the mPDF library and font downloads, and enabled SSL verification for the mPDF library download.
     314* Security: Removed the site-wide REST API CORS headers.
     315* Security: Invoice template selection now accepts only available templates.
     316* Fixed: Sending an order email no longer deletes the invoice PDFs of other orders.
     317* Fixed: Fatal error "Call to undefined function get_user_id" on the settings page template preview.
     318* Fixed: Upgrade buttons in the dashboard linked to an expired discount page.
     319* Improved: Meta key lists on the settings page are cached and refreshed when settings are saved.
     320* Improved: New invoice and font directories are created with 0755 permissions.
     321
    311322= 3.7.88  ( October 01, 2026 ) =
    312323* Updated : Plugin description.
  • webappick-pdf-invoice-for-woocommerce/tags/3.7.89/admin/js/webappick-pdf-invoice-for-woocommerce-admin.js

    r3081641 r3743261  
    204204            },
    205205            success: function (response) {
     206                if (!response.success) {
     207                    return;
     208                }
    206209                $(".woo-invoice-template-preview").attr(
    207210                    "src",
  • webappick-pdf-invoice-for-woocommerce/tags/3.7.89/admin/js/webappick-pdf-invoice-for-woocommerce-admin.min.js

    r3081641 r3743261  
    1 "use strict";!function(a){a(window).scroll(function(){a(this).scrollTop()+a(window).height()<a(document).height()-150?a(".woo-invoice-save-changes-selector").addClass("woo-invoice-save-changes"):a(".woo-invoice-save-changes-selector").removeClass("woo-invoice-save-changes")}),a(window).scroll(function(){a(this).scrollTop()+a(window).height()<a(document).height()-150?a(".woo-invoice-banner-sidebar").addClass("woo-invoice-banner-sidebar-sticky"):a(".woo-invoice-banner-sidebar").removeClass("woo-invoice-banner-sidebar-sticky")}),a(window).on("mousewheel",function(e){var o=a(".woo-invoice-dashboard-content > li:eq(0)");a(".woo-invoice-dashboard-sidebar .woo-invoice-sidebar-navbar-light").height(o.parent().height()-23)}),a(window).load(function(){a("input[name='wf_tabs']").on("change",function(){var e=a(this).val();sessionStorage.setItem("active_tab",e)});var e,o,i=sessionStorage.getItem("active_tab"),t=("settings"===i?a("#tab1").attr("checked",!0):"seller&buyer"===i?a("#tab2").attr("checked",!0):"localization"===i?a("#tab3").attr("checked",!0):"bulk_download"===i&&a("#tab4").attr("checked",!0),0),n=0;a("#Date-from").on("change",function(){e=Date.parse(a(this).val()),n=1,t&&n&&o<e&&(alert("Input date should be less than or equal Date To"),a("#Date-from").val(""),n=0)}),a("#Date-to").on("change",function(){o=Date.parse(a(this).val()),(t=1)&&n&&o<e&&(alert("Input date should be greater than or equal Date From"),a("#Date-to").val(""),t=0)}),a(function(){var e,o=a(".woo-invoice-sidebar-navbar-nav > li > a"),i=a(".woo-invoice-dashboard-content > li");null!=sessionStorage.getItem("activeSidebarTab")?(e=sessionStorage.getItem("activeSidebarTab"),i.hide(),o.removeClass("active"),a(i[e]).show(),a(".woo-invoice-sidebar-navbar-nav > li:eq( "+e+" ) > a").addClass("active"),a(".woo-invoice-dashboard-sidebar .woo-invoice-sidebar-navbar-light").height(a(i[e]).parent().height()-23)):((e=a(".woo-invoice-dashboard-content > li:eq(0)")).css("display","block"),a(".woo-invoice-sidebar-navbar-nav > li:eq(0) > a").addClass("active"),a(".woo-invoice-dashboard-sidebar .woo-invoice-sidebar-navbar-light").height(e.parent().height()-23)),o.bind("click",function(e){e.preventDefault();e=a(this).parent().prevAll().length,i.hide(),o.removeClass("active"),a(i[e]).show(),a(this).addClass("active"),e=a(this).parent().prevAll().length;sessionStorage.setItem("activeSidebarTab",e),a(".woo-invoice-dashboard-sidebar .woo-invoice-sidebar-navbar-light").height(i.parent().height()-23)})})}),a(document).on("click",".woo-invoice-template-selection",function(e){e.preventDefault();e=a(this).data("template");a("#winvoiceModalTemplates").modal("hide"),a("body").removeClass(function(e,o){return(o.match(/\S+-modal-open(^|\s)/g)||[]).join(" ")}),a('div[class*="-modal-backdrop"]').remove(),a(this).find("img").removeClass("woo-invoice-template"),a(this).find("img").removeClass("woo-invoice-disable-template"),a(this).find("img").addClass("woo-invoice-slected-template"),a(".woo-invoice-element-disable").find("img").addClass("woo-invoice-template"),a(".woo-invoice-element-disable").find("img").removeClass("woo-invoice-disable-template"),a(".woo-invoice-element-disable").css("z-index","3333"),a(".woo-invoice-element-disable").siblings("div").css("z-index","1111"),a(".woo-invoice-element-disable").siblings("a").css("z-index","2222"),a(this).parent().siblings().find("img").removeClass("woo-invoice-slected-template").addClass("woo-invoice-template"),a.ajax({url:woo_invoice_ajax_obj_2.woo_invoice_ajax_url_2,type:"post",data:{_ajax_nonce:woo_invoice_ajax_obj_2.nonce,action:"wpifw_save_pdf_template",template:e},success:function(e){a(".woo-invoice-template-preview").attr("src",e.data.location+"/"+e.data.template_name+".png"),a(".invoice_template_preiview_btn").attr("href",e.data.location+"/"+e.data.template_name+".png")}})}),a(document).on("click",".woo-invoice-element-disable",function(e){e.preventDefault(),a(this).children("img").removeClass("woo-invoice-template"),a(this).children("img").addClass("woo-invoice-disable-template"),a(this).css("z-index","1111"),a(this).siblings("div").css("z-index","2222"),a(this).siblings("a").css("z-index","3333")}),flatpickr(".woo-invoice-datepicker",{dateFormat:"n/j/Y",allowInput:!0,onOpen:function(e,o,i){i.setDate(i.input.value,!1)}});var o=a(".woo_invoice_order_meta_html").first().clone(),i=(a(document).on("click",".woo-invoice-add-order-meta",function(e){e.preventDefault(),0<a(".woo_invoice_order_meta > .woo_invoice_order_meta_html").length?n("You can add more than 1 order meta in"):a(this).siblings(".woo_invoice_order_meta").append(o.clone())}),a(document).on("click",".woo-invoice-delete-order-meta",function(e){e.preventDefault(),a(this).parent().remove(),a(".woo_invoice_order_meta_html").length}),a(".woo_invoice_order_item_meta_html").first().clone()),t=(a(document).on("click",".woo-invoice-add-order-item-meta",function(e){e.preventDefault(),0<a(".woo_invoice_order_item_meta > .woo_invoice_order_item_meta_html").length?n("You can add more than 1 order item meta in"):a(this).siblings(".woo_invoice_order_item_meta").append(i.clone())}),a(document).on("click",".woo-invoice-delete-order-item-meta",function(e){e.preventDefault(),a(this).parent().remove(),a(".woo_invoice_order_item_meta_html").length}),a(".woo_invoice_product_meta_html").first().clone());function e(e,o){a(document).on("change","".concat(e).concat(o),function(e){var o=this;e.preventDefault(),"all"!==a(this).val()&&(a(this).parent().append('<p  class="woo_invoice_meta_html woo_invoice_col_3 woo_invoice_pro_notice">Notice: Challan Pro only.</p>'),setTimeout(function(){a(o).parent().children("p").hide("slow"),setTimeout(function(){a(o).parent().children("p").remove()},500)},2e3))})}function n(e){a(".woo-invoice-modal").show(),a(".woo-invoice-modal-body p").html("".concat(e,"  <a type='button' href='https://webappick.com/plugin/woocommerce-pdf-invoice-packing-slips/?utm_source=customer_site&utm_medium=free_vs_pro&utm_campaign=woo_invoice_free' target='_blank'>Challan Pro</a>"))}a(document).on("click",".woo-invoice-product-add-meta",function(e){e.preventDefault(),0<a(".woo_invoice_product_meta > .woo_invoice_product_meta_html").length?n("You can add more than 1 product meta in"):a(this).siblings(".woo_invoice_product_meta").append(t.clone())}),a(document).on("click",".woo-invoice-delete-product-meta",function(e){e.preventDefault(),a(this).parent().remove(),a(".woo_invoice_product_meta_html").length}),a(document).on("click","#wpifw_submit_bulk_download",function(o){a(this).parent().parent().serializeArray().map(function(e){"wpifw_bulk_type"==e.name&&"WPIFW_CSV"==e.value?(o.preventDefault(),n("To download bulk csv file you need")):"wpifw_bulk_type"==e.name&&"WPIFW_SHIPPING_LABEL"==e.value&&(o.preventDefault(),n("To download bulk shipping label you need"))})}),e("#","wpifw_bulk_download_order_payment_method"),e("#","wpifw_bulk_download_order_status"),a(".wpifw_attr").selectize({plugins:["remove_button"],render:{item:function(e,o){return'<div class="item wpifw_selector">'+o(e.text)+"</div>"}}}),a(document).on("change","#wpifw_bulk_type",function(e){e.preventDefault(),"WPIFW_CSV"==a(this).val()?a(".woo-invoice-add-csv-fields").show():a(".woo-invoice-add-csv-fields").hide()}),a(".wpifw_header").selectize({plugins:["remove_button"],maxItems:4,render:{item:function(e,o){var i=e.value,t=e.text.slice(0,-5);return["price","total","quantity"].includes(i)?a(".woo_invoice_pro_notice").hide():(a(".woo_invoice_pro_notice_name").text(t),n('To add <span style="font-weight: bold;">'.concat(t,"</span> column you have to upgrade")),a(".woo_invoice_pro_notice").show()),'<div class="item wpifw_selector" disabled="disable">'+o(e.text)+"</div>"}},onInitialize:function(){var o=this;a.ajax({url:woo_invoice_ajax_obj_2.woo_invoice_ajax_url_2,type:"post",data:{_ajax_nonce:woo_invoice_ajax_obj_2.nonce,action:"wpifw_get_product_column_show"},success:function(e){e=[].slice.call(e.data);o.setValue(e)}})}}),a(document).on("change",".wpifw_header",function(e){e.preventDefault(),a.ajax({url:woo_invoice_ajax_obj_2.woo_invoice_ajax_url_2,type:"post",data:{_ajax_nonce:woo_invoice_ajax_obj_2.nonce,action:"wpifw_select_product_column",columns:a(".wpifw_header").val()},success:function(e){}})}),a(".woo-invoice-modal .woo-invoice-modal-close").on("click",function(){a(".woo-invoice-modal").hide()}),a(window).load(function(){a("#wpfooter #footer-thankyou").html("If you like <strong><ins>Challan</ins></strong> please leave us a <a target='_blank' style='color:#f9b918' href='https://wordpress.org/support/view/plugin-reviews/webappick-pdf-invoice-for-woocommerce?rate=5#postform'>★★★★★</a> rating. A huge thank you in advance!")})}(jQuery);
     1"use strict";!function(a){a(window).scroll(function(){a(this).scrollTop()+a(window).height()<a(document).height()-150?a(".woo-invoice-save-changes-selector").addClass("woo-invoice-save-changes"):a(".woo-invoice-save-changes-selector").removeClass("woo-invoice-save-changes")}),a(window).scroll(function(){a(this).scrollTop()+a(window).height()<a(document).height()-150?a(".woo-invoice-banner-sidebar").addClass("woo-invoice-banner-sidebar-sticky"):a(".woo-invoice-banner-sidebar").removeClass("woo-invoice-banner-sidebar-sticky")}),a(window).on("mousewheel",function(e){var o=a(".woo-invoice-dashboard-content > li:eq(0)");a(".woo-invoice-dashboard-sidebar .woo-invoice-sidebar-navbar-light").height(o.parent().height()-23)}),a(window).load(function(){a("input[name='wf_tabs']").on("change",function(){var e=a(this).val();sessionStorage.setItem("active_tab",e)});var e,o,i=sessionStorage.getItem("active_tab"),t=("settings"===i?a("#tab1").attr("checked",!0):"seller&buyer"===i?a("#tab2").attr("checked",!0):"localization"===i?a("#tab3").attr("checked",!0):"bulk_download"===i&&a("#tab4").attr("checked",!0),0),n=0;a("#Date-from").on("change",function(){e=Date.parse(a(this).val()),n=1,t&&n&&o<e&&(alert("Input date should be less than or equal Date To"),a("#Date-from").val(""),n=0)}),a("#Date-to").on("change",function(){o=Date.parse(a(this).val()),(t=1)&&n&&o<e&&(alert("Input date should be greater than or equal Date From"),a("#Date-to").val(""),t=0)}),a(function(){var e,o=a(".woo-invoice-sidebar-navbar-nav > li > a"),i=a(".woo-invoice-dashboard-content > li");null!=sessionStorage.getItem("activeSidebarTab")?(e=sessionStorage.getItem("activeSidebarTab"),i.hide(),o.removeClass("active"),a(i[e]).show(),a(".woo-invoice-sidebar-navbar-nav > li:eq( "+e+" ) > a").addClass("active"),a(".woo-invoice-dashboard-sidebar .woo-invoice-sidebar-navbar-light").height(a(i[e]).parent().height()-23)):((e=a(".woo-invoice-dashboard-content > li:eq(0)")).css("display","block"),a(".woo-invoice-sidebar-navbar-nav > li:eq(0) > a").addClass("active"),a(".woo-invoice-dashboard-sidebar .woo-invoice-sidebar-navbar-light").height(e.parent().height()-23)),o.bind("click",function(e){e.preventDefault();e=a(this).parent().prevAll().length,i.hide(),o.removeClass("active"),a(i[e]).show(),a(this).addClass("active"),e=a(this).parent().prevAll().length;sessionStorage.setItem("activeSidebarTab",e),a(".woo-invoice-dashboard-sidebar .woo-invoice-sidebar-navbar-light").height(i.parent().height()-23)})})}),a(document).on("click",".woo-invoice-template-selection",function(e){e.preventDefault();e=a(this).data("template");a("#winvoiceModalTemplates").modal("hide"),a("body").removeClass(function(e,o){return(o.match(/\S+-modal-open(^|\s)/g)||[]).join(" ")}),a('div[class*="-modal-backdrop"]').remove(),a(this).find("img").removeClass("woo-invoice-template"),a(this).find("img").removeClass("woo-invoice-disable-template"),a(this).find("img").addClass("woo-invoice-slected-template"),a(".woo-invoice-element-disable").find("img").addClass("woo-invoice-template"),a(".woo-invoice-element-disable").find("img").removeClass("woo-invoice-disable-template"),a(".woo-invoice-element-disable").css("z-index","3333"),a(".woo-invoice-element-disable").siblings("div").css("z-index","1111"),a(".woo-invoice-element-disable").siblings("a").css("z-index","2222"),a(this).parent().siblings().find("img").removeClass("woo-invoice-slected-template").addClass("woo-invoice-template"),a.ajax({url:woo_invoice_ajax_obj_2.woo_invoice_ajax_url_2,type:"post",data:{_ajax_nonce:woo_invoice_ajax_obj_2.nonce,action:"wpifw_save_pdf_template",template:e},success:function(e){e.success&&(a(".woo-invoice-template-preview").attr("src",e.data.location+"/"+e.data.template_name+".png"),a(".invoice_template_preiview_btn").attr("href",e.data.location+"/"+e.data.template_name+".png"))}})}),a(document).on("click",".woo-invoice-element-disable",function(e){e.preventDefault(),a(this).children("img").removeClass("woo-invoice-template"),a(this).children("img").addClass("woo-invoice-disable-template"),a(this).css("z-index","1111"),a(this).siblings("div").css("z-index","2222"),a(this).siblings("a").css("z-index","3333")}),flatpickr(".woo-invoice-datepicker",{dateFormat:"n/j/Y",allowInput:!0,onOpen:function(e,o,i){i.setDate(i.input.value,!1)}});var o=a(".woo_invoice_order_meta_html").first().clone(),i=(a(document).on("click",".woo-invoice-add-order-meta",function(e){e.preventDefault(),0<a(".woo_invoice_order_meta > .woo_invoice_order_meta_html").length?n("You can add more than 1 order meta in"):a(this).siblings(".woo_invoice_order_meta").append(o.clone())}),a(document).on("click",".woo-invoice-delete-order-meta",function(e){e.preventDefault(),a(this).parent().remove(),a(".woo_invoice_order_meta_html").length}),a(".woo_invoice_order_item_meta_html").first().clone()),t=(a(document).on("click",".woo-invoice-add-order-item-meta",function(e){e.preventDefault(),0<a(".woo_invoice_order_item_meta > .woo_invoice_order_item_meta_html").length?n("You can add more than 1 order item meta in"):a(this).siblings(".woo_invoice_order_item_meta").append(i.clone())}),a(document).on("click",".woo-invoice-delete-order-item-meta",function(e){e.preventDefault(),a(this).parent().remove(),a(".woo_invoice_order_item_meta_html").length}),a(".woo_invoice_product_meta_html").first().clone());function e(e,o){a(document).on("change","".concat(e).concat(o),function(e){var o=this;e.preventDefault(),"all"!==a(this).val()&&(a(this).parent().append('<p  class="woo_invoice_meta_html woo_invoice_col_3 woo_invoice_pro_notice">Notice: Challan Pro only.</p>'),setTimeout(function(){a(o).parent().children("p").hide("slow"),setTimeout(function(){a(o).parent().children("p").remove()},500)},2e3))})}function n(e){a(".woo-invoice-modal").show(),a(".woo-invoice-modal-body p").html("".concat(e,"  <a type='button' href='https://webappick.com/plugin/woocommerce-pdf-invoice-packing-slips/?utm_source=customer_site&utm_medium=free_vs_pro&utm_campaign=woo_invoice_free' target='_blank'>Challan Pro</a>"))}a(document).on("click",".woo-invoice-product-add-meta",function(e){e.preventDefault(),0<a(".woo_invoice_product_meta > .woo_invoice_product_meta_html").length?n("You can add more than 1 product meta in"):a(this).siblings(".woo_invoice_product_meta").append(t.clone())}),a(document).on("click",".woo-invoice-delete-product-meta",function(e){e.preventDefault(),a(this).parent().remove(),a(".woo_invoice_product_meta_html").length}),a(document).on("click","#wpifw_submit_bulk_download",function(o){a(this).parent().parent().serializeArray().map(function(e){"wpifw_bulk_type"==e.name&&"WPIFW_CSV"==e.value?(o.preventDefault(),n("To download bulk csv file you need")):"wpifw_bulk_type"==e.name&&"WPIFW_SHIPPING_LABEL"==e.value&&(o.preventDefault(),n("To download bulk shipping label you need"))})}),e("#","wpifw_bulk_download_order_payment_method"),e("#","wpifw_bulk_download_order_status"),a(".wpifw_attr").selectize({plugins:["remove_button"],render:{item:function(e,o){return'<div class="item wpifw_selector">'+o(e.text)+"</div>"}}}),a(document).on("change","#wpifw_bulk_type",function(e){e.preventDefault(),"WPIFW_CSV"==a(this).val()?a(".woo-invoice-add-csv-fields").show():a(".woo-invoice-add-csv-fields").hide()}),a(".wpifw_header").selectize({plugins:["remove_button"],maxItems:4,render:{item:function(e,o){var i=e.value,t=e.text.slice(0,-5);return["price","total","quantity"].includes(i)?a(".woo_invoice_pro_notice").hide():(a(".woo_invoice_pro_notice_name").text(t),n('To add <span style="font-weight: bold;">'.concat(t,"</span> column you have to upgrade")),a(".woo_invoice_pro_notice").show()),'<div class="item wpifw_selector" disabled="disable">'+o(e.text)+"</div>"}},onInitialize:function(){var o=this;a.ajax({url:woo_invoice_ajax_obj_2.woo_invoice_ajax_url_2,type:"post",data:{_ajax_nonce:woo_invoice_ajax_obj_2.nonce,action:"wpifw_get_product_column_show"},success:function(e){e=[].slice.call(e.data);o.setValue(e)}})}}),a(document).on("change",".wpifw_header",function(e){e.preventDefault(),a.ajax({url:woo_invoice_ajax_obj_2.woo_invoice_ajax_url_2,type:"post",data:{_ajax_nonce:woo_invoice_ajax_obj_2.nonce,action:"wpifw_select_product_column",columns:a(".wpifw_header").val()},success:function(e){}})}),a(".woo-invoice-modal .woo-invoice-modal-close").on("click",function(){a(".woo-invoice-modal").hide()}),a(window).load(function(){a("#wpfooter #footer-thankyou").html("If you like <strong><ins>Challan</ins></strong> please leave us a <a target='_blank' style='color:#f9b918' href='https://wordpress.org/support/view/plugin-reviews/webappick-pdf-invoice-for-woocommerce?rate=5#postform'>★★★★★</a> rating. A huge thank you in advance!")})}(jQuery);
    22//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYmFwcGljay1wZGYtaW52b2ljZS1mb3Itd29vY29tbWVyY2UtYWRtaW4uanMiXSwibmFtZXMiOlsiJCIsIndpbmRvdyIsInNjcm9sbCIsInNjcm9sbFRvcCIsImhlaWdodCIsImRvY3VtZW50IiwiYWRkQ2xhc3MiLCJyZW1vdmVDbGFzcyIsInRoaXMiLCJpbml0aWFsQ29udGVudCIsInNlc3Npb25TdG9yYWdlIiwiZSIsInBhcmVudCIsImxvYWQiLCJmcm9tX2RhdGUiLCJvbiIsInRvX2RhdGUiLCJzZWxlY3RlZFRhYiIsInZhbCIsInRvQ2hlY2siLCJzZXRJdGVtIiwiZnJvbUNoZWNrIiwiYWxlcnQiLCJwYXJzZSIsImFjdGl2ZVRhYiIsImF0dHIiLCJEYXRlIiwiYWN0aXZlU2lkZWJhclRhYiIsImFjdGl2ZVRhYlNlbGVjdG9yIiwidGFicyIsImNvbnRlbnRzIiwidGFiSW5kZXgiLCJzZWxlY3RlZFNpZGViYXJUYWIiLCJnZXRJdGVtIiwiaGlkZSIsInNob3ciLCJjbGFzc05hbWUiLCJjc3MiLCJ3b29faW52b2ljZV9hamF4X29ial8yIiwic3VjY2VzcyIsImJpbmQiLCJwcmV2ZW50RGVmYXVsdCIsInByZXZBbGwiLCJyZXNwb25zZSIsImxlbmd0aCIsImNoaWxkcmVuIiwic2libGluZ3MiLCJmbGF0cGlja3IiLCJkYXRlRm9ybWF0IiwiYWxsb3dJbnB1dCIsImRhdGEiLCJvbk9wZW4iLCJzZWxlY3RlZERhdGVzIiwiZGF0ZVN0ciIsImluc3RhbmNlIiwic2V0RGF0ZSIsInZhbHVlIiwibWF0Y2giLCJqb2luIiwicmVtb3ZlIiwiZmluZCIsImRpc3BsYXlfY2hhbGxhbl9wcm9fbm90aWNlX21vZGFsIiwiYWpheCIsInVybCIsIndvb19pbnZvaWNlX2FqYXhfdXJsXzIiLCJ0eXBlIiwiX2FqYXhfbm9uY2UiLCJub25jZSIsImFjdGlvbiIsInRlbXBsYXRlIiwib3JkZXJJdGVtTWV0YSIsImxvY2F0aW9uIiwidGVtcGxhdGVfbmFtZSIsInByb2R1Y3RNZXRhIiwiaW5wdXQiLCJhcHBlbmQiLCJmaXJzdCIsImNsb25lIiwic2V0VGltZW91dCIsImZpZWxkIiwibmFtZSIsImRpc3BsYXlfY2hhbGxhbl9wcm9fbm90aWNlX2Zvcl9zZWxlY3Rfb3B0aW9uIiwic2VsZWN0aXplIiwicmVuZGVyIiwic2VsZWN0b3JfdHlwZSIsInNlbGVjdG9yIiwiY29uY2F0IiwiX3RoaXMiLCJjb250ZW50IiwiaHRtbCIsInBsdWdpbnMiLCJtYXhJdGVtcyIsInNlbGVjdEl0ZW0iLCJjb2x1bW5OYW1lIiwiZnJlZUhlYWRlciIsIm9uSW5pdGlhbGl6ZSIsInNlcmlhbGl6ZUFycmF5IiwibWFwIiwiaXRlbSIsImVzY2FwZSIsInRleHQiLCJzbGljZSIsImluY2x1ZGVzIiwic2VsZWN0ZWRfaXRlbXMiLCJjYWxsIiwic2V0VmFsdWUiLCJjb2x1bW5zIiwialF1ZXJ5Il0sIm1hcHBpbmdzIjoiYUFBQSxDQUFBLFNBQVdBLEdBcUJQQSxFQUFFQyxNQUFNLEVBQUVDLE9BQU8sV0FBUEEsRUFBQUEsSUFBTSxFQUFDQyxVQUFBLEVBQVlILEVBQUFDLE1BQUEsRUFBQUcsT0FBQSxFQUVuQkosRUFBSUssUUFBRUYsRUFBQUEsT0FBZSxFQUFDRixJQU1yQkQsRUFBQSxvQ0FBQSxFQUFBTSxTQUNELDBCQUdOLEVBR01KLEVBQUFBLG9DQUFtQixFQUFBSyxZQUViSiwwQkFHTixDQVBWLENBQUMsRUFlQ0gsRUFBQUMsTUFBQSxFQUFBQyxPQUFBLFdBR0VGLEVBQUFRLElBQUEsRUFBQUwsVUFBQSxFQUFBSCxFQUFBQyxNQUFBLEVBQUFHLE9BQUEsRUFiSUosRUFBRUssUUFBUSxFQUFFRCxPQUFPLEVBQUksSUFnQjNCSixFQUFBLDZCQUFBLEVBQUFNLFNBQ0EsbUNBQ0EsRUFFSUcsRUFBQUEsNkJBQW1CLEVBQUFGLFlBRW5CLG1DQUVOLENBR0VQLENBQUMsRUFmTEEsRUFpQlFVLE1BQUFBLEVBQUFBLEdBQUFBLGFBQXVCLFNBQVlDLEdBVWpDLElBQUFGLEVBQWNULEVBQVMsMkNBQU8sRUFDbkNB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Qix1QkFBdUIwQix1QkFDNUJDLEtBQU0sT0FDTmYsS0FBTSxDQUNGZ0IsWUFBYTVCLHVCQUF1QjZCLE1BQ3BDQyxPQUFRLCtCQUNaLEVBQ0E3QixRQUFTLFNBQVVJLEdBQ1g0RCxFQUFpQixHQUFHRixNQUFNRyxLQUFLN0QsRUFBU08sSUFBSSxFQUNoRGdDLEVBQVV1QixTQUFTRixDQUFjLENBQ3JDLENBQ0osQ0FDSixDQUNKLENBQ0osQ0FDSixFQUtBdkcsRUFBRUssUUFBUSxFQUFFVSxHQUNSLFNBQVUsZ0JBQWlCLFNBQVVKLEdBQ2pDQSxFQUFFOEIsZUFBZSxFQUNqQnpDLEVBQUU4RCxLQUNFLENBQ0lDLElBQUt6Qix1QkFBdUIwQix1QkFDNUJDLEtBQU0sT0FDTmYsS0FBTSxDQUNGZ0IsWUFBYTVCLHVCQUF1QjZCLE1BQ3BDQyxPQUFRLDhCQUNSc0MsUUFBUzFHLEVBQUUsZUFBZSxFQUFFa0IsSUFBSSxDQUNwQyxFQUNBcUIsUUFBUyxTQUFVSSxJQUV2QixDQUNKLENBQ0osQ0FDSixFQWNBM0MsRUFBRSw2Q0FBNkMsRUFBRWUsR0FBRyxRQUFTLFdBQ3pEZixFQUFFLG9CQUFvQixFQUFFa0MsS0FBSyxDQUNqQyxDQUFDLEVBTURsQyxFQUFFQyxNQUFNLEVBQUVZLEtBQUssV0FDWGIsRUFBRSw0QkFBNEIsRUFBRXlGLEtBQzVCLDBRQUNKLENBQ0osQ0FBQyxDQUNKLEVBQUVrQixNQUFNIiwiZmlsZSI6IndlYmFwcGljay1wZGYtaW52b2ljZS1mb3Itd29vY29tbWVyY2UtYWRtaW4ubWluLmpzIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uICgkKSB7XG4gICAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgICAvKipcbiAgICAgKiBBbGwgb2YgdGhlIGNvZGUgZm9yIHlvdXIgYWRtaW4tZmFjaW5nIEphdmFTY3JpcHQgc291cmNlXG4gICAgICogc2hvdWxkIHJlc2lkZSBpbiB0aGlzIGZpbGUuXG4gICAgICpcbiAgICAgKiBOb3RlOiBJdCBoYXMgYmVlbiBhc3N1bWVkIHlvdSB3aWxsIHdyaXRlIGpRdWVyeSBjb2RlIGhlcmUsIHNvIHRoZVxuICAgICAqICQgZnVuY3Rpb24gcmVmZXJlbmNlIGhhcyBiZWVuIHByZXBhcmVkIGZvciB1c2FnZSB3aXRoaW4gdGhlIHNjb3BlXG4gICAgICogb2YgdGhpcyBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIFRoaXMgZW5hYmxlcyB5b3UgdG8gZGVmaW5lIGhhbmRsZXJzLCBmb3Igd2hlbiB0aGUgRE9NIGlzIHJlYWR5OlxuICAgICAqXG4gICAgICogJChmdW5jdGlvbigpIHtcbiAgICAgKlxuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogV2hlbiB0aGUgd2luZG93IGlzIGxvYWRlZDpcbiAgICAgKi9cblxuICAgIC8vIHNjcm9sbCBhZGQgYW5kIHJlbW92ZSBjbGFzc1xuICAgICQod2luZG93KS5zY3JvbGwoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICAkKHRoaXMpLnNjcm9sbFRvcCgpICsgJCh3aW5kb3cpLmhlaWdodCgpIDxcbiAgICAgICAgICAgICQoZG9jdW1lbnQpLmhlaWdodCgpIC0gMTUwXG4gICAgICAgICkge1xuICAgICAgICAgICAgJChcIi53b28taW52b2ljZS1zYXZlLWNoYW5nZXMtc2VsZWN0b3JcIikuYWRkQ2xhc3MoXG4gICAgICAgICAgICAgICAgXCJ3b28taW52b2ljZS1zYXZlLWNoYW5nZXNcIlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICQoXCIud29vLWludm9pY2Utc2F2ZS1jaGFuZ2VzLXNlbGVjdG9yXCIpLnJlbW92ZUNsYXNzKFxuICAgICAgICAgICAgICAgIFwid29vLWludm9pY2Utc2F2ZS1jaGFuZ2VzXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgICQod2luZG93KS5zY3JvbGwoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICAkKHRoaXMpLnNjcm9sbFRvcCgpICsgJCh3aW5kb3cpLmhlaWdodCgpIDxcbiAgICAgICAgICAgICQoZG9jdW1lbnQpLmhlaWdodCgpIC0gMTUwXG4gICAgICAgICkge1xuICAgICAgICAgICAgJChcIi53b28taW52b2ljZS1iYW5uZXItc2lkZWJhclwiKS5hZGRDbGFzcyhcbiAgICAgICAgICAgICAgICBcIndvby1pbnZvaWNlLWJhbm5lci1zaWRlYmFyLXN0aWNreVwiXG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgJChcIi53b28taW52b2ljZS1iYW5uZXItc2lkZWJhclwiKS5yZW1vdmVDbGFzcyhcbiAgICAgICAgICAgICAgICBcIndvby1pbnZvaWNlLWJhbm5lci1zaWRlYmFyLXN0aWNreVwiXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICAkKHdpbmRvdykub24oXCJtb3VzZXdoZWVsXCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIC8vaWYoJCh3aW5kb3cpLnNjcm9sbFRvcCgpICsgJCh3aW5kb3cpLmhlaWdodCgpID4gJChkb2N1bWVudCkuaGVpZ2h0KCktMTAwKSAge1xuXG4gICAgICAgIC8vJChcIi53b28taW52b2ljZS1zYXZlLWNoYW5nZXMtc2VsZWN0b3JcIikucmVtb3ZlQ2xhc3MoXCJ3b28taW52b2ljZS1zYXZlLWNoYW5nZXNcIik7XG4gICAgICAgIC8vIH0gZWxzZSB7XG4gICAgICAgIC8vJChcIi53b28taW52b2ljZS1zYXZlLWNoYW5nZXMtc2VsZWN0b3JcIikuYWRkQ2xhc3MoXCJ3b28taW52b2ljZS1zYXZlLWNoYW5nZXNcIik7XG4gICAgICAgIC8vfVxuXG4gICAgICAgIHZhciBpbml0aWFsQ29udGVudCA9ICQoXCIud29vLWludm9pY2UtZGFzaGJvYXJkLWNvbnRlbnQgPiBsaTplcSgwKVwiKTtcbiAgICAgICAgJChcbiAgICAgICAgICAgIFwiLndvby1pbnZvaWNlLWRhc2hib2FyZC1zaWRlYmFyIC53b28taW52b2ljZS1zaWRlYmFyLW5hdmJhci1saWdodFwiXG4gICAgICAgICkuaGVpZ2h0KGluaXRpYWxDb250ZW50LnBhcmVudCgpLmhlaWdodCgpIC0gMjMpO1xuICAgIH0pO1xuXG4gICAgJCh3aW5kb3cpLmxvYWQoZnVuY3Rpb24gKCkge1xuICAgICAgICAkKFwiaW5wdXRbbmFtZT0nd2ZfdGFicyddXCIpLm9uKFwiY2hhbmdlXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBzZWxlY3RlZFRhYiA9ICQodGhpcykudmFsKCk7XG4gICAgICAgICAgICBzZXNzaW9uU3RvcmFnZS5zZXRJdGVtKFwiYWN0aXZlX3RhYlwiLCBzZWxlY3RlZFRhYik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHZhciBhY3RpdmVUYWIgPSBzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKFwiYWN0aXZlX3RhYlwiKTtcblxuICAgICAgICBpZiAoYWN0aXZlVGFiID09PSBcInNldHRpbmdzXCIpIHtcbiAgICAgICAgICAgICQoXCIjdGFiMVwiKS5hdHRyKFwiY2hlY2tlZFwiLCB0cnVlKTtcbiAgICAgICAgfSBlbHNlIGlmIChhY3RpdmVUYWIgPT09IFwic2VsbGVyJmJ1eWVyXCIpIHtcbiAgICAgICAgICAgICQoXCIjdGFiMlwiKS5hdHRyKFwiY2hlY2tlZFwiLCB0cnVlKTtcbiAgICAgICAgfSBlbHNlIGlmIChhY3RpdmVUYWIgPT09IFwibG9jYWxpemF0aW9uXCIpIHtcbiAgICAgICAgICAgICQoXCIjdGFiM1wiKS5hdHRyKFwiY2hlY2tlZFwiLCB0cnVlKTtcbiAgICAgICAgfSBlbHNlIGlmIChhY3RpdmVUYWIgPT09IFwiYnVsa19kb3dubG9hZFwiKSB7XG4gICAgICAgICAgICAkKFwiI3RhYjRcIikuYXR0cihcImNoZWNrZWRcIiwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gc2V0IGFjdGl2ZSBvZiBTZXR0aW5nIHRhYiBlbmRlZFxuXG4gICAgICAgIC8vQnVsayBpbnB1dCBkYXRlIHZhbGlkYXRpb25cbiAgICAgICAgdmFyIGZyb21fZGF0ZTtcbiAgICAgICAgdmFyIHRvX2RhdGU7XG4gICAgICAgIHZhciB0b0NoZWNrID0gMDtcbiAgICAgICAgdmFyIGZyb21DaGVjayA9IDA7XG5cbiAgICAgICAgJChcIiNEYXRlLWZyb21cIikub24oXCJjaGFuZ2VcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZnJvbV9kYXRlID0gRGF0ZS5wYXJzZSgkKHRoaXMpLnZhbCgpKTtcbiAgICAgICAgICAgIGZyb21DaGVjayA9IDE7XG4gICAgICAgICAgICBpZiAodG9DaGVjayAmJiBmcm9tQ2hlY2spIHtcbiAgICAgICAgICAgICAgICBpZiAodG9fZGF0ZSA8IGZyb21fZGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICBhbGVydChcIklucHV0IGRhdGUgc2hvdWxkIGJlIGxlc3MgdGhhbiBvciBlcXVhbCBEYXRlIFRvXCIpO1xuICAgICAgICAgICAgICAgICAgICAkKFwiI0RhdGUtZnJvbVwiKS52YWwoXCJcIik7XG4gICAgICAgICAgICAgICAgICAgIGZyb21DaGVjayA9IDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAkKFwiI0RhdGUtdG9cIikub24oXCJjaGFuZ2VcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdG9fZGF0ZSA9IERhdGUucGFyc2UoJCh0aGlzKS52YWwoKSk7XG4gICAgICAgICAgICB0b0NoZWNrID0gMTtcbiAgICAgICAgICAgIGlmICh0b0NoZWNrICYmIGZyb21DaGVjaykge1xuICAgICAgICAgICAgICAgIGlmICh0b19kYXRlIDwgZnJvbV9kYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIGFsZXJ0KFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJJbnB1dCBkYXRlIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgRGF0ZSBGcm9tXCJcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgJChcIiNEYXRlLXRvXCIpLnZhbChcIlwiKTtcbiAgICAgICAgICAgICAgICAgICAgdG9DaGVjayA9IDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAkKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciB0YWJzID0gJChcIi53b28taW52b2ljZS1zaWRlYmFyLW5hdmJhci1uYXYgPiBsaSA+IGFcIik7IC8vZ3JhYiB0YWJzXG4gICAgICAgICAgICB2YXIgY29udGVudHMgPSAkKFwiLndvby1pbnZvaWNlLWRhc2hib2FyZC1jb250ZW50ID4gbGlcIik7IC8vZ3JhYiBjb250ZW50c1xuXG4gICAgICAgICAgICBpZiAoc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbShcImFjdGl2ZVNpZGViYXJUYWJcIikgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHZhciBhY3RpdmVTaWRlYmFyVGFiID1cbiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbShcImFjdGl2ZVNpZGViYXJUYWJcIik7XG4gICAgICAgICAgICAgICAgY29udGVudHMuaGlkZSgpOyAvL2hpZGUgYWxsIGNvbnRlbnRzXG4gICAgICAgICAgICAgICAgdGFicy5yZW1vdmVDbGFzcyhcImFjdGl2ZVwiKTsgLy9yZW1vdmUgJ2N1cnJlbnQnIGNsYXNzZXNcbiAgICAgICAgICAgICAgICAkKGNvbnRlbnRzW2FjdGl2ZVNpZGViYXJUYWJdKS5zaG93KCk7IC8vc2hvdyB0YWIgY29udGVudCB0aGF0IG1hdGNoZXMgdGFiIHRpdGxlIGluZGV4XG4gICAgICAgICAgICAgICAgdmFyIGFjdGl2ZVRhYlNlbGVjdG9yID0gJChcbiAgICAgICAgICAgICAgICAgICAgXCIud29vLWludm9pY2Utc2lkZWJhci1uYXZiYXItbmF2ID4gbGk6ZXEoIFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZVNpZGViYXJUYWIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgXCIgKSA+IGFcIlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgYWN0aXZlVGFiU2VsZWN0b3IuYWRkQ2xhc3MoXCJhY3RpdmVcIik7XG4gICAgICAgICAgICAgICAgLyokKHRoaXMpLmFkZENsYXNzKCdhY3RpdmUnKTsgLy9hZGQgY3VycmVudCBjbGFzcyBvbiBjbGlja2VkIHRhYiB0aXRsZSovXG4gICAgICAgICAgICAgICAgJChcbiAgICAgICAgICAgICAgICAgICAgXCIud29vLWludm9pY2UtZGFzaGJvYXJkLXNpZGViYXIgLndvby1pbnZvaWNlLXNpZGViYXItbmF2YmFyLWxpZ2h0XCJcbiAgICAgICAgICAgICAgICApLmhlaWdodCgkKGNvbnRlbnRzW2FjdGl2ZVNpZGViYXJUYWJdKS5wYXJlbnQoKS5oZWlnaHQoKSAtIDIzKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFyIGluaXRpYWxDb250ZW50ID0gJChcbiAgICAgICAgICAgICAgICAgICAgXCIud29vLWludm9pY2UtZGFzaGJvYXJkLWNvbnRlbnQgPiBsaTplcSgwKVwiXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBpbml0aWFsQ29udGVudC5jc3MoXCJkaXNwbGF5XCIsIFwiYmxvY2tcIik7IC8vc2hvdyB0YWIgY29udGVudCB0aGF0IG1hdGNoZXMgdGFiIHRpdGxlIGluZGV4XG4gICAgICAgICAgICAgICAgdmFyIGFjdGl2ZVRhYlNlbGVjdG9yID0gJChcbiAgICAgICAgICAgICAgICAgICAgXCIud29vLWludm9pY2Utc2lkZWJhci1uYXZiYXItbmF2ID4gbGk6ZXEoMCkgPiBhXCJcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGFjdGl2ZVRhYlNlbGVjdG9yLmFkZENsYXNzKFwiYWN0aXZlXCIpO1xuICAgICAgICAgICAgICAgICQoXG4gICAgICAgICAgICAgICAgICAgIFwiLndvby1pbnZvaWNlLWRhc2hib2FyZC1zaWRlYmFyIC53b28taW52b2ljZS1zaWRlYmFyLW5hdmJhci1saWdodFwiXG4gICAgICAgICAgICAgICAgKS5oZWlnaHQoaW5pdGlhbENvbnRlbnQucGFyZW50KCkuaGVpZ2h0KCkgLSAyMyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRhYnMuYmluZChcImNsaWNrXCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIHZhciB0YWJJbmRleCA9ICQodGhpcykucGFyZW50KCkucHJldkFsbCgpLmxlbmd0aDtcbiAgICAgICAgICAgICAgICBjb250ZW50cy5oaWRlKCk7IC8vaGlkZSBhbGwgY29udGVudHNcbiAgICAgICAgICAgICAgICB0YWJzLnJlbW92ZUNsYXNzKFwiYWN0aXZlXCIpOyAvL3JlbW92ZSAnY3VycmVudCcgY2xhc3Nlc1xuICAgICAgICAgICAgICAgICQoY29udGVudHNbdGFiSW5kZXhdKS5zaG93KCk7IC8vc2hvdyB0YWIgY29udGVudCB0aGF0IG1hdGNoZXMgdGFiIHRpdGxlIGluZGV4XG4gICAgICAgICAgICAgICAgJCh0aGlzKS5hZGRDbGFzcyhcImFjdGl2ZVwiKTsgLy9hZGQgY3VycmVudCBjbGFzcyBvbiBjbGlja2VkIHRhYiB0aXRsZVxuICAgICAgICAgICAgICAgIHZhciBzZWxlY3RlZFNpZGViYXJUYWIgPSAkKHRoaXMpLnBhcmVudCgpLnByZXZBbGwoKS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShcImFjdGl2ZVNpZGViYXJUYWJcIiwgc2VsZWN0ZWRTaWRlYmFyVGFiKTtcbiAgICAgICAgICAgICAgICAkKFxuICAgICAgICAgICAgICAgICAgICBcIi53b28taW52b2ljZS1kYXNoYm9hcmQtc2lkZWJhciAud29vLWludm9pY2Utc2lkZWJhci1uYXZiYXItbGlnaHRcIlxuICAgICAgICAgICAgICAgICkuaGVpZ2h0KGNvbnRlbnRzLnBhcmVudCgpLmhlaWdodCgpIC0gMjMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIi53b28taW52b2ljZS10ZW1wbGF0ZS1zZWxlY3Rpb25cIiwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBsZXQgdGVtcGxhdGUgPSAkKHRoaXMpLmRhdGEoXCJ0ZW1wbGF0ZVwiKTtcbiAgICAgICAgJChcIiN3aW52b2ljZU1vZGFsVGVtcGxhdGVzXCIpLm1vZGFsKFwiaGlkZVwiKTtcbiAgICAgICAgJChcImJvZHlcIikucmVtb3ZlQ2xhc3MoZnVuY3Rpb24gKGluZGV4LCBjbGFzc05hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiAoY2xhc3NOYW1lLm1hdGNoKC9cXFMrLW1vZGFsLW9wZW4oXnxcXHMpL2cpIHx8IFtdKS5qb2luKFwiIFwiKTtcbiAgICAgICAgfSk7XG4gICAgICAgICQoJ2RpdltjbGFzcyo9XCItbW9kYWwtYmFja2Ryb3BcIl0nKS5yZW1vdmUoKTtcbiAgICAgICAgJCh0aGlzKS5maW5kKFwiaW1nXCIpLnJlbW92ZUNsYXNzKFwid29vLWludm9pY2UtdGVtcGxhdGVcIik7XG4gICAgICAgICQodGhpcykuZmluZChcImltZ1wiKS5yZW1vdmVDbGFzcyhcIndvby1pbnZvaWNlLWRpc2FibGUtdGVtcGxhdGVcIik7XG4gICAgICAgICQodGhpcykuZmluZChcImltZ1wiKS5hZGRDbGFzcyhcIndvby1pbnZvaWNlLXNsZWN0ZWQtdGVtcGxhdGVcIik7XG5cbiAgICAgICAgJChcIi53b28taW52b2ljZS1lbGVtZW50LWRpc2FibGVcIilcbiAgICAgICAgICAgIC5maW5kKFwiaW1nXCIpXG4gICAgICAgICAgICAuYWRkQ2xhc3MoXCJ3b28taW52b2ljZS10ZW1wbGF0ZVwiKTtcbiAgICAgICAgJChcIi53b28taW52b2ljZS1lbGVtZW50LWRpc2FibGVcIilcbiAgICAgICAgICAgIC5maW5kKFwiaW1nXCIpXG4gICAgICAgICAgICAucmVtb3ZlQ2xhc3MoXCJ3b28taW52b2ljZS1kaXNhYmxlLXRlbXBsYXRlXCIpO1xuICAgICAgICAkKFwiLndvby1pbnZvaWNlLWVsZW1lbnQtZGlzYWJsZVwiKS5jc3MoXCJ6LWluZGV4XCIsIFwiMzMzM1wiKTtcbiAgICAgICAgJChcIi53b28taW52b2ljZS1lbGVtZW50LWRpc2FibGVcIilcbiAgICAgICAgICAgIC5zaWJsaW5ncyhcImRpdlwiKVxuICAgICAgICAgICAgLmNzcyhcInotaW5kZXhcIiwgXCIxMTExXCIpO1xuICAgICAgICAkKFwiLndvby1pbnZvaWNlLWVsZW1lbnQtZGlzYWJsZVwiKS5zaWJsaW5ncyhcImFcIikuY3NzKFwiei1pbmRleFwiLCBcIjIyMjJcIik7XG5cbiAgICAgICAgJCh0aGlzKVxuICAgICAgICAgICAgLnBhcmVudCgpXG4gICAgICAgICAgICAuc2libGluZ3MoKVxuICAgICAgICAgICAgLmZpbmQoXCJpbWdcIilcbiAgICAgICAgICAgIC5yZW1vdmVDbGFzcyhcIndvby1pbnZvaWNlLXNsZWN0ZWQtdGVtcGxhdGVcIilcbiAgICAgICAgICAgIC5hZGRDbGFzcyhcIndvby1pbnZvaWNlLXRlbXBsYXRlXCIpO1xuICAgICAgICAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsOiB3b29faW52b2ljZV9hamF4X29ial8yLndvb19pbnZvaWNlX2FqYXhfdXJsXzIsXG4gICAgICAgICAgICB0eXBlOiBcInBvc3RcIixcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICBfYWpheF9ub25jZTogd29vX2ludm9pY2VfYWpheF9vYmpfMi5ub25jZSxcbiAgICAgICAgICAgICAgICBhY3Rpb246IFwid3BpZndfc2F2ZV9wZGZfdGVtcGxhdGVcIixcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZTogdGVtcGxhdGUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgJChcIi53b28taW52b2ljZS10ZW1wbGF0ZS1wcmV2aWV3XCIpLmF0dHIoXG4gICAgICAgICAgICAgICAgICAgIFwic3JjXCIsXG4gICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmRhdGEubG9jYXRpb24gK1xuICAgICAgICAgICAgICAgICAgICAgICAgXCIvXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UuZGF0YS50ZW1wbGF0ZV9uYW1lICtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiLnBuZ1wiXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAkKFwiLmludm9pY2VfdGVtcGxhdGVfcHJlaXZpZXdfYnRuXCIpLmF0dHIoXG4gICAgICAgICAgICAgICAgICAgIFwiaHJlZlwiLFxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5kYXRhLmxvY2F0aW9uICtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiL1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmRhdGEudGVtcGxhdGVfbmFtZSArXG4gICAgICAgICAgICAgICAgICAgICAgICBcIi5wbmdcIlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgICQoZG9jdW1lbnQpLm9uKFwiY2xpY2tcIiwgXCIud29vLWludm9pY2UtZWxlbWVudC1kaXNhYmxlXCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgJCh0aGlzKS5jaGlsZHJlbihcImltZ1wiKS5yZW1vdmVDbGFzcyhcIndvby1pbnZvaWNlLXRlbXBsYXRlXCIpO1xuICAgICAgICAkKHRoaXMpLmNoaWxkcmVuKFwiaW1nXCIpLmFkZENsYXNzKFwid29vLWludm9pY2UtZGlzYWJsZS10ZW1wbGF0ZVwiKTtcbiAgICAgICAgJCh0aGlzKS5jc3MoXCJ6LWluZGV4XCIsIFwiMTExMVwiKTtcbiAgICAgICAgJCh0aGlzKS5zaWJsaW5ncyhcImRpdlwiKS5jc3MoXCJ6LWluZGV4XCIsIFwiMjIyMlwiKTtcbiAgICAgICAgJCh0aGlzKS5zaWJsaW5ncyhcImFcIikuY3NzKFwiei1pbmRleFwiLCBcIjMzMzNcIik7XG4gICAgfSk7XG5cbiAgICAvL0RhdGVwaWNrZXJcbiAgICBmbGF0cGlja3IoXCIud29vLWludm9pY2UtZGF0ZXBpY2tlclwiLCB7XG4gICAgICAgIGRhdGVGb3JtYXQ6IFwibi9qL1lcIixcbiAgICAgICAgYWxsb3dJbnB1dDogdHJ1ZSxcbiAgICAgICAgb25PcGVuOiBmdW5jdGlvbiAoc2VsZWN0ZWREYXRlcywgZGF0ZVN0ciwgaW5zdGFuY2UpIHtcbiAgICAgICAgICAgIGluc3RhbmNlLnNldERhdGUoaW5zdGFuY2UuaW5wdXQudmFsdWUsIGZhbHNlKTtcbiAgICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICAvLyBEaXNwbGF5IG9yZGVyIG1ldGEgZm9yIGludm9pY2UuXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIHZhciBtZXRhT3JkZXJIVE1MID0gJChcIi53b29faW52b2ljZV9vcmRlcl9tZXRhX2h0bWxcIikuZmlyc3QoKS5jbG9uZSgpO1xuXG4gICAgLy8gY2xvbmUgYSBuZXcgaW5wdXQgZmllbGQgZm9yIHNldHRpbmcgb3JkZXIgbWF0ZS5cbiAgICAkKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiLndvby1pbnZvaWNlLWFkZC1vcmRlci1tZXRhXCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgICAkKFwiLndvb19pbnZvaWNlX29yZGVyX21ldGEgPiAud29vX2ludm9pY2Vfb3JkZXJfbWV0YV9odG1sXCIpLmxlbmd0aCA+XG4gICAgICAgICAgICAwXG4gICAgICAgICkge1xuICAgICAgICAgICAgZGlzcGxheV9jaGFsbGFuX3Byb19ub3RpY2VfbW9kYWwoXG4gICAgICAgICAgICAgICAgXCJZb3UgY2FuIGFkZCBtb3JlIHRoYW4gMSBvcmRlciBtZXRhIGluXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAgICAgLnNpYmxpbmdzKFwiLndvb19pbnZvaWNlX29yZGVyX21ldGFcIilcbiAgICAgICAgICAgICAgICAuYXBwZW5kKG1ldGFPcmRlckhUTUwuY2xvbmUoKSk7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIGRlbGV0ZSBvcmRlciBtZXRhLlxuICAgICQoZG9jdW1lbnQpLm9uKFwiY2xpY2tcIiwgXCIud29vLWludm9pY2UtZGVsZXRlLW9yZGVyLW1ldGFcIiwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAkKHRoaXMpLnBhcmVudCgpLnJlbW92ZSgpO1xuICAgICAgICBpZiAoJChcIi53b29faW52b2ljZV9vcmRlcl9tZXRhX2h0bWxcIikubGVuZ3RoID09PSBcIjFcIikge1xuICAgICAgICAgICAgLy8kKCcud29vX2ludm9pY2UtYWRkLW9yZGVyLW1ldGEgLmRhc2hpY29ucy1wbHVzLWFsdCcpLmNzcyhcIm1hcmdpbi1sZWZ0XCIsXCIwcHhcIik7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vICBFbmQgOiAgZGlzcGxheSBvcmRlciBtZXRhICBmb3IgaW52b2ljZS5cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vIERpc3BsYXkgb3JkZXIgaXRlbSBtZXRhIGZvciBpbnZvaWNlLlxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICB2YXIgb3JkZXJJdGVtTWV0YSA9ICQoXCIud29vX2ludm9pY2Vfb3JkZXJfaXRlbV9tZXRhX2h0bWxcIikuZmlyc3QoKS5jbG9uZSgpO1xuICAgIC8vIGNsb25lIGEgbmV3IGlucHV0IGZpZWxkIGZvciBzZXR0aW5nIG9yZGVyIG1hdGUuXG4gICAgJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIi53b28taW52b2ljZS1hZGQtb3JkZXItaXRlbS1tZXRhXCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgJChcbiAgICAgICAgICAgICAgICBcIi53b29faW52b2ljZV9vcmRlcl9pdGVtX21ldGEgPiAud29vX2ludm9pY2Vfb3JkZXJfaXRlbV9tZXRhX2h0bWxcIlxuICAgICAgICAgICAgKS5sZW5ndGggPiAwXG4gICAgICAgICkge1xuICAgICAgICAgICAgZGlzcGxheV9jaGFsbGFuX3Byb19ub3RpY2VfbW9kYWwoXG4gICAgICAgICAgICAgICAgXCJZb3UgY2FuIGFkZCBtb3JlIHRoYW4gMSBvcmRlciBpdGVtIG1ldGEgaW5cIlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICQodGhpcylcbiAgICAgICAgICAgICAgICAuc2libGluZ3MoXCIud29vX2ludm9pY2Vfb3JkZXJfaXRlbV9tZXRhXCIpXG4gICAgICAgICAgICAgICAgLmFwcGVuZChvcmRlckl0ZW1NZXRhLmNsb25lKCkpO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgLy8gZGVsZXRlIG9yZGVyIG1ldGEuXG4gICAgJChkb2N1bWVudCkub24oXG4gICAgICAgIFwiY2xpY2tcIixcbiAgICAgICAgXCIud29vLWludm9pY2UtZGVsZXRlLW9yZGVyLWl0ZW0tbWV0YVwiLFxuICAgICAgICBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgJCh0aGlzKS5wYXJlbnQoKS5yZW1vdmUoKTtcbiAgICAgICAgICAgIGlmICgkKFwiLndvb19pbnZvaWNlX29yZGVyX2l0ZW1fbWV0YV9odG1sXCIpLmxlbmd0aCA9PT0gXCIxXCIpIHtcbiAgICAgICAgICAgICAgICAvLyQoJy53b29faW52b2ljZS1hZGQtb3JkZXItbWV0YSAuZGFzaGljb25zLXBsdXMtYWx0JykuY3NzKFwibWFyZ2luLWxlZnRcIixcIjBweFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICk7XG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vICBFbmQgOiAgZGlzcGxheSBvcmRlciBpdGVtIG1ldGEgZm9yIGludm9pY2UuXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vIERpc3BsYXkgcHJvZHVjdCBtZXRhIGZvciBpbnZvaWNlLlxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICB2YXIgcHJvZHVjdE1ldGEgPSAkKFwiLndvb19pbnZvaWNlX3Byb2R1Y3RfbWV0YV9odG1sXCIpLmZpcnN0KCkuY2xvbmUoKTtcblxuICAgIC8vIGNsb25lIGEgbmV3IGlucHV0IGZpZWxkIGZvciBzZXR0aW5nIG9yZGVyIG1hdGUuXG4gICAgJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIi53b28taW52b2ljZS1wcm9kdWN0LWFkZC1tZXRhXCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgJChcIi53b29faW52b2ljZV9wcm9kdWN0X21ldGEgPiAud29vX2ludm9pY2VfcHJvZHVjdF9tZXRhX2h0bWxcIilcbiAgICAgICAgICAgICAgICAubGVuZ3RoID4gMFxuICAgICAgICApIHtcbiAgICAgICAgICAgIGRpc3BsYXlfY2hhbGxhbl9wcm9fbm90aWNlX21vZGFsKFxuICAgICAgICAgICAgICAgIFwiWW91IGNhbiBhZGQgbW9yZSB0aGFuIDEgcHJvZHVjdCBtZXRhIGluXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAgICAgLnNpYmxpbmdzKFwiLndvb19pbnZvaWNlX3Byb2R1Y3RfbWV0YVwiKVxuICAgICAgICAgICAgICAgIC5hcHBlbmQocHJvZHVjdE1ldGEuY2xvbmUoKSk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICAvLyBkZWxldGUgb3JkZXIgbWV0YS5cbiAgICAkKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiLndvby1pbnZvaWNlLWRlbGV0ZS1wcm9kdWN0LW1ldGFcIiwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAkKHRoaXMpLnBhcmVudCgpLnJlbW92ZSgpO1xuICAgICAgICBpZiAoJChcIi53b29faW52b2ljZV9wcm9kdWN0X21ldGFfaHRtbFwiKS5sZW5ndGggPT09IFwiMVwiKSB7XG4gICAgICAgICAgICAvLyQoJy53b29faW52b2ljZS1hZGQtb3JkZXItbWV0YSAuZGFzaGljb25zLXBsdXMtYWx0JykuY3NzKFwibWFyZ2luLWxlZnRcIixcIjBweFwiKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgLy8gIEVuZCA6ICBkaXNwbGF5IG9yZGVyIG1ldGEgIGZvciBpbnZvaWNlLlxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vIEFsZXJ0IGZvciBidWxrIGNzdiBmaWxlIGFuZCBzaGlwcGluZyBsYWJlbC5cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIiN3cGlmd19zdWJtaXRfYnVsa19kb3dubG9hZFwiLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAucGFyZW50KClcbiAgICAgICAgICAgIC5wYXJlbnQoKVxuICAgICAgICAgICAgLnNlcmlhbGl6ZUFycmF5KClcbiAgICAgICAgICAgIC5tYXAoKGZpZWxkKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICBmaWVsZC5uYW1lID09IFwid3BpZndfYnVsa190eXBlXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgZmllbGQudmFsdWUgPT0gXCJXUElGV19DU1ZcIlxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIGRpc3BsYXlfY2hhbGxhbl9wcm9fbm90aWNlX21vZGFsKFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJUbyBkb3dubG9hZCBidWxrIGNzdiBmaWxlIHlvdSBuZWVkXCJcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICAgICAgICBmaWVsZC5uYW1lID09IFwid3BpZndfYnVsa190eXBlXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgZmllbGQudmFsdWUgPT0gXCJXUElGV19TSElQUElOR19MQUJFTFwiXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgZGlzcGxheV9jaGFsbGFuX3Byb19ub3RpY2VfbW9kYWwoXG4gICAgICAgICAgICAgICAgICAgICAgICBcIlRvIGRvd25sb2FkIGJ1bGsgc2hpcHBpbmcgbGFiZWwgeW91IG5lZWRcIlxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgIH0pO1xuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICAvLyAgRW5kIDogIEFsZXJ0IGZvciBidWxrIGNzdiBmaWxlIGFuZCBzaGlwcGluZyBsYWJlbC5cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vICBTdGFydCA6ICBQYXltZW50IG1ldGhvZCBzZWxlY3Qgb3B0aW9uIG5vdGljZS5cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIGZ1bmN0aW9uIGRpc3BsYXlfY2hhbGxhbl9wcm9fbm90aWNlX2Zvcl9zZWxlY3Rfb3B0aW9uKFxuICAgICAgICBzZWxlY3Rvcl90eXBlLFxuICAgICAgICBzZWxlY3RvclxuICAgICkge1xuICAgICAgICAkKGRvY3VtZW50KS5vbihcImNoYW5nZVwiLCBgJHtzZWxlY3Rvcl90eXBlfSR7c2VsZWN0b3J9YCwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGlmICgkKHRoaXMpLnZhbCgpICE9PSBcImFsbFwiKSB7XG4gICAgICAgICAgICAgICAgJCh0aGlzKVxuICAgICAgICAgICAgICAgICAgICAucGFyZW50KClcbiAgICAgICAgICAgICAgICAgICAgLmFwcGVuZChcbiAgICAgICAgICAgICAgICAgICAgICAgIGA8cCAgY2xhc3M9XCJ3b29faW52b2ljZV9tZXRhX2h0bWwgd29vX2ludm9pY2VfY29sXzMgd29vX2ludm9pY2VfcHJvX25vdGljZVwiPk5vdGljZTogQ2hhbGxhbiBQcm8gb25seS48L3A+YFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAkKHRoaXMpLnBhcmVudCgpLmNoaWxkcmVuKFwicFwiKS5oaWRlKFwic2xvd1wiKTtcbiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAkKHRoaXMpLnBhcmVudCgpLmNoaWxkcmVuKFwicFwiKS5yZW1vdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgICAgICAgICB9LCAyMDAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3BsYXlfY2hhbGxhbl9wcm9fbm90aWNlX2Zvcl9zZWxlY3Rfb3B0aW9uKFxuICAgICAgICBcIiNcIixcbiAgICAgICAgXCJ3cGlmd19idWxrX2Rvd25sb2FkX29yZGVyX3BheW1lbnRfbWV0aG9kXCJcbiAgICApO1xuICAgIGRpc3BsYXlfY2hhbGxhbl9wcm9fbm90aWNlX2Zvcl9zZWxlY3Rfb3B0aW9uKFxuICAgICAgICBcIiNcIixcbiAgICAgICAgXCJ3cGlmd19idWxrX2Rvd25sb2FkX29yZGVyX3N0YXR1c1wiXG4gICAgKTtcblxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vICBFbmQgOiAgUGF5bWVudCBtZXRob2Qgc2VsZWN0IG9wdGlvbiBub3RpY2UuXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgJChcIi53cGlmd19hdHRyXCIpLnNlbGVjdGl6ZSh7XG4gICAgICAgIHBsdWdpbnM6IFtcInJlbW92ZV9idXR0b25cIl0sXG4gICAgICAgIHJlbmRlcjoge1xuICAgICAgICAgICAgaXRlbTogZnVuY3Rpb24gKGRhdGEsIGVzY2FwZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwiaXRlbSB3cGlmd19zZWxlY3RvclwiPicgK1xuICAgICAgICAgICAgICAgICAgICBlc2NhcGUoZGF0YS50ZXh0KSArXG4gICAgICAgICAgICAgICAgICAgIFwiPC9kaXY+XCJcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgLy8gRGlzcGxheSBjc3YgZmlsZVxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgJChkb2N1bWVudCkub24oXCJjaGFuZ2VcIiwgXCIjd3BpZndfYnVsa190eXBlXCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgaWYgKCQodGhpcykudmFsKCkgPT0gXCJXUElGV19DU1ZcIikge1xuICAgICAgICAgICAgJChcIi53b28taW52b2ljZS1hZGQtY3N2LWZpZWxkc1wiKS5zaG93KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAkKFwiLndvby1pbnZvaWNlLWFkZC1jc3YtZmllbGRzXCIpLmhpZGUoKTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICAvLyBTaG93IFByb2R1Y3QgQ29sdW1uXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICAkKCcud3BpZndfaGVhZGVyJykuc2VsZWN0aXplKFxuICAgICAgICB7XG4gICAgICAgICAgICBwbHVnaW5zOiBbJ3JlbW92ZV9idXR0b24nXSxcbiAgICAgICAgICAgIG1heEl0ZW1zOiA0LFxuICAgICAgICAgICAgcmVuZGVyOiB7XG4gICAgICAgICAgICAgICAgaXRlbTogZnVuY3Rpb24gKGRhdGEsIGVzY2FwZSkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgc2VsZWN0SXRlbSA9IGRhdGEudmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIGxldCBmcmVlSGVhZGVyID0gWyAncHJpY2UnLCd0b3RhbCcsJ3F1YW50aXR5J107XG4gICAgICAgICAgICAgICAgICAgIGxldCBjb2x1bW5OYW1lID0gZGF0YS50ZXh0LnNsaWNlKDAsIC01KTtcbiAgICAgICAgICAgICAgICAgICAgaWYoZnJlZUhlYWRlci5pbmNsdWRlcyhzZWxlY3RJdGVtKSl7XG4gICAgICAgICAgICAgICAgICAgICAgICAkKCcud29vX2ludm9pY2VfcHJvX25vdGljZScpLmhpZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgfWVsc2V7XG4gICAgICAgICAgICAgICAgICAgICAgICAkKCcud29vX2ludm9pY2VfcHJvX25vdGljZV9uYW1lJykudGV4dChjb2x1bW5OYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXlfY2hhbGxhbl9wcm9fbm90aWNlX21vZGFsKGBUbyBhZGQgPHNwYW4gc3R5bGU9XCJmb250LXdlaWdodDogYm9sZDtcIj4ke2NvbHVtbk5hbWV9PC9zcGFuPiBjb2x1bW4geW91IGhhdmUgdG8gdXBncmFkZWApO1xuICAgICAgICAgICAgICAgICAgICAgICAgJCgnLndvb19pbnZvaWNlX3Byb19ub3RpY2UnKS5zaG93KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gJzxkaXYgY2xhc3M9XCJpdGVtIHdwaWZ3X3NlbGVjdG9yXCIgZGlzYWJsZWQ9XCJkaXNhYmxlXCI+JysgZXNjYXBlKGRhdGEudGV4dCkgKyAnPC9kaXY+JztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb25Jbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIHNlbGVjdGl6ZSA9IHRoaXM7XG4gICAgICAgICAgICAgICAgJC5hamF4KFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cmw6IHdvb19pbnZvaWNlX2FqYXhfb2JqXzIud29vX2ludm9pY2VfYWpheF91cmxfMixcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdwb3N0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfYWpheF9ub25jZTogd29vX2ludm9pY2VfYWpheF9vYmpfMi5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb246IFwid3BpZndfZ2V0X3Byb2R1Y3RfY29sdW1uX3Nob3dcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzOiBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ZWRfaXRlbXMgPSBbXS5zbGljZS5jYWxsKHJlc3BvbnNlLmRhdGEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGl6ZS5zZXRWYWx1ZShzZWxlY3RlZF9pdGVtcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgKTtcblxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgLy8gU2F2ZSBQcm9kdWN0IENvbHVtbi5cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgICQoZG9jdW1lbnQpLm9uKFxuICAgICAgICAnY2hhbmdlJywgJy53cGlmd19oZWFkZXInLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgJC5hamF4KFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgdXJsOiB3b29faW52b2ljZV9hamF4X29ial8yLndvb19pbnZvaWNlX2FqYXhfdXJsXzIsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICdwb3N0JyxcbiAgICAgICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICAgICAgX2FqYXhfbm9uY2U6IHdvb19pbnZvaWNlX2FqYXhfb2JqXzIubm9uY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb246IFwid3BpZndfc2VsZWN0X3Byb2R1Y3RfY29sdW1uXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW5zOiAkKFwiLndwaWZ3X2hlYWRlclwiKS52YWwoKVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzOiBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICApO1xuXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICAvLyBTdGFydCA6IFNob3cgbW9kYWwgYW5kIGNsb3NlIG1vZGFsLlxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgLy8gbW9kYWwgc2hvdyBmdW5jdGlvblxuICAgIGZ1bmN0aW9uIGRpc3BsYXlfY2hhbGxhbl9wcm9fbm90aWNlX21vZGFsKGNvbnRlbnQpIHtcbiAgICAgICAgJChcIi53b28taW52b2ljZS1tb2RhbFwiKS5zaG93KCk7XG4gICAgICAgICQoXCIud29vLWludm9pY2UtbW9kYWwtYm9keSBwXCIpLmh0bWwoXG4gICAgICAgICAgICBgJHtjb250ZW50fSAgPGEgdHlwZT0nYnV0dG9uJyBocmVmPSdodHRwczovL3dlYmFwcGljay5jb20vcGx1Z2luL3dvb2NvbW1lcmNlLXBkZi1pbnZvaWNlLXBhY2tpbmctc2xpcHMvP3V0bV9zb3VyY2U9Y3VzdG9tZXJfc2l0ZSZ1dG1fbWVkaXVtPWZyZWVfdnNfcHJvJnV0bV9jYW1wYWlnbj13b29faW52b2ljZV9mcmVlJyB0YXJnZXQ9J19ibGFuayc+Q2hhbGxhbiBQcm88L2E+YFxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8vIENsb3NlIG1vZGFsLlxuICAgICQoXCIud29vLWludm9pY2UtbW9kYWwgLndvby1pbnZvaWNlLW1vZGFsLWNsb3NlXCIpLm9uKFwiY2xpY2tcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAkKFwiLndvby1pbnZvaWNlLW1vZGFsXCIpLmhpZGUoKTtcbiAgICB9KTtcblxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgLy8gRW5kIDogU2hvdyBtb2RhbCBhbmQgY2xvc2UgbW9kYWwuXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuICAgICQod2luZG93KS5sb2FkKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgJChcIiN3cGZvb3RlciAjZm9vdGVyLXRoYW5reW91XCIpLmh0bWwoXG4gICAgICAgICAgICBcIklmIHlvdSBsaWtlIDxzdHJvbmc+PGlucz5DaGFsbGFuPC9pbnM+PC9zdHJvbmc+IHBsZWFzZSBsZWF2ZSB1cyBhIDxhIHRhcmdldD0nX2JsYW5rJyBzdHlsZT0nY29sb3I6I2Y5YjkxOCcgaHJlZj0naHR0cHM6Ly93b3JkcHJlc3Mub3JnL3N1cHBvcnQvdmlldy9wbHVnaW4tcmV2aWV3cy93ZWJhcHBpY2stcGRmLWludm9pY2UtZm9yLXdvb2NvbW1lcmNlP3JhdGU9NSNwb3N0Zm9ybSc+4piF4piF4piF4piF4piFPC9hPiByYXRpbmcuIEEgaHVnZSB0aGFuayB5b3UgaW4gYWR2YW5jZSFcIlxuICAgICAgICApO1xuICAgIH0pO1xufSkoalF1ZXJ5KTtcbiJdfQ==
  • webappick-pdf-invoice-for-woocommerce/tags/3.7.89/admin/partials/tabs/bulk-download-tab.php

    r3463094 r3743261  
    247247                            <p class="woo-invoice-banner-title">Upgrade to Challan Pro Today!</p>
    248248                            <button
    249                                     onclick="window.open('https://webappick.com/discount-deal/?utm_source=10YC-fix&utm_medium=free-to-pro&utm_campaign=10Y-25&utm_id=1')"
     249                                    onclick="window.open('https://webappick.com/plugin/woocommerce-pdf-invoice-packing-slips/?utm_source=customer_site&utm_medium=free_vs_pro&utm_campaign=woo_invoice_free', '_blank')"
    250250                                    class="woo-invoice-banner-btn"
    251251                            >
  • webappick-pdf-invoice-for-woocommerce/tags/3.7.89/admin/partials/tabs/free-vs-pro-tab.php

    r3463094 r3743261  
    218218                            <p class="woo-invoice-banner-title">Upgrade to Challan Pro Today!</p>
    219219                            <button
    220                                     onclick="window.open('https://webappick.com/discount-deal/?utm_source=10YC-fix&utm_medium=free-to-pro&utm_campaign=10Y-25&utm_id=1')"
     220                                    onclick="window.open('https://webappick.com/plugin/woocommerce-pdf-invoice-packing-slips/?utm_source=customer_site&utm_medium=free_vs_pro&utm_campaign=woo_invoice_free', '_blank')"
    221221                                    class="woo-invoice-banner-btn"
    222222                            >
  • webappick-pdf-invoice-for-woocommerce/tags/3.7.89/admin/partials/tabs/seller-buyer-tab.php

    r3463094 r3743261  
    118118                            <p class="woo-invoice-banner-title">Upgrade to Challan Pro Today!</p>
    119119                            <button
    120                                     onclick="window.open('https://webappick.com/discount-deal/?utm_source=10YC-fix&utm_medium=free-to-pro&utm_campaign=10Y-25&utm_id=1')"
     120                                    onclick="window.open('https://webappick.com/plugin/woocommerce-pdf-invoice-packing-slips/?utm_source=customer_site&utm_medium=free_vs_pro&utm_campaign=woo_invoice_free', '_blank')"
    121121                                    class="woo-invoice-banner-btn"
    122122                            >
  • webappick-pdf-invoice-for-woocommerce/tags/3.7.89/admin/partials/tabs/settings-tab.php

    r3463094 r3743261  
    779779                            <p class="woo-invoice-banner-title">Upgrade to Challan Pro Today!</p>
    780780                            <button
    781                                     onclick="window.open('https://webappick.com/discount-deal/?utm_source=10YC-fix&utm_medium=free-to-pro&utm_campaign=10Y-25&utm_id=1')"
     781                                    onclick="window.open('https://webappick.com/plugin/woocommerce-pdf-invoice-packing-slips/?utm_source=customer_site&utm_medium=free_vs_pro&utm_campaign=woo_invoice_free', '_blank')"
    782782                                    class="woo-invoice-banner-btn"
    783783                            >
    … …  
    809809                    </div>
    810810                <?php endif; ?>
     811                <?php
     812                if ( ! function_exists( 'get_last_order_id' ) ) {
     813                    /**
     814                     * Latest order in the store, any status.
     815                     *
     816                     * @return int
     817                     */
     818                    function get_last_order_id() {
     819                        $cache_key     = 'woo_last_store_order_id';
     820                        $last_order_id = wp_cache_get( $cache_key );
     821
     822                        if ( false === $last_order_id ) {
     823                            $orders        = wc_get_orders(
     824                                array(
     825                                    'limit'   => 1,
     826                                    'orderby' => 'date',
     827                                    'order'   => 'DESC',
     828                                    'status'  => 'any',
     829                                    'return'  => 'ids',
     830                                )
     831                            );
     832                            $last_order_id = ! empty( $orders ) ? $orders[0] : 0;
     833
     834                            if ( $last_order_id ) {
     835                                wp_cache_set( $cache_key, $last_order_id, '', 60 );
     836                            }
     837                        }
     838
     839                        return $last_order_id;
     840                    }
     841                }
     842
     843                $order_id      = get_last_order_id();
     844                $preview_order = absint( $order_id ) ? wc_get_order( absint( $order_id ) ) : false;
     845                if ( $preview_order ) :
     846                    ?>
    811847                <div class="woo-invoice-card">
    812848                    <div class="woo-invoice-card-header">
    … …  
    816852                        <?php
    817853                        $template_name = get_option('wpifw_templateid');
    818 
    819                         // Function to get the last order ID
    820                         function get_last_order_id() {
    821                             $cache_key = 'woo_last_order_id';
    822                             $last_order_id = wp_cache_get( $cache_key );
    823 
    824                             if ( false === $last_order_id ) {
    825                                 $statuses = wc_get_is_paid_statuses(); // safer than all possible statuses
    826 
    827                                 $args = array(
    828                                     'limit'        => 1,
    829                                     'orderby'      => 'date',
    830                                     'order'        => 'DESC',
    831                                     'status'       => $statuses,
    832                                     'return'       => 'ids',
    833                                 );
    834 
    835                                 $orders = wc_get_orders( $args );
    836                                 $last_order_id = ! empty( $orders ) ? $orders[0] : 0;
    837 
    838                                 wp_cache_set( $cache_key, $last_order_id, '', 60 ); // cache for 60 seconds
    839                             }
    840 
    841                             return $last_order_id;
    842                         }
    843 
    844                         $order_id = get_last_order_id();
    845854                        $preview_url = esc_url(wp_nonce_url(admin_url('admin-ajax.php?action=wpifw_generate_invoice&order_id=' . $order_id) .'#toolbar=0', 'woo_invoice_ajax_nonce'));
    846855                        $template_image_url = esc_attr(CHALLAN_FREE_PLUGIN_URL . 'admin/images/templates/' . $template_name . '.png');
    847856                        ?>
    848857
    849                         <?php if ('' != $order_id) { ?>
     858                        <?php if ( $preview_order ) { ?>
    850859                            <div class="_winvoice-iframe-container">
    851                                 <iframe class="_winvoice-iframe-responsive woo-invoice-template-preview" src="<?php echo esc_url($preview_url); ?>"></iframe>
    852                             </div>
     860                                <iframe class="_winvoice-iframe-responsive woo-invoice-template-preview" src="<?php echo esc_url($preview_url); ?>" onload="challanFitPreviewFrame(this)"></iframe>
     861                            </div>
     862                            <script>
     863                                function challanFitPreviewFrame(frame) {
     864                                    var doc;
     865                                    try {
     866                                        doc = frame.contentDocument;
     867                                    } catch (e) {
     868                                        return;
     869                                    }
     870                                    if (!doc || !doc.body || doc.body.getAttribute('data-challan-notice') !== '1') {
     871                                        return;
     872                                    }
     873                                    var box = frame.parentNode;
     874                                    if (box) {
     875                                        box.style.aspectRatio = 'auto';
     876                                        box.style.height = 'auto';
     877                                    }
     878                                    frame.style.position = 'relative';
     879                                    frame.style.height = doc.body.scrollHeight + 'px';
     880                                }
     881                            </script>
     882                        <?php } elseif ( '' != $order_id ) { ?>
     883                            <p class="woo-invoice-preview-notice"><?php esc_html_e( 'Order not found.', 'webappick-pdf-invoice-for-woocommerce' ); ?></p>
     884                            <style>
     885                                .woo-invoice-preview-notice {
     886                                    box-sizing: border-box;
     887                                    height: auto;
     888                                    margin: 16px;
     889                                    padding: 12px 14px;
     890                                    background: #fcf9e8;
     891                                    border: 1px solid #dba617;
     892                                    border-left-width: 4px;
     893                                    color: #1d2327;
     894                                    font-size: 13px;
     895                                    line-height: 1.5;
     896                                    text-align: left;
     897                                }
     898                            </style>
    853899                        <?php } else { ?>
    854900                            <img class="woo-invoice-template-preview" src="<?php echo esc_url($template_image_url); //phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage ?>" alt="Preview Template">
    … …  
    869915                    </div><!-- end .woo-invoice-card-body -->
    870916                </div><!-- end .woo-invoice-card -->
     917                <?php endif; ?>
    871918
    872919                <!-- <div class="woo_invoice_template_free_vs_pro">
  • webappick-pdf-invoice-for-woocommerce/tags/3.7.89/admin/partials/tabs/system-status-tab.php

    r3463094 r3743261  
    320320                            <p class="woo-invoice-banner-title">Upgrade to Challan Pro Today!</p>
    321321                            <button
    322                                     onclick="window.open('https://webappick.com/discount-deal/?utm_source=10YC-fix&utm_medium=free-to-pro&utm_campaign=10Y-25&utm_id=1')"
     322                                    onclick="window.open('https://webappick.com/plugin/woocommerce-pdf-invoice-packing-slips/?utm_source=customer_site&utm_medium=free_vs_pro&utm_campaign=woo_invoice_free', '_blank')"
    323323                                    class="woo-invoice-banner-btn"
    324324                            >
  • webappick-pdf-invoice-for-woocommerce/tags/3.7.89/includes/class-woo-invoice-hooks.php

    r3467231 r3743261  
    660660        $allowed_statuses = apply_filters( 'woo_invoice_email_types', $allowed_statuses );
    661661
    662         // Delete old pdf files before generating new one.
    663         array_map( 'unlink', glob( CHALLAN_FREE_INVOICE_DIR . '*.pdf' ) ); // Delete files.
    664 
    665         // Generate & Save Invoice.
    666         woo_invoice_engine()->save_invoice($order_id);
    667 
    668         // Attach invoice with email.
     662        // Replace only this order's invoice. Other PDFs in the folder stay in place.
    669663        $invoice_no = woo_invoice_get_invoice_number( $order_id );
    670664        $file_name  = 'Invoice-' . $invoice_no;
    671665        $file_name  = apply_filters( 'woo_invoice_file_name', $file_name, 'invoice', $order_id );
     666        $pdf_path   = CHALLAN_FREE_INVOICE_DIR . $file_name . '.pdf';
     667
     668        $invoice_dir = wp_normalize_path( untrailingslashit( CHALLAN_FREE_INVOICE_DIR ) );
     669        $normalized  = wp_normalize_path( $pdf_path );
     670        if ( $invoice_dir && 0 === strpos( $normalized, $invoice_dir . '/' ) && file_exists( $pdf_path ) ) {
     671            wp_delete_file( $pdf_path );
     672        }
     673
     674        // Generate & Save Invoice.
     675        woo_invoice_engine()->save_invoice( $order_id );
    672676
    673677        // Return file path.
    674678        if ( isset( $status ) && in_array( $status, $allowed_statuses ) ) {
    675             $pdf_path      = CHALLAN_FREE_INVOICE_DIR . $file_name . '.pdf';
    676679            $attachments[] = $pdf_path;
    677680        }
    … …  
    837840            $order_id = ! empty($_REQUEST['order_id']) ? sanitize_text_field(wp_unslash($_REQUEST['order_id'])) : '';
    838841
    839             $order = wc_get_order($order_id);
     842            $order = wc_get_order( absint( $order_id ) );
     843            if ( ! $order ) {
     844                woo_invoice_exit_with_notice( __( 'Order not found.', 'webappick-pdf-invoice-for-woocommerce' ) );
     845            }
    840846            $user  = $order->get_user_id();
    841847            if ( wc_user_has_role(get_current_user_id(), 'administrator')
    … …  
    876882            $order_id = ! empty($_REQUEST['order_id']) ? sanitize_text_field(wp_unslash($_REQUEST['order_id'])) : '';
    877883
    878             $order = wc_get_order($order_id);
     884            $order = wc_get_order( absint( $order_id ) );
     885            if ( ! $order ) {
     886                woo_invoice_exit_with_notice( __( 'Order not found.', 'webappick-pdf-invoice-for-woocommerce' ) );
     887            }
    879888            $user  = $order->get_user_id();
    880889            if ( wc_user_has_role(get_current_user_id(), 'administrator')
    … …  
    919928                        $order_id = ! empty($_REQUEST['order_id']) ? sanitize_text_field(wp_unslash($_REQUEST['order_id'])) : '';
    920929
    921                         $order = wc_get_order($order_id);
     930                        $order = wc_get_order( absint( $order_id ) );
     931                        if ( ! $order ) {
     932                                woo_invoice_exit_with_notice( __( 'Order not found.', 'webappick-pdf-invoice-for-woocommerce' ) );
     933                        }
    922934                        $user  = $order->get_user_id();
    923935                        if ( wc_user_has_role(get_current_user_id(), 'administrator')
    … …  
    949961    public function save_pdf_template() {
    950962        check_ajax_referer('woo_invoice_ajax_nonce');
    951         $template = array(
    952                         'template_name' => isset($_POST['template']) ? sanitize_text_field(wp_unslash($_POST['template'])) : '',
    953                         'location'      => CHALLAN_FREE_PLUGIN_URL . 'admin/images/templates',
    954         );
    955 
    956         if ( ! empty($template) ) {
    957             update_option('wpifw_templateid', $template['template_name']);
    958             wp_send_json_success($template);
    959         }
    960         wp_send_json_error($_POST);
     963        $template_name = isset($_POST['template']) ? sanitize_key(wp_unslash($_POST['template'])) : '';
     964
     965        // Accept only template ids that have a stylesheet in includes/templates (e.g. invoice-1).
     966        $is_valid_template = 1 === preg_match('/^invoice-\d+$/', $template_name)
     967            && file_exists(CHALLAN_FREE_ROOT_FILE_PATH . 'includes/templates/' . $template_name . '.css');
     968
     969        if ( $is_valid_template ) {
     970            update_option('wpifw_templateid', $template_name);
     971            wp_send_json_success(
     972                array(
     973                                        'template_name' => $template_name,
     974                                        'location'      => CHALLAN_FREE_PLUGIN_URL . 'admin/images/templates',
     975                )
     976            );
     977        }
     978        wp_send_json_error( array( 'message' => 'Could not save the template.' ) );
    961979    }
    962980
  • webappick-pdf-invoice-for-woocommerce/tags/3.7.89/includes/classes/class-admin-ui-font-downloader.php

    r3467231 r3743261  
    5757            $res        = $zip->open($zipFile);
    5858            if ( TRUE === $res ) {
     59                if ( ! self::zipEntriesAreSafe( $zip ) ) {
     60                    $zip->close();
     61                    wp_delete_file( $zipFile );
     62                    return false;
     63                }
    5964                $zip->extractTo($extractTo);
    6065                $zip->close();
    … …  
    9499        return self::$fontConfig;
    95100    }
     101
     102    /**
     103     * Reject ZIP entries that would write outside the destination directory.
     104     *
     105     * @param ZipArchive $zip Open archive.
     106     * @return bool
     107     */
     108    private static function zipEntriesAreSafe( $zip ) {
     109        for ( $i = 0; $i < $zip->numFiles; $i++ ) {
     110            $entry_name = $zip->getNameIndex( $i );
     111            if ( ! is_string( $entry_name ) ) {
     112                return false;
     113            }
     114            $entry_name = str_replace( '\\', '/', $entry_name );
     115            if ( false !== strpos( $entry_name, '..' ) || ( isset( $entry_name[0] ) && '/' === $entry_name[0] ) ) {
     116                return false;
     117            }
     118        }
     119        return true;
     120    }
    96121}
  • webappick-pdf-invoice-for-woocommerce/tags/3.7.89/includes/classes/class-dropbox-font-downloader.php

    r3467231 r3743261  
    117117        $res = $zip->open($zipFile);
    118118        if ( TRUE === $res ) {
     119            if ( ! self::zipEntriesAreSafe( $zip ) ) {
     120                $zip->close();
     121                wp_delete_file( $zipFile );
     122                return false;
     123            }
    119124            $zip->extractTo($extractTo);
    120125            $zip->close();
    … …  
    126131            return false;
    127132        }
     133    }
     134
     135    /**
     136     * Reject ZIP entries that would write outside the destination directory.
     137     *
     138     * @param ZipArchive $zip Open archive.
     139     * @return bool
     140     */
     141    private static function zipEntriesAreSafe( $zip ) {
     142        for ( $i = 0; $i < $zip->numFiles; $i++ ) {
     143            $entry_name = $zip->getNameIndex( $i );
     144            if ( ! is_string( $entry_name ) ) {
     145                return false;
     146            }
     147            $entry_name = str_replace( '\\', '/', $entry_name );
     148            if ( false !== strpos( $entry_name, '..' ) || ( isset( $entry_name[0] ) && '/' === $entry_name[0] ) ) {
     149                return false;
     150            }
     151        }
     152        return true;
    128153    }
    129154
  • webappick-pdf-invoice-for-woocommerce/tags/3.7.89/includes/classes/class-mpdf-lib-downloader.php

    r3190901 r3743261  
    4141        $arrContextOptions = array(
    4242            "ssl" => array(
    43                 "verify_peer"      => false,
    44                 "verify_peer_name" => false,
     43                "verify_peer"      => true,
     44                "verify_peer_name" => true,
    4545            ),
    4646        );
    … …  
    5252            $res        = $zip->open($zipFile);
    5353            if ( TRUE === $res ) {
     54                if ( ! self::zipEntriesAreSafe( $zip ) ) {
     55                    $zip->close();
     56                    wp_delete_file( $zipFile );
     57                    return false;
     58                }
    5459                $zip->extractTo($extractTo);
    5560                $zip->close();
    … …  
    6368        }
    6469    }
     70
     71    /**
     72     * Reject ZIP entries that would write outside the destination directory.
     73     *
     74     * @param ZipArchive $zip Open archive.
     75     * @return bool
     76     */
     77    private static function zipEntriesAreSafe( $zip ) {
     78        for ( $i = 0; $i < $zip->numFiles; $i++ ) {
     79            $entry_name = $zip->getNameIndex( $i );
     80            if ( ! is_string( $entry_name ) ) {
     81                return false;
     82            }
     83            $entry_name = str_replace( '\\', '/', $entry_name );
     84            if ( false !== strpos( $entry_name, '..' ) || ( isset( $entry_name[0] ) && '/' === $entry_name[0] ) ) {
     85                return false;
     86            }
     87        }
     88        return true;
     89    }
    6590}
  • webappick-pdf-invoice-for-woocommerce/tags/3.7.89/includes/constants.php

    r3722380 r3743261  
    1515}
    1616
    17 define( 'CHALLAN_FREE_VERSION', '3.7.88' );
     17define( 'CHALLAN_FREE_VERSION', '3.7.89' );
    1818
    1919if ( ! defined( 'CHALLAN_FREE_FONTS_COUNT' ) ) {
  • webappick-pdf-invoice-for-woocommerce/tags/3.7.89/includes/helper.php

    r3467231 r3743261  
    7777}
    7878
     79if ( ! function_exists('challan_get_cached_meta_keys') ) {
     80    /**
     81     * Return a meta key list from a transient and run the query only when the transient is empty.
     82     *
     83     * The lists are cleared by challan_flush_meta_keys_cache() when the Settings tab is saved,
     84     * so newly added meta keys show up right after a save.
     85     *
     86     * @param string   $cache_key Transient name.
     87     * @param callable $query     Returns the meta key rows.
     88     * @return array
     89     */
     90    function challan_get_cached_meta_keys( $cache_key, $query ) {
     91        $meta_keys = get_transient( $cache_key );
     92        if ( false === $meta_keys ) {
     93            $meta_keys = call_user_func( $query );
     94            $meta_keys = is_array( $meta_keys ) ? $meta_keys : array();
     95            set_transient( $cache_key, $meta_keys, 12 * HOUR_IN_SECONDS );
     96        }
     97
     98        return $meta_keys;
     99    }
     100}
     101
     102if ( ! function_exists('challan_flush_meta_keys_cache') ) {
     103    /**
     104     * Delete the cached order, product and order item meta key lists.
     105     *
     106     * @return void
     107     */
     108    function challan_flush_meta_keys_cache() {
     109        delete_transient( 'challan_order_meta_keys_hpos' );
     110        delete_transient( 'challan_order_meta_keys_cpt' );
     111        delete_transient( 'challan_product_meta_keys' );
     112        delete_transient( 'challan_item_meta_keys' );
     113    }
     114}
     115
    79116if ( ! function_exists('challan_order_meta_query') ) {
    80117    /**
    81      * @return array|object|null
     118     * @return array
    82119     */
    83120    function challan_order_meta_query(){
    84         global $wpdb;
    85         // Check if HPOS (High-Performance Order Storage) is enabled
    86         if ( woo_invoice_hpos_enabled() ) {
    87             // HPOS is enabled, query the wc_orders_meta table
    88             // Note: Table name uses $wpdb->prefix which is a trusted WordPress value
    89             $table_name = esc_sql( $wpdb->prefix . 'wc_orders_meta' );
    90             $order_meta_query_arr = $wpdb->get_results( "SELECT DISTINCT meta_key FROM {$table_name}" ); // phpcs:ignore
    91         } else {
     121        $hpos_enabled = woo_invoice_hpos_enabled();
     122        $cache_key    = $hpos_enabled ? 'challan_order_meta_keys_hpos' : 'challan_order_meta_keys_cpt';
     123
     124        return challan_get_cached_meta_keys( $cache_key, function () use ( $hpos_enabled ) {
     125            global $wpdb;
     126            // Check if HPOS (High-Performance Order Storage) is enabled
     127            if ( $hpos_enabled ) {
     128                // HPOS is enabled, query the wc_orders_meta table
     129                // Note: Table name uses $wpdb->prefix which is a trusted WordPress value
     130                $table_name = esc_sql( $wpdb->prefix . 'wc_orders_meta' );
     131                return $wpdb->get_results( "SELECT DISTINCT meta_key FROM {$table_name}" ); // phpcs:ignore
     132            }
     133
    92134            // Traditional CPT-based orders are in use, query the postmeta table
    93135            // Note: $wpdb->postmeta and $wpdb->posts are trusted WordPress table name constants
    94             $order_meta_query_arr = $wpdb->get_results( $wpdb->prepare(
     136            return $wpdb->get_results( $wpdb->prepare(
    95137                "SELECT pm.meta_key FROM {$wpdb->postmeta} AS pm LEFT JOIN {$wpdb->posts} AS p ON pm.post_id = p.id WHERE p.post_type = %s GROUP BY pm.meta_key",
    96138                'shop_order'
    97139            ) ); // phpcs:ignore
    98         }
    99         $order_meta_query = array();
    100         $order_meta_query = $order_meta_query_arr;
    101 
    102         return $order_meta_query;
     140        } );
    103141    }
    104142}
    … …  
    106144if ( ! function_exists('challan_product_meta_query') ) {
    107145    /**
    108      * @return array|object|null
     146     * @return array
    109147     */
    110148    function challan_product_meta_query(){
    111         global $wpdb;
    112 
    113         // Note: $wpdb->postmeta and $wpdb->posts are trusted WordPress table name constants
    114         $product_meta_query = $wpdb->get_results( $wpdb->prepare(
    115             "SELECT pm.meta_key, pm.meta_id FROM {$wpdb->postmeta} AS pm LEFT JOIN {$wpdb->posts} AS p ON pm.post_id = p.id WHERE p.post_type = %s GROUP BY pm.meta_key",
    116             'product'
    117         ) ); // phpcs:ignore
    118 
    119         return $product_meta_query;
     149        return challan_get_cached_meta_keys( 'challan_product_meta_keys', function () {
     150            global $wpdb;
     151
     152            // Note: $wpdb->postmeta and $wpdb->posts are trusted WordPress table name constants
     153            return $wpdb->get_results( $wpdb->prepare(
     154                "SELECT pm.meta_key, pm.meta_id FROM {$wpdb->postmeta} AS pm LEFT JOIN {$wpdb->posts} AS p ON pm.post_id = p.id WHERE p.post_type = %s GROUP BY pm.meta_key",
     155                'product'
     156            ) ); // phpcs:ignore
     157        } );
    120158    }
    121159}
    … …  
    123161if ( ! function_exists('challan_item_meta_query') ) {
    124162    /**
    125      * @return array|object|null
     163     * @return array
    126164     */
    127165    function challan_item_meta_query(){
    128         global $wpdb;
    129 
    130                 if ( class_exists( 'WooCommerce' ) ) {
    131                         // Note: $wpdb->order_itemmeta is a trusted WooCommerce table name constant
    132                         $item_meta = $wpdb->get_results( "SELECT DISTINCT meta_key FROM {$wpdb->order_itemmeta}" ); // phpcs:ignore
    133                 } else {
    134                         $item_meta = array();
    135                 }
    136 
    137         return $item_meta;
     166        return challan_get_cached_meta_keys( 'challan_item_meta_keys', function () {
     167            global $wpdb;
     168
     169            if ( ! class_exists( 'WooCommerce' ) ) {
     170                return array();
     171            }
     172
     173            // Note: $wpdb->order_itemmeta is a trusted WooCommerce table name constant
     174            return $wpdb->get_results( "SELECT DISTINCT meta_key FROM {$wpdb->order_itemmeta}" ); // phpcs:ignore
     175        } );
    138176    }
    139177}
    … …  
    383421    return true;
    384422}
     423
     424/**
     425 * Stop the request with a compact notice.
     426 * Used inside the invoice preview frame, which otherwise keeps an A4-page height.
     427 *
     428 * @param string $message Notice text.
     429 */
     430function woo_invoice_exit_with_notice( $message ) {
     431    if ( ! headers_sent() ) {
     432        status_header( 404 );
     433        nocache_headers();
     434        header( 'Content-Type: text/html; charset=utf-8' );
     435    }
     436
     437    $message = esc_html( $message );
     438    echo '<!DOCTYPE html><html><head><meta charset="utf-8"><style>
     439html,body{margin:0;height:auto;background:#fff;}
     440body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;}
     441.challan-order-notice{box-sizing:border-box;margin:16px;padding:12px 14px;background:#fcf9e8;border:1px solid #dba617;border-left-width:4px;color:#1d2327;font-size:13px;line-height:1.5;}
     442</style></head><body data-challan-notice="1"><p class="challan-order-notice">' . $message . '</p></body></html>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
     443    exit;
     444}
  • webappick-pdf-invoice-for-woocommerce/tags/3.7.89/includes/rest-api/font-downloader-api.php

    r3467231 r3743261  
    248248                        wp_send_json($response->get_data(), 200);
    249249                        exit;
    250                         wp_die();
    251250                }
    252251    } // end class definition
    253252
    254253    add_action('rest_api_init', function () {
    255                 if ( ! headers_sent() ) {
    256                         header('Access-Control-Allow-Headers: Authorization, X-WP-Nonce,Content-Type, X-Requested-With');
    257                         // Security: Only allow requests from the same origin (WordPress site URL)
    258                         $allowed_origin = esc_url_raw( home_url() );
    259                         header('Access-Control-Allow-Origin: ' . $allowed_origin);
    260                         header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
    261                         header('Access-Control-Allow-Credentials: true');
    262                 }
    263254        $apiFontDownloader = new Challan_Font_Downloader_API();
    264255        $apiFontDownloader->register_routes();
  • webappick-pdf-invoice-for-woocommerce/tags/3.7.89/includes/settings.php

    r3042853 r3743261  
    4040
    4141    if ( ! file_exists($invoice_dir_without_trailing_slash) && is_writable($base_dir) ) {
    42         mkdir($invoice_dir_without_trailing_slash, 0777, true);
     42        mkdir($invoice_dir_without_trailing_slash, 0755, true);
    4343        // Protect files from public access.
    4444        touch(CHALLAN_FREE_INVOICE_DIR . '.htaccess');
    … …  
    6363
    6464    if ( ! file_exists($wpifw_invoice_font_dir) && is_writable($base_dir) ) {
    65         mkdir($wpifw_invoice_font_dir, 0777, true);
     65        mkdir($wpifw_invoice_font_dir, 0755, true);
    6666
    6767        // Protect files from public access.
  • webappick-pdf-invoice-for-woocommerce/tags/3.7.89/includes/settings/admin-ui-fonts-dir-setting.php

    r3042853 r3743261  
    3030            //Make dir like /uploads/WOO-INVOICE-ADMIN-UI-FONTS/
    3131            if ( ! file_exists(rtrim(CHALLAN_ADMIN_UI_FONTS_DIR, "/")) ) {
    32                 mkdir(rtrim(CHALLAN_ADMIN_UI_FONTS_DIR, "/"), 0777, true);
     32                mkdir(rtrim(CHALLAN_ADMIN_UI_FONTS_DIR, "/"), 0755, true);
    3333            }
    3434        }
  • webappick-pdf-invoice-for-woocommerce/tags/3.7.89/includes/settings/invoice-temp-dir-setting.php

    r3042853 r3743261  
    3030            //Make dir like /WOO-INVOICE/TEMP
    3131            if ( ! file_exists(rtrim(CHALLAN_FREETEMP_DIR, "/")) ) {
    32                 mkdir(rtrim(CHALLAN_FREETEMP_DIR, "/"), 0777, true);
     32                mkdir(rtrim(CHALLAN_FREETEMP_DIR, "/"), 0755, true);
    3333            }
    3434            if ( is_writable(rtrim(CHALLAN_FREETEMP_DIR, "/")) ) {
    … …  
    4545            //Make dir like /WOO-INVOICE/TEMP/ttfontdata
    4646            if ( ! file_exists(CHALLAN_FREETEMP_DIR . "ttfontdata") ) {
    47                 mkdir(CHALLAN_FREETEMP_DIR . "ttfontdata", 0777, true);
     47                mkdir(CHALLAN_FREETEMP_DIR . "ttfontdata", 0755, true);
    4848            }
    4949            if ( is_writeable(CHALLAN_FREETEMP_DIR . "ttfontdata") ) {
  • webappick-pdf-invoice-for-woocommerce/tags/3.7.89/libs/WebAppick/AppServices/Insights.php

    r3258881 r3743261  
    22namespace Challan\AppServices;
    33
    4 use mysql_xdevapi\Exception;
    54use WP_Theme;
    65use WP_User;
    … …  
    256255                try {
    257256                        $intervalCheck = strtotime( $trackingInterval );
    258                 } catch ( Exception $e ) {
     257                } catch ( \Exception $e ) {
    259258                        // fallback to default 1 week if filter returned unusable data
    260259                        $intervalCheck = strtotime( '-1 week' );
  • webappick-pdf-invoice-for-woocommerce/tags/3.7.89/woo-invoice.php

    r3722380 r3743261  
    77 * Plugin URI:   https://webappick.com
    88 * Description:  Automatic Generate PDF Invoice and attach  with order email for WooCommerce.
    9  * Version:      3.7.88
     9 * Version:      3.7.89
    1010 * Author:       WebAppick
    1111 * Author URI:   https://webappick.com
    … …  
    6464    if ( woo_invoice_is_uploads_folder_writable() ) {
    6565        if ( ! file_exists(CHALLAN_FREE_INVOICE_DIR.'.htaccess' ) ) {
    66             mkdir( CHALLAN_FREE_INVOICE_DIR, 0777, true );
     66            mkdir( CHALLAN_FREE_INVOICE_DIR, 0755, true );
    6767            // Protect files from public access.
    6868            $content = 'deny from all';
    … …  
    8787        if ( woo_invoice_is_uploads_folder_writable() ) {
    8888        if ( ! file_exists(CHALLAN_FREE_FONT_DIR ) ) {
    89             mkdir( $wpifw_invoice_font_dir, 0777, true );
     89            mkdir( $wpifw_invoice_font_dir, 0755, true );
    9090            // Protect files from public access.
    9191            $content = 'deny from all';
    … …  
    319319        }
    320320
     321        // Rebuild the meta key dropdown lists after save so newly added keys appear.
     322        challan_flush_meta_keys_cache();
     323
    321324                // If checkbox is not checked then put empty value.
    322325                if ( ! isset( $_POST[ $invoice_allow ] ) ||
    … …  
    380383                $name = array();
    381384                $place = array();
    382                 $label_arr = isset($_POST['_winvoice_order_meta_label']) ? $_POST['_winvoice_order_meta_label'] : array(); //phpcs:ignore
    383                 $name_arr = isset($_POST['_winvoice_order_meta_name']) ? $_POST['_winvoice_order_meta_name'] : array(); //phpcs:ignore
    384                 $place_arr = isset($_POST['_winvoice_order_meta_name_position']) ? $_POST['_winvoice_order_meta_name_position'] : array(); //phpcs:ignore
     385                $label_arr = isset( $_POST['_winvoice_order_meta_label'] ) ? wp_unslash( $_POST['_winvoice_order_meta_label'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
     386                $name_arr = isset( $_POST['_winvoice_order_meta_name'] ) ? wp_unslash( $_POST['_winvoice_order_meta_name'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
     387                $place_arr = isset( $_POST['_winvoice_order_meta_name_position'] ) ? wp_unslash( $_POST['_winvoice_order_meta_name_position'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
     388                $label_arr = is_array( $label_arr ) ? $label_arr : array();
     389                $name_arr  = is_array( $name_arr ) ? $name_arr : array();
     390                $place_arr = is_array( $place_arr ) ? $place_arr : array();
    385391
    386392                foreach ( $label_arr as $index => $val ) {
    387 
    388                     if ( '' != $val && '' != $name_arr[ $index ] && '' != $place_arr[ $index ] ) {
    389                         array_push($label, $val);
    390                         array_push($name, $name_arr[ $index ]);
    391                         array_push($place, $place_arr[ $index ]);
    392                     } else {
    393                         $label_arr[ $index ] = '';
    394                         $name_arr[ $index ] = '';
    395                         $place_arr[ $index ] = '';
     393                    $val        = sanitize_text_field( $val );
     394                    $meta_name  = isset( $name_arr[ $index ] ) ? sanitize_text_field( $name_arr[ $index ] ) : '';
     395                    $meta_place = isset( $place_arr[ $index ] ) ? sanitize_text_field( $place_arr[ $index ] ) : '';
     396
     397                    if ( '' != $val && '' != $meta_name && '' != $meta_place ) {
     398                        array_push( $label, $val );
     399                        array_push( $name, $meta_name );
     400                        array_push( $place, $meta_place );
    396401                    }
    397402                }
    398403
    399                 if ( count($label) > 0 ) {
    400                     update_option($key, $label);
    401                     update_option('_winvoice_order_meta_name', $name);
    402                     update_option('_winvoice_order_meta_name_position', $place);
     404                if ( count( $label ) > 0 ) {
     405                    update_option( $key, $label );
     406                    update_option( '_winvoice_order_meta_name', $name );
     407                    update_option( '_winvoice_order_meta_name_position', $place );
    403408                } else {
    404                     update_option('_winvoice_order_meta_label', array());
    405                     update_option('_winvoice_order_meta_name', array());
    406                     update_option('_winvoice_order_meta_name_position', array());
     409                    update_option( '_winvoice_order_meta_label', array() );
     410                    update_option( '_winvoice_order_meta_name', array() );
     411                    update_option( '_winvoice_order_meta_name_position', array() );
    407412                }
    408             }elseif ( '_winvoice_post_meta_name' == $key ) {
    409 
    410                 $label = $_POST['_winvoice_post_meta_label']; //phpcs:ignore
    411                 $name = $_POST['_winvoice_post_meta_name']; //phpcs:ignore
     413            } elseif ( '_winvoice_post_meta_name' == $key ) {
     414
     415                $label = isset( $_POST['_winvoice_post_meta_label'] ) ? sanitize_text_field( wp_unslash( $_POST['_winvoice_post_meta_label'] ) ) : '';
     416                $name  = isset( $_POST['_winvoice_post_meta_name'] ) ? sanitize_text_field( wp_unslash( $_POST['_winvoice_post_meta_name'] ) ) : '';
    412417                if ( $name ) {
    413                     update_option('_winvoice_post_meta_label', $label);
    414                     update_option($key, $name);
     418                    update_option( '_winvoice_post_meta_label', $label );
     419                    update_option( $key, $name );
    415420                } else {
    416                     update_option('_winvoice_post_meta_label', '');
    417                     update_option('_winvoice_post_meta_name','');
     421                    update_option( '_winvoice_post_meta_label', '' );
     422                    update_option( '_winvoice_post_meta_name', '' );
    418423                }
    419             }elseif ( strpos( $key, '_winvoice_order_item_meta_name' ) !== false ) {
    420 
    421                 $label = $_POST['_winvoice_order_item_meta_label']; //phpcs:ignore
    422                 $name = $_POST['_winvoice_order_item_meta_name']; //phpcs:ignore
     424            } elseif ( strpos( $key, '_winvoice_order_item_meta_name' ) !== false ) {
     425
     426                $label = isset( $_POST['_winvoice_order_item_meta_label'] ) ? sanitize_text_field( wp_unslash( $_POST['_winvoice_order_item_meta_label'] ) ) : '';
     427                $name  = isset( $_POST['_winvoice_order_item_meta_name'] ) ? sanitize_text_field( wp_unslash( $_POST['_winvoice_order_item_meta_name'] ) ) : '';
    423428                if ( $name ) {
    424                     update_option('_winvoice_order_item_meta_label', $label);
    425                     update_option('_winvoice_order_item_meta_name', $name);
     429                    update_option( '_winvoice_order_item_meta_label', $label );
     430                    update_option( '_winvoice_order_item_meta_name', $name );
    426431                } else {
    427                     update_option('_winvoice_order_item_meta_label', '');
    428                     update_option('_winvoice_order_item_meta_name','');
     432                    update_option( '_winvoice_order_item_meta_label', '' );
     433                    update_option( '_winvoice_order_item_meta_name', '' );
    429434                }
    430435            }
  • webappick-pdf-invoice-for-woocommerce/trunk/README.txt

    r3722380 r3743261  
    55Requires at least: 3.6
    66Tested up to: 7.1
    7 Stable tag: 3.7.88
     7Stable tag: 3.7.89
    88Requires PHP: 7.4
    99License: GPLv2 or later
    … …  
    309309Help us & the WordPress community, translate the plugin [here](https://translate.wordpress.org/projects/wp-plugins/webappick-pdf-invoice-for-woocommerce/)
    310310
     311= 3.7.89  ( October 13, 2026 ) =
     312* Security: Sanitized the order, product and order item meta field settings before saving.
     313* Security: Added ZIP entry validation for the mPDF library and font downloads, and enabled SSL verification for the mPDF library download.
     314* Security: Removed the site-wide REST API CORS headers.
     315* Security: Invoice template selection now accepts only available templates.
     316* Fixed: Sending an order email no longer deletes the invoice PDFs of other orders.
     317* Fixed: Fatal error "Call to undefined function get_user_id" on the settings page template preview.
     318* Fixed: Upgrade buttons in the dashboard linked to an expired discount page.
     319* Improved: Meta key lists on the settings page are cached and refreshed when settings are saved.
     320* Improved: New invoice and font directories are created with 0755 permissions.
     321
    311322= 3.7.88  ( October 01, 2026 ) =
    312323* Updated : Plugin description.
  • webappick-pdf-invoice-for-woocommerce/trunk/admin/js/webappick-pdf-invoice-for-woocommerce-admin.js

    r3081641 r3743261  
    204204            },
    205205            success: function (response) {
     206                if (!response.success) {
     207                    return;
     208                }
    206209                $(".woo-invoice-template-preview").attr(
    207210                    "src",
  • webappick-pdf-invoice-for-woocommerce/trunk/admin/js/webappick-pdf-invoice-for-woocommerce-admin.min.js

    r3081641 r3743261  
    1 "use strict";!function(a){a(window).scroll(function(){a(this).scrollTop()+a(window).height()<a(document).height()-150?a(".woo-invoice-save-changes-selector").addClass("woo-invoice-save-changes"):a(".woo-invoice-save-changes-selector").removeClass("woo-invoice-save-changes")}),a(window).scroll(function(){a(this).scrollTop()+a(window).height()<a(document).height()-150?a(".woo-invoice-banner-sidebar").addClass("woo-invoice-banner-sidebar-sticky"):a(".woo-invoice-banner-sidebar").removeClass("woo-invoice-banner-sidebar-sticky")}),a(window).on("mousewheel",function(e){var o=a(".woo-invoice-dashboard-content > li:eq(0)");a(".woo-invoice-dashboard-sidebar .woo-invoice-sidebar-navbar-light").height(o.parent().height()-23)}),a(window).load(function(){a("input[name='wf_tabs']").on("change",function(){var e=a(this).val();sessionStorage.setItem("active_tab",e)});var e,o,i=sessionStorage.getItem("active_tab"),t=("settings"===i?a("#tab1").attr("checked",!0):"seller&buyer"===i?a("#tab2").attr("checked",!0):"localization"===i?a("#tab3").attr("checked",!0):"bulk_download"===i&&a("#tab4").attr("checked",!0),0),n=0;a("#Date-from").on("change",function(){e=Date.parse(a(this).val()),n=1,t&&n&&o<e&&(alert("Input date should be less than or equal Date To"),a("#Date-from").val(""),n=0)}),a("#Date-to").on("change",function(){o=Date.parse(a(this).val()),(t=1)&&n&&o<e&&(alert("Input date should be greater than or equal Date From"),a("#Date-to").val(""),t=0)}),a(function(){var e,o=a(".woo-invoice-sidebar-navbar-nav > li > a"),i=a(".woo-invoice-dashboard-content > li");null!=sessionStorage.getItem("activeSidebarTab")?(e=sessionStorage.getItem("activeSidebarTab"),i.hide(),o.removeClass("active"),a(i[e]).show(),a(".woo-invoice-sidebar-navbar-nav > li:eq( "+e+" ) > a").addClass("active"),a(".woo-invoice-dashboard-sidebar .woo-invoice-sidebar-navbar-light").height(a(i[e]).parent().height()-23)):((e=a(".woo-invoice-dashboard-content > li:eq(0)")).css("display","block"),a(".woo-invoice-sidebar-navbar-nav > li:eq(0) > a").addClass("active"),a(".woo-invoice-dashboard-sidebar .woo-invoice-sidebar-navbar-light").height(e.parent().height()-23)),o.bind("click",function(e){e.preventDefault();e=a(this).parent().prevAll().length,i.hide(),o.removeClass("active"),a(i[e]).show(),a(this).addClass("active"),e=a(this).parent().prevAll().length;sessionStorage.setItem("activeSidebarTab",e),a(".woo-invoice-dashboard-sidebar .woo-invoice-sidebar-navbar-light").height(i.parent().height()-23)})})}),a(document).on("click",".woo-invoice-template-selection",function(e){e.preventDefault();e=a(this).data("template");a("#winvoiceModalTemplates").modal("hide"),a("body").removeClass(function(e,o){return(o.match(/\S+-modal-open(^|\s)/g)||[]).join(" ")}),a('div[class*="-modal-backdrop"]').remove(),a(this).find("img").removeClass("woo-invoice-template"),a(this).find("img").removeClass("woo-invoice-disable-template"),a(this).find("img").addClass("woo-invoice-slected-template"),a(".woo-invoice-element-disable").find("img").addClass("woo-invoice-template"),a(".woo-invoice-element-disable").find("img").removeClass("woo-invoice-disable-template"),a(".woo-invoice-element-disable").css("z-index","3333"),a(".woo-invoice-element-disable").siblings("div").css("z-index","1111"),a(".woo-invoice-element-disable").siblings("a").css("z-index","2222"),a(this).parent().siblings().find("img").removeClass("woo-invoice-slected-template").addClass("woo-invoice-template"),a.ajax({url:woo_invoice_ajax_obj_2.woo_invoice_ajax_url_2,type:"post",data:{_ajax_nonce:woo_invoice_ajax_obj_2.nonce,action:"wpifw_save_pdf_template",template:e},success:function(e){a(".woo-invoice-template-preview").attr("src",e.data.location+"/"+e.data.template_name+".png"),a(".invoice_template_preiview_btn").attr("href",e.data.location+"/"+e.data.template_name+".png")}})}),a(document).on("click",".woo-invoice-element-disable",function(e){e.preventDefault(),a(this).children("img").removeClass("woo-invoice-template"),a(this).children("img").addClass("woo-invoice-disable-template"),a(this).css("z-index","1111"),a(this).siblings("div").css("z-index","2222"),a(this).siblings("a").css("z-index","3333")}),flatpickr(".woo-invoice-datepicker",{dateFormat:"n/j/Y",allowInput:!0,onOpen:function(e,o,i){i.setDate(i.input.value,!1)}});var o=a(".woo_invoice_order_meta_html").first().clone(),i=(a(document).on("click",".woo-invoice-add-order-meta",function(e){e.preventDefault(),0<a(".woo_invoice_order_meta > .woo_invoice_order_meta_html").length?n("You can add more than 1 order meta in"):a(this).siblings(".woo_invoice_order_meta").append(o.clone())}),a(document).on("click",".woo-invoice-delete-order-meta",function(e){e.preventDefault(),a(this).parent().remove(),a(".woo_invoice_order_meta_html").length}),a(".woo_invoice_order_item_meta_html").first().clone()),t=(a(document).on("click",".woo-invoice-add-order-item-meta",function(e){e.preventDefault(),0<a(".woo_invoice_order_item_meta > .woo_invoice_order_item_meta_html").length?n("You can add more than 1 order item meta in"):a(this).siblings(".woo_invoice_order_item_meta").append(i.clone())}),a(document).on("click",".woo-invoice-delete-order-item-meta",function(e){e.preventDefault(),a(this).parent().remove(),a(".woo_invoice_order_item_meta_html").length}),a(".woo_invoice_product_meta_html").first().clone());function e(e,o){a(document).on("change","".concat(e).concat(o),function(e){var o=this;e.preventDefault(),"all"!==a(this).val()&&(a(this).parent().append('<p  class="woo_invoice_meta_html woo_invoice_col_3 woo_invoice_pro_notice">Notice: Challan Pro only.</p>'),setTimeout(function(){a(o).parent().children("p").hide("slow"),setTimeout(function(){a(o).parent().children("p").remove()},500)},2e3))})}function n(e){a(".woo-invoice-modal").show(),a(".woo-invoice-modal-body p").html("".concat(e,"  <a type='button' href='https://webappick.com/plugin/woocommerce-pdf-invoice-packing-slips/?utm_source=customer_site&utm_medium=free_vs_pro&utm_campaign=woo_invoice_free' target='_blank'>Challan Pro</a>"))}a(document).on("click",".woo-invoice-product-add-meta",function(e){e.preventDefault(),0<a(".woo_invoice_product_meta > .woo_invoice_product_meta_html").length?n("You can add more than 1 product meta in"):a(this).siblings(".woo_invoice_product_meta").append(t.clone())}),a(document).on("click",".woo-invoice-delete-product-meta",function(e){e.preventDefault(),a(this).parent().remove(),a(".woo_invoice_product_meta_html").length}),a(document).on("click","#wpifw_submit_bulk_download",function(o){a(this).parent().parent().serializeArray().map(function(e){"wpifw_bulk_type"==e.name&&"WPIFW_CSV"==e.value?(o.preventDefault(),n("To download bulk csv file you need")):"wpifw_bulk_type"==e.name&&"WPIFW_SHIPPING_LABEL"==e.value&&(o.preventDefault(),n("To download bulk shipping label you need"))})}),e("#","wpifw_bulk_download_order_payment_method"),e("#","wpifw_bulk_download_order_status"),a(".wpifw_attr").selectize({plugins:["remove_button"],render:{item:function(e,o){return'<div class="item wpifw_selector">'+o(e.text)+"</div>"}}}),a(document).on("change","#wpifw_bulk_type",function(e){e.preventDefault(),"WPIFW_CSV"==a(this).val()?a(".woo-invoice-add-csv-fields").show():a(".woo-invoice-add-csv-fields").hide()}),a(".wpifw_header").selectize({plugins:["remove_button"],maxItems:4,render:{item:function(e,o){var i=e.value,t=e.text.slice(0,-5);return["price","total","quantity"].includes(i)?a(".woo_invoice_pro_notice").hide():(a(".woo_invoice_pro_notice_name").text(t),n('To add <span style="font-weight: bold;">'.concat(t,"</span> column you have to upgrade")),a(".woo_invoice_pro_notice").show()),'<div class="item wpifw_selector" disabled="disable">'+o(e.text)+"</div>"}},onInitialize:function(){var o=this;a.ajax({url:woo_invoice_ajax_obj_2.woo_invoice_ajax_url_2,type:"post",data:{_ajax_nonce:woo_invoice_ajax_obj_2.nonce,action:"wpifw_get_product_column_show"},success:function(e){e=[].slice.call(e.data);o.setValue(e)}})}}),a(document).on("change",".wpifw_header",function(e){e.preventDefault(),a.ajax({url:woo_invoice_ajax_obj_2.woo_invoice_ajax_url_2,type:"post",data:{_ajax_nonce:woo_invoice_ajax_obj_2.nonce,action:"wpifw_select_product_column",columns:a(".wpifw_header").val()},success:function(e){}})}),a(".woo-invoice-modal .woo-invoice-modal-close").on("click",function(){a(".woo-invoice-modal").hide()}),a(window).load(function(){a("#wpfooter #footer-thankyou").html("If you like <strong><ins>Challan</ins></strong> please leave us a <a target='_blank' style='color:#f9b918' href='https://wordpress.org/support/view/plugin-reviews/webappick-pdf-invoice-for-woocommerce?rate=5#postform'>★★★★★</a> rating. A huge thank you in advance!")})}(jQuery);
     1"use strict";!function(a){a(window).scroll(function(){a(this).scrollTop()+a(window).height()<a(document).height()-150?a(".woo-invoice-save-changes-selector").addClass("woo-invoice-save-changes"):a(".woo-invoice-save-changes-selector").removeClass("woo-invoice-save-changes")}),a(window).scroll(function(){a(this).scrollTop()+a(window).height()<a(document).height()-150?a(".woo-invoice-banner-sidebar").addClass("woo-invoice-banner-sidebar-sticky"):a(".woo-invoice-banner-sidebar").removeClass("woo-invoice-banner-sidebar-sticky")}),a(window).on("mousewheel",function(e){var o=a(".woo-invoice-dashboard-content > li:eq(0)");a(".woo-invoice-dashboard-sidebar .woo-invoice-sidebar-navbar-light").height(o.parent().height()-23)}),a(window).load(function(){a("input[name='wf_tabs']").on("change",function(){var e=a(this).val();sessionStorage.setItem("active_tab",e)});var e,o,i=sessionStorage.getItem("active_tab"),t=("settings"===i?a("#tab1").attr("checked",!0):"seller&buyer"===i?a("#tab2").attr("checked",!0):"localization"===i?a("#tab3").attr("checked",!0):"bulk_download"===i&&a("#tab4").attr("checked",!0),0),n=0;a("#Date-from").on("change",function(){e=Date.parse(a(this).val()),n=1,t&&n&&o<e&&(alert("Input date should be less than or equal Date To"),a("#Date-from").val(""),n=0)}),a("#Date-to").on("change",function(){o=Date.parse(a(this).val()),(t=1)&&n&&o<e&&(alert("Input date should be greater than or equal Date From"),a("#Date-to").val(""),t=0)}),a(function(){var e,o=a(".woo-invoice-sidebar-navbar-nav > li > a"),i=a(".woo-invoice-dashboard-content > li");null!=sessionStorage.getItem("activeSidebarTab")?(e=sessionStorage.getItem("activeSidebarTab"),i.hide(),o.removeClass("active"),a(i[e]).show(),a(".woo-invoice-sidebar-navbar-nav > li:eq( "+e+" ) > a").addClass("active"),a(".woo-invoice-dashboard-sidebar .woo-invoice-sidebar-navbar-light").height(a(i[e]).parent().height()-23)):((e=a(".woo-invoice-dashboard-content > li:eq(0)")).css("display","block"),a(".woo-invoice-sidebar-navbar-nav > li:eq(0) > a").addClass("active"),a(".woo-invoice-dashboard-sidebar .woo-invoice-sidebar-navbar-light").height(e.parent().height()-23)),o.bind("click",function(e){e.preventDefault();e=a(this).parent().prevAll().length,i.hide(),o.removeClass("active"),a(i[e]).show(),a(this).addClass("active"),e=a(this).parent().prevAll().length;sessionStorage.setItem("activeSidebarTab",e),a(".woo-invoice-dashboard-sidebar .woo-invoice-sidebar-navbar-light").height(i.parent().height()-23)})})}),a(document).on("click",".woo-invoice-template-selection",function(e){e.preventDefault();e=a(this).data("template");a("#winvoiceModalTemplates").modal("hide"),a("body").removeClass(function(e,o){return(o.match(/\S+-modal-open(^|\s)/g)||[]).join(" ")}),a('div[class*="-modal-backdrop"]').remove(),a(this).find("img").removeClass("woo-invoice-template"),a(this).find("img").removeClass("woo-invoice-disable-template"),a(this).find("img").addClass("woo-invoice-slected-template"),a(".woo-invoice-element-disable").find("img").addClass("woo-invoice-template"),a(".woo-invoice-element-disable").find("img").removeClass("woo-invoice-disable-template"),a(".woo-invoice-element-disable").css("z-index","3333"),a(".woo-invoice-element-disable").siblings("div").css("z-index","1111"),a(".woo-invoice-element-disable").siblings("a").css("z-index","2222"),a(this).parent().siblings().find("img").removeClass("woo-invoice-slected-template").addClass("woo-invoice-template"),a.ajax({url:woo_invoice_ajax_obj_2.woo_invoice_ajax_url_2,type:"post",data:{_ajax_nonce:woo_invoice_ajax_obj_2.nonce,action:"wpifw_save_pdf_template",template:e},success:function(e){e.success&&(a(".woo-invoice-template-preview").attr("src",e.data.location+"/"+e.data.template_name+".png"),a(".invoice_template_preiview_btn").attr("href",e.data.location+"/"+e.data.template_name+".png"))}})}),a(document).on("click",".woo-invoice-element-disable",function(e){e.preventDefault(),a(this).children("img").removeClass("woo-invoice-template"),a(this).children("img").addClass("woo-invoice-disable-template"),a(this).css("z-index","1111"),a(this).siblings("div").css("z-index","2222"),a(this).siblings("a").css("z-index","3333")}),flatpickr(".woo-invoice-datepicker",{dateFormat:"n/j/Y",allowInput:!0,onOpen:function(e,o,i){i.setDate(i.input.value,!1)}});var o=a(".woo_invoice_order_meta_html").first().clone(),i=(a(document).on("click",".woo-invoice-add-order-meta",function(e){e.preventDefault(),0<a(".woo_invoice_order_meta > .woo_invoice_order_meta_html").length?n("You can add more than 1 order meta in"):a(this).siblings(".woo_invoice_order_meta").append(o.clone())}),a(document).on("click",".woo-invoice-delete-order-meta",function(e){e.preventDefault(),a(this).parent().remove(),a(".woo_invoice_order_meta_html").length}),a(".woo_invoice_order_item_meta_html").first().clone()),t=(a(document).on("click",".woo-invoice-add-order-item-meta",function(e){e.preventDefault(),0<a(".woo_invoice_order_item_meta > .woo_invoice_order_item_meta_html").length?n("You can add more than 1 order item meta in"):a(this).siblings(".woo_invoice_order_item_meta").append(i.clone())}),a(document).on("click",".woo-invoice-delete-order-item-meta",function(e){e.preventDefault(),a(this).parent().remove(),a(".woo_invoice_order_item_meta_html").length}),a(".woo_invoice_product_meta_html").first().clone());function e(e,o){a(document).on("change","".concat(e).concat(o),function(e){var o=this;e.preventDefault(),"all"!==a(this).val()&&(a(this).parent().append('<p  class="woo_invoice_meta_html woo_invoice_col_3 woo_invoice_pro_notice">Notice: Challan Pro only.</p>'),setTimeout(function(){a(o).parent().children("p").hide("slow"),setTimeout(function(){a(o).parent().children("p").remove()},500)},2e3))})}function n(e){a(".woo-invoice-modal").show(),a(".woo-invoice-modal-body p").html("".concat(e,"  <a type='button' href='https://webappick.com/plugin/woocommerce-pdf-invoice-packing-slips/?utm_source=customer_site&utm_medium=free_vs_pro&utm_campaign=woo_invoice_free' target='_blank'>Challan Pro</a>"))}a(document).on("click",".woo-invoice-product-add-meta",function(e){e.preventDefault(),0<a(".woo_invoice_product_meta > .woo_invoice_product_meta_html").length?n("You can add more than 1 product meta in"):a(this).siblings(".woo_invoice_product_meta").append(t.clone())}),a(document).on("click",".woo-invoice-delete-product-meta",function(e){e.preventDefault(),a(this).parent().remove(),a(".woo_invoice_product_meta_html").length}),a(document).on("click","#wpifw_submit_bulk_download",function(o){a(this).parent().parent().serializeArray().map(function(e){"wpifw_bulk_type"==e.name&&"WPIFW_CSV"==e.value?(o.preventDefault(),n("To download bulk csv file you need")):"wpifw_bulk_type"==e.name&&"WPIFW_SHIPPING_LABEL"==e.value&&(o.preventDefault(),n("To download bulk shipping label you need"))})}),e("#","wpifw_bulk_download_order_payment_method"),e("#","wpifw_bulk_download_order_status"),a(".wpifw_attr").selectize({plugins:["remove_button"],render:{item:function(e,o){return'<div class="item wpifw_selector">'+o(e.text)+"</div>"}}}),a(document).on("change","#wpifw_bulk_type",function(e){e.preventDefault(),"WPIFW_CSV"==a(this).val()?a(".woo-invoice-add-csv-fields").show():a(".woo-invoice-add-csv-fields").hide()}),a(".wpifw_header").selectize({plugins:["remove_button"],maxItems:4,render:{item:function(e,o){var i=e.value,t=e.text.slice(0,-5);return["price","total","quantity"].includes(i)?a(".woo_invoice_pro_notice").hide():(a(".woo_invoice_pro_notice_name").text(t),n('To add <span style="font-weight: bold;">'.concat(t,"</span> column you have to upgrade")),a(".woo_invoice_pro_notice").show()),'<div class="item wpifw_selector" disabled="disable">'+o(e.text)+"</div>"}},onInitialize:function(){var o=this;a.ajax({url:woo_invoice_ajax_obj_2.woo_invoice_ajax_url_2,type:"post",data:{_ajax_nonce:woo_invoice_ajax_obj_2.nonce,action:"wpifw_get_product_column_show"},success:function(e){e=[].slice.call(e.data);o.setValue(e)}})}}),a(document).on("change",".wpifw_header",function(e){e.preventDefault(),a.ajax({url:woo_invoice_ajax_obj_2.woo_invoice_ajax_url_2,type:"post",data:{_ajax_nonce:woo_invoice_ajax_obj_2.nonce,action:"wpifw_select_product_column",columns:a(".wpifw_header").val()},success:function(e){}})}),a(".woo-invoice-modal .woo-invoice-modal-close").on("click",function(){a(".woo-invoice-modal").hide()}),a(window).load(function(){a("#wpfooter #footer-thankyou").html("If you like <strong><ins>Challan</ins></strong> please leave us a <a target='_blank' style='color:#f9b918' href='https://wordpress.org/support/view/plugin-reviews/webappick-pdf-invoice-for-woocommerce?rate=5#postform'>★★★★★</a> rating. A huge thank you in advance!")})}(jQuery);
    22//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYmFwcGljay1wZGYtaW52b2ljZS1mb3Itd29vY29tbWVyY2UtYWRtaW4uanMiXSwibmFtZXMiOlsiJCIsIndpbmRvdyIsInNjcm9sbCIsInNjcm9sbFRvcCIsImhlaWdodCIsImRvY3VtZW50IiwiYWRkQ2xhc3MiLCJyZW1vdmVDbGFzcyIsInRoaXMiLCJpbml0aWFsQ29udGVudCIsInNlc3Npb25TdG9yYWdlIiwiZSIsInBhcmVudCIsImxvYWQiLCJmcm9tX2RhdGUiLCJvbiIsInRvX2RhdGUiLCJzZWxlY3RlZFRhYiIsInZhbCIsInRvQ2hlY2siLCJzZXRJdGVtIiwiZnJvbUNoZWNrIiwiYWxlcnQiLCJwYXJzZSIsImFjdGl2ZVRhYiIsImF0dHIiLCJEYXRlIiwiYWN0aXZlU2lkZWJhclRhYiIsImFjdGl2ZVRhYlNlbGVjdG9yIiwidGFicyIsImNvbnRlbnRzIiwidGFiSW5kZXgiLCJzZWxlY3RlZFNpZGViYXJUYWIiLCJnZXRJdGVtIiwiaGlkZSIsInNob3ciLCJjbGFzc05hbWUiLCJjc3MiLCJ3b29faW52b2ljZV9hamF4X29ial8yIiwic3VjY2VzcyIsImJpbmQiLCJwcmV2ZW50RGVmYXVsdCIsInByZXZBbGwiLCJyZXNwb25zZSIsImxlbmd0aCIsImNoaWxkcmVuIiwic2libGluZ3MiLCJmbGF0cGlja3IiLCJkYXRlRm9ybWF0IiwiYWxsb3dJbnB1dCIsImRhdGEiLCJvbk9wZW4iLCJzZWxlY3RlZERhdGVzIiwiZGF0ZVN0ciIsImluc3RhbmNlIiwic2V0RGF0ZSIsInZhbHVlIiwibWF0Y2giLCJqb2luIiwicmVtb3ZlIiwiZmluZCIsImRpc3BsYXlfY2hhbGxhbl9wcm9fbm90aWNlX21vZGFsIiwiYWpheCIsInVybCIsIndvb19pbnZvaWNlX2FqYXhfdXJsXzIiLCJ0eXBlIiwiX2FqYXhfbm9uY2UiLCJub25jZSIsImFjdGlvbiIsInRlbXBsYXRlIiwib3JkZXJJdGVtTWV0YSIsImxvY2F0aW9uIiwidGVtcGxhdGVfbmFtZSIsInByb2R1Y3RNZXRhIiwiaW5wdXQiLCJhcHBlbmQiLCJmaXJzdCIsImNsb25lIiwic2V0VGltZW91dCIsImZpZWxkIiwibmFtZSIsImRpc3BsYXlfY2hhbGxhbl9wcm9fbm90aWNlX2Zvcl9zZWxlY3Rfb3B0aW9uIiwic2VsZWN0aXplIiwicmVuZGVyIiwic2VsZWN0b3JfdHlwZSIsInNlbGVjdG9yIiwiY29uY2F0IiwiX3RoaXMiLCJjb250ZW50IiwiaHRtbCIsInBsdWdpbnMiLCJtYXhJdGVtcyIsInNlbGVjdEl0ZW0iLCJjb2x1bW5OYW1lIiwiZnJlZUhlYWRlciIsIm9uSW5pdGlhbGl6ZSIsInNlcmlhbGl6ZUFycmF5IiwibWFwIiwiaXRlbSIsImVzY2FwZSIsInRleHQiLCJzbGljZSIsImluY2x1ZGVzIiwic2VsZWN0ZWRfaXRlbXMiLCJjYWxsIiwic2V0VmFsdWUiLCJjb2x1bW5zIiwialF1ZXJ5Il0sIm1hcHBpbmdzIjoiYUFBQSxDQUFBLFNBQVdBLEdBcUJQQSxFQUFFQyxNQUFNLEVBQUVDLE9BQU8sV0FBUEEsRUFBQUEsSUFBTSxFQUFDQyxVQUFBLEVBQVlILEVBQUFDLE1BQUEsRUFBQUcsT0FBQSxFQUVuQkosRUFBSUssUUFBRUYsRUFBQUEsT0FBZSxFQUFDRixJQU1yQkQsRUFBQSxvQ0FBQSxFQUFBTSxTQUNELDBCQUdOLEVBR01KLEVBQUFBLG9DQUFtQixFQUFBSyxZQUViSiwwQkFHTixDQVBWLENBQUMsRUFlQ0gsRUFBQUMsTUFBQSxFQUFBQyxPQUFBLFdBR0VGLEVBQUFRLElBQUEsRUFBQUwsVUFBQSxFQUFBSCxFQUFBQyxNQUFBLEVBQUFHLE9BQUEsRUFiSUosRUFBRUssUUFBUSxFQUFFRCxPQUFPLEVBQUksSUFnQjNCSixFQUFBLDZCQUFBLEVBQUFNLFNBQ0EsbUNBQ0EsRUFFSUcsRUFBQUEsNkJBQW1CLEVBQUFGLFlBRW5CLG1DQUVOLENBR0VQLENBQUMsRUFmTEEsRUFpQlFVLE1BQUFBLEVBQUFBLEdBQUFBLGFBQXVCLFNBQVlDLEdBVWpDLElBQUFGLEVBQWNULEVBQVMsMkNBQU8sRUFDbkNB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Qix1QkFBdUIwQix1QkFDNUJDLEtBQU0sT0FDTmYsS0FBTSxDQUNGZ0IsWUFBYTVCLHVCQUF1QjZCLE1BQ3BDQyxPQUFRLCtCQUNaLEVBQ0E3QixRQUFTLFNBQVVJLEdBQ1g0RCxFQUFpQixHQUFHRixNQUFNRyxLQUFLN0QsRUFBU08sSUFBSSxFQUNoRGdDLEVBQVV1QixTQUFTRixDQUFjLENBQ3JDLENBQ0osQ0FDSixDQUNKLENBQ0osQ0FDSixFQUtBdkcsRUFBRUssUUFBUSxFQUFFVSxHQUNSLFNBQVUsZ0JBQWlCLFNBQVVKLEdBQ2pDQSxFQUFFOEIsZUFBZSxFQUNqQnpDLEVBQUU4RCxLQUNFLENBQ0lDLElBQUt6Qix1QkFBdUIwQix1QkFDNUJDLEtBQU0sT0FDTmYsS0FBTSxDQUNGZ0IsWUFBYTVCLHVCQUF1QjZCLE1BQ3BDQyxPQUFRLDhCQUNSc0MsUUFBUzFHLEVBQUUsZUFBZSxFQUFFa0IsSUFBSSxDQUNwQyxFQUNBcUIsUUFBUyxTQUFVSSxJQUV2QixDQUNKLENBQ0osQ0FDSixFQWNBM0MsRUFBRSw2Q0FBNkMsRUFBRWUsR0FBRyxRQUFTLFdBQ3pEZixFQUFFLG9CQUFvQixFQUFFa0MsS0FBSyxDQUNqQyxDQUFDLEVBTURsQyxFQUFFQyxNQUFNLEVBQUVZLEtBQUssV0FDWGIsRUFBRSw0QkFBNEIsRUFBRXlGLEtBQzVCLDBRQUNKLENBQ0osQ0FBQyxDQUNKLEVBQUVrQixNQUFNIiwiZmlsZSI6IndlYmFwcGljay1wZGYtaW52b2ljZS1mb3Itd29vY29tbWVyY2UtYWRtaW4ubWluLmpzIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uICgkKSB7XG4gICAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgICAvKipcbiAgICAgKiBBbGwgb2YgdGhlIGNvZGUgZm9yIHlvdXIgYWRtaW4tZmFjaW5nIEphdmFTY3JpcHQgc291cmNlXG4gICAgICogc2hvdWxkIHJlc2lkZSBpbiB0aGlzIGZpbGUuXG4gICAgICpcbiAgICAgKiBOb3RlOiBJdCBoYXMgYmVlbiBhc3N1bWVkIHlvdSB3aWxsIHdyaXRlIGpRdWVyeSBjb2RlIGhlcmUsIHNvIHRoZVxuICAgICAqICQgZnVuY3Rpb24gcmVmZXJlbmNlIGhhcyBiZWVuIHByZXBhcmVkIGZvciB1c2FnZSB3aXRoaW4gdGhlIHNjb3BlXG4gICAgICogb2YgdGhpcyBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIFRoaXMgZW5hYmxlcyB5b3UgdG8gZGVmaW5lIGhhbmRsZXJzLCBmb3Igd2hlbiB0aGUgRE9NIGlzIHJlYWR5OlxuICAgICAqXG4gICAgICogJChmdW5jdGlvbigpIHtcbiAgICAgKlxuICAgICAqIH0pO1xuICAgICAqXG4gICAgICogV2hlbiB0aGUgd2luZG93IGlzIGxvYWRlZDpcbiAgICAgKi9cblxuICAgIC8vIHNjcm9sbCBhZGQgYW5kIHJlbW92ZSBjbGFzc1xuICAgICQod2luZG93KS5zY3JvbGwoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICAkKHRoaXMpLnNjcm9sbFRvcCgpICsgJCh3aW5kb3cpLmhlaWdodCgpIDxcbiAgICAgICAgICAgICQoZG9jdW1lbnQpLmhlaWdodCgpIC0gMTUwXG4gICAgICAgICkge1xuICAgICAgICAgICAgJChcIi53b28taW52b2ljZS1zYXZlLWNoYW5nZXMtc2VsZWN0b3JcIikuYWRkQ2xhc3MoXG4gICAgICAgICAgICAgICAgXCJ3b28taW52b2ljZS1zYXZlLWNoYW5nZXNcIlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICQoXCIud29vLWludm9pY2Utc2F2ZS1jaGFuZ2VzLXNlbGVjdG9yXCIpLnJlbW92ZUNsYXNzKFxuICAgICAgICAgICAgICAgIFwid29vLWludm9pY2Utc2F2ZS1jaGFuZ2VzXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgICQod2luZG93KS5zY3JvbGwoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICAkKHRoaXMpLnNjcm9sbFRvcCgpICsgJCh3aW5kb3cpLmhlaWdodCgpIDxcbiAgICAgICAgICAgICQoZG9jdW1lbnQpLmhlaWdodCgpIC0gMTUwXG4gICAgICAgICkge1xuICAgICAgICAgICAgJChcIi53b28taW52b2ljZS1iYW5uZXItc2lkZWJhclwiKS5hZGRDbGFzcyhcbiAgICAgICAgICAgICAgICBcIndvby1pbnZvaWNlLWJhbm5lci1zaWRlYmFyLXN0aWNreVwiXG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgJChcIi53b28taW52b2ljZS1iYW5uZXItc2lkZWJhclwiKS5yZW1vdmVDbGFzcyhcbiAgICAgICAgICAgICAgICBcIndvby1pbnZvaWNlLWJhbm5lci1zaWRlYmFyLXN0aWNreVwiXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICAkKHdpbmRvdykub24oXCJtb3VzZXdoZWVsXCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIC8vaWYoJCh3aW5kb3cpLnNjcm9sbFRvcCgpICsgJCh3aW5kb3cpLmhlaWdodCgpID4gJChkb2N1bWVudCkuaGVpZ2h0KCktMTAwKSAge1xuXG4gICAgICAgIC8vJChcIi53b28taW52b2ljZS1zYXZlLWNoYW5nZXMtc2VsZWN0b3JcIikucmVtb3ZlQ2xhc3MoXCJ3b28taW52b2ljZS1zYXZlLWNoYW5nZXNcIik7XG4gICAgICAgIC8vIH0gZWxzZSB7XG4gICAgICAgIC8vJChcIi53b28taW52b2ljZS1zYXZlLWNoYW5nZXMtc2VsZWN0b3JcIikuYWRkQ2xhc3MoXCJ3b28taW52b2ljZS1zYXZlLWNoYW5nZXNcIik7XG4gICAgICAgIC8vfVxuXG4gICAgICAgIHZhciBpbml0aWFsQ29udGVudCA9ICQoXCIud29vLWludm9pY2UtZGFzaGJvYXJkLWNvbnRlbnQgPiBsaTplcSgwKVwiKTtcbiAgICAgICAgJChcbiAgICAgICAgICAgIFwiLndvby1pbnZvaWNlLWRhc2hib2FyZC1zaWRlYmFyIC53b28taW52b2ljZS1zaWRlYmFyLW5hdmJhci1saWdodFwiXG4gICAgICAgICkuaGVpZ2h0KGluaXRpYWxDb250ZW50LnBhcmVudCgpLmhlaWdodCgpIC0gMjMpO1xuICAgIH0pO1xuXG4gICAgJCh3aW5kb3cpLmxvYWQoZnVuY3Rpb24gKCkge1xuICAgICAgICAkKFwiaW5wdXRbbmFtZT0nd2ZfdGFicyddXCIpLm9uKFwiY2hhbmdlXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBzZWxlY3RlZFRhYiA9ICQodGhpcykudmFsKCk7XG4gICAgICAgICAgICBzZXNzaW9uU3RvcmFnZS5zZXRJdGVtKFwiYWN0aXZlX3RhYlwiLCBzZWxlY3RlZFRhYik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHZhciBhY3RpdmVUYWIgPSBzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKFwiYWN0aXZlX3RhYlwiKTtcblxuICAgICAgICBpZiAoYWN0aXZlVGFiID09PSBcInNldHRpbmdzXCIpIHtcbiAgICAgICAgICAgICQoXCIjdGFiMVwiKS5hdHRyKFwiY2hlY2tlZFwiLCB0cnVlKTtcbiAgICAgICAgfSBlbHNlIGlmIChhY3RpdmVUYWIgPT09IFwic2VsbGVyJmJ1eWVyXCIpIHtcbiAgICAgICAgICAgICQoXCIjdGFiMlwiKS5hdHRyKFwiY2hlY2tlZFwiLCB0cnVlKTtcbiAgICAgICAgfSBlbHNlIGlmIChhY3RpdmVUYWIgPT09IFwibG9jYWxpemF0aW9uXCIpIHtcbiAgICAgICAgICAgICQoXCIjdGFiM1wiKS5hdHRyKFwiY2hlY2tlZFwiLCB0cnVlKTtcbiAgICAgICAgfSBlbHNlIGlmIChhY3RpdmVUYWIgPT09IFwiYnVsa19kb3dubG9hZFwiKSB7XG4gICAgICAgICAgICAkKFwiI3RhYjRcIikuYXR0cihcImNoZWNrZWRcIiwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gc2V0IGFjdGl2ZSBvZiBTZXR0aW5nIHRhYiBlbmRlZFxuXG4gICAgICAgIC8vQnVsayBpbnB1dCBkYXRlIHZhbGlkYXRpb25cbiAgICAgICAgdmFyIGZyb21fZGF0ZTtcbiAgICAgICAgdmFyIHRvX2RhdGU7XG4gICAgICAgIHZhciB0b0NoZWNrID0gMDtcbiAgICAgICAgdmFyIGZyb21DaGVjayA9IDA7XG5cbiAgICAgICAgJChcIiNEYXRlLWZyb21cIikub24oXCJjaGFuZ2VcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZnJvbV9kYXRlID0gRGF0ZS5wYXJzZSgkKHRoaXMpLnZhbCgpKTtcbiAgICAgICAgICAgIGZyb21DaGVjayA9IDE7XG4gICAgICAgICAgICBpZiAodG9DaGVjayAmJiBmcm9tQ2hlY2spIHtcbiAgICAgICAgICAgICAgICBpZiAodG9fZGF0ZSA8IGZyb21fZGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICBhbGVydChcIklucHV0IGRhdGUgc2hvdWxkIGJlIGxlc3MgdGhhbiBvciBlcXVhbCBEYXRlIFRvXCIpO1xuICAgICAgICAgICAgICAgICAgICAkKFwiI0RhdGUtZnJvbVwiKS52YWwoXCJcIik7XG4gICAgICAgICAgICAgICAgICAgIGZyb21DaGVjayA9IDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAkKFwiI0RhdGUtdG9cIikub24oXCJjaGFuZ2VcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdG9fZGF0ZSA9IERhdGUucGFyc2UoJCh0aGlzKS52YWwoKSk7XG4gICAgICAgICAgICB0b0NoZWNrID0gMTtcbiAgICAgICAgICAgIGlmICh0b0NoZWNrICYmIGZyb21DaGVjaykge1xuICAgICAgICAgICAgICAgIGlmICh0b19kYXRlIDwgZnJvbV9kYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIGFsZXJ0KFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJJbnB1dCBkYXRlIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgRGF0ZSBGcm9tXCJcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgJChcIiNEYXRlLXRvXCIpLnZhbChcIlwiKTtcbiAgICAgICAgICAgICAgICAgICAgdG9DaGVjayA9IDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAkKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciB0YWJzID0gJChcIi53b28taW52b2ljZS1zaWRlYmFyLW5hdmJhci1uYXYgPiBsaSA+IGFcIik7IC8vZ3JhYiB0YWJzXG4gICAgICAgICAgICB2YXIgY29udGVudHMgPSAkKFwiLndvby1pbnZvaWNlLWRhc2hib2FyZC1jb250ZW50ID4gbGlcIik7IC8vZ3JhYiBjb250ZW50c1xuXG4gICAgICAgICAgICBpZiAoc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbShcImFjdGl2ZVNpZGViYXJUYWJcIikgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHZhciBhY3RpdmVTaWRlYmFyVGFiID1cbiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvblN0b3JhZ2UuZ2V0SXRlbShcImFjdGl2ZVNpZGViYXJUYWJcIik7XG4gICAgICAgICAgICAgICAgY29udGVudHMuaGlkZSgpOyAvL2hpZGUgYWxsIGNvbnRlbnRzXG4gICAgICAgICAgICAgICAgdGFicy5yZW1vdmVDbGFzcyhcImFjdGl2ZVwiKTsgLy9yZW1vdmUgJ2N1cnJlbnQnIGNsYXNzZXNcbiAgICAgICAgICAgICAgICAkKGNvbnRlbnRzW2FjdGl2ZVNpZGViYXJUYWJdKS5zaG93KCk7IC8vc2hvdyB0YWIgY29udGVudCB0aGF0IG1hdGNoZXMgdGFiIHRpdGxlIGluZGV4XG4gICAgICAgICAgICAgICAgdmFyIGFjdGl2ZVRhYlNlbGVjdG9yID0gJChcbiAgICAgICAgICAgICAgICAgICAgXCIud29vLWludm9pY2Utc2lkZWJhci1uYXZiYXItbmF2ID4gbGk6ZXEoIFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZVNpZGViYXJUYWIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgXCIgKSA+IGFcIlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgYWN0aXZlVGFiU2VsZWN0b3IuYWRkQ2xhc3MoXCJhY3RpdmVcIik7XG4gICAgICAgICAgICAgICAgLyokKHRoaXMpLmFkZENsYXNzKCdhY3RpdmUnKTsgLy9hZGQgY3VycmVudCBjbGFzcyBvbiBjbGlja2VkIHRhYiB0aXRsZSovXG4gICAgICAgICAgICAgICAgJChcbiAgICAgICAgICAgICAgICAgICAgXCIud29vLWludm9pY2UtZGFzaGJvYXJkLXNpZGViYXIgLndvby1pbnZvaWNlLXNpZGViYXItbmF2YmFyLWxpZ2h0XCJcbiAgICAgICAgICAgICAgICApLmhlaWdodCgkKGNvbnRlbnRzW2FjdGl2ZVNpZGViYXJUYWJdKS5wYXJlbnQoKS5oZWlnaHQoKSAtIDIzKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFyIGluaXRpYWxDb250ZW50ID0gJChcbiAgICAgICAgICAgICAgICAgICAgXCIud29vLWludm9pY2UtZGFzaGJvYXJkLWNvbnRlbnQgPiBsaTplcSgwKVwiXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBpbml0aWFsQ29udGVudC5jc3MoXCJkaXNwbGF5XCIsIFwiYmxvY2tcIik7IC8vc2hvdyB0YWIgY29udGVudCB0aGF0IG1hdGNoZXMgdGFiIHRpdGxlIGluZGV4XG4gICAgICAgICAgICAgICAgdmFyIGFjdGl2ZVRhYlNlbGVjdG9yID0gJChcbiAgICAgICAgICAgICAgICAgICAgXCIud29vLWludm9pY2Utc2lkZWJhci1uYXZiYXItbmF2ID4gbGk6ZXEoMCkgPiBhXCJcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGFjdGl2ZVRhYlNlbGVjdG9yLmFkZENsYXNzKFwiYWN0aXZlXCIpO1xuICAgICAgICAgICAgICAgICQoXG4gICAgICAgICAgICAgICAgICAgIFwiLndvby1pbnZvaWNlLWRhc2hib2FyZC1zaWRlYmFyIC53b28taW52b2ljZS1zaWRlYmFyLW5hdmJhci1saWdodFwiXG4gICAgICAgICAgICAgICAgKS5oZWlnaHQoaW5pdGlhbENvbnRlbnQucGFyZW50KCkuaGVpZ2h0KCkgLSAyMyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRhYnMuYmluZChcImNsaWNrXCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIHZhciB0YWJJbmRleCA9ICQodGhpcykucGFyZW50KCkucHJldkFsbCgpLmxlbmd0aDtcbiAgICAgICAgICAgICAgICBjb250ZW50cy5oaWRlKCk7IC8vaGlkZSBhbGwgY29udGVudHNcbiAgICAgICAgICAgICAgICB0YWJzLnJlbW92ZUNsYXNzKFwiYWN0aXZlXCIpOyAvL3JlbW92ZSAnY3VycmVudCcgY2xhc3Nlc1xuICAgICAgICAgICAgICAgICQoY29udGVudHNbdGFiSW5kZXhdKS5zaG93KCk7IC8vc2hvdyB0YWIgY29udGVudCB0aGF0IG1hdGNoZXMgdGFiIHRpdGxlIGluZGV4XG4gICAgICAgICAgICAgICAgJCh0aGlzKS5hZGRDbGFzcyhcImFjdGl2ZVwiKTsgLy9hZGQgY3VycmVudCBjbGFzcyBvbiBjbGlja2VkIHRhYiB0aXRsZVxuICAgICAgICAgICAgICAgIHZhciBzZWxlY3RlZFNpZGViYXJUYWIgPSAkKHRoaXMpLnBhcmVudCgpLnByZXZBbGwoKS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShcImFjdGl2ZVNpZGViYXJUYWJcIiwgc2VsZWN0ZWRTaWRlYmFyVGFiKTtcbiAgICAgICAgICAgICAgICAkKFxuICAgICAgICAgICAgICAgICAgICBcIi53b28taW52b2ljZS1kYXNoYm9hcmQtc2lkZWJhciAud29vLWludm9pY2Utc2lkZWJhci1uYXZiYXItbGlnaHRcIlxuICAgICAgICAgICAgICAgICkuaGVpZ2h0KGNvbnRlbnRzLnBhcmVudCgpLmhlaWdodCgpIC0gMjMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIi53b28taW52b2ljZS10ZW1wbGF0ZS1zZWxlY3Rpb25cIiwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBsZXQgdGVtcGxhdGUgPSAkKHRoaXMpLmRhdGEoXCJ0ZW1wbGF0ZVwiKTtcbiAgICAgICAgJChcIiN3aW52b2ljZU1vZGFsVGVtcGxhdGVzXCIpLm1vZGFsKFwiaGlkZVwiKTtcbiAgICAgICAgJChcImJvZHlcIikucmVtb3ZlQ2xhc3MoZnVuY3Rpb24gKGluZGV4LCBjbGFzc05hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiAoY2xhc3NOYW1lLm1hdGNoKC9cXFMrLW1vZGFsLW9wZW4oXnxcXHMpL2cpIHx8IFtdKS5qb2luKFwiIFwiKTtcbiAgICAgICAgfSk7XG4gICAgICAgICQoJ2RpdltjbGFzcyo9XCItbW9kYWwtYmFja2Ryb3BcIl0nKS5yZW1vdmUoKTtcbiAgICAgICAgJCh0aGlzKS5maW5kKFwiaW1nXCIpLnJlbW92ZUNsYXNzKFwid29vLWludm9pY2UtdGVtcGxhdGVcIik7XG4gICAgICAgICQodGhpcykuZmluZChcImltZ1wiKS5yZW1vdmVDbGFzcyhcIndvby1pbnZvaWNlLWRpc2FibGUtdGVtcGxhdGVcIik7XG4gICAgICAgICQodGhpcykuZmluZChcImltZ1wiKS5hZGRDbGFzcyhcIndvby1pbnZvaWNlLXNsZWN0ZWQtdGVtcGxhdGVcIik7XG5cbiAgICAgICAgJChcIi53b28taW52b2ljZS1lbGVtZW50LWRpc2FibGVcIilcbiAgICAgICAgICAgIC5maW5kKFwiaW1nXCIpXG4gICAgICAgICAgICAuYWRkQ2xhc3MoXCJ3b28taW52b2ljZS10ZW1wbGF0ZVwiKTtcbiAgICAgICAgJChcIi53b28taW52b2ljZS1lbGVtZW50LWRpc2FibGVcIilcbiAgICAgICAgICAgIC5maW5kKFwiaW1nXCIpXG4gICAgICAgICAgICAucmVtb3ZlQ2xhc3MoXCJ3b28taW52b2ljZS1kaXNhYmxlLXRlbXBsYXRlXCIpO1xuICAgICAgICAkKFwiLndvby1pbnZvaWNlLWVsZW1lbnQtZGlzYWJsZVwiKS5jc3MoXCJ6LWluZGV4XCIsIFwiMzMzM1wiKTtcbiAgICAgICAgJChcIi53b28taW52b2ljZS1lbGVtZW50LWRpc2FibGVcIilcbiAgICAgICAgICAgIC5zaWJsaW5ncyhcImRpdlwiKVxuICAgICAgICAgICAgLmNzcyhcInotaW5kZXhcIiwgXCIxMTExXCIpO1xuICAgICAgICAkKFwiLndvby1pbnZvaWNlLWVsZW1lbnQtZGlzYWJsZVwiKS5zaWJsaW5ncyhcImFcIikuY3NzKFwiei1pbmRleFwiLCBcIjIyMjJcIik7XG5cbiAgICAgICAgJCh0aGlzKVxuICAgICAgICAgICAgLnBhcmVudCgpXG4gICAgICAgICAgICAuc2libGluZ3MoKVxuICAgICAgICAgICAgLmZpbmQoXCJpbWdcIilcbiAgICAgICAgICAgIC5yZW1vdmVDbGFzcyhcIndvby1pbnZvaWNlLXNsZWN0ZWQtdGVtcGxhdGVcIilcbiAgICAgICAgICAgIC5hZGRDbGFzcyhcIndvby1pbnZvaWNlLXRlbXBsYXRlXCIpO1xuICAgICAgICAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsOiB3b29faW52b2ljZV9hamF4X29ial8yLndvb19pbnZvaWNlX2FqYXhfdXJsXzIsXG4gICAgICAgICAgICB0eXBlOiBcInBvc3RcIixcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICBfYWpheF9ub25jZTogd29vX2ludm9pY2VfYWpheF9vYmpfMi5ub25jZSxcbiAgICAgICAgICAgICAgICBhY3Rpb246IFwid3BpZndfc2F2ZV9wZGZfdGVtcGxhdGVcIixcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZTogdGVtcGxhdGUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgJChcIi53b28taW52b2ljZS10ZW1wbGF0ZS1wcmV2aWV3XCIpLmF0dHIoXG4gICAgICAgICAgICAgICAgICAgIFwic3JjXCIsXG4gICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmRhdGEubG9jYXRpb24gK1xuICAgICAgICAgICAgICAgICAgICAgICAgXCIvXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UuZGF0YS50ZW1wbGF0ZV9uYW1lICtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiLnBuZ1wiXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAkKFwiLmludm9pY2VfdGVtcGxhdGVfcHJlaXZpZXdfYnRuXCIpLmF0dHIoXG4gICAgICAgICAgICAgICAgICAgIFwiaHJlZlwiLFxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5kYXRhLmxvY2F0aW9uICtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiL1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmRhdGEudGVtcGxhdGVfbmFtZSArXG4gICAgICAgICAgICAgICAgICAgICAgICBcIi5wbmdcIlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgICQoZG9jdW1lbnQpLm9uKFwiY2xpY2tcIiwgXCIud29vLWludm9pY2UtZWxlbWVudC1kaXNhYmxlXCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgJCh0aGlzKS5jaGlsZHJlbihcImltZ1wiKS5yZW1vdmVDbGFzcyhcIndvby1pbnZvaWNlLXRlbXBsYXRlXCIpO1xuICAgICAgICAkKHRoaXMpLmNoaWxkcmVuKFwiaW1nXCIpLmFkZENsYXNzKFwid29vLWludm9pY2UtZGlzYWJsZS10ZW1wbGF0ZVwiKTtcbiAgICAgICAgJCh0aGlzKS5jc3MoXCJ6LWluZGV4XCIsIFwiMTExMVwiKTtcbiAgICAgICAgJCh0aGlzKS5zaWJsaW5ncyhcImRpdlwiKS5jc3MoXCJ6LWluZGV4XCIsIFwiMjIyMlwiKTtcbiAgICAgICAgJCh0aGlzKS5zaWJsaW5ncyhcImFcIikuY3NzKFwiei1pbmRleFwiLCBcIjMzMzNcIik7XG4gICAgfSk7XG5cbiAgICAvL0RhdGVwaWNrZXJcbiAgICBmbGF0cGlja3IoXCIud29vLWludm9pY2UtZGF0ZXBpY2tlclwiLCB7XG4gICAgICAgIGRhdGVGb3JtYXQ6IFwibi9qL1lcIixcbiAgICAgICAgYWxsb3dJbnB1dDogdHJ1ZSxcbiAgICAgICAgb25PcGVuOiBmdW5jdGlvbiAoc2VsZWN0ZWREYXRlcywgZGF0ZVN0ciwgaW5zdGFuY2UpIHtcbiAgICAgICAgICAgIGluc3RhbmNlLnNldERhdGUoaW5zdGFuY2UuaW5wdXQudmFsdWUsIGZhbHNlKTtcbiAgICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICAvLyBEaXNwbGF5IG9yZGVyIG1ldGEgZm9yIGludm9pY2UuXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIHZhciBtZXRhT3JkZXJIVE1MID0gJChcIi53b29faW52b2ljZV9vcmRlcl9tZXRhX2h0bWxcIikuZmlyc3QoKS5jbG9uZSgpO1xuXG4gICAgLy8gY2xvbmUgYSBuZXcgaW5wdXQgZmllbGQgZm9yIHNldHRpbmcgb3JkZXIgbWF0ZS5cbiAgICAkKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiLndvby1pbnZvaWNlLWFkZC1vcmRlci1tZXRhXCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgICAkKFwiLndvb19pbnZvaWNlX29yZGVyX21ldGEgPiAud29vX2ludm9pY2Vfb3JkZXJfbWV0YV9odG1sXCIpLmxlbmd0aCA+XG4gICAgICAgICAgICAwXG4gICAgICAgICkge1xuICAgICAgICAgICAgZGlzcGxheV9jaGFsbGFuX3Byb19ub3RpY2VfbW9kYWwoXG4gICAgICAgICAgICAgICAgXCJZb3UgY2FuIGFkZCBtb3JlIHRoYW4gMSBvcmRlciBtZXRhIGluXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAgICAgLnNpYmxpbmdzKFwiLndvb19pbnZvaWNlX29yZGVyX21ldGFcIilcbiAgICAgICAgICAgICAgICAuYXBwZW5kKG1ldGFPcmRlckhUTUwuY2xvbmUoKSk7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIGRlbGV0ZSBvcmRlciBtZXRhLlxuICAgICQoZG9jdW1lbnQpLm9uKFwiY2xpY2tcIiwgXCIud29vLWludm9pY2UtZGVsZXRlLW9yZGVyLW1ldGFcIiwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAkKHRoaXMpLnBhcmVudCgpLnJlbW92ZSgpO1xuICAgICAgICBpZiAoJChcIi53b29faW52b2ljZV9vcmRlcl9tZXRhX2h0bWxcIikubGVuZ3RoID09PSBcIjFcIikge1xuICAgICAgICAgICAgLy8kKCcud29vX2ludm9pY2UtYWRkLW9yZGVyLW1ldGEgLmRhc2hpY29ucy1wbHVzLWFsdCcpLmNzcyhcIm1hcmdpbi1sZWZ0XCIsXCIwcHhcIik7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vICBFbmQgOiAgZGlzcGxheSBvcmRlciBtZXRhICBmb3IgaW52b2ljZS5cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vIERpc3BsYXkgb3JkZXIgaXRlbSBtZXRhIGZvciBpbnZvaWNlLlxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICB2YXIgb3JkZXJJdGVtTWV0YSA9ICQoXCIud29vX2ludm9pY2Vfb3JkZXJfaXRlbV9tZXRhX2h0bWxcIikuZmlyc3QoKS5jbG9uZSgpO1xuICAgIC8vIGNsb25lIGEgbmV3IGlucHV0IGZpZWxkIGZvciBzZXR0aW5nIG9yZGVyIG1hdGUuXG4gICAgJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIi53b28taW52b2ljZS1hZGQtb3JkZXItaXRlbS1tZXRhXCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgJChcbiAgICAgICAgICAgICAgICBcIi53b29faW52b2ljZV9vcmRlcl9pdGVtX21ldGEgPiAud29vX2ludm9pY2Vfb3JkZXJfaXRlbV9tZXRhX2h0bWxcIlxuICAgICAgICAgICAgKS5sZW5ndGggPiAwXG4gICAgICAgICkge1xuICAgICAgICAgICAgZGlzcGxheV9jaGFsbGFuX3Byb19ub3RpY2VfbW9kYWwoXG4gICAgICAgICAgICAgICAgXCJZb3UgY2FuIGFkZCBtb3JlIHRoYW4gMSBvcmRlciBpdGVtIG1ldGEgaW5cIlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICQodGhpcylcbiAgICAgICAgICAgICAgICAuc2libGluZ3MoXCIud29vX2ludm9pY2Vfb3JkZXJfaXRlbV9tZXRhXCIpXG4gICAgICAgICAgICAgICAgLmFwcGVuZChvcmRlckl0ZW1NZXRhLmNsb25lKCkpO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgLy8gZGVsZXRlIG9yZGVyIG1ldGEuXG4gICAgJChkb2N1bWVudCkub24oXG4gICAgICAgIFwiY2xpY2tcIixcbiAgICAgICAgXCIud29vLWludm9pY2UtZGVsZXRlLW9yZGVyLWl0ZW0tbWV0YVwiLFxuICAgICAgICBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgJCh0aGlzKS5wYXJlbnQoKS5yZW1vdmUoKTtcbiAgICAgICAgICAgIGlmICgkKFwiLndvb19pbnZvaWNlX29yZGVyX2l0ZW1fbWV0YV9odG1sXCIpLmxlbmd0aCA9PT0gXCIxXCIpIHtcbiAgICAgICAgICAgICAgICAvLyQoJy53b29faW52b2ljZS1hZGQtb3JkZXItbWV0YSAuZGFzaGljb25zLXBsdXMtYWx0JykuY3NzKFwibWFyZ2luLWxlZnRcIixcIjBweFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICk7XG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vICBFbmQgOiAgZGlzcGxheSBvcmRlciBpdGVtIG1ldGEgZm9yIGludm9pY2UuXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vIERpc3BsYXkgcHJvZHVjdCBtZXRhIGZvciBpbnZvaWNlLlxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICB2YXIgcHJvZHVjdE1ldGEgPSAkKFwiLndvb19pbnZvaWNlX3Byb2R1Y3RfbWV0YV9odG1sXCIpLmZpcnN0KCkuY2xvbmUoKTtcblxuICAgIC8vIGNsb25lIGEgbmV3IGlucHV0IGZpZWxkIGZvciBzZXR0aW5nIG9yZGVyIG1hdGUuXG4gICAgJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIi53b28taW52b2ljZS1wcm9kdWN0LWFkZC1tZXRhXCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgJChcIi53b29faW52b2ljZV9wcm9kdWN0X21ldGEgPiAud29vX2ludm9pY2VfcHJvZHVjdF9tZXRhX2h0bWxcIilcbiAgICAgICAgICAgICAgICAubGVuZ3RoID4gMFxuICAgICAgICApIHtcbiAgICAgICAgICAgIGRpc3BsYXlfY2hhbGxhbl9wcm9fbm90aWNlX21vZGFsKFxuICAgICAgICAgICAgICAgIFwiWW91IGNhbiBhZGQgbW9yZSB0aGFuIDEgcHJvZHVjdCBtZXRhIGluXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAgICAgLnNpYmxpbmdzKFwiLndvb19pbnZvaWNlX3Byb2R1Y3RfbWV0YVwiKVxuICAgICAgICAgICAgICAgIC5hcHBlbmQocHJvZHVjdE1ldGEuY2xvbmUoKSk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICAvLyBkZWxldGUgb3JkZXIgbWV0YS5cbiAgICAkKGRvY3VtZW50KS5vbihcImNsaWNrXCIsIFwiLndvby1pbnZvaWNlLWRlbGV0ZS1wcm9kdWN0LW1ldGFcIiwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAkKHRoaXMpLnBhcmVudCgpLnJlbW92ZSgpO1xuICAgICAgICBpZiAoJChcIi53b29faW52b2ljZV9wcm9kdWN0X21ldGFfaHRtbFwiKS5sZW5ndGggPT09IFwiMVwiKSB7XG4gICAgICAgICAgICAvLyQoJy53b29faW52b2ljZS1hZGQtb3JkZXItbWV0YSAuZGFzaGljb25zLXBsdXMtYWx0JykuY3NzKFwibWFyZ2luLWxlZnRcIixcIjBweFwiKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgLy8gIEVuZCA6ICBkaXNwbGF5IG9yZGVyIG1ldGEgIGZvciBpbnZvaWNlLlxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vIEFsZXJ0IGZvciBidWxrIGNzdiBmaWxlIGFuZCBzaGlwcGluZyBsYWJlbC5cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgJChkb2N1bWVudCkub24oXCJjbGlja1wiLCBcIiN3cGlmd19zdWJtaXRfYnVsa19kb3dubG9hZFwiLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAucGFyZW50KClcbiAgICAgICAgICAgIC5wYXJlbnQoKVxuICAgICAgICAgICAgLnNlcmlhbGl6ZUFycmF5KClcbiAgICAgICAgICAgIC5tYXAoKGZpZWxkKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICBmaWVsZC5uYW1lID09IFwid3BpZndfYnVsa190eXBlXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgZmllbGQudmFsdWUgPT0gXCJXUElGV19DU1ZcIlxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIGRpc3BsYXlfY2hhbGxhbl9wcm9fbm90aWNlX21vZGFsKFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJUbyBkb3dubG9hZCBidWxrIGNzdiBmaWxlIHlvdSBuZWVkXCJcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICAgICAgICBmaWVsZC5uYW1lID09IFwid3BpZndfYnVsa190eXBlXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgZmllbGQudmFsdWUgPT0gXCJXUElGV19TSElQUElOR19MQUJFTFwiXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgZGlzcGxheV9jaGFsbGFuX3Byb19ub3RpY2VfbW9kYWwoXG4gICAgICAgICAgICAgICAgICAgICAgICBcIlRvIGRvd25sb2FkIGJ1bGsgc2hpcHBpbmcgbGFiZWwgeW91IG5lZWRcIlxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgIH0pO1xuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICAvLyAgRW5kIDogIEFsZXJ0IGZvciBidWxrIGNzdiBmaWxlIGFuZCBzaGlwcGluZyBsYWJlbC5cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vICBTdGFydCA6ICBQYXltZW50IG1ldGhvZCBzZWxlY3Qgb3B0aW9uIG5vdGljZS5cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIGZ1bmN0aW9uIGRpc3BsYXlfY2hhbGxhbl9wcm9fbm90aWNlX2Zvcl9zZWxlY3Rfb3B0aW9uKFxuICAgICAgICBzZWxlY3Rvcl90eXBlLFxuICAgICAgICBzZWxlY3RvclxuICAgICkge1xuICAgICAgICAkKGRvY3VtZW50KS5vbihcImNoYW5nZVwiLCBgJHtzZWxlY3Rvcl90eXBlfSR7c2VsZWN0b3J9YCwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGlmICgkKHRoaXMpLnZhbCgpICE9PSBcImFsbFwiKSB7XG4gICAgICAgICAgICAgICAgJCh0aGlzKVxuICAgICAgICAgICAgICAgICAgICAucGFyZW50KClcbiAgICAgICAgICAgICAgICAgICAgLmFwcGVuZChcbiAgICAgICAgICAgICAgICAgICAgICAgIGA8cCAgY2xhc3M9XCJ3b29faW52b2ljZV9tZXRhX2h0bWwgd29vX2ludm9pY2VfY29sXzMgd29vX2ludm9pY2VfcHJvX25vdGljZVwiPk5vdGljZTogQ2hhbGxhbiBQcm8gb25seS48L3A+YFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAkKHRoaXMpLnBhcmVudCgpLmNoaWxkcmVuKFwicFwiKS5oaWRlKFwic2xvd1wiKTtcbiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAkKHRoaXMpLnBhcmVudCgpLmNoaWxkcmVuKFwicFwiKS5yZW1vdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgICAgICAgICB9LCAyMDAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3BsYXlfY2hhbGxhbl9wcm9fbm90aWNlX2Zvcl9zZWxlY3Rfb3B0aW9uKFxuICAgICAgICBcIiNcIixcbiAgICAgICAgXCJ3cGlmd19idWxrX2Rvd25sb2FkX29yZGVyX3BheW1lbnRfbWV0aG9kXCJcbiAgICApO1xuICAgIGRpc3BsYXlfY2hhbGxhbl9wcm9fbm90aWNlX2Zvcl9zZWxlY3Rfb3B0aW9uKFxuICAgICAgICBcIiNcIixcbiAgICAgICAgXCJ3cGlmd19idWxrX2Rvd25sb2FkX29yZGVyX3N0YXR1c1wiXG4gICAgKTtcblxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgIC8vICBFbmQgOiAgUGF5bWVudCBtZXRob2Qgc2VsZWN0IG9wdGlvbiBub3RpY2UuXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgJChcIi53cGlmd19hdHRyXCIpLnNlbGVjdGl6ZSh7XG4gICAgICAgIHBsdWdpbnM6IFtcInJlbW92ZV9idXR0b25cIl0sXG4gICAgICAgIHJlbmRlcjoge1xuICAgICAgICAgICAgaXRlbTogZnVuY3Rpb24gKGRhdGEsIGVzY2FwZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwiaXRlbSB3cGlmd19zZWxlY3RvclwiPicgK1xuICAgICAgICAgICAgICAgICAgICBlc2NhcGUoZGF0YS50ZXh0KSArXG4gICAgICAgICAgICAgICAgICAgIFwiPC9kaXY+XCJcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgLy8gRGlzcGxheSBjc3YgZmlsZVxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgJChkb2N1bWVudCkub24oXCJjaGFuZ2VcIiwgXCIjd3BpZndfYnVsa190eXBlXCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgaWYgKCQodGhpcykudmFsKCkgPT0gXCJXUElGV19DU1ZcIikge1xuICAgICAgICAgICAgJChcIi53b28taW52b2ljZS1hZGQtY3N2LWZpZWxkc1wiKS5zaG93KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAkKFwiLndvby1pbnZvaWNlLWFkZC1jc3YtZmllbGRzXCIpLmhpZGUoKTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICAvLyBTaG93IFByb2R1Y3QgQ29sdW1uXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICAkKCcud3BpZndfaGVhZGVyJykuc2VsZWN0aXplKFxuICAgICAgICB7XG4gICAgICAgICAgICBwbHVnaW5zOiBbJ3JlbW92ZV9idXR0b24nXSxcbiAgICAgICAgICAgIG1heEl0ZW1zOiA0LFxuICAgICAgICAgICAgcmVuZGVyOiB7XG4gICAgICAgICAgICAgICAgaXRlbTogZnVuY3Rpb24gKGRhdGEsIGVzY2FwZSkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgc2VsZWN0SXRlbSA9IGRhdGEudmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIGxldCBmcmVlSGVhZGVyID0gWyAncHJpY2UnLCd0b3RhbCcsJ3F1YW50aXR5J107XG4gICAgICAgICAgICAgICAgICAgIGxldCBjb2x1bW5OYW1lID0gZGF0YS50ZXh0LnNsaWNlKDAsIC01KTtcbiAgICAgICAgICAgICAgICAgICAgaWYoZnJlZUhlYWRlci5pbmNsdWRlcyhzZWxlY3RJdGVtKSl7XG4gICAgICAgICAgICAgICAgICAgICAgICAkKCcud29vX2ludm9pY2VfcHJvX25vdGljZScpLmhpZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgfWVsc2V7XG4gICAgICAgICAgICAgICAgICAgICAgICAkKCcud29vX2ludm9pY2VfcHJvX25vdGljZV9uYW1lJykudGV4dChjb2x1bW5OYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXlfY2hhbGxhbl9wcm9fbm90aWNlX21vZGFsKGBUbyBhZGQgPHNwYW4gc3R5bGU9XCJmb250LXdlaWdodDogYm9sZDtcIj4ke2NvbHVtbk5hbWV9PC9zcGFuPiBjb2x1bW4geW91IGhhdmUgdG8gdXBncmFkZWApO1xuICAgICAgICAgICAgICAgICAgICAgICAgJCgnLndvb19pbnZvaWNlX3Byb19ub3RpY2UnKS5zaG93KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gJzxkaXYgY2xhc3M9XCJpdGVtIHdwaWZ3X3NlbGVjdG9yXCIgZGlzYWJsZWQ9XCJkaXNhYmxlXCI+JysgZXNjYXBlKGRhdGEudGV4dCkgKyAnPC9kaXY+JztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb25Jbml0aWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIHNlbGVjdGl6ZSA9IHRoaXM7XG4gICAgICAgICAgICAgICAgJC5hamF4KFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cmw6IHdvb19pbnZvaWNlX2FqYXhfb2JqXzIud29vX2ludm9pY2VfYWpheF91cmxfMixcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdwb3N0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfYWpheF9ub25jZTogd29vX2ludm9pY2VfYWpheF9vYmpfMi5ub25jZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb246IFwid3BpZndfZ2V0X3Byb2R1Y3RfY29sdW1uX3Nob3dcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzOiBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2VsZWN0ZWRfaXRlbXMgPSBbXS5zbGljZS5jYWxsKHJlc3BvbnNlLmRhdGEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGl6ZS5zZXRWYWx1ZShzZWxlY3RlZF9pdGVtcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgKTtcblxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgLy8gU2F2ZSBQcm9kdWN0IENvbHVtbi5cbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgICQoZG9jdW1lbnQpLm9uKFxuICAgICAgICAnY2hhbmdlJywgJy53cGlmd19oZWFkZXInLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgJC5hamF4KFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgdXJsOiB3b29faW52b2ljZV9hamF4X29ial8yLndvb19pbnZvaWNlX2FqYXhfdXJsXzIsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICdwb3N0JyxcbiAgICAgICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICAgICAgX2FqYXhfbm9uY2U6IHdvb19pbnZvaWNlX2FqYXhfb2JqXzIubm9uY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb246IFwid3BpZndfc2VsZWN0X3Byb2R1Y3RfY29sdW1uXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW5zOiAkKFwiLndwaWZ3X2hlYWRlclwiKS52YWwoKVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzOiBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICApO1xuXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICAvLyBTdGFydCA6IFNob3cgbW9kYWwgYW5kIGNsb3NlIG1vZGFsLlxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgLy8gbW9kYWwgc2hvdyBmdW5jdGlvblxuICAgIGZ1bmN0aW9uIGRpc3BsYXlfY2hhbGxhbl9wcm9fbm90aWNlX21vZGFsKGNvbnRlbnQpIHtcbiAgICAgICAgJChcIi53b28taW52b2ljZS1tb2RhbFwiKS5zaG93KCk7XG4gICAgICAgICQoXCIud29vLWludm9pY2UtbW9kYWwtYm9keSBwXCIpLmh0bWwoXG4gICAgICAgICAgICBgJHtjb250ZW50fSAgPGEgdHlwZT0nYnV0dG9uJyBocmVmPSdodHRwczovL3dlYmFwcGljay5jb20vcGx1Z2luL3dvb2NvbW1lcmNlLXBkZi1pbnZvaWNlLXBhY2tpbmctc2xpcHMvP3V0bV9zb3VyY2U9Y3VzdG9tZXJfc2l0ZSZ1dG1fbWVkaXVtPWZyZWVfdnNfcHJvJnV0bV9jYW1wYWlnbj13b29faW52b2ljZV9mcmVlJyB0YXJnZXQ9J19ibGFuayc+Q2hhbGxhbiBQcm88L2E+YFxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8vIENsb3NlIG1vZGFsLlxuICAgICQoXCIud29vLWludm9pY2UtbW9kYWwgLndvby1pbnZvaWNlLW1vZGFsLWNsb3NlXCIpLm9uKFwiY2xpY2tcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAkKFwiLndvby1pbnZvaWNlLW1vZGFsXCIpLmhpZGUoKTtcbiAgICB9KTtcblxuICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgLy8gRW5kIDogU2hvdyBtb2RhbCBhbmQgY2xvc2UgbW9kYWwuXG4gICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuICAgICQod2luZG93KS5sb2FkKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgJChcIiN3cGZvb3RlciAjZm9vdGVyLXRoYW5reW91XCIpLmh0bWwoXG4gICAgICAgICAgICBcIklmIHlvdSBsaWtlIDxzdHJvbmc+PGlucz5DaGFsbGFuPC9pbnM+PC9zdHJvbmc+IHBsZWFzZSBsZWF2ZSB1cyBhIDxhIHRhcmdldD0nX2JsYW5rJyBzdHlsZT0nY29sb3I6I2Y5YjkxOCcgaHJlZj0naHR0cHM6Ly93b3JkcHJlc3Mub3JnL3N1cHBvcnQvdmlldy9wbHVnaW4tcmV2aWV3cy93ZWJhcHBpY2stcGRmLWludm9pY2UtZm9yLXdvb2NvbW1lcmNlP3JhdGU9NSNwb3N0Zm9ybSc+4piF4piF4piF4piF4piFPC9hPiByYXRpbmcuIEEgaHVnZSB0aGFuayB5b3UgaW4gYWR2YW5jZSFcIlxuICAgICAgICApO1xuICAgIH0pO1xufSkoalF1ZXJ5KTtcbiJdfQ==
  • webappick-pdf-invoice-for-woocommerce/trunk/admin/partials/tabs/bulk-download-tab.php

    r3463094 r3743261  
    247247                            <p class="woo-invoice-banner-title">Upgrade to Challan Pro Today!</p>
    248248                            <button
    249                                     onclick="window.open('https://webappick.com/discount-deal/?utm_source=10YC-fix&utm_medium=free-to-pro&utm_campaign=10Y-25&utm_id=1')"
     249                                    onclick="window.open('https://webappick.com/plugin/woocommerce-pdf-invoice-packing-slips/?utm_source=customer_site&utm_medium=free_vs_pro&utm_campaign=woo_invoice_free', '_blank')"
    250250                                    class="woo-invoice-banner-btn"
    251251                            >
  • webappick-pdf-invoice-for-woocommerce/trunk/admin/partials/tabs/free-vs-pro-tab.php

    r3463094 r3743261  
    218218                            <p class="woo-invoice-banner-title">Upgrade to Challan Pro Today!</p>
    219219                            <button
    220                                     onclick="window.open('https://webappick.com/discount-deal/?utm_source=10YC-fix&utm_medium=free-to-pro&utm_campaign=10Y-25&utm_id=1')"
     220                                    onclick="window.open('https://webappick.com/plugin/woocommerce-pdf-invoice-packing-slips/?utm_source=customer_site&utm_medium=free_vs_pro&utm_campaign=woo_invoice_free', '_blank')"
    221221                                    class="woo-invoice-banner-btn"
    222222                            >
  • webappick-pdf-invoice-for-woocommerce/trunk/admin/partials/tabs/seller-buyer-tab.php

    r3463094 r3743261  
    118118                            <p class="woo-invoice-banner-title">Upgrade to Challan Pro Today!</p>
    119119                            <button
    120                                     onclick="window.open('https://webappick.com/discount-deal/?utm_source=10YC-fix&utm_medium=free-to-pro&utm_campaign=10Y-25&utm_id=1')"
     120                                    onclick="window.open('https://webappick.com/plugin/woocommerce-pdf-invoice-packing-slips/?utm_source=customer_site&utm_medium=free_vs_pro&utm_campaign=woo_invoice_free', '_blank')"
    121121                                    class="woo-invoice-banner-btn"
    122122                            >
  • webappick-pdf-invoice-for-woocommerce/trunk/admin/partials/tabs/settings-tab.php

    r3463094 r3743261  
    779779                            <p class="woo-invoice-banner-title">Upgrade to Challan Pro Today!</p>
    780780                            <button
    781                                     onclick="window.open('https://webappick.com/discount-deal/?utm_source=10YC-fix&utm_medium=free-to-pro&utm_campaign=10Y-25&utm_id=1')"
     781                                    onclick="window.open('https://webappick.com/plugin/woocommerce-pdf-invoice-packing-slips/?utm_source=customer_site&utm_medium=free_vs_pro&utm_campaign=woo_invoice_free', '_blank')"
    782782                                    class="woo-invoice-banner-btn"
    783783                            >
    … …  
    809809                    </div>
    810810                <?php endif; ?>
     811                <?php
     812                if ( ! function_exists( 'get_last_order_id' ) ) {
     813                    /**
     814                     * Latest order in the store, any status.
     815                     *
     816                     * @return int
     817                     */
     818                    function get_last_order_id() {
     819                        $cache_key     = 'woo_last_store_order_id';
     820                        $last_order_id = wp_cache_get( $cache_key );
     821
     822                        if ( false === $last_order_id ) {
     823                            $orders        = wc_get_orders(
     824                                array(
     825                                    'limit'   => 1,
     826                                    'orderby' => 'date',
     827                                    'order'   => 'DESC',
     828                                    'status'  => 'any',
     829                                    'return'  => 'ids',
     830                                )
     831                            );
     832                            $last_order_id = ! empty( $orders ) ? $orders[0] : 0;
     833
     834                            if ( $last_order_id ) {
     835                                wp_cache_set( $cache_key, $last_order_id, '', 60 );
     836                            }
     837                        }
     838
     839                        return $last_order_id;
     840                    }
     841                }
     842
     843                $order_id      = get_last_order_id();
     844                $preview_order = absint( $order_id ) ? wc_get_order( absint( $order_id ) ) : false;
     845                if ( $preview_order ) :
     846                    ?>
    811847                <div class="woo-invoice-card">
    812848                    <div class="woo-invoice-card-header">
    … …  
    816852                        <?php
    817853                        $template_name = get_option('wpifw_templateid');
    818 
    819                         // Function to get the last order ID
    820                         function get_last_order_id() {
    821                             $cache_key = 'woo_last_order_id';
    822                             $last_order_id = wp_cache_get( $cache_key );
    823 
    824                             if ( false === $last_order_id ) {
    825                                 $statuses = wc_get_is_paid_statuses(); // safer than all possible statuses
    826 
    827                                 $args = array(
    828                                     'limit'        => 1,
    829                                     'orderby'      => 'date',
    830                                     'order'        => 'DESC',
    831                                     'status'       => $statuses,
    832                                     'return'       => 'ids',
    833                                 );
    834 
    835                                 $orders = wc_get_orders( $args );
    836                                 $last_order_id = ! empty( $orders ) ? $orders[0] : 0;
    837 
    838                                 wp_cache_set( $cache_key, $last_order_id, '', 60 ); // cache for 60 seconds
    839                             }
    840 
    841                             return $last_order_id;
    842                         }
    843 
    844                         $order_id = get_last_order_id();
    845854                        $preview_url = esc_url(wp_nonce_url(admin_url('admin-ajax.php?action=wpifw_generate_invoice&order_id=' . $order_id) .'#toolbar=0', 'woo_invoice_ajax_nonce'));
    846855                        $template_image_url = esc_attr(CHALLAN_FREE_PLUGIN_URL . 'admin/images/templates/' . $template_name . '.png');
    847856                        ?>
    848857
    849                         <?php if ('' != $order_id) { ?>
     858                        <?php if ( $preview_order ) { ?>
    850859                            <div class="_winvoice-iframe-container">
    851                                 <iframe class="_winvoice-iframe-responsive woo-invoice-template-preview" src="<?php echo esc_url($preview_url); ?>"></iframe>
    852                             </div>
     860                                <iframe class="_winvoice-iframe-responsive woo-invoice-template-preview" src="<?php echo esc_url($preview_url); ?>" onload="challanFitPreviewFrame(this)"></iframe>
     861                            </div>
     862                            <script>
     863                                function challanFitPreviewFrame(frame) {
     864                                    var doc;
     865                                    try {
     866                                        doc = frame.contentDocument;
     867                                    } catch (e) {
     868                                        return;
     869                                    }
     870                                    if (!doc || !doc.body || doc.body.getAttribute('data-challan-notice') !== '1') {
     871                                        return;
     872                                    }
     873                                    var box = frame.parentNode;
     874                                    if (box) {
     875                                        box.style.aspectRatio = 'auto';
     876                                        box.style.height = 'auto';
     877                                    }
     878                                    frame.style.position = 'relative';
     879                                    frame.style.height = doc.body.scrollHeight + 'px';
     880                                }
     881                            </script>
     882                        <?php } elseif ( '' != $order_id ) { ?>
     883                            <p class="woo-invoice-preview-notice"><?php esc_html_e( 'Order not found.', 'webappick-pdf-invoice-for-woocommerce' ); ?></p>
     884                            <style>
     885                                .woo-invoice-preview-notice {
     886                                    box-sizing: border-box;
     887                                    height: auto;
     888                                    margin: 16px;
     889                                    padding: 12px 14px;
     890                                    background: #fcf9e8;
     891                                    border: 1px solid #dba617;
     892                                    border-left-width: 4px;
     893                                    color: #1d2327;
     894                                    font-size: 13px;
     895                                    line-height: 1.5;
     896                                    text-align: left;
     897                                }
     898                            </style>
    853899                        <?php } else { ?>
    854900                            <img class="woo-invoice-template-preview" src="<?php echo esc_url($template_image_url); //phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage ?>" alt="Preview Template">
    … …  
    869915                    </div><!-- end .woo-invoice-card-body -->
    870916                </div><!-- end .woo-invoice-card -->
     917                <?php endif; ?>
    871918
    872919                <!-- <div class="woo_invoice_template_free_vs_pro">
  • webappick-pdf-invoice-for-woocommerce/trunk/admin/partials/tabs/system-status-tab.php

    r3463094 r3743261  
    320320                            <p class="woo-invoice-banner-title">Upgrade to Challan Pro Today!</p>
    321321                            <button
    322                                     onclick="window.open('https://webappick.com/discount-deal/?utm_source=10YC-fix&utm_medium=free-to-pro&utm_campaign=10Y-25&utm_id=1')"
     322                                    onclick="window.open('https://webappick.com/plugin/woocommerce-pdf-invoice-packing-slips/?utm_source=customer_site&utm_medium=free_vs_pro&utm_campaign=woo_invoice_free', '_blank')"
    323323                                    class="woo-invoice-banner-btn"
    324324                            >
  • webappick-pdf-invoice-for-woocommerce/trunk/includes/class-woo-invoice-hooks.php

    r3467231 r3743261  
    660660        $allowed_statuses = apply_filters( 'woo_invoice_email_types', $allowed_statuses );
    661661
    662         // Delete old pdf files before generating new one.
    663         array_map( 'unlink', glob( CHALLAN_FREE_INVOICE_DIR . '*.pdf' ) ); // Delete files.
    664 
    665         // Generate & Save Invoice.
    666         woo_invoice_engine()->save_invoice($order_id);
    667 
    668         // Attach invoice with email.
     662        // Replace only this order's invoice. Other PDFs in the folder stay in place.
    669663        $invoice_no = woo_invoice_get_invoice_number( $order_id );
    670664        $file_name  = 'Invoice-' . $invoice_no;
    671665        $file_name  = apply_filters( 'woo_invoice_file_name', $file_name, 'invoice', $order_id );
     666        $pdf_path   = CHALLAN_FREE_INVOICE_DIR . $file_name . '.pdf';
     667
     668        $invoice_dir = wp_normalize_path( untrailingslashit( CHALLAN_FREE_INVOICE_DIR ) );
     669        $normalized  = wp_normalize_path( $pdf_path );
     670        if ( $invoice_dir && 0 === strpos( $normalized, $invoice_dir . '/' ) && file_exists( $pdf_path ) ) {
     671            wp_delete_file( $pdf_path );
     672        }
     673
     674        // Generate & Save Invoice.
     675        woo_invoice_engine()->save_invoice( $order_id );
    672676
    673677        // Return file path.
    674678        if ( isset( $status ) && in_array( $status, $allowed_statuses ) ) {
    675             $pdf_path      = CHALLAN_FREE_INVOICE_DIR . $file_name . '.pdf';
    676679            $attachments[] = $pdf_path;
    677680        }
    … …  
    837840            $order_id = ! empty($_REQUEST['order_id']) ? sanitize_text_field(wp_unslash($_REQUEST['order_id'])) : '';
    838841
    839             $order = wc_get_order($order_id);
     842            $order = wc_get_order( absint( $order_id ) );
     843            if ( ! $order ) {
     844                woo_invoice_exit_with_notice( __( 'Order not found.', 'webappick-pdf-invoice-for-woocommerce' ) );
     845            }
    840846            $user  = $order->get_user_id();
    841847            if ( wc_user_has_role(get_current_user_id(), 'administrator')
    … …  
    876882            $order_id = ! empty($_REQUEST['order_id']) ? sanitize_text_field(wp_unslash($_REQUEST['order_id'])) : '';
    877883
    878             $order = wc_get_order($order_id);
     884            $order = wc_get_order( absint( $order_id ) );
     885            if ( ! $order ) {
     886                woo_invoice_exit_with_notice( __( 'Order not found.', 'webappick-pdf-invoice-for-woocommerce' ) );
     887            }
    879888            $user  = $order->get_user_id();
    880889            if ( wc_user_has_role(get_current_user_id(), 'administrator')
    … …  
    919928                        $order_id = ! empty($_REQUEST['order_id']) ? sanitize_text_field(wp_unslash($_REQUEST['order_id'])) : '';
    920929
    921                         $order = wc_get_order($order_id);
     930                        $order = wc_get_order( absint( $order_id ) );
     931                        if ( ! $order ) {
     932                                woo_invoice_exit_with_notice( __( 'Order not found.', 'webappick-pdf-invoice-for-woocommerce' ) );
     933                        }
    922934                        $user  = $order->get_user_id();
    923935                        if ( wc_user_has_role(get_current_user_id(), 'administrator')
    … …  
    949961    public function save_pdf_template() {
    950962        check_ajax_referer('woo_invoice_ajax_nonce');
    951         $template = array(
    952                         'template_name' => isset($_POST['template']) ? sanitize_text_field(wp_unslash($_POST['template'])) : '',
    953                         'location'      => CHALLAN_FREE_PLUGIN_URL . 'admin/images/templates',
    954         );
    955 
    956         if ( ! empty($template) ) {
    957             update_option('wpifw_templateid', $template['template_name']);
    958             wp_send_json_success($template);
    959         }
    960         wp_send_json_error($_POST);
     963        $template_name = isset($_POST['template']) ? sanitize_key(wp_unslash($_POST['template'])) : '';
     964
     965        // Accept only template ids that have a stylesheet in includes/templates (e.g. invoice-1).
     966        $is_valid_template = 1 === preg_match('/^invoice-\d+$/', $template_name)
     967            && file_exists(CHALLAN_FREE_ROOT_FILE_PATH . 'includes/templates/' . $template_name . '.css');
     968
     969        if ( $is_valid_template ) {
     970            update_option('wpifw_templateid', $template_name);
     971            wp_send_json_success(
     972                array(
     973                                        'template_name' => $template_name,
     974                                        'location'      => CHALLAN_FREE_PLUGIN_URL . 'admin/images/templates',
     975                )
     976            );
     977        }
     978        wp_send_json_error( array( 'message' => 'Could not save the template.' ) );
    961979    }
    962980
  • webappick-pdf-invoice-for-woocommerce/trunk/includes/classes/class-admin-ui-font-downloader.php

    r3467231 r3743261  
    5757            $res        = $zip->open($zipFile);
    5858            if ( TRUE === $res ) {
     59                if ( ! self::zipEntriesAreSafe( $zip ) ) {
     60                    $zip->close();
     61                    wp_delete_file( $zipFile );
     62                    return false;
     63                }
    5964                $zip->extractTo($extractTo);
    6065                $zip->close();
    … …  
    9499        return self::$fontConfig;
    95100    }
     101
     102    /**
     103     * Reject ZIP entries that would write outside the destination directory.
     104     *
     105     * @param ZipArchive $zip Open archive.
     106     * @return bool
     107     */
     108    private static function zipEntriesAreSafe( $zip ) {
     109        for ( $i = 0; $i < $zip->numFiles; $i++ ) {
     110            $entry_name = $zip->getNameIndex( $i );
     111            if ( ! is_string( $entry_name ) ) {
     112                return false;
     113            }
     114            $entry_name = str_replace( '\\', '/', $entry_name );
     115            if ( false !== strpos( $entry_name, '..' ) || ( isset( $entry_name[0] ) && '/' === $entry_name[0] ) ) {
     116                return false;
     117            }
     118        }
     119        return true;
     120    }
    96121}
  • webappick-pdf-invoice-for-woocommerce/trunk/includes/classes/class-dropbox-font-downloader.php

    r3467231 r3743261  
    117117        $res = $zip->open($zipFile);
    118118        if ( TRUE === $res ) {
     119            if ( ! self::zipEntriesAreSafe( $zip ) ) {
     120                $zip->close();
     121                wp_delete_file( $zipFile );
     122                return false;
     123            }
    119124            $zip->extractTo($extractTo);
    120125            $zip->close();
    … …  
    126131            return false;
    127132        }
     133    }
     134
     135    /**
     136     * Reject ZIP entries that would write outside the destination directory.
     137     *
     138     * @param ZipArchive $zip Open archive.
     139     * @return bool
     140     */
     141    private static function zipEntriesAreSafe( $zip ) {
     142        for ( $i = 0; $i < $zip->numFiles; $i++ ) {
     143            $entry_name = $zip->getNameIndex( $i );
     144            if ( ! is_string( $entry_name ) ) {
     145                return false;
     146            }
     147            $entry_name = str_replace( '\\', '/', $entry_name );
     148            if ( false !== strpos( $entry_name, '..' ) || ( isset( $entry_name[0] ) && '/' === $entry_name[0] ) ) {
     149                return false;
     150            }
     151        }
     152        return true;
    128153    }
    129154
  • webappick-pdf-invoice-for-woocommerce/trunk/includes/classes/class-mpdf-lib-downloader.php

    r3190901 r3743261  
    4141        $arrContextOptions = array(
    4242            "ssl" => array(
    43                 "verify_peer"      => false,
    44                 "verify_peer_name" => false,
     43                "verify_peer"      => true,
     44                "verify_peer_name" => true,
    4545            ),
    4646        );
    … …  
    5252            $res        = $zip->open($zipFile);
    5353            if ( TRUE === $res ) {
     54                if ( ! self::zipEntriesAreSafe( $zip ) ) {
     55                    $zip->close();
     56                    wp_delete_file( $zipFile );
     57                    return false;
     58                }
    5459                $zip->extractTo($extractTo);
    5560                $zip->close();
    … …  
    6368        }
    6469    }
     70
     71    /**
     72     * Reject ZIP entries that would write outside the destination directory.
     73     *
     74     * @param ZipArchive $zip Open archive.
     75     * @return bool
     76     */
     77    private static function zipEntriesAreSafe( $zip ) {
     78        for ( $i = 0; $i < $zip->numFiles; $i++ ) {
     79            $entry_name = $zip->getNameIndex( $i );
     80            if ( ! is_string( $entry_name ) ) {
     81                return false;
     82            }
     83            $entry_name = str_replace( '\\', '/', $entry_name );
     84            if ( false !== strpos( $entry_name, '..' ) || ( isset( $entry_name[0] ) && '/' === $entry_name[0] ) ) {
     85                return false;
     86            }
     87        }
     88        return true;
     89    }
    6590}
  • webappick-pdf-invoice-for-woocommerce/trunk/includes/constants.php

    r3722380 r3743261  
    1515}
    1616
    17 define( 'CHALLAN_FREE_VERSION', '3.7.88' );
     17define( 'CHALLAN_FREE_VERSION', '3.7.89' );
    1818
    1919if ( ! defined( 'CHALLAN_FREE_FONTS_COUNT' ) ) {
  • webappick-pdf-invoice-for-woocommerce/trunk/includes/helper.php

    r3467231 r3743261  
    7777}
    7878
     79if ( ! function_exists('challan_get_cached_meta_keys') ) {
     80    /**
     81     * Return a meta key list from a transient and run the query only when the transient is empty.
     82     *
     83     * The lists are cleared by challan_flush_meta_keys_cache() when the Settings tab is saved,
     84     * so newly added meta keys show up right after a save.
     85     *
     86     * @param string   $cache_key Transient name.
     87     * @param callable $query     Returns the meta key rows.
     88     * @return array
     89     */
     90    function challan_get_cached_meta_keys( $cache_key, $query ) {
     91        $meta_keys = get_transient( $cache_key );
     92        if ( false === $meta_keys ) {
     93            $meta_keys = call_user_func( $query );
     94            $meta_keys = is_array( $meta_keys ) ? $meta_keys : array();
     95            set_transient( $cache_key, $meta_keys, 12 * HOUR_IN_SECONDS );
     96        }
     97
     98        return $meta_keys;
     99    }
     100}
     101
     102if ( ! function_exists('challan_flush_meta_keys_cache') ) {
     103    /**
     104     * Delete the cached order, product and order item meta key lists.
     105     *
     106     * @return void
     107     */
     108    function challan_flush_meta_keys_cache() {
     109        delete_transient( 'challan_order_meta_keys_hpos' );
     110        delete_transient( 'challan_order_meta_keys_cpt' );
     111        delete_transient( 'challan_product_meta_keys' );
     112        delete_transient( 'challan_item_meta_keys' );
     113    }
     114}
     115
    79116if ( ! function_exists('challan_order_meta_query') ) {
    80117    /**
    81      * @return array|object|null
     118     * @return array
    82119     */
    83120    function challan_order_meta_query(){
    84         global $wpdb;
    85         // Check if HPOS (High-Performance Order Storage) is enabled
    86         if ( woo_invoice_hpos_enabled() ) {
    87             // HPOS is enabled, query the wc_orders_meta table
    88             // Note: Table name uses $wpdb->prefix which is a trusted WordPress value
    89             $table_name = esc_sql( $wpdb->prefix . 'wc_orders_meta' );
    90             $order_meta_query_arr = $wpdb->get_results( "SELECT DISTINCT meta_key FROM {$table_name}" ); // phpcs:ignore
    91         } else {
     121        $hpos_enabled = woo_invoice_hpos_enabled();
     122        $cache_key    = $hpos_enabled ? 'challan_order_meta_keys_hpos' : 'challan_order_meta_keys_cpt';
     123
     124        return challan_get_cached_meta_keys( $cache_key, function () use ( $hpos_enabled ) {
     125            global $wpdb;
     126            // Check if HPOS (High-Performance Order Storage) is enabled
     127            if ( $hpos_enabled ) {
     128                // HPOS is enabled, query the wc_orders_meta table
     129                // Note: Table name uses $wpdb->prefix which is a trusted WordPress value
     130                $table_name = esc_sql( $wpdb->prefix . 'wc_orders_meta' );
     131                return $wpdb->get_results( "SELECT DISTINCT meta_key FROM {$table_name}" ); // phpcs:ignore
     132            }
     133
    92134            // Traditional CPT-based orders are in use, query the postmeta table
    93135            // Note: $wpdb->postmeta and $wpdb->posts are trusted WordPress table name constants
    94             $order_meta_query_arr = $wpdb->get_results( $wpdb->prepare(
     136            return $wpdb->get_results( $wpdb->prepare(
    95137                "SELECT pm.meta_key FROM {$wpdb->postmeta} AS pm LEFT JOIN {$wpdb->posts} AS p ON pm.post_id = p.id WHERE p.post_type = %s GROUP BY pm.meta_key",
    96138                'shop_order'
    97139            ) ); // phpcs:ignore
    98         }
    99         $order_meta_query = array();
    100         $order_meta_query = $order_meta_query_arr;
    101 
    102         return $order_meta_query;
     140        } );
    103141    }
    104142}
    … …  
    106144if ( ! function_exists('challan_product_meta_query') ) {
    107145    /**
    108      * @return array|object|null
     146     * @return array
    109147     */
    110148    function challan_product_meta_query(){
    111         global $wpdb;
    112 
    113         // Note: $wpdb->postmeta and $wpdb->posts are trusted WordPress table name constants
    114         $product_meta_query = $wpdb->get_results( $wpdb->prepare(
    115             "SELECT pm.meta_key, pm.meta_id FROM {$wpdb->postmeta} AS pm LEFT JOIN {$wpdb->posts} AS p ON pm.post_id = p.id WHERE p.post_type = %s GROUP BY pm.meta_key",
    116             'product'
    117         ) ); // phpcs:ignore
    118 
    119         return $product_meta_query;
     149        return challan_get_cached_meta_keys( 'challan_product_meta_keys', function () {
     150            global $wpdb;
     151
     152            // Note: $wpdb->postmeta and $wpdb->posts are trusted WordPress table name constants
     153            return $wpdb->get_results( $wpdb->prepare(
     154                "SELECT pm.meta_key, pm.meta_id FROM {$wpdb->postmeta} AS pm LEFT JOIN {$wpdb->posts} AS p ON pm.post_id = p.id WHERE p.post_type = %s GROUP BY pm.meta_key",
     155                'product'
     156            ) ); // phpcs:ignore
     157        } );
    120158    }
    121159}
    … …  
    123161if ( ! function_exists('challan_item_meta_query') ) {
    124162    /**
    125      * @return array|object|null
     163     * @return array
    126164     */
    127165    function challan_item_meta_query(){
    128         global $wpdb;
    129 
    130                 if ( class_exists( 'WooCommerce' ) ) {
    131                         // Note: $wpdb->order_itemmeta is a trusted WooCommerce table name constant
    132                         $item_meta = $wpdb->get_results( "SELECT DISTINCT meta_key FROM {$wpdb->order_itemmeta}" ); // phpcs:ignore
    133                 } else {
    134                         $item_meta = array();
    135                 }
    136 
    137         return $item_meta;
     166        return challan_get_cached_meta_keys( 'challan_item_meta_keys', function () {
     167            global $wpdb;
     168
     169            if ( ! class_exists( 'WooCommerce' ) ) {
     170                return array();
     171            }
     172
     173            // Note: $wpdb->order_itemmeta is a trusted WooCommerce table name constant
     174            return $wpdb->get_results( "SELECT DISTINCT meta_key FROM {$wpdb->order_itemmeta}" ); // phpcs:ignore
     175        } );
    138176    }
    139177}
    … …  
    383421    return true;
    384422}
     423
     424/**
     425 * Stop the request with a compact notice.
     426 * Used inside the invoice preview frame, which otherwise keeps an A4-page height.
     427 *
     428 * @param string $message Notice text.
     429 */
     430function woo_invoice_exit_with_notice( $message ) {
     431    if ( ! headers_sent() ) {
     432        status_header( 404 );
     433        nocache_headers();
     434        header( 'Content-Type: text/html; charset=utf-8' );
     435    }
     436
     437    $message = esc_html( $message );
     438    echo '<!DOCTYPE html><html><head><meta charset="utf-8"><style>
     439html,body{margin:0;height:auto;background:#fff;}
     440body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;}
     441.challan-order-notice{box-sizing:border-box;margin:16px;padding:12px 14px;background:#fcf9e8;border:1px solid #dba617;border-left-width:4px;color:#1d2327;font-size:13px;line-height:1.5;}
     442</style></head><body data-challan-notice="1"><p class="challan-order-notice">' . $message . '</p></body></html>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
     443    exit;
     444}
  • webappick-pdf-invoice-for-woocommerce/trunk/includes/rest-api/font-downloader-api.php

    r3467231 r3743261  
    248248                        wp_send_json($response->get_data(), 200);
    249249                        exit;
    250                         wp_die();
    251250                }
    252251    } // end class definition
    253252
    254253    add_action('rest_api_init', function () {
    255                 if ( ! headers_sent() ) {
    256                         header('Access-Control-Allow-Headers: Authorization, X-WP-Nonce,Content-Type, X-Requested-With');
    257                         // Security: Only allow requests from the same origin (WordPress site URL)
    258                         $allowed_origin = esc_url_raw( home_url() );
    259                         header('Access-Control-Allow-Origin: ' . $allowed_origin);
    260                         header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
    261                         header('Access-Control-Allow-Credentials: true');
    262                 }
    263254        $apiFontDownloader = new Challan_Font_Downloader_API();
    264255        $apiFontDownloader->register_routes();
  • webappick-pdf-invoice-for-woocommerce/trunk/includes/settings.php

    r3042853 r3743261  
    4040
    4141    if ( ! file_exists($invoice_dir_without_trailing_slash) && is_writable($base_dir) ) {
    42         mkdir($invoice_dir_without_trailing_slash, 0777, true);
     42        mkdir($invoice_dir_without_trailing_slash, 0755, true);
    4343        // Protect files from public access.
    4444        touch(CHALLAN_FREE_INVOICE_DIR . '.htaccess');
    … …  
    6363
    6464    if ( ! file_exists($wpifw_invoice_font_dir) && is_writable($base_dir) ) {
    65         mkdir($wpifw_invoice_font_dir, 0777, true);
     65        mkdir($wpifw_invoice_font_dir, 0755, true);
    6666
    6767        // Protect files from public access.
  • webappick-pdf-invoice-for-woocommerce/trunk/includes/settings/admin-ui-fonts-dir-setting.php

    r3042853 r3743261  
    3030            //Make dir like /uploads/WOO-INVOICE-ADMIN-UI-FONTS/
    3131            if ( ! file_exists(rtrim(CHALLAN_ADMIN_UI_FONTS_DIR, "/")) ) {
    32                 mkdir(rtrim(CHALLAN_ADMIN_UI_FONTS_DIR, "/"), 0777, true);
     32                mkdir(rtrim(CHALLAN_ADMIN_UI_FONTS_DIR, "/"), 0755, true);
    3333            }
    3434        }
  • webappick-pdf-invoice-for-woocommerce/trunk/includes/settings/invoice-temp-dir-setting.php

    r3042853 r3743261  
    3030            //Make dir like /WOO-INVOICE/TEMP
    3131            if ( ! file_exists(rtrim(CHALLAN_FREETEMP_DIR, "/")) ) {
    32                 mkdir(rtrim(CHALLAN_FREETEMP_DIR, "/"), 0777, true);
     32                mkdir(rtrim(CHALLAN_FREETEMP_DIR, "/"), 0755, true);
    3333            }
    3434            if ( is_writable(rtrim(CHALLAN_FREETEMP_DIR, "/")) ) {
    … …  
    4545            //Make dir like /WOO-INVOICE/TEMP/ttfontdata
    4646            if ( ! file_exists(CHALLAN_FREETEMP_DIR . "ttfontdata") ) {
    47                 mkdir(CHALLAN_FREETEMP_DIR . "ttfontdata", 0777, true);
     47                mkdir(CHALLAN_FREETEMP_DIR . "ttfontdata", 0755, true);
    4848            }
    4949            if ( is_writeable(CHALLAN_FREETEMP_DIR . "ttfontdata") ) {
  • webappick-pdf-invoice-for-woocommerce/trunk/libs/WebAppick/AppServices/Insights.php

    r3258881 r3743261  
    22namespace Challan\AppServices;
    33
    4 use mysql_xdevapi\Exception;
    54use WP_Theme;
    65use WP_User;
    … …  
    256255                try {
    257256                        $intervalCheck = strtotime( $trackingInterval );
    258                 } catch ( Exception $e ) {
     257                } catch ( \Exception $e ) {
    259258                        // fallback to default 1 week if filter returned unusable data
    260259                        $intervalCheck = strtotime( '-1 week' );
  • webappick-pdf-invoice-for-woocommerce/trunk/woo-invoice.php

    r3722380 r3743261  
    77 * Plugin URI:   https://webappick.com
    88 * Description:  Automatic Generate PDF Invoice and attach  with order email for WooCommerce.
    9  * Version:      3.7.88
     9 * Version:      3.7.89
    1010 * Author:       WebAppick
    1111 * Author URI:   https://webappick.com
    … …  
    6464    if ( woo_invoice_is_uploads_folder_writable() ) {
    6565        if ( ! file_exists(CHALLAN_FREE_INVOICE_DIR.'.htaccess' ) ) {
    66             mkdir( CHALLAN_FREE_INVOICE_DIR, 0777, true );
     66            mkdir( CHALLAN_FREE_INVOICE_DIR, 0755, true );
    6767            // Protect files from public access.
    6868            $content = 'deny from all';
    … …  
    8787        if ( woo_invoice_is_uploads_folder_writable() ) {
    8888        if ( ! file_exists(CHALLAN_FREE_FONT_DIR ) ) {
    89             mkdir( $wpifw_invoice_font_dir, 0777, true );
     89            mkdir( $wpifw_invoice_font_dir, 0755, true );
    9090            // Protect files from public access.
    9191            $content = 'deny from all';
    … …  
    319319        }
    320320
     321        // Rebuild the meta key dropdown lists after save so newly added keys appear.
     322        challan_flush_meta_keys_cache();
     323
    321324                // If checkbox is not checked then put empty value.
    322325                if ( ! isset( $_POST[ $invoice_allow ] ) ||
    … …  
    380383                $name = array();
    381384                $place = array();
    382                 $label_arr = isset($_POST['_winvoice_order_meta_label']) ? $_POST['_winvoice_order_meta_label'] : array(); //phpcs:ignore
    383                 $name_arr = isset($_POST['_winvoice_order_meta_name']) ? $_POST['_winvoice_order_meta_name'] : array(); //phpcs:ignore
    384                 $place_arr = isset($_POST['_winvoice_order_meta_name_position']) ? $_POST['_winvoice_order_meta_name_position'] : array(); //phpcs:ignore
     385                $label_arr = isset( $_POST['_winvoice_order_meta_label'] ) ? wp_unslash( $_POST['_winvoice_order_meta_label'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
     386                $name_arr = isset( $_POST['_winvoice_order_meta_name'] ) ? wp_unslash( $_POST['_winvoice_order_meta_name'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
     387                $place_arr = isset( $_POST['_winvoice_order_meta_name_position'] ) ? wp_unslash( $_POST['_winvoice_order_meta_name_position'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
     388                $label_arr = is_array( $label_arr ) ? $label_arr : array();
     389                $name_arr  = is_array( $name_arr ) ? $name_arr : array();
     390                $place_arr = is_array( $place_arr ) ? $place_arr : array();
    385391
    386392                foreach ( $label_arr as $index => $val ) {
    387 
    388                     if ( '' != $val && '' != $name_arr[ $index ] && '' != $place_arr[ $index ] ) {
    389                         array_push($label, $val);
    390                         array_push($name, $name_arr[ $index ]);
    391                         array_push($place, $place_arr[ $index ]);
    392                     } else {
    393                         $label_arr[ $index ] = '';
    394                         $name_arr[ $index ] = '';
    395                         $place_arr[ $index ] = '';
     393                    $val        = sanitize_text_field( $val );
     394                    $meta_name  = isset( $name_arr[ $index ] ) ? sanitize_text_field( $name_arr[ $index ] ) : '';
     395                    $meta_place = isset( $place_arr[ $index ] ) ? sanitize_text_field( $place_arr[ $index ] ) : '';
     396
     397                    if ( '' != $val && '' != $meta_name && '' != $meta_place ) {
     398                        array_push( $label, $val );
     399                        array_push( $name, $meta_name );
     400                        array_push( $place, $meta_place );
    396401                    }
    397402                }
    398403
    399                 if ( count($label) > 0 ) {
    400                     update_option($key, $label);
    401                     update_option('_winvoice_order_meta_name', $name);
    402                     update_option('_winvoice_order_meta_name_position', $place);
     404                if ( count( $label ) > 0 ) {
     405                    update_option( $key, $label );
     406                    update_option( '_winvoice_order_meta_name', $name );
     407                    update_option( '_winvoice_order_meta_name_position', $place );
    403408                } else {
    404                     update_option('_winvoice_order_meta_label', array());
    405                     update_option('_winvoice_order_meta_name', array());
    406                     update_option('_winvoice_order_meta_name_position', array());
     409                    update_option( '_winvoice_order_meta_label', array() );
     410                    update_option( '_winvoice_order_meta_name', array() );
     411                    update_option( '_winvoice_order_meta_name_position', array() );
    407412                }
    408             }elseif ( '_winvoice_post_meta_name' == $key ) {
    409 
    410                 $label = $_POST['_winvoice_post_meta_label']; //phpcs:ignore
    411                 $name = $_POST['_winvoice_post_meta_name']; //phpcs:ignore
     413            } elseif ( '_winvoice_post_meta_name' == $key ) {
     414
     415                $label = isset( $_POST['_winvoice_post_meta_label'] ) ? sanitize_text_field( wp_unslash( $_POST['_winvoice_post_meta_label'] ) ) : '';
     416                $name  = isset( $_POST['_winvoice_post_meta_name'] ) ? sanitize_text_field( wp_unslash( $_POST['_winvoice_post_meta_name'] ) ) : '';
    412417                if ( $name ) {
    413                     update_option('_winvoice_post_meta_label', $label);
    414                     update_option($key, $name);
     418                    update_option( '_winvoice_post_meta_label', $label );
     419                    update_option( $key, $name );
    415420                } else {
    416                     update_option('_winvoice_post_meta_label', '');
    417                     update_option('_winvoice_post_meta_name','');
     421                    update_option( '_winvoice_post_meta_label', '' );
     422                    update_option( '_winvoice_post_meta_name', '' );
    418423                }
    419             }elseif ( strpos( $key, '_winvoice_order_item_meta_name' ) !== false ) {
    420 
    421                 $label = $_POST['_winvoice_order_item_meta_label']; //phpcs:ignore
    422                 $name = $_POST['_winvoice_order_item_meta_name']; //phpcs:ignore
     424            } elseif ( strpos( $key, '_winvoice_order_item_meta_name' ) !== false ) {
     425
     426                $label = isset( $_POST['_winvoice_order_item_meta_label'] ) ? sanitize_text_field( wp_unslash( $_POST['_winvoice_order_item_meta_label'] ) ) : '';
     427                $name  = isset( $_POST['_winvoice_order_item_meta_name'] ) ? sanitize_text_field( wp_unslash( $_POST['_winvoice_order_item_meta_name'] ) ) : '';
    423428                if ( $name ) {
    424                     update_option('_winvoice_order_item_meta_label', $label);
    425                     update_option('_winvoice_order_item_meta_name', $name);
     429                    update_option( '_winvoice_order_item_meta_label', $label );
     430                    update_option( '_winvoice_order_item_meta_name', $name );
    426431                } else {
    427                     update_option('_winvoice_order_item_meta_label', '');
    428                     update_option('_winvoice_order_item_meta_name','');
     432                    update_option( '_winvoice_order_item_meta_label', '' );
     433                    update_option( '_winvoice_order_item_meta_name', '' );
    429434                }
    430435            }
Note: See TracChangeset for help on using the changeset viewer.