handsontable 18.1.1 → 18.1.2-rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/base.js +2 -2
  3. package/base.mjs +2 -2
  4. package/dataMap/metaManager/metaSchema.js +4 -2
  5. package/dataMap/metaManager/metaSchema.mjs +4 -2
  6. package/dist/handsontable.full.js +223 -44
  7. package/dist/handsontable.full.min.js +129 -129
  8. package/dist/handsontable.js +223 -44
  9. package/dist/handsontable.min.js +129 -129
  10. package/dist/themes/classic.js +2 -2
  11. package/dist/themes/classic.min.js +2 -2
  12. package/dist/themes/horizon.js +2 -2
  13. package/dist/themes/horizon.min.js +2 -2
  14. package/dist/themes/main.js +2 -2
  15. package/dist/themes/main.min.js +2 -2
  16. package/dist/themes/static/variables/colors/ant.js +2 -2
  17. package/dist/themes/static/variables/colors/ant.min.js +2 -2
  18. package/dist/themes/static/variables/colors/classic.js +2 -2
  19. package/dist/themes/static/variables/colors/classic.min.js +2 -2
  20. package/dist/themes/static/variables/colors/horizon.js +2 -2
  21. package/dist/themes/static/variables/colors/horizon.min.js +2 -2
  22. package/dist/themes/static/variables/colors/main.js +2 -2
  23. package/dist/themes/static/variables/colors/main.min.js +2 -2
  24. package/dist/themes/static/variables/colors/material.js +2 -2
  25. package/dist/themes/static/variables/colors/material.min.js +2 -2
  26. package/dist/themes/static/variables/colors/shadcn.js +2 -2
  27. package/dist/themes/static/variables/colors/shadcn.min.js +2 -2
  28. package/dist/themes/static/variables/density.js +2 -2
  29. package/dist/themes/static/variables/density.min.js +2 -2
  30. package/dist/themes/static/variables/helpers/iconsMap.js +2 -2
  31. package/dist/themes/static/variables/helpers/iconsMap.min.js +2 -2
  32. package/dist/themes/static/variables/icons/horizon.js +2 -2
  33. package/dist/themes/static/variables/icons/horizon.min.js +2 -2
  34. package/dist/themes/static/variables/icons/main.js +2 -2
  35. package/dist/themes/static/variables/icons/main.min.js +2 -2
  36. package/dist/themes/static/variables/sizing.js +2 -2
  37. package/dist/themes/static/variables/sizing.min.js +2 -2
  38. package/dist/themes/static/variables/tokens/classic.js +2 -2
  39. package/dist/themes/static/variables/tokens/classic.min.js +2 -2
  40. package/dist/themes/static/variables/tokens/horizon.js +2 -2
  41. package/dist/themes/static/variables/tokens/horizon.min.js +2 -2
  42. package/dist/themes/static/variables/tokens/main.js +2 -2
  43. package/dist/themes/static/variables/tokens/main.min.js +2 -2
  44. package/helpers/mixed.js +5 -5
  45. package/helpers/mixed.mjs +5 -5
  46. package/package.json +1 -1
  47. package/styles/handsontable.css +2 -2
  48. package/styles/handsontable.min.css +2 -2
  49. package/styles/handsontableStyles.js +1 -1
  50. package/styles/handsontableStyles.mjs +1 -1
  51. package/styles/ht-icons-horizon.min.css +2 -2
  52. package/styles/ht-icons-main.min.css +2 -2
  53. package/styles/ht-theme-classic-no-icons.min.css +2 -2
  54. package/styles/ht-theme-classic.min.css +2 -2
  55. package/styles/ht-theme-horizon-no-icons.min.css +2 -2
  56. package/styles/ht-theme-horizon.min.css +2 -2
  57. package/styles/ht-theme-main-no-icons.min.css +2 -2
  58. package/styles/ht-theme-main.min.css +2 -2
  59. package/utils/entitlementLicenseKey/constants.d.ts +7 -1
  60. package/utils/entitlementLicenseKey/constants.js +5 -1
  61. package/utils/entitlementLicenseKey/constants.mjs +6 -1
  62. package/utils/entitlementLicenseKey/encoding.d.ts +1 -1
  63. package/utils/entitlementLicenseKey/encoding.js +4 -1
  64. package/utils/entitlementLicenseKey/encoding.mjs +4 -1
  65. package/utils/entitlementLicenseKey/extractKeyData.d.ts +47 -8
  66. package/utils/entitlementLicenseKey/extractKeyData.js +155 -14
  67. package/utils/entitlementLicenseKey/extractKeyData.mjs +188 -23
  68. package/utils/entitlementLicenseKey/types.d.ts +5 -0
  69. package/utils/licenseBranding/index.js +2 -2
  70. package/utils/licenseBranding/index.mjs +2 -2
  71. package/utils/licenseNotification.js +2 -2
  72. package/utils/licenseNotification.mjs +2 -2
@@ -25,7 +25,7 @@
25
25
  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER ARISING FROM
26
26
  * USE OR INABILITY TO USE THIS SOFTWARE.
27
27
  *
28
- * Version: 18.1.1
29
- * Release date: 15/09/2026 (built at 15/09/2026 08:36:12)
28
+ * Version: 18.1.2-rc1
29
+ * Release date: 07/10/2026 (built at 07/10/2026 08:29:56)
30
30
  */
