CVE-2024-23825 (published 2024-01-30T17:15Z)

TablePress is a table plugin for Wordpress. For importing tables, TablePress makes external HTTP requests based on a URL that is provided by the user. That user input is filtered insufficiently, which makes it is possible to send requests to unintended network locations and receive responses. On sites in a cloud environment like AWS, an attacker can potentially make GET requests to the instance's metadata REST API. If the instance's configuration is insecure, this can lead to the exposure of internal data, including credentials. This vulnerability is fixed in 2.2.5.

CVSS v3 base score: 4.9, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:N/A:N)

Weakness information:
cwe_id: CWE-918
cwe_name: Server-Side Request Forgery (SSRF)
description: The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.
extended_description: By providing URLs to unexpected hosts or ports, attackers can make it appear that the server is sending the request, possibly bypassing access controls such as firewalls that prevent the attackers from accessing the URLs directly. The server can be used as a proxy to conduct port scanning of hosts in internal networks, use other URLs such as that can access documents on the system (using file://), or use other protocols such as gopher:// or tftp://, which may provide greater control over the contents of requests.
         

Fix information:
repo_url: https://github.com/TablePress/TablePress
commit_details: repo_url: https://github.com/TablePress/TablePress
author: TobiasBg
author_date: 2024-01-27 21:56:59+01:00
msg: Finish TablePress 2.2.5.
repository: repo_url: https://github.com/TablePress/TablePress
repo_name: TablePress/TablePress
description: TablePress is the most popular and highest-rated table plugin for WordPress. Create and embed attractive and interactive tables on your website!
repo_language: PHP
owner: TablePress
file_changes: filename: .gitattributes
change_type: ModificationType.MODIFY
diff: @@ -4,6 +4,7 @@
 /.git/ export-ignore
 /.github/ export-ignore
 /.phpstan/ export-ignore
+/.wordpress-org/ export-ignore
 /node_modules/ export-ignore
 /tests/ export-ignore
 /vendor/ export-ignore
@@ -13,20 +14,23 @@
 /.eslintrc.js export-ignore
 /.gitattributes export-ignore
 /.gitignore export-ignore
+/.phpunit.result.cache export-ignore
 /.prettierignore export-ignore
 /.prettierrc.js export-ignore
 /.stylelintignore export-ignore
 /.stylelintrc.json export-ignore
+/.typos.toml export-ignore
 /composer.json export-ignore
 /composer.lock export-ignore
 /Gruntfile.js export-ignore
-/package.json export-ignore
 /package-lock.json export-ignore
+/package.json export-ignore
 /phpcompat.xml.dist export-ignore
 /phpcs.xml.dist export-ignore
 /phpstan.neon.dist export-ignore
 /phpunit.xml.dist export-ignore
 /readme.md export-ignore
+/rector.php export-ignore
 /webpack.config.js export-ignore
 
 # Set default behaviour, in case users don't have core.autocrlf set.

programming_language: JavaScript
filename: wp-org-deploy.yml
change_type: ModificationType.ADD
diff: @@ -0,0 +1,47 @@
+name: Deploy to wordpress.org Repository
+
+on:
+  # Deploy to wordpress.org when a production release is created.
+  release:
+    types: [ released ]
+  # Do a "dry run" (without comming to SVN) when the workflow is manually triggered.
+  workflow_dispatch:
+
+jobs:
+
+  deploy_to_wordpress_org:
+    name: Deploy to wordpress.org${{ github.event_name == 'workflow_dispatch' && ' (dry run)' || '' }}
+    if: github.repository == 'TablePress/TablePress'
+    runs-on: ubuntu-latest
+
+    steps:
+      - name: Checkout TablePress repository
+        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
+
+      - name: WordPress Plugin Deploy
+        id: deploy
+        uses: 10up/action-wordpress-plugin-deploy@stable
+        with:
+          generate-zip: true
+          dry-run: ${{ github.event_name == 'workflow_dispatch' }}
+        env:
+          SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
+          SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
+          SLUG: ${{ vars.SLUG }}
+
+      - name: Get plugin version
+        id: get-version
+        if: ${{ github.event_name != 'workflow_dispatch' }}
+        run: |
+          echo "version=$(awk '/Stable tag: /{print $NF}' readme.txt)" >> $GITHUB_OUTPUT
+
+      - name: Upload release ZIP file
+        uses: actions/upload-release-asset@v1
+        if: ${{ github.event_name != 'workflow_dispatch' }}
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        with:
+          upload_url: ${{ github.event.release.upload_url }}
+          asset_path: ${{ steps.deploy.outputs.zip-path }}
+          asset_name: ${{ vars.SLUG }}.${{ steps.get-version.outputs.version }}.zip
+          asset_content_type: application/zip

programming_language: Shell
filename: edit.asset.php
change_type: ModificationType.MODIFY
diff: @@ -1 +1 @@
-<?php return array('dependencies' => array('wp-hooks', 'wp-i18n', 'wp-url'), 'version' => 'cdf1475bc9e3883381b2');
+<?php return array('dependencies' => array('wp-hooks', 'wp-i18n', 'wp-url'), 'version' => 'aabe698a026e2cdb0743');

programming_language: PHP
filename: edit.js
change_type: ModificationType.MODIFY
diff: @@ -1 +1 @@
-!function(){"use strict";var e=window.wp.i18n,t=window.wp.hooks,s=window.wp.url;const o=e=>"#"===e[0]?document.getElementById(e.slice(1)):document.querySelectorAll(e);window.tp=window.tp||{},tp.made_changes=!1,tp.helpers=tp.helpers||{},tp.callbacks=tp.callbacks||{},tp.helpers.selection=tp.helpers.selection||{rows:[0],columns:[0]},tp.helpers.unsaved_changes=tp.helpers.unsaved_changes||{},tp.helpers.unsaved_changes.unload_dialog=function(e){e.preventDefault(),e.returnValue=""},tp.helpers.unsaved_changes.set=function(){tp.made_changes||(tp.made_changes=!0,window.addEventListener("beforeunload",tp.helpers.unsaved_changes.unload_dialog))},tp.helpers.unsaved_changes.unset=function(){tp.made_changes=!1,window.removeEventListener("beforeunload",tp.helpers.unsaved_changes.unload_dialog)},tp.helpers.options=tp.helpers.options||{},tp.helpers.options.load=function(){Object.keys(tp.table.options).forEach((function(e){if("last_editor"===e)return;if(""===(e=(0,t.applyFilters)("tablepress.optionsLoad",e)))return;let s=o(`#option-${e}`);s||(s=o(`#option-${e}-${tp.table.options[e]}`)),s&&(s instanceof HTMLInputElement&&"checkbox"===s.type?s.checked=tp.table.options[e]:s instanceof HTMLInputElement&&"radio"===s.type?s.checked=!0:s.value=tp.table.options[e])})),tp.table.options.use_datatables&&tp.helpers.editor.has_merged_cells()&&(tp.table.options.use_datatables=!1,o("#option-use_datatables").checked=!1),tp.helpers.options.check_dependencies()},tp.helpers.options.change=function(s){if(!s.target)return;const l=s.target.name||"";if(""===l)return;const a=s.target instanceof HTMLInputElement&&"checkbox"===s.target.type?"checked":"value";tp.table.options[l]=s.target[a],s.target instanceof HTMLInputElement&&"number"===s.target.type&&(tp.table.options[l]=parseInt(tp.table.options[l],10)),"use_datatables"===l&&tp.table.options.use_datatables&&tp.helpers.editor.has_merged_cells()&&(tp.table.options.use_datatables=!1,o("#option-use_datatables").checked=!1,window.alert((0,e.__)("You can not enable the Table Features for Site Visitors, because your table contains combined/merged cells.","tablepress"))),(0,t.doAction)("tablepress.optionsChange",l,a,s),tp.helpers.options.check_dependencies(),tp.helpers.unsaved_changes.set(),tp.editor.updateTable()},tp.helpers.options.check_dependencies=function(){o("#option-use_datatables").disabled=!tp.table.options.table_head,o("#notice-datatables-head-row").style.display=tp.table.options.table_head?"none":"block",o("#option-print_name_position").disabled=!tp.table.options.print_name,o("#option-print_description_position").disabled=!tp.table.options.print_description;const e=tp.table.options.use_datatables&&tp.table.options.table_head;o("#tablepress_edit-datatables-features").querySelectorAll(":scope input:not(#option-use_datatables), :scope textarea").forEach((t=>t.disabled=!e));const s=e&&tp.table.options.datatables_paginate;o("#option-datatables_lengthchange").disabled=!s,o("#option-datatables_paginate_entries").disabled=!s,(0,t.doAction)("tablepress.optionsCheckDependencies")},tp.helpers.options.validate_fields=function(){if(tp.table.options.datatables_paginate&&(isNaN(tp.table.options.datatables_paginate_entries)||tp.table.options.datatables_paginate_entries<1||tp.table.options.datatables_paginate_entries>9999)){window.alert((0,e.sprintf)((0,e.__)("The entered value in the “%1$s” field is invalid.","tablepress"),(0,e.__)("Pagination Entries","tablepress")));const t=o("#option-datatables_paginate_entries");return t.focus(),t.select(),!1}if(/[^A-Za-z0-9- _:]/.test(tp.table.options.extra_css_classes)){window.alert((0,e.sprintf)((0,e.__)("The entered value in the “%1$s” field is invalid.","tablepress"),(0,e.__)("Extra CSS Classes","tablepress")));const t=o("#option-extra_css_classes");return t.focus(),t.select(),!1}return(0,t.applyFilters)("tablepress.optionsValidateFields",!0)},tp.helpers.visibility=tp.helpers.visibility||{},tp.helpers.visibility.load=function(){const e=tp.table.visibility.rows.length,t=tp.table.visibility.columns.length,s={};for(let o=0;o<e;o++)if(1!==tp.table.visibility.rows[o])for(let e=0;e<t;e++){const t=jspreadsheet.getColumnNameFromId([e,o]);s[t]=s[t]||{},s[t].row_hidden=!0}for(let o=0;o<t;o++)if(1!==tp.table.visibility.columns[o])for(let t=0;t<e;t++){const e=jspreadsheet.getColumnNameFromId([o,t]);s[e]=s[e]||{},s[e].column_hidden=!0}return s},tp.helpers.visibility.update=function(){tp.table.visibility.rows=[];for(let e=0;e<tp.editor.options.data.length;e++)tp.table.visibility.rows[e]=1;tp.table.visibility.columns=[];for(let e=0;e<tp.editor.options.columns.length;e++)tp.table.visibility.columns[e]=1;Object.keys(tp.editor.options.meta).forEach((function(e){const t=jspreadsheet.getIdFromColumnName(e,!0);1===tp.table.visibility.rows[t[1]]&&tp.editor.options.meta[e].row_hidden&&(tp.table.visibility.rows[t[1]]=0),1===tp.table.visibility.columns[t[0]]&&tp.editor.options.meta[e].column_hidden&&(tp.table.visibility.columns[t[0]]=0)}))},tp.helpers.visibility.selection_contains=function(e,t){return tp.helpers.selection[e].some((s=>tp.table.visibility[e][s]===t))},tp.helpers.move_allowed=function(e,t){let s=tp.helpers.selection[e][0],o=0;return"down"!==t&&"right"!==t&&"bottom"!==t&&"last"!==t||(s=tp.helpers.selection[e][tp.helpers.selection[e].length-1],o="rows"===e?tp.editor.options.data.length-1:tp.editor.options.columns.length-1),o!==s},tp.helpers.cell_merge_allowed=function(t,s={}){const o="alert"===t;if(tp.table.options.table_head&&tp.table.options.use_datatables)return s.text=(0,e.sprintf)((0,e.__)("You can not combine these cells, because the “%1$s” checkbox in the “%2$s” section is checked.","tablepress"),(0,e.__)("Enable Visitor Features","tablepress"),(0,e.__)("Table Features for Site Visitors","tablepress"))+" "+(0,e.__)("The Table Features for Site Visitors are not compatible with merged cells.","tablepress"),o&&window.alert(s.text),!1;const l=tp.helpers.selection.rows[0],a=tp.helpers.selection.rows[tp.helpers.selection.rows.length-1];if(tp.table.options.table_head&&0===l&&a>0)return s.text=(0,e.sprintf)((0,e.__)("You can not combine these cells, because the “%1$s” checkbox in the “%2$s” section is checked.","tablepress"),(0,e.__)("Table Head Row","tablepress"),(0,e.__)("Table Options","tablepress")),o&&window.alert(s.text),!1;const n=tp.editor.options.data.length-1;return!(tp.table.options.table_foot&&n===a&&l<n&&(s.text=(0,e.sprintf)((0,e.__)("You can not combine these cells, because the “%1$s” checkbox in the “%2$s” section is checked.","tablepress"),(0,e.__)("Table Foot Row","tablepress"),(0,e.__)("Table Options","tablepress")),o&&window.alert(s.text),1))},tp.helpers.editor=tp.helpers.editor||{},tp.helpers.editor.reselect=function(e,t){void 0===t&&(t=tp.editor),t.updateSelectionFromCoords(tp.helpers.selection.columns[0],tp.helpers.selection.rows[0],tp.helpers.selection.columns[tp.helpers.selection.columns.length-1],tp.helpers.selection.rows[tp.helpers.selection.rows.length-1])},tp.helpers.editor.has_merged_cells=function(){const e=tp.editor.options.data.length,t=tp.editor.options.columns.length;for(let s=1;s<e;s++)for(let e=1;e<t;e++)if("#rowspan#"===tp.editor.options.data[s][e]||"#colspan#"===tp.editor.options.data[s][e])return!0;return!1},tp.helpers.editor.sorting=function(e){return e=e?-1:1,function(t,s){return e*((e,t)=>{const s=/(^([+\-]?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?(?=\D|\s|$))|^0x[\da-fA-F]+$|\d+)/g,o=/^\s+|\s+$/g,l=/\s+/g,a=/^0x[0-9a-f]+$/i,n=/^0/,i=e.replace(o,"")||"",r=t.replace(o,"")||"",c=i.replace(s,"\0$1\0").replace(/\0$/,"").replace(/^\0/,"").split("\0"),p=r.replace(s,"\0$1\0").replace(/\0$/,"").replace(/^\0/,"").split("\0"),d=parseInt(i.match(a),16)||1!==c.length&&Date.parse(i),u=parseInt(r.match(a),16)||d&&r.match(/(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/)&&Date.parse(r)||null,b=(e,t)=>(!e.match(n)||1===t)&&parseFloat(e)||e.replace(l," ").replace(o,"")||0;if(u){if(d<u)return-1;if(d>u)return 1}for(let e=0,t=c.length,s=p.length,o=Math.max(t,s);e<o;e++){const o=b(c[e]||"",t),l=b(p[e]||"",s);if(isNaN(o)!==isNaN(l))return isNaN(o)?1:-1;if(/[^\x00-\x80]/.test(o+l)&&o.localeCompare){const e=o.localeCompare(l);return e/Math.abs(e)}if(o<l)return-1;if(o>l)return 1}return 0})(t[1],s[1])}},tp.callbacks.editor=tp.callbacks.editor||{},tp.callbacks.editor.onselection=function(e,t,s,o,l){tp.helpers.selection={rows:[],columns:[]};for(let e=s;e<=l;e++)tp.helpers.selection.rows.push(e);for(let e=t;e<=o;e++)tp.helpers.selection.columns.push(e)},tp.callbacks.editor.onupdatetable=function(e,t,s,o,l,a,n){const i=e.jspreadsheet.options.meta[n];if(t.classList.toggle("column-hidden",Boolean(i?.column_hidden)),0===s&&(t.parentNode.classList.toggle("row-hidden",Boolean(i?.row_hidden)),t.parentNode.classList.remove("head-row","foot-row"),o===e.jspreadsheet.rows.length-1)){const t=e.jspreadsheet.content.querySelectorAll(":scope tbody tr:not(.row-hidden)");1<t.length&&(tp.table.options.table_head&&t[0].classList.add("head-row"),tp.table.options.table_foot&&t[t.length-1].classList.add("foot-row"))}},tp.callbacks.editor.oninsertroc=function(e,t,s,o,l,a,n){const i="rows"===e,r=i?"column_hidden":"row_hidden",c="duplicate"===t,p=o+(n?l:0),d=i?tp.editor.options.columns.length:tp.editor.options.data.length,u={};for(let e=0;e<d;e++){const t=i?[e,p]:[p,e],s=tp.editor.options.meta[jspreadsheet.getColumnNameFromId(t)];s&&(c?u[e]=s:s[r]&&(u[e]=u[e]||{},u[e][r]=!0))}const b=Object.keys(u);if(!b.length)return;const h={};n||o++;for(let e=0;e<l;e++){const t=o+e;b.forEach((function(e){const s=i?[e,t]:[t,e];h[jspreadsheet.getColumnNameFromId(s)]=u[e]}))}tp.editor.setMeta(h),tp.editor.updateTable()},tp.callbacks.editor.onmove=function(){tp.helpers.editor.reselect(),tp.helpers.unsaved_changes.set()},tp.callbacks.editor.onsort=function(){tp.editor.updateTable(),tp.helpers.unsaved_changes.set()},tp.helpers.editor.insert_from_helper_textarea=function(){tp.editor.setValueFromCoords(tp.helpers.selection.columns[0],tp.helpers.selection.rows[0],this.value)},tp.callbacks.insert_link={},tp.callbacks.insert_link.open_dialog=function(t=null){const s=o("#textarea-insert-helper");s.value=tp.editor.options.data[tp.helpers.selection.rows[0]][tp.helpers.selection.columns[0]],t?(s.selectionStart=t.selectionStart,s.selectionEnd=t.selectionEnd):(s.selectionStart=s.value.length,s.selectionEnd=s.value.length);const l=jexcel.getColumnNameFromId([tp.helpers.selection.columns[0],tp.helpers.selection.rows[0]]);o("#link-modal-title").textContent=(0,e.sprintf)((0,e.__)("Insert Link into cell %1$s","tablepress"),l),wpLink.open("textarea-insert-helper"),jexcel.current=null},tp.callbacks.insert_image={},tp.callbacks.insert_image.open_dialog=function(t=null){const s=o("#textarea-insert-helper");s.value=tp.editor.options.data[tp.helpers.selection.rows[0]][tp.helpers.selection.columns[0]],t?(s.selectionStart=t.selectionStart,s.selectionEnd=t.selectionEnd):(s.selectionStart=s.value.length,s.selectionEnd=s.value.length),wp.media.editor.open("textarea-insert-helper",{frame:"post",state:"insert",title:wp.media.view.l10n.addMedia,multiple:!0});const l=jexcel.getColumnNameFromId([tp.helpers.selection.columns[0],tp.helpers.selection.rows[0]]);document.querySelector("#media-frame-title h1").textContent=(0,e.sprintf)((0,e.__)("Add media to cell %1$s","tablepress"),l),jexcel.current=null},tp.callbacks.advanced_editor={},tp.callbacks.advanced_editor.$textarea=o("#advanced-editor-content"),tp.callbacks.advanced_editor.open_dialog=function(t=null){tp.callbacks.advanced_editor.$textarea.value=tp.editor.options.data[tp.helpers.selection.rows[0]][tp.helpers.selection.columns[0]];const s=jexcel.getColumnNameFromId([tp.helpers.selection.columns[0],tp.helpers.selection.rows[0]]),l=(0,e.sprintf)((0,e.__)("Advanced Editor for cell %1$s","tablepress"),s);o("#advanced-editor-label").textContent=l,o("#link-modal-title").textContent=(0,e.sprintf)((0,e.__)("Insert Link into cell %1$s","tablepress"),s),jQuery("#advanced-editor").wpdialog({width:600,modal:!0,title:l,resizable:!1,closeOnEscape:!0,buttons:[{text:(0,e.__)("Cancel","tablepress"),class:"button button-cancel",click(){jQuery(this).wpdialog("close")}},{text:(0,e.__)("OK","tablepress"),class:"button button-primary button-ok",click:tp.callbacks.advanced_editor.confirm_save}]}),jexcel.current=null,t?(tp.callbacks.advanced_editor.$textarea.selectionStart=t.selectionStart,tp.callbacks.advanced_editor.$textarea.selectionEnd=t.selectionEnd):(tp.callbacks.advanced_editor.$textarea.selectionStart=tp.callbacks.advanced_editor.$textarea.value.length,tp.callbacks.advanced_editor.$textarea.selectionEnd=tp.callbacks.advanced_editor.$textarea.value.length),tp.callbacks.advanced_editor.$textarea.focus()},tp.callbacks.advanced_editor.confirm_save=function(){const e=tp.editor.options.data[tp.helpers.selection.rows[0]][tp.helpers.selection.columns[0]];tp.callbacks.advanced_editor.$textarea.value!==e&&tp.editor.setValueFromCoords(tp.helpers.selection.columns[0],tp.helpers.selection.rows[0],tp.callbacks.advanced_editor.$textarea.value),jQuery(this).wpdialog("close")},tp.callbacks.help_box={},tp.callbacks.help_box.open_dialog=function(t){const s=o(t.target.dataset.helpBox);jQuery(s).wpdialog({height:s.dataset.height,width:s.dataset.width,minWidth:260,modal:!0,closeOnEscape:!0,buttons:[{text:(0,e.__)("OK","tablepress"),class:"button button-ok",click(){jQuery(this).wpdialog("close")}}],open(){jQuery(this).next().find(".button-ok").trigger("focus")}})},tp.callbacks.table_preview={},tp.callbacks.table_preview.process=function(t){t.preventDefault();let l=o("#table-name").value;if(""===l.trim()&&(l=(0,e.__)("(no name)","tablepress")),tp.callbacks.table_preview.$dialog=jQuery("#table-preview").wpdialog({autoOpen:!1,width:window.innerWidth-80,height:window.innerHeight-80,modal:!0,title:(0,e.sprintf)((0,e.__)("Preview of table “%1$s” (ID %2$s)","tablepress"),l,tp.table.id),closeOnEscape:!0,buttons:[{text:(0,e.__)("OK","tablepress"),class:"button button-ok",click(){jQuery(this).wpdialog("close")}}]}),!tp.made_changes){const e=o("#table-preview-iframe");return e.src=t.target.href,e.removeAttribute("srcdoc"),void tp.callbacks.table_preview.$dialog.wpdialog("open")}tp.helpers.visibility.update();const a={action:"tablepress_preview_table",_ajax_nonce:tp.nonces.preview_table,tablepress:{id:tp.table.id,new_id:tp.table.new_id,name:o("#table-name").value,description:o("#table-description").value,data:JSON.stringify(tp.editor.options.data),options:JSON.stringify(tp.table.options),visibility:JSON.stringify(tp.table.visibility),number:{rows:tp.editor.options.data.length,columns:tp.editor.options.columns.length}}};t.target.parentNode.insertAdjacentHTML("beforeend",`<span id="spinner-table-preview" class="spinner-table-preview spinner is-active" title="${(0,e.__)("The Table Preview is being loaded …","tablepress")}"/>`),o(".button-show-preview").forEach((e=>e.classList.add("disabled"))),document.body.classList.add("wait"),fetch(ajaxurl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:(0,s.buildQueryString)(a)}).then((e=>{if(!e.ok)throw new Error(`There was a problem with the server, HTTP response code ${e.status} (${e.statusText}).`);return e.json()})).then((e=>{if(null==e||"-1"===e||void 0===e.success)throw new Error("The JSON data returned from the server is unclear or incomplete.");if(!0!==e.success)throw new Error("The preview could not be loaded.");tp.callbacks.table_preview.success(e)})).catch((e=>tp.callbacks.table_preview.error(e.message))).finally((()=>{o("#spinner-table-preview").remove(),o(".button-show-preview").forEach((e=>e.classList.remove("disabled"))),document.body.classList.remove("wait")}))},tp.callbacks.table_preview.success=function(e){const t=o("#table-preview-iframe");t.src="",t.srcdoc=`<!DOCTYPE html><html><head>${e.head_html}</head><body>${e.body_html}</body></html>`,tp.callbacks.table_preview.$dialog.wpdialog("open")},tp.callbacks.table_preview.error=function(t){t=(0,e.__)("Attention: Unfortunately, an error occurred.","tablepress")+" "+t;const s=`show-preview-${Date.now()}`;o("#spinner-table-preview").parentNode.insertAdjacentHTML("afterend",`<div id="${s}" class="ajax-alert notice notice-error"><p>${t}</p></div>`);const l=o(`#${s}`);l.offsetWidth,l.style.opacity=0,l.addEventListener("transitionend",(()=>l.remove()))},tp.callbacks.save_changes={},tp.callbacks.save_changes.process=function(t){if(!tp.helpers.options.validate_fields())return;tp.helpers.visibility.update();const l={action:"tablepress_save_table",_ajax_nonce:tp.nonces.edit_table,tablepress:{id:tp.table.id,new_id:tp.table.new_id,name:o("#table-name").value,description:o("#table-description").value,data:JSON.stringify(tp.editor.options.data),options:JSON.stringify(tp.table.options),visibility:JSON.stringify(tp.table.visibility),number:{rows:tp.editor.options.data.length,columns:tp.editor.options.columns.length}}};t.target.parentNode.insertAdjacentHTML("beforeend",`<span id="spinner-save-changes" class="spinner-save-changes spinner is-active" title="${(0,e.__)("Changes are being saved …","tablepress")}"/>`),o(".button-save-changes").forEach((e=>e.disabled=!0)),document.body.classList.add("wait"),fetch(ajaxurl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:(0,s.buildQueryString)(l)}).then((e=>{if(!e.ok)throw new Error(`There was a problem with the server, HTTP response code ${e.status} (${e.statusText}).`);return e.json()})).then((t=>{if(null==t||"-1"===t||void 0===t.success)throw new Error("The JSON data returned from the server is unclear or incomplete.");if(!0!==t.success){const s=(0,e.__)("These errors were encountered:","tablepress"),o=t.error_details?`</p><p>${s}</p><pre>${t.error_details}</pre><p>`:"";throw new Error(`The table could not be saved to the database properly.${o}`)}tp.callbacks.save_changes.success(t)})).catch((e=>tp.callbacks.save_changes.error(e.message))).finally((()=>{o("#spinner-save-changes").remove(),o(".button-save-changes").forEach((e=>e.disabled=!1)),document.body.classList.remove("wait")}))},tp.callbacks.save_changes.success=function(t){tp.table.id!==t.table_id&&window?.history?.pushState&&window.history.pushState("","",window.location.href.replace(/table_id=[0-9a-zA-Z-_]+/gi,`table_id=${t.table_id}`)),tp.table.id=t.table_id,tp.table.new_id=t.table_id,o("#table-id").value=t.table_id;const s=o("#table-information-shortcode");s&&(s.value=`[${tp.table.shortcode} id=${t.table_id} /]`),tp.nonces.edit_table=t.new_edit_nonce,tp.nonces.preview_table=t.new_preview_nonce,o(".button-show-preview").forEach((e=>{e.href=e.href.replace(/item=[a-zA-Z0-9_-]+/g,`item=${t.table_id}`).replace(/&_wpnonce=[a-z0-9]+/gi,`&_wpnonce=${t.new_preview_nonce}`)})),o("#last-modified").textContent=t.last_modified,o("#last-editor").textContent=t.last_editor,tp.helpers.unsaved_changes.unset();const l={};if(l.success_save=(0,e.__)("The table was saved successfully.","tablepress"),l.success_save_success_id_change=l.success_save+" "+(0,e.__)("The table ID was changed.","tablepress"),l.success_save_error_id_change=l.success_save+" "+(0,e.__)("The table ID could not be changed, probably because the new ID is already in use!","tablepress"),"success_save_error_id_change"===t.message&&t.error_details){const s=(0,e.__)("These errors were encountered:","tablepress");l.success_save_error_id_change+=`</p><p>${s}</p><pre>${t.error_details}</pre><p>`}const a=t.message.includes("error")?"error":"success";tp.callbacks.save_changes.after_saving_notice(a,l[t.message])},tp.callbacks.save_changes.error=function(t){t=(0,e.__)("Attention: Unfortunately, an error occurred.","tablepress")+" "+t,tp.callbacks.save_changes.after_saving_notice("error",t)},tp.callbacks.save_changes.after_saving_notice=function(e,t){const s=`save-changes-${Date.now()}`;o("#spinner-save-changes").parentNode.insertAdjacentHTML("afterend",`<div id="${s}" class="ajax-alert notice notice-${e}"><p>${t}</p></div>`);const l=o(`#${s}`);l.offsetWidth,l.style.opacity=0,l.addEventListener("transitionend",(()=>l.remove()))},tp.callbacks.screen_options={},tp.callbacks.screen_options.update=function(e){if(e.target)return"table_editor_line_clamp"===e.target.id?(tp.editor.el.style.setProperty("--table-editor-line-clamp",parseInt(e.target.value,10)),void tp.editor.updateCornerPosition()):"table_editor_column_width"===e.target.id?(tp.screen_options.table_editor_column_width=parseInt(e.target.value,10),tp.screen_options.table_editor_column_width=Math.max(tp.screen_options.table_editor_column_width,30),tp.screen_options.table_editor_column_width=Math.min(tp.screen_options.table_editor_column_width,9999),tp.editor.colgroup.forEach((e=>e.setAttribute("width",tp.screen_options.table_editor_column_width))),void tp.editor.updateCornerPosition()):void 0},tp.callbacks.screen_options.set_was_changed=function(e){e.target&&(e.target.was_changed=!0)},tp.callbacks.screen_options.save=function(t){if(!t.target)return;if(!t.target.was_changed)return;t.target.was_changed=!1;const l={action:"tablepress_save_screen_options",_ajax_nonce:tp.nonces.screen_options,tablepress:{[t.target.id]:parseInt(t.target.value,10)}};t.target.parentNode.insertAdjacentHTML("beforeend",`<span id="spinner-save-changes" class="spinner-save-changes spinner is-active" title="${(0,e.__)("Changes are being saved …","tablepress")}"/>`),document.body.classList.add("wait"),fetch(ajaxurl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:(0,s.buildQueryString)(l)}).finally((()=>{o("#spinner-save-changes").remove(),document.body.classList.remove("wait")}))},tp.callbacks.table_id=tp.callbacks.table_id||{},tp.callbacks.table_id.sanitize=function(){this.value=this.value.replace(/[^0-9a-zA-Z-_]/g,"")},tp.callbacks.table_id.change=function(){if(""===this.value||"0"===this.value)return window.alert((0,e.__)("This table ID is invalid. Please enter a different table ID.","tablepress")),this.value=tp.table.new_id,this.focus(),void this.select();if(!window.confirm((0,e.__)("Do you really want to change the Table ID? All blocks and Shortcodes for this table in your posts and pages will have to be adjusted!","tablepress")))return void(this.value=tp.table.new_id);tp.table.new_id=this.value;const t=o("#table-information-shortcode");t&&(t.value=`[${tp.table.shortcode} id=${tp.table.new_id} /]`,t.focus(),t.select()),tp.helpers.unsaved_changes.set()},tp.callbacks.insert_duplicate=function(e,t,s="before"){const o="rows"===t,l=o?tp.editor.insertRow:tp.editor.insertColumn,a=o?tp.editor.getRowData:tp.editor.getColumnData,n="duplicate"===e;tp.editor.options[o?"oninsertrow":"oninsertcolumn"]=tp.callbacks.editor.oninsertroc.bind(null,t,e),tp.helpers.selection[t].forEach((function(e,t){const o=e+t,i=n?a(o):1;l(i,o,"before"===s)})),tp.helpers.unsaved_changes.set();const i=tp.helpers.selection[t].length;i>1&&tp.editor.updateSelectionFromCoords(tp.helpers.selection.columns[0],tp.helpers.selection.rows[0],o?tp.helpers.selection.columns[tp.helpers.selection.columns.length-1]:tp.helpers.selection.columns[tp.helpers.selection.columns.length-1]+i,o?tp.helpers.selection.rows[tp.helpers.selection.rows.length-1]+i:tp.helpers.selection.rows[tp.helpers.selection.rows.length-1])},tp.callbacks.remove=function(e){const t="rows"===e,s=t?tp.editor.options.columns.length:tp.editor.options.data.length,o=t?tp.editor.options.data.length-1:tp.editor.options.columns.length-1;if(tp.editor.options.meta&&tp.helpers.selection[e].forEach((function(e){for(let o=0;o<s;o++){const s=t?[o,e]:[e,o];delete tp.editor.options.meta[jspreadsheet.getColumnNameFromId(s)]}})),(t?tp.editor.deleteRow:tp.editor.deleteColumn)(tp.helpers.selection[e][0],tp.helpers.selection[e].length),tp.helpers.unsaved_changes.set(),o===tp.helpers.selection[e][tp.helpers.selection[e].length-1]){const e=t?tp.helpers.selection.columns[0]:tp.helpers.selection.columns[0]-1,s=t?tp.helpers.selection.rows[0]-1:tp.helpers.selection.rows[0];tp.editor.updateSelectionFromCoords(e,s,e,s)}},tp.callbacks.append=function(e,t){const s="rows"===e,o=s?tp.editor.insertRow:tp.editor.insertColumn;tp.editor.options[s?"oninsertrow":"oninsertcolumn"]=tp.callbacks.editor.oninsertroc.bind(null,e,"append"),o(t),tp.helpers.unsaved_changes.set()},tp.callbacks.move=function(e,t){const s="rows"===t;let o=tp.helpers.selection[t],l=-1;if("down"===e||"right"===e)o=o.slice().reverse(),l=1;else if("top"===e||"first"===e)l=-o[0];else if("bottom"===e||"last"===e){o=o.slice().reverse();const e="rows"===t?tp.editor.options.data.length-1:tp.editor.options.columns.length-1;l=e-o[0]}if(0===l)return;const a=s?tp.editor.moveRow:tp.editor.moveColumn;o.forEach((e=>a(e,e+l))),tp.helpers.unsaved_changes.set(),tp.editor.updateSelectionFromCoords(s?tp.helpers.selection.columns[0]:tp.helpers.selection.columns[0]+l,s?tp.helpers.selection.rows[0]+l:tp.helpers.selection.rows[0],s?tp.helpers.selection.columns[tp.helpers.selection.columns.length-1]:tp.helpers.selection.columns[tp.helpers.selection.columns.length-1]+l,s?tp.helpers.selection.rows[tp.helpers.selection.rows.length-1]+l:tp.helpers.selection.rows[tp.helpers.selection.rows.length-1])},tp.callbacks.sort=function(e){tp.editor.orderBy(tp.helpers.selection.columns[0],"desc"===e)},tp.callbacks.hide_unhide=function(e,t){const s="rows"===t,o=s?"row_hidden":"column_hidden",l=s?tp.editor.options.columns.length:tp.editor.options.data.length,a="hide"===e,n={};tp.helpers.selection[t].forEach((function(e){for(let t=0;t<l;t++){const l=s?[t,e]:[e,t],i=jspreadsheet.getColumnNameFromId(l);n[i]={},n[i][o]=a}})),tp.editor.setMeta(n),tp.helpers.unsaved_changes.set(),tp.editor.updateTable()},tp.callbacks.merge_cells=function(){const e=tp.helpers.selection.columns[0],t=tp.helpers.selection.rows[0],s=tp.helpers.selection.columns.length,o=tp.helpers.selection.rows.length;for(let s=1;s<o;s++)tp.editor.setValueFromCoords(e,t+s,"#rowspan#");for(let o=1;o<s;o++)tp.editor.setValueFromCoords(e+o,t,"#colspan#");for(let l=1;l<o;l++)for(let o=1;o<s;o++)tp.editor.setValueFromCoords(e+o,t+l,"#span#");tp.helpers.unsaved_changes.set()},tp.callbacks.keyboard_shortcuts=function(e){let t="",s="",l="";if((e.ctrlKey||e.metaKey)&&(80===e.keyCode?t="show-preview":83===e.keyCode?t="save-changes":76===e.keyCode?t="insert_link":73===e.keyCode?t="insert_image":69===e.keyCode?t="advanced_editor":e.shiftKey&&e.altKey&&38===e.keyCode?(t="move",s="top",l="rows"):e.shiftKey&&e.altKey&&40===e.keyCode?(t="move",s="bottom",l="rows"):e.shiftKey&&e.altKey&&37===e.keyCode?(t="move",s="first",l="columns"):e.shiftKey&&e.altKey&&39===e.keyCode?(t="move",s="last",l="columns"):e.shiftKey&&38===e.keyCode?(t="move",s="up",l="rows"):e.shiftKey&&40===e.keyCode?(t="move",s="down",l="rows"):e.shiftKey&&37===e.keyCode?(t="move",s="left",l="columns"):e.shiftKey&&39===e.keyCode&&(t="move",s="right",l="columns")),"save-changes"===t||"show-preview"===t)document.activeElement.blur(),document.querySelector(`#tablepress_edit-buttons-2-submit .button-${t}`).click(),e.preventDefault();else if("insert_link"===t||"insert_image"===t||"advanced_editor"===t){if(o("#table-editor").contains(document.activeElement)){const e="TEXTAREA"===document.activeElement.tagName?document.activeElement:null;tp.callbacks[t].open_dialog(e)}e.preventDefault()}else"move"===t&&(o("#table-editor").contains(document.activeElement)&&"TEXTAREA"!==document.activeElement.tagName&&tp.helpers.move_allowed(l,s)&&tp.callbacks.move(s,l),e.stopImmediatePropagation())},tp.editor=jspreadsheet(o("#table-editor"),{data:tp.table.data,meta:tp.helpers.visibility.load(),wordWrap:!0,rowDrag:!0,rowResize:!0,columnSorting:!0,columnDrag:!0,columnResize:!0,defaultColWidth:tp.screen_options.table_editor_column_width,defaultColAlign:"left",parseFormulas:!1,allowExport:!1,allowComments:!1,allowManualInsertRow:!1,allowManualInsertColumn:!1,about:!1,secureFormulas:!1,detachForUpdates:!0,onselection:tp.callbacks.editor.onselection,updateTable:tp.callbacks.editor.onupdatetable,contextMenu:t=>{const s=tp.editor.options.data.length,o=tp.editor.options.columns.length,l=tp.helpers.selection.rows.length,a=tp.helpers.selection.columns.length,n=window?.navigator?.platform?.includes("Mac"),i=n?(0,e._x)("⌘","keyboard shortcut modifier key on a Mac keyboard","tablepress"):(0,e._x)("Ctrl+","keyboard shortcut modifier key on a non-Mac keyboard","tablepress"),r=n?(0,e._x)("⌥","keyboard shortcut option key on a Mac keyboard","tablepress"):(0,e._x)("Alt+","keyboard shortcut Alt key on a non-Mac keyboard","tablepress"),c={text:""};return tp.helpers.visibility.update(),[{title:(0,e.__)("Undo","tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$sZ","keyboard shortcut for Undo","tablepress"),i),onclick:t.undo,disabled:-1===t.historyIndex},{title:(0,e.__)("Redo","tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$sY","keyboard shortcut for Redo","tablepress"),i),onclick:t.redo,disabled:t.historyIndex===t.history.length-1},{type:"divisor"},{title:(0,e.__)("Cut","tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$sX","keyboard shortcut for Cut","tablepress"),i),onclick(){if("TEXTAREA"===document.activeElement.tagName&&document.activeElement.selectionStart!==document.activeElement.selectionEnd){document.execCommand("copy");const e=document.activeElement.selectionStart;document.activeElement.value=document.activeElement.value.slice(0,document.activeElement.selectionStart)+document.activeElement.value.slice(document.activeElement.selectionEnd),document.activeElement.selectionEnd=e}else t.copy(!0),t.setValue(t.highlighted,"")}},{title:(0,e.__)("Copy","tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$sC","keyboard shortcut for Copy","tablepress"),i),onclick(){"TEXTAREA"===document.activeElement.tagName&&document.activeElement.selectionStart!==document.activeElement.selectionEnd?document.execCommand("copy"):t.copy(!0)}},{title:(0,e.__)("Paste","tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$sV","keyboard shortcut for Paste","tablepress"),i),onclick(){"TEXTAREA"===document.activeElement.tagName?window.navigator.clipboard.readText().then((e=>{if(e){const t=document.activeElement.selectionStart+e.length;document.activeElement.value=document.activeElement.value.slice(0,document.activeElement.selectionStart)+e+document.activeElement.value.slice(document.activeElement.selectionEnd),document.activeElement.selectionEnd=t}})):t.selectedCell&&window.navigator.clipboard.readText().then((e=>{e&&t.paste(t.selectedCell[0],t.selectedCell[1],e)}))},disabled:!window?.navigator?.clipboard?.readText,tooltip:window?.navigator?.clipboard?.readText?"":(0,e.__)("Your browser does not allow pasting via the context menu. Use the keyboard shortcut instead.","tablepress")},{type:"divisor"},{title:(0,e.__)("Insert Link","tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$sL","keyboard shortcut for Insert Link","tablepress"),i),onclick:tp.callbacks.insert_link.open_dialog.bind(null,"TEXTAREA"===document.activeElement.tagName?document.activeElement:null)},{title:(0,e.__)("Insert Image","tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$sI","keyboard shortcut for Insert Image","tablepress"),i),onclick:tp.callbacks.insert_image.open_dialog.bind(null,"TEXTAREA"===document.activeElement.tagName?document.activeElement:null)},{title:(0,e.__)("Advanced Editor","tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$sE","keyboard shortcut for Advanced Editor","tablepress"),i),onclick:tp.callbacks.advanced_editor.open_dialog.bind(null,"TEXTAREA"===document.activeElement.tagName?document.activeElement:null)},{type:"divisor"},{title:(0,e.__)("Duplicate …","tablepress"),submenu:[{title:(0,e._n)("Duplicate row","Duplicate rows",l,"tablepress"),onclick:tp.callbacks.insert_duplicate.bind(null,"duplicate","rows")},{title:(0,e._n)("Duplicate column","Duplicate columns",a,"tablepress"),onclick:tp.callbacks.insert_duplicate.bind(null,"duplicate","columns")}]},{title:(0,e.__)("Insert …","tablepress"),submenu:[{title:(0,e._n)("Insert row above","Insert rows above",l,"tablepress"),onclick:tp.callbacks.insert_duplicate.bind(null,"insert","rows","before")},{title:(0,e._n)("Insert row below","Insert rows below",l,"tablepress"),onclick:tp.callbacks.insert_duplicate.bind(null,"insert","rows","after")},{title:(0,e._n)("Insert column on the left","Insert columns on the left",a,"tablepress"),onclick:tp.callbacks.insert_duplicate.bind(null,"insert","columns","before")},{title:(0,e._n)("Insert column on the right","Insert columns on the right",a,"tablepress"),onclick:tp.callbacks.insert_duplicate.bind(null,"insert","columns","after")}]},{title:(0,e.__)("Append …","tablepress"),submenu:[{title:(0,e.__)("Append row","tablepress"),onclick:tp.callbacks.append.bind(null,"rows",1)},{title:(0,e.__)("Append column","tablepress"),onclick:tp.callbacks.append.bind(null,"columns",1)}]},{title:(0,e.__)("Delete …","tablepress"),submenu:[{title:(0,e._n)("Delete row","Delete rows",l,"tablepress"),onclick:tp.callbacks.remove.bind(null,"rows"),disabled:s===l,tooltip:s===l?(0,e.__)("This option is disabled.","tablepress")+" "+(0,e.__)("You can not delete all table rows!","tablepress"):""},{title:(0,e._n)("Delete column","Delete columns",a,"tablepress"),onclick:tp.callbacks.remove.bind(null,"columns"),disabled:o===a,tooltip:o===a?(0,e.__)("This option is disabled.","tablepress")+" "+(0,e.__)("You can not delete all table columns!","tablepress"):""}]},{type:"divisor"},{title:(0,e.__)("Move …","tablepress"),submenu:[{title:(0,e._n)("Move row up","Move rows up",l,"tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$s⇧↑","keyboard shortcut for Move up","tablepress"),i),onclick:tp.callbacks.move.bind(null,"up","rows"),disabled:!tp.helpers.move_allowed("rows","up")},{title:(0,e._n)("Move row down","Move rows down",l,"tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$s⇧↓","keyboard shortcut for Move down","tablepress"),i),onclick:tp.callbacks.move.bind(null,"down","rows"),disabled:!tp.helpers.move_allowed("rows","down")},{title:(0,e._n)("Move column left","Move columns left",a,"tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$s⇧←","keyboard shortcut for Move left","tablepress"),i),onclick:tp.callbacks.move.bind(null,"left","columns"),disabled:!tp.helpers.move_allowed("columns","left")},{title:(0,e._n)("Move column right","Move columns right",a,"tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$s⇧→","keyboard shortcut for Move right","tablepress"),i),onclick:tp.callbacks.move.bind(null,"right","columns"),disabled:!tp.helpers.move_allowed("columns","right")},{type:"divisor"},{title:(0,e._n)("Move row to the top","Move rows to the top",l,"tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$s%2$s⇧↑","keyboard shortcut for Move to the top","tablepress"),i,r),onclick:tp.callbacks.move.bind(null,"top","rows"),disabled:!tp.helpers.move_allowed("rows","top")},{title:(0,e._n)("Move row to the bottom","Move rows to the bottom",l,"tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$s%2$s⇧↓","keyboard shortcut for Move to the bottom","tablepress"),i,r),onclick:tp.callbacks.move.bind(null,"bottom","rows"),disabled:!tp.helpers.move_allowed("rows","bottom")},{title:(0,e._n)("Move column to first","Move columns to first",a,"tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$s%2$s⇧←","keyboard shortcut for Move to first","tablepress"),i,r),onclick:tp.callbacks.move.bind(null,"first","columns"),disabled:!tp.helpers.move_allowed("columns","first")},{title:(0,e._n)("Move column to last","Move columns to last",a,"tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$s%2$s⇧→","keyboard shortcut for Move to last","tablepress"),i,r),onclick:tp.callbacks.move.bind(null,"last","columns"),disabled:!tp.helpers.move_allowed("columns","last")}]},{title:(0,e.__)("Sort by column …","tablepress"),submenu:[{title:(0,e.__)("Sort by column ascending","tablepress"),onclick:tp.callbacks.sort.bind(null,"asc"),disabled:1!==a,tooltip:1!==a?(0,e.__)("This option is disabled because more than one column was selected.","tablepress"):""},{title:(0,e.__)("Sort by column descending","tablepress"),onclick:tp.callbacks.sort.bind(null,"desc"),disabled:1!==a,tooltip:1!==a?(0,e.__)("This option is disabled because more than one column was selected.","tablepress"):""}]},{type:"divisor"},{title:(0,e.__)("Hide/Show …","tablepress"),submenu:[{title:(0,e._n)("Hide row","Hide rows",l,"tablepress"),onclick:tp.callbacks.hide_unhide.bind(null,"hide","rows"),disabled:!tp.helpers.visibility.selection_contains("rows",1),tooltip:tp.helpers.visibility.selection_contains("rows",1)?"":(0,e.__)("This option is disabled because no visible rows were selected.","tablepress")},{title:(0,e._n)("Hide column","Hide columns",a,"tablepress"),onclick:tp.callbacks.hide_unhide.bind(null,"hide","columns"),disabled:!tp.helpers.visibility.selection_contains("columns",1),tooltip:tp.helpers.visibility.selection_contains("columns",1)?"":(0,e.__)("This option is disabled because no visible columns were selected.","tablepress")},{title:(0,e._n)("Show row","Show rows",l,"tablepress"),onclick:tp.callbacks.hide_unhide.bind(null,"unhide","rows"),disabled:!tp.helpers.visibility.selection_contains("rows",0),tooltip:tp.helpers.visibility.selection_contains("rows",0)?"":(0,e.__)("This option is disabled because no hidden rows were selected.","tablepress")},{title:(0,e._n)("Show column","Show columns",a,"tablepress"),onclick:tp.callbacks.hide_unhide.bind(null,"unhide","columns"),disabled:!tp.helpers.visibility.selection_contains("columns",0),tooltip:tp.helpers.visibility.selection_contains("columns",0)?"":(0,e.__)("This option is disabled because no hidden columns were selected.","tablepress")}]},{type:"divisor"},{title:(0,e.__)("Combine/Merge cells","tablepress"),onclick:tp.callbacks.merge_cells,disabled:1===l&&1===a||!tp.helpers.cell_merge_allowed("no-alert"),tooltip:1===l&&1===a||!tp.helpers.cell_merge_allowed("no-alert",c)?(0,e.__)("This option is disabled.","tablepress")+" "+c.text:""}]},sorting:tp.helpers.editor.sorting,onmoverow:tp.callbacks.editor.onmove,onmovecolumn:tp.callbacks.editor.onmove,onblur:tp.helpers.editor.reselect,onload:tp.helpers.editor.reselect,onchange:tp.helpers.unsaved_changes.set,onsort:tp.callbacks.editor.onsort}),tp.helpers.options.load(),o("#tablepress-page").addEventListener("click",(e=>{e.target&&(e.target.matches(".button-show-preview")?tp.callbacks.table_preview.process(e):e.target.matches(".button-save-changes")?tp.callbacks.save_changes.process(e):e.target.matches(".button-show-help-box")&&tp.callbacks.help_box.open_dialog(e))})),o("#tablepress-manipulation-controls").addEventListener("click",(t=>{if(t.target)if(t.target.matches(".button-append")){const s=t.target.dataset.type,l=o(`#${s}-append-number`),a=parseInt(l.value,10);if(isNaN(a)||a<1||a>99999){const s="rows"===t.target.dataset.type?(0,e.__)("The value for the number of rows is invalid!","tablepress"):(0,e.__)("The value for the number of columns is invalid!","tablepress");return window.alert(s),l.focus(),void l.select()}tp.callbacks.append(s,a)}else if("button-insert-link"!==t.target.id)if("button-insert-image"!==t.target.id)if("button-advanced-editor"!==t.target.id)if(t.target.matches(".button-insert-duplicate"))tp.callbacks.insert_duplicate(t.target.dataset.action,t.target.dataset.type);else{if(t.target.matches(".button-move"))return tp.helpers.move_allowed(t.target.dataset.type,t.target.dataset.direction)?void tp.callbacks.move(t.target.dataset.direction,t.target.dataset.type):void window.alert((0,e.__)("You can not do this move, because you reached the border of the table.","tablepress"));if(t.target.matches(".button-remove")){const s="rows"===t.target.dataset.type;if((s?tp.editor.options.data.length:tp.editor.options.columns.length)===tp.helpers.selection[t.target.dataset.type].length){const t=s?(0,e.__)("You can not delete all table rows!","tablepress"):(0,e.__)("You can not delete all table columns!","tablepress");return void window.alert(t)}tp.callbacks.remove(t.target.dataset.type)}else t.target.matches(".button-merge-unmerge")?tp.helpers.cell_merge_allowed("alert")&&tp.callbacks.merge_cells():t.target.matches(".button-hide-unhide")&&tp.callbacks.hide_unhide(t.target.dataset.action,t.target.dataset.type)}else tp.callbacks.advanced_editor.open_dialog();else tp.callbacks.insert_image.open_dialog();else tp.callbacks.insert_link.open_dialog()}));const l=o("#table-id");l.addEventListener("input",tp.callbacks.table_id.sanitize),l.addEventListener("change",tp.callbacks.table_id.change);const a=o("#table-information-shortcode");a&&a.addEventListener("focus",(function(){this.select()})),jQuery("#textarea-insert-helper").on("change",tp.helpers.editor.insert_from_helper_textarea),["#table-name","#table-description"].forEach((e=>o(e).addEventListener("change",tp.helpers.unsaved_changes.set))),(0,t.applyFilters)("tablepress.optionsMetaBoxes",["#tablepress_edit-table-options","#tablepress_edit-datatables-features"]).forEach((e=>o(e).addEventListener("change",tp.helpers.options.change))),document.querySelectorAll("#tablepress-body .button-module-help").forEach((e=>e.closest(".postbox").querySelector(".handle-actions").prepend(e)));const n=o("#tablepress-screen-options");n.addEventListener("input",tp.callbacks.screen_options.update),n.addEventListener("change",tp.callbacks.screen_options.set_was_changed),n.addEventListener("focusout",tp.callbacks.screen_options.save),window.addEventListener("keydown",tp.callbacks.keyboard_shortcuts,!0);const i=window?.navigator?.platform?.includes("Mac")?(0,e._x)("⌘","keyboard shortcut modifier key on a Mac keyboard","tablepress"):(0,e._x)("Ctrl+","keyboard shortcut modifier key on a non-Mac keyboard","tablepress");document.querySelectorAll(".button[data-shortcut]").forEach((t=>{const s=(0,e.sprintf)(t.dataset.shortcut,i);t.title=(0,e.sprintf)((0,e.__)("Keyboard Shortcut: %s","tablepress"),s)})),jQuery((function(){jQuery("#wp-link").on("focus","input",(function(e){e.stopPropagation()})),jQuery("body").on("focus",".media-modal .media-frame-content input, .media-modal .media-frame-content textarea",(function(e){e.stopPropagation()}))}))}();
\ No newline at end of file
+!function(){"use strict";var e=window.wp.i18n,t=window.wp.hooks,s=window.wp.url;const o=e=>"#"===e[0]?document.getElementById(e.slice(1)):document.querySelectorAll(e);window.tp=window.tp||{},tp.made_changes=!1,tp.helpers=tp.helpers||{},tp.callbacks=tp.callbacks||{},tp.helpers.selection=tp.helpers.selection||{rows:[0],columns:[0]},tp.helpers.unsaved_changes=tp.helpers.unsaved_changes||{},tp.helpers.unsaved_changes.unload_dialog=function(e){e.preventDefault(),e.returnValue=""},tp.helpers.unsaved_changes.set=function(){tp.made_changes||(tp.made_changes=!0,window.addEventListener("beforeunload",tp.helpers.unsaved_changes.unload_dialog))},tp.helpers.unsaved_changes.unset=function(){tp.made_changes=!1,window.removeEventListener("beforeunload",tp.helpers.unsaved_changes.unload_dialog)},tp.helpers.options=tp.helpers.options||{},tp.helpers.options.load=function(){Object.keys(tp.table.options).forEach((function(e){if("last_editor"===e)return;if(""===(e=(0,t.applyFilters)("tablepress.optionsLoad",e)))return;let s=o(`#option-${e}`);s||(s=o(`#option-${e}-${tp.table.options[e]}`)),s&&(s instanceof HTMLInputElement&&"checkbox"===s.type?s.checked=tp.table.options[e]:s instanceof HTMLInputElement&&"radio"===s.type?s.checked=!0:s.value=tp.table.options[e])})),tp.table.options.use_datatables&&tp.helpers.editor.has_merged_cells()&&(tp.table.options.use_datatables=!1,o("#option-use_datatables").checked=!1),tp.helpers.options.check_dependencies()},tp.helpers.options.change=function(s){if(!s.target)return;const l=s.target.name||"";if(""===l)return;const n=s.target instanceof HTMLInputElement&&"checkbox"===s.target.type?"checked":"value";tp.table.options[l]=s.target[n],s.target instanceof HTMLInputElement&&"number"===s.target.type&&(tp.table.options[l]=parseInt(tp.table.options[l],10)),"use_datatables"===l&&tp.table.options.use_datatables&&tp.helpers.editor.has_merged_cells()&&(tp.table.options.use_datatables=!1,o("#option-use_datatables").checked=!1,window.alert((0,e.__)("You can not enable the Table Features for Site Visitors, because your table contains combined/merged cells.","tablepress"))),(0,t.doAction)("tablepress.optionsChange",l,n,s),tp.helpers.options.check_dependencies(),tp.helpers.unsaved_changes.set(),tp.editor.updateTable()},tp.helpers.options.check_dependencies=function(){o("#option-use_datatables").disabled=!tp.table.options.table_head,o("#notice-datatables-head-row").style.display=tp.table.options.table_head?"none":"block",o("#option-print_name_position").disabled=!tp.table.options.print_name,o("#option-print_description_position").disabled=!tp.table.options.print_description;const e=tp.table.options.use_datatables&&tp.table.options.table_head;o("#tablepress_edit-datatables-features").querySelectorAll(":scope input:not(#option-use_datatables), :scope textarea").forEach((t=>t.disabled=!e));const s=e&&tp.table.options.datatables_paginate;o("#option-datatables_lengthchange").disabled=!s,o("#option-datatables_paginate_entries").disabled=!s,(0,t.doAction)("tablepress.optionsCheckDependencies")},tp.helpers.options.validate_fields=function(){if(tp.table.options.datatables_paginate&&(isNaN(tp.table.options.datatables_paginate_entries)||tp.table.options.datatables_paginate_entries<1||tp.table.options.datatables_paginate_entries>9999)){window.alert((0,e.sprintf)((0,e.__)("The entered value in the “%1$s” field is invalid.","tablepress"),(0,e.__)("Pagination Entries","tablepress")));const t=o("#option-datatables_paginate_entries");return t.focus(),t.select(),!1}if(/[^A-Za-z0-9- _:]/.test(tp.table.options.extra_css_classes)){window.alert((0,e.sprintf)((0,e.__)("The entered value in the “%1$s” field is invalid.","tablepress"),(0,e.__)("Extra CSS Classes","tablepress")));const t=o("#option-extra_css_classes");return t.focus(),t.select(),!1}return(0,t.applyFilters)("tablepress.optionsValidateFields",!0)},tp.helpers.visibility=tp.helpers.visibility||{},tp.helpers.visibility.load=function(){const e=tp.table.visibility.rows.length,t=tp.table.visibility.columns.length,s={};for(let o=0;o<e;o++)if(1!==tp.table.visibility.rows[o])for(let e=0;e<t;e++){const t=jspreadsheet.getColumnNameFromId([e,o]);s[t]=s[t]||{},s[t].row_hidden=!0}for(let o=0;o<t;o++)if(1!==tp.table.visibility.columns[o])for(let t=0;t<e;t++){const e=jspreadsheet.getColumnNameFromId([o,t]);s[e]=s[e]||{},s[e].column_hidden=!0}return s},tp.helpers.visibility.update=function(){tp.table.visibility.rows=[];for(let e=0;e<tp.editor.options.data.length;e++)tp.table.visibility.rows[e]=1;tp.table.visibility.columns=[];for(let e=0;e<tp.editor.options.columns.length;e++)tp.table.visibility.columns[e]=1;Object.keys(tp.editor.options.meta).forEach((function(e){const t=jspreadsheet.getIdFromColumnName(e,!0);1===tp.table.visibility.rows[t[1]]&&tp.editor.options.meta[e].row_hidden&&(tp.table.visibility.rows[t[1]]=0),1===tp.table.visibility.columns[t[0]]&&tp.editor.options.meta[e].column_hidden&&(tp.table.visibility.columns[t[0]]=0)}))},tp.helpers.visibility.selection_contains=function(e,t){return tp.helpers.selection[e].some((s=>tp.table.visibility[e][s]===t))},tp.helpers.move_allowed=function(e,t){let s=tp.helpers.selection[e][0],o=0;return"down"!==t&&"right"!==t&&"bottom"!==t&&"last"!==t||(s=tp.helpers.selection[e][tp.helpers.selection[e].length-1],o="rows"===e?tp.editor.options.data.length-1:tp.editor.options.columns.length-1),o!==s},tp.helpers.cell_merge_allowed=function(t,s={}){const o="alert"===t;if(tp.table.options.table_head&&tp.table.options.use_datatables)return s.text=(0,e.sprintf)((0,e.__)("You can not combine these cells, because the “%1$s” checkbox in the “%2$s” section is checked.","tablepress"),(0,e.__)("Enable Visitor Features","tablepress"),(0,e.__)("Table Features for Site Visitors","tablepress"))+" "+(0,e.__)("The Table Features for Site Visitors are not compatible with merged cells.","tablepress"),o&&window.alert(s.text),!1;const l=tp.helpers.selection.rows[0],n=tp.helpers.selection.rows[tp.helpers.selection.rows.length-1];if(tp.table.options.table_head&&0===l&&n>0)return s.text=(0,e.sprintf)((0,e.__)("You can not combine these cells, because the “%1$s” checkbox in the “%2$s” section is checked.","tablepress"),(0,e.__)("Table Head Row","tablepress"),(0,e.__)("Table Options","tablepress")),o&&window.alert(s.text),!1;const a=tp.editor.options.data.length-1;return!(tp.table.options.table_foot&&a===n&&l<a&&(s.text=(0,e.sprintf)((0,e.__)("You can not combine these cells, because the “%1$s” checkbox in the “%2$s” section is checked.","tablepress"),(0,e.__)("Table Foot Row","tablepress"),(0,e.__)("Table Options","tablepress")),o&&window.alert(s.text),1))},tp.helpers.editor=tp.helpers.editor||{},tp.helpers.editor.reselect=function(e,t){void 0===t&&(t=tp.editor),t.updateSelectionFromCoords(tp.helpers.selection.columns[0],tp.helpers.selection.rows[0],tp.helpers.selection.columns[tp.helpers.selection.columns.length-1],tp.helpers.selection.rows[tp.helpers.selection.rows.length-1])},tp.helpers.editor.has_merged_cells=function(){const e=tp.editor.options.data.length,t=tp.editor.options.columns.length;for(let s=1;s<e;s++)for(let e=1;e<t;e++)if("#rowspan#"===tp.editor.options.data[s][e]||"#colspan#"===tp.editor.options.data[s][e])return!0;return!1},tp.helpers.editor.sorting=function(e){return e=e?-1:1,function(t,s){return e*((e,t)=>{const s=/(^([+\-]?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?(?=\D|\s|$))|^0x[\da-fA-F]+$|\d+)/g,o=/^\s+|\s+$/g,l=/\s+/g,n=/^0x[0-9a-f]+$/i,a=/^0/,i=e.replace(o,"")||"",r=t.replace(o,"")||"",c=i.replace(s,"\0$1\0").replace(/\0$/,"").replace(/^\0/,"").split("\0"),p=r.replace(s,"\0$1\0").replace(/\0$/,"").replace(/^\0/,"").split("\0"),d=parseInt(i.match(n),16)||1!==c.length&&Date.parse(i),b=parseInt(r.match(n),16)||d&&r.match(/(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/)&&Date.parse(r)||null,u=(e,t)=>(!e.match(a)||1===t)&&parseFloat(e)||e.replace(l," ").replace(o,"")||0;if(b){if(d<b)return-1;if(d>b)return 1}for(let e=0,t=c.length,s=p.length,o=Math.max(t,s);e<o;e++){const o=u(c[e]||"",t),l=u(p[e]||"",s);if(isNaN(o)!==isNaN(l))return isNaN(o)?1:-1;if(/[^\x00-\x80]/.test(o+l)&&o.localeCompare){const e=o.localeCompare(l);return e/Math.abs(e)}if(o<l)return-1;if(o>l)return 1}return 0})(t[1],s[1])}},tp.callbacks.editor=tp.callbacks.editor||{},tp.callbacks.editor.onselection=function(e,t,s,o,l){tp.helpers.selection={rows:[],columns:[]};for(let e=s;e<=l;e++)tp.helpers.selection.rows.push(e);for(let e=t;e<=o;e++)tp.helpers.selection.columns.push(e)},tp.callbacks.editor.onupdatetable=function(e,t,s,o,l,n,a){const i=e.jspreadsheet.options.meta[a];if(t.classList.toggle("column-hidden",Boolean(i?.column_hidden)),0===s&&(t.parentNode.classList.toggle("row-hidden",Boolean(i?.row_hidden)),t.parentNode.classList.remove("head-row","foot-row"),o===e.jspreadsheet.rows.length-1)){const t=e.jspreadsheet.content.querySelectorAll(":scope tbody tr:not(.row-hidden)");1<t.length&&(tp.table.options.table_head&&t[0].classList.add("head-row"),tp.table.options.table_foot&&t[t.length-1].classList.add("foot-row"))}},tp.callbacks.editor.oninsertroc=function(e,t,s,o,l,n,a){const i="rows"===e,r=i?"column_hidden":"row_hidden",c="duplicate"===t,p=o+(a?l:0),d=i?tp.editor.options.columns.length:tp.editor.options.data.length,b={};for(let e=0;e<d;e++){const t=i?[e,p]:[p,e],s=tp.editor.options.meta[jspreadsheet.getColumnNameFromId(t)];s&&(c?b[e]=s:s[r]&&(b[e]=b[e]||{},b[e][r]=!0))}const u=Object.keys(b);if(!u.length)return;const h={};a||o++;for(let e=0;e<l;e++){const t=o+e;u.forEach((function(e){const s=i?[e,t]:[t,e];h[jspreadsheet.getColumnNameFromId(s)]=b[e]}))}tp.editor.setMeta(h),tp.editor.updateTable()},tp.callbacks.editor.onmove=function(){tp.helpers.editor.reselect(),tp.helpers.unsaved_changes.set()},tp.callbacks.editor.onsort=function(){tp.editor.updateTable(),tp.helpers.unsaved_changes.set()},tp.helpers.editor.insert_from_helper_textarea=function(){tp.editor.setValueFromCoords(tp.helpers.selection.columns[0],tp.helpers.selection.rows[0],this.value)},tp.callbacks.insert_link={},tp.callbacks.insert_link.open_dialog=function(t=null){const s=o("#textarea-insert-helper");s.value=tp.editor.options.data[tp.helpers.selection.rows[0]][tp.helpers.selection.columns[0]],t?(s.selectionStart=t.selectionStart,s.selectionEnd=t.selectionEnd):(s.selectionStart=s.value.length,s.selectionEnd=s.value.length);const l=jexcel.getColumnNameFromId([tp.helpers.selection.columns[0],tp.helpers.selection.rows[0]]);o("#link-modal-title").textContent=(0,e.sprintf)((0,e.__)("Insert Link into cell %1$s","tablepress"),l),wpLink.open("textarea-insert-helper"),jexcel.current=null},tp.callbacks.insert_image={},tp.callbacks.insert_image.open_dialog=function(t=null){const s=o("#textarea-insert-helper");s.value=tp.editor.options.data[tp.helpers.selection.rows[0]][tp.helpers.selection.columns[0]],t?(s.selectionStart=t.selectionStart,s.selectionEnd=t.selectionEnd):(s.selectionStart=s.value.length,s.selectionEnd=s.value.length),wp.media.editor.open("textarea-insert-helper",{frame:"post",state:"insert",title:wp.media.view.l10n.addMedia,multiple:!0});const l=jexcel.getColumnNameFromId([tp.helpers.selection.columns[0],tp.helpers.selection.rows[0]]);document.querySelector("#media-frame-title h1").textContent=(0,e.sprintf)((0,e.__)("Add media to cell %1$s","tablepress"),l),jexcel.current=null},tp.callbacks.advanced_editor={},tp.callbacks.advanced_editor.$textarea=o("#advanced-editor-content"),tp.callbacks.advanced_editor.open_dialog=function(t=null){tp.callbacks.advanced_editor.$textarea.value=tp.editor.options.data[tp.helpers.selection.rows[0]][tp.helpers.selection.columns[0]];const s=jexcel.getColumnNameFromId([tp.helpers.selection.columns[0],tp.helpers.selection.rows[0]]),l=(0,e.sprintf)((0,e.__)("Advanced Editor for cell %1$s","tablepress"),s);o("#advanced-editor-label").textContent=l,o("#link-modal-title").textContent=(0,e.sprintf)((0,e.__)("Insert Link into cell %1$s","tablepress"),s),jQuery("#advanced-editor").wpdialog({width:600,modal:!0,title:l,resizable:!1,closeOnEscape:!0,buttons:[{text:(0,e.__)("Cancel","tablepress"),class:"button button-cancel",click(){jQuery(this).wpdialog("close")}},{text:(0,e.__)("OK","tablepress"),class:"button button-primary button-ok",click:tp.callbacks.advanced_editor.confirm_save}]}),jexcel.current=null,t?(tp.callbacks.advanced_editor.$textarea.selectionStart=t.selectionStart,tp.callbacks.advanced_editor.$textarea.selectionEnd=t.selectionEnd):(tp.callbacks.advanced_editor.$textarea.selectionStart=tp.callbacks.advanced_editor.$textarea.value.length,tp.callbacks.advanced_editor.$textarea.selectionEnd=tp.callbacks.advanced_editor.$textarea.value.length),tp.callbacks.advanced_editor.$textarea.focus()},tp.callbacks.advanced_editor.confirm_save=function(){const e=tp.editor.options.data[tp.helpers.selection.rows[0]][tp.helpers.selection.columns[0]];tp.callbacks.advanced_editor.$textarea.value!==e&&tp.editor.setValueFromCoords(tp.helpers.selection.columns[0],tp.helpers.selection.rows[0],tp.callbacks.advanced_editor.$textarea.value),jQuery(this).wpdialog("close")},tp.callbacks.help_box={},tp.callbacks.help_box.open_dialog=function(t){const s=o(t.target.dataset.helpBox);jQuery(s).wpdialog({height:s.dataset.height,width:s.dataset.width,minWidth:260,modal:!0,closeOnEscape:!0,buttons:[{text:(0,e.__)("OK","tablepress"),class:"button button-ok",click(){jQuery(this).wpdialog("close")}}],open(){jQuery(this).next().find(".button-ok").trigger("focus")}})},tp.callbacks.table_preview={},tp.callbacks.table_preview.process=function(t){t.preventDefault();let l=o("#table-name").value;if(""===l.trim()&&(l=(0,e.__)("(no name)","tablepress")),tp.callbacks.table_preview.$dialog=jQuery("#table-preview").wpdialog({autoOpen:!1,width:window.innerWidth-80,height:window.innerHeight-80,modal:!0,title:(0,e.sprintf)((0,e.__)("Preview of table “%1$s” (ID %2$s)","tablepress"),l,tp.table.id),closeOnEscape:!0,buttons:[{text:(0,e.__)("OK","tablepress"),class:"button button-ok",click(){jQuery(this).wpdialog("close")}}]}),!tp.made_changes){const e=o("#table-preview-iframe");return e.src=t.target.href,e.removeAttribute("srcdoc"),void tp.callbacks.table_preview.$dialog.wpdialog("open")}tp.helpers.visibility.update();const n={action:"tablepress_preview_table",_ajax_nonce:tp.nonces.preview_table,tablepress:{id:tp.table.id,new_id:tp.table.new_id,name:o("#table-name").value,description:o("#table-description").value,data:JSON.stringify(tp.editor.options.data),options:JSON.stringify(tp.table.options),visibility:JSON.stringify(tp.table.visibility),number:{rows:tp.editor.options.data.length,columns:tp.editor.options.columns.length}}};t.target.parentNode.insertAdjacentHTML("beforeend",`<span id="spinner-table-preview" class="spinner-table-preview spinner is-active" title="${(0,e.__)("The Table Preview is being loaded …","tablepress")}"/>`),o(".button-preview").forEach((e=>e.classList.add("disabled"))),document.body.classList.add("wait"),fetch(ajaxurl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:(0,s.buildQueryString)(n)}).then((e=>{if(!e.ok)throw new Error(`There was a problem with the server, HTTP response code ${e.status} (${e.statusText}).`);return e.json()})).then((e=>{if(null==e||"-1"===e||void 0===e.success)throw new Error("The JSON data returned from the server is unclear or incomplete.");if(!0!==e.success)throw new Error("The preview could not be loaded.");tp.callbacks.table_preview.success(e)})).catch((e=>tp.callbacks.table_preview.error(e.message))).finally((()=>{o("#spinner-table-preview").remove(),o(".button-preview").forEach((e=>e.classList.remove("disabled"))),document.body.classList.remove("wait")}))},tp.callbacks.table_preview.success=function(e){const t=o("#table-preview-iframe");t.src="",t.srcdoc=`<!DOCTYPE html><html><head>${e.head_html}</head><body>${e.body_html}</body></html>`,tp.callbacks.table_preview.$dialog.wpdialog("open")},tp.callbacks.table_preview.error=function(t){t=(0,e.__)("Attention: Unfortunately, an error occurred.","tablepress")+" "+t;const s=`show-preview-${Date.now()}`;o("#spinner-table-preview").parentNode.insertAdjacentHTML("afterend",`<div id="${s}" class="ajax-alert notice notice-error"><p>${t}</p></div>`);const l=o(`#${s}`);l.offsetWidth,l.style.opacity=0,l.addEventListener("transitionend",(()=>l.remove()))},tp.callbacks.save_changes={},tp.callbacks.save_changes.process=function(t){if(!tp.helpers.options.validate_fields())return;tp.helpers.visibility.update();const l={action:"tablepress_save_table",_ajax_nonce:tp.nonces.edit_table,tablepress:{id:tp.table.id,new_id:tp.table.new_id,name:o("#table-name").value,description:o("#table-description").value,data:JSON.stringify(tp.editor.options.data),options:JSON.stringify(tp.table.options),visibility:JSON.stringify(tp.table.visibility),number:{rows:tp.editor.options.data.length,columns:tp.editor.options.columns.length}}};t.target.parentNode.insertAdjacentHTML("beforeend",`<span id="spinner-save-changes" class="spinner-save-changes spinner is-active" title="${(0,e.__)("Changes are being saved …","tablepress")}"/>`),o(".button-save-changes").forEach((e=>e.disabled=!0)),document.body.classList.add("wait"),fetch(ajaxurl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:(0,s.buildQueryString)(l)}).then((e=>{if(!e.ok)throw new Error(`There was a problem with the server, HTTP response code ${e.status} (${e.statusText}).`);return e.json()})).then((t=>{if(null==t||"-1"===t||void 0===t.success)throw new Error("The JSON data returned from the server is unclear or incomplete.");if(!0!==t.success){const s=(0,e.__)("These errors were encountered:","tablepress"),o=t.error_details?`</p><p>${s}</p><pre>${t.error_details}</pre><p>`:"";throw new Error(`The table could not be saved to the database properly.${o}`)}tp.callbacks.save_changes.success(t)})).catch((e=>tp.callbacks.save_changes.error(e.message))).finally((()=>{o("#spinner-save-changes").remove(),o(".button-save-changes").forEach((e=>e.disabled=!1)),document.body.classList.remove("wait")}))},tp.callbacks.save_changes.success=function(t){tp.table.id!==t.table_id&&window?.history?.pushState&&window.history.pushState("","",window.location.href.replace(/table_id=[0-9a-zA-Z-_]+/gi,`table_id=${t.table_id}`)),tp.table.id=t.table_id,tp.table.new_id=t.table_id,o("#table-id").value=t.table_id;const s=o("#table-information-shortcode");s&&(s.value=`[${tp.table.shortcode} id=${t.table_id} /]`),tp.nonces.edit_table=t.new_edit_nonce,tp.nonces.preview_table=t.new_preview_nonce,tp.nonces.copy_table=t.new_copy_nonce,tp.nonces.delete_table=t.new_delete_nonce,["preview","copy","delete"].forEach((e=>{o(`.button-${e}`).forEach((s=>{s.href=s.href.replace(/item=[a-zA-Z0-9_-]+/g,`item=${t.table_id}`).replace(/&_wpnonce=[a-z0-9]+/gi,`&_wpnonce=${t[`new_${e}_nonce`]}`)}))})),o(".button-export").forEach((e=>{e.href=e.href.replace(/table_id=[a-zA-Z0-9_-]+/g,`table_id=${t.table_id}`)})),o("#last-modified").textContent=t.last_modified,o("#last-editor").textContent=t.last_editor,tp.helpers.unsaved_changes.unset();const l={};if(l.success_save=(0,e.__)("The table was saved successfully.","tablepress"),l.success_save_success_id_change=l.success_save+" "+(0,e.__)("The table ID was changed.","tablepress"),l.success_save_error_id_change=l.success_save+" "+(0,e.__)("The table ID could not be changed, probably because the new ID is already in use!","tablepress"),"success_save_error_id_change"===t.message&&t.error_details){const s=(0,e.__)("These errors were encountered:","tablepress");l.success_save_error_id_change+=`</p><p>${s}</p><pre>${t.error_details}</pre><p>`}const n=t.message.includes("error")?"error":"success";tp.callbacks.save_changes.after_saving_notice(n,l[t.message])},tp.callbacks.save_changes.error=function(t){t=(0,e.__)("Attention: Unfortunately, an error occurred.","tablepress")+" "+t,tp.callbacks.save_changes.after_saving_notice("error",t)},tp.callbacks.save_changes.after_saving_notice=function(e,t){const s=`save-changes-${Date.now()}`;o("#spinner-save-changes").parentNode.insertAdjacentHTML("afterend",`<div id="${s}" class="ajax-alert notice notice-${e}"><p>${t}</p></div>`);const l=o(`#${s}`);l.offsetWidth,l.style.opacity=0,l.addEventListener("transitionend",(()=>l.remove()))},tp.callbacks.screen_options={},tp.callbacks.screen_options.update=function(e){if(e.target)return"table_editor_line_clamp"===e.target.id?(tp.editor.el.style.setProperty("--table-editor-line-clamp",parseInt(e.target.value,10)),void tp.editor.updateCornerPosition()):"table_editor_column_width"===e.target.id?(tp.screen_options.table_editor_column_width=parseInt(e.target.value,10),tp.screen_options.table_editor_column_width=Math.max(tp.screen_options.table_editor_column_width,30),tp.screen_options.table_editor_column_width=Math.min(tp.screen_options.table_editor_column_width,9999),tp.editor.colgroup.forEach((e=>e.setAttribute("width",tp.screen_options.table_editor_column_width))),void tp.editor.updateCornerPosition()):void 0},tp.callbacks.screen_options.set_was_changed=function(e){e.target&&(e.target.was_changed=!0)},tp.callbacks.screen_options.save=function(t){if(!t.target)return;if(!t.target.was_changed)return;t.target.was_changed=!1;const l={action:"tablepress_save_screen_options",_ajax_nonce:tp.nonces.screen_options,tablepress:{[t.target.id]:parseInt(t.target.value,10)}};t.target.parentNode.insertAdjacentHTML("beforeend",`<span id="spinner-save-changes" class="spinner-save-changes spinner is-active" title="${(0,e.__)("Changes are being saved …","tablepress")}"/>`),document.body.classList.add("wait"),fetch(ajaxurl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:(0,s.buildQueryString)(l)}).finally((()=>{o("#spinner-save-changes").remove(),document.body.classList.remove("wait")}))},tp.callbacks.table_id=tp.callbacks.table_id||{},tp.callbacks.table_id.sanitize=function(){this.value=this.value.replace(/[^0-9a-zA-Z-_]/g,"")},tp.callbacks.table_id.change=function(){if(""===this.value||"0"===this.value)return window.alert((0,e.__)("This table ID is invalid. Please enter a different table ID.","tablepress")),this.value=tp.table.new_id,this.focus(),void this.select();if(!window.confirm((0,e.__)("Do you really want to change the Table ID? All blocks and Shortcodes for this table in your posts and pages will have to be adjusted!","tablepress")))return void(this.value=tp.table.new_id);tp.table.new_id=this.value;const t=o("#table-information-shortcode");t&&(t.value=`[${tp.table.shortcode} id=${tp.table.new_id} /]`,t.focus(),t.select()),tp.helpers.unsaved_changes.set()},tp.callbacks.insert_duplicate=function(e,t,s="before"){const o="rows"===t,l=o?tp.editor.insertRow:tp.editor.insertColumn,n=o?tp.editor.getRowData:tp.editor.getColumnData,a="duplicate"===e;tp.editor.options[o?"oninsertrow":"oninsertcolumn"]=tp.callbacks.editor.oninsertroc.bind(null,t,e),tp.helpers.selection[t].forEach((function(e,t){const o=e+t,i=a?n(o):1;l(i,o,"before"===s)})),tp.helpers.unsaved_changes.set();const i=tp.helpers.selection[t].length;i>1&&tp.editor.updateSelectionFromCoords(tp.helpers.selection.columns[0],tp.helpers.selection.rows[0],o?tp.helpers.selection.columns[tp.helpers.selection.columns.length-1]:tp.helpers.selection.columns[tp.helpers.selection.columns.length-1]+i,o?tp.helpers.selection.rows[tp.helpers.selection.rows.length-1]+i:tp.helpers.selection.rows[tp.helpers.selection.rows.length-1])},tp.callbacks.remove=function(e){const t="rows"===e,s=t?tp.editor.options.columns.length:tp.editor.options.data.length,o=t?tp.editor.options.data.length-1:tp.editor.options.columns.length-1;if(tp.editor.options.meta&&tp.helpers.selection[e].forEach((function(e){for(let o=0;o<s;o++){const s=t?[o,e]:[e,o];delete tp.editor.options.meta[jspreadsheet.getColumnNameFromId(s)]}})),(t?tp.editor.deleteRow:tp.editor.deleteColumn)(tp.helpers.selection[e][0],tp.helpers.selection[e].length),tp.helpers.unsaved_changes.set(),o===tp.helpers.selection[e][tp.helpers.selection[e].length-1]){const e=t?tp.helpers.selection.columns[0]:tp.helpers.selection.columns[0]-1,s=t?tp.helpers.selection.rows[0]-1:tp.helpers.selection.rows[0];tp.editor.updateSelectionFromCoords(e,s,e,s)}},tp.callbacks.append=function(e,t){const s="rows"===e,o=s?tp.editor.insertRow:tp.editor.insertColumn;tp.editor.options[s?"oninsertrow":"oninsertcolumn"]=tp.callbacks.editor.oninsertroc.bind(null,e,"append"),o(t),tp.helpers.unsaved_changes.set()},tp.callbacks.move=function(e,t){const s="rows"===t;let o=tp.helpers.selection[t],l=-1;if("down"===e||"right"===e)o=o.slice().reverse(),l=1;else if("top"===e||"first"===e)l=-o[0];else if("bottom"===e||"last"===e){o=o.slice().reverse();const e="rows"===t?tp.editor.options.data.length-1:tp.editor.options.columns.length-1;l=e-o[0]}if(0===l)return;const n=s?tp.editor.moveRow:tp.editor.moveColumn;o.forEach((e=>n(e,e+l))),tp.helpers.unsaved_changes.set(),tp.editor.updateSelectionFromCoords(s?tp.helpers.selection.columns[0]:tp.helpers.selection.columns[0]+l,s?tp.helpers.selection.rows[0]+l:tp.helpers.selection.rows[0],s?tp.helpers.selection.columns[tp.helpers.selection.columns.length-1]:tp.helpers.selection.columns[tp.helpers.selection.columns.length-1]+l,s?tp.helpers.selection.rows[tp.helpers.selection.rows.length-1]+l:tp.helpers.selection.rows[tp.helpers.selection.rows.length-1])},tp.callbacks.sort=function(e){tp.editor.orderBy(tp.helpers.selection.columns[0],"desc"===e)},tp.callbacks.hide_unhide=function(e,t){const s="rows"===t,o=s?"row_hidden":"column_hidden",l=s?tp.editor.options.columns.length:tp.editor.options.data.length,n="hide"===e,a={};tp.helpers.selection[t].forEach((function(e){for(let t=0;t<l;t++){const l=s?[t,e]:[e,t],i=jspreadsheet.getColumnNameFromId(l);a[i]={},a[i][o]=n}})),tp.editor.setMeta(a),tp.helpers.unsaved_changes.set(),tp.editor.updateTable()},tp.callbacks.merge_cells=function(){const e=tp.helpers.selection.columns[0],t=tp.helpers.selection.rows[0],s=tp.helpers.selection.columns.length,o=tp.helpers.selection.rows.length;for(let s=1;s<o;s++)tp.editor.setValueFromCoords(e,t+s,"#rowspan#");for(let o=1;o<s;o++)tp.editor.setValueFromCoords(e+o,t,"#colspan#");for(let l=1;l<o;l++)for(let o=1;o<s;o++)tp.editor.setValueFromCoords(e+o,t+l,"#span#");tp.helpers.unsaved_changes.set()},tp.callbacks.keyboard_shortcuts=function(e){let t="",s="",l="";if((e.ctrlKey||e.metaKey)&&(80===e.keyCode?t="preview":83===e.keyCode?t="save-changes":76===e.keyCode?t="insert_link":73===e.keyCode?t="insert_image":69===e.keyCode?t="advanced_editor":e.shiftKey&&e.altKey&&38===e.keyCode?(t="move",s="top",l="rows"):e.shiftKey&&e.altKey&&40===e.keyCode?(t="move",s="bottom",l="rows"):e.shiftKey&&e.altKey&&37===e.keyCode?(t="move",s="first",l="columns"):e.shiftKey&&e.altKey&&39===e.keyCode?(t="move",s="last",l="columns"):e.shiftKey&&38===e.keyCode?(t="move",s="up",l="rows"):e.shiftKey&&40===e.keyCode?(t="move",s="down",l="rows"):e.shiftKey&&37===e.keyCode?(t="move",s="left",l="columns"):e.shiftKey&&39===e.keyCode&&(t="move",s="right",l="columns")),"save-changes"===t||"preview"===t)document.activeElement.blur(),document.querySelector(`#tablepress_edit-buttons-2-submit .button-${t}`).click(),e.preventDefault();else if("insert_link"===t||"insert_image"===t||"advanced_editor"===t){if(o("#table-editor").contains(document.activeElement)){const e="TEXTAREA"===document.activeElement.tagName?document.activeElement:null;tp.callbacks[t].open_dialog(e)}e.preventDefault()}else"move"===t&&(o("#table-editor").contains(document.activeElement)&&"TEXTAREA"!==document.activeElement.tagName&&tp.helpers.move_allowed(l,s)&&tp.callbacks.move(s,l),e.stopImmediatePropagation())},tp.editor=jspreadsheet(o("#table-editor"),{data:tp.table.data,meta:tp.helpers.visibility.load(),wordWrap:!0,rowDrag:!0,rowResize:!0,columnSorting:!0,columnDrag:!0,columnResize:!0,defaultColWidth:tp.screen_options.table_editor_column_width,defaultColAlign:"left",parseFormulas:!1,allowExport:!1,allowComments:!1,allowManualInsertRow:!1,allowManualInsertColumn:!1,about:!1,secureFormulas:!1,detachForUpdates:!0,onselection:tp.callbacks.editor.onselection,updateTable:tp.callbacks.editor.onupdatetable,contextMenu:t=>{const s=tp.editor.options.data.length,o=tp.editor.options.columns.length,l=tp.helpers.selection.rows.length,n=tp.helpers.selection.columns.length,a=window?.navigator?.platform?.includes("Mac"),i=a?(0,e._x)("⌘","keyboard shortcut modifier key on a Mac keyboard","tablepress"):(0,e._x)("Ctrl+","keyboard shortcut modifier key on a non-Mac keyboard","tablepress"),r=a?(0,e._x)("⌥","keyboard shortcut option key on a Mac keyboard","tablepress"):(0,e._x)("Alt+","keyboard shortcut Alt key on a non-Mac keyboard","tablepress"),c={text:""};return tp.helpers.visibility.update(),[{title:(0,e.__)("Undo","tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$sZ","keyboard shortcut for Undo","tablepress"),i),onclick:t.undo,disabled:-1===t.historyIndex},{title:(0,e.__)("Redo","tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$sY","keyboard shortcut for Redo","tablepress"),i),onclick:t.redo,disabled:t.historyIndex===t.history.length-1},{type:"divisor"},{title:(0,e.__)("Cut","tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$sX","keyboard shortcut for Cut","tablepress"),i),onclick(){if("TEXTAREA"===document.activeElement.tagName&&document.activeElement.selectionStart!==document.activeElement.selectionEnd){document.execCommand("copy");const e=document.activeElement.selectionStart;document.activeElement.value=document.activeElement.value.slice(0,document.activeElement.selectionStart)+document.activeElement.value.slice(document.activeElement.selectionEnd),document.activeElement.selectionEnd=e}else t.copy(!0),t.setValue(t.highlighted,"")}},{title:(0,e.__)("Copy","tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$sC","keyboard shortcut for Copy","tablepress"),i),onclick(){"TEXTAREA"===document.activeElement.tagName&&document.activeElement.selectionStart!==document.activeElement.selectionEnd?document.execCommand("copy"):t.copy(!0)}},{title:(0,e.__)("Paste","tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$sV","keyboard shortcut for Paste","tablepress"),i),onclick(){"TEXTAREA"===document.activeElement.tagName?window.navigator.clipboard.readText().then((e=>{if(e){const t=document.activeElement.selectionStart+e.length;document.activeElement.value=document.activeElement.value.slice(0,document.activeElement.selectionStart)+e+document.activeElement.value.slice(document.activeElement.selectionEnd),document.activeElement.selectionEnd=t}})):t.selectedCell&&window.navigator.clipboard.readText().then((e=>{e&&t.paste(t.selectedCell[0],t.selectedCell[1],e)}))},disabled:!window?.navigator?.clipboard?.readText,tooltip:window?.navigator?.clipboard?.readText?"":(0,e.__)("Your browser does not allow pasting via the context menu. Use the keyboard shortcut instead.","tablepress")},{type:"divisor"},{title:(0,e.__)("Insert Link","tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$sL","keyboard shortcut for Insert Link","tablepress"),i),onclick:tp.callbacks.insert_link.open_dialog.bind(null,"TEXTAREA"===document.activeElement.tagName?document.activeElement:null)},{title:(0,e.__)("Insert Image","tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$sI","keyboard shortcut for Insert Image","tablepress"),i),onclick:tp.callbacks.insert_image.open_dialog.bind(null,"TEXTAREA"===document.activeElement.tagName?document.activeElement:null)},{title:(0,e.__)("Advanced Editor","tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$sE","keyboard shortcut for Advanced Editor","tablepress"),i),onclick:tp.callbacks.advanced_editor.open_dialog.bind(null,"TEXTAREA"===document.activeElement.tagName?document.activeElement:null)},{type:"divisor"},{title:(0,e.__)("Duplicate …","tablepress"),submenu:[{title:(0,e._n)("Duplicate row","Duplicate rows",l,"tablepress"),onclick:tp.callbacks.insert_duplicate.bind(null,"duplicate","rows")},{title:(0,e._n)("Duplicate column","Duplicate columns",n,"tablepress"),onclick:tp.callbacks.insert_duplicate.bind(null,"duplicate","columns")}]},{title:(0,e.__)("Insert …","tablepress"),submenu:[{title:(0,e._n)("Insert row above","Insert rows above",l,"tablepress"),onclick:tp.callbacks.insert_duplicate.bind(null,"insert","rows","before")},{title:(0,e._n)("Insert row below","Insert rows below",l,"tablepress"),onclick:tp.callbacks.insert_duplicate.bind(null,"insert","rows","after")},{title:(0,e._n)("Insert column on the left","Insert columns on the left",n,"tablepress"),onclick:tp.callbacks.insert_duplicate.bind(null,"insert","columns","before")},{title:(0,e._n)("Insert column on the right","Insert columns on the right",n,"tablepress"),onclick:tp.callbacks.insert_duplicate.bind(null,"insert","columns","after")}]},{title:(0,e.__)("Append …","tablepress"),submenu:[{title:(0,e.__)("Append row","tablepress"),onclick:tp.callbacks.append.bind(null,"rows",1)},{title:(0,e.__)("Append column","tablepress"),onclick:tp.callbacks.append.bind(null,"columns",1)}]},{title:(0,e.__)("Delete …","tablepress"),submenu:[{title:(0,e._n)("Delete row","Delete rows",l,"tablepress"),onclick:tp.callbacks.remove.bind(null,"rows"),disabled:s===l,tooltip:s===l?(0,e.__)("This option is disabled.","tablepress")+" "+(0,e.__)("You can not delete all table rows!","tablepress"):""},{title:(0,e._n)("Delete column","Delete columns",n,"tablepress"),onclick:tp.callbacks.remove.bind(null,"columns"),disabled:o===n,tooltip:o===n?(0,e.__)("This option is disabled.","tablepress")+" "+(0,e.__)("You can not delete all table columns!","tablepress"):""}]},{type:"divisor"},{title:(0,e.__)("Move …","tablepress"),submenu:[{title:(0,e._n)("Move row up","Move rows up",l,"tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$s⇧↑","keyboard shortcut for Move up","tablepress"),i),onclick:tp.callbacks.move.bind(null,"up","rows"),disabled:!tp.helpers.move_allowed("rows","up")},{title:(0,e._n)("Move row down","Move rows down",l,"tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$s⇧↓","keyboard shortcut for Move down","tablepress"),i),onclick:tp.callbacks.move.bind(null,"down","rows"),disabled:!tp.helpers.move_allowed("rows","down")},{title:(0,e._n)("Move column left","Move columns left",n,"tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$s⇧←","keyboard shortcut for Move left","tablepress"),i),onclick:tp.callbacks.move.bind(null,"left","columns"),disabled:!tp.helpers.move_allowed("columns","left")},{title:(0,e._n)("Move column right","Move columns right",n,"tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$s⇧→","keyboard shortcut for Move right","tablepress"),i),onclick:tp.callbacks.move.bind(null,"right","columns"),disabled:!tp.helpers.move_allowed("columns","right")},{type:"divisor"},{title:(0,e._n)("Move row to the top","Move rows to the top",l,"tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$s%2$s⇧↑","keyboard shortcut for Move to the top","tablepress"),i,r),onclick:tp.callbacks.move.bind(null,"top","rows"),disabled:!tp.helpers.move_allowed("rows","top")},{title:(0,e._n)("Move row to the bottom","Move rows to the bottom",l,"tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$s%2$s⇧↓","keyboard shortcut for Move to the bottom","tablepress"),i,r),onclick:tp.callbacks.move.bind(null,"bottom","rows"),disabled:!tp.helpers.move_allowed("rows","bottom")},{title:(0,e._n)("Move column to first","Move columns to first",n,"tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$s%2$s⇧←","keyboard shortcut for Move to first","tablepress"),i,r),onclick:tp.callbacks.move.bind(null,"first","columns"),disabled:!tp.helpers.move_allowed("columns","first")},{title:(0,e._n)("Move column to last","Move columns to last",n,"tablepress"),shortcut:(0,e.sprintf)((0,e._x)("%1$s%2$s⇧→","keyboard shortcut for Move to last","tablepress"),i,r),onclick:tp.callbacks.move.bind(null,"last","columns"),disabled:!tp.helpers.move_allowed("columns","last")}]},{title:(0,e.__)("Sort by column …","tablepress"),submenu:[{title:(0,e.__)("Sort by column ascending","tablepress"),onclick:tp.callbacks.sort.bind(null,"asc"),disabled:1!==n,tooltip:1!==n?(0,e.__)("This option is disabled because more than one column was selected.","tablepress"):""},{title:(0,e.__)("Sort by column descending","tablepress"),onclick:tp.callbacks.sort.bind(null,"desc"),disabled:1!==n,tooltip:1!==n?(0,e.__)("This option is disabled because more than one column was selected.","tablepress"):""}]},{type:"divisor"},{title:(0,e.__)("Hide/Show …","tablepress"),submenu:[{title:(0,e._n)("Hide row","Hide rows",l,"tablepress"),onclick:tp.callbacks.hide_unhide.bind(null,"hide","rows"),disabled:!tp.helpers.visibility.selection_contains("rows",1),tooltip:tp.helpers.visibility.selection_contains("rows",1)?"":(0,e.__)("This option is disabled because no visible rows were selected.","tablepress")},{title:(0,e._n)("Hide column","Hide columns",n,"tablepress"),onclick:tp.callbacks.hide_unhide.bind(null,"hide","columns"),disabled:!tp.helpers.visibility.selection_contains("columns",1),tooltip:tp.helpers.visibility.selection_contains("columns",1)?"":(0,e.__)("This option is disabled because no visible columns were selected.","tablepress")},{title:(0,e._n)("Show row","Show rows",l,"tablepress"),onclick:tp.callbacks.hide_unhide.bind(null,"unhide","rows"),disabled:!tp.helpers.visibility.selection_contains("rows",0),tooltip:tp.helpers.visibility.selection_contains("rows",0)?"":(0,e.__)("This option is disabled because no hidden rows were selected.","tablepress")},{title:(0,e._n)("Show column","Show columns",n,"tablepress"),onclick:tp.callbacks.hide_unhide.bind(null,"unhide","columns"),disabled:!tp.helpers.visibility.selection_contains("columns",0),tooltip:tp.helpers.visibility.selection_contains("columns",0)?"":(0,e.__)("This option is disabled because no hidden columns were selected.","tablepress")}]},{type:"divisor"},{title:(0,e.__)("Combine/Merge cells","tablepress"),onclick:tp.callbacks.merge_cells,disabled:1===l&&1===n||!tp.helpers.cell_merge_allowed("no-alert"),tooltip:1===l&&1===n||!tp.helpers.cell_merge_allowed("no-alert",c)?(0,e.__)("This option is disabled.","tablepress")+" "+c.text:""}]},sorting:tp.helpers.editor.sorting,onmoverow:tp.callbacks.editor.onmove,onmovecolumn:tp.callbacks.editor.onmove,onblur:tp.helpers.editor.reselect,onload:tp.helpers.editor.reselect,onchange:tp.helpers.unsaved_changes.set,onsort:tp.callbacks.editor.onsort}),tp.helpers.options.load(),o("#tablepress-page").addEventListener("click",(e=>{e.target&&(e.target.matches(".button-preview")?tp.callbacks.table_preview.process(e):e.target.matches(".button-save-changes")?tp.callbacks.save_changes.process(e):e.target.matches(".button-show-help-box")&&tp.callbacks.help_box.open_dialog(e))})),o("#tablepress-manipulation-controls").addEventListener("click",(t=>{if(t.target)if(t.target.matches(".button-append")){const s=t.target.dataset.type,l=o(`#${s}-append-number`),n=parseInt(l.value,10);if(isNaN(n)||n<1||n>99999){const s="rows"===t.target.dataset.type?(0,e.__)("The value for the number of rows is invalid!","tablepress"):(0,e.__)("The value for the number of columns is invalid!","tablepress");return window.alert(s),l.focus(),void l.select()}tp.callbacks.append(s,n)}else if("button-insert-link"!==t.target.id)if("button-insert-image"!==t.target.id)if("button-advanced-editor"!==t.target.id)if(t.target.matches(".button-insert-duplicate"))tp.callbacks.insert_duplicate(t.target.dataset.action,t.target.dataset.type);else{if(t.target.matches(".button-move"))return tp.helpers.move_allowed(t.target.dataset.type,t.target.dataset.direction)?void tp.callbacks.move(t.target.dataset.direction,t.target.dataset.type):void window.alert((0,e.__)("You can not do this move, because you reached the border of the table.","tablepress"));if(t.target.matches(".button-remove")){const s="rows"===t.target.dataset.type;if((s?tp.editor.options.data.length:tp.editor.options.columns.length)===tp.helpers.selection[t.target.dataset.type].length){const t=s?(0,e.__)("You can not delete all table rows!","tablepress"):(0,e.__)("You can not delete all table columns!","tablepress");return void window.alert(t)}tp.callbacks.remove(t.target.dataset.type)}else t.target.matches(".button-merge-unmerge")?tp.helpers.cell_merge_allowed("alert")&&tp.callbacks.merge_cells():t.target.matches(".button-hide-unhide")&&tp.callbacks.hide_unhide(t.target.dataset.action,t.target.dataset.type)}else tp.callbacks.advanced_editor.open_dialog();else tp.callbacks.insert_image.open_dialog();else tp.callbacks.insert_link.open_dialog()}));const l=o("#table-id");l.addEventListener("input",tp.callbacks.table_id.sanitize),l.addEventListener("change",tp.callbacks.table_id.change);const n=o("#table-information-shortcode");n&&n.addEventListener("focus",(function(){this.select()})),jQuery("#textarea-insert-helper").on("change",tp.helpers.editor.insert_from_helper_textarea),["#table-name","#table-description"].forEach((e=>o(e).addEventListener("change",tp.helpers.unsaved_changes.set))),(0,t.applyFilters)("tablepress.optionsMetaBoxes",["#tablepress_edit-table-options","#tablepress_edit-datatables-features"]).forEach((e=>o(e).addEventListener("change",tp.helpers.options.change))),document.querySelectorAll("#tablepress-body .button-module-help").forEach((e=>e.closest(".postbox").querySelector(".handle-actions").prepend(e)));const a=o("#tablepress-screen-options");a.addEventListener("input",tp.callbacks.screen_options.update),a.addEventListener("change",tp.callbacks.screen_options.set_was_changed),a.addEventListener("focusout",tp.callbacks.screen_options.save),window.addEventListener("keydown",tp.callbacks.keyboard_shortcuts,!0);const i=window?.navigator?.platform?.includes("Mac")?(0,e._x)("⌘","keyboard shortcut modifier key on a Mac keyboard","tablepress"):(0,e._x)("Ctrl+","keyboard shortcut modifier key on a non-Mac keyboard","tablepress");document.querySelectorAll(".button[data-shortcut]").forEach((t=>{const s=(0,e.sprintf)(t.dataset.shortcut,i);t.title=(0,e.sprintf)((0,e.__)("Keyboard Shortcut: %s","tablepress"),s)})),jQuery((function(){jQuery("#wp-link").on("focus","input",(function(e){e.stopPropagation()})),jQuery("body").on("focus",".media-modal .media-frame-content input, .media-modal .media-frame-content textarea",(function(e){e.stopPropagation()}))}))}();
\ No newline at end of file

programming_language: JavaScript
filename: edit.js
change_type: ModificationType.MODIFY
diff: @@ -765,7 +765,7 @@ tp.callbacks.table_preview.process = function ( event ) {
 
 	// Add spinner, disable "Preview" buttons, and change cursor.
 	event.target.parentNode.insertAdjacentHTML( 'beforeend', `<span id="spinner-table-preview" class="spinner-table-preview spinner is-active" title="${ __( 'The Table Preview is being loaded …', 'tablepress' ) }"/>` );
-	$( '.button-show-preview' ).forEach( ( button ) => button.classList.add( 'disabled' ) );
+	$( '.button-preview' ).forEach( ( button ) => button.classList.add( 'disabled' ) );
 	document.body.classList.add( 'wait' );
 
 	// Load the table preview data from the server via an AJAX request.
@@ -800,7 +800,7 @@ tp.callbacks.table_preview.process = function ( event ) {
 	.catch( ( error ) => tp.callbacks.table_preview.error( error.message ) )
 	.finally( () => {
 		$( '#spinner-table-preview' ).remove();
-		$( '.button-show-preview' ).forEach( ( button ) => button.classList.remove( 'disabled' ) );
+		$( '.button-preview' ).forEach( ( button ) => button.classList.remove( 'disabled' ) );
 		document.body.classList.remove( 'wait' );
 	} );
 };
@@ -938,12 +938,22 @@ tp.callbacks.save_changes.success = function ( data ) {
 	// Update the nonces.
 	tp.nonces.edit_table = data.new_edit_nonce;
 	tp.nonces.preview_table = data.new_preview_nonce;
+	tp.nonces.copy_table = data.new_copy_nonce;
+	tp.nonces.delete_table = data.new_delete_nonce;
+
+	// Update URLs in Preview, Copy, and Delete links/buttons.
+	[ 'preview', 'copy', 'delete' ].forEach( ( action ) => {
+		$( `.button-${ action }` ).forEach( ( button ) => {
+			button.href = button.href
+				.replace( /item=[a-zA-Z0-9_-]+/g, `item=${ data.table_id }` ) // Updates both the "item" and the "return_item" parameters.
+				.replace( /&_wpnonce=[a-z0-9]+/ig, `&_wpnonce=${ data[ `new_${ action }_nonce` ] }` );
+		} );
+	} );
 
-	// Update URLs in Preview links.
-	$( '.button-show-preview' ).forEach( ( button ) => {
+	// Update URL in Export links/buttons.
+	$( '.button-export' ).forEach( ( button ) => {
 		button.href = button.href
-			.replace( /item=[a-zA-Z0-9_-]+/g, `item=${ data.table_id }` )
-			.replace( /&_wpnonce=[a-z0-9]+/ig, `&_wpnonce=${ data.new_preview_nonce }` );
+			.replace( /table_id=[a-zA-Z0-9_-]+/g, `table_id=${ data.table_id }` );
 	} );
 
 	// Update last-modified date and user nickname.
@@ -1309,7 +1319,7 @@ tp.callbacks.keyboard_shortcuts = function ( event ) {
 	if ( event.ctrlKey || event.metaKey ) {
 		if ( 80 === event.keyCode ) {
 			// Preview: Ctrl/Cmd + P.
-			action = 'show-preview';
+			action = 'preview';
 		} else if ( 83 === event.keyCode ) {
 			// Save Changes: Ctrl/Cmd + S.
 			action = 'save-changes';
@@ -1365,7 +1375,7 @@ tp.callbacks.keyboard_shortcuts = function ( event ) {
 		}
 	}
 
-	if ( 'save-changes' === action || 'show-preview' === action ) {
+	if ( 'save-changes' === action || 'preview' === action ) {
 		// Blur the focussed element to make sure that all change events were triggered.
 		document.activeElement.blur(); // eslint-disable-line @wordpress/no-global-active-element
 
@@ -1446,7 +1456,7 @@ $( '#tablepress-page' ).addEventListener( 'click', ( event ) => {
 		return;
 	}
 
-	if ( event.target.matches( '.button-show-preview' ) ) {
+	if ( event.target.matches( '.button-preview' ) ) {
 		tp.callbacks.table_preview.process( event );
 		return;
 	}

programming_language: JavaScript
filename: block.json
change_type: ModificationType.MODIFY
diff: @@ -2,7 +2,7 @@
 	"$schema": "https://schemas.wp.org/trunk/block.json",
 	"apiVersion": 3,
 	"name": "tablepress/table",
-	"version": "2.2.4",
+	"version": "2.2.5",
 	"title": "TablePress table",
 	"category": "media",
 	"icon": "list-view",

programming_language: JavaScript
filename: class-import-phpspreadsheet.php
change_type: ModificationType.MODIFY
diff: @@ -77,10 +77,12 @@ class TablePress_Import_PHPSpreadsheet extends TablePress_Import_Base {
 	 * @return array<string, mixed>|false Table array on success, false if the file is not a JSON file.
 	 */
 	protected function _maybe_import_json( string $data ) /* : array|false */ {
-		// If the first non-whitespace character is not a { or [, the file is not a supported JSON file.
-		$data = ltrim( $data );
+		$data = trim( $data );
+
+		// If the file does not begin / end with [ / ] or { / }, it's not a supported JSON file.
 		$first_character = $data[0];
-		if ( '{' !== $first_character && '[' !== $first_character ) {
+		$last_character = $data[-1];
+		if ( ! ( '[' === $first_character && ']' === $last_character ) && ! ( '{' === $first_character && '}' === $last_character ) ) {
 			return false;
 		}
 
@@ -246,9 +248,16 @@ class TablePress_Import_PHPSpreadsheet extends TablePress_Import_Base {
 
 					// Apply data type formatting.
 					$style = $spreadsheet->getCellXfByIndex( $cell->getXfIndex() );
+
+					$format = $style->getNumberFormat()->getFormatCode() ?? \TablePress\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_GENERAL;
+
+					// Fix floating point precision issues with numbers in the "General" Excel .xlsx format.
+					if ( 'xlsx' === $detected_format && \TablePress\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_GENERAL === $format && is_numeric( $cell_data ) ) {
+						$cell_data = (string) (float) $cell_data; // Type-cast strings to float and back.
+					}
 					$cell_data = \TablePress\PhpOffice\PhpSpreadsheet\Style\NumberFormat::toFormattedString(
 						$cell_data,
-						$style->getNumberFormat() ? $style->getNumberFormat()->getFormatCode() : \TablePress\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_GENERAL, // @phpstan-ignore-line
+						$format,
 						array( $this, 'format_color' )
 					);
 

programming_language: PHP
filename: class-import.php
change_type: ModificationType.MODIFY
diff: @@ -127,12 +127,16 @@ class TablePress_Import {
 					return new WP_Error( 'table_import_url_host_invalid', '', $this->import_config['url'] );
 				}
 
-				// Check the host of the Import URL against a blacklist of hosts, which should not be accessible, e.g. for security considerations.
-				$blocked_hosts = array(
-					'169.254.169.254', // AWS Meta-data API.
+				// Check the IP address of the host against a blocklist of hosts which should not be accessible, e.g. for security considerations.
+				$ip = gethostbyname( $host ); // If no IP address can be found, this will return the host name, which will then be checked against the blocklist.
+				$blocked_ips = array(
+					'169.254.169.254', // Meta-data API for various cloud providers.
+					'169.254.170.2', // AWS task metadata endpoint.
+					'192.0.0.192', // Oracle Cloud endpoint.
+					'100.100.100.200', // Alibaba Cloud endpoint.
 				);
-				if ( in_array( $host, $blocked_hosts, true ) ) {
-					return new WP_Error( 'table_import_url_host_blocked', '', $this->import_config['url'] );
+				if ( in_array( $ip, $blocked_ips, true ) ) {
+					return new WP_Error( 'table_import_url_host_blocked', '', array( 'url' => $this->import_config['url'], 'ip' => $ip ) );
 				}
 
 				/**
@@ -395,7 +399,7 @@ class TablePress_Import {
 			&& class_exists( 'ZipArchive', false )
 			&& class_exists( 'DOMDocument', false )
 			&& function_exists( 'simplexml_load_string' )
-			&& function_exists( 'libxml_disable_entity_loader' );
+			&& ( function_exists( 'libxml_disable_entity_loader' ) || PHP_VERSION_ID >= 80000 ); // This function is only needed for older versions of PHP.
 		if ( ! $phpspreadsheet_requirements_fulfilled ) {
 			return true;
 		}
@@ -531,11 +535,17 @@ class TablePress_Import {
 
 		// If no format could be determined from the file extension, try guessing from the file content.
 		if ( '' === $format ) {
+			$data = trim( $data );
 			$first_character = $data[0];
-			if ( '<' === $first_character ) {
+			$last_character = $data[-1];
+
+			if ( '<' === $first_character && '>' === $last_character ) {
 				$format = 'html';
-			} elseif ( '{' === $first_character || '[' === $first_character ) {
-				$format = 'json';
+			} elseif ( ( '[' === $first_character && ']' === $last_character ) || ( '{' === $first_character && '}' === $last_character ) ) {
+				$json_table = json_decode( $data, true );
+				if ( ! is_null( $json_table ) ) {
+					$format = 'json';
+				}
 			}
 		}
 

programming_language: PHP
filename: class-tablepress.php
change_type: ModificationType.MODIFY
diff: @@ -27,7 +27,7 @@ abstract class TablePress {
 	 * @since 1.0.0
 	 * @const string
 	 */
-	public const version = '2.2.4'; // phpcs:ignore Generic.NamingConventions.UpperCaseConstantName.ClassConstantNotUpperCase
+	public const version = '2.2.5'; // phpcs:ignore Generic.NamingConventions.UpperCaseConstantName.ClassConstantNotUpperCase
 
 	/**
 	 * TablePress internal plugin version ("options scheme" version).
@@ -37,7 +37,7 @@ abstract class TablePress {
 	 * @since 1.0.0
 	 * @const int
 	 */
-	public const db_version = 70; // phpcs:ignore Generic.NamingConventions.UpperCaseConstantName.ClassConstantNotUpperCase
+	public const db_version = 73; // phpcs:ignore Generic.NamingConventions.UpperCaseConstantName.ClassConstantNotUpperCase
 
 	/**
 	 * TablePress "table scheme" (data format structure) version.

programming_language: PHP
filename: class-view.php
change_type: ModificationType.MODIFY
diff: @@ -411,7 +411,7 @@ abstract class TablePress_View {
 		?>
 		<div id="tablepress-header" class="header">
 			<h1 class="name"><img src="<?php echo plugins_url( 'admin/img/tablepress-icon.png', TABLEPRESS__FILE__ ); ?>" class="tablepress-icon" alt="<?php esc_attr_e( 'TablePress plugin logo', 'tablepress' ); ?>" /><?php _e( 'TablePress', 'tablepress' ); ?></h1>
-			<?php if ( tb_tp_fs()->is_free_plan() ) : ?>
+			<?php if ( ! TABLEPRESS_IS_PLAYGROUND_PREVIEW && tb_tp_fs()->is_free_plan() ) : ?>
 				<div class="buttons">
 					<a href="https://tablepress.org/premium/?utm_source=plugin&utm_medium=button&utm_content=upgrade-button" class="tablepress-button">
 						<span><?php _e( 'Upgrade to Premium', 'tablepress' ); ?></span>

programming_language: PHP
filename: controller-admin.php
change_type: ModificationType.MODIFY
diff: @@ -410,7 +410,7 @@ JS;
 			$links[] = '<a href="https://tablepress.org/faq/" title="' . esc_attr__( 'Frequently Asked Questions', 'tablepress' ) . '">' . __( 'FAQ', 'tablepress' ) . '</a>';
 			$links[] = '<a href="https://tablepress.org/documentation/">' . __( 'Documentation', 'tablepress' ) . '</a>';
 			$links[] = '<a href="https://tablepress.org/support/">' . __( 'Support', 'tablepress' ) . '</a>';
-			if ( tb_tp_fs()->is_free_plan() ) {
+			if ( ! TABLEPRESS_IS_PLAYGROUND_PREVIEW && tb_tp_fs()->is_free_plan() ) {
 				$links[] = '<a href="https://tablepress.org/premium/?utm_source=plugin&utm_medium=textlink&utm_content=plugins-screen" title="' . esc_attr__( 'Check out the Premium version of TablePress!', 'tablepress' ) . '"><strong>' . __( 'Go Premium', 'tablepress' ) . '</strong></a>';
 			}
 		}
@@ -790,7 +790,7 @@ JS;
 
 		$add_table = wp_unslash( $_POST['table'] );
 
-		// Perform sanity checks of posted data.
+		// Perform confidence checks of posted data.
 		$name = ( isset( $add_table['name'] ) ) ? $add_table['name'] : '';
 		$description = ( isset( $add_table['description'] ) ) ? $add_table['description'] : '';
 		if ( ! isset( $add_table['rows'], $add_table['columns'] ) ) {

programming_language: PHP
filename: controller-admin_ajax.php
change_type: ModificationType.MODIFY
diff: @@ -174,6 +174,8 @@ class TablePress_Admin_AJAX_Controller extends TablePress_Controller {
 			$response['table_id'] = $table['id']; // @phpstan-ignore-line
 			$response['new_edit_nonce'] = wp_create_nonce( TablePress::nonce( 'edit', $table['id'] ) ); // @phpstan-ignore-line
 			$response['new_preview_nonce'] = wp_create_nonce( TablePress::nonce( 'preview_table', $table['id'] ) ); // @phpstan-ignore-line
+			$response['new_copy_nonce'] = wp_create_nonce( TablePress::nonce( 'copy_table', $table['id'] ) ); // @phpstan-ignore-line
+			$response['new_delete_nonce'] = wp_create_nonce( TablePress::nonce( 'delete_table', $table['id'] ) ); // @phpstan-ignore-line
 			$response['last_modified'] = TablePress::format_datetime( $table['last_modified'] ); // @phpstan-ignore-line
 			$response['last_editor'] = TablePress::get_user_display_name( $table['options']['last_editor'] ); // @phpstan-ignore-line
 		}

programming_language: PHP
filename: controller-frontend.php
change_type: ModificationType.MODIFY
diff: @@ -253,6 +253,8 @@ class TablePress_Frontend_Controller extends TablePress_Controller {
 		$commands = array();
 
 		foreach ( $this->shown_tables as $table_id => $table_store ) {
+			$table_id = (string) $table_id; // Ensure that the table ID is a string, as it comes from an array key where numeric strings are converted to integers.
+
 			if ( empty( $table_store['instances'] ) ) {
 				continue;
 			}
@@ -514,7 +516,7 @@ JS;
 		// Check, if a table with the given ID exists.
 		$table_id = (string) preg_replace( '/[^a-zA-Z0-9_-]/', '', $shortcode_atts['id'] );
 		if ( ! TablePress::$model_table->table_exists( $table_id ) ) {
-			$message = "[table &#8220;{$table_id}&#8221; not found /]<br />\n";
+			$message = "&#91;table “{$table_id}” not found /&#93;<br />\n";
 			/**
 			 * Filters the "Table not found" message.
 			 *
@@ -530,7 +532,7 @@ JS;
 		// Load table, with table data, options, and visibility settings.
 		$table = TablePress::$model_table->load( $table_id, true, true );
 		if ( is_wp_error( $table ) ) {
-			$message = "[table &#8220;{$table_id}&#8221; could not be loaded /]<br />\n";
+			$message = "&#91;table “{$table_id}” could not be loaded /&#93;<br />\n";
 			/**
 			 * Filters the "Table could not be loaded" message.
 			 *
@@ -544,7 +546,7 @@ JS;
 			return $message;
 		}
 		if ( isset( $table['is_corrupted'] ) && $table['is_corrupted'] ) {
-			$message = "<div>Attention: The internal data of table &#8220;{$table_id}&#8221; is corrupted!</div>";
+			$message = "<div>Attention: The internal data of table “{$table_id}” is corrupted!</div>";
 			/**
 			 * Filters the "Table data is corrupted" message.
 			 *
@@ -786,7 +788,7 @@ JS;
 		// Check, if a table with the given ID exists.
 		$table_id = preg_replace( '/[^a-zA-Z0-9_-]/', '', $shortcode_atts['id'] );
 		if ( ! TablePress::$model_table->table_exists( $table_id ) ) {
-			$message = "[table &#8220;{$table_id}&#8221; not found /]<br />\n";
+			$message = "&#91;table “{$table_id}” not found /&#93;<br />\n";
 			/** This filter is documented in controllers/controller-frontend.php */
 			$message = apply_filters( 'tablepress_table_not_found_message', $message, $table_id );
 			return $message;
@@ -795,7 +797,7 @@ JS;
 		// Load table, with table data, options, and visibility settings.
 		$table = TablePress::$model_table->load( $table_id, true, true );
 		if ( is_wp_error( $table ) ) {
-			$message = "[table &#8220;{$table_id}&#8221; could not be loaded /]<br />\n";
+			$message = "&#91;table “{$table_id}” could not be loaded /&#93;<br />\n";
 			/** This filter is documented in controllers/controller-frontend.php */
 			$message = apply_filters( 'tablepress_table_load_error_message', $message, $table_id, $table );
 			return $message;
@@ -860,7 +862,7 @@ JS;
 				$output = count( $table['data'][0] );
 				break;
 			default:
-				$output = "[table-info field &#8220;{$field}&#8221; not found in table &#8220;{$table_id}&#8221; /]<br />\n";
+				$output = "&#91;table-info field “{$field}” not found in table “{$table_id}” /&#93;<br />\n";
 				/**
 				 * Filters the "table info field not found" message.
 				 *

programming_language: PHP
filename: class-freemius.php
change_type: ModificationType.MODIFY
diff: @@ -1357,8 +1357,7 @@
 		}
 
 		function _run_garbage_collector() {
-			// @todo - Remove this check once the garbage collector is ready to be out of beta.
-			if ( true !== fs_get_optional_constant( 'WP_FS__ENABLE_GARBAGE_COLLECTOR', false ) ) {
+			if ( true !== fs_get_optional_constant( 'WP_FS__ENABLE_GARBAGE_COLLECTOR', true ) ) {
 				return;
 			}
 

programming_language: PHP
filename: class-fs-garbage-collector.php
change_type: ModificationType.MODIFY
diff: @@ -281,7 +281,7 @@
 			$has_updated_option = false;
 
 			foreach ( $users as $user_id => $user ) {
-				if ( ! isset( $user_has_install[ $user_id ] ) ) {
+				if ( ! isset( $user_has_install_map[ $user_id ] ) ) {
 					unset( $users[ $user_id ] );
 
 					foreach( $products_user_id_license_ids_map as $product_id => $user_id_license_ids_map ) {

programming_language: PHP
filename: start.php
change_type: ModificationType.MODIFY
diff: @@ -15,7 +15,7 @@
 	 *
 	 * @var string
 	 */
-	$this_sdk_version = '2.6.1';
+	$this_sdk_version = '2.6.2';
 
 	#region SDK Selection Logic --------------------------------------------------------------------
 

programming_language: PHP
filename: model-table.php
change_type: ModificationType.MODIFY
diff: @@ -233,9 +233,11 @@ class TablePress_Table_Model extends TablePress_Model {
 		// This loop now uses the WP cache.
 		$table_ids = array();
 		foreach ( $table_post as $table_id => $post_id ) {
-			$table_id = (string) $table_id;
+			$table_id = (string) $table_id; // Ensure that the table ID is a string, as it comes from an array key where numeric strings are converted to integers.
+
 			// Load table without data and options to save memory.
 			$table = $this->load( $table_id, false, false );
+
 			// Skip tables that could not be loaded properly.
 			if ( ! is_wp_error( $table ) ) {
 				$table_ids[] = $table_id;
@@ -527,9 +529,11 @@ class TablePress_Table_Model extends TablePress_Model {
 		}
 
 		foreach ( $tables['table_post'] as $table_id => $post_id ) {
-			$table_id = (string) $table_id;
+			$table_id = (string) $table_id; // Ensure that the table ID is a string, as it comes from an array key where numeric strings are converted to integers.
+
 			$this->model_post->delete( $post_id ); // Post Meta fields will be deleted automatically by that function.
 			unset( $tables['table_post'][ $table_id ] );
+
 			// Invalidate table output caches that belong to this table.
 			$this->invalidate_table_output_cache( $table_id );
 		}
@@ -1058,7 +1062,7 @@ class TablePress_Table_Model extends TablePress_Model {
 		$default_table = $this->get_table_template();
 
 		// Go through all tables (this loop now uses the WP cache).
-		foreach ( $table_post as $table_id => $post_id ) {
+		foreach ( $table_post as $post_id ) {
 			$table_options = $this->_get_table_options( $post_id );
 			if ( $remove_old_options ) {
 				// Remove old (i.e. no longer existing) Table Options.
@@ -1082,6 +1086,7 @@ class TablePress_Table_Model extends TablePress_Model {
 		}
 
 		foreach ( $table_post as $table_id => $post_id ) {
+			$table_id = (string) $table_id; // Ensure that the table ID is a string, as it comes from an array key where numeric strings are converted to integers.
 			$this->invalidate_table_output_cache( $table_id );
 		}
 	}

programming_language: PHP
filename: package-lock.json
change_type: ModificationType.MODIFY
diff: @@ -1,12 +1,12 @@
 {
 	"name": "@tablepress/tablepress",
-	"version": "2.2.4",
+	"version": "2.2.5",
 	"lockfileVersion": 3,
 	"requires": true,
 	"packages": {
 		"": {
 			"name": "@tablepress/tablepress",
-			"version": "2.2.4",
+			"version": "2.2.5",
 			"license": "GPL-2.0-only",
 			"devDependencies": {
 				"@wordpress/icons": "^9.36.0",

programming_language: JavaScript
filename: package.json
change_type: ModificationType.MODIFY
diff: @@ -1,6 +1,6 @@
 {
 	"name": "@tablepress/tablepress",
-	"version": "2.2.4",
+	"version": "2.2.5",
 	"description": "Embed beautiful and feature-rich tables into your posts and pages, without having to write code.",
 	"author": "Tobias Bäthge",
 	"license": "GPL-2.0-only",

programming_language: Go
filename: phpstan.neon.dist
change_type: ModificationType.MODIFY
diff: @@ -13,6 +13,8 @@ parameters:
 		- libraries/
 	bootstrapFiles:
 		- .phpstan/symbols.php
+	dynamicConstantNames:
+		- TABLEPRESS_IS_PLAYGROUND_PREVIEW
 	earlyTerminatingMethodCalls:
 		TablePress:
 			- redirect

programming_language: PHP
filename: readme.md
change_type: ModificationType.MODIFY
diff: @@ -68,6 +68,7 @@ After installing the plugin, you can create and manage tables on the “TablePre
 
 To insert a table into a post or page, add a “TablePress table” block in the block editor and select the desired table.
 
+Beginner-friendly step-by-step [tutorials, guides, and how-tos](https://tablepress.org/tutorials/) show how to achieve common and popular tasks with TablePress.
 Examples for common styling changes via “Custom CSS” code can be found on the [TablePress FAQ page](https://tablepress.org/faq/).
 You may also add certain features (like sorting, pagination, filtering, alternating row colors, row highlighting, print name and/or description, ...) by enabling the corresponding checkboxes on a table’s “Edit” screen.
 

programming_language: Markdown
filename: readme.txt
change_type: ModificationType.MODIFY
diff: @@ -1,11 +1,11 @@
 === TablePress - Tables in WordPress made easy ===
 Contributors: TobiasBg
 Donate link: https://tablepress.org/premium/?utm_source=wordpress.org&utm_medium=textlink&utm_content=donate-link
-Tags: table,spreadsheet,data,csv,excel,html,tables
+Tags: table, spreadsheet, csv, excel, tables
 Requires at least: 6.0
 Requires PHP: 7.2
 Tested up to: 6.4
-Stable tag: 2.2.4
+Stable tag: 2.2.5
 License: GPLv2
 License URI: https://www.gnu.org/licenses/gpl-2.0.html
 
@@ -97,6 +97,7 @@ After installing the plugin, you can create and manage tables on the "TablePress
 
 To insert a table into a post or page, add a "TablePress table" block in the block editor and select the desired table or use Shortcodes with common page builders.
 
+Beginner-friendly step-by-step [tutorials, guides, and how-tos](https://tablepress.org/tutorials/) show how to achieve common and popular tasks with TablePress.
 Examples for common styling changes via "Custom CSS" code can be found on the [TablePress FAQ page](https://tablepress.org/faq/).
 You may also add certain features (like sorting, pagination, filtering, alternating row colors, row highlighting, print name and/or description, ...) by enabling the corresponding checkboxes on a table's "Edit" screen.
 
@@ -106,6 +107,18 @@ You may also add certain features (like sorting, pagination, filtering, alternat
 
 Changes in recent versions are shown below. For earlier changes, please see the [changelog history](https://tablepress.org/info/#changelog).
 
+= Version 2.2.5 (January 30, 2024) =
+
+* *Security fix*: The URL import now properly blocks hosts of cloud providers’ metadata API endpoints to prevent data extraction.
+* When importing a table in the Excel format, floating point numbers are now detected and handled more reliably.
+* The detection of the JSON format when importing a table is now more reliable.
+* The “Copy”, “Export”, and “Delete” buttons/links on a table’s “Edit” screen now work again after a table ID was changed.
+* Error messages when a table could not be found and similar are now shown properly in modern themes.
+* The “Automatic Filtering” feature module now also allows using a slash in the filter term. (TablePress Pro and Max only.)
+* The “Debug and Version Information” section was cleaned up and updated with more relevant checks.
+* Updated external libraries to benefit from enhancements and bug fixes.
+* Cleaned up and simplified code, for easier future maintenance, to follow WordPress Coding Standards, and to offer helpful inline documentation.
+
 = Version 2.2.4 (December 11, 2023) =
 
 * The math formula calculation engine now properly handles quotation marks in text around embedded formulas.
@@ -132,11 +145,11 @@ Changes in recent versions are shown below. For earlier changes, please see the
 * The “Sorted” order of the “Row Order” premium feature module no longer raises an error. (TablePress Pro and Max only.)
 * Updated external libraries to benefit from enhancements and bug fixes.
 
-= Version 2.2.1 (November 2, 2023)=
+= Version 2.2.1 (November 2, 2023) =
 
 * Further protection against bugs in other plugins that interfere with the loading of JavaScript files, causing the TablePress admin screens to be unusable, was added.
 
-= Version 2.2 (November 2, 2023)=
+= Version 2.2 (November 2, 2023) =
 
 **Improvements around table styling**
 
@@ -175,8 +188,8 @@ Changes in recent versions are shown below. For earlier changes, please see the
 
 == Upgrade Notice ==
 
-= 2.2.4 =
-This update is a stability and maintenance release. Updating is highly recommended.
+= 2.2.5 =
+This update is a security and maintenance release. Updating is highly recommended.
 
 = 2.2 =
 This update is a feature, stability, maintenance, and compatibility release. Updating is highly recommended.

programming_language: Markdown
filename: tablepress.php
change_type: ModificationType.MODIFY
diff: @@ -4,13 +4,13 @@
  *
  * @package TablePress
  * @author Tobias Bäthge
- * @version 2.2.4
+ * @version 2.2.5
  *
  *
  * Plugin Name: TablePress
  * Plugin URI: https://tablepress.org/
  * Description: Embed beautiful and interactive tables into your WordPress website’s posts and pages, without having to write code!
- * Version: 2.2.4
+ * Version: 2.2.5
  * Requires at least: 6.0
  * Requires PHP: 7.2
  * Author: Tobias Bäthge
@@ -20,7 +20,7 @@
  * Donate URI: https://tablepress.org/donate/
  *
  *
- * Copyright 2012-2023 Tobias Bäthge
+ * Copyright 2012-2024 Tobias Bäthge
  *
  * TablePress is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, version 2, as published by
@@ -40,6 +40,10 @@
 // Prohibit direct script loading.
 defined( 'ABSPATH' ) || die( 'No direct script access allowed!' );
 
+if ( ! defined( 'TABLEPRESS_IS_PLAYGROUND_PREVIEW' ) ) {
+	define( 'TABLEPRESS_IS_PLAYGROUND_PREVIEW', false );
+}
+
 if ( function_exists( 'tb_tp_fs' ) ) {
 	tb_tp_fs()->set_basename( false, __FILE__ ); // @phpstan-ignore-line
 } else {
@@ -78,6 +82,7 @@ if ( function_exists( 'tb_tp_fs' ) ) {
 					'localhost' => false,
 				),
 				'is_live'           => true,
+				'anonymous_mode'    => TABLEPRESS_IS_PLAYGROUND_PREVIEW,
 			) );
 		}
 

programming_language: PHP
filename: test-tablepress_import.php
change_type: ModificationType.MODIFY
diff: @@ -137,7 +137,7 @@ class TablePress_Test_TablePress_Import extends TablePress_TestCase {
 			array( '1230', '1230', 'Integer with trailing zero', '1230' ),
 			array( '0123', '0123', 'Integer with leading zero', '0123' ),
 			array( '   123   ', '   123   ', 'Three spaces before and after an integer', '   123   ' ),
-			array( '123.5', '123.5', 'Float', '123.5' ),
+			array( '123.5', '123.5', 'Float with comma and period', '123.5' ),
 			array( '0123.5', '0123.5', 'Float with leading zero', '0123.5' ),
 			array( '123.50', '123.50', 'Float with trailing zero', '123.50' ),
 			array( '0123.50', '0123.50', 'Float with leading and trailing zero', '0123.50' ),
@@ -177,6 +177,8 @@ class TablePress_Test_TablePress_Import extends TablePress_TestCase {
 			array( '<span style="color:#FF0000;">red text <span style="color:#FFFF00;">yellow text</span></span>', 'H<sub>2</sub>O', 'left aligned', '' ),
 			array( '', 'H<sub>2</sub>O <span style="color:#00FA00;">green</span>', '<span style="color:#0432FF;">H<span style="color:#0432FF;"><sub>2</sub></span><span style="color:#0432FF;">O </span><span style="color:#FF2600;">gr</span>e<span style="color:#FF2600;">en</span></span>', '' ),
 			array( '1', '2', 'Styled formula does not get inline HTML after import', '=A61+B61' ),
+			array( '3.022', '-0.162', 'Floats that can cause floating point precision errors with the General format 1', '0.579' ),
+			array( '-3.022', '-0.051', 'Floats that can cause floating point precision errors with the General format 2', '0.094' ),
 		);
 
 		$this->assertSame( $expected_table_data, $imported_table_data );

programming_language: PHP
filename: view-about.php
change_type: ModificationType.MODIFY
diff: @@ -205,7 +205,6 @@ class TablePress_About_View extends TablePress_View {
 	 * @param array<string, mixed> $box  Information about the meta box.
 	 */
 	public function postbox_debug_version_information( array $data, array $box ): void {
-		$mysqli = ( isset( $GLOBALS['wpdb']->use_mysqli, $GLOBALS['wpdb']->dbh ) && $GLOBALS['wpdb']->use_mysqli );
 		?>
 		<p>
 			<strong><?php _e( 'Please provide this information in bug reports and support requests.', 'tablepress' ); ?></strong>
@@ -220,11 +219,14 @@ class TablePress_About_View extends TablePress_View {
 			<br />&middot; WordPress: <?php echo $GLOBALS['wp_version']; ?>
 			<br />&middot; Multisite: <?php echo is_multisite() ? 'yes' : 'no'; ?>
 			<br />&middot; PHP: <?php echo PHP_VERSION; ?>
-			<br />&middot; mysqli Extension: <?php echo $mysqli ? 'true' : 'false'; ?>
-			<br />&middot; mySQL (Server): <?php echo $mysqli ? mysqli_get_server_info( $GLOBALS['wpdb']->dbh ) : '<em>no mysqli</em>'; // phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_get_server_info ?>
-			<br />&middot; mySQL (Client): <?php echo $mysqli ? mysqli_get_client_info() : '<em>no mysqli</em>'; // phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_get_client_info ?>
-			<br />&middot; ZIP support: <?php echo $data['zip_support_available'] ? 'yes' : 'no'; ?>
-			<br />&middot; UTF-8 conversion: <?php echo ( function_exists( 'mb_detect_encoding' ) && function_exists( 'iconv' ) ) ? 'yes' : 'no'; ?>
+			<br />&middot; mySQL (Server): <?php echo isset( $GLOBALS['wpdb']->dbh ) ? mysqli_get_server_info( $GLOBALS['wpdb']->dbh ) : 'wpdb::$dbh not set'; // phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_get_server_info ?>
+			<br />&middot; mySQL (Client): <?php echo mysqli_get_client_info(); // phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_get_client_info ?>
+			<br />&middot; mbstring: <?php echo extension_loaded( 'mbstring' ) ? 'yes' : '<span style="color:#800000;font-weight:bold;">no</span>'; ?>
+			<br />&middot; ZipArchive: <?php echo class_exists( 'ZipArchive', false ) ? 'yes' : '<span style="color:#800000;font-weight:bold;">no</span>'; ?>
+			<br />&middot; DOMDocument: <?php echo class_exists( 'DOMDocument', false ) ? 'yes' : '<span style="color:#800000;font-weight:bold;">no</span>'; ?>
+			<br />&middot; simplexml_load_string: <?php echo function_exists( 'simplexml_load_string' ) ? 'yes' : '<span style="color:#800000;font-weight:bold;">no</span>'; ?>
+			<br />&middot; libxml_disable_entity_loader: <?php echo function_exists( 'libxml_disable_entity_loader' ) ? 'yes' : '<span style="color:#800000;font-weight:bold;">no</span>'; ?>
+			<br />&middot; UTF-8 conversion: <?php echo ( function_exists( 'mb_detect_encoding' ) && function_exists( 'iconv' ) ) ? 'yes' : '<span style="color:#800000;font-weight:bold;">no</span>'; ?>
 			<br />&middot; WP Memory Limit: <?php echo WP_MEMORY_LIMIT; ?>
 			<br />&middot; Server Memory Limit: <?php echo (int) @ini_get( 'memory_limit' ) . 'M'; // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged ?>
 			<br />&middot; WP_DEBUG: <?php echo WP_DEBUG ? 'true' : 'false'; ?>

programming_language: PHP
filename: view-edit.php
change_type: ModificationType.MODIFY
diff: @@ -66,7 +66,7 @@ class TablePress_Edit_View extends TablePress_View {
 		$this->admin_page->enqueue_style( 'jspreadsheet' );
 		$this->admin_page->enqueue_style( 'jsuites', array( 'tablepress-jspreadsheet' ) );
 		$this->admin_page->enqueue_style( 'edit', array( 'tablepress-jspreadsheet', 'tablepress-jsuites' ) );
-		if ( tb_tp_fs()->is_free_plan() ) {
+		if ( ! TABLEPRESS_IS_PLAYGROUND_PREVIEW && tb_tp_fs()->is_free_plan() ) {
 			$this->admin_page->enqueue_style( 'edit-features', array( 'tablepress-edit' ) );
 		}
 		$this->admin_page->enqueue_script( 'jspreadsheet' );
@@ -233,7 +233,7 @@ class TablePress_Edit_View extends TablePress_View {
 	</tr>
 </table>
 		<?php
-		if ( tb_tp_fs()->is_free_plan() ) :
+		if ( ! TABLEPRESS_IS_PLAYGROUND_PREVIEW && tb_tp_fs()->is_free_plan() ) :
 			?>
 			<div class="postbox premium-features">
 				<div>
@@ -281,6 +281,8 @@ class TablePress_Edit_View extends TablePress_View {
 		echo "tp.nonces = {};\n";
 		echo "tp.nonces.edit_table = '" . wp_create_nonce( TablePress::nonce( $this->action, $data['table']['id'] ) ) . "';\n";
 		echo "tp.nonces.preview_table = '" . wp_create_nonce( TablePress::nonce( 'preview_table', $data['table']['id'] ) ) . "';\n";
+		echo "tp.nonces.copy_table = '" . wp_create_nonce( TablePress::nonce( 'copy_table', $data['table']['id'] ) ) . "';\n";
+		echo "tp.nonces.delete_table = '" . wp_create_nonce( TablePress::nonce( 'delete_table', $data['table']['id'] ) ) . "';\n";
 		echo "tp.nonces.screen_options = '" . wp_create_nonce( TablePress::nonce( 'screen_options' ) ) . "';\n";
 
 		echo "tp.table = {};\n";
@@ -391,7 +393,7 @@ class TablePress_Edit_View extends TablePress_View {
 
 		echo '<p id="' . $box['id'] . '-submit" class="submit">';
 		if ( current_user_can( 'tablepress_preview_table', $data['table']['id'] ) ) {
-			echo '<a href="' . $preview_url . '" class="button button-large button-show-preview" target="_blank" data-shortcut="' . esc_attr( _x( '%1$sP', 'keyboard shortcut for Preview', 'tablepress' ) ) . '">' . __( 'Preview', 'tablepress' ) . '</a>';
+			echo '<a href="' . $preview_url . '" class="button button-large button-preview" target="_blank" data-shortcut="' . esc_attr( _x( '%1$sP', 'keyboard shortcut for Preview', 'tablepress' ) ) . '">' . __( 'Preview', 'tablepress' ) . '</a>';
 		}
 		?>
 			<input type="button" class="button button-primary button-large button-save-changes" value="<?php esc_attr_e( 'Save Changes', 'tablepress' ); ?>" data-shortcut="<?php echo esc_attr( _x( '%1$sS', 'keyboard shortcut for Save Changes', 'tablepress' ) ); ?>" />
@@ -419,13 +421,13 @@ class TablePress_Edit_View extends TablePress_View {
 		echo '<p class="submit">';
 		echo __( 'Other Actions', 'tablepress' ) . ':&nbsp; ';
 		if ( $user_can_copy_table ) {
-			echo '<a href="' . TablePress::url( array( 'action' => 'copy_table', 'item' => $data['table']['id'], 'return' => 'edit' ), true, 'admin-post.php' ) . '" class="button">' . __( 'Copy Table', 'tablepress' ) . '</a> ';
+			echo '<a href="' . TablePress::url( array( 'action' => 'copy_table', 'item' => $data['table']['id'], 'return' => 'edit' ), true, 'admin-post.php' ) . '" class="button button-copy">' . __( 'Copy Table', 'tablepress' ) . '</a> ';
 		}
 		if ( $user_can_export_table ) {
-			echo '<a href="' . TablePress::url( array( 'action' => 'export', 'table_id' => $data['table']['id'] ) ) . '" class="button">' . __( 'Export Table', 'tablepress' ) . '</a> ';
+			echo '<a href="' . TablePress::url( array( 'action' => 'export', 'table_id' => $data['table']['id'] ) ) . '" class="button button-export">' . __( 'Export Table', 'tablepress' ) . '</a> ';
 		}
 		if ( $user_can_delete_table ) {
-			echo '<a href="' . TablePress::url( array( 'action' => 'delete_table', 'item' => $data['table']['id'], 'return' => 'edit', 'return_item' => $data['table']['id'] ), true, 'admin-post.php' ) . '" class="button delete-link">' . __( 'Delete Table', 'tablepress' ) . '</a>';
+			echo '<a href="' . TablePress::url( array( 'action' => 'delete_table', 'item' => $data['table']['id'], 'return' => 'edit', 'return_item' => $data['table']['id'] ), true, 'admin-post.php' ) . '" class="button button-delete delete-link">' . __( 'Delete Table', 'tablepress' ) . '</a>';
 		}
 		echo '</p>';
 	}

programming_language: PHP
filename: view-editor_button_thickbox.php
change_type: ModificationType.MODIFY
diff: @@ -125,7 +125,7 @@ html {
 			printf( '<span class="subtitle">' . __( 'Search results for &#8220;%s&#8221;', 'tablepress' ) . '</span>', esc_html( wp_unslash( $_GET['s'] ) ) );
 		}
 		?>
-<form method="get" action="">
+<form method="get">
 	<input type="hidden" name="action" value="tablepress_<?php echo $this->action; ?>" />
 		<?php
 		wp_nonce_field( TablePress::nonce( $this->action ), '_wpnonce', false );

programming_language: PHP
filename: view-list.php
change_type: ModificationType.MODIFY
diff: @@ -211,7 +211,7 @@ class TablePress_List_View extends TablePress_View {
 			printf( '<span class="subtitle">' . __( 'Search results for &#8220;%s&#8221;', 'tablepress' ) . '</span>', esc_html( wp_unslash( $_GET['s'] ) ) );
 		}
 		?>
-<form method="get" action="">
+<form method="get">
 		<?php
 		if ( isset( $_GET['page'] ) ) {
 			echo '<input type="hidden" name="page" value="' . esc_attr( $_GET['page'] ) . '" />' . "\n";

programming_language: PHP