31
31
  .ht-theme-main,.ht-theme-main-dark,.ht-theme-main-dark-auto{--ht-sizing-size-0:0px;--ht-sizing-size-0-5:2px;--ht-sizing-size-1:4px;--ht-sizing-size-2:8px;--ht-sizing-size-1-5:6px;--ht-sizing-size-3:12px;--ht-sizing-size-4:16px;--ht-sizing-size-5:20px;--ht-sizing-size-6:24px;--ht-sizing-size-7:28px;--ht-sizing-size-8:32px;--ht-sizing-size-9:36px;--ht-sizing-size-10:40px;--ht-sizing-size-0-25:1px;--ht-density-cell-vertical:var(--ht-sizing-size-1);--ht-density-cell-horizontal:var(--ht-sizing-size-2);--ht-density-bars-horizontal:var(--ht-sizing-size-4);--ht-density-bars-vertical:var(--ht-sizing-size-2);--ht-density-gap:var(--ht-sizing-size-1);--ht-density-button-horizontal:var(--ht-sizing-size-3);--ht-density-button-vertical:var(--ht-sizing-size-1-5);--ht-density-dialog-horizontal:var(--ht-sizing-size-2);--ht-density-dialog-vertical:var(--ht-sizing-size-2);--ht-density-input-horizontal:var(--ht-sizing-size-3);--ht-density-input-vertical:var(--ht-sizing-size-1-5);--ht-density-menu-vertical:var(--ht-sizing-size-2);--ht-density-menu-horizontal:var(--ht-sizing-size-0);--ht-density-menu-item-vertical:var(--ht-sizing-size-1);--ht-density-menu-item-horizontal:var(--ht-sizing-size-3);--ht-colors-white:#fff;--ht-colors-black:#000;--ht-colors-primary-100:#6180ff;--ht-colors-primary-200:#5573f0;--ht-colors-primary-300:#4669f6;--ht-colors-primary-400:#2e56fc;--ht-colors-primary-500:#1a42e8;--ht-colors-primary-600:#1535bc;--ht-colors-palette-50:#f7f7f9;--ht-colors-palette-100:#e7e7e9;--ht-colors-palette-200:#b9b9bb;--ht-colors-palette-300:#a3a3a3;--ht-colors-palette-400:#68696c;--ht-colors-palette-500:#404144;--ht-colors-palette-600:#313132;--ht-colors-palette-700:#282829;--ht-colors-palette-800:#222;--ht-colors-palette-900:#1e1e1f;--ht-colors-palette-950:#050506;--ht-colors-transparent:#fff0;--ht-font-family:Inter;--ht-font-size:14px;--ht-font-size-small:12px;--ht-line-height:20px;--ht-line-height-small:18px;--ht-font-weight:400;--ht-letter-spacing:0px;--ht-border-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-accent-color:var(--lightningcss-light,var(--ht-colors-primary-500))var(--lightningcss-dark,var(--ht-colors-primary-300));--ht-foreground-color:var(--lightningcss-light,var(--ht-colors-palette-800))var(--lightningcss-dark,var(--ht-colors-palette-200));--ht-foreground-secondary-color:var(--lightningcss-light,var(--ht-colors-palette-400))var(--lightningcss-dark,var(--ht-colors-palette-300));--ht-background-color:var(--lightningcss-light,var(--ht-colors-white))var(--lightningcss-dark,var(--ht-colors-palette-950));--ht-background-secondary-color:var(--lightningcss-light,var(--ht-colors-palette-50))var(--lightningcss-dark,var(--ht-colors-palette-900));--ht-placeholder-color:var(--lightningcss-light,var(--ht-colors-palette-300))var(--lightningcss-dark,var(--ht-colors-palette-400));--ht-read-only-color:var(--lightningcss-light,var(--ht-colors-palette-400))var(--lightningcss-dark,var(--ht-colors-palette-300));--ht-disabled-color:var(--lightningcss-light,var(--ht-colors-palette-300))var(--lightningcss-dark,var(--ht-colors-palette-400));--ht-gap-size:var(--ht-density-gap);--ht-icon-size:var(--ht-sizing-size-4);--ht-table-transition:.15s;--ht-border-radius:var(--ht-sizing-size-1);--ht-bar-foreground-color:var(--ht-foreground-color);--ht-bar-background-color:var(--ht-background-secondary-color);--ht-bar-horizontal-padding:var(--ht-density-bars-horizontal);--ht-bar-vertical-padding:var(--ht-density-bars-vertical);--ht-shadow-color:var(--lightningcss-light,var(--ht-colors-palette-800))var(--lightningcss-dark,var(--ht-colors-palette-200));--ht-shadow-x:var(--ht-sizing-size-0);--ht-shadow-y:var(--ht-sizing-size-2);--ht-shadow-blur:var(--ht-sizing-size-4);--ht-shadow-opacity:8%;--ht-cell-horizontal-padding:var(--ht-density-cell-horizontal);--ht-cell-vertical-padding:var(--ht-density-cell-vertical);--ht-cell-horizontal-border-color:var(--ht-border-color);--ht-cell-vertical-border-color:var(--ht-border-color);--ht-cell-selection-border-color:var(--ht-accent-color);--ht-cell-selection-background-color:var(--lightningcss-light,var(--ht-colors-primary-400))var(--lightningcss-dark,var(--ht-colors-primary-200));--ht-cell-success-background-color:#37bc6c33;--ht-cell-error-background-color:#fa4d3233;--ht-cell-read-only-background-color:var(--ht-background-secondary-color);--ht-cell-autofill-size:var(--ht-sizing-size-1-5);--ht-cell-autofill-hit-area-size:var(--ht-sizing-size-3);--ht-cell-autofill-border-width:var(--ht-sizing-size-0-25);--ht-cell-autofill-border-radius:var(--ht-sizing-size-1);--ht-cell-autofill-border-color:var(--ht-background-color);--ht-cell-autofill-background-color:var(--ht-accent-color);--ht-cell-autofill-fill-border-color:var(--ht-foreground-color);--ht-cell-editor-border-width:2px;--ht-cell-editor-border-color:var(--ht-accent-color);--ht-cell-editor-foreground-color:var(--lightningcss-light,var(--ht-colors-palette-950))var(--lightningcss-dark,var(--ht-colors-white));--ht-cell-editor-background-color:var(--ht-background-color);--ht-cell-editor-shadow-blur-radius:0px;--ht-cell-editor-shadow-color:var(--ht-accent-color);--ht-cell-mobile-handle-size:var(--ht-sizing-size-3);--ht-cell-mobile-handle-border-width:var(--ht-sizing-size-0-25);--ht-cell-mobile-handle-border-radius:var(--ht-sizing-size-3);--ht-cell-mobile-handle-border-color:var(--ht-accent-color);--ht-cell-mobile-handle-background-color:var(--ht-accent-color);--ht-cell-mobile-handle-background-opacity:40%;--ht-cell-selection-handle-size:var(--ht-sizing-size-2);--ht-cell-selection-handle-length:var(--ht-sizing-size-4);--ht-cell-selection-handle-border-width:var(--ht-sizing-size-0-25);--ht-cell-selection-handle-border-radius:var(--ht-sizing-size-3);--ht-cell-selection-handle-border-color:var(--ht-accent-color);--ht-cell-selection-handle-background-color:var(--ht-background-color);--ht-header-font-weight:var(--ht-font-weight);--ht-header-foreground-color:var(--ht-foreground-color);--ht-header-background-color:var(--ht-background-secondary-color);--ht-header-highlighted-shadow-size:0px;--ht-header-highlighted-foreground-color:var(--lightningcss-light,var(--ht-colors-palette-950))var(--lightningcss-dark,var(--ht-colors-white));--ht-header-highlighted-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-header-active-border-color:var(--lightningcss-light,var(--ht-colors-primary-400))var(--lightningcss-dark,var(--ht-colors-primary-200));--ht-header-active-foreground-color:var(--ht-colors-white);--ht-header-active-background-color:var(--ht-accent-color);--ht-header-filter-background-color:var(--ht-cell-success-background-color);--ht-header-row-foreground-color:var(--ht-foreground-color);--ht-header-row-background-color:var(--ht-background-secondary-color);--ht-header-row-highlighted-foreground-color:var(--lightningcss-light,var(--ht-colors-palette-950))var(--lightningcss-dark,var(--ht-colors-white));--ht-header-row-highlighted-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-header-row-active-foreground-color:var(--ht-colors-white);--ht-header-row-active-background-color:var(--ht-accent-color);--ht-row-header-odd-background-color:var(--ht-header-row-background-color);--ht-row-header-even-background-color:var(--ht-header-row-background-color);--ht-row-cell-odd-background-color:var(--ht-background-color);--ht-row-cell-even-background-color:var(--ht-background-color);--ht-button-border-radius:var(--ht-sizing-size-1);--ht-button-horizontal-padding:var(--ht-density-button-horizontal);--ht-button-vertical-padding:var(--ht-density-button-vertical);--ht-primary-button-border-color:var(--ht-colors-transparent);--ht-primary-button-foreground-color:var(--ht-colors-white);--ht-primary-button-background-color:var(--ht-accent-color);--ht-primary-button-disabled-border-color:var(--ht-colors-transparent);--ht-primary-button-disabled-foreground-color:var(--ht-disabled-color);--ht-primary-button-disabled-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-primary-button-hover-border-color:var(--ht-colors-transparent);--ht-primary-button-hover-foreground-color:var(--ht-background-color);--ht-primary-button-hover-background-color:var(--lightningcss-light,var(--ht-colors-primary-600))var(--lightningcss-dark,var(--ht-colors-primary-100));--ht-primary-button-focus-border-color:var(--ht-background-color);--ht-primary-button-focus-foreground-color:var(--ht-background-color);--ht-primary-button-focus-background-color:var(--ht-accent-color);--ht-secondary-button-border-color:var(--ht-border-color);--ht-secondary-button-foreground-color:var(--ht-foreground-color);--ht-secondary-button-background-color:var(--ht-background-color);--ht-secondary-button-disabled-border-color:var(--ht-border-color);--ht-secondary-button-disabled-foreground-color:var(--ht-disabled-color);--ht-secondary-button-disabled-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-secondary-button-hover-border-color:var(--ht-border-color);--ht-secondary-button-hover-foreground-color:var(--ht-foreground-color);--ht-secondary-button-hover-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-secondary-button-focus-border-color:var(--ht-border-color);--ht-secondary-button-focus-foreground-color:var(--ht-foreground-color);--ht-secondary-button-focus-background-color:var(--ht-background-color);--ht-icon-button-border-radius:var(--ht-sizing-size-0-5);--ht-icon-button-large-border-radius:var(--ht-sizing-size-1);--ht-icon-button-large-padding:var(--ht-sizing-size-1);--ht-icon-button-border-color:var(--lightningcss-light,var(--ht-colors-palette-50))var(--lightningcss-dark,var(--ht-colors-palette-900));--ht-icon-button-background-color:var(--ht-background-secondary-color);--ht-icon-button-icon-color:var(--lightningcss-light,var(--ht-colors-palette-300))var(--lightningcss-dark,var(--ht-colors-palette-400));--ht-icon-button-hit-area-size:var(--ht-sizing-size-6);--ht-icon-button-hover-border-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-icon-button-hover-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-icon-button-hover-icon-color:var(--lightningcss-light,var(--ht-colors-palette-300))var(--lightningcss-dark,var(--ht-colors-palette-400));--ht-icon-button-active-border-color:var(--lightningcss-light,var(--ht-colors-primary-400))var(--lightningcss-dark,var(--ht-colors-primary-200));--ht-icon-button-active-background-color:var(--ht-accent-color);--ht-icon-button-active-icon-color:var(--ht-colors-white);--ht-icon-button-active-hover-border-color:var(--lightningcss-light,var(--ht-colors-primary-400))var(--lightningcss-dark,var(--ht-colors-primary-200));--ht-icon-button-active-hover-background-color:var(--lightningcss-light,var(--ht-colors-primary-400))var(--lightningcss-dark,var(--ht-colors-primary-200));--ht-icon-button-active-hover-icon-color:var(--ht-colors-white);--ht-collapse-button-border-radius:var(--ht-sizing-size-1);--ht-collapse-button-open-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-collapse-button-open-background-color:var(--lightningcss-light,var(--ht-colors-white))var(--lightningcss-dark,var(--ht-colors-palette-950));--ht-collapse-button-open-icon-color:var(--lightningcss-light,var(--ht-colors-palette-400))var(--lightningcss-dark,var(--ht-colors-palette-300));--ht-collapse-button-open-icon-active-color:var(--lightningcss-light,var(--ht-colors-palette-400))var(--lightningcss-dark,var(--ht-colors-palette-300));--ht-collapse-button-open-hover-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-collapse-button-open-hover-background-color:var(--lightningcss-light,var(--ht-colors-palette-50))var(--lightningcss-dark,var(--ht-colors-palette-900));--ht-collapse-button-open-hover-icon-color:var(--lightningcss-light,var(--ht-colors-palette-400))var(--lightningcss-dark,var(--ht-colors-palette-300));--ht-collapse-button-open-hover-icon-active-color:var(--lightningcss-light,var(--ht-colors-palette-400))var(--lightningcss-dark,var(--ht-colors-palette-300));--ht-collapse-button-close-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-collapse-button-close-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-collapse-button-close-icon-color:var(--lightningcss-light,var(--ht-colors-palette-400))var(--lightningcss-dark,var(--ht-colors-palette-300));--ht-collapse-button-close-icon-active-color:var(--lightningcss-light,var(--ht-colors-palette-400))var(--lightningcss-dark,var(--ht-colors-palette-300));--ht-collapse-button-close-hover-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-collapse-button-close-hover-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-collapse-button-close-hover-icon-color:var(--lightningcss-light,var(--ht-colors-palette-400))var(--lightningcss-dark,var(--ht-colors-palette-300));--ht-collapse-button-close-hover-icon-active-color:var(--lightningcss-light,var(--ht-colors-palette-400))var(--lightningcss-dark,var(--ht-colors-palette-300));--ht-link-color:var(--lightningcss-light,var(--ht-colors-primary-600))var(--lightningcss-dark,var(--ht-colors-primary-100));--ht-link-hover-color:var(--ht-accent-color);--ht-input-border-width:1px;--ht-input-border-radius:var(--ht-sizing-size-1);--ht-input-horizontal-padding:var(--ht-density-input-horizontal);--ht-input-vertical-padding:var(--ht-density-input-vertical);--ht-input-border-color:var(--ht-border-color);--ht-input-foreground-color:var(--ht-foreground-color);--ht-input-background-color:var(--ht-background-secondary-color);--ht-input-hover-border-color:var(--ht-border-color);--ht-input-hover-foreground-color:var(--ht-foreground-color);--ht-input-hover-background-color:var(--ht-background-color);--ht-input-disabled-border-color:var(--ht-border-color);--ht-input-disabled-foreground-color:var(--ht-disabled-color);--ht-input-disabled-background-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-input-focus-border-color:var(--ht-accent-color);--ht-input-focus-foreground-color:var(--ht-foreground-color);--ht-input-focus-background-color:var(--ht-background-color);--ht-checkbox-size:var(--ht-icon-size);--ht-checkbox-border-radius:var(--ht-sizing-size-1);--ht-checkbox-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-checkbox-background-color:var(--ht-background-color);--ht-checkbox-icon-color:var(--ht-colors-transparent);--ht-checkbox-focus-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-checkbox-focus-background-color:var(--ht-background-color);--ht-checkbox-focus-icon-color:var(--ht-colors-transparent);--ht-checkbox-focus-ring-color:var(--ht-accent-color);--ht-checkbox-disabled-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-checkbox-disabled-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-checkbox-disabled-icon-color:var(--ht-colors-transparent);--ht-checkbox-checked-border-color:var(--lightningcss-light,var(--ht-colors-primary-400))var(--lightningcss-dark,var(--ht-colors-primary-200));--ht-checkbox-checked-background-color:var(--ht-accent-color);--ht-checkbox-checked-icon-color:var(--ht-colors-white);--ht-checkbox-checked-focus-border-color:var(--ht-background-color);--ht-checkbox-checked-focus-background-color:var(--ht-accent-color);--ht-checkbox-checked-focus-icon-color:var(--ht-colors-white);--ht-checkbox-checked-disabled-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-checkbox-checked-disabled-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-checkbox-checked-disabled-icon-color:var(--ht-disabled-color);--ht-checkbox-indeterminate-border-color:var(--lightningcss-light,var(--ht-colors-primary-400))var(--lightningcss-dark,var(--ht-colors-primary-200));--ht-checkbox-indeterminate-background-color:var(--ht-accent-color);--ht-checkbox-indeterminate-icon-color:var(--ht-colors-white);--ht-checkbox-indeterminate-focus-border-color:var(--ht-background-color);--ht-checkbox-indeterminate-focus-background-color:var(--ht-accent-color);--ht-checkbox-indeterminate-focus-icon-color:var(--ht-colors-white);--ht-checkbox-indeterminate-disabled-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-600));--ht-checkbox-indeterminate-disabled-background-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-checkbox-indeterminate-disabled-icon-color:var(--ht-disabled-color);--ht-radio-size:var(--ht-icon-size);--ht-radio-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-radio-background-color:var(--ht-background-color);--ht-radio-icon-color:var(--ht-colors-transparent);--ht-radio-focus-border-color:var(--ht-border-color);--ht-radio-focus-background-color:var(--ht-background-color);--ht-radio-focus-icon-color:var(--ht-colors-transparent);--ht-radio-focus-ring-color:var(--ht-accent-color);--ht-radio-disabled-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-radio-disabled-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-radio-disabled-icon-color:var(--ht-colors-transparent);--ht-radio-checked-border-color:var(--ht-accent-color);--ht-radio-checked-background-color:var(--ht-background-color);--ht-radio-checked-icon-color:var(--ht-accent-color);--ht-radio-checked-focus-border-color:var(--lightningcss-light,var(--ht-colors-primary-400))var(--lightningcss-dark,var(--ht-colors-primary-200));--ht-radio-checked-focus-background-color:var(--ht-background-color);--ht-radio-checked-focus-icon-color:var(--lightningcss-light,var(--ht-colors-primary-400))var(--lightningcss-dark,var(--ht-colors-primary-200));--ht-radio-checked-disabled-border-color:var(--lightningcss-light,var(--ht-colors-palette-200))var(--lightningcss-dark,var(--ht-colors-palette-500));--ht-radio-checked-disabled-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-radio-checked-disabled-icon-color:var(--ht-disabled-color);--ht-move-backlight-color:var(--lightningcss-light,var(--ht-colors-palette-800))var(--lightningcss-dark,var(--ht-colors-palette-200));--ht-move-backlight-opacity:8%;--ht-move-indicator-color:var(--ht-accent-color);--ht-resize-indicator-color:var(--lightningcss-light,var(--ht-colors-palette-300))var(--lightningcss-dark,var(--ht-colors-palette-400));--ht-hidden-indicator-color:var(--lightningcss-light,var(--ht-colors-palette-300))var(--lightningcss-dark,var(--ht-colors-palette-400));--ht-menu-border-width:1px;--ht-menu-border-radius:var(--ht-sizing-size-1);--ht-menu-horizontal-padding:var(--ht-density-menu-horizontal);--ht-menu-vertical-padding:var(--ht-density-menu-vertical);--ht-menu-item-horizontal-padding:var(--ht-density-menu-item-horizontal);--ht-menu-item-vertical-padding:var(--ht-density-menu-item-vertical);--ht-menu-border-color:var(--ht-border-color);--ht-menu-shadow-x:var(--ht-shadow-x);--ht-menu-shadow-y:var(--ht-shadow-y);--ht-menu-shadow-blur:var(--ht-shadow-blur);--ht-menu-shadow-color:var(--lightningcss-light,var(--ht-colors-palette-950))var(--lightningcss-dark,var(--ht-colors-white));--ht-menu-shadow-opacity:8%;--ht-menu-item-hover-color:var(--lightningcss-light,var(--ht-colors-palette-800))var(--lightningcss-dark,var(--ht-colors-palette-200));--ht-menu-item-hover-color-opacity:4%;--ht-menu-item-active-color:var(--ht-accent-color);--ht-menu-item-active-color-opacity:8%;--ht-comments-textarea-horizontal-padding:var(--ht-density-cell-horizontal);--ht-comments-textarea-vertical-padding:var(--ht-density-cell-vertical);--ht-comments-textarea-border-width:1px;--ht-comments-textarea-border-color:var(--ht-colors-transparent);--ht-comments-textarea-foreground-color:var(--ht-foreground-color);--ht-comments-textarea-background-color:var(--ht-background-secondary-color);--ht-comments-textarea-focus-border-width:1px;--ht-comments-textarea-focus-border-color:var(--ht-accent-color);--ht-comments-textarea-focus-foreground-color:var(--ht-foreground-color);--ht-comments-textarea-focus-background-color:var(--ht-background-color);--ht-comments-indicator-size:var(--ht-sizing-size-1-5);--ht-comments-indicator-color:var(--ht-accent-color);--ht-license-horizontal-padding:var(--ht-bar-horizontal-padding);--ht-license-vertical-padding:var(--ht-bar-vertical-padding);--ht-license-foreground-color:var(--ht-bar-foreground-color);--ht-license-background-color:var(--ht-bar-background-color);--ht-pagination-bar-foreground-color:var(--ht-bar-foreground-color);--ht-pagination-bar-background-color:var(--ht-bar-background-color);--ht-pagination-bar-horizontal-padding:var(--ht-bar-horizontal-padding);--ht-pagination-bar-vertical-padding:var(--ht-bar-vertical-padding);--ht-pagination-button-border-color:var(--ht-pagination-bar-background-color);--ht-pagination-button-foreground-color:var(--ht-foreground-secondary-color);--ht-pagination-button-background-color:var(--ht-pagination-bar-background-color);--ht-pagination-button-hover-border-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-pagination-button-hover-foreground-color:var(--ht-foreground-color);--ht-pagination-button-hover-background-color:var(--lightningcss-light,var(--ht-colors-palette-100))var(--lightningcss-dark,var(--ht-colors-palette-700));--ht-pagination-button-disabled-border-color:var(--ht-pagination-bar-background-color);--ht-pagination-button-disabled-foreground-color:var(--ht-disabled-color);--ht-pagination-button-disabled-background-color:var(--ht-pagination-bar-background-color);--ht-pagination-button-focus-border-color:var(--ht-accent-color);--ht-pagination-button-focus-foreground-color:var(--ht-foreground-color);--ht-pagination-button-focus-background-color:var(--ht-pagination-bar-background-color);--ht-dialog-semi-transparent-background-color:var(--lightningcss-light,var(--ht-colors-white))var(--lightningcss-dark,var(--ht-colors-palette-950));--ht-dialog-semi-transparent-background-opacity:80%;--ht-dialog-solid-background-color:var(--lightningcss-light,var(--ht-colors-white))var(--lightningcss-dark,var(--ht-colors-palette-950));--ht-dialog-content-padding-horizontal:var(--ht-density-dialog-horizontal);--ht-dialog-content-padding-vertical:var(--ht-density-dialog-vertical);--ht-dialog-content-border-radius:var(--ht-sizing-size-2);--ht-dialog-content-background-color:var(--ht-background-secondary-color);--ht-notification-foreground-color:var(--ht-foreground-color);--ht-notification-background-color:var(--ht-background-color);--ht-notification-border-color:var(--ht-background-color);--ht-notification-success-accent:#37bc6c;--ht-notification-warning-accent:#fbe952;--ht-notification-error-accent:#fa4d32;--ht-chip-background:var(--ht-background-secondary-color);--ht-chip-border-radius:var(--ht-sizing-size-0-5);--ht-chip-vertical-padding:var(--ht-sizing-size-0);--ht-chip-horizontal-padding:var(--ht-sizing-size-0-5);--ht-chip-gap:var(--ht-sizing-size-1);--ht-scrollbar-border-radius:var(--ht-sizing-size-2);--ht-scrollbar-track-color:var(--ht-background-secondary-color);--ht-scrollbar-thumb-color:var(--lightningcss-light,var(--ht-colors-palette-300))var(--lightningcss-dark,var(--ht-colors-palette-400))}.ht-theme-main{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}.ht-theme-main-dark{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}.ht-theme-main-dark-auto{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark}@media (prefers-color-scheme:dark){.ht-theme-main-dark-auto{--lightningcss-light: ;--lightningcss-dark:initial}}[class*=ht-theme-main] .htDropdownMenu table tbody tr td.htSubmenu .htItemWrapper:after,[class*=ht-theme-main] .htContextMenu table tbody tr td.htSubmenu .htItemWrapper:after,[class*=ht-theme-main] .htFiltersConditionsMenu table tbody tr td.htSubmenu .htItemWrapper:after{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M6.64648 10.9393L9.93938 7.64644L6.64648 4.35354%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .ht-page-size-section__select-wrapper:after{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cg opacity=%270.6%27%3E%3Cpath d=%27M11.5859 6L8.29304 9.29289L5.00015 6%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/g%3E%3C/svg%3E");-webkit-mask-size:contain}[class*=ht-theme-main] .changeType:before,[class*=ht-theme-main] .htUISelectCaption:after,.htAutocompleteArrow:after{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M11.0002 6.66663C11.4262 6.66663 11.6487 7.15963 11.3917 7.47813L11.3537 7.52013L8.35372 10.5201C8.26762 10.6062 8.15307 10.6579 8.03156 10.6656C7.91005 10.6732 7.78992 10.6363 7.69372 10.5616L7.64672 10.5201L4.64672 7.52013L4.60522 7.47313L4.57822 7.43463L4.55122 7.38663L4.54272 7.36863L4.52922 7.33513L4.51322 7.28113L4.50822 7.25463L4.50322 7.22463L4.50122 7.19613V7.13713L4.50372 7.10813L4.50822 7.07813L4.51322 7.05213L4.52922 6.99813L4.54272 6.96463L4.57772 6.89863L4.61022 6.85363L4.64672 6.81313L4.69372 6.77163L4.73222 6.74463L4.78022 6.71763L4.79822 6.70913L4.83172 6.69563L4.88572 6.67963L4.91222 6.67463L4.94222 6.66963L4.97072 6.66763L11.0002 6.66663Z%27 fill=%27currentColor%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .columnSorting.sortAction.ascending:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M8.00008 12.6667L8.00008 3.33335M8.00008 3.33335L5.33342 6.00002M8.00008 3.33335L10.6667 6.00002%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .columnSorting.sortAction.descending:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M8.00004 3.33331V12.6666M8.00004 12.6666L10.6667 9.99998M8.00004 12.6666L5.33337 9.99998%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .ht-page-navigation-section .ht-page-first:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M11.0713 4.64188L7.72115 7.99203L11.0713 11.3422M4.92936 4.08353L4.92936 11.3422%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E");-webkit-mask-size:contain}[class*=ht-theme-main] [dir=rtl] .ht-page-navigation-section .ht-page-first:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M4.9292 4.64188L8.27934 7.99203L4.9292 11.3422M11.0711 4.08353V11.3422%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E");-webkit-mask-size:contain}[class*=ht-theme-main] .ht-page-navigation-section .ht-page-prev:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M9.49268 11.2929L6.19978 8.00001L9.49268 4.70712%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] [dir=rtl] .ht-page-navigation-section .ht-page-prev:before,[class*=ht-theme-main] .ht-page-navigation-section .ht-page-next:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M6.64648 10.9393L9.93938 7.64644L6.64648 4.35354%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] [dir=rtl] .ht-page-navigation-section .ht-page-next:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M9.49268 11.2929L6.19978 8.00001L9.49268 4.70712%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .ht-page-navigation-section .ht-page-last:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M4.9292 4.64188L8.27934 7.99203L4.9292 11.3422M11.0711 4.08353V11.3422%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E");-webkit-mask-size:contain}[class*=ht-theme-main] [dir=rtl] .ht-page-navigation-section .ht-page-last:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M11.0713 4.64188L7.72115 7.99203L11.0713 11.3422M4.92936 4.08353L4.92936 11.3422%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E");-webkit-mask-size:contain}[class*=ht-theme-main] .htDropdownMenu table tbody tr td .htItemWrapper span.selected:after,[class*=ht-theme-main] .htContextMenu table tbody tr td .htItemWrapper span.selected:after,[class*=ht-theme-main] .htFiltersConditionsMenu table tbody tr td .htItemWrapper span.selected:after{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M3.33337 8.00002L6.66671 11.3334L13.3334 4.66669%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .htCheckboxRendererInput{-webkit-appearance:none;appearance:none}[class*=ht-theme-main] .htCheckboxRendererInput:after{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M5 8L7 10L11 6%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] th.beforeHiddenColumn:after{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml,%3Csvg width=%2710%27 height=%2710%27 viewBox=%270 0 10 10%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M6.08482 1.35771L6.11503 1.3551H6.17649L6.2067 1.35771L6.23795 1.36239L6.26503 1.3676L6.32128 1.38427L6.35618 1.39833L6.42493 1.43479L6.4718 1.46864L6.51399 1.50667L6.55722 1.55562L6.58534 1.59573L6.61347 1.64573L6.62232 1.66448L6.63639 1.69937L6.65305 1.75562L6.65826 1.78323L6.66347 1.81448L6.66555 1.84417L6.66659 1.87489V8.12489C6.66659 8.56864 6.15305 8.80042 5.82128 8.53271L5.77753 8.49312L2.65253 5.36812C2.56286 5.27844 2.50899 5.15912 2.50103 5.03254C2.49307 4.90596 2.53157 4.78083 2.6093 4.68062L2.65253 4.63167L5.77753 1.50667L5.82649 1.46344L5.86659 1.43531L5.91659 1.40719L5.93534 1.39833L5.97024 1.38427L6.02649 1.3676L6.05409 1.36239L6.08482 1.35771Z%27 fill=%27currentColor%27/%3E%3C/svg%3E");-webkit-mask-size:contain}[class*=ht-theme-main] th.afterHiddenColumn:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml,%3Csvg width=%2710%27 height=%2710%27 viewBox=%270 0 10 10%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M3.33337 1.87499C3.33337 1.43124 3.84692 1.19947 4.17869 1.46718L4.22244 1.50676L7.34744 4.63176C7.43711 4.72145 7.49098 4.84077 7.49894 4.96735C7.5069 5.09392 7.4684 5.21905 7.39067 5.31926L7.34744 5.36822L4.22244 8.49322L4.17348 8.53645L4.13337 8.56457L4.08337 8.5927L4.06462 8.60155L4.02973 8.61562L3.97348 8.63228L3.94587 8.63749L3.91462 8.6427L3.88494 8.64478L3.85421 8.64582L3.82348 8.64478L3.79327 8.64218L3.76202 8.63749L3.73494 8.63228L3.67869 8.61562L3.64379 8.60155L3.57504 8.5651L3.52817 8.53124L3.48598 8.49322L3.44275 8.44426L3.41462 8.40416L3.3865 8.35416L3.37764 8.33541L3.36358 8.30051L3.34692 8.24426L3.34171 8.21666L3.3365 8.18541L3.33442 8.15572L3.33337 1.87499Z%27 fill=%27currentColor%27/%3E%3C/svg%3E");-webkit-mask-size:contain}[class*=ht-theme-main] th.beforeHiddenRow:after{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%278%27 height=%278%27 viewBox=%270 0 8 8%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M3.76425 2.43099C3.82165 2.3736 3.89801 2.33913 3.97902 2.33403C4.06003 2.32894 4.14012 2.35358 4.20425 2.40333L4.23558 2.43099L6.23558 4.43099L6.26325 4.46233L6.28125 4.48799L6.29925 4.51999L6.30492 4.53199L6.31392 4.55433L6.32458 4.59033L6.32792 4.60799L6.33125 4.62799L6.33258 4.64699L6.33325 4.66666L6.33258 4.68633L6.33092 4.70566L6.32792 4.72566L6.32458 4.74299L6.31392 4.77899L6.30492 4.80133L6.28158 4.84533L6.25992 4.87533L6.23558 4.90233L6.20425 4.92999L6.17858 4.94799L6.14658 4.96599L6.13458 4.97166L6.11225 4.98066L6.07625 4.99133L6.05858 4.99466L6.03858 4.99799L6.01958 4.99933L5.99992 4.99999H1.99992C1.71592 4.99999 1.56758 4.67133 1.73892 4.45899L1.76425 4.43099L3.76425 2.43099Z%27 fill=%27currentColor%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] th.afterHiddenRow:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%278%27 height=%278%27 viewBox=%270 0 8 8%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M5.9999 3C6.2839 3 6.43224 3.32867 6.2609 3.541L6.23557 3.569L4.23557 5.569C4.17817 5.62639 4.10181 5.66087 4.0208 5.66596C3.93979 5.67106 3.8597 5.64642 3.79557 5.59667L3.76424 5.569L1.76424 3.569L1.73657 3.53767L1.71857 3.512L1.70057 3.48L1.6949 3.468L1.6859 3.44567L1.67524 3.40967L1.6719 3.392L1.66857 3.372L1.66724 3.353V3.31367L1.6689 3.29433L1.6719 3.27433L1.67524 3.257L1.6859 3.221L1.6949 3.19867L1.71824 3.15467L1.7399 3.12467L1.76424 3.09767L1.79557 3.07L1.82124 3.052L1.85324 3.034L1.86524 3.02833L1.88757 3.01933L1.92357 3.00867L1.94124 3.00533L1.96124 3.002L1.98024 3.00067L5.9999 3Z%27 fill=%27currentColor%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .collapsibleIndicator:before,[class*=ht-theme-main] .ht_nestingButton:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M4.33325 8H11.6666%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .collapsibleIndicator.collapsed:before,[class*=ht-theme-main] .ht_nestingButton.ht_nestingExpand:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath fill-rule=%27evenodd%27 clip-rule=%27evenodd%27 d=%27M7.49988 11.6667C7.49988 11.9428 7.72374 12.1667 7.99988 12.1667C8.27602 12.1667 8.49988 11.9428 8.49988 11.6667V8.50002H11.6666C11.9427 8.50002 12.1666 8.27616 12.1666 8.00002C12.1666 7.72388 11.9427 7.50002 11.6666 7.50002H8.49988V4.33337C8.49988 4.05723 8.27602 3.83337 7.99988 3.83337C7.72374 3.83337 7.49988 4.05723 7.49988 4.33337V7.50002H4.33325C4.05711 7.50002 3.83325 7.72388 3.83325 8.00002C3.83325 8.27616 4.05711 8.50002 4.33325 8.50002H7.49988V11.6667Z%27 fill=%27currentColor%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .htUIRadio>input[type=radio]:after{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Ccircle cx=%278%27 cy=%278%27 r=%274%27 fill=%27currentColor%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .ht-multi-select-chip-remove:before,[class*=ht-theme-main] .ht-notification__close:before{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M12 4L4 12M4 4L12 12%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}[class*=ht-theme-main] .ht-multi-select-editor-search-icon{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%2732%27 height=%2732%27 viewBox=%270 0 32 32%27 fill=%27none%27%3E%3Cg opacity=%270.5%27%3E%3Cpath d=%27M28 28L20 20M4 13.3333C4 14.559 4.24141 15.7727 4.71046 16.905C5.1795 18.0374 5.86699 19.0663 6.73367 19.933C7.60035 20.7997 8.62925 21.4872 9.76162 21.9562C10.894 22.4253 12.1077 22.6667 13.3333 22.6667C14.559 22.6667 15.7727 22.4253 16.905 21.9562C18.0374 21.4872 19.0663 20.7997 19.933 19.933C20.7997 19.0663 21.4872 18.0374 21.9562 16.905C22.4253 15.7727 22.6667 14.559 22.6667 13.3333C22.6667 12.1077 22.4253 10.894 21.9562 9.76162C21.4872 8.62925 20.7997 7.60035 19.933 6.73367C19.0663 5.86699 18.0374 5.1795 16.905 4.71046C15.7727 4.24141 14.559 4 13.3333 4C12.1077 4 10.894 4.24141 9.76162 4.71046C8.62925 5.1795 7.60035 5.86699 6.73367 6.73367C5.86699 7.60035 5.1795 8.62925 4.71046 9.76162C4.24141 10.894 4 12.1077 4 13.3333Z%27 stroke=%27black%27 stroke-width=%272%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/g%3E%3C/svg%3E");-webkit-mask-size:contain}[class*=ht-theme-main] .ht-multi-select-editor-item-selected input:after{width:var(--ht-icon-size);height:var(--ht-icon-size);background-color:currentColor;-webkit-mask-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width=%2716%27 height=%2716%27 viewBox=%270 0 16 16%27 fill=%27none%27 xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cpath d=%27M5 8L7 10L11 6%27 stroke=%27currentColor%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27/%3E%3C/svg%3E%0A");-webkit-mask-size:contain}
@@ -1,10 +1,16 @@
1
1
  /**
2
- * The length of the checksum (SHA-512 as hex) that closes the machine-readable
2
+ * The length of the checksum that closes the machine-readable
3
3
  * block of every entitlement license key.
4
4
  *
5
5
  * @type {number}
6
6
  */
7
7
  export declare const CHECKSUM_LENGTH = 128;
8
+ /**
9
+ * The length of the value a current key stores for its text.
10
+ *
11
+ * @type {number}
12
+ */
13
+ export declare const PROSE_DIGEST_LENGTH = 64;
8
14
  /**
9
15
  * The two mutually exclusive date fields of a product entry. Exactly one of
10
16
  * them is present:
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The length of the checksum (SHA-512 as hex) that closes the machine-readable
2
+ * The length of the checksum that closes the machine-readable
3
3
  * block of every entitlement license key.
4
4
  *
5
5
  * @type {number}
@@ -35,11 +35,15 @@ _export(exports, {
35
35
  get NO_UI_WARNS_FLAG () {
36
36
  return NO_UI_WARNS_FLAG;
37
37
  },
38
+ get PROSE_DIGEST_LENGTH () {
39
+ return PROSE_DIGEST_LENGTH;
40
+ },
38
41
  get TRIAL_FLAG () {
39
42
  return TRIAL_FLAG;
40
43
  }
41
44
  });
42
45
  const CHECKSUM_LENGTH = 128;
46
+ const PROSE_DIGEST_LENGTH = 64;
43
47
  const DATE_FIELDS = [
44
48
  'usage_until',
45
49
  'release_until'
@@ -1,9 +1,14 @@
1
1
  /**
2
- * The length of the checksum (SHA-512 as hex) that closes the machine-readable
2
+ * The length of the checksum that closes the machine-readable
3
3
  * block of every entitlement license key.
4
4
  *
5
5
  * @type {number}
6
6
  */ export const CHECKSUM_LENGTH = 128;
7
+ /**
8
+ * The length of the value a current key stores for its text.
9
+ *
10
+ * @type {number}
11
+ */ export const PROSE_DIGEST_LENGTH = 64;
7
12
  /**
8
13
  * The two mutually exclusive date fields of a product entry. Exactly one of
9
14
  * them is present:
@@ -55,4 +55,4 @@ export declare function base64ToString(base64: string): string | null;
55
55
  * @param {string} isoDate The date to parse.
56
56
  * @returns {number|null}
57
57
  */
58
- export declare function parseIsoDateToTimestamp(isoDate: string): number | null;
58
+ export declare function parseIsoDateToTimestamp(isoDate: unknown): number | null;
@@ -138,7 +138,10 @@ function base64ToString(base64) {
138
138
  return bytes === null ? null : utf8BytesToString(bytes);
139
139
  }
140
140
  function parseIsoDateToTimestamp(isoDate) {
141
- const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(`${isoDate}`);
141
+ // Only a string is a date. Checked before the text test on purpose: an array
142
+ // like `['2027-08-12']` stringifies to a valid date and would otherwise pass,
143
+ // and an object whose `toString` is not a function would throw.
144
+ const match = typeof isoDate === 'string' ? /^(\d{4})-(\d{2})-(\d{2})$/.exec(isoDate) : null;
142
145
  if (match === null) {
143
146
  return null;
144
147
  }
@@ -149,7 +149,10 @@
149
149
  * @param {string} isoDate The date to parse.
150
150
  * @returns {number|null}
151
151
  */ export function parseIsoDateToTimestamp(isoDate) {
152
- const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(`${isoDate}`);
152
+ // Only a string is a date. Checked before the text test on purpose: an array
153
+ // like `['2027-08-12']` stringifies to a valid date and would otherwise pass,
154
+ // and an object whose `toString` is not a function would throw.
155
+ const match = typeof isoDate === 'string' ? /^(\d{4})-(\d{2})-(\d{2})$/.exec(isoDate) : null;
153
156
  if (match === null) {
154
157
  return null;
155
158
  }
@@ -1,4 +1,36 @@
1
1
  import type { EntitlementKeyData, ProductEntitlement } from './types';
2
+ /**
3
+ * Brings the human-readable text of a key to the form the key protects.
4
+ *
5
+ * Only the whitespace, its escaped forms, and the Unicode composition are
6
+ * ignored. A mail client that rewraps the text (also between two CJK
7
+ * characters or inside a word) or collapses a blank line, a `.env` file that
8
+ * saves a line break as `\n`, or a system that stores "u" + U+0308 instead of
9
+ * U+00FC leaves the key valid. A changed, added, or removed letter, digit, or
10
+ * symbol does not.
11
+ * Exported for the test key builder; the library calls `extractEntitlementKeyData`.
12
+ *
13
+ * @param {string} prose The text in front of the machine-readable block.
14
+ * @returns {string}
15
+ */
16
+ export declare function canonicalizeProse(prose: string): string;
17
+ /**
18
+ * Computes the checksum that closes the block. It must match the canonical
19
+ * reader in every key format, so Handsontable 18.1 keeps reading newer keys.
20
+ * Exported for the test key builder.
21
+ *
22
+ * @param {string} encodedPayload The encoded payload.
23
+ * @returns {string}
24
+ */
25
+ export declare function computePayloadChecksum(encodedPayload: string): string;
26
+ /**
27
+ * Computes the value a current key stores for its text. Exported for the test
28
+ * key builder.
29
+ *
30
+ * @param {string} canonicalProse The text, already passed through `canonicalizeProse`.
31
+ * @returns {string}
32
+ */
33
+ export declare function computeProseDigest(canonicalProse: string): string;
2
34
  /**
3
35
  * Adds an own, ordinary property.
4
36
  *
@@ -18,19 +50,26 @@ export declare function defineOwn(target: object, key: string, value: unknown):
18
50
  /**
19
51
  * Extracts the machine-readable data from an entitlement license key.
20
52
  *
21
- * The checksum is verified first, so the returned data is guaranteed to belong
22
- * to an intact block. A malformed or tampered key reads as `null` - reporting
23
- * an invalid key is the caller's job, not this function's.
53
+ * The key is verified first, so the returned data is guaranteed to belong to
54
+ * an intact key. A malformed or tampered key reads as `null` - reporting an
55
+ * invalid key is the caller's job, not this function's.
56
+ *
57
+ * A current key protects its text as well: edited or removed text (the bare
58
+ * `[...]` block), or anything but whitespace after the block, reads as `null`.
59
+ * A key in the earlier format reads the way Handsontable 18.1 reads it. The
60
+ * verification rules are those of the canonical reader in the private
61
+ * `license-key` repository.
24
62
  *
25
- * Only the bracketed block matters. The prose in front of it is neither parsed
26
- * nor covered by the checksum, so the caller may pass the whole key or just the
27
- * `[...]` block, and rewrapped or re-pasted prose still validates. The block
28
- * itself has to be intact: its alphabet has no whitespace, so a newline inside
29
- * it makes the key unreadable, exactly as it does for the key generator.
63
+ * The caller passes the whole key. The text is never parsed, and its
64
+ * whitespace and Unicode composition are ignored, so rewrapped or re-pasted
65
+ * text still validates. Whitespace inside the block is ignored too, so a
66
+ * block wrapped by a mail client still validates.
30
67
  *
31
68
  * Unknown products, capability tokens and flags are all tolerated, so nothing
32
69
  * about reading a key depends on the commercial vocabulary.
33
70
  *
71
+ * The result is frozen. Copy an array before sorting or changing it.
72
+ *
34
73
  * @param {string} licenseKey The license key to extract the data from.
35
74
  * @returns {EntitlementKeyData|null}
36
75
  */
@@ -9,6 +9,15 @@ function _export(target, all) {
9
9
  });
10
10
  }
11
11
  _export(exports, {
12
+ get canonicalizeProse () {
13
+ return canonicalizeProse;
14
+ },
15
+ get computePayloadChecksum () {
16
+ return computePayloadChecksum;
17
+ },
18
+ get computeProseDigest () {
19
+ return computeProseDigest;
20
+ },
12
21
  get defineOwn () {
13
22
  return defineOwn;
14
23
  },
@@ -23,13 +32,63 @@ const _constants = require("./constants");
23
32
  const _sha512 = require("./sha512");
24
33
  const _encoding = require("./encoding");
25
34
  /**
26
- * The alphabet of the encoded payload - URL-safe base64 without padding. The
27
- * checksum (lowercase hex) is a subset of it, which is what lets the two be
28
- * split by a fixed length from the right.
35
+ * The alphabets of the two parts of the machine-readable block. The second
36
+ * part has a fixed length, so the two are split from the right.
29
37
  *
30
38
  * @type {RegExp}
31
39
  */ const ENCODED_PAYLOAD = /^[A-Za-z0-9\-_]+$/;
32
40
  const CHECKSUM = /^[0-9a-f]+$/;
41
+ /**
42
+ * The whitespace the reader ignores, in the text and inside the block: TAB,
43
+ * LF, VT, FF, CR, SPACE, NO-BREAK SPACE,
44
+ * OGHAM SPACE MARK, the U+2000-U+200A spaces, LINE SEPARATOR, PARAGRAPH
45
+ * SEPARATOR, NARROW NO-BREAK SPACE, MEDIUM MATHEMATICAL SPACE, IDEOGRAPHIC
46
+ * SPACE, and the BOM.
47
+ *
48
+ * Listed explicitly instead of `\s`, whose set has changed between JavaScript
49
+ * engines (U+180E) and differs in other languages (U+0085), so it matches the
50
+ * key generator exactly.
51
+ *
52
+ * @type {RegExp}
53
+ */ const PROSE_WHITESPACE = /[\t\n\v\f\r \u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+/g;
54
+ /**
55
+ * A line break or tab that was saved as text - a backslash followed by "n",
56
+ * "r", or "t" - also ignored.
57
+ *
58
+ * Several places a key is stored keep a line break that way rather than as a
59
+ * real one: a single-quoted or unquoted `.env` value, Docker's `--env-file`,
60
+ * and many CI secret fields. The block survives that intact, so without this
61
+ * a genuine key would fail only because of how it was stored. The generator
62
+ * strips backslashes from every free-text field, so a key it issues never
63
+ * carries one of its own.
64
+ *
65
+ * @type {RegExp}
66
+ */ const ESCAPED_WHITESPACE = /\\[nrt]/g;
67
+ /**
68
+ * Removes every escaped line break or tab (`\n`, `\r`, `\t` saved as text) and
69
+ * then every whitespace character, in that order.
70
+ *
71
+ * The block is one long word, so a mail client or an editor that wraps the key
72
+ * can break it across lines, and a `.env` file can save that line break as the
73
+ * text `\n`. The block's alphabet has neither, so removing them cannot change
74
+ * a genuine block.
75
+ *
76
+ * @param {string} text The text to remove the whitespace from.
77
+ * @returns {string}
78
+ */ function removeWhitespace(text) {
79
+ return text.replace(ESCAPED_WHITESPACE, '').replace(PROSE_WHITESPACE, '');
80
+ }
81
+ function canonicalizeProse(prose) {
82
+ // NFC runs last: a line break between a letter and its combining mark (an
83
+ // NFD copy rewrapped there) has to be gone before the two can compose.
84
+ return removeWhitespace(prose).normalize('NFC');
85
+ }
86
+ function computePayloadChecksum(encodedPayload) {
87
+ return (0, _sha512.sha512)((0, _encoding.stringToUtf8Bytes)(encodedPayload));
88
+ }
89
+ function computeProseDigest(canonicalProse) {
90
+ return (0, _sha512.sha512)((0, _encoding.stringToUtf8Bytes)(canonicalProse)).slice(0, _constants.PROSE_DIGEST_LENGTH);
91
+ }
33
92
  /**
34
93
  * Reports own-property presence without trusting a payload's inherited or
35
94
  * overridden `hasOwnProperty`.
@@ -66,6 +125,39 @@ const CHECKSUM = /^[0-9a-f]+$/;
66
125
  */ function isStringArray(value) {
67
126
  return Array.isArray(value) && value.every((item)=>typeof item === 'string');
68
127
  }
128
+ /**
129
+ * Freezes the value and everything nested in it. The read result is shared
130
+ * between callers (see the memo below), so a caller that sorted or pushed into
131
+ * it would silently rewrite what the next caller reads.
132
+ *
133
+ * It walks with an explicit stack, not by recursion. An unknown extra field is
134
+ * kept as it is, and a key can nest one thousands of levels deep - recursion
135
+ * would then overflow the call stack and throw out of the reader, where a key
136
+ * is only ever allowed to read as data or as `null`.
137
+ *
138
+ * @param {*} value The value to freeze.
139
+ * @returns {*}
140
+ */ function deepFreeze(value) {
141
+ const pending = [
142
+ value
143
+ ];
144
+ while(pending.length > 0){
145
+ const current = pending.pop();
146
+ if (isFreezable(current)) {
147
+ Object.freeze(current);
148
+ Object.keys(current).forEach((key)=>pending.push(current[key]));
149
+ }
150
+ }
151
+ return value;
152
+ }
153
+ /**
154
+ * Narrows an unknown value to an object (or array) that is not frozen yet.
155
+ *
156
+ * @param {*} value The value to check.
157
+ * @returns {boolean}
158
+ */ function isFreezable(value) {
159
+ return value !== null && typeof value === 'object' && !Object.isFrozen(value);
160
+ }
69
161
  function defineOwn(target, key, value) {
70
162
  Object.defineProperty(target, key, {
71
163
  value,
@@ -104,7 +196,7 @@ function defineOwn(target, key, value) {
104
196
  if (presentDateFields.length !== 1) {
105
197
  return null;
106
198
  }
107
- if ((0, _encoding.parseIsoDateToTimestamp)(`${entry[presentDateFields[0]]}`) === null) {
199
+ if ((0, _encoding.parseIsoDateToTimestamp)(entry[presentDateFields[0]]) === null) {
108
200
  return null;
109
201
  }
110
202
  if (!isNonNegativeInteger(entry.notice) || !isNonNegativeInteger(entry.grace)) {
@@ -129,6 +221,41 @@ function defineOwn(target, key, value) {
129
221
  defineOwn(normalized, presentDateFields[0], entry[presentDateFields[0]]);
130
222
  return normalized;
131
223
  }
224
+ /**
225
+ * Reads the format version of a payload. Returns `null` for a value no
226
+ * generator writes. A version newer than this reader knows is accepted, so a
227
+ * build already in the field keeps reading newer keys.
228
+ *
229
+ * @param {object} payload The decoded payload.
230
+ * @returns {number|null}
231
+ */ function readFormatVersion(payload) {
232
+ // Own properties only, so a value another script put on `Object.prototype`
233
+ // cannot change how a key is read.
234
+ if (!hasOwn(payload, 'v')) {
235
+ return 1;
236
+ }
237
+ if (!isNonNegativeInteger(payload.v) || payload.v < 2) {
238
+ return null;
239
+ }
240
+ return payload.v;
241
+ }
242
+ /**
243
+ * Checks that the text of a current key is intact and that nothing but
244
+ * whitespace follows its block. A key always states its terms, so the bare
245
+ * block is rejected. A key in the earlier format is read the way Handsontable
246
+ * 18.1 reads it.
247
+ *
248
+ * @param {object} payload The decoded payload.
249
+ * @param {string} prose The text in front of the block.
250
+ * @param {string} textAfterBlock The text after the block.
251
+ * @returns {boolean}
252
+ */ function coversItsText(payload, prose, textAfterBlock) {
253
+ if (canonicalizeProse(textAfterBlock) !== '') {
254
+ return false;
255
+ }
256
+ const canonicalProse = canonicalizeProse(prose);
257
+ return canonicalProse !== '' && hasOwn(payload, 'prose') && typeof payload.prose === 'string' && computeProseDigest(canonicalProse) === payload.prose;
258
+ }
132
259
  /**
133
260
  * Reads and verifies one key. Split out from the memoized public entry point so
134
261
  * the memo can wrap every exit path uniformly.
@@ -146,7 +273,7 @@ function defineOwn(target, key, value) {
146
273
  if (blockEnd === -1) {
147
274
  return null;
148
275
  }
149
- const content = licenseKey.slice(blockStart + 1, blockEnd);
276
+ const content = removeWhitespace(licenseKey.slice(blockStart + 1, blockEnd));
150
277
  if (content.length <= _constants.CHECKSUM_LENGTH) {
151
278
  return null;
152
279
  }
@@ -155,7 +282,7 @@ function defineOwn(target, key, value) {
155
282
  if (!ENCODED_PAYLOAD.test(encodedPayload) || !CHECKSUM.test(checksum)) {
156
283
  return null;
157
284
  }
158
- if ((0, _sha512.sha512)((0, _encoding.stringToUtf8Bytes)(encodedPayload)) !== checksum) {
285
+ if (computePayloadChecksum(encodedPayload) !== checksum) {
159
286
  return null;
160
287
  }
161
288
  const payloadJson = (0, _encoding.base64ToString)(encodedPayload);
@@ -171,6 +298,13 @@ function defineOwn(target, key, value) {
171
298
  if (!isPlainObject(payload) || !isPlainObject(payload.products)) {
172
299
  return null;
173
300
  }
301
+ const version = readFormatVersion(payload);
302
+ if (version === null) {
303
+ return null;
304
+ }
305
+ if (version >= 2 && !coversItsText(payload, licenseKey.slice(0, blockStart), licenseKey.slice(blockEnd + 1))) {
306
+ return null;
307
+ }
174
308
  const products = {};
175
309
  const entries = payload.products;
176
310
  let malformed = false;
@@ -185,22 +319,29 @@ function defineOwn(target, key, value) {
185
319
  if (malformed) {
186
320
  return null;
187
321
  }
188
- return {
322
+ return deepFreeze({
323
+ version,
189
324
  products
190
- };
325
+ });
191
326
  }
192
327
  // The license key is read twice per grid init - the bottom bar
193
328
  // (`initLicenseNotification`) and the branding UI (`initLicenseBranding`) each resolve the license
194
- // state - and reading runs the full SHA-512 + base64 + JSON parse. A one-entry memo on the key makes
195
- // the second read free. The returned data is treated as read-only by every caller, so sharing one
329
+ // state - and reading runs the full verification and decoding. A one-entry memo on the key makes
330
+ // the second read free. The returned data is frozen, as in the canonical reader, so sharing one
196
331
  // object is safe.
197
332
  let memoizedKey = null;
198
333
  let memoizedData = null;
199
334
  function extractEntitlementKeyData(licenseKey) {
200
- const key = `${licenseKey}`;
201
- if (key !== memoizedKey) {
202
- memoizedKey = key;
203
- memoizedData = readEntitlementKeyData(key);
335
+ if (typeof licenseKey !== 'string') {
336
+ return null;
337
+ }
338
+ if (licenseKey !== memoizedKey) {
339
+ // Read first, remember second. Were the key remembered before the read,
340
+ // a read that throws would leave the new key paired with the previous
341
+ // key's data, and the next read of the new key would return it.
342
+ const data = readEntitlementKeyData(licenseKey);
343
+ memoizedKey = licenseKey;
344
+ memoizedData = data;
204
345
  }
205
346
  return memoizedData;
206
347
  }