Plugin Directory

Changeset 3345284


Ignore:
Timestamp:
08/15/2025 07:18:40 PM (6 months ago)
Author:
barb0ss
Message:

Updated to v1.7.0

Location:
squeeze
Files:
107 added
27 edited

Legend:

Unmodified
Added
Removed
  • squeeze/trunk/assets/css/admin.css

    r3311866 r3345284  
    382382  margin-inline-start: 0.5em;
    383383}
     384.squeeze-settings-example {
     385  max-width: fit-content;
     386  display: inline-block;
     387  margin-inline-start: var(--squeeze-spacing-m);
     388  /*opacity: 0.5;
     389
     390    &.enabled {
     391        opacity: 1;
     392    }*/
     393}
     394.squeeze-settings-example.squeeze-settings-example--webp_replace_urls {
     395  display: block;
     396  margin-inline-start: 0;
     397  margin-top: var(--squeeze-spacing-m);
     398}
     399.squeeze-settings-example .squeeze-box--fieldset {
     400  display: flex;
     401  gap: var(--squeeze-spacing-m);
     402}
     403.squeeze-settings-example .squeeze-box--fieldset .squeeze-box-content {
     404  gap: var(--squeeze-spacing-s);
     405}
     406.squeeze-settings-example .squeeze-box--fieldset .squeeze-box-content p {
     407  display: flex;
     408  justify-content: space-between;
     409  gap: var(--squeeze-spacing-m);
     410}
     411.squeeze-settings-example .squeeze-box--fieldset .squeeze-box-content .striked {
     412  text-decoration: line-through;
     413  color: var(--squeeze-error-color);
     414}
     415.squeeze-settings-example .squeeze-box--fieldset .squeeze-box-content .greened {
     416  color: var(--squeeze-success-color);
     417}
     418.squeeze-settings-example .squeeze-box--fieldset .squeeze-box-content img {
     419  max-width: 100%;
     420  height: auto;
     421}
    384422.form-table tr.squeeze_setting_restore_defaults {
    385423  display: none;
     
    387425.form-table tr:has(.squeeze-hidden) {
    388426  display: none;
     427}
     428.form-table tr.squeeze-legacy-option {
     429  opacity: 0.5;
     430}
     431.form-table tr.squeeze-legacy-option:hover {
     432  opacity: 1;
    389433}
    390434.js .squeeze-single-file-upload-notice:has(+ .html-uploader) {
     
    466510  gap: var(--squeeze-spacing-s);
    467511}
    468 .squeeze-path-list input[type="text"].squeeze-path-list__item {
     512.squeeze-path-list input[type="text"].squeeze-path-list__input {
    469513  min-width: 15rem;
    470514  font-family: monospace;
     
    473517  background-color: var(--squeeze-border-color);
    474518  padding: var(--squeeze-spacing-xs) var(--squeeze-spacing-s);
     519}
     520.squeeze-path-list__item {
     521  position: relative;
     522  display: flex;
     523  align-items: center;
     524  gap: var(--squeeze-spacing-s);
     525}
     526.squeeze-path-list__remove {
     527  background: none;
     528  border: 0;
     529  padding: 0;
     530  cursor: pointer;
     531  color: var(--squeeze-error-color);
     532  width: 1.5rem;
     533  height: 1.5rem;
     534}
     535.squeeze-path-list__remove:disabled {
     536  opacity: 0.5;
     537  cursor: not-allowed;
     538}
     539.squeeze-path-list__remove .squeeze-icon {
     540  width: 1.5rem;
     541  height: 1.5rem;
     542  fill: currentColor;
    475543}
    476544.media-log-wrapper {
     
    622690  width: auto;
    623691}
     692body.settings_page_squeeze-account .nav-tab[href*="#squeeze_account"] {
     693  display: none !important;
     694}
     695body.media_page_squeeze-bulk .wrap .nav-tab-wrapper {
     696  display: none !important;
     697}
    624698/*# sourceMappingURL=admin.css.map */
  • squeeze/trunk/assets/css/admin.css.map

    r3311866 r3345284  
    1 {"version":3,"sources":["admin.less"],"names":[],"mappings":"AAAA;EACI,yBAAyB,oCAAzB;EACA,kCAAA;EACA,gCAAA;EACA,gCAAA;EACA,8BAAA;EACA,8BAAA;EACA,4BAAA;EACA,+BAAA;EACA,8BAAA;EACA,6BAAA;EACA,uCAAA;EACA,2BAAA;EACA,0BAAA;EACA,6BAAA;EACA,uCAAA;EACA,wDAAA;EACA,8DAAA;EACA,0DAAA;EACA,mCAAA;EACA,4BAAA;EACA,2BAAA;EACA,yBAAA;EACA,2BAAA;EACA,6BAAA;EACA,kCAAA;EACA,qCAAA;EACA,uCAAA;EAEA,uBAAA;EACA,sBAAA;;AAGJ;EAEI;IAAK,2BAAA;;;AAGT;EACI;IAAK,WAAW,cAAX;;;AAGT,YAAa,KAAI;EACb,mBAAA;;AAGJ;EACI,kBAAkB,wBAAlB;EACA,eAAe,4BAAf;EACA,eAAe,wBAAf;EACA,SAAS,wBAAT;EACA,kBAAA;EACA,YAAY,yBAAZ;;;;AAEA,YAAC,YAAC;EACE,yBAAA;EACA,0BAAA;;AAGJ,YAAC;EACG,eAAe,kCAAf;EACA,YAAY,+BAAZ;EACA,kBAAkB,0BAAlB;EACA,qBAAA;;AAJJ,YAAC,UAMG;EACI,KAAK,wBAAL;;AAIR,YAAC;AAAS,YAAC;EACP,aAAA;EACA,8BAAA;EACA,mBAAA;EACA,gBAAgB,wBAAhB;EACA,yBAAyB,2BAAzB;;AALJ,YAAC,OAOG;AAPM,YAAC,OAOP;EACI,SAAA;EACA,WAAW,gCAAX;EACA,gBAAA;;AAGJ,YAbH,OAaI;AAAD,YAbO,OAaN;EACG,aAAA;EACA,KAAK,wBAAL;EACA,sBAAA;;AAIR,YAAC;EACG,aAAa,wBAAb;EACA,iBAAA;EACA,mBAAA;EACA,sBAAsB,2BAAtB;;AAGJ,YAAC;EACG,aAAA;EACA,sBAAA;EACA,KAAK,wBAAL;;AAEA,YALH,QAKI;EACG,aAAA;EACA,KAAK,wBAAL;EACA,mBAAA;EACA,8BAAA;EACA,eAAA;;AAGJ,YAbH,QAaI;EACG,aAAA;EACA,sBAAA;EACA,KAAK,wBAAL;;AAIR,YAAC;EACG,aAAA;EACA,uBAAuB,UAAU,mBAAjC;EACA,UAAU,yBAAV;;AAEA,QAA0B;EAA1B,YALH;IAMO,0BAAA;;;AAGJ,YATH,UASI;EACG,aAAA;EACA,sBAAA;EACA,KAAK,wBAAL;EACA,kBAAA;;AAEA,YAfP,UASI,KAMI,IAAI,eAAe;EAChB,SAAS,EAAT;EACA,kBAAA;EACA,MAAA;EACA,OAAO,KAAK,+BAAZ;EACA,SAAA;EACA,uBAAuB,2BAAvB;;AAIR,YAzBH,UAyBI;EACG,aAAA;EACA,KAAK,wBAAL;EACA,mBAAA;EACA,8BAAA;EACA,mBAAA;EACA,kBAAA;;AAEA,YAjCP,UAyBI,KAQI;EACG,SAAS,EAAT;EACA,kBAAA;EACA,KAAK,KAAK,+BAAV;EACA,QAAA;EACA,OAAA;EACA,sBAAsB,2BAAtB;;AAMZ,YAAC;EACG,mBAAA;;AADJ,YAAC,UAGG;EACI,2BAAA;;AAxHZ,YA6HI,MACI;EACI,YAAY,yBAAZ;;AA/HZ,YAmII;EACI,oBAAA;;AApIR,YAuII,MAAK;AAvIT,YAwII,MAAK;AAxIT,YAyII,MAAK;AAzIT,YA0II,MAAK;AA1IT,YA2II;AA3IJ,YA4II;EACI,kBAAkB,2BAAlB;EACA,oBAAA;;AA9IR,YAiJI;EACI,eAAA;EACA,WAAA;EACA,eAAe,kCAAf;;AApJR,YAuJI,MAAK;EACD,6BAAA;EACA,sBAAA;EACA,cAAc,4BAAd;;AAEA,YALJ,MAAK,cAKA;EAEG,kBAAkB,2BAAlB;EACA,QAAQ,sBAAR;;AAEJ,YAVJ,MAAK,cAUA;EAEG,kBAAkB,2BAAlB;EACA,QAAQ,sBAAR;;AAGJ,YAhBJ,MAAK,cAgBA;EACG,YAAY,4BAAZ;EACA,kBAAA;EACA,YAAY,KAAK,4BAAjB;EACA,YAAY,gCAAZ;;AAEJ,YAtBJ,MAAK,cAsBA;EACG,YAAY,4BAAZ;EACA,kBAAA;EACA,YAAY,KAAK,4BAAjB;EACA,YAAY,gCAAZ;;AAEJ,YA5BJ,MAAK,cA4BA;EACG,YAAY,4BAAZ;;AAGJ,YAhCJ,MAAK,cAgCC;EACE,sBAAA;EACA,0BAAA;;AAzLZ,YA6LI;EACI,aAAA;EACA,eAAe,wBAAf;;AAEA,YAJJ,EAIK;EACG,gBAAA;;AAlMZ,YAsMI,sBAEI;AAxMR,YAuMI,kCACI;EACI,MAAM,0BAAN;;AAMR,aAAC;EACG,aAAA;EACA,KAAK,wBAAL;EACA,mBAAA;;AAEA,aALH,YAKI;EACG,aAAA;EACA,KAAK,wBAAL;EACA,sBAAA;;AAEA,aAVP,YAKI,KAKI;EACG,WAAW,iCAAX;EACA,gBAAA;;AAGJ,aAfP,YAKI,KAUI,MACG;EACI,4CAAA;;AAMZ,aAvBH,YAuBI;EACG,aAAA;EACA,mBAAA;EACA,uBAAA;EACA,kBAAA;EACA,yBAAA;;AAEA,aA9BP,YAuBI,MAOI;EACG,QAAQ,0BAAR;EACA,cAAc,0BAAd;;AAGJ,aAnCP,YAuBI,MAYI;EACG,QAAQ,4BAAR;EACA,cAAc,KAAK,+BAAnB;EACA,qBAAA;EAEA,kBAAkB,mCAAlB;EAEA,WAAW,cAAX;EACA,wBAAA;EACA,QAAQ,0CAA0C,0CAAlD;EACA,8CAAA;EACA,yCAAA;;AAGJ,aAjDP,YAuBI,MA0BI;EACG,WAAW,iCAAX;;AAMhB;EACI,WAAA;EACA,YAAA;EACA,MAAM,4BAAN;EACA,2BAAA;EACA,0BAAA;;AAGJ;EACI,WAAW,mCAAX;EACA,OAAO,mCAAP;EACA,cAAA;EACA,eAAA;;AAGJ;EACI,kBAAkB,8BAAlB;EACA,OAAO,yBAAP;EACA,SAAS,wBAAT;EACA,eAAe,kCAAf;EACA,aAAA;EACA,8BAAA;;AAEA,eAAC,eAAC;EACE,kBAAkB,4BAAlB;;AAGJ,eAAC,SACG;EACI,WAAW,iCAAX;;AAdZ,eAkBI;EACI,MAAM,yBAAN;EACA,cAAA;EACA,aAAA;EACA,SAAA;EACA,SAAA;;AAIR;EACI,aAAA;EACA,cAAA;EACA,kBAAkB,0BAAlB;EACA,qBAAA;;AAEA,iBAAC,IAAI;EACD,aAAA;;AAIR,iBAAkB;EACd,qBAAA;;AAEJ;EACI,qBAAA;EACA,WAAA;;AAGJ;EACI,sBAAA;EACA,OAAO,mCAAP;EACA,WAAW,gCAAX;EACA,kBAAA;;AAEA,wBAAE;EACE,YAAY,wBAAZ;;AAKR,KAAK,iBAAiB;EAClB,kBAAA;EACA,UAAA;EACA,QAAQ,4BAA4B,KAAK,4BAAzC;;AAEA,KALC,iBAAiB,oBAKhB;EACE,kBAAA;EACA,eAAe,KAAK,4BAApB;EACA,aAAa,KAAK,gCAAlB;;AAEA,KAVH,iBAAiB,oBAKhB,QAKG;EACG,SAAS,EAAT;EACA,kBAAA;EACA,cAAA;EACA,OAAA;EACA,MAAA;EACA,OAAO,KAAK,4BAAZ;;EACA,QAAQ,KAAK,4BAAb;;EACA,eAAe,KAAK,4BAApB;;EACA,YAAY,0BAAZ;EACA,kBAAkB,2BAAlB;EACA,oBAAA;;AAGJ,KAxBH,iBAAiB,oBAKhB,QAmBG;EACG,SAAS,EAAT;EACA,kBAAA;EACA,cAAA;EACA,SAAA;EACA,QAAA;EACA,OAAO,KAAK,4BAAZ;;EACA,QAAQ,KAAK,4BAAb;;EACA,eAAe,KAAK,4BAApB;;EACA,YAAY,0BAAZ;EACA,kBAAkB,2BAAlB;EACA,oBAAA;;AAEJ,KArCH,iBAAiB,oBAKhB,QAgCG,MAAM;EACH,YAAY,gCAAZ;;AAKA,KA3CP,iBAAiB,oBAyCjB,QACK,QACG;EACG,aAAa,KAAK,4BAAlB;;AAEJ,KA9CP,iBAAiB,oBAyCjB,QACK,QAIG;EACG,YAAY,4BAAZ;;AAMJ,KArDP,iBAAiB,oBAmDjB,cACK,QACG;EACG,YAAY,gCAAZ;;AAQJ,KA9DP,iBAAiB,oBA0DjB,SACK,QAGG;AAAS,KA9DjB,iBAAiB,oBA0DjB,SACK,QAGa;EACP,YAAA;;AAOhB;EACI,kBAAA;;AAEJ;EACI,0BAAA;;AAEJ,WACI,GAAE;EACE,aAAA;;AAFR,WAII,GAAE,IAAI;EACF,aAAA;;AAIR,GAAI,mCAAkC,IAAI;EACtC,cAAA;;AAGJ;EACI,SAAS,wBAAT;EACA,YAAA;EACA,eAAe,4BAAf;EACA,YAAA;EACA,eAAA;EACA,YAAY,yBAAZ;EACA,gBAAA;;AAPJ,oBASI;EACI,gBAAgB,wBAAhB;;AAVR,oBAaI,0CACI;EACI,MAAM,yBAAN;EACA,SAAA;;AAhBZ,oBAoBI;EACI,WAAA;;AAGR;EACI,gBAAA;EACA,cAAA;EACA,SAAS,0BAAT;;AAHJ,4BAKI;EACI,4CAAA;;AAGR;EACI,aAAA;EACA,uBAAA;EACA,KAAK,wBAAL;EACA,sBAAA;;AAEA,eAAE,gBAAC;EACC,aAAA;EACA,mBAAA;EACA,KAAK,wBAAL;;AAEA,eALF,gBAAC,OAKG;EACE,cAAc,wBAAd;EACA,+DAAA;EACA,wCAAA;EACA,4BAAA;EACA,iBAAiB,wBAAjB;;AAIR,eAAC;EACG,YAAA;;AAGJ,eAAE;EACE,cAAc,wBAAd;;AAIA,eADH,IAAI,SACC;EACE,aAAA;;AAMA,eAFP,OACK,yBACI;EACE,8DAAA;;AArChB,eA0CI;EACI,eAAA;EACA,0BAAA;EACA,4BAAA;EACA,6BAAA;;AAEA,eANJ,MAMK;EACG,OAAO,4BAAP;;AAjDZ,eAqDI,MAAK;AArDT,eAqD4B,MAAK;EACzB,SAAA;;AAKR;EACI,aAAA;EACA,sBAAA;EACA,KAAK,wBAAL;;AAEA,kBAAE,MAAK,aAAa,kBAAC;EACjB,gBAAA;EACA,sBAAA;EACA,SAAA;EACA,gBAAA;EACA,kBAAkB,2BAAlB;EACA,SAAS,0BAA0B,wBAAnC;;AAIR;EACI,aAAA;EACA,sBAAA;EACA,KAAK,wBAAL;EACA,SAAS,wBAAT;EACA,eAAe,kCAAf;EACA,kBAAkB,0BAAlB;EACA,kBAAA;;AAPJ,kBASI;EACI,SAAA;EACA,aAAA;EACA,KAAK,wBAAL;EACA,mBAAA;EACA,kBAAA;EACA,UAAA;;AAfR,kBASI,GAQI;EACI,SAAA;EACA,aAAA;EACA,cAAA;;AApBZ,kBAuBI;EACI,sBAAA;;AAxBR,kBA0BI;EACI,aAAA;;AAEA,kBAHJ,0BAGK;EACG,cAAA;;AA9BZ,kBAiCI,MAAK;EACD,SAAA;EACA,sBAAsB,2BAAtB;EACA,yBAAyB,2BAAzB;;AAIR;EACI,aAAA;EACA,KAAK,yBAAL;EACA,kBAAA;EACA,sBAAsB,yBAAtB;EACA,kBAAA;;AAEA,kBAAC;EACG,SAAS,EAAT;EACA,kBAAA;EACA,WAAA;EACA,aAAA;EACA,QAAA;EACA,kBAAA;EACA,QAAQ,wBAAwB,yBAAhC;EACA,uBAAuB,2BAAvB;EACA,yBAAyB,2BAAzB;EACA,2BAA2B,4BAA3B;EACA,YAAY,yBAAZ;;AAEJ,kBAAC;EACG,SAAS,EAAT;EACA,kBAAA;EACA,WAAA;EACA,QAAA;EACA,aAAA;EACA,cAAA;EACA,kBAAkB,2BAAlB;EACA,kBAAA;EACA,oBAAA;;AAIR;EACI,aAAA;EACA,sBAAA;EACA,KAAK,wBAAL;EACA,mBAAA;EACA,kBAAA;;AALJ,eAOI;EACI,MAAM,4BAAN;EACA,SAAA;;AAEA,eAJJ,cAIK;EACG,MAAM,4BAAN;;AAEJ,eAPJ,cAOK;EACG,MAAM,0BAAN;;AAfZ,eAmBI;EACI,WAAW,iCAAX;EACA,OAAO,mCAAP;;AAGR;EACI,kBAAA;EACA,OAAO,wBAAP;EACA,QAAQ,wBAAR;EACA,KAAK,wBAAL;EACA,gBAAA;;AALJ,oBAOI;EACI,YAAA;EACA,WAAA;;AAIR;EACI,aAAA;EACA,sBAAA;EACA,KAAK,wBAAL;;AAGJ,yBAA0B,MAAM;EAAI,kBAAA;;AAEpC;EACI,OAAO,0BAAP;EACA,SAAS,0BAA0B,wBAAnC;EACA,sBAAA;EACA,kBAAA;EACA,mBAAA;;AAEA,sBAAC;EACG,kBAAkB,4BAAlB;;AAEA,sBAHH,yBAGI;EACG,SAAS,OAAT;EACA,kBAAA;EACA,0BAAA;;AAIR,sBAAC;EACG,kBAAkB,0BAAlB;;AAEA,sBAHH,yBAGI;EACG,SAAS,OAAT;EACA,kBAAA;EACA,0BAAA;;;AAKZ,sBAAuB;EACnB,kBAAA;;AAEA,sBAHmB,uBAGjB;EACE,kBAAA;EACA,UAAA;;AAEA,sBAPe,uBAGjB,WAIG;EACG,oBAAA;;AADJ,sBAPe,uBAGjB,WAIG,QAGG;EACI,YAAA;;AAKhB;EACI,kBAAA;;AAEA,oBAAE,EAAC;EACC,kBAAA;EACA,UAAA;;AAEA,oBAJF,EAAC,sBAIE;EACG,oBAAA;;AAIZ;EACI,kBAAA;EACA,MAAA;EACA,SAAA;EACA,WAAA;;AAEJ;EACI,kBAAA;EACA,aAAA;;;AAIJ;EACI,aAAA;EACA,KAAK,wBAAL;EACA,gBAAA;;AAEA,yBAAE;EACE,OAAA;EACA,aAAA;EACA,sBAAA;EACA,KAAK,wBAAL;EACA,mBAAA;EACA,SAAS,wBAAT;;AANJ,yBAAE,IAQE;EACI,WAAA;EACA,WAAA","file":"admin.css"}
     1{"version":3,"sources":["admin.less"],"names":[],"mappings":"AAAA;EACI,yBAAyB,oCAAzB;EACA,kCAAA;EACA,gCAAA;EACA,gCAAA;EACA,8BAAA;EACA,8BAAA;EACA,4BAAA;EACA,+BAAA;EACA,8BAAA;EACA,6BAAA;EACA,uCAAA;EACA,2BAAA;EACA,0BAAA;EACA,6BAAA;EACA,uCAAA;EACA,wDAAA;EACA,8DAAA;EACA,0DAAA;EACA,mCAAA;EACA,4BAAA;EACA,2BAAA;EACA,yBAAA;EACA,2BAAA;EACA,6BAAA;EACA,kCAAA;EACA,qCAAA;EACA,uCAAA;EAEA,uBAAA;EACA,sBAAA;;AAGJ;EAEI;IAAK,2BAAA;;;AAGT;EACI;IAAK,WAAW,cAAX;;;AAGT,YAAa,KAAI;EACb,mBAAA;;AAGJ;EACI,kBAAkB,wBAAlB;EACA,eAAe,4BAAf;EACA,eAAe,wBAAf;EACA,SAAS,wBAAT;EACA,kBAAA;EACA,YAAY,yBAAZ;;;;AAEA,YAAC,YAAC;EACE,yBAAA;EACA,0BAAA;;AAGJ,YAAC;EACG,eAAe,kCAAf;EACA,YAAY,+BAAZ;EACA,kBAAkB,0BAAlB;EACA,qBAAA;;AAJJ,YAAC,UAMG;EACI,KAAK,wBAAL;;AAIR,YAAC;AAAS,YAAC;EACP,aAAA;EACA,8BAAA;EACA,mBAAA;EACA,gBAAgB,wBAAhB;EACA,yBAAyB,2BAAzB;;AALJ,YAAC,OAOG;AAPM,YAAC,OAOP;EACI,SAAA;EACA,WAAW,gCAAX;EACA,gBAAA;;AAGJ,YAbH,OAaI;AAAD,YAbO,OAaN;EACG,aAAA;EACA,KAAK,wBAAL;EACA,sBAAA;;AAIR,YAAC;EACG,aAAa,wBAAb;EACA,iBAAA;EACA,mBAAA;EACA,sBAAsB,2BAAtB;;AAGJ,YAAC;EACG,aAAA;EACA,sBAAA;EACA,KAAK,wBAAL;;AAEA,YALH,QAKI;EACG,aAAA;EACA,KAAK,wBAAL;EACA,mBAAA;EACA,8BAAA;EACA,eAAA;;AAGJ,YAbH,QAaI;EACG,aAAA;EACA,sBAAA;EACA,KAAK,wBAAL;;AAIR,YAAC;EACG,aAAA;EACA,uBAAuB,UAAU,mBAAjC;EACA,UAAU,yBAAV;;AAEA,QAA0B;EAA1B,YALH;IAMO,0BAAA;;;AAGJ,YATH,UASI;EACG,aAAA;EACA,sBAAA;EACA,KAAK,wBAAL;EACA,kBAAA;;AAEA,YAfP,UASI,KAMI,IAAI,eAAe;EAChB,SAAS,EAAT;EACA,kBAAA;EACA,MAAA;EACA,OAAO,KAAK,+BAAZ;EACA,SAAA;EACA,uBAAuB,2BAAvB;;AAIR,YAzBH,UAyBI;EACG,aAAA;EACA,KAAK,wBAAL;EACA,mBAAA;EACA,8BAAA;EACA,mBAAA;EACA,kBAAA;;AAEA,YAjCP,UAyBI,KAQI;EACG,SAAS,EAAT;EACA,kBAAA;EACA,KAAK,KAAK,+BAAV;EACA,QAAA;EACA,OAAA;EACA,sBAAsB,2BAAtB;;AAMZ,YAAC;EACG,mBAAA;;AADJ,YAAC,UAGG;EACI,2BAAA;;AAxHZ,YA6HI,MACI;EACI,YAAY,yBAAZ;;AA/HZ,YAmII;EACI,oBAAA;;AApIR,YAuII,MAAK;AAvIT,YAwII,MAAK;AAxIT,YAyII,MAAK;AAzIT,YA0II,MAAK;AA1IT,YA2II;AA3IJ,YA4II;EACI,kBAAkB,2BAAlB;EACA,oBAAA;;AA9IR,YAiJI;EACI,eAAA;EACA,WAAA;EACA,eAAe,kCAAf;;AApJR,YAuJI,MAAK;EACD,6BAAA;EACA,sBAAA;EACA,cAAc,4BAAd;;AAEA,YALJ,MAAK,cAKA;EAEG,kBAAkB,2BAAlB;EACA,QAAQ,sBAAR;;AAEJ,YAVJ,MAAK,cAUA;EAEG,kBAAkB,2BAAlB;EACA,QAAQ,sBAAR;;AAGJ,YAhBJ,MAAK,cAgBA;EACG,YAAY,4BAAZ;EACA,kBAAA;EACA,YAAY,KAAK,4BAAjB;EACA,YAAY,gCAAZ;;AAEJ,YAtBJ,MAAK,cAsBA;EACG,YAAY,4BAAZ;EACA,kBAAA;EACA,YAAY,KAAK,4BAAjB;EACA,YAAY,gCAAZ;;AAEJ,YA5BJ,MAAK,cA4BA;EACG,YAAY,4BAAZ;;AAGJ,YAhCJ,MAAK,cAgCC;EACE,sBAAA;EACA,0BAAA;;AAzLZ,YA6LI;EACI,aAAA;EACA,eAAe,wBAAf;;AAEA,YAJJ,EAIK;EACG,gBAAA;;AAlMZ,YAsMI,sBAEI;AAxMR,YAuMI,kCACI;EACI,MAAM,0BAAN;;AAMR,aAAC;EACG,aAAA;EACA,KAAK,wBAAL;EACA,mBAAA;;AAEA,aALH,YAKI;EACG,aAAA;EACA,KAAK,wBAAL;EACA,sBAAA;;AAEA,aAVP,YAKI,KAKI;EACG,WAAW,iCAAX;EACA,gBAAA;;AAGJ,aAfP,YAKI,KAUI,MACG;EACI,4CAAA;;AAMZ,aAvBH,YAuBI;EACG,aAAA;EACA,mBAAA;EACA,uBAAA;EACA,kBAAA;EACA,yBAAA;;AAEA,aA9BP,YAuBI,MAOI;EACG,QAAQ,0BAAR;EACA,cAAc,0BAAd;;AAGJ,aAnCP,YAuBI,MAYI;EACG,QAAQ,4BAAR;EACA,cAAc,KAAK,+BAAnB;EACA,qBAAA;EAEA,kBAAkB,mCAAlB;EAEA,WAAW,cAAX;EACA,wBAAA;EACA,QAAQ,0CAA0C,0CAAlD;EACA,8CAAA;EACA,yCAAA;;AAGJ,aAjDP,YAuBI,MA0BI;EACG,WAAW,iCAAX;;AAMhB;EACI,WAAA;EACA,YAAA;EACA,MAAM,4BAAN;EACA,2BAAA;EACA,0BAAA;;AAGJ;EACI,WAAW,mCAAX;EACA,OAAO,mCAAP;EACA,cAAA;EACA,eAAA;;AAGJ;EACI,kBAAkB,8BAAlB;EACA,OAAO,yBAAP;EACA,SAAS,wBAAT;EACA,eAAe,kCAAf;EACA,aAAA;EACA,8BAAA;;AAEA,eAAC,eAAC;EACE,kBAAkB,4BAAlB;;AAGJ,eAAC,SACG;EACI,WAAW,iCAAX;;AAdZ,eAkBI;EACI,MAAM,yBAAN;EACA,cAAA;EACA,aAAA;EACA,SAAA;EACA,SAAA;;AAIR;EACI,aAAA;EACA,cAAA;EACA,kBAAkB,0BAAlB;EACA,qBAAA;;AAEA,iBAAC,IAAI;EACD,aAAA;;AAIR,iBAAkB;EACd,qBAAA;;AAEJ;EACI,qBAAA;EACA,WAAA;;AAGJ;EACI,sBAAA;EACA,OAAO,mCAAP;EACA,WAAW,gCAAX;EACA,kBAAA;;AAEA,wBAAE;EACE,YAAY,wBAAZ;;AAKR,KAAK,iBAAiB;EAClB,kBAAA;EACA,UAAA;EACA,QAAQ,4BAA4B,KAAK,4BAAzC;;AAEA,KALC,iBAAiB,oBAKhB;EACE,kBAAA;EACA,eAAe,KAAK,4BAApB;EACA,aAAa,KAAK,gCAAlB;;AAEA,KAVH,iBAAiB,oBAKhB,QAKG;EACG,SAAS,EAAT;EACA,kBAAA;EACA,cAAA;EACA,OAAA;EACA,MAAA;EACA,OAAO,KAAK,4BAAZ;;EACA,QAAQ,KAAK,4BAAb;;EACA,eAAe,KAAK,4BAApB;;EACA,YAAY,0BAAZ;EACA,kBAAkB,2BAAlB;EACA,oBAAA;;AAGJ,KAxBH,iBAAiB,oBAKhB,QAmBG;EACG,SAAS,EAAT;EACA,kBAAA;EACA,cAAA;EACA,SAAA;EACA,QAAA;EACA,OAAO,KAAK,4BAAZ;;EACA,QAAQ,KAAK,4BAAb;;EACA,eAAe,KAAK,4BAApB;;EACA,YAAY,0BAAZ;EACA,kBAAkB,2BAAlB;EACA,oBAAA;;AAEJ,KArCH,iBAAiB,oBAKhB,QAgCG,MAAM;EACH,YAAY,gCAAZ;;AAKA,KA3CP,iBAAiB,oBAyCjB,QACK,QACG;EACG,aAAa,KAAK,4BAAlB;;AAEJ,KA9CP,iBAAiB,oBAyCjB,QACK,QAIG;EACG,YAAY,4BAAZ;;AAMJ,KArDP,iBAAiB,oBAmDjB,cACK,QACG;EACG,YAAY,gCAAZ;;AAQJ,KA9DP,iBAAiB,oBA0DjB,SACK,QAGG;AAAS,KA9DjB,iBAAiB,oBA0DjB,SACK,QAGa;EACP,YAAA;;AAOhB;EACI,kBAAA;;AAEJ;EACI,0BAAA;;AAEJ;EACI,sBAAA;EACA,qBAAA;EACA,qBAAqB,wBAArB;;;;;;;AAOA,yBAAC,yBAAC;EACE,cAAA;EACA,sBAAA;EACA,YAAY,wBAAZ;;AAbR,yBAgBI;EACI,aAAA;EACA,KAAK,wBAAL;;AAlBR,yBAgBI,uBAII;EACI,KAAK,wBAAL;;AArBZ,yBAgBI,uBAII,qBAGI;EACI,aAAA;EACA,8BAAA;EACA,KAAK,wBAAL;;AA1BhB,yBAgBI,uBAII,qBAQI;EACI,6BAAA;EACA,OAAO,0BAAP;;AA9BhB,yBAgBI,uBAII,qBAYI;EACI,OAAO,4BAAP;;AAjChB,yBAgBI,uBAII,qBAeI;EACI,eAAA;EACA,YAAA;;AAKhB,WACI,GAAE;EACE,aAAA;;AAFR,WAII,GAAE,IAAI;EACF,aAAA;;AALR,WAOI,GAAE;EACE,YAAA;;AAEA,WAHJ,GAAE,sBAGG;EACG,UAAA;;AAKZ,GAAI,mCAAkC,IAAI;EACtC,cAAA;;AAGJ;EACI,SAAS,wBAAT;EACA,YAAA;EACA,eAAe,4BAAf;EACA,YAAA;EACA,eAAA;EACA,YAAY,yBAAZ;EACA,gBAAA;;AAPJ,oBASI;EACI,gBAAgB,wBAAhB;;AAVR,oBAaI,0CACI;EACI,MAAM,yBAAN;EACA,SAAA;;AAhBZ,oBAoBI;EACI,WAAA;;AAGR;EACI,gBAAA;EACA,cAAA;EACA,SAAS,0BAAT;;AAHJ,4BAKI;EACI,4CAAA;;AAGR;EACI,aAAA;EACA,uBAAA;EACA,KAAK,wBAAL;EACA,sBAAA;;AAEA,eAAE,gBAAC;EACC,aAAA;EACA,mBAAA;EACA,KAAK,wBAAL;;AAEA,eALF,gBAAC,OAKG;EACE,cAAc,wBAAd;EACA,+DAAA;EACA,wCAAA;EACA,4BAAA;EACA,iBAAiB,wBAAjB;;AAIR,eAAC;EACG,YAAA;;AAGJ,eAAE;EACE,cAAc,wBAAd;;AAIA,eADH,IAAI,SACC;EACE,aAAA;;AAMA,eAFP,OACK,yBACI;EACE,8DAAA;;AArChB,eA0CI;EACI,eAAA;EACA,0BAAA;EACA,4BAAA;EACA,6BAAA;;AAEA,eANJ,MAMK;EACG,OAAO,4BAAP;;AAjDZ,eAqDI,MAAK;AArDT,eAqD4B,MAAK;EACzB,SAAA;;AAKR;EACI,aAAA;EACA,sBAAA;EACA,KAAK,wBAAL;;AAEA,kBAAE,MAAK,aAAa,kBAAC;EACjB,gBAAA;EACA,sBAAA;EACA,SAAA;EACA,gBAAA;EACA,kBAAkB,2BAAlB;EACA,SAAS,0BAA0B,wBAAnC;;AAGJ,kBAAC;EACG,kBAAA;EACA,aAAA;EACA,mBAAA;EACA,KAAK,wBAAL;;AAGJ,kBAAC;EACG,gBAAA;EACA,SAAA;EACA,UAAA;EACA,eAAA;EACA,OAAO,0BAAP;EACA,aAAA;EACA,cAAA;;AAEA,kBATH,QASI;EACG,YAAA;EACA,mBAAA;;AAXR,kBAAC,QAcG;EACI,aAAA;EACA,cAAA;EACA,kBAAA;;AAKZ;EACI,aAAA;EACA,sBAAA;EACA,KAAK,wBAAL;EACA,SAAS,wBAAT;EACA,eAAe,kCAAf;EACA,kBAAkB,0BAAlB;EACA,kBAAA;;AAPJ,kBASI;EACI,SAAA;EACA,aAAA;EACA,KAAK,wBAAL;EACA,mBAAA;EACA,kBAAA;EACA,UAAA;;AAfR,kBASI,GAQI;EACI,SAAA;EACA,aAAA;EACA,cAAA;;AApBZ,kBAuBI;EACI,sBAAA;;AAxBR,kBA0BI;EACI,aAAA;;AAEA,kBAHJ,0BAGK;EACG,cAAA;;AA9BZ,kBAiCI,MAAK;EACD,SAAA;EACA,sBAAsB,2BAAtB;EACA,yBAAyB,2BAAzB;;AAIR;EACI,aAAA;EACA,KAAK,yBAAL;EACA,kBAAA;EACA,sBAAsB,yBAAtB;EACA,kBAAA;;AAEA,kBAAC;EACG,SAAS,EAAT;EACA,kBAAA;EACA,WAAA;EACA,aAAA;EACA,QAAA;EACA,kBAAA;EACA,QAAQ,wBAAwB,yBAAhC;EACA,uBAAuB,2BAAvB;EACA,yBAAyB,2BAAzB;EACA,2BAA2B,4BAA3B;EACA,YAAY,yBAAZ;;AAEJ,kBAAC;EACG,SAAS,EAAT;EACA,kBAAA;EACA,WAAA;EACA,QAAA;EACA,aAAA;EACA,cAAA;EACA,kBAAkB,2BAAlB;EACA,kBAAA;EACA,oBAAA;;AAIR;EACI,aAAA;EACA,sBAAA;EACA,KAAK,wBAAL;EACA,mBAAA;EACA,kBAAA;;AALJ,eAOI;EACI,MAAM,4BAAN;EACA,SAAA;;AAEA,eAJJ,cAIK;EACG,MAAM,4BAAN;;AAEJ,eAPJ,cAOK;EACG,MAAM,0BAAN;;AAfZ,eAmBI;EACI,WAAW,iCAAX;EACA,OAAO,mCAAP;;AAGR;EACI,kBAAA;EACA,OAAO,wBAAP;EACA,QAAQ,wBAAR;EACA,KAAK,wBAAL;EACA,gBAAA;;AALJ,oBAOI;EACI,YAAA;EACA,WAAA;;AAIR;EACI,aAAA;EACA,sBAAA;EACA,KAAK,wBAAL;;AAGJ,yBAA0B,MAAM;EAAI,kBAAA;;AAEpC;EACI,OAAO,0BAAP;EACA,SAAS,0BAA0B,wBAAnC;EACA,sBAAA;EACA,kBAAA;EACA,mBAAA;;AAEA,sBAAC;EACG,kBAAkB,4BAAlB;;AAEA,sBAHH,yBAGI;EACG,SAAS,OAAT;EACA,kBAAA;EACA,0BAAA;;AAIR,sBAAC;EACG,kBAAkB,0BAAlB;;AAEA,sBAHH,yBAGI;EACG,SAAS,OAAT;EACA,kBAAA;EACA,0BAAA;;;AAKZ,sBAAuB;EACnB,kBAAA;;AAEA,sBAHmB,uBAGjB;EACE,kBAAA;EACA,UAAA;;AAEA,sBAPe,uBAGjB,WAIG;EACG,oBAAA;;AADJ,sBAPe,uBAGjB,WAIG,QAGG;EACI,YAAA;;AAKhB;EACI,kBAAA;;AAEA,oBAAE,EAAC;EACC,kBAAA;EACA,UAAA;;AAEA,oBAJF,EAAC,sBAIE;EACG,oBAAA;;AAIZ;EACI,kBAAA;EACA,MAAA;EACA,SAAA;EACA,WAAA;;AAEJ;EACI,kBAAA;EACA,aAAA;;;AAIJ;EACI,aAAA;EACA,KAAK,wBAAL;EACA,gBAAA;;AAEA,yBAAE;EACE,OAAA;EACA,aAAA;EACA,sBAAA;EACA,KAAK,wBAAL;EACA,mBAAA;EACA,SAAS,wBAAT;;AANJ,yBAAE,IAQE;EACI,WAAA;EACA,WAAA;;AAKZ,IAAI,8BAEA,SAAQ;EACJ,wBAAA;;AAGR,IAAI,wBAEA,MAAM;EACF,wBAAA","file":"admin.css"}
  • squeeze/trunk/assets/css/admin.less

    r3311866 r3345284  
    457457    margin-inline-start: .5em;
    458458}
     459.squeeze-settings-example {
     460    max-width: fit-content;
     461    display: inline-block;
     462    margin-inline-start: var(--squeeze-spacing-m);
     463    /*opacity: 0.5;
     464
     465    &.enabled {
     466        opacity: 1;
     467    }*/
     468
     469    &&--webp_replace_urls {
     470        display: block;
     471        margin-inline-start: 0;
     472        margin-top: var(--squeeze-spacing-m);
     473    }
     474
     475    .squeeze-box--fieldset {
     476        display: flex;
     477        gap: var(--squeeze-spacing-m);
     478
     479        .squeeze-box-content {
     480            gap: var(--squeeze-spacing-s);
     481
     482            p {
     483                display: flex;
     484                justify-content: space-between;
     485                gap: var(--squeeze-spacing-m);
     486            }
     487            .striked {
     488                text-decoration: line-through;
     489                color: var(--squeeze-error-color);
     490            }
     491            .greened {
     492                color: var(--squeeze-success-color);
     493            }
     494            img {
     495                max-width: 100%;
     496                height: auto;
     497            }
     498        }
     499    }
     500}
    459501.form-table {
    460502    tr.squeeze_setting_restore_defaults {
     
    463505    tr:has(.squeeze-hidden) {
    464506        display: none;
     507    }
     508    tr.squeeze-legacy-option {
     509        opacity: 0.5;
     510
     511        &:hover {
     512            opacity: 1;
     513        }
    465514    }
    466515}
     
    567616    gap: var(--squeeze-spacing-s);
    568617
    569     & input[type="text"]&__item {
     618    & input[type="text"]&__input {
    570619        min-width: 15rem;
    571620        font-family: monospace;
     
    574623        background-color: var(--squeeze-border-color);
    575624        padding: var(--squeeze-spacing-xs) var(--squeeze-spacing-s);
     625    }
     626
     627    &__item {
     628        position: relative;
     629        display: flex;
     630        align-items: center;
     631        gap: var(--squeeze-spacing-s);
     632    }
     633
     634    &__remove {
     635        background: none;
     636        border: 0;
     637        padding: 0;
     638        cursor: pointer;
     639        color: var(--squeeze-error-color);
     640        width: 1.5rem;
     641        height: 1.5rem;
     642
     643        &:disabled {
     644            opacity: 0.5;
     645            cursor: not-allowed;
     646        }
     647
     648        .squeeze-icon {
     649            width: 1.5rem;
     650            height: 1.5rem;
     651            fill: currentColor;
     652        }
    576653    }
    577654}
     
    782859    }
    783860}
     861
     862body.settings_page_squeeze-account {
     863    // Hide the your-license tab when on the account settings page
     864    .nav-tab[href*="#squeeze_account"] {
     865        display: none !important;
     866    }
     867}
     868body.media_page_squeeze-bulk {
     869    // Hide the account tab when on the bulk squeeze page
     870    .wrap .nav-tab-wrapper {
     871        display: none !important;
     872    }
     873}
  • squeeze/trunk/assets/js/admin.bundle.js

    r3311866 r3345284  
    2727/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
    2828
    29 eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"handleBulkButtonClick\": () => (/* binding */ handleBulkButtonClick),\n/* harmony export */   \"handleBulkFromPage\": () => (/* binding */ handleBulkFromPage),\n/* harmony export */   \"handleBulkToggle\": () => (/* binding */ handleBulkToggle),\n/* harmony export */   \"handleButtonsClick\": () => (/* binding */ handleButtonsClick),\n/* harmony export */   \"handleClosePathDialog\": () => (/* binding */ handleClosePathDialog),\n/* harmony export */   \"handleDirectoryCheck\": () => (/* binding */ handleDirectoryCheck),\n/* harmony export */   \"handleDirectoryClick\": () => (/* binding */ handleDirectoryClick),\n/* harmony export */   \"handleFetchImagesFromPage\": () => (/* binding */ handleFetchImagesFromPage),\n/* harmony export */   \"handleMultiFileFormUpload\": () => (/* binding */ handleMultiFileFormUpload),\n/* harmony export */   \"handleOnLeave\": () => (/* binding */ handleOnLeave),\n/* harmony export */   \"handleRecursiveUpload\": () => (/* binding */ handleRecursiveUpload),\n/* harmony export */   \"handleRestoreBtnClick\": () => (/* binding */ handleRestoreBtnClick),\n/* harmony export */   \"handleSingleBtnClick\": () => (/* binding */ handleSingleBtnClick)\n/* harmony export */ });\n/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./helpers.js */ \"./assets/js/helpers.js\");\n/* harmony import */ var _squeeze_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./squeeze.js */ \"./assets/js/squeeze.js\");\n\r\n\r\n\r\n\r\n\r\n\r\nconst { __ } = wp.i18n; // Import __() from wp.i18n\r\nconst Squeeze = new _squeeze_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"](squeezeOptions);\r\n\r\nconst updateUI = (initId, response) => {\r\n  const statusEl = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.postsFilterForm?.querySelector(`#post-${initId} .column-squeeze .squeeze_status`);\r\n  if (statusEl) statusEl.innerHTML = response.data;\r\n\r\n  const gridItem = document.querySelector(`.media-frame.mode-grid .attachment[data-id=\"${initId}\"]`);\r\n  if (gridItem) {\r\n    const centered = gridItem.querySelector('.centered');\r\n    const progress = gridItem.querySelector('.media-progress-bar');\r\n    if (centered) centered.style.display = 'block';\r\n    if (progress) progress.remove();\r\n    gridItem.classList.remove('uploading');\r\n  }\r\n};\r\n\r\nconst getTotalPages = (path) => {\r\n  const selectors = {\r\n    uncompressed: \"input[name='squeeze_bulk_uncompressed_pages']\",\r\n    all: \"input[name='squeeze_bulk_total_pages']\"\r\n  };\r\n  const sel = selectors[path];\r\n  const val = sel && document.querySelector(sel)?.value;\r\n  return Number(val) || 1;\r\n};\r\n\r\nconst checkPaused = (data, page) => {\r\n  if (!_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.isPaused) return false;\r\n  handleBulkPause(data, page);\r\n  return true;\r\n};\r\n\r\nconst logAndThumbnail = async (filename, response, wrapper) => {\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(response.data, {\r\n    mediaLogWrapper: wrapper,\r\n    iconId: response.success ? 'check-mark-circle-icon' : 'ban-sign-icon'\r\n  });\r\n\r\n  const titleEl = wrapper.querySelector('h3');\r\n  if (titleEl && response.filename) {\r\n    titleEl.textContent = `${__('Media', 'squeeze')} ${filename} (${response.filename}):`;\r\n  }\r\n\r\n  const thumbUrl = response.sizes?.thumbnail?.url || response.url;\r\n  if (thumbUrl) {\r\n    const thumb = document.createElement('div');\r\n    thumb.classList.add('media-log-thumbnail');\r\n    thumb.innerHTML = `<img src=\"${thumbUrl}\" alt=\"${filename}\"/>`;\r\n    wrapper.appendChild(thumb);\r\n  }\r\n};\r\n\r\nconst handleDirectoryCheck = (event) => {\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.savePathBtn.disabled = !_helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.dirContainer.querySelector(\"input[type='checkbox']:checked\");\r\n};\r\n\r\nconst handleClosePathDialog = (event) => {\r\n  if (!event.target.contains(_helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.pathDialog)) return;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.pathDialog.close();\r\n};\r\n\r\nconst handleBulkToggle = (event, process, mediaIDs, page = 1) => {\r\n  const isPaused = event.target.dataset.running === 'true';\r\n\r\n  event.target.dataset.running = isPaused ? 'false' : 'true';\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.updateButtonText(event.target, isPaused ? __('Resume bulk squeezing', 'squeeze') : __('Pause bulk squeezing', 'squeeze'), isPaused ? '#play-button-round-icon' : '#pause-button-icon');\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.isPaused = isPaused;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.process = process;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs = mediaIDs;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page = page;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.target = event.target;\r\n\r\n  console.log('handleBulkToggle', _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData);\r\n\r\n  return isPaused;\r\n};\r\n\r\n// Handle single compress button click\r\n// manually pass Squeeze, because of the dynamic options update in the Preview Mode\r\nconst handleSingleBtnClick = async (event, Squeeze) => {\r\n  const attachmentID = event.target.dataset.attachment;\r\n  const squeezeStatus = event.target.closest(\"td\").querySelector(\".squeeze_status\");\r\n\r\n  try {\r\n    wp.media.attachment(attachmentID).fetch().then(async (data) => {\r\n      const attachment = { attributes: data };\r\n\r\n      try {\r\n        const compressData = await Squeeze.handleCompress(attachment);\r\n        const response = await Squeeze.handleUpload({ attachment, base64: compressData });\r\n\r\n        //squeezeStatus.innerHTML = response?.data?.message ?? response;\r\n        squeezeStatus.innerHTML = response?.data ?? response;\r\n\r\n        if (event.target.closest(\"td.field\")) {\r\n          const table = event.target.closest(\"td\")?.querySelector(\".squeeze_status .squeeze-comparison-table\");\r\n          if (table) {\r\n            const td = document.createElement(\"td\");\r\n            td.classList.add(\"field\");\r\n            td.style.width = \"100%\";\r\n            td.appendChild(table);\r\n            event.target.closest(\"tr\").appendChild(td);\r\n          }\r\n        }\r\n        // TBD: add file size label to the attachment info\r\n        /*\r\n        if (event.target.closest('.attachment-info')) {\r\n          const fileSizeLabel = event.target.closest('.attachment-info').querySelector('.file-size');\r\n          if (fileSizeLabel) {\r\n            const fileSize = response?.data?.sizes?.scaled?.compressed_size ?? response?.data?.sizes?.original?.compressed_size ?? null;\r\n            if (fileSize) {\r\n              const humanFileSize = SqueezeHelpers.humanFileSize(fileSize, true);\r\n              fileSizeLabel.innerHTML = fileSizeLabel.innerHTML.replace(/(<\\/strong>\\s*)(.*)/, `$1${humanFileSize}`);\r\n            }\r\n          }\r\n        }\r\n        */\r\n      } catch (error) {\r\n        console.error(error);\r\n        squeezeStatus.innerHTML = error;\r\n      } finally {\r\n        _helpers_js__WEBPACK_IMPORTED_MODULE_0__.removeAllButtons(event.target.closest(\"td\")?.querySelectorAll(`button`));\r\n        window.onbeforeunload = null;\r\n      }\r\n    });\r\n  } catch (error) {\r\n    console.error(error);\r\n    squeezeStatus.innerHTML = error;\r\n    event.target.remove();\r\n  }\r\n};\r\n\r\nconst handleRestoreBtnClick = async (event) => {\r\n  const attachmentID = event.target.dataset.attachment;\r\n\r\n  event.target.disabled = true;\r\n  event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = '⏳ ' + __('Restore in process...', 'squeeze');\r\n\r\n  try {\r\n    const response = await Squeeze.handleRestore(attachmentID);\r\n    event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = response.data;\r\n  } catch (error) {\r\n    console.error(error);\r\n    event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = error;\r\n  } finally {\r\n    event.target.closest('td').querySelector(`[name='squeeze_compress_again']`).disabled = false;\r\n    event.target.remove();\r\n    window.onbeforeunload = null;\r\n  }\r\n};\r\n\r\nconst handleBulkButtonClick = async (event, process, mediaIDs, currentPage) => {\r\n  if (mediaIDs.length === 0) return;\r\n\r\n  const totalPages = getTotalPages(process);\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.disableBulkButtons();\r\n  window.onbeforeunload = handleOnLeave;\r\n\r\n  if (_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.process === process) {\r\n    if (_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs/*.length > 0*/) {\r\n      mediaIDs = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs;\r\n    }\r\n    if (_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page) {\r\n      currentPage = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page;\r\n    }\r\n  }\r\n\r\n  const isPaused = handleBulkToggle(event, process, mediaIDs, currentPage);\r\n  if (isPaused) {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.updateButtonText(event.target, __('Pausing...', 'squeeze'), '#pause-button-icon');\r\n    return;\r\n  } else {\r\n    event.target.disabled = false;\r\n  }\r\n\r\n  try {\r\n    const finalResponse = await handleRecursiveUpload(process, mediaIDs, currentPage, true);\r\n\r\n    if (finalResponse?.mediaIDs) {\r\n      if (finalResponse.mediaIDs.length === 0 && finalResponse.page >= totalPages) {\r\n        alert(__('All images have been processed!', 'squeeze'));\r\n        window.onbeforeunload = null;\r\n        _helpers_js__WEBPACK_IMPORTED_MODULE_0__.restoreBulkButtons();\r\n      }\r\n    }\r\n  } catch (error) {\r\n    console.error(error);\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.restoreBulkButtons();\r\n    window.onbeforeunload = null;\r\n    alert(__('An error has occured. Check the console for details.', 'squeeze'));\r\n  }\r\n};\r\n\r\n// manually pass Squeeze, because of the dynamic options update in the Preview Mode\r\nconst handleButtonsClick = async (event, Squeeze) => {\r\n  const singleBtnName = 'squeeze_compress_single';\r\n  const compressAgainBtnName = 'squeeze_compress_again';\r\n  const restoreBtnName = 'squeeze_restore';\r\n\r\n  if (event.target.getAttribute(\"name\") === singleBtnName || event.target.getAttribute(\"name\") === compressAgainBtnName) {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.disableAllButtons(event.target.closest(\"td\").querySelectorAll(`button`));\r\n    event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = '⏳ ' + __('Squeezing...', 'squeeze');\r\n    window.onbeforeunload = handleOnLeave;\r\n    handleSingleBtnClick(event, Squeeze);\r\n  }\r\n\r\n  if (event.target.getAttribute(\"name\") === restoreBtnName) {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.disableAllButtons(event.target.closest(\"td\").querySelectorAll(`button`));\r\n    window.onbeforeunload = handleOnLeave;\r\n    handleRestoreBtnClick(event);\r\n  }\r\n};\r\n\r\nconst handleDirectoryClick = async (event) => {\r\n  if (event.target !== event.currentTarget) return;\r\n\r\n  const currentDir = event.target.closest(\".directory-item\");\r\n  const currentPath = currentDir.dataset.path;\r\n  const parentPath = currentDir.dataset.parent;\r\n\r\n  if (parentPath === '/' || currentDir.classList.contains(\"loading\")) return;\r\n\r\n  if (currentDir.classList.contains(\"loaded\")) {\r\n    currentDir.classList.toggle(\"opened\");\r\n    return;\r\n  }\r\n\r\n  currentDir.classList.add(\"loading\");\r\n\r\n  const subDirs = await Squeeze.getDirectories(currentPath);\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.renderDirectories(subDirs, currentDir, {\r\n    handleDirectoryClick,\r\n    handleDirectoryCheck\r\n  });\r\n\r\n  currentDir.classList.remove(\"loading\");\r\n  currentDir.classList.add(\"loaded\", \"opened\");\r\n}\r\n\r\n/**\r\n * Hadnle warning on page leave\r\n*/\r\nconst handleOnLeave = () => {\r\n  const urlParams = new URLSearchParams(window.location.search);\r\n  const page = urlParams.get('page');\r\n  const isUploadPage = window.location.href.includes('upload.php');\r\n  const isMediaNewPage = window.location.href.includes('media-new.php');\r\n  const isAttachmentPage = window.location.href.includes('post.php') && urlParams.get('action') === 'edit';\r\n\r\n  if (page === 'squeeze-bulk' || isMediaNewPage || isAttachmentPage) {\r\n    return __('Are you sure you want to leave this page? The squeezing process will be terminated!', 'squeeze');\r\n  }\r\n  if (isUploadPage) {\r\n    return __('Are you sure you want to leave this page? The settings will not be saved!', 'squeeze');\r\n  }\r\n};\r\n\r\nconst handleBulkPause = (data, currentPage) => {\r\n  window.onbeforeunload = null;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(__('Bulk squeezing has been paused!', 'squeeze'), { isPause: true });\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs = data;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page = currentPage;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.target.disabled = false;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.updateButtonText(_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.target, __('Resume bulk squeezing', 'squeeze'), '#play-button-round-icon');\r\n};\r\n\r\nconst handleUpdateChart = (uncompressedImagesCount) => {\r\n  const chartValue = document.querySelector(\".squeeze-bulk-media-stats-chart-value > text\");\r\n  const chartBar = document.querySelector(\".squeeze-bulk-media-stats-chart\");\r\n  const squeezedImages = document.querySelector(\".squeeze-bulk-media-stats-item-value\");\r\n\r\n  if (!chartValue || !chartBar) return;\r\n\r\n  const imagesLeft = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.totalImages - uncompressedImagesCount;\r\n  const percentage = parseFloat((imagesLeft / _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.totalImages) * 100).toFixed(2);\r\n  const dasharray = percentage * 560 / 100;\r\n  chartValue.textContent = `${percentage}%`;\r\n  chartBar.style.setProperty('--squeeze-dasharray', dasharray);\r\n\r\n  if (squeezedImages) {\r\n    squeezedImages.textContent = `${imagesLeft} / ${_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.totalImages}`;\r\n  }\r\n};\r\n\r\nconst handleRecursiveUpload = async (path, data, currentPage, isUpdateChart = false) => {\r\n\r\n  if (!Array.isArray(data)) return { success: false, data: 'No data provided!', mediaIDs: [] }; // when bulk directory path has no images\r\n  \r\n  const totalPages = getTotalPages(path);\r\n\r\n  if (data.length === 0) {\r\n    currentPage += 1;\r\n    if (currentPage > totalPages || !_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.lastId) return { success: true, data: __('No more images found!', 'squeeze'), mediaIDs: [], page: currentPage };\r\n\r\n    const maybeGetNextMediaIDs = await Squeeze.getNextAttachments(currentPage, path, _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.lastId);\r\n    if (maybeGetNextMediaIDs.success && maybeGetNextMediaIDs.data.length > 0) {\r\n      const nextMediaIDs = maybeGetNextMediaIDs.data;\r\n      return handleRecursiveUpload(path, nextMediaIDs, currentPage, isUpdateChart);\r\n    } else {\r\n      return { success: true, data: __('No more images found!', 'squeeze'), mediaIDs: [], page: currentPage };\r\n    }\r\n  }\r\n\r\n  const initData = [...data];  // initial data\r\n\r\n  const filename = data[0]?.filename ? data[0].filename : `ID #${data[0]}`;\r\n  const mediaLogWrapper = await _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(`${__('Start squeezing...', 'squeeze')}`, { title: filename, isStart: true });\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.lastId = data[0] || 0; // update lastId to the last processed ID\r\n\r\n  try {\r\n    const response = await Squeeze.handleBulkUpload(path, data);\r\n\r\n    await logAndThumbnail(filename, response, mediaLogWrapper);\r\n\r\n    if (isUpdateChart && path !== 'all') {\r\n      let uncompressedImagesCount = 0;\r\n      if (path === 'uncompressed') {\r\n        _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.uncompressedImages = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.uncompressedImages - 1 || 0;\r\n        uncompressedImagesCount = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.uncompressedImages;\r\n      } else if (path === 'path') {\r\n        uncompressedImagesCount = response.mediaIDs.length;\r\n      }\r\n      handleUpdateChart(uncompressedImagesCount);\r\n    }\r\n\r\n    if (checkPaused(data, currentPage)) {\r\n      return { success: false, data: 'Process has been paused!', mediaIDs: data, page: currentPage };\r\n    }\r\n\r\n    updateUI(initData[0], response);\r\n\r\n    if (response.mediaIDs.length > 0) {\r\n      return handleRecursiveUpload(path, response.mediaIDs, currentPage, isUpdateChart);\r\n    } else {\r\n      currentPage += 1;\r\n      if (currentPage > totalPages) return { ...response, page: currentPage };\r\n\r\n      const lastId = initData[initData.length - 1];\r\n      const maybeGetNextMediaIDs = await Squeeze.getNextAttachments(currentPage, path, lastId);\r\n      if (maybeGetNextMediaIDs.success && maybeGetNextMediaIDs.data.length > 0) {\r\n        const nextMediaIDs = maybeGetNextMediaIDs.data;\r\n        return handleRecursiveUpload(path, nextMediaIDs, currentPage, isUpdateChart);\r\n      }\r\n    }\r\n\r\n    return response;\r\n\r\n  } catch (error) {\r\n    console.error(error);\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(`${error}`, { mediaLogWrapper, iconId: 'ban-sign-icon' });\r\n\r\n    if (data.length > 0) {\r\n      return handleRecursiveUpload(path, data, currentPage, isUpdateChart);\r\n    } else {\r\n      currentPage += 1;\r\n      if (currentPage > totalPages) return { success: false, data: error, mediaIDs: [], page: currentPage };\r\n\r\n      const lastId = initData[initData.length - 1];\r\n      const maybeGetNextMediaIDs = await Squeeze.getNextAttachments(currentPage, path, lastId);\r\n      if (maybeGetNextMediaIDs.success && maybeGetNextMediaIDs.data.length > 0) {\r\n        const nextMediaIDs = maybeGetNextMediaIDs.data;\r\n        return handleRecursiveUpload(path, nextMediaIDs, currentPage, isUpdateChart);\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\n\r\n\r\nconst handleMultiFileFormUpload = (compressOptions) => {\r\n  if (typeof wpUploaderInit === 'undefined' || typeof plupload === 'undefined' || typeof uploader === 'undefined') return;\r\n\r\n  const SqueezeUploader = uploader;\r\n\r\n  SqueezeUploader.bind('FilesAdded', function (up, files) { });\r\n\r\n  SqueezeUploader.bind('FileUploaded', function (up, file, response) {\r\n    const fileMime = file.type;\r\n    const fileType = fileMime.split('/')[0];\r\n    const fileSubType = fileMime.split('/')[1];\r\n\r\n    if (!_helpers_js__WEBPACK_IMPORTED_MODULE_0__.maybeCompressAttachment(fileType, fileSubType, compressOptions)) return;\r\n\r\n    const fileID = file.id;\r\n    const attachmentID = response.response;\r\n    const mediaItem = document.getElementById(`media-item-${fileID}`);\r\n\r\n    window.onbeforeunload = handleOnLeave;\r\n\r\n    /**\r\n     * Wait for media item to load( 'async-upload.php' )\r\n     * Ping every 1 second until the media item is loaded\r\n     * @returns Promise\r\n    */\r\n    const waitForItemLoad = () => {\r\n      return new Promise((resolve) => {\r\n        let interval = setInterval(() => {\r\n          if (mediaItem.querySelector('.media-item-wrapper')) {\r\n            mediaItem.querySelector('.media-item-wrapper').innerHTML += `\r\n              <div class=\"progress\">\r\n                <div class=\"percent\">${__('Squeezing...', 'squeeze')}</div>\r\n                <div class=\"bar\" style=\"width: 200px;\"></div>\r\n              </div>\r\n            `;\r\n            clearInterval(interval);\r\n            resolve();\r\n          }\r\n        }, 1000);\r\n      });\r\n    };\r\n\r\n    waitForItemLoad().then(() => {\r\n      try {\r\n        wp.media.attachment(attachmentID).fetch().then(async function (data) {\r\n          const attachment = { attributes: data };\r\n\r\n          try {\r\n            const compressData = await Squeeze.handleCompress(attachment);\r\n            const uploadData = await Squeeze.handleUpload({ attachment, base64: compressData });\r\n\r\n            if (uploadData.success) {\r\n              window.onbeforeunload = null;\r\n              mediaItem.innerHTML += `<div class=\"squeeze_status\">${uploadData.data}</div>`;\r\n              mediaItem.querySelector('.progress')?.remove();\r\n            } else {\r\n              alert(uploadData?.data ?? uploadData);\r\n              window.onbeforeunload = null;\r\n              mediaItem.querySelector('.progress')?.remove();\r\n            }\r\n          } catch (error) {\r\n            console.error(error);\r\n            mediaItem.innerHTML += error;\r\n            window.onbeforeunload = null;\r\n            mediaItem.querySelector('.progress')?.remove();\r\n          }\r\n        });\r\n      } catch (error) {\r\n        console.error(error);\r\n        mediaItem.innerHTML += error;\r\n        window.onbeforeunload = null;\r\n        mediaItem.querySelector('.progress')?.remove();\r\n      }\r\n    });\r\n  });\r\n\r\n  SqueezeUploader.bind('UploadComplete', function (up, files) { });\r\n};\n\n//# sourceURL=webpack:///./assets/js/handlers.js?");
     29eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"handleBulkButtonClick\": () => (/* binding */ handleBulkButtonClick),\n/* harmony export */   \"handleBulkFromPage\": () => (/* binding */ handleBulkFromPage),\n/* harmony export */   \"handleBulkToggle\": () => (/* binding */ handleBulkToggle),\n/* harmony export */   \"handleButtonsClick\": () => (/* binding */ handleButtonsClick),\n/* harmony export */   \"handleClosePathDialog\": () => (/* binding */ handleClosePathDialog),\n/* harmony export */   \"handleCompressBeforeUpload\": () => (/* binding */ handleCompressBeforeUpload),\n/* harmony export */   \"handleDirectoryCheck\": () => (/* binding */ handleDirectoryCheck),\n/* harmony export */   \"handleDirectoryClick\": () => (/* binding */ handleDirectoryClick),\n/* harmony export */   \"handleFetchImagesFromPage\": () => (/* binding */ handleFetchImagesFromPage),\n/* harmony export */   \"handleMultiFileFormUpload\": () => (/* binding */ handleMultiFileFormUpload),\n/* harmony export */   \"handleOnLeave\": () => (/* binding */ handleOnLeave),\n/* harmony export */   \"handleRecursiveUpload\": () => (/* binding */ handleRecursiveUpload),\n/* harmony export */   \"handleRestoreBtnClick\": () => (/* binding */ handleRestoreBtnClick),\n/* harmony export */   \"handleSingleBtnClick\": () => (/* binding */ handleSingleBtnClick)\n/* harmony export */ });\n/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./helpers.js */ \"./assets/js/helpers.js\");\n/* harmony import */ var _squeeze_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./squeeze.js */ \"./assets/js/squeeze.js\");\n\r\n\r\n\r\n\r\n\r\n\r\nconst { __ } = wp.i18n; // Import __() from wp.i18n\r\nconst Squeeze = new _squeeze_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"](squeezeOptions);\r\n\r\nconst updateUI = (initId, response) => {\r\n  const statusEl = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.postsFilterForm?.querySelector(`#post-${initId} .column-squeeze .squeeze_status`);\r\n  if (statusEl) statusEl.innerHTML = response?.data?.message ?? response?.data ?? response;\r\n\r\n  const gridItem = document.querySelector(`.media-frame.mode-grid .attachment[data-id=\"${initId}\"]`);\r\n  if (gridItem) {\r\n    const centered = gridItem.querySelector('.centered');\r\n    const progress = gridItem.querySelector('.media-progress-bar');\r\n    if (centered) centered.style.display = 'block';\r\n    if (progress) progress.remove();\r\n    gridItem.classList.remove('uploading');\r\n  }\r\n};\r\n\r\nconst getTotalPages = (path) => {\r\n  const selectors = {\r\n    uncompressed: \"input[name='squeeze_bulk_uncompressed_pages']\",\r\n    all: \"input[name='squeeze_bulk_total_pages']\"\r\n  };\r\n  const sel = selectors[path];\r\n  const val = sel && document.querySelector(sel)?.value;\r\n  return Number(val) || 1;\r\n};\r\n\r\nconst checkPaused = (data, page) => {\r\n  if (!_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.isPaused) return false;\r\n  handleBulkPause(data, page);\r\n  return true;\r\n};\r\n\r\nconst logAndThumbnail = async (filename, response, wrapper) => {\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(response?.data?.message ?? response?.data, {\r\n    mediaLogWrapper: wrapper,\r\n    iconId: response.success ? 'check-mark-circle-icon' : 'ban-sign-icon'\r\n  });\r\n\r\n  const titleEl = wrapper?.querySelector('h3');\r\n  if (titleEl && response?.data?.filename) {\r\n    titleEl.textContent = `${__('Media', 'squeeze')} ${filename} (${response.data.filename}):`;\r\n  }\r\n\r\n  const thumbUrl = response?.data?.sizes?.thumbnail?.url || response?.data?.url || response?.url;\r\n  if (thumbUrl) {\r\n    const thumb = document.createElement('div');\r\n    thumb.classList.add('media-log-thumbnail');\r\n    thumb.innerHTML = `<img src=\"${thumbUrl}\" alt=\"${filename}\"/>`;\r\n    wrapper?.appendChild(thumb);\r\n  }\r\n};\r\n\r\nconst handleDirectoryCheck = (event) => {\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.savePathBtn.disabled = !_helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.dirContainer.querySelector(\"input[type='checkbox']:checked\");\r\n};\r\n\r\nconst handleClosePathDialog = (event) => {\r\n  if (!event.target.contains(_helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.pathDialog)) return;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.pathDialog.close();\r\n};\r\n\r\nconst handleBulkToggle = (event, process, mediaIDs, page = 1) => {\r\n  const isPaused = event.target.dataset.running === 'true';\r\n\r\n  event.target.dataset.running = isPaused ? 'false' : 'true';\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.updateButtonText(event.target, isPaused ? __('Resume bulk squeezing', 'squeeze') : __('Pause bulk squeezing', 'squeeze'), isPaused ? '#play-button-round-icon' : '#pause-button-icon');\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.isPaused = isPaused;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.process = process;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs = mediaIDs;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page = page;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.target = event.target;\r\n\r\n  //console.log('handleBulkToggle', cachedMediaData);\r\n\r\n  return isPaused;\r\n};\r\n\r\n// Handle single compress button click\r\n// manually pass Squeeze, because of the dynamic options update in the Preview Mode\r\nconst handleSingleBtnClick = async (event, Squeeze) => {\r\n  const attachmentID = event.target.dataset.attachment;\r\n  const squeezeStatus = event.target.closest(\"td\").querySelector(\".squeeze_status\");\r\n\r\n  try {\r\n    wp.media.attachment(attachmentID).fetch().then(async (data) => {\r\n      const attachment = { attributes: data };\r\n\r\n      try {\r\n        const compressData = await Squeeze.handleCompress(attachment);\r\n        const response = await Squeeze.handleUpload({ attachment, base64: compressData });\r\n\r\n        squeezeStatus.innerHTML = response?.data?.message ?? response?.data ?? response;\r\n\r\n        if (event.target.closest(\"td.field\")) {\r\n          const table = event.target.closest(\"td\")?.querySelector(\".squeeze_status .squeeze-comparison-table\");\r\n          if (table) {\r\n            const td = document.createElement(\"td\");\r\n            td.classList.add(\"field\");\r\n            td.style.width = \"100%\";\r\n            td.appendChild(table);\r\n            event.target.closest(\"tr\").appendChild(td);\r\n          }\r\n        }\r\n        // TBD: add file size label to the attachment info\r\n        /*\r\n        if (event.target.closest('.attachment-info')) {\r\n          const fileSizeLabel = event.target.closest('.attachment-info').querySelector('.file-size');\r\n          if (fileSizeLabel) {\r\n            const fileSize = response?.data?.sizes?.scaled?.compressed_size ?? response?.data?.sizes?.original?.compressed_size ?? null;\r\n            if (fileSize) {\r\n              const humanFileSize = SqueezeHelpers.humanFileSize(fileSize, true);\r\n              fileSizeLabel.innerHTML = fileSizeLabel.innerHTML.replace(/(<\\/strong>\\s*)(.*)/, `$1${humanFileSize}`);\r\n            }\r\n          }\r\n        }\r\n        */\r\n      } catch (error) {\r\n        console.error(error);\r\n        squeezeStatus.innerHTML = error?.message ?? error;\r\n      } finally {\r\n        _helpers_js__WEBPACK_IMPORTED_MODULE_0__.removeAllButtons(event.target.closest(\"td\")?.querySelectorAll(`button`));\r\n        window.onbeforeunload = null;\r\n      }\r\n    });\r\n  } catch (error) {\r\n    console.error(error);\r\n    squeezeStatus.innerHTML = error?.message ?? error;\r\n    event.target.remove();\r\n  }\r\n};\r\n\r\nconst handleRestoreBtnClick = async (event) => {\r\n  const attachmentID = event.target.dataset.attachment;\r\n\r\n  event.target.disabled = true;\r\n  event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = '⏳ ' + __('Restore in process...', 'squeeze');\r\n\r\n  try {\r\n    const response = await Squeeze.handleRestore(attachmentID);\r\n    event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = response?.data ?? response;\r\n  } catch (error) {\r\n    console.error(error);\r\n    event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = error?.message ?? JSON.stringify(error, null, 2);\r\n  } finally {\r\n    event.target.closest('td').querySelector(`[name='squeeze_compress_again']`).disabled = false;\r\n    event.target.remove();\r\n    window.onbeforeunload = null;\r\n  }\r\n};\r\n\r\nconst handleBulkButtonClick = async (event, process, mediaIDs, currentPage) => {\r\n  if (mediaIDs.length === 0) return;\r\n\r\n  const totalPages = getTotalPages(process);\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.disableBulkButtons();\r\n  window.onbeforeunload = handleOnLeave;\r\n\r\n  if (_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.process === process) {\r\n    if (_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs/*.length > 0*/) {\r\n      mediaIDs = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs;\r\n    }\r\n    if (_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page) {\r\n      currentPage = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page;\r\n    }\r\n  }\r\n\r\n  const isPaused = handleBulkToggle(event, process, mediaIDs, currentPage);\r\n  if (isPaused) {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.updateButtonText(event.target, __('Pausing...', 'squeeze'), '#pause-button-icon');\r\n    return;\r\n  } else {\r\n    event.target.disabled = false;\r\n  }\r\n\r\n  try {\r\n    const finalResponse = await handleRecursiveUpload(process, mediaIDs, currentPage, true);\r\n\r\n    if (finalResponse?.mediaIDs) {\r\n      if (finalResponse.mediaIDs.length === 0 && finalResponse.page >= totalPages) {\r\n        alert(__('All images have been processed!', 'squeeze'));\r\n        window.onbeforeunload = null;\r\n        _helpers_js__WEBPACK_IMPORTED_MODULE_0__.restoreBulkButtons();\r\n      }\r\n    }\r\n  } catch (error) {\r\n    console.error(error);\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.restoreBulkButtons();\r\n    window.onbeforeunload = null;\r\n    alert(__('An error has occured. Check the console for details.', 'squeeze'));\r\n  }\r\n};\r\n\r\n// manually pass Squeeze, because of the dynamic options update in the Preview Mode\r\nconst handleButtonsClick = async (event, Squeeze) => {\r\n  const singleBtnName = 'squeeze_compress_single';\r\n  const compressAgainBtnName = 'squeeze_compress_again';\r\n  const restoreBtnName = 'squeeze_restore';\r\n\r\n  if (event.target.getAttribute(\"name\") === singleBtnName || event.target.getAttribute(\"name\") === compressAgainBtnName) {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.disableAllButtons(event.target.closest(\"td\").querySelectorAll(`button`));\r\n    event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = '⏳ ' + __('Squeezing...', 'squeeze');\r\n    window.onbeforeunload = handleOnLeave;\r\n    handleSingleBtnClick(event, Squeeze);\r\n  }\r\n\r\n  if (event.target.getAttribute(\"name\") === restoreBtnName) {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.disableAllButtons(event.target.closest(\"td\").querySelectorAll(`button`));\r\n    window.onbeforeunload = handleOnLeave;\r\n    handleRestoreBtnClick(event);\r\n  }\r\n};\r\n\r\nconst handleDirectoryClick = async (event) => {\r\n  if (event.target !== event.currentTarget) return;\r\n\r\n  const currentDir = event.target.closest(\".directory-item\");\r\n  const currentPath = currentDir.dataset.path;\r\n  const parentPath = currentDir.dataset.parent;\r\n\r\n  if (parentPath === '/' || currentDir.classList.contains(\"loading\")) return;\r\n\r\n  if (currentDir.classList.contains(\"loaded\")) {\r\n    currentDir.classList.toggle(\"opened\");\r\n    return;\r\n  }\r\n\r\n  currentDir.classList.add(\"loading\");\r\n\r\n  const subDirs = await Squeeze.getDirectories(currentPath);\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.renderDirectories(subDirs, currentDir, {\r\n    handleDirectoryClick,\r\n    handleDirectoryCheck\r\n  });\r\n\r\n  currentDir.classList.remove(\"loading\");\r\n  currentDir.classList.add(\"loaded\", \"opened\");\r\n}\r\n\r\n/**\r\n * Hadnle warning on page leave\r\n*/\r\nconst handleOnLeave = () => {\r\n  const urlParams = new URLSearchParams(window.location.search);\r\n  const page = urlParams.get('page');\r\n  const isUploadPage = window.location.href.includes('upload.php');\r\n  const isMediaNewPage = window.location.href.includes('media-new.php');\r\n  const isAttachmentPage = window.location.href.includes('post.php') && urlParams.get('action') === 'edit';\r\n\r\n  if (page === 'squeeze-bulk' || isMediaNewPage || isAttachmentPage) {\r\n    return __('Are you sure you want to leave this page? The squeezing process will be terminated!', 'squeeze');\r\n  }\r\n  if (isUploadPage) {\r\n    return __('Are you sure you want to leave this page? The settings will not be saved!', 'squeeze');\r\n  }\r\n};\r\n\r\nconst handleBulkPause = (data, currentPage) => {\r\n  window.onbeforeunload = null;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(__('Bulk squeezing has been paused!', 'squeeze'), { isPause: true });\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs = data;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page = currentPage;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.target.disabled = false;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.updateButtonText(_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.target, __('Resume bulk squeezing', 'squeeze'), '#play-button-round-icon');\r\n};\r\n\r\nconst handleUpdateChart = (uncompressedImagesCount) => {\r\n  const chartValue = document.querySelector(\".squeeze-bulk-media-stats-chart-value > text\");\r\n  const chartBar = document.querySelector(\".squeeze-bulk-media-stats-chart\");\r\n  const squeezedImages = document.querySelector(\".squeeze-bulk-media-stats-item-value\");\r\n\r\n  if (!chartValue || !chartBar) return;\r\n\r\n  const imagesLeft = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.totalImages - uncompressedImagesCount;\r\n  const percentage = parseFloat((imagesLeft / _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.totalImages) * 100).toFixed(2);\r\n  const dasharray = percentage * 560 / 100;\r\n  chartValue.textContent = `${percentage}%`;\r\n  chartBar.style.setProperty('--squeeze-dasharray', dasharray);\r\n\r\n  if (squeezedImages) {\r\n    squeezedImages.textContent = `${imagesLeft} / ${_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.totalImages}`;\r\n  }\r\n};\r\n\r\nconst handleRecursiveUpload = async (path, data, currentPage, isUpdateChart = false) => {\r\n\r\n  if (!Array.isArray(data)) return { success: false, data: 'No data provided!', mediaIDs: [] }; // when bulk directory path has no images\r\n\r\n  const totalPages = getTotalPages(path);\r\n\r\n  if (data.length === 0) {\r\n    currentPage += 1;\r\n    if (currentPage > totalPages || !_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.lastId) return { success: true, data: __('No more images found!', 'squeeze'), mediaIDs: [], page: currentPage };\r\n\r\n    const maybeGetNextMediaIDs = await Squeeze.getNextAttachments(currentPage, path, _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.lastId);\r\n    if (maybeGetNextMediaIDs.success && maybeGetNextMediaIDs.data.length > 0) {\r\n      const nextMediaIDs = maybeGetNextMediaIDs.data;\r\n      return handleRecursiveUpload(path, nextMediaIDs, currentPage, isUpdateChart);\r\n    } else {\r\n      return { success: true, data: __('No more images found!', 'squeeze'), mediaIDs: [], page: currentPage };\r\n    }\r\n  }\r\n\r\n  const initData = [...data];  // initial data\r\n\r\n  const filename = data[0]?.filename ? data[0].filename : `ID #${data[0]}`;\r\n  const mediaLogWrapper = await _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(`${__('Start squeezing...', 'squeeze')}`, { title: filename, isStart: true });\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.lastId = data[0] || 0; // update lastId to the last processed ID\r\n\r\n  try {\r\n    const response = await Squeeze.handleBulkUpload(path, data);\r\n\r\n    //console.log('handleRecursiveUpload response', response);\r\n\r\n    await logAndThumbnail(filename, response, mediaLogWrapper);\r\n\r\n    if (isUpdateChart && path !== 'all') {\r\n      let uncompressedImagesCount = 0;\r\n      if (path === 'uncompressed') {\r\n        _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.uncompressedImages = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.uncompressedImages - 1 || 0;\r\n        uncompressedImagesCount = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.uncompressedImages;\r\n      } else if (path === 'path') {\r\n        uncompressedImagesCount = response.mediaIDs.length;\r\n      }\r\n      handleUpdateChart(uncompressedImagesCount);\r\n    }\r\n\r\n    if (checkPaused(data, currentPage)) {\r\n      return { success: false, data: 'Process has been paused!', mediaIDs: data, page: currentPage };\r\n    }\r\n\r\n    updateUI(initData[0], response);\r\n\r\n    if (response.mediaIDs.length > 0) {\r\n      return handleRecursiveUpload(path, response.mediaIDs, currentPage, isUpdateChart);\r\n    } else {\r\n      currentPage += 1;\r\n      if (currentPage > totalPages) return { ...response, page: currentPage };\r\n\r\n      const lastId = initData[initData.length - 1];\r\n      const maybeGetNextMediaIDs = await Squeeze.getNextAttachments(currentPage, path, lastId);\r\n      if (maybeGetNextMediaIDs.success && maybeGetNextMediaIDs.data.length > 0) {\r\n        const nextMediaIDs = maybeGetNextMediaIDs.data;\r\n        return handleRecursiveUpload(path, nextMediaIDs, currentPage, isUpdateChart);\r\n      }\r\n    }\r\n\r\n    return response;\r\n\r\n  } catch (error) {\r\n    console.error(error);\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(`${error}`, { mediaLogWrapper, iconId: 'ban-sign-icon' });\r\n\r\n    if (data.length > 0) {\r\n      return handleRecursiveUpload(path, data, currentPage, isUpdateChart);\r\n    } else {\r\n      currentPage += 1;\r\n      if (currentPage > totalPages) return { success: false, data: error, mediaIDs: [], page: currentPage };\r\n\r\n      const lastId = initData[initData.length - 1];\r\n      const maybeGetNextMediaIDs = await Squeeze.getNextAttachments(currentPage, path, lastId);\r\n      if (maybeGetNextMediaIDs.success && maybeGetNextMediaIDs.data.length > 0) {\r\n        const nextMediaIDs = maybeGetNextMediaIDs.data;\r\n        return handleRecursiveUpload(path, nextMediaIDs, currentPage, isUpdateChart);\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\n\r\n\r\n/**\r\n * Handles the compression of image before upload using Squeeze.\r\n * It compresses only the original image, not the thumbnails.\r\n * \r\n * @param {object} up - The plupload instance\r\n * @param {object} pluploadFile - The file to be compressed\r\n * @param {object} compressOptions - The compression options object\r\n * @returns {boolean} - Returns false to prevent further processing of the file\r\n */\r\nconst handleCompressBeforeUpload = async (up, pluploadFile, compressOptions) => {\r\n  if (typeof Squeeze === 'undefined') return;\r\n  if (typeof Squeeze.compressBeforeUpload !== 'function') {\r\n    console.warn('Squeeze.compressBeforeUpload is not a function');\r\n    return;\r\n  }\r\n  \r\n  if (pluploadFile?._isSqueezed || pluploadFile?._isExcluded || pluploadFile?._isFailed) {\r\n    //console.warn('File is already compressed:', pluploadFile);\r\n    return; // Skip files that are already compressed\r\n  }\r\n  // Check if the file is an image based on its MIME type\r\n  if (!pluploadFile.type.startsWith('image/')) {\r\n    //console.warn('File is not an image:', pluploadFile.name);\r\n    return; // Skip non-image files\r\n  }\r\n\r\n  const file = pluploadFile.getNative() || pluploadFile.getSource();\r\n\r\n  const type = file?.type?.split('/')[0] ?? '';\r\n  const subtype = file?.type?.split('/')[1] ?? '';\r\n\r\n  if (!_helpers_js__WEBPACK_IMPORTED_MODULE_0__.maybeCompressAttachment(type, subtype, compressOptions)) {\r\n    //console.warn('Skipping compression for:', pluploadFile.name);\r\n    return; // Skip compression for this file\r\n  }\r\n\r\n  //console.time('BeforeUpload')\r\n\r\n  up.stop();\r\n  window.onbeforeunload = handleOnLeave;\r\n  \r\n  \r\n\r\n  try {\r\n    let originalFile = file;\r\n    const base64Obj = await Squeeze.compressBeforeUpload(file);\r\n    if (!base64Obj || !base64Obj.base64) {\r\n      console.warn('Compression skipped or failed for:', file.name);\r\n      pluploadFile.status = plupload.QUEUED;\r\n      pluploadFile.loaded = 0;\r\n      pluploadFile._isFailed = true; // Mark the file as failed\r\n      //window.onbeforeunload = null;\r\n      setTimeout(() => up.start(), 0);\r\n      return; // Skip further processing if compression failed or was skipped\r\n    }\r\n    \r\n    const isDirectWebp = compressOptions?.direct_webp && file.type !== 'image/webp';\r\n    const isBackupOriginal = compressOptions?.backup_original;\r\n\r\n    if (isBackupOriginal) {\r\n      // If backup original is enabled, convert the original file to WebP if it's not already\r\n      if (isDirectWebp) {\r\n        originalFile = await Squeeze.convertFileToWebp(file);\r\n      } else {\r\n        originalFile = file; // Keep the original file as is\r\n      }\r\n      pluploadFile.originalFile = originalFile; // Store the original file in the pluploadFile object\r\n    }\r\n\r\n    const compressedFile = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.base64ToFile(base64Obj.base64, file.name, file.type);\r\n    const newSource = new mOxie.File(null, compressedFile);\r\n\r\n    if (!newSource) {\r\n      console.error('Failed to create new mOxie.File from base64 data');\r\n      return; // Exit if newSource is not created\r\n    }\r\n\r\n    //console.log('Compressed file created:', newSource);\r\n\r\n    // Override the file's getSource method to return the new compressed source\r\n    pluploadFile.getSource = function () {\r\n      return newSource;\r\n    };\r\n\r\n    // Reset status back to QUEUED\r\n    pluploadFile.status = plupload.QUEUED;\r\n    pluploadFile.loaded = 0;\r\n    pluploadFile._isSqueezed = true; // Mark the file as compressed\r\n    pluploadFile.base64 = base64Obj.base64; // Store the base64 data of the compressed image in the attachment\r\n    pluploadFile.base64Webp = base64Obj?.base64Webp; // Store the WebP base64 data of the compressed image in the attachment\r\n    \r\n    // In the next tick, restart the queue\r\n    setTimeout(() => up.start(), 0);\r\n\r\n    //window.onbeforeunload = null;\r\n\r\n  } catch (error) {\r\n    console.error('Error during compression before upload:', error);\r\n    pluploadFile.status = plupload.QUEUED;\r\n    pluploadFile.loaded = 0;\r\n    pluploadFile._isFailed = true; // Mark the file as failed\r\n    setTimeout(() => up.start(), 0);\r\n    return false;\r\n  }\r\n\r\n  return true;\r\n}\r\n\r\nconst handleMultiFileFormUpload = (compressOptions) => {\r\n  if (typeof wpUploaderInit === 'undefined' || typeof plupload === 'undefined' || typeof uploader === 'undefined') return;\r\n\r\n  const SqueezeUploader = uploader;\r\n\r\n  SqueezeUploader.bind('BeforeUpload', async function (up, pluploadFile) {\r\n    handleCompressBeforeUpload(up, pluploadFile, compressOptions)\r\n  });\r\n\r\n  SqueezeUploader.bind('FileUploaded', function (up, file, response) {\r\n    //console.log('FileUploaded', file, response);\r\n    const fileMime = file.type;\r\n    const fileType = fileMime.split('/')[0];\r\n    const fileSubType = fileMime.split('/')[1];\r\n\r\n    if (!_helpers_js__WEBPACK_IMPORTED_MODULE_0__.maybeCompressAttachment(fileType, fileSubType, compressOptions)) return;\r\n\r\n    /**\r\n     * Wait for media item to load( 'async-upload.php' )\r\n     * Ping every 1 second until the media item is loaded\r\n     * @returns Promise\r\n    */\r\n    const waitForItemLoad = (addProgressBar = true) => {\r\n      return new Promise((resolve) => {\r\n        let interval = setInterval(() => {\r\n          if (mediaItem.querySelector('.media-item-wrapper')) {\r\n            if (addProgressBar) {\r\n              mediaItem.querySelector('.media-item-wrapper').innerHTML += `\r\n                <div class=\"progress\">\r\n                  <div class=\"percent\">${__('Squeezing...', 'squeeze')}</div>\r\n                  <div class=\"bar\" style=\"width: 200px;\"></div>\r\n                </div>\r\n              `;\r\n            }\r\n            clearInterval(interval);\r\n            resolve();\r\n          }\r\n        }, 1000);\r\n      });\r\n    };\r\n\r\n    const fileID = file.id;\r\n    const attachmentID = response.response;\r\n    const mediaItem = document.getElementById(`media-item-${fileID}`);\r\n\r\n    if (file?._isExcluded) {\r\n      console.warn('File is excluded from compression:', file.name);\r\n      waitForItemLoad(false).then(() => {\r\n        mediaItem.innerHTML += `<div class=\"squeeze_status\">${__('File is excluded from compression:', 'squeeze')} ${file.name}</div>`;\r\n      });\r\n      window.onbeforeunload = null;\r\n      return;\r\n    }\r\n\r\n    if (file?._isFailed) {\r\n      console.warn('File compression failed:', file.name);\r\n      waitForItemLoad(false).then(() => {\r\n        mediaItem.innerHTML += `<div class=\"squeeze_status\">${__('File compression failed:', 'squeeze')} ${file.name}</div>`;\r\n      });\r\n      window.onbeforeunload = null;\r\n      return;\r\n    }\r\n\r\n    window.onbeforeunload = handleOnLeave;\r\n\r\n    waitForItemLoad().then(() => {\r\n      try {\r\n        wp.media.attachment(attachmentID).fetch().then(async function (data) {\r\n          //console.log('Fetched attachment data:', data);\r\n          const attachment = { attributes: data };\r\n\r\n          _helpers_js__WEBPACK_IMPORTED_MODULE_0__.extendAttachment(attachment, file);\r\n\r\n          try {\r\n            const compressData = await Squeeze.handleCompress(attachment);\r\n            const uploadData = await Squeeze.handleUpload({ attachment, base64: compressData });\r\n\r\n            if (uploadData.success) {\r\n              window.onbeforeunload = null;\r\n              mediaItem.innerHTML += `<div class=\"squeeze_status\">${uploadData?.data?.message}</div>`;\r\n              mediaItem.querySelector('.progress')?.remove();\r\n            } else {\r\n              mediaItem.innerHTML += uploadData?.data?.message ?? uploadData?.data ?? uploadData;\r\n              window.onbeforeunload = null;\r\n              mediaItem.querySelector('.progress')?.remove();\r\n            }\r\n          } catch (error) {\r\n            console.error(error);\r\n            mediaItem.innerHTML += error;\r\n            window.onbeforeunload = null;\r\n            mediaItem.querySelector('.progress')?.remove();\r\n          }\r\n        });\r\n      } catch (error) {\r\n        console.error(error);\r\n        mediaItem.innerHTML += error;\r\n        window.onbeforeunload = null;\r\n        mediaItem.querySelector('.progress')?.remove();\r\n      }\r\n    });\r\n  });\r\n}\r\n\r\n\n\n//# sourceURL=webpack:///./assets/js/handlers.js?");
    3030
    3131/***/ }),
     
    3737/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
    3838
    39 eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"base64SizeInBytes\": () => (/* binding */ base64SizeInBytes),\n/* harmony export */   \"base64ToBlob\": () => (/* binding */ base64ToBlob),\n/* harmony export */   \"cachedMediaData\": () => (/* binding */ cachedMediaData),\n/* harmony export */   \"disableAllButtons\": () => (/* binding */ disableAllButtons),\n/* harmony export */   \"disableBulkButtons\": () => (/* binding */ disableBulkButtons),\n/* harmony export */   \"elements\": () => (/* binding */ elements),\n/* harmony export */   \"humanFileSize\": () => (/* binding */ humanFileSize),\n/* harmony export */   \"isDocHidden\": () => (/* binding */ isDocHidden),\n/* harmony export */   \"logMessage\": () => (/* binding */ logMessage),\n/* harmony export */   \"maybeCompressAttachment\": () => (/* binding */ maybeCompressAttachment),\n/* harmony export */   \"populatePathInput\": () => (/* binding */ populatePathInput),\n/* harmony export */   \"removeAllButtons\": () => (/* binding */ removeAllButtons),\n/* harmony export */   \"renderDirectories\": () => (/* binding */ renderDirectories),\n/* harmony export */   \"renderTemplate\": () => (/* binding */ renderTemplate),\n/* harmony export */   \"restoreBulkButtons\": () => (/* binding */ restoreBulkButtons),\n/* harmony export */   \"updateButtonText\": () => (/* binding */ updateButtonText)\n/* harmony export */ });\n\r\n\r\nconst { __ } = wp.i18n; // Import __() from wp.i18n\r\n\r\n// move static helper functions here\r\nconst elements = {\r\n  bulkBtn: document.querySelector(\"[name='squeeze_bulk']\"),\r\n  bulkAgainBtn: document.querySelector(\"[name='squeeze_bulk_again']\"),\r\n  bulkPathBtn: document.querySelector(\"[name='squeeze_bulk_path_button']\"),\r\n  selectPathBtn: document.querySelector(\"[name='squeeze_select_path_button']\"),\r\n  savePathBtn: document.querySelector(\"[name='squeeze_save_path_button']\"),\r\n  pathDialog: document.getElementById(\"squeeze-path-dialog\"),\r\n  closePathDialogBtn: document.querySelector(\"[name='squeeze_close_path_dialog_button']\"),\r\n  pathInput: document.querySelector(\"[name='squeeze_bulk_path']\"),\r\n  pathList: document.querySelector(\".squeeze-path-list\"),\r\n  postsFilterForm: document.querySelector(\"#posts-filter\"),\r\n  dirContainer: document.getElementById(\"squeeze-bulk-directory-list\"),\r\n  bulkLogInput: document.querySelector(\"#squeeze-log-data\"),\r\n  pauseBulkBtn: document.querySelector(\"[name='squeeze_pause_page_bulk']\")\r\n}\r\n\r\nconst cachedMediaData = {\r\n  isPaused: false,\r\n  page: 1,\r\n  process: '',\r\n  mediaIDs: [],\r\n  lastId: 0,\r\n  totalImages: document.querySelector(\"[name='squeeze_bulk_total_images']\")?.value || 0,\r\n  uncompressedImages: document.querySelector(\"[name='squeeze_bulk_uncompressed_images']\")?.value || 0,\r\n  target: null\r\n}\r\n\r\nconst loadTemplate = async (templatePath, data) => {\r\n  const response = await fetch(templatePath);\r\n  let template = await response.text();\r\n\r\n  // Process sub-templates\r\n  const subTemplateRegex = /\\{\\{\\>\\s*(.*?)\\s*\\}\\}/g;\r\n  let match;\r\n  while ((match = subTemplateRegex.exec(template)) !== null) {\r\n    const subTemplatePath = `${squeezeOptions.templateBase}/${match[1].trim()}.html`;\r\n    const subTemplate = await loadTemplate(subTemplatePath, data);\r\n    template = template.replace(match[0], subTemplate);\r\n  }\r\n\r\n  // Function to safely evaluate conditions (supports boolean variables, expressions, AND/OR)\r\n  const evaluateCondition = (condition, data) => {\r\n    try {\r\n      // Convert standalone boolean variables (e.g., webp_lossless) to data['webp_lossless']\r\n      condition = condition.replace(/\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b/g, (match) =>\r\n        match in data ? `data['${match}']` : match\r\n      );\r\n\r\n      return new Function(\"data\", `with(data) { return ${condition}; }`)(data);\r\n    } catch (e) {\r\n      console.error(\"Error evaluating condition:\", condition, e);\r\n      return false;\r\n    }\r\n  };\r\n\r\n  // Recursive function to process nested if-else conditions\r\n  const processIfStatements = (template) => {\r\n    return template.replace(/\\{\\{#if ([\\s\\S]*?)\\}\\}([\\s\\S]*?)\\{\\{\\/if\\}\\}/g, (match, condition, content) => {\r\n      condition = condition.trim();\r\n      const conditionResult = evaluateCondition(condition, data);\r\n\r\n      // Extract and split the if-else blocks\r\n      const elseMatch = content.match(/\\{\\{#else\\}\\}([\\s\\S]*)/);\r\n      const trueBlock = elseMatch ? content.replace(/\\{\\{#else\\}\\}([\\s\\S]*)/, \"\") : content;\r\n      const falseBlock = elseMatch ? elseMatch[1] : \"\";\r\n\r\n      // Process nested if statements recursively\r\n      return processIfStatements(conditionResult ? trueBlock : falseBlock);\r\n    });\r\n  };\r\n\r\n  // Apply recursive processing of if conditions\r\n  template = processIfStatements(template);\r\n\r\n  // Replace variables\r\n  return template.replace(/\\{\\{(.*?)\\}\\}/g, (match, key) => data[key.trim()] || '');\r\n}\r\n\r\nconst renderTemplate = async (templatePath, data, target = null) => {\r\n  const renderedHTML = await loadTemplate(templatePath, data);\r\n\r\n  // Create a temporary container to parse HTML\r\n  const tempContainer = document.createElement(\"template\");\r\n  tempContainer.innerHTML = renderedHTML.trim();\r\n\r\n  if (!target) {\r\n    return tempContainer.content.firstChild;\r\n  }\r\n\r\n  target.appendChild(tempContainer.content.firstChild);\r\n\r\n  // Return the last element of the rendered template\r\n  return target.lastElementChild;\r\n}\r\n\r\nconst logMessage = async (msg, options = {}) => {\r\n  const { mediaLogWrapper = null, isStart = false, isPause = false } = options;\r\n  let { title = '', iconId = 'check-mark-circle-icon' } = options;\r\n\r\n  if (!elements.bulkLogInput) return;\r\n\r\n  if (isStart || isPause) {\r\n    iconId = isPause ? 'pause-button-icon' : 'image-file-icon';\r\n    title = isPause ? __('Bulk squeezing has been paused!', 'squeeze') : `${__('Media', 'squeeze')} ${title}:`;\r\n    return await renderTemplate(squeezeOptions.templates.logWrapper, { title: title, msg: msg, iconId: iconId, isStart: isStart, isPause: isPause }, elements.bulkLogInput);\r\n  } else {\r\n    if (mediaLogWrapper) {\r\n      const process = mediaLogWrapper.querySelector(\".media-log-process\");\r\n      const step = await renderTemplate(squeezeOptions.templates.logStep, { msg: msg, iconId: iconId }, process);\r\n\r\n      if (msg.includes('squeeze-comparison-table')) {\r\n        const comparisonTable = step.querySelector('.squeeze-comparison-table');\r\n        const toggleBtn = await renderTemplate(squeezeOptions.templates.logDetailsButton, { buttonText: __('Show details', 'squeeze') }, mediaLogWrapper);\r\n\r\n        toggleBtn.addEventListener(\"click\", () => {\r\n          comparisonTable.classList.toggle(\"show\");\r\n          toggleBtn.textContent = comparisonTable.classList.contains(\"show\") ? __('Hide details', 'squeeze') : __('Show details', 'squeeze');\r\n        });\r\n        step.closest(\".media-log-wrapper\").appendChild(comparisonTable);\r\n        step.closest(\".media-log-wrapper\").appendChild(toggleBtn);\r\n      }\r\n    } else {\r\n      elements.bulkLogInput.innerHTML += msg + `<br>`;\r\n    }\r\n  }\r\n}\r\n\r\nconst restoreBulkButtons = () => {\r\n  elements.bulkBtn.disabled = false;\r\n  elements.bulkAgainBtn.disabled = false;\r\n  elements.bulkPathBtn.disabled = false;\r\n  elements.selectPathBtn.disabled = false;\r\n  updateButtonText(elements.bulkBtn, __('Run Bulk Squeeze', 'squeeze'), '#play-button-round-icon');\r\n  updateButtonText(elements.bulkAgainBtn, __('Repeat Bulk Squeeze', 'squeeze'), '#combine-left-right-outline-icon');\r\n  updateButtonText(elements.bulkPathBtn, __('Run Directory Squeeze', 'squeeze'), '#play-button-round-icon');\r\n  elements.bulkBtn.dataset.running = 'false';\r\n  elements.bulkAgainBtn.dataset.running = 'false';\r\n  elements.bulkPathBtn.dataset.running = 'false';\r\n\r\n  cachedMediaData.process = '';\r\n  cachedMediaData.mediaIDs = [];\r\n  cachedMediaData.page = 1;\r\n}\r\n\r\nconst disableBulkButtons = () => {\r\n  elements.bulkBtn.disabled = true;\r\n  elements.bulkAgainBtn.disabled = true;\r\n  elements.bulkPathBtn.disabled = true;\r\n  elements.selectPathBtn.disabled = true;\r\n}\r\n\r\nconst disableAllButtons = (buttons) => {\r\n  if (!buttons) return;\r\n  buttons.forEach((btn) => btn.disabled = true);\r\n}\r\n\r\nconst removeAllButtons = (buttons) => {\r\n  if (!buttons) return;\r\n  buttons.forEach((btn) => btn.remove());\r\n}\r\n\r\nconst updateButtonText = (button, text, svgAnchor = false) => {\r\n  button.childNodes.forEach((node) => {\r\n    if (node.nodeName === '#text' && node.textContent.trim() !== '') {\r\n      node.textContent = text;\r\n    }\r\n    if (svgAnchor && node.nodeName === 'svg') {\r\n      node.querySelector('use').setAttribute('xlink:href', svgAnchor);\r\n    }\r\n  });\r\n}\r\n\r\n// Function to render directories in the dialog\r\nconst renderDirectories = async (dirs, parentDir = null, listeners = {}) => {\r\n  if (!dirs) return;\r\n  if (typeof dirs === 'object') dirs = Object.values(dirs);\r\n  if (!elements.dirContainer.classList.contains(\"loaded\")) elements.dirContainer.innerHTML = \"\";\r\n\r\n  if (dirs.length === 0 && !parentDir) {\r\n    const listItem = await renderTemplate(squeezeOptions.templates.directoryItemEmpty, { emptyText: __('No directories found!', 'squeeze') }, elements.dirContainer);\r\n    return;\r\n  }\r\n\r\n  const selectedFolders = JSON.parse(elements.pathInput.value);\r\n  let target;\r\n\r\n  for (const dir of dirs) {\r\n    const listItemClasses = [];\r\n\r\n    if (dir.parent === '/') {\r\n      listItemClasses.push(\"loaded\", \"opened\");\r\n    }\r\n\r\n    if (parentDir) {\r\n      target = parentDir;\r\n    } else if (dir.parent) {\r\n      const parentElement = elements.dirContainer.querySelector(`[data-path=\"${dir.parent}\"]`);\r\n      if (parentElement) {\r\n        target = parentElement;\r\n      } else {\r\n        target = elements.dirContainer;\r\n      }\r\n    } else {\r\n      target = elements.dirContainer;\r\n    }\r\n\r\n    const listItem = await renderTemplate(\r\n      squeezeOptions.templates.directoryItem,\r\n      {\r\n        parent: dir.parent,\r\n        path: dir.path,\r\n        label: dir.name,\r\n        classes: listItemClasses.join(\" \"),\r\n        isWritable: dir.is_writeable && !(Array.isArray(selectedFolders) && selectedFolders.includes(dir.path)),\r\n        isChecked: dir.is_writeable && Array.isArray(selectedFolders) && selectedFolders.includes(dir.path),\r\n      },\r\n      target\r\n    )\r\n\r\n    listItem.querySelector(\"label\").addEventListener(\"click\", listeners.handleDirectoryClick);\r\n    listItem.querySelector(\"input[type='checkbox']\")?.addEventListener(\"change\", listeners.handleDirectoryCheck);\r\n  }\r\n\r\n  elements.dirContainer.classList.add(\"loaded\");\r\n}\r\n\r\nconst populatePathInput = async () => {\r\n  const path = elements.pathInput.value;\r\n  if (!path) return;\r\n\r\n  try {\r\n    const selectedFolders = JSON.parse(path);\r\n    const inputs = elements.pathList.querySelectorAll(\".squeeze-path-list__item\");\r\n\r\n    inputs.forEach(input => input.remove());\r\n\r\n    for (const folder of selectedFolders) {\r\n      const input = await renderTemplate(squeezeOptions.templates.pathListItem, { folder: folder }, elements.pathList);\r\n    }\r\n  } catch (error) {\r\n    alert(__('Error parsing path input!', 'squeeze'));\r\n    console.error('Error parsing path input:', error);\r\n  }\r\n}\r\n\r\nconst getHiddenProp = () => {\r\n  var prefixes = ['webkit', 'moz', 'ms', 'o'];\r\n\r\n  // if 'hidden' is natively supported just return it\r\n  if ('hidden' in document) return 'hidden';\r\n\r\n  // otherwise loop over all the known prefixes until we find one\r\n  for (let i = 0; i < prefixes.length; i++) {\r\n    if ((prefixes[i] + 'Hidden') in document)\r\n      return prefixes[i] + 'Hidden';\r\n  }\r\n\r\n  // otherwise it's not supported\r\n  return null;\r\n}\r\n\r\nconst isDocHidden = () => {\r\n  const prop = getHiddenProp();\r\n  if (!prop) return false;\r\n\r\n  return document[prop];\r\n}\r\n\r\n/**\r\n * @see https://stackoverflow.com/a/20732091\r\n */\r\nconst humanFileSize = (size) => {\r\n  let i = size == 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024));\r\n  return +((size / Math.pow(1024, i)).toFixed(2)) * 1 + ' ' + ['B', 'KB', 'MB', 'GB', 'TB'][i];\r\n}\r\n\r\nconst base64SizeInBytes = (base64) => {\r\n  // Remove data URL prefix if present\r\n  const base64String = base64.split(',')[1] || base64;  \r\n\r\n  // Calculate padding characters ('=' at the end of Base64)\r\n  const padding = (base64String.match(/=+$/) || [\"\"])[0].length;\r\n\r\n  // Compute byte size\r\n  return (base64String.length * 3) / 4 - padding;\r\n}\r\n\r\nconst maybeCompressAttachment = (attachmentType, attachmentSubType, compressOptions) => {\r\n  const isAutoCompress = compressOptions.auto_compress;\r\n  const allowedMimeTypes = ['jpeg', 'png', 'webp', 'avif'];\r\n  const isImage = attachmentType === 'image' && allowedMimeTypes.includes(attachmentSubType);\r\n\r\n  return isImage && isAutoCompress;\r\n};\r\n\r\nconst base64ToBlob = (base64, type = 'image/jpeg') => {\r\n  // Remove data URL prefix if present\r\n  const base64String = base64.split(',')[1] || base64;\r\n\r\n  // Decode Base64 string\r\n  const byteCharacters = atob(base64String);\r\n  const byteNumbers = new Array(byteCharacters.length);\r\n  \r\n  for (let i = 0; i < byteCharacters.length; i++) {\r\n    byteNumbers[i] = byteCharacters.charCodeAt(i);\r\n  }\r\n\r\n  const byteArray = new Uint8Array(byteNumbers);\r\n  return new Blob([byteArray], { type: type });\r\n}\n\n//# sourceURL=webpack:///./assets/js/helpers.js?");
     39eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"base64SizeInBytes\": () => (/* binding */ base64SizeInBytes),\n/* harmony export */   \"base64ToBlob\": () => (/* binding */ base64ToBlob),\n/* harmony export */   \"base64ToFile\": () => (/* binding */ base64ToFile),\n/* harmony export */   \"cachedMediaData\": () => (/* binding */ cachedMediaData),\n/* harmony export */   \"disableAllButtons\": () => (/* binding */ disableAllButtons),\n/* harmony export */   \"disableBulkButtons\": () => (/* binding */ disableBulkButtons),\n/* harmony export */   \"elements\": () => (/* binding */ elements),\n/* harmony export */   \"extendAttachment\": () => (/* binding */ extendAttachment),\n/* harmony export */   \"fileToBase64\": () => (/* binding */ fileToBase64),\n/* harmony export */   \"getFileFromUrl\": () => (/* binding */ getFileFromUrl),\n/* harmony export */   \"handleRemovePathButton\": () => (/* binding */ handleRemovePathButton),\n/* harmony export */   \"humanFileSize\": () => (/* binding */ humanFileSize),\n/* harmony export */   \"isDocHidden\": () => (/* binding */ isDocHidden),\n/* harmony export */   \"logMessage\": () => (/* binding */ logMessage),\n/* harmony export */   \"maybeCompressAttachment\": () => (/* binding */ maybeCompressAttachment),\n/* harmony export */   \"objectToFormData\": () => (/* binding */ objectToFormData),\n/* harmony export */   \"populatePathInput\": () => (/* binding */ populatePathInput),\n/* harmony export */   \"removeAllButtons\": () => (/* binding */ removeAllButtons),\n/* harmony export */   \"renderDirectories\": () => (/* binding */ renderDirectories),\n/* harmony export */   \"renderTemplate\": () => (/* binding */ renderTemplate),\n/* harmony export */   \"restoreBulkButtons\": () => (/* binding */ restoreBulkButtons),\n/* harmony export */   \"updateButtonText\": () => (/* binding */ updateButtonText)\n/* harmony export */ });\n\r\n\r\nconst { __ } = wp.i18n; // Import __() from wp.i18n\r\n\r\n// move static helper functions here\r\nconst elements = {\r\n  bulkBtn: document.querySelector(\"[name='squeeze_bulk']\"),\r\n  bulkAgainBtn: document.querySelector(\"[name='squeeze_bulk_again']\"),\r\n  bulkPathBtn: document.querySelector(\"[name='squeeze_bulk_path_button']\"),\r\n  bulkPathRemoveBtns: document.querySelectorAll(\".squeeze-path-list__remove\"),\r\n  selectPathBtn: document.querySelector(\"[name='squeeze_select_path_button']\"),\r\n  savePathBtn: document.querySelector(\"[name='squeeze_save_path_button']\"),\r\n  pathDialog: document.getElementById(\"squeeze-path-dialog\"),\r\n  closePathDialogBtn: document.querySelector(\"[name='squeeze_close_path_dialog_button']\"),\r\n  pathInput: document.querySelector(\"[name='squeeze_bulk_path']\"),\r\n  pathList: document.querySelector(\".squeeze-path-list\"),\r\n  postsFilterForm: document.querySelector(\"#posts-filter\"),\r\n  dirContainer: document.getElementById(\"squeeze-bulk-directory-list\"),\r\n  bulkLogInput: document.querySelector(\"#squeeze-log-data\"),\r\n  pauseBulkBtn: document.querySelector(\"[name='squeeze_pause_page_bulk']\")\r\n}\r\n\r\nconst cachedMediaData = {\r\n  isPaused: false,\r\n  page: 1,\r\n  process: '',\r\n  mediaIDs: [],\r\n  lastId: 0,\r\n  totalImages: document.querySelector(\"[name='squeeze_bulk_total_images']\")?.value || 0,\r\n  uncompressedImages: document.querySelector(\"[name='squeeze_bulk_uncompressed_images']\")?.value || 0,\r\n  target: null\r\n}\r\n\r\nconst loadTemplate = async (templatePath, data) => {\r\n  const response = await fetch(templatePath);\r\n  let template = await response.text();\r\n\r\n  // Process sub-templates\r\n  const subTemplateRegex = /\\{\\{\\>\\s*(.*?)\\s*\\}\\}/g;\r\n  let match;\r\n  while ((match = subTemplateRegex.exec(template)) !== null) {\r\n    const subTemplatePath = `${squeezeOptions.templateBase}/${match[1].trim()}.html`;\r\n    const subTemplate = await loadTemplate(subTemplatePath, data);\r\n    template = template.replace(match[0], subTemplate);\r\n  }\r\n\r\n  // Function to safely evaluate conditions (supports boolean variables, expressions, AND/OR)\r\n  const evaluateCondition = (condition, data) => {\r\n    try {\r\n      // Convert standalone boolean variables (e.g., webp_lossless) to data['webp_lossless']\r\n      condition = condition.replace(/\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b/g, (match) =>\r\n        match in data ? `data['${match}']` : match\r\n      );\r\n\r\n      return new Function(\"data\", `with(data) { return ${condition}; }`)(data);\r\n    } catch (e) {\r\n      console.error(\"Error evaluating condition:\", condition, e);\r\n      return false;\r\n    }\r\n  };\r\n\r\n  // Recursive function to process nested if-else conditions\r\n  const processIfStatements = (template) => {\r\n    return template.replace(/\\{\\{#if ([\\s\\S]*?)\\}\\}([\\s\\S]*?)\\{\\{\\/if\\}\\}/g, (match, condition, content) => {\r\n      condition = condition.trim();\r\n      const conditionResult = evaluateCondition(condition, data);\r\n\r\n      // Extract and split the if-else blocks\r\n      const elseMatch = content.match(/\\{\\{#else\\}\\}([\\s\\S]*)/);\r\n      const trueBlock = elseMatch ? content.replace(/\\{\\{#else\\}\\}([\\s\\S]*)/, \"\") : content;\r\n      const falseBlock = elseMatch ? elseMatch[1] : \"\";\r\n\r\n      // Process nested if statements recursively\r\n      return processIfStatements(conditionResult ? trueBlock : falseBlock);\r\n    });\r\n  };\r\n\r\n  // Apply recursive processing of if conditions\r\n  template = processIfStatements(template);\r\n\r\n  // Replace variables\r\n  return template.replace(/\\{\\{(.*?)\\}\\}/g, (match, key) => data[key.trim()] || '');\r\n}\r\n\r\nconst renderTemplate = async (templatePath, data, target = null) => {\r\n  const renderedHTML = await loadTemplate(templatePath, data);\r\n\r\n  // Create a temporary container to parse HTML\r\n  const tempContainer = document.createElement(\"template\");\r\n  tempContainer.innerHTML = renderedHTML.trim();\r\n\r\n  if (!target) {\r\n    return tempContainer.content.firstChild;\r\n  }\r\n\r\n  target.appendChild(tempContainer.content.firstChild);\r\n\r\n  // Return the last element of the rendered template\r\n  return target.lastElementChild;\r\n}\r\n\r\nconst logMessage = async (msg, options = {}) => {\r\n  const { mediaLogWrapper = null, isStart = false, isPause = false } = options;\r\n  let { title = '', iconId = 'check-mark-circle-icon' } = options;\r\n\r\n  if (!elements.bulkLogInput) return;\r\n\r\n  if (isStart || isPause) {\r\n    iconId = isPause ? 'pause-button-icon' : 'image-file-icon';\r\n    title = isPause ? __('Bulk squeezing has been paused!', 'squeeze') : `${__('Media', 'squeeze')} ${title}:`;\r\n    return await renderTemplate(squeezeOptions.templates.logWrapper, { title: title, msg: msg, iconId: iconId, isStart: isStart, isPause: isPause }, elements.bulkLogInput);\r\n  } else {\r\n    if (mediaLogWrapper) {\r\n      const process = mediaLogWrapper.querySelector(\".media-log-process\");\r\n      const step = await renderTemplate(squeezeOptions.templates.logStep, { msg: msg, iconId: iconId }, process);\r\n\r\n      if (msg && msg.includes('squeeze-comparison-table')) {\r\n        const comparisonTable = step.querySelector('.squeeze-comparison-table');\r\n        const toggleBtn = await renderTemplate(squeezeOptions.templates.logDetailsButton, { buttonText: __('Show details', 'squeeze') }, mediaLogWrapper);\r\n\r\n        toggleBtn.addEventListener(\"click\", () => {\r\n          comparisonTable.classList.toggle(\"show\");\r\n          toggleBtn.textContent = comparisonTable.classList.contains(\"show\") ? __('Hide details', 'squeeze') : __('Show details', 'squeeze');\r\n        });\r\n        step.closest(\".media-log-wrapper\").appendChild(comparisonTable);\r\n        step.closest(\".media-log-wrapper\").appendChild(toggleBtn);\r\n      }\r\n    } else {\r\n      elements.bulkLogInput.innerHTML += msg + `<br>`;\r\n    }\r\n  }\r\n}\r\n\r\nconst restoreBulkButtons = () => {\r\n  elements.bulkBtn.disabled = false;\r\n  elements.bulkAgainBtn.disabled = false;\r\n  elements.bulkPathBtn.disabled = false;\r\n  elements.selectPathBtn.disabled = false;\r\n  updateButtonText(elements.bulkBtn, __('Run Bulk Squeeze', 'squeeze'), '#play-button-round-icon');\r\n  updateButtonText(elements.bulkAgainBtn, __('Repeat Bulk Squeeze', 'squeeze'), '#combine-left-right-outline-icon');\r\n  updateButtonText(elements.bulkPathBtn, __('Run Directory Squeeze', 'squeeze'), '#play-button-round-icon');\r\n  elements.bulkBtn.dataset.running = 'false';\r\n  elements.bulkAgainBtn.dataset.running = 'false';\r\n  elements.bulkPathBtn.dataset.running = 'false';\r\n  elements.bulkPathRemoveBtns?.forEach((btn) => {\r\n    btn.disabled = false;\r\n  });\r\n\r\n  cachedMediaData.process = '';\r\n  cachedMediaData.mediaIDs = [];\r\n  cachedMediaData.page = 1;\r\n}\r\n\r\nconst disableBulkButtons = () => {\r\n  elements.bulkBtn.disabled = true;\r\n  elements.bulkAgainBtn.disabled = true;\r\n  elements.bulkPathBtn.disabled = true;\r\n  elements.selectPathBtn.disabled = true;\r\n  elements.bulkPathRemoveBtns?.forEach((btn) => btn.disabled = true);\r\n}\r\n\r\nconst disableAllButtons = (buttons) => {\r\n  if (!buttons) return;\r\n  buttons.forEach((btn) => btn.disabled = true);\r\n}\r\n\r\nconst removeAllButtons = (buttons) => {\r\n  if (!buttons) return;\r\n  buttons.forEach((btn) => btn.remove());\r\n}\r\n\r\nconst updateButtonText = (button, text, svgAnchor = false) => {\r\n  button.childNodes.forEach((node) => {\r\n    if (node.nodeName === '#text' && node.textContent.trim() !== '') {\r\n      node.textContent = text;\r\n    }\r\n    if (svgAnchor && node.nodeName === 'svg') {\r\n      node.querySelector('use').setAttribute('xlink:href', svgAnchor);\r\n    }\r\n  });\r\n}\r\n\r\n// Function to render directories in the dialog\r\nconst renderDirectories = async (dirs, parentDir = null, listeners = {}) => {\r\n  if (!dirs) return;\r\n  if (typeof dirs === 'object') dirs = Object.values(dirs);\r\n  if (!elements.dirContainer.classList.contains(\"loaded\")) elements.dirContainer.innerHTML = \"\";\r\n\r\n  if (dirs.length === 0 && !parentDir) {\r\n    const listItem = await renderTemplate(squeezeOptions.templates.directoryItemEmpty, { emptyText: __('No directories found!', 'squeeze') }, elements.dirContainer);\r\n    return;\r\n  }\r\n\r\n  const selectedFolders = JSON.parse(elements.pathInput.value);\r\n  let target;\r\n\r\n  for (const dir of dirs) {\r\n    const listItemClasses = [];\r\n\r\n    if (dir.parent === '/') {\r\n      listItemClasses.push(\"loaded\", \"opened\");\r\n    }\r\n\r\n    if (parentDir) {\r\n      target = parentDir;\r\n    } else if (dir.parent) {\r\n      const parentElement = elements.dirContainer.querySelector(`[data-path=\"${dir.parent}\"]`);\r\n      if (parentElement) {\r\n        target = parentElement;\r\n      } else {\r\n        target = elements.dirContainer;\r\n      }\r\n    } else {\r\n      target = elements.dirContainer;\r\n    }\r\n\r\n    const listItem = await renderTemplate(\r\n      squeezeOptions.templates.directoryItem,\r\n      {\r\n        parent: dir.parent,\r\n        path: dir.path,\r\n        label: dir.name,\r\n        classes: listItemClasses.join(\" \"),\r\n        isWritable: dir.is_writeable && !(Array.isArray(selectedFolders) && selectedFolders.includes(dir.path)),\r\n        isChecked: dir.is_writeable && Array.isArray(selectedFolders) && selectedFolders.includes(dir.path),\r\n      },\r\n      target\r\n    )\r\n\r\n    listItem.querySelector(\"label\").addEventListener(\"click\", listeners.handleDirectoryClick);\r\n    listItem.querySelector(\"input[type='checkbox']\")?.addEventListener(\"change\", listeners.handleDirectoryCheck);\r\n  }\r\n\r\n  elements.dirContainer.classList.add(\"loaded\");\r\n}\r\n\r\nconst handleRemovePathButton = (e) => {\r\n  e.preventDefault();\r\n  const item = e.target.closest(\".squeeze-path-list__item\");\r\n  if (item) {\r\n    item.remove();\r\n    const currentPaths = Array.from(elements.pathList.querySelectorAll(\".squeeze-path-list__input\"))\r\n      .map(input => input.value.trim())\r\n      .filter(value => value !== '');\r\n    elements.pathInput.value = JSON.stringify(currentPaths);\r\n  }\r\n}\r\n\r\nconst populatePathInput = async () => {\r\n  const path = elements.pathInput.value;\r\n  if (!path) return;\r\n\r\n  try {\r\n    const selectedFolders = JSON.parse(path);\r\n    const items = elements.pathList.querySelectorAll(\".squeeze-path-list__item\");\r\n\r\n    items.forEach(item => item.remove());\r\n\r\n    for (const folder of selectedFolders) {\r\n      const item = await renderTemplate(squeezeOptions.templates.pathListItem, { folder: folder }, elements.pathList);\r\n      const removeButton = item.querySelector(\".squeeze-path-list__remove\");\r\n      removeButton.addEventListener(\"click\", handleRemovePathButton);\r\n\r\n    }\r\n  } catch (error) {\r\n    alert(__('Error parsing path input!', 'squeeze'));\r\n    console.error('Error parsing path input:', error);\r\n  }\r\n}\r\n\r\nconst getHiddenProp = () => {\r\n  var prefixes = ['webkit', 'moz', 'ms', 'o'];\r\n\r\n  // if 'hidden' is natively supported just return it\r\n  if ('hidden' in document) return 'hidden';\r\n\r\n  // otherwise loop over all the known prefixes until we find one\r\n  for (let i = 0; i < prefixes.length; i++) {\r\n    if ((prefixes[i] + 'Hidden') in document)\r\n      return prefixes[i] + 'Hidden';\r\n  }\r\n\r\n  // otherwise it's not supported\r\n  return null;\r\n}\r\n\r\nconst isDocHidden = () => {\r\n  const prop = getHiddenProp();\r\n  if (!prop) return false;\r\n\r\n  return document[prop];\r\n}\r\n\r\n/**\r\n * @see https://stackoverflow.com/a/20732091\r\n */\r\nconst humanFileSize = (size) => {\r\n  let i = size == 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024));\r\n  return +((size / Math.pow(1024, i)).toFixed(2)) * 1 + ' ' + ['B', 'KB', 'MB', 'GB', 'TB'][i];\r\n}\r\n\r\nconst base64SizeInBytes = (base64) => {\r\n  // Remove data URL prefix if present\r\n  const base64String = base64.split(',')[1] || base64;  \r\n\r\n  // Calculate padding characters ('=' at the end of Base64)\r\n  const padding = (base64String.match(/=+$/) || [\"\"])[0].length;\r\n\r\n  // Compute byte size\r\n  return (base64String.length * 3) / 4 - padding;\r\n}\r\n\r\nconst maybeCompressAttachment = (attachmentType, attachmentSubType, compressOptions = null) => {\r\n  const isAutoCompress = compressOptions?.auto_compress ?? true;\r\n  const allowedMimeTypes = ['jpeg', 'png', 'webp', 'avif'];\r\n  const isImage = attachmentType === 'image' && allowedMimeTypes.includes(attachmentSubType);\r\n\r\n  return isImage && isAutoCompress;\r\n};\r\n\r\nconst base64ToBlob = (base64, type = 'image/jpeg') => {\r\n  // Remove data URL prefix if present\r\n  const base64String = base64.split(',')[1] || base64;\r\n\r\n  // Decode Base64 string\r\n  const byteCharacters = atob(base64String);\r\n  const byteNumbers = new Array(byteCharacters.length);\r\n  \r\n  for (let i = 0; i < byteCharacters.length; i++) {\r\n    byteNumbers[i] = byteCharacters.charCodeAt(i);\r\n  }\r\n\r\n  const byteArray = new Uint8Array(byteNumbers);\r\n  return new Blob([byteArray], { type: type });\r\n}\r\n\r\nconst base64ToFile = (base64, fileName = 'image.jpg', type = 'image/jpeg') => {\r\n  const blob = base64ToBlob(base64, type);\r\n  return new File([blob], fileName, { type: type });\r\n}\r\n\r\nconst fileToBase64 = (file) => {\r\n  return new Promise((resolve, reject) => {\r\n    const reader = new FileReader();\r\n    reader.onload = () => resolve(reader.result);\r\n    reader.onerror = (error) => reject(error);\r\n    reader.readAsDataURL(file);\r\n  });\r\n}\r\n\r\nfunction objectToFormData(obj, fd = null, parentKey = null) {\r\n  const formData = fd || new FormData();\r\n\r\n  for (const key in obj) {\r\n    if (!obj.hasOwnProperty(key)) continue;\r\n    const value = obj[key];\r\n\r\n    // build the form key: either \"foo\", \"parent[foo]\" or \"parent[]\" for arrays\r\n    const formKey = parentKey\r\n      ? Array.isArray(obj)\r\n        ? `${parentKey}[]`\r\n        : `${parentKey}[${key}]`\r\n      : key;\r\n\r\n    // Files or Blobs go straight in\r\n    if (value instanceof File || value instanceof Blob) {\r\n      formData.append(formKey, value, value.name);\r\n    }\r\n    // Arrays: recurse so they become key[]=val0, key[]=val1…\r\n    else if (Array.isArray(value)) {\r\n      objectToFormData(value, formData, formKey);\r\n    }\r\n    // Plain objects: recurse so they become key[subkey]=subval\r\n    else if (\r\n      value !== null &&\r\n      typeof value === 'object' &&\r\n      !(value instanceof Date)\r\n    ) {\r\n      objectToFormData(value, formData, formKey);\r\n    }\r\n    // Dates: convert to ISO string (or format as you like)\r\n    else if (value instanceof Date) {\r\n      formData.append(formKey, value.toISOString());\r\n    }\r\n    // Everything else (number, string, boolean, null, undefined)\r\n    else {\r\n      // Explicitly convert undefined to empty string so PHP sees it\r\n      const stringVal =\r\n        value === undefined || value === null ? '' : String(value);\r\n      formData.append(formKey, stringVal);\r\n    }\r\n  }\r\n\r\n  return formData;\r\n}\r\n\r\n/**\r\n * Extend the attachment object with additional data from the file.\r\n * @param {object} attachment \r\n * @param {object} file \r\n * @returns {object} — the extended attachment object.\r\n */\r\nconst extendAttachment = async (attachment, file) => {\r\n  if (typeof attachment !== 'object' || !attachment.attributes) {\r\n    console.warn('Invalid attachment object:', attachment);\r\n    return;\r\n  }\r\n\r\n  const attributes = attachment.attributes;\r\n\r\n  if (file?.base64) {\r\n    attributes.base64Compressed = file.base64; // Use the base64 data from the attachment\r\n  }\r\n\r\n  if (file?.base64Webp) {\r\n    attributes.base64WebpCompressed = file.base64Webp; // Use the WebP base64 data from the attachment\r\n  }\r\n\r\n  if (file?.originalFile) {\r\n    attributes.originalFile = file.originalFile; // Use the original file from the attachment to be able to create a backup\r\n  }\r\n\r\n  return attachment;\r\n}\r\n\r\nconst getFileFromUrl = async (url, filename, format) => {\r\n  const response = await fetch(url);\r\n  const blob = await response.blob();\r\n  const mimeType = format ? `image/${format}` : blob.type;\r\n  return new File([blob], filename, { type: mimeType });\r\n}\n\n//# sourceURL=webpack:///./assets/js/helpers.js?");
    4040
    4141/***/ }),
     
    4747/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
    4848
    49 eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ SQUEEZE)\n/* harmony export */ });\n\r\n\r\nconst { __ } = wp.i18n; // Import __() from wp.i18n\r\n\r\nclass SQUEEZE {\r\n\r\n  constructor(squeeze) {\r\n    this.options = JSON.parse(squeeze.options); // plugin options\r\n    this.nonce = squeeze.nonce; // nonce\r\n    this.ajaxUrl = squeeze.ajaxUrl; // ajax url\r\n    this.timeout = parseInt(this.options.timeout) * 1000; // convert to milliseconds\r\n    this.poolSize = navigator.hardwareConcurrency || 1; // number of threads\r\n  }\r\n\r\n  handleCompress = async ( attachment ) => {\r\n    const attachmentData = attachment.attributes;\r\n    const url = attachmentData?.originalImageURL ?? attachmentData.url;\r\n    const mime = attachmentData.mime;\r\n    const name = attachmentData.name;\r\n    const filename = attachmentData?.originalImageName ?? attachmentData.filename;\r\n    const attachmentID = attachmentData.id;\r\n    const sizes = attachmentData.sizes;\r\n    const format = mime.split(\"/\")[1];\r\n    const sourceType = format;\r\n    const outputType = format;\r\n    const skipFull = attachmentData.originalImageName === undefined ? true : false;\r\n    const timeout = this.timeout;\r\n    const isPreview = attachmentData?.isPreview ?? false;\r\n    const file = attachmentData?.file ?? null;\r\n\r\n    //console.log(attachmentData, 'attachmentData')\r\n\r\n    const worker = new Worker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u(\"assets_js_worker_js\"), __webpack_require__.b), {type: undefined}); // worker url\r\n    worker.postMessage({\r\n      action: 'compress',\r\n      format,\r\n      url,\r\n      name,\r\n      sourceType,\r\n      outputType,\r\n      mime,\r\n      sizes,\r\n      skipFull,\r\n      timeout,\r\n      isPreview,\r\n      file,\r\n      options: this.options,\r\n      //urlOriginal: urlOriginal,\r\n    });\r\n\r\n    return new Promise((resolve, reject) => {\r\n      const timeoutId = setTimeout(() => {\r\n        worker.terminate();\r\n        console.warn('Worker terminated');\r\n        reject(__('Request timed out.', 'squeeze'));\r\n      }, timeout);\r\n\r\n      worker.onmessage = (event) => {\r\n        clearTimeout(timeoutId);\r\n        if (event.data.error) {\r\n          reject(event.data.error);\r\n        } else {\r\n          resolve(event.data);\r\n        }\r\n        worker.terminate();\r\n      };\r\n\r\n      worker.onerror = (error) => {\r\n        clearTimeout(timeoutId);\r\n        reject(`Worker error: ${error.message}`);\r\n      };\r\n    });\r\n\r\n  }\r\n\r\n  handleUpload = async ({ attachment, base64, type = 'uncompressed', mediaIDs = [] }) => {\r\n\r\n    const attachmentData = attachment.attributes;\r\n    const url = attachmentData?.originalImageURL ?? attachmentData.url;\r\n    const mime = attachmentData.mime;\r\n    const filename = attachmentData?.originalImageName ?? attachmentData.filename;\r\n    const attachmentID = attachmentData.id;\r\n    const format = mime.split(\"/\")[1];\r\n    const sizes = attachmentData.sizes;\r\n\r\n    //console.log(attachmentData, 'attachmentData')\r\n\r\n    const data = {\r\n      action: 'squeeze_update_attachment',\r\n      _ajax_nonce: this.nonce,\r\n      filename: filename,\r\n      type: 'image',\r\n      format: format,\r\n      base64: base64.base64,\r\n      base64Sizes: base64.base64Sizes,\r\n      base64Webp: base64.base64Webp,\r\n      base64SizesWebp: base64.base64SizesWebp,\r\n      attachmentID: attachmentID,\r\n      url: url,\r\n      process: type,\r\n    }\r\n\r\n    console.log(data, 'squeeze_update_attachment') \r\n\r\n    try {\r\n      const uploadResponse = await jQuery.ajax({\r\n      url: this.ajaxUrl, // + '111',\r\n      type: 'POST',\r\n      data: data,\r\n      });\r\n\r\n      //if (type === 'uncompressed' || type === 'all' || type === 'path') {\r\n      //if (uploadResponse.success) {\r\n        uploadResponse['mediaIDs'] = mediaIDs;\r\n      //}\r\n\r\n      uploadResponse['filename'] = filename;\r\n      uploadResponse['url'] = url;\r\n      uploadResponse['sizes'] = sizes;\r\n\r\n      return uploadResponse;\r\n      \r\n    } catch (error) {\r\n      return {\r\n      'mediaIDs': mediaIDs,\r\n      'data': error.message,\r\n      'success': false\r\n      };\r\n    }\r\n\r\n  }\r\n\r\n  handleBulkUpload = async (type = 'uncompressed', mediaIDs = []) => {\r\n    let currentID;\r\n    let attachment;\r\n\r\n    switch (type) {\r\n      case 'all':\r\n      case 'uncompressed':\r\n        currentID = mediaIDs[0];\r\n        break;\r\n      case 'path':\r\n        currentID = mediaIDs[0]?.filename;\r\n        break;\r\n      default:\r\n        currentID = 0;\r\n        break;\r\n    }\r\n\r\n    if (type === 'path') {\r\n\r\n      \r\n\r\n      attachment = {\r\n        attributes: {\r\n          url: mediaIDs[0].url,\r\n          mime: mediaIDs[0].mime,\r\n          name: mediaIDs[0].name,\r\n          filename: mediaIDs[0].filename,\r\n          id: mediaIDs[0].id,\r\n          sizes: mediaIDs[0]?.sizes,\r\n        }\r\n      }\r\n\r\n    } else {\r\n\r\n      const attachmentResponse = await this.getAttachment(currentID); \r\n      if (attachmentResponse.success === false) {\r\n        if (Array.isArray(mediaIDs)) mediaIDs.shift();\r\n        return {\r\n          'mediaIDs': mediaIDs,\r\n          'data': attachmentResponse.data\r\n        }\r\n      }\r\n      const attachmentData = attachmentResponse.data;\r\n      attachment = {\r\n        attributes: {\r\n          url: attachmentData.url,\r\n          mime: attachmentData.mime,\r\n          name: attachmentData.name,\r\n          filename: attachmentData.filename,\r\n          id: attachmentData.id,\r\n          sizes: attachmentData.sizes,\r\n        }\r\n      }\r\n\r\n    }\r\n\r\n    if (Array.isArray(mediaIDs)) mediaIDs.shift();\r\n\r\n    const mediaType = attachment.attributes.mime.split(\"/\")[0];\r\n    const mediaSubType = attachment.attributes.mime.split(\"/\")[1];\r\n\r\n    if (!this.maybeCompressAttachment(mediaType, mediaSubType)) {\r\n      return {\r\n        'mediaIDs': mediaIDs,\r\n        'data': __('Skipped', 'squeeze')\r\n      }\r\n    }\r\n\r\n    try {\r\n      const compressData = await this.handleCompress( attachment );\r\n      const uploadData = await this.handleUpload({ attachment: attachment, base64: compressData, type: type, mediaIDs: mediaIDs })\r\n\r\n      return uploadData;\r\n\r\n    } catch (error) {\r\n      return {\r\n        'mediaIDs': mediaIDs,\r\n        'data': error.message,\r\n        'success': false\r\n      }\r\n    }\r\n\r\n  }\r\n\r\n  maybeCompressAttachment = (attachmentType, attachmentSubType) => {\r\n    const allowedMimeTypes = ['jpeg', 'png', 'webp', 'avif'];\r\n    const isImage = attachmentType === 'image' && allowedMimeTypes.includes(attachmentSubType)\r\n\r\n    if (isImage) {\r\n      return true;\r\n    }\r\n\r\n    return false;\r\n  }\r\n\r\n  \r\n\r\n  handleRestore = async (attachmentID) => {\r\n    const data = {\r\n      action: 'squeeze_restore_attachment',\r\n      _ajax_nonce: this.nonce,\r\n      attachmentID: attachmentID,\r\n    };\r\n\r\n    const response = await jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  };\r\n\r\n  // Get list of attachments by path\r\n  getAttachmentsByPath = async (path) => {\r\n\r\n    const data = {\r\n      action: 'squeeze_get_attachment_by_path',\r\n      path: path,\r\n      _ajax_nonce: this.nonce,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  getAttachment = async (attachmentID) => {\r\n    const data = {\r\n      action: 'squeeze_get_attachment',\r\n      _ajax_nonce: this.nonce,\r\n      attachmentID: attachmentID,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  getNextAttachments = async (page = 1, type = 'uncompressed', lastId = 0) => {\r\n    const data = {\r\n      action: 'squeeze_get_next_attachments',\r\n      _ajax_nonce: this.nonce,\r\n      page: page,\r\n      type: type,\r\n      lastId: lastId,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  getDirectories = async (parentDir = false) => {\r\n    const data = {\r\n      action: 'squeeze_get_directories',\r\n      _ajax_nonce: this.nonce,\r\n    }\r\n\r\n    if (parentDir) {\r\n      data['parentDir'] = parentDir;\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  \r\n\r\n  setOptions = async (options) => {\r\n    const data = {\r\n      action: 'squeeze_set_options',\r\n      _ajax_nonce: this.nonce,\r\n      options: options,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  /*\r\n  getSizesFromFile = (file) => {\r\n    if (!file) return;\r\n\r\n    // get list of thumbnails from file\r\n    const sizes = {};\r\n    \r\n    const fd = new FormData();\r\n    fd.append('action', 'squeeze_get_sizes_from_file');\r\n    fd.append('_ajax_nonce', this.nonce);\r\n    fd.append('file', file);\r\n\r\n    jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: fd,\r\n      processData: false,\r\n      contentType: false,\r\n      async: false, // synchronous request\r\n    }).done((response) => {\r\n      console.log(response, 'getSizesFromFile response');\r\n      if (response.success) {\r\n        Object.keys(response.data).forEach((size) => {\r\n          sizes[size] = response.data[size];\r\n        });\r\n      } else {\r\n        console.error('Error getting sizes from file:', response.data);\r\n      }\r\n    }).fail((error) => {\r\n      console.error('AJAX error:', error);\r\n    });\r\n\r\n    return sizes;\r\n\r\n  }\r\n  */\r\n\r\n}\n\n//# sourceURL=webpack:///./assets/js/squeeze.js?");
     49eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ SQUEEZE)\n/* harmony export */ });\n/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./helpers.js */ \"./assets/js/helpers.js\");\n/* harmony import */ var browser_image_compression__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! browser-image-compression */ \"./node_modules/browser-image-compression/dist/browser-image-compression.mjs\");\n/* harmony import */ var _jsquash_webp__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @jsquash/webp */ \"./node_modules/@jsquash/webp/encode.js\");\n\r\n\r\n\r\n\r\n\r\n\r\nconst { __ } = wp.i18n; // Import __() from wp.i18n\r\n\r\nclass SQUEEZE {\r\n\r\n  constructor(squeeze) {\r\n    this.options = JSON.parse(squeeze.options); // plugin options\r\n    this.nonce = squeeze.nonce; // nonce\r\n    this.ajaxUrl = squeeze.ajaxUrl; // ajax url\r\n    this.timeout = parseInt(this.options.timeout) * 1000; // convert to milliseconds\r\n    this.poolSize = navigator.hardwareConcurrency || 1; // number of threads\r\n  }\r\n\r\n  handleCompress = async ( attachment, type = 'uncompressed' ) => {\r\n    const attachmentData = attachment.attributes;\r\n    const url = attachmentData?.originalImageURL ?? attachmentData.url;\r\n    const mime = attachmentData.mime;\r\n    const name = attachmentData.name;\r\n    const filename = attachmentData?.originalImageName ?? attachmentData.filename;\r\n    const attachmentID = attachmentData.id;\r\n    const sizes = attachmentData.sizes;\r\n    const format = mime.split(\"/\")[1];\r\n    const sourceType = format;\r\n    const outputType = format;\r\n    const skipFull = attachmentData?.skipFull ?? attachmentData.originalImageName === undefined ? true : false;\r\n    const timeout = this.timeout;\r\n    const isPreview = attachmentData?.isPreview ?? false;\r\n    const file = attachmentData?.file ?? null; // the original file, it passed for the newly uploaded attachment to compress it\r\n\r\n    // the original compressed image base64, it passed when the attachment was already compressed and we need to compress thumbs only\r\n    // we pass it in order to prevent re-compressing the original image when we need to compress thumbs only\r\n    const base64Compressed = attachmentData?.base64Compressed ?? null; \r\n    const base64WebpCompressed = attachmentData?.base64WebpCompressed ?? null; // the original compressed webp image base64\r\n\r\n    const worker = new Worker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u(\"assets_js_worker_js\"), __webpack_require__.b), {type: undefined}); // worker url\r\n    const channel = new MessageChannel();\r\n    worker.postMessage({\r\n      action: 'compress',\r\n      format,\r\n      url,\r\n      name,\r\n      sourceType,\r\n      outputType,\r\n      mime,\r\n      sizes,\r\n      skipFull,\r\n      timeout,\r\n      isPreview,\r\n      file,\r\n      base64Compressed,\r\n      base64WebpCompressed,\r\n      type,\r\n      options: this.options,\r\n      //urlOriginal: urlOriginal,\r\n    }, [channel.port2]);\r\n\r\n    // Listen for compression requests from the worker via port1\r\n    channel.port1.onmessage = async (ev) => {\r\n      //console.log(\"Worker received compression request:\", ev.data);\r\n      const { id, action, fileOrArrayBuffer, mime, options } = ev.data;\r\n      if (action !== 'imageCompression') return;\r\n\r\n      try {\r\n        // Accept ArrayBuffer or Blob\r\n        const blob = (fileOrArrayBuffer instanceof ArrayBuffer)\r\n          ? new Blob([this.toUint8Array(fileOrArrayBuffer)], { type: mime })\r\n          : fileOrArrayBuffer;\r\n\r\n        const compressedBlob = await (0,browser_image_compression__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(blob, { useWebWorker: true, ...(options || {}) });\r\n\r\n        // quick checks\r\n        //console.log('compressedBlob.type, size:', compressedBlob.type, compressedBlob.size);\r\n        // normalize final binary\r\n        const compressedArrayBuffer = await compressedBlob.arrayBuffer();\r\n\r\n        // Reply with the compressed ArrayBuffer (transfer to avoid copy)\r\n        channel.port1.postMessage({ id, ok: true, arrayBuffer: compressedArrayBuffer }, [compressedArrayBuffer]);\r\n      } catch (err) {\r\n        channel.port1.postMessage({ id, ok: false, error: err.message || String(err) });\r\n      }\r\n    }\r\n\r\n    return new Promise((resolve, reject) => {\r\n      const timeoutId = setTimeout(() => {\r\n        worker.terminate();\r\n        console.warn('Worker compress terminated', name, sourceType, outputType);\r\n        reject(__('Request timed out.', 'squeeze'));\r\n      }, timeout);\r\n\r\n      worker.onmessage = (event) => {\r\n        clearTimeout(timeoutId);\r\n        if (event.data.error) {\r\n          reject(event.data.error);\r\n        } else {\r\n          resolve(event.data);\r\n        }\r\n        worker.terminate();\r\n      };\r\n\r\n      worker.onerror = (error) => {\r\n        clearTimeout(timeoutId);\r\n        reject(`Worker error: ${error.message}`);\r\n      };\r\n    });\r\n\r\n  }\r\n\r\n  handleUpload = async ({ attachment, base64, type = 'uncompressed', mediaIDs = [] }) => {\r\n\r\n    const attachmentData = attachment.attributes;\r\n    const url = attachmentData?.originalImageURL ?? attachmentData.url;\r\n    const mime = attachmentData.mime;\r\n    const filename = attachmentData?.originalImageName ?? attachmentData.filename;\r\n    const attachmentID = attachmentData.id;\r\n    const format = base64?.isDirectWebp && type !== 'path' ? 'webp' : mime.split(\"/\")[1];\r\n    const sizes = attachmentData.sizes;\r\n\r\n    const isDirectWebp = base64?.isDirectWebp && mime !== 'image/webp';\r\n    const isBackupOriginal = this.options?.backup_original ?? false; // check if backup original is enabled\r\n    let originalFile = attachmentData?.originalFile ?? null; // the original file, used for creating backup\r\n    \r\n    // if originalFile is not provided, try to get it from the URL\r\n    // used when the attachment needs to be converted to webp from jpg or png\r\n    if (!originalFile && type !== 'path' && isBackupOriginal && isDirectWebp) {\r\n      const file = await (0,_helpers_js__WEBPACK_IMPORTED_MODULE_0__.getFileFromUrl)(url, filename, mime.split(\"/\")[1])\r\n      //console.log('conveting original file to webp', file);\r\n      originalFile = await this.convertFileToWebp(file);\r\n    }\r\n    //console.log('handleUpload attachmentData', attachmentData)\r\n\r\n    const data = {\r\n      action: 'squeeze_update_attachment',\r\n      _ajax_nonce: this.nonce,\r\n      filename: filename,\r\n      type: 'image',\r\n      format: format,\r\n      base64: base64.base64,\r\n      base64Sizes: base64.base64Sizes,\r\n      base64Webp: base64.base64Webp,\r\n      base64SizesWebp: base64.base64SizesWebp,\r\n      attachmentID: attachmentID,\r\n      url: url,\r\n      process: type,\r\n      originalFile: originalFile,\r\n    }\r\n\r\n    const formData = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_0__.objectToFormData)(data);\r\n\r\n    //console.log('squeeze_update_attachment', JSON.stringify(data, null, 2));\r\n\r\n    try {\r\n      const uploadResponse = await jQuery.ajax({\r\n      url: this.ajaxUrl, // + '111',\r\n      type: 'POST',\r\n      data: formData,\r\n      processData: false,  // very important!\r\n      contentType: false,  // very important!\r\n      });\r\n\r\n      //if (uploadResponse.success) {\r\n        uploadResponse['mediaIDs'] = mediaIDs;\r\n      //}\r\n\r\n      if (!uploadResponse?.data?.url) {\r\n        uploadResponse.url = url; // fallback to original URL if not provided\r\n      }\r\n\r\n      //console.log('uploadResponse', JSON.stringify(uploadResponse, null, 2));\r\n\r\n      return uploadResponse;\r\n      \r\n    } catch (error) {\r\n      return {\r\n      'mediaIDs': mediaIDs,\r\n      'data': error.message,\r\n      'success': false\r\n      };\r\n    }\r\n\r\n  }\r\n\r\n  handleBulkUpload = async (type = 'uncompressed', mediaIDs = []) => {\r\n    let currentID;\r\n    let attachment;\r\n\r\n    switch (type) {\r\n      case 'all':\r\n      case 'uncompressed':\r\n        currentID = mediaIDs[0];\r\n        break;\r\n      case 'path':\r\n        currentID = mediaIDs[0]?.filename;\r\n        break;\r\n      default:\r\n        currentID = 0;\r\n        break;\r\n    }\r\n\r\n    if (type === 'path') {\r\n\r\n      \r\n\r\n      attachment = {\r\n        attributes: {\r\n          url: mediaIDs[0].url,\r\n          mime: mediaIDs[0].mime,\r\n          name: mediaIDs[0].name,\r\n          filename: mediaIDs[0].filename,\r\n          id: mediaIDs[0].id,\r\n          sizes: mediaIDs[0]?.sizes,\r\n        }\r\n      }\r\n\r\n    } else {\r\n\r\n      const attachmentResponse = await this.getAttachment(currentID); \r\n      if (attachmentResponse.success === false) {\r\n        if (Array.isArray(mediaIDs)) mediaIDs.shift();\r\n        return {\r\n          'mediaIDs': mediaIDs,\r\n          'data': attachmentResponse.data\r\n        }\r\n      }\r\n      const attachmentData = attachmentResponse.data;\r\n      attachment = {\r\n        attributes: {\r\n          url: attachmentData.url,\r\n          mime: attachmentData.mime,\r\n          name: attachmentData.name,\r\n          filename: attachmentData.filename,\r\n          id: attachmentData.id,\r\n          sizes: attachmentData.sizes,\r\n        }\r\n      }\r\n\r\n    }\r\n\r\n    if (Array.isArray(mediaIDs)) mediaIDs.shift();\r\n\r\n    const mediaType = attachment.attributes.mime.split(\"/\")[0];\r\n    const mediaSubType = attachment.attributes.mime.split(\"/\")[1];\r\n\r\n    if (!(0,_helpers_js__WEBPACK_IMPORTED_MODULE_0__.maybeCompressAttachment)(mediaType, mediaSubType)) {\r\n      return {\r\n        'mediaIDs': mediaIDs,\r\n        'data': __('Skipped', 'squeeze')\r\n      }\r\n    }\r\n\r\n    try {\r\n      const compressData = await this.handleCompress( attachment, type );\r\n      const uploadData = await this.handleUpload({ attachment: attachment, base64: compressData, type: type, mediaIDs: mediaIDs })\r\n\r\n      return uploadData;\r\n\r\n    } catch (error) {\r\n      return {\r\n        'mediaIDs': mediaIDs,\r\n        'data': error?.message ?? error,\r\n        'success': false\r\n      }\r\n    }\r\n\r\n  }\r\n\r\n  \r\n\r\n  handleRestore = async (attachmentID) => {\r\n    const data = {\r\n      action: 'squeeze_restore_attachment',\r\n      _ajax_nonce: this.nonce,\r\n      attachmentID: attachmentID,\r\n    };\r\n\r\n    const response = await jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  };\r\n\r\n  // Get list of attachments by path\r\n  getAttachmentsByPath = async (path) => {\r\n\r\n    const data = {\r\n      action: 'squeeze_get_attachment_by_path',\r\n      path: path,\r\n      _ajax_nonce: this.nonce,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  getAttachment = async (attachmentID) => {\r\n    const data = {\r\n      action: 'squeeze_get_attachment',\r\n      _ajax_nonce: this.nonce,\r\n      attachmentID: attachmentID,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  getNextAttachments = async (page = 1, type = 'uncompressed', lastId = 0) => {\r\n    const data = {\r\n      action: 'squeeze_get_next_attachments',\r\n      _ajax_nonce: this.nonce,\r\n      page: page,\r\n      type: type,\r\n      lastId: lastId,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  getDirectories = async (parentDir = false) => {\r\n    const data = {\r\n      action: 'squeeze_get_directories',\r\n      _ajax_nonce: this.nonce,\r\n    }\r\n\r\n    if (parentDir) {\r\n      data['parentDir'] = parentDir;\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  \r\n\r\n  setOptions = async (options) => {\r\n    const data = {\r\n      action: 'squeeze_set_options',\r\n      _ajax_nonce: this.nonce,\r\n      options: options,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  /**\r\n   * Compresses an image before upload.\r\n   * If the compressSizes parameter is provided, it will compress the sizes specified along with the original image.\r\n   * \r\n   * @param {File} file - The file to be compressed\r\n   * @param {object} compressSizes - Optional sizes for compression\r\n   * @returns {Promise<object|boolean>} - Returns a Promise that resolves to the compressed file as a base64 object or false if the file is invalid\r\n   */\r\n  compressBeforeUpload = async (file, compressSizes = null) => {\r\n    if (!(file instanceof Blob) && !(file instanceof File)) {\r\n      console.error('Invalid file type:', file);\r\n      return false; // Return false if the file is not a Blob or File\r\n    }\r\n\r\n    const attachment = {\r\n      attributes: {\r\n        url: null,\r\n        mime: file.type,\r\n        name: file.name,\r\n        filename: file.name,\r\n        id: 0,\r\n        sizes: compressSizes,\r\n        file: file,\r\n        skipFull: false,\r\n      }\r\n    }\r\n\r\n    try {\r\n      const base64Obj = await this.handleCompress(attachment);\r\n\r\n      return base64Obj; // Return the compressed file as base64Obj\r\n    } catch (error) {\r\n      console.error(error);\r\n      return error; // Return the error for further handling\r\n    }\r\n  }\r\n\r\n  isWebpEncodingSupported = async () => {\r\n    try {\r\n      const canvas = document.createElement('canvas');\r\n      if (!canvas.toDataURL) return false;\r\n      const data = canvas.toDataURL('image/webp');\r\n      // WebP signature starts with \"data:image/webp\"\r\n      return data.indexOf('data:image/webp') === 0;\r\n    } catch (e) {\r\n      return false;\r\n    }\r\n  }\r\n\r\n  handleConvertFileToWebp = async (args) => {\r\n    const timeout = this.timeout;\r\n    \r\n    const { file, sourceType, name } = args;\r\n    const fileBuffer = await file.arrayBuffer();\r\n    const mime = sourceType === 'png' ? 'image/png' : 'image/jpeg';\r\n    const inputBlob = new Blob([fileBuffer], { type: mime });\r\n    // compression options you can tune\r\n    const imageCompressionOptions = {\r\n      useWebWorker: true,\r\n      fileType: 'image/webp',\r\n    };\r\n\r\n    return new Promise(async (resolve, reject) => {\r\n      const timeoutId = setTimeout(() => {\r\n      console.warn('Worker convertToWebp terminated', name);\r\n      reject(new Error(__('Request timed out.', 'squeeze')));\r\n      }, timeout);\r\n\r\n      try {\r\n\r\n        const compressedBlob = await (0,browser_image_compression__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(inputBlob, imageCompressionOptions);\r\n\r\n        // quick checks\r\n        //console.log('compressedBlob.type, size:', compressedBlob.type, compressedBlob.size);\r\n        // normalize final binary\r\n        const webpArrayBuffer = await compressedBlob.arrayBuffer();\r\n\r\n        const webpName = name.replace(/\\.\\w+$/, '.webp');\r\n        const webpFile = new File([webpArrayBuffer], webpName, { type: 'image/webp', lastModified: Date.now() });\r\n\r\n        clearTimeout(timeoutId);\r\n        resolve({ webpFile }); // must return object with webpFile prop\r\n      } catch (error) {\r\n        clearTimeout(timeoutId);\r\n        console.error('Error during image processing:', error);\r\n        reject(error);\r\n      }\r\n    });\r\n    \r\n  }\r\n\r\n  // helper: normalize buffer-like inputs to Uint8Array\r\n  toUint8Array = (bufferLike) => {\r\n    if (bufferLike instanceof Uint8Array) return bufferLike;\r\n    if (bufferLike instanceof ArrayBuffer) return new Uint8Array(bufferLike);\r\n    if (ArrayBuffer.isView(bufferLike)) return new Uint8Array(bufferLike.buffer, bufferLike.byteOffset, bufferLike.byteLength);\r\n    // Node Buffer (in some environments) has .buffer and .byteOffset\r\n    if (bufferLike && typeof bufferLike === 'object' && bufferLike.buffer) {\r\n      return new Uint8Array(bufferLike.buffer, bufferLike.byteOffset || 0, bufferLike.byteLength || bufferLike.length);\r\n    }\r\n    throw new Error('Unsupported buffer type: ' + Object.prototype.toString.call(bufferLike));\r\n  }\r\n\r\n  /**\r\n   * Convert an image File to WebP.\r\n   *\r\n   * @param {File} inputFile  — the original image File (e.g. JPEG, PNG).\r\n   * @returns {Promise<File>} — a Promise that resolves to a WebP File.\r\n   */\r\n  convertFileToWebp = async (inputFile) => {\r\n    // Ensure it’s an image\r\n    if (!inputFile.type.startsWith('image/')) {\r\n      throw new Error('Input must be an image File');\r\n    }\r\n    const args = {\r\n      file: inputFile,\r\n      sourceType: inputFile.type.split('/')[1], // e.g. 'jpeg', 'png'\r\n      name: inputFile.name,\r\n    }\r\n    const webpSupported = await this.isWebpEncodingSupported();\r\n    try {\r\n      // Convert the image to WebP\r\n      let webpData;\r\n      if (webpSupported) {\r\n        webpData = await this.handleConvertFileToWebp(args);\r\n      } else {\r\n        console.warn('WebP encoding not supported on this device. Using original format instead.');\r\n        const webpName = args.name.replace(/\\.\\w+$/, '.webp');\r\n        webpData = await this.convertToWebpWithJsquash(inputFile, webpName);\r\n      }\r\n      if (!webpData || !webpData.webpFile) {\r\n        throw new Error('Failed to convert image to WebP');\r\n      }\r\n\r\n      return webpData.webpFile; // Return the WebP File\r\n\r\n    } catch (error) {\r\n      console.error('Error converting image to WebP:', error);\r\n      throw error; // Re-throw the error for further handling\r\n    }\r\n\r\n  }\r\n\r\n  /**\r\n * Convert an input (File | Blob | ArrayBuffer | Uint8Array) to a WebP File using @jsquash/webp.\r\n * @param {File|Blob|ArrayBuffer|Uint8Array} input\r\n * @param {string} outputName - desired filename for the .webp output\r\n * @param {{quality?: number, lossless?: boolean, method?: number}} [opts] - encoder options (quality 0-100)\r\n * @returns {Promise<File>} - WebP File\r\n */\r\n  convertToWebpWithJsquash = async (input, outputName = 'out.webp', opts = { quality: 100 }) => {\r\n    // Normalize input to Blob\r\n    let blob;\r\n    if (input instanceof Blob) {\r\n      blob = input;\r\n    } else if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) {\r\n      blob = new Blob([input]);\r\n    } else {\r\n      throw new Error('Unsupported input type. Provide File, Blob, ArrayBuffer or TypedArray.');\r\n    }\r\n\r\n    // Load image into <img>\r\n    const dataURL = await new Promise((resolve, reject) => {\r\n      const fr = new FileReader();\r\n      fr.onload = () => resolve(fr.result);\r\n      fr.onerror = reject;\r\n      fr.readAsDataURL(blob);\r\n    });\r\n\r\n    const img = await new Promise((resolve, reject) => {\r\n      const i = new Image();\r\n      i.onload = () => resolve(i);\r\n      i.onerror = () => reject(new Error('Failed to load image for conversion'));\r\n      i.src = dataURL;\r\n      // avoid cross-origin taint if data-url is used\r\n    });\r\n\r\n    // Draw to canvas and extract ImageData\r\n    const canvas = document.createElement('canvas');\r\n    canvas.width = img.naturalWidth || img.width;\r\n    canvas.height = img.naturalHeight || img.height;\r\n    const ctx = canvas.getContext('2d');\r\n    ctx.drawImage(img, 0, 0);\r\n    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\r\n\r\n    // encode -> returns ArrayBuffer (WASM libwebp)\r\n    // opts example: { quality: 75, lossless: false, method: 4 }\r\n    const webpArrayBuffer = await (0,_jsquash_webp__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(imageData, opts);\r\n\r\n    // Validate a little (size)\r\n    if (!webpArrayBuffer || webpArrayBuffer.byteLength < 20) {\r\n      throw new Error('jsquash produced an invalid WebP buffer');\r\n    }\r\n\r\n    // Wrap into File\r\n    const webpFile = new File([webpArrayBuffer], outputName.replace(/\\.\\w+$/, '.webp'), {\r\n      type: 'image/webp',\r\n      lastModified: Date.now(),\r\n    });\r\n\r\n    return {webpFile};\r\n  }\r\n\r\n}\n\n//# sourceURL=webpack:///./assets/js/squeeze.js?");
     50
     51/***/ }),
     52
     53/***/ "./node_modules/@jsquash/webp/encode.js":
     54/*!**********************************************!*\
     55  !*** ./node_modules/@jsquash/webp/encode.js ***!
     56  \**********************************************/
     57/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
     58
     59eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ encode),\n/* harmony export */   \"init\": () => (/* binding */ init)\n/* harmony export */ });\n/* harmony import */ var _meta_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./meta.js */ \"./node_modules/@jsquash/webp/meta.js\");\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils.js */ \"./node_modules/@jsquash/webp/utils.js\");\n/* harmony import */ var wasm_feature_detect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! wasm-feature-detect */ \"./node_modules/wasm-feature-detect/dist/esm/index.js\");\n/**\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *     http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n\nlet emscriptenModule;\nasync function init(module, moduleOptionOverrides) {\n    if (await (0,wasm_feature_detect__WEBPACK_IMPORTED_MODULE_0__.simd)()) {\n        const webpEncoder = await __webpack_require__.e(/*! import() */ \"vendors-node_modules_jsquash_webp_codec_enc_webp_enc_simd_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./codec/enc/webp_enc_simd.js */ \"./node_modules/@jsquash/webp/codec/enc/webp_enc_simd.js\"));\n        emscriptenModule = (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.initEmscriptenModule)(webpEncoder.default, module, moduleOptionOverrides);\n        return emscriptenModule;\n    }\n    const webpEncoder = await __webpack_require__.e(/*! import() */ \"vendors-node_modules_jsquash_webp_codec_enc_webp_enc_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./codec/enc/webp_enc.js */ \"./node_modules/@jsquash/webp/codec/enc/webp_enc.js\"));\n    emscriptenModule = (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.initEmscriptenModule)(webpEncoder.default, module, moduleOptionOverrides);\n    return emscriptenModule;\n}\nasync function encode(data, options = {}) {\n    if (!emscriptenModule)\n        emscriptenModule = init();\n    const _options = { ..._meta_js__WEBPACK_IMPORTED_MODULE_2__.defaultOptions, ...options };\n    const module = await emscriptenModule;\n    const result = module.encode(data.data, data.width, data.height, _options);\n    if (!result)\n        throw new Error('Encoding error.');\n    return result.buffer;\n}\n\n\n//# sourceURL=webpack:///./node_modules/@jsquash/webp/encode.js?");
     60
     61/***/ }),
     62
     63/***/ "./node_modules/@jsquash/webp/meta.js":
     64/*!********************************************!*\
     65  !*** ./node_modules/@jsquash/webp/meta.js ***!
     66  \********************************************/
     67/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
     68
     69eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"defaultOptions\": () => (/* binding */ defaultOptions),\n/* harmony export */   \"extension\": () => (/* binding */ extension),\n/* harmony export */   \"label\": () => (/* binding */ label),\n/* harmony export */   \"mimeType\": () => (/* binding */ mimeType)\n/* harmony export */ });\nconst label = 'WebP';\nconst mimeType = 'image/webp';\nconst extension = 'webp';\n// These come from struct WebPConfig in encode.h.\nconst defaultOptions = {\n    quality: 75,\n    target_size: 0,\n    target_PSNR: 0,\n    method: 4,\n    sns_strength: 50,\n    filter_strength: 60,\n    filter_sharpness: 0,\n    filter_type: 1,\n    partitions: 0,\n    segments: 4,\n    pass: 1,\n    show_compressed: 0,\n    preprocessing: 0,\n    autofilter: 0,\n    partition_limit: 0,\n    alpha_compression: 1,\n    alpha_filtering: 1,\n    alpha_quality: 100,\n    lossless: 0,\n    exact: 0,\n    image_hint: 0,\n    emulate_jpeg_size: 0,\n    thread_level: 0,\n    low_memory: 0,\n    near_lossless: 100,\n    use_delta_palette: 0,\n    use_sharp_yuv: 0,\n};\n\n\n//# sourceURL=webpack:///./node_modules/@jsquash/webp/meta.js?");
     70
     71/***/ }),
     72
     73/***/ "./node_modules/@jsquash/webp/utils.js":
     74/*!*********************************************!*\
     75  !*** ./node_modules/@jsquash/webp/utils.js ***!
     76  \*********************************************/
     77/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
     78
     79eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"initEmscriptenModule\": () => (/* binding */ initEmscriptenModule)\n/* harmony export */ });\n/**\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *     http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Notice: I (Jamie Sinclair) have modified this file to allow manual instantiation of the Wasm Module.\n */\nfunction initEmscriptenModule(moduleFactory, wasmModule, moduleOptionOverrides = {}) {\n    let instantiateWasm;\n    if (wasmModule) {\n        instantiateWasm = (imports, callback) => {\n            const instance = new WebAssembly.Instance(wasmModule, imports);\n            callback(instance);\n            return instance.exports;\n        };\n    }\n    return moduleFactory({\n        // Just to be safe, don't automatically invoke any wasm functions\n        noInitialRun: true,\n        instantiateWasm,\n        ...moduleOptionOverrides,\n    });\n}\n\n\n//# sourceURL=webpack:///./node_modules/@jsquash/webp/utils.js?");
     80
     81/***/ }),
     82
     83/***/ "./node_modules/browser-image-compression/dist/browser-image-compression.mjs":
     84/*!***********************************************************************************!*\
     85  !*** ./node_modules/browser-image-compression/dist/browser-image-compression.mjs ***!
     86  \***********************************************************************************/
     87/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
     88
     89eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ imageCompression)\n/* harmony export */ });\n/**\n * Browser Image Compression\n * v2.0.2\n * by Donald <[email protected]>\n * https://github.com/Donaldcwl/browser-image-compression\n */\n\nfunction _mergeNamespaces(e,t){return t.forEach((function(t){t&&\"string\"!=typeof t&&!Array.isArray(t)&&Object.keys(t).forEach((function(r){if(\"default\"!==r&&!(r in e)){var i=Object.getOwnPropertyDescriptor(t,r);Object.defineProperty(e,r,i.get?i:{enumerable:!0,get:function(){return t[r]}})}}))})),Object.freeze(e)}function copyExifWithoutOrientation(e,t){return new Promise((function(r,i){let o;return getApp1Segment(e).then((function(e){try{return o=e,r(new Blob([t.slice(0,2),o,t.slice(2)],{type:\"image/jpeg\"}))}catch(e){return i(e)}}),i)}))}const getApp1Segment=e=>new Promise(((t,r)=>{const i=new FileReader;i.addEventListener(\"load\",(({target:{result:e}})=>{const i=new DataView(e);let o=0;if(65496!==i.getUint16(o))return r(\"not a valid JPEG\");for(o+=2;;){const a=i.getUint16(o);if(65498===a)break;const s=i.getUint16(o+2);if(65505===a&&1165519206===i.getUint32(o+4)){const a=o+10;let f;switch(i.getUint16(a)){case 18761:f=!0;break;case 19789:f=!1;break;default:return r(\"TIFF header contains invalid endian\")}if(42!==i.getUint16(a+2,f))return r(\"TIFF header contains invalid version\");const l=i.getUint32(a+4,f),c=a+l+2+12*i.getUint16(a+l,f);for(let e=a+l+2;e<c;e+=12){if(274==i.getUint16(e,f)){if(3!==i.getUint16(e+2,f))return r(\"Orientation data type is invalid\");if(1!==i.getUint32(e+4,f))return r(\"Orientation data count is invalid\");i.setUint16(e+8,1,f);break}}return t(e.slice(o,o+2+s))}o+=2+s}return t(new Blob)})),i.readAsArrayBuffer(e)}));var e={},t={get exports(){return e},set exports(t){e=t}};!function(e){var r,i,UZIP={};t.exports=UZIP,UZIP.parse=function(e,t){for(var r=UZIP.bin.readUshort,i=UZIP.bin.readUint,o=0,a={},s=new Uint8Array(e),f=s.length-4;101010256!=i(s,f);)f--;o=f;o+=4;var l=r(s,o+=4);r(s,o+=2);var c=i(s,o+=2),u=i(s,o+=4);o+=4,o=u;for(var h=0;h<l;h++){i(s,o),o+=4,o+=4,o+=4,i(s,o+=4);c=i(s,o+=4);var d=i(s,o+=4),A=r(s,o+=4),g=r(s,o+2),p=r(s,o+4);o+=6;var m=i(s,o+=8);o+=4,o+=A+g+p,UZIP._readLocal(s,m,a,c,d,t)}return a},UZIP._readLocal=function(e,t,r,i,o,a){var s=UZIP.bin.readUshort,f=UZIP.bin.readUint;f(e,t),s(e,t+=4),s(e,t+=2);var l=s(e,t+=2);f(e,t+=2),f(e,t+=4),t+=4;var c=s(e,t+=8),u=s(e,t+=2);t+=2;var h=UZIP.bin.readUTF8(e,t,c);if(t+=c,t+=u,a)r[h]={size:o,csize:i};else{var d=new Uint8Array(e.buffer,t);if(0==l)r[h]=new Uint8Array(d.buffer.slice(t,t+i));else{if(8!=l)throw\"unknown compression method: \"+l;var A=new Uint8Array(o);UZIP.inflateRaw(d,A),r[h]=A}}},UZIP.inflateRaw=function(e,t){return UZIP.F.inflate(e,t)},UZIP.inflate=function(e,t){return e[0],e[1],UZIP.inflateRaw(new Uint8Array(e.buffer,e.byteOffset+2,e.length-6),t)},UZIP.deflate=function(e,t){null==t&&(t={level:6});var r=0,i=new Uint8Array(50+Math.floor(1.1*e.length));i[r]=120,i[r+1]=156,r+=2,r=UZIP.F.deflateRaw(e,i,r,t.level);var o=UZIP.adler(e,0,e.length);return i[r+0]=o>>>24&255,i[r+1]=o>>>16&255,i[r+2]=o>>>8&255,i[r+3]=o>>>0&255,new Uint8Array(i.buffer,0,r+4)},UZIP.deflateRaw=function(e,t){null==t&&(t={level:6});var r=new Uint8Array(50+Math.floor(1.1*e.length)),i=UZIP.F.deflateRaw(e,r,i,t.level);return new Uint8Array(r.buffer,0,i)},UZIP.encode=function(e,t){null==t&&(t=!1);var r=0,i=UZIP.bin.writeUint,o=UZIP.bin.writeUshort,a={};for(var s in e){var f=!UZIP._noNeed(s)&&!t,l=e[s],c=UZIP.crc.crc(l,0,l.length);a[s]={cpr:f,usize:l.length,crc:c,file:f?UZIP.deflateRaw(l):l}}for(var s in a)r+=a[s].file.length+30+46+2*UZIP.bin.sizeUTF8(s);r+=22;var u=new Uint8Array(r),h=0,d=[];for(var s in a){var A=a[s];d.push(h),h=UZIP._writeHeader(u,h,s,A,0)}var g=0,p=h;for(var s in a){A=a[s];d.push(h),h=UZIP._writeHeader(u,h,s,A,1,d[g++])}var m=h-p;return i(u,h,101010256),h+=4,o(u,h+=4,g),o(u,h+=2,g),i(u,h+=2,m),i(u,h+=4,p),h+=4,h+=2,u.buffer},UZIP._noNeed=function(e){var t=e.split(\".\").pop().toLowerCase();return-1!=\"png,jpg,jpeg,zip\".indexOf(t)},UZIP._writeHeader=function(e,t,r,i,o,a){var s=UZIP.bin.writeUint,f=UZIP.bin.writeUshort,l=i.file;return s(e,t,0==o?67324752:33639248),t+=4,1==o&&(t+=2),f(e,t,20),f(e,t+=2,0),f(e,t+=2,i.cpr?8:0),s(e,t+=2,0),s(e,t+=4,i.crc),s(e,t+=4,l.length),s(e,t+=4,i.usize),f(e,t+=4,UZIP.bin.sizeUTF8(r)),f(e,t+=2,0),t+=2,1==o&&(t+=2,t+=2,s(e,t+=6,a),t+=4),t+=UZIP.bin.writeUTF8(e,t,r),0==o&&(e.set(l,t),t+=l.length),t},UZIP.crc={table:function(){for(var e=new Uint32Array(256),t=0;t<256;t++){for(var r=t,i=0;i<8;i++)1&r?r=3988292384^r>>>1:r>>>=1;e[t]=r}return e}(),update:function(e,t,r,i){for(var o=0;o<i;o++)e=UZIP.crc.table[255&(e^t[r+o])]^e>>>8;return e},crc:function(e,t,r){return 4294967295^UZIP.crc.update(4294967295,e,t,r)}},UZIP.adler=function(e,t,r){for(var i=1,o=0,a=t,s=t+r;a<s;){for(var f=Math.min(a+5552,s);a<f;)o+=i+=e[a++];i%=65521,o%=65521}return o<<16|i},UZIP.bin={readUshort:function(e,t){return e[t]|e[t+1]<<8},writeUshort:function(e,t,r){e[t]=255&r,e[t+1]=r>>8&255},readUint:function(e,t){return 16777216*e[t+3]+(e[t+2]<<16|e[t+1]<<8|e[t])},writeUint:function(e,t,r){e[t]=255&r,e[t+1]=r>>8&255,e[t+2]=r>>16&255,e[t+3]=r>>24&255},readASCII:function(e,t,r){for(var i=\"\",o=0;o<r;o++)i+=String.fromCharCode(e[t+o]);return i},writeASCII:function(e,t,r){for(var i=0;i<r.length;i++)e[t+i]=r.charCodeAt(i)},pad:function(e){return e.length<2?\"0\"+e:e},readUTF8:function(e,t,r){for(var i,o=\"\",a=0;a<r;a++)o+=\"%\"+UZIP.bin.pad(e[t+a].toString(16));try{i=decodeURIComponent(o)}catch(i){return UZIP.bin.readASCII(e,t,r)}return i},writeUTF8:function(e,t,r){for(var i=r.length,o=0,a=0;a<i;a++){var s=r.charCodeAt(a);if(0==(4294967168&s))e[t+o]=s,o++;else if(0==(4294965248&s))e[t+o]=192|s>>6,e[t+o+1]=128|s>>0&63,o+=2;else if(0==(4294901760&s))e[t+o]=224|s>>12,e[t+o+1]=128|s>>6&63,e[t+o+2]=128|s>>0&63,o+=3;else{if(0!=(4292870144&s))throw\"e\";e[t+o]=240|s>>18,e[t+o+1]=128|s>>12&63,e[t+o+2]=128|s>>6&63,e[t+o+3]=128|s>>0&63,o+=4}}return o},sizeUTF8:function(e){for(var t=e.length,r=0,i=0;i<t;i++){var o=e.charCodeAt(i);if(0==(4294967168&o))r++;else if(0==(4294965248&o))r+=2;else if(0==(4294901760&o))r+=3;else{if(0!=(4292870144&o))throw\"e\";r+=4}}return r}},UZIP.F={},UZIP.F.deflateRaw=function(e,t,r,i){var o=[[0,0,0,0,0],[4,4,8,4,0],[4,5,16,8,0],[4,6,16,16,0],[4,10,16,32,0],[8,16,32,32,0],[8,16,128,128,0],[8,32,128,256,0],[32,128,258,1024,1],[32,258,258,4096,1]][i],a=UZIP.F.U,s=UZIP.F._goodIndex;UZIP.F._hash;var f=UZIP.F._putsE,l=0,c=r<<3,u=0,h=e.length;if(0==i){for(;l<h;){f(t,c,l+(_=Math.min(65535,h-l))==h?1:0),c=UZIP.F._copyExact(e,l,_,t,c+8),l+=_}return c>>>3}var d=a.lits,A=a.strt,g=a.prev,p=0,m=0,w=0,v=0,b=0,y=0;for(h>2&&(A[y=UZIP.F._hash(e,0)]=0),l=0;l<h;l++){if(b=y,l+1<h-2){y=UZIP.F._hash(e,l+1);var E=l+1&32767;g[E]=A[y],A[y]=E}if(u<=l){(p>14e3||m>26697)&&h-l>100&&(u<l&&(d[p]=l-u,p+=2,u=l),c=UZIP.F._writeBlock(l==h-1||u==h?1:0,d,p,v,e,w,l-w,t,c),p=m=v=0,w=l);var F=0;l<h-2&&(F=UZIP.F._bestMatch(e,l,g,b,Math.min(o[2],h-l),o[3]));var _=F>>>16,B=65535&F;if(0!=F){B=65535&F;var U=s(_=F>>>16,a.of0);a.lhst[257+U]++;var C=s(B,a.df0);a.dhst[C]++,v+=a.exb[U]+a.dxb[C],d[p]=_<<23|l-u,d[p+1]=B<<16|U<<8|C,p+=2,u=l+_}else a.lhst[e[l]]++;m++}}for(w==l&&0!=e.length||(u<l&&(d[p]=l-u,p+=2,u=l),c=UZIP.F._writeBlock(1,d,p,v,e,w,l-w,t,c),p=0,m=0,p=m=v=0,w=l);0!=(7&c);)c++;return c>>>3},UZIP.F._bestMatch=function(e,t,r,i,o,a){var s=32767&t,f=r[s],l=s-f+32768&32767;if(f==s||i!=UZIP.F._hash(e,t-l))return 0;for(var c=0,u=0,h=Math.min(32767,t);l<=h&&0!=--a&&f!=s;){if(0==c||e[t+c]==e[t+c-l]){var d=UZIP.F._howLong(e,t,l);if(d>c){if(u=l,(c=d)>=o)break;l+2<d&&(d=l+2);for(var A=0,g=0;g<d-2;g++){var p=t-l+g+32768&32767,m=p-r[p]+32768&32767;m>A&&(A=m,f=p)}}}l+=(s=f)-(f=r[s])+32768&32767}return c<<16|u},UZIP.F._howLong=function(e,t,r){if(e[t]!=e[t-r]||e[t+1]!=e[t+1-r]||e[t+2]!=e[t+2-r])return 0;var i=t,o=Math.min(e.length,t+258);for(t+=3;t<o&&e[t]==e[t-r];)t++;return t-i},UZIP.F._hash=function(e,t){return(e[t]<<8|e[t+1])+(e[t+2]<<4)&65535},UZIP.saved=0,UZIP.F._writeBlock=function(e,t,r,i,o,a,s,f,l){var c,u,h,d,A,g,p,m,w,v=UZIP.F.U,b=UZIP.F._putsF,y=UZIP.F._putsE;v.lhst[256]++,u=(c=UZIP.F.getTrees())[0],h=c[1],d=c[2],A=c[3],g=c[4],p=c[5],m=c[6],w=c[7];var E=32+(0==(l+3&7)?0:8-(l+3&7))+(s<<3),F=i+UZIP.F.contSize(v.fltree,v.lhst)+UZIP.F.contSize(v.fdtree,v.dhst),_=i+UZIP.F.contSize(v.ltree,v.lhst)+UZIP.F.contSize(v.dtree,v.dhst);_+=14+3*p+UZIP.F.contSize(v.itree,v.ihst)+(2*v.ihst[16]+3*v.ihst[17]+7*v.ihst[18]);for(var B=0;B<286;B++)v.lhst[B]=0;for(B=0;B<30;B++)v.dhst[B]=0;for(B=0;B<19;B++)v.ihst[B]=0;var U=E<F&&E<_?0:F<_?1:2;if(b(f,l,e),b(f,l+1,U),l+=3,0==U){for(;0!=(7&l);)l++;l=UZIP.F._copyExact(o,a,s,f,l)}else{var C,I;if(1==U&&(C=v.fltree,I=v.fdtree),2==U){UZIP.F.makeCodes(v.ltree,u),UZIP.F.revCodes(v.ltree,u),UZIP.F.makeCodes(v.dtree,h),UZIP.F.revCodes(v.dtree,h),UZIP.F.makeCodes(v.itree,d),UZIP.F.revCodes(v.itree,d),C=v.ltree,I=v.dtree,y(f,l,A-257),y(f,l+=5,g-1),y(f,l+=5,p-4),l+=4;for(var Q=0;Q<p;Q++)y(f,l+3*Q,v.itree[1+(v.ordr[Q]<<1)]);l+=3*p,l=UZIP.F._codeTiny(m,v.itree,f,l),l=UZIP.F._codeTiny(w,v.itree,f,l)}for(var M=a,x=0;x<r;x+=2){for(var S=t[x],R=S>>>23,T=M+(8388607&S);M<T;)l=UZIP.F._writeLit(o[M++],C,f,l);if(0!=R){var O=t[x+1],P=O>>16,H=O>>8&255,L=255&O;y(f,l=UZIP.F._writeLit(257+H,C,f,l),R-v.of0[H]),l+=v.exb[H],b(f,l=UZIP.F._writeLit(L,I,f,l),P-v.df0[L]),l+=v.dxb[L],M+=R}}l=UZIP.F._writeLit(256,C,f,l)}return l},UZIP.F._copyExact=function(e,t,r,i,o){var a=o>>>3;return i[a]=r,i[a+1]=r>>>8,i[a+2]=255-i[a],i[a+3]=255-i[a+1],a+=4,i.set(new Uint8Array(e.buffer,t,r),a),o+(r+4<<3)},UZIP.F.getTrees=function(){for(var e=UZIP.F.U,t=UZIP.F._hufTree(e.lhst,e.ltree,15),r=UZIP.F._hufTree(e.dhst,e.dtree,15),i=[],o=UZIP.F._lenCodes(e.ltree,i),a=[],s=UZIP.F._lenCodes(e.dtree,a),f=0;f<i.length;f+=2)e.ihst[i[f]]++;for(f=0;f<a.length;f+=2)e.ihst[a[f]]++;for(var l=UZIP.F._hufTree(e.ihst,e.itree,7),c=19;c>4&&0==e.itree[1+(e.ordr[c-1]<<1)];)c--;return[t,r,l,o,s,c,i,a]},UZIP.F.getSecond=function(e){for(var t=[],r=0;r<e.length;r+=2)t.push(e[r+1]);return t},UZIP.F.nonZero=function(e){for(var t=\"\",r=0;r<e.length;r+=2)0!=e[r+1]&&(t+=(r>>1)+\",\");return t},UZIP.F.contSize=function(e,t){for(var r=0,i=0;i<t.length;i++)r+=t[i]*e[1+(i<<1)];return r},UZIP.F._codeTiny=function(e,t,r,i){for(var o=0;o<e.length;o+=2){var a=e[o],s=e[o+1];i=UZIP.F._writeLit(a,t,r,i);var f=16==a?2:17==a?3:7;a>15&&(UZIP.F._putsE(r,i,s,f),i+=f)}return i},UZIP.F._lenCodes=function(e,t){for(var r=e.length;2!=r&&0==e[r-1];)r-=2;for(var i=0;i<r;i+=2){var o=e[i+1],a=i+3<r?e[i+3]:-1,s=i+5<r?e[i+5]:-1,f=0==i?-1:e[i-1];if(0==o&&a==o&&s==o){for(var l=i+5;l+2<r&&e[l+2]==o;)l+=2;(c=Math.min(l+1-i>>>1,138))<11?t.push(17,c-3):t.push(18,c-11),i+=2*c-2}else if(o==f&&a==o&&s==o){for(l=i+5;l+2<r&&e[l+2]==o;)l+=2;var c=Math.min(l+1-i>>>1,6);t.push(16,c-3),i+=2*c-2}else t.push(o,0)}return r>>>1},UZIP.F._hufTree=function(e,t,r){var i=[],o=e.length,a=t.length,s=0;for(s=0;s<a;s+=2)t[s]=0,t[s+1]=0;for(s=0;s<o;s++)0!=e[s]&&i.push({lit:s,f:e[s]});var f=i.length,l=i.slice(0);if(0==f)return 0;if(1==f){var c=i[0].lit;l=0==c?1:0;return t[1+(c<<1)]=1,t[1+(l<<1)]=1,1}i.sort((function(e,t){return e.f-t.f}));var u=i[0],h=i[1],d=0,A=1,g=2;for(i[0]={lit:-1,f:u.f+h.f,l:u,r:h,d:0};A!=f-1;)u=d!=A&&(g==f||i[d].f<i[g].f)?i[d++]:i[g++],h=d!=A&&(g==f||i[d].f<i[g].f)?i[d++]:i[g++],i[A++]={lit:-1,f:u.f+h.f,l:u,r:h};var p=UZIP.F.setDepth(i[A-1],0);for(p>r&&(UZIP.F.restrictDepth(l,r,p),p=r),s=0;s<f;s++)t[1+(l[s].lit<<1)]=l[s].d;return p},UZIP.F.setDepth=function(e,t){return-1!=e.lit?(e.d=t,t):Math.max(UZIP.F.setDepth(e.l,t+1),UZIP.F.setDepth(e.r,t+1))},UZIP.F.restrictDepth=function(e,t,r){var i=0,o=1<<r-t,a=0;for(e.sort((function(e,t){return t.d==e.d?e.f-t.f:t.d-e.d})),i=0;i<e.length&&e[i].d>t;i++){var s=e[i].d;e[i].d=t,a+=o-(1<<r-s)}for(a>>>=r-t;a>0;){(s=e[i].d)<t?(e[i].d++,a-=1<<t-s-1):i++}for(;i>=0;i--)e[i].d==t&&a<0&&(e[i].d--,a++);0!=a&&console.log(\"debt left\")},UZIP.F._goodIndex=function(e,t){var r=0;return t[16|r]<=e&&(r|=16),t[8|r]<=e&&(r|=8),t[4|r]<=e&&(r|=4),t[2|r]<=e&&(r|=2),t[1|r]<=e&&(r|=1),r},UZIP.F._writeLit=function(e,t,r,i){return UZIP.F._putsF(r,i,t[e<<1]),i+t[1+(e<<1)]},UZIP.F.inflate=function(e,t){var r=Uint8Array;if(3==e[0]&&0==e[1])return t||new r(0);var i=UZIP.F,o=i._bitsF,a=i._bitsE,s=i._decodeTiny,f=i.makeCodes,l=i.codes2map,c=i._get17,u=i.U,h=null==t;h&&(t=new r(e.length>>>2<<3));for(var d,A,g=0,p=0,m=0,w=0,v=0,b=0,y=0,E=0,F=0;0==g;)if(g=o(e,F,1),p=o(e,F+1,2),F+=3,0!=p){if(h&&(t=UZIP.F._check(t,E+(1<<17))),1==p&&(d=u.flmap,A=u.fdmap,b=511,y=31),2==p){m=a(e,F,5)+257,w=a(e,F+5,5)+1,v=a(e,F+10,4)+4,F+=14;for(var _=0;_<38;_+=2)u.itree[_]=0,u.itree[_+1]=0;var B=1;for(_=0;_<v;_++){var U=a(e,F+3*_,3);u.itree[1+(u.ordr[_]<<1)]=U,U>B&&(B=U)}F+=3*v,f(u.itree,B),l(u.itree,B,u.imap),d=u.lmap,A=u.dmap,F=s(u.imap,(1<<B)-1,m+w,e,F,u.ttree);var C=i._copyOut(u.ttree,0,m,u.ltree);b=(1<<C)-1;var I=i._copyOut(u.ttree,m,w,u.dtree);y=(1<<I)-1,f(u.ltree,C),l(u.ltree,C,d),f(u.dtree,I),l(u.dtree,I,A)}for(;;){var Q=d[c(e,F)&b];F+=15&Q;var M=Q>>>4;if(M>>>8==0)t[E++]=M;else{if(256==M)break;var x=E+M-254;if(M>264){var S=u.ldef[M-257];x=E+(S>>>3)+a(e,F,7&S),F+=7&S}var R=A[c(e,F)&y];F+=15&R;var T=R>>>4,O=u.ddef[T],P=(O>>>4)+o(e,F,15&O);for(F+=15&O,h&&(t=UZIP.F._check(t,E+(1<<17)));E<x;)t[E]=t[E++-P],t[E]=t[E++-P],t[E]=t[E++-P],t[E]=t[E++-P];E=x}}}else{0!=(7&F)&&(F+=8-(7&F));var H=4+(F>>>3),L=e[H-4]|e[H-3]<<8;h&&(t=UZIP.F._check(t,E+L)),t.set(new r(e.buffer,e.byteOffset+H,L),E),F=H+L<<3,E+=L}return t.length==E?t:t.slice(0,E)},UZIP.F._check=function(e,t){var r=e.length;if(t<=r)return e;var i=new Uint8Array(Math.max(r<<1,t));return i.set(e,0),i},UZIP.F._decodeTiny=function(e,t,r,i,o,a){for(var s=UZIP.F._bitsE,f=UZIP.F._get17,l=0;l<r;){var c=e[f(i,o)&t];o+=15&c;var u=c>>>4;if(u<=15)a[l]=u,l++;else{var h=0,d=0;16==u?(d=3+s(i,o,2),o+=2,h=a[l-1]):17==u?(d=3+s(i,o,3),o+=3):18==u&&(d=11+s(i,o,7),o+=7);for(var A=l+d;l<A;)a[l]=h,l++}}return o},UZIP.F._copyOut=function(e,t,r,i){for(var o=0,a=0,s=i.length>>>1;a<r;){var f=e[a+t];i[a<<1]=0,i[1+(a<<1)]=f,f>o&&(o=f),a++}for(;a<s;)i[a<<1]=0,i[1+(a<<1)]=0,a++;return o},UZIP.F.makeCodes=function(e,t){for(var r,i,o,a,s=UZIP.F.U,f=e.length,l=s.bl_count,c=0;c<=t;c++)l[c]=0;for(c=1;c<f;c+=2)l[e[c]]++;var u=s.next_code;for(r=0,l[0]=0,i=1;i<=t;i++)r=r+l[i-1]<<1,u[i]=r;for(o=0;o<f;o+=2)0!=(a=e[o+1])&&(e[o]=u[a],u[a]++)},UZIP.F.codes2map=function(e,t,r){for(var i=e.length,o=UZIP.F.U.rev15,a=0;a<i;a+=2)if(0!=e[a+1])for(var s=a>>1,f=e[a+1],l=s<<4|f,c=t-f,u=e[a]<<c,h=u+(1<<c);u!=h;){r[o[u]>>>15-t]=l,u++}},UZIP.F.revCodes=function(e,t){for(var r=UZIP.F.U.rev15,i=15-t,o=0;o<e.length;o+=2){var a=e[o]<<t-e[o+1];e[o]=r[a]>>>i}},UZIP.F._putsE=function(e,t,r){r<<=7&t;var i=t>>>3;e[i]|=r,e[i+1]|=r>>>8},UZIP.F._putsF=function(e,t,r){r<<=7&t;var i=t>>>3;e[i]|=r,e[i+1]|=r>>>8,e[i+2]|=r>>>16},UZIP.F._bitsE=function(e,t,r){return(e[t>>>3]|e[1+(t>>>3)]<<8)>>>(7&t)&(1<<r)-1},UZIP.F._bitsF=function(e,t,r){return(e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)&(1<<r)-1},UZIP.F._get17=function(e,t){return(e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)},UZIP.F._get25=function(e,t){return(e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16|e[3+(t>>>3)]<<24)>>>(7&t)},UZIP.F.U=(r=Uint16Array,i=Uint32Array,{next_code:new r(16),bl_count:new r(16),ordr:[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],of0:[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,999,999,999],exb:[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0],ldef:new r(32),df0:[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,65535,65535],dxb:[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0],ddef:new i(32),flmap:new r(512),fltree:[],fdmap:new r(32),fdtree:[],lmap:new r(32768),ltree:[],ttree:[],dmap:new r(32768),dtree:[],imap:new r(512),itree:[],rev15:new r(32768),lhst:new i(286),dhst:new i(30),ihst:new i(19),lits:new i(15e3),strt:new r(65536),prev:new r(32768)}),function(){for(var e=UZIP.F.U,t=0;t<32768;t++){var r=t;r=(4278255360&(r=(4042322160&(r=(3435973836&(r=(2863311530&r)>>>1|(1431655765&r)<<1))>>>2|(858993459&r)<<2))>>>4|(252645135&r)<<4))>>>8|(16711935&r)<<8,e.rev15[t]=(r>>>16|r<<16)>>>17}function pushV(e,t,r){for(;0!=t--;)e.push(0,r)}for(t=0;t<32;t++)e.ldef[t]=e.of0[t]<<3|e.exb[t],e.ddef[t]=e.df0[t]<<4|e.dxb[t];pushV(e.fltree,144,8),pushV(e.fltree,112,9),pushV(e.fltree,24,7),pushV(e.fltree,8,8),UZIP.F.makeCodes(e.fltree,9),UZIP.F.codes2map(e.fltree,9,e.flmap),UZIP.F.revCodes(e.fltree,9),pushV(e.fdtree,32,5),UZIP.F.makeCodes(e.fdtree,5),UZIP.F.codes2map(e.fdtree,5,e.fdmap),UZIP.F.revCodes(e.fdtree,5),pushV(e.itree,19,0),pushV(e.ltree,286,0),pushV(e.dtree,30,0),pushV(e.ttree,320,0)}()}();var UZIP=_mergeNamespaces({__proto__:null,default:e},[e]);const UPNG=function(){var e={nextZero(e,t){for(;0!=e[t];)t++;return t},readUshort:(e,t)=>e[t]<<8|e[t+1],writeUshort(e,t,r){e[t]=r>>8&255,e[t+1]=255&r},readUint:(e,t)=>16777216*e[t]+(e[t+1]<<16|e[t+2]<<8|e[t+3]),writeUint(e,t,r){e[t]=r>>24&255,e[t+1]=r>>16&255,e[t+2]=r>>8&255,e[t+3]=255&r},readASCII(e,t,r){let i=\"\";for(let o=0;o<r;o++)i+=String.fromCharCode(e[t+o]);return i},writeASCII(e,t,r){for(let i=0;i<r.length;i++)e[t+i]=r.charCodeAt(i)},readBytes(e,t,r){const i=[];for(let o=0;o<r;o++)i.push(e[t+o]);return i},pad:e=>e.length<2?`0${e}`:e,readUTF8(t,r,i){let o,a=\"\";for(let o=0;o<i;o++)a+=`%${e.pad(t[r+o].toString(16))}`;try{o=decodeURIComponent(a)}catch(o){return e.readASCII(t,r,i)}return o}};function decodeImage(t,r,i,o){const a=r*i,s=_getBPP(o),f=Math.ceil(r*s/8),l=new Uint8Array(4*a),c=new Uint32Array(l.buffer),{ctype:u}=o,{depth:h}=o,d=e.readUshort;if(6==u){const e=a<<2;if(8==h)for(var A=0;A<e;A+=4)l[A]=t[A],l[A+1]=t[A+1],l[A+2]=t[A+2],l[A+3]=t[A+3];if(16==h)for(A=0;A<e;A++)l[A]=t[A<<1]}else if(2==u){const e=o.tabs.tRNS;if(null==e){if(8==h)for(A=0;A<a;A++){var g=3*A;c[A]=255<<24|t[g+2]<<16|t[g+1]<<8|t[g]}if(16==h)for(A=0;A<a;A++){g=6*A;c[A]=255<<24|t[g+4]<<16|t[g+2]<<8|t[g]}}else{var p=e[0];const r=e[1],i=e[2];if(8==h)for(A=0;A<a;A++){var m=A<<2;g=3*A;c[A]=255<<24|t[g+2]<<16|t[g+1]<<8|t[g],t[g]==p&&t[g+1]==r&&t[g+2]==i&&(l[m+3]=0)}if(16==h)for(A=0;A<a;A++){m=A<<2,g=6*A;c[A]=255<<24|t[g+4]<<16|t[g+2]<<8|t[g],d(t,g)==p&&d(t,g+2)==r&&d(t,g+4)==i&&(l[m+3]=0)}}}else if(3==u){const e=o.tabs.PLTE,s=o.tabs.tRNS,c=s?s.length:0;if(1==h)for(var w=0;w<i;w++){var v=w*f,b=w*r;for(A=0;A<r;A++){m=b+A<<2;var y=3*(E=t[v+(A>>3)]>>7-((7&A)<<0)&1);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255}}if(2==h)for(w=0;w<i;w++)for(v=w*f,b=w*r,A=0;A<r;A++){m=b+A<<2,y=3*(E=t[v+(A>>2)]>>6-((3&A)<<1)&3);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255}if(4==h)for(w=0;w<i;w++)for(v=w*f,b=w*r,A=0;A<r;A++){m=b+A<<2,y=3*(E=t[v+(A>>1)]>>4-((1&A)<<2)&15);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255}if(8==h)for(A=0;A<a;A++){var E;m=A<<2,y=3*(E=t[A]);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255}}else if(4==u){if(8==h)for(A=0;A<a;A++){m=A<<2;var F=t[_=A<<1];l[m]=F,l[m+1]=F,l[m+2]=F,l[m+3]=t[_+1]}if(16==h)for(A=0;A<a;A++){var _;m=A<<2,F=t[_=A<<2];l[m]=F,l[m+1]=F,l[m+2]=F,l[m+3]=t[_+2]}}else if(0==u)for(p=o.tabs.tRNS?o.tabs.tRNS:-1,w=0;w<i;w++){const e=w*f,i=w*r;if(1==h)for(var B=0;B<r;B++){var U=(F=255*(t[e+(B>>>3)]>>>7-(7&B)&1))==255*p?0:255;c[i+B]=U<<24|F<<16|F<<8|F}else if(2==h)for(B=0;B<r;B++){U=(F=85*(t[e+(B>>>2)]>>>6-((3&B)<<1)&3))==85*p?0:255;c[i+B]=U<<24|F<<16|F<<8|F}else if(4==h)for(B=0;B<r;B++){U=(F=17*(t[e+(B>>>1)]>>>4-((1&B)<<2)&15))==17*p?0:255;c[i+B]=U<<24|F<<16|F<<8|F}else if(8==h)for(B=0;B<r;B++){U=(F=t[e+B])==p?0:255;c[i+B]=U<<24|F<<16|F<<8|F}else if(16==h)for(B=0;B<r;B++){F=t[e+(B<<1)],U=d(t,e+(B<<1))==p?0:255;c[i+B]=U<<24|F<<16|F<<8|F}}return l}function _decompress(e,r,i,o){const a=_getBPP(e),s=Math.ceil(i*a/8),f=new Uint8Array((s+1+e.interlace)*o);return r=e.tabs.CgBI?t(r,f):_inflate(r,f),0==e.interlace?r=_filterZero(r,e,0,i,o):1==e.interlace&&(r=function _readInterlace(e,t){const r=t.width,i=t.height,o=_getBPP(t),a=o>>3,s=Math.ceil(r*o/8),f=new Uint8Array(i*s);let l=0;const c=[0,0,4,0,2,0,1],u=[0,4,0,2,0,1,0],h=[8,8,8,4,4,2,2],d=[8,8,4,4,2,2,1];let A=0;for(;A<7;){const p=h[A],m=d[A];let w=0,v=0,b=c[A];for(;b<i;)b+=p,v++;let y=u[A];for(;y<r;)y+=m,w++;const E=Math.ceil(w*o/8);_filterZero(e,t,l,w,v);let F=0,_=c[A];for(;_<i;){let t=u[A],i=l+F*E<<3;for(;t<r;){var g;if(1==o)g=(g=e[i>>3])>>7-(7&i)&1,f[_*s+(t>>3)]|=g<<7-((7&t)<<0);if(2==o)g=(g=e[i>>3])>>6-(7&i)&3,f[_*s+(t>>2)]|=g<<6-((3&t)<<1);if(4==o)g=(g=e[i>>3])>>4-(7&i)&15,f[_*s+(t>>1)]|=g<<4-((1&t)<<2);if(o>=8){const r=_*s+t*a;for(let t=0;t<a;t++)f[r+t]=e[(i>>3)+t]}i+=o,t+=m}F++,_+=p}w*v!=0&&(l+=v*(1+E)),A+=1}return f}(r,e)),r}function _inflate(e,r){return t(new Uint8Array(e.buffer,2,e.length-6),r)}var t=function(){const e={H:{}};return e.H.N=function(t,r){const i=Uint8Array;let o,a,s=0,f=0,l=0,c=0,u=0,h=0,d=0,A=0,g=0;if(3==t[0]&&0==t[1])return r||new i(0);const p=e.H,m=p.b,w=p.e,v=p.R,b=p.n,y=p.A,E=p.Z,F=p.m,_=null==r;for(_&&(r=new i(t.length>>>2<<5));0==s;)if(s=m(t,g,1),f=m(t,g+1,2),g+=3,0!=f){if(_&&(r=e.H.W(r,A+(1<<17))),1==f&&(o=F.J,a=F.h,h=511,d=31),2==f){l=w(t,g,5)+257,c=w(t,g+5,5)+1,u=w(t,g+10,4)+4,g+=14;let e=1;for(var B=0;B<38;B+=2)F.Q[B]=0,F.Q[B+1]=0;for(B=0;B<u;B++){const r=w(t,g+3*B,3);F.Q[1+(F.X[B]<<1)]=r,r>e&&(e=r)}g+=3*u,b(F.Q,e),y(F.Q,e,F.u),o=F.w,a=F.d,g=v(F.u,(1<<e)-1,l+c,t,g,F.v);const r=p.V(F.v,0,l,F.C);h=(1<<r)-1;const i=p.V(F.v,l,c,F.D);d=(1<<i)-1,b(F.C,r),y(F.C,r,o),b(F.D,i),y(F.D,i,a)}for(;;){const e=o[E(t,g)&h];g+=15&e;const i=e>>>4;if(i>>>8==0)r[A++]=i;else{if(256==i)break;{let e=A+i-254;if(i>264){const r=F.q[i-257];e=A+(r>>>3)+w(t,g,7&r),g+=7&r}const o=a[E(t,g)&d];g+=15&o;const s=o>>>4,f=F.c[s],l=(f>>>4)+m(t,g,15&f);for(g+=15&f;A<e;)r[A]=r[A++-l],r[A]=r[A++-l],r[A]=r[A++-l],r[A]=r[A++-l];A=e}}}}else{0!=(7&g)&&(g+=8-(7&g));const o=4+(g>>>3),a=t[o-4]|t[o-3]<<8;_&&(r=e.H.W(r,A+a)),r.set(new i(t.buffer,t.byteOffset+o,a),A),g=o+a<<3,A+=a}return r.length==A?r:r.slice(0,A)},e.H.W=function(e,t){const r=e.length;if(t<=r)return e;const i=new Uint8Array(r<<1);return i.set(e,0),i},e.H.R=function(t,r,i,o,a,s){const f=e.H.e,l=e.H.Z;let c=0;for(;c<i;){const e=t[l(o,a)&r];a+=15&e;const i=e>>>4;if(i<=15)s[c]=i,c++;else{let e=0,t=0;16==i?(t=3+f(o,a,2),a+=2,e=s[c-1]):17==i?(t=3+f(o,a,3),a+=3):18==i&&(t=11+f(o,a,7),a+=7);const r=c+t;for(;c<r;)s[c]=e,c++}}return a},e.H.V=function(e,t,r,i){let o=0,a=0;const s=i.length>>>1;for(;a<r;){const r=e[a+t];i[a<<1]=0,i[1+(a<<1)]=r,r>o&&(o=r),a++}for(;a<s;)i[a<<1]=0,i[1+(a<<1)]=0,a++;return o},e.H.n=function(t,r){const i=e.H.m,o=t.length;let a,s,f;let l;const c=i.j;for(var u=0;u<=r;u++)c[u]=0;for(u=1;u<o;u+=2)c[t[u]]++;const h=i.K;for(a=0,c[0]=0,s=1;s<=r;s++)a=a+c[s-1]<<1,h[s]=a;for(f=0;f<o;f+=2)l=t[f+1],0!=l&&(t[f]=h[l],h[l]++)},e.H.A=function(t,r,i){const o=t.length,a=e.H.m.r;for(let e=0;e<o;e+=2)if(0!=t[e+1]){const o=e>>1,s=t[e+1],f=o<<4|s,l=r-s;let c=t[e]<<l;const u=c+(1<<l);for(;c!=u;){i[a[c]>>>15-r]=f,c++}}},e.H.l=function(t,r){const i=e.H.m.r,o=15-r;for(let e=0;e<t.length;e+=2){const a=t[e]<<r-t[e+1];t[e]=i[a]>>>o}},e.H.M=function(e,t,r){r<<=7&t;const i=t>>>3;e[i]|=r,e[i+1]|=r>>>8},e.H.I=function(e,t,r){r<<=7&t;const i=t>>>3;e[i]|=r,e[i+1]|=r>>>8,e[i+2]|=r>>>16},e.H.e=function(e,t,r){return(e[t>>>3]|e[1+(t>>>3)]<<8)>>>(7&t)&(1<<r)-1},e.H.b=function(e,t,r){return(e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)&(1<<r)-1},e.H.Z=function(e,t){return(e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)},e.H.i=function(e,t){return(e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16|e[3+(t>>>3)]<<24)>>>(7&t)},e.H.m=function(){const e=Uint16Array,t=Uint32Array;return{K:new e(16),j:new e(16),X:[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],S:[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,999,999,999],T:[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0],q:new e(32),p:[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,65535,65535],z:[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0],c:new t(32),J:new e(512),_:[],h:new e(32),$:[],w:new e(32768),C:[],v:[],d:new e(32768),D:[],u:new e(512),Q:[],r:new e(32768),s:new t(286),Y:new t(30),a:new t(19),t:new t(15e3),k:new e(65536),g:new e(32768)}}(),function(){const t=e.H.m;for(var r=0;r<32768;r++){let e=r;e=(2863311530&e)>>>1|(1431655765&e)<<1,e=(3435973836&e)>>>2|(858993459&e)<<2,e=(4042322160&e)>>>4|(252645135&e)<<4,e=(4278255360&e)>>>8|(16711935&e)<<8,t.r[r]=(e>>>16|e<<16)>>>17}function n(e,t,r){for(;0!=t--;)e.push(0,r)}for(r=0;r<32;r++)t.q[r]=t.S[r]<<3|t.T[r],t.c[r]=t.p[r]<<4|t.z[r];n(t._,144,8),n(t._,112,9),n(t._,24,7),n(t._,8,8),e.H.n(t._,9),e.H.A(t._,9,t.J),e.H.l(t._,9),n(t.$,32,5),e.H.n(t.$,5),e.H.A(t.$,5,t.h),e.H.l(t.$,5),n(t.Q,19,0),n(t.C,286,0),n(t.D,30,0),n(t.v,320,0)}(),e.H.N}();function _getBPP(e){return[1,null,3,1,2,null,4][e.ctype]*e.depth}function _filterZero(e,t,r,i,o){let a=_getBPP(t);const s=Math.ceil(i*a/8);let f,l;a=Math.ceil(a/8);let c=e[r],u=0;if(c>1&&(e[r]=[0,0,1][c-2]),3==c)for(u=a;u<s;u++)e[u+1]=e[u+1]+(e[u+1-a]>>>1)&255;for(let t=0;t<o;t++)if(f=r+t*s,l=f+t+1,c=e[l-1],u=0,0==c)for(;u<s;u++)e[f+u]=e[l+u];else if(1==c){for(;u<a;u++)e[f+u]=e[l+u];for(;u<s;u++)e[f+u]=e[l+u]+e[f+u-a]}else if(2==c)for(;u<s;u++)e[f+u]=e[l+u]+e[f+u-s];else if(3==c){for(;u<a;u++)e[f+u]=e[l+u]+(e[f+u-s]>>>1);for(;u<s;u++)e[f+u]=e[l+u]+(e[f+u-s]+e[f+u-a]>>>1)}else{for(;u<a;u++)e[f+u]=e[l+u]+_paeth(0,e[f+u-s],0);for(;u<s;u++)e[f+u]=e[l+u]+_paeth(e[f+u-a],e[f+u-s],e[f+u-a-s])}return e}function _paeth(e,t,r){const i=e+t-r,o=i-e,a=i-t,s=i-r;return o*o<=a*a&&o*o<=s*s?e:a*a<=s*s?t:r}function _IHDR(t,r,i){i.width=e.readUint(t,r),r+=4,i.height=e.readUint(t,r),r+=4,i.depth=t[r],r++,i.ctype=t[r],r++,i.compress=t[r],r++,i.filter=t[r],r++,i.interlace=t[r],r++}function _copyTile(e,t,r,i,o,a,s,f,l){const c=Math.min(t,o),u=Math.min(r,a);let h=0,d=0;for(let r=0;r<u;r++)for(let a=0;a<c;a++)if(s>=0&&f>=0?(h=r*t+a<<2,d=(f+r)*o+s+a<<2):(h=(-f+r)*t-s+a<<2,d=r*o+a<<2),0==l)i[d]=e[h],i[d+1]=e[h+1],i[d+2]=e[h+2],i[d+3]=e[h+3];else if(1==l){var A=e[h+3]*(1/255),g=e[h]*A,p=e[h+1]*A,m=e[h+2]*A,w=i[d+3]*(1/255),v=i[d]*w,b=i[d+1]*w,y=i[d+2]*w;const t=1-A,r=A+w*t,o=0==r?0:1/r;i[d+3]=255*r,i[d+0]=(g+v*t)*o,i[d+1]=(p+b*t)*o,i[d+2]=(m+y*t)*o}else if(2==l){A=e[h+3],g=e[h],p=e[h+1],m=e[h+2],w=i[d+3],v=i[d],b=i[d+1],y=i[d+2];A==w&&g==v&&p==b&&m==y?(i[d]=0,i[d+1]=0,i[d+2]=0,i[d+3]=0):(i[d]=g,i[d+1]=p,i[d+2]=m,i[d+3]=A)}else if(3==l){A=e[h+3],g=e[h],p=e[h+1],m=e[h+2],w=i[d+3],v=i[d],b=i[d+1],y=i[d+2];if(A==w&&g==v&&p==b&&m==y)continue;if(A<220&&w>20)return!1}return!0}return{decode:function decode(r){const i=new Uint8Array(r);let o=8;const a=e,s=a.readUshort,f=a.readUint,l={tabs:{},frames:[]},c=new Uint8Array(i.length);let u,h=0,d=0;const A=[137,80,78,71,13,10,26,10];for(var g=0;g<8;g++)if(i[g]!=A[g])throw\"The input is not a PNG file!\";for(;o<i.length;){const e=a.readUint(i,o);o+=4;const r=a.readASCII(i,o,4);if(o+=4,\"IHDR\"==r)_IHDR(i,o,l);else if(\"iCCP\"==r){for(var p=o;0!=i[p];)p++;a.readASCII(i,o,p-o),i[p+1];const s=i.slice(p+2,o+e);let f=null;try{f=_inflate(s)}catch(e){f=t(s)}l.tabs[r]=f}else if(\"CgBI\"==r)l.tabs[r]=i.slice(o,o+4);else if(\"IDAT\"==r){for(g=0;g<e;g++)c[h+g]=i[o+g];h+=e}else if(\"acTL\"==r)l.tabs[r]={num_frames:f(i,o),num_plays:f(i,o+4)},u=new Uint8Array(i.length);else if(\"fcTL\"==r){if(0!=d)(E=l.frames[l.frames.length-1]).data=_decompress(l,u.slice(0,d),E.rect.width,E.rect.height),d=0;const e={x:f(i,o+12),y:f(i,o+16),width:f(i,o+4),height:f(i,o+8)};let t=s(i,o+22);t=s(i,o+20)/(0==t?100:t);const r={rect:e,delay:Math.round(1e3*t),dispose:i[o+24],blend:i[o+25]};l.frames.push(r)}else if(\"fdAT\"==r){for(g=0;g<e-4;g++)u[d+g]=i[o+g+4];d+=e-4}else if(\"pHYs\"==r)l.tabs[r]=[a.readUint(i,o),a.readUint(i,o+4),i[o+8]];else if(\"cHRM\"==r){l.tabs[r]=[];for(g=0;g<8;g++)l.tabs[r].push(a.readUint(i,o+4*g))}else if(\"tEXt\"==r||\"zTXt\"==r){null==l.tabs[r]&&(l.tabs[r]={});var m=a.nextZero(i,o),w=a.readASCII(i,o,m-o),v=o+e-m-1;if(\"tEXt\"==r)y=a.readASCII(i,m+1,v);else{var b=_inflate(i.slice(m+2,m+2+v));y=a.readUTF8(b,0,b.length)}l.tabs[r][w]=y}else if(\"iTXt\"==r){null==l.tabs[r]&&(l.tabs[r]={});m=0,p=o;m=a.nextZero(i,p);w=a.readASCII(i,p,m-p);const t=i[p=m+1];var y;i[p+1],p+=2,m=a.nextZero(i,p),a.readASCII(i,p,m-p),p=m+1,m=a.nextZero(i,p),a.readUTF8(i,p,m-p);v=e-((p=m+1)-o);if(0==t)y=a.readUTF8(i,p,v);else{b=_inflate(i.slice(p,p+v));y=a.readUTF8(b,0,b.length)}l.tabs[r][w]=y}else if(\"PLTE\"==r)l.tabs[r]=a.readBytes(i,o,e);else if(\"hIST\"==r){const e=l.tabs.PLTE.length/3;l.tabs[r]=[];for(g=0;g<e;g++)l.tabs[r].push(s(i,o+2*g))}else if(\"tRNS\"==r)3==l.ctype?l.tabs[r]=a.readBytes(i,o,e):0==l.ctype?l.tabs[r]=s(i,o):2==l.ctype&&(l.tabs[r]=[s(i,o),s(i,o+2),s(i,o+4)]);else if(\"gAMA\"==r)l.tabs[r]=a.readUint(i,o)/1e5;else if(\"sRGB\"==r)l.tabs[r]=i[o];else if(\"bKGD\"==r)0==l.ctype||4==l.ctype?l.tabs[r]=[s(i,o)]:2==l.ctype||6==l.ctype?l.tabs[r]=[s(i,o),s(i,o+2),s(i,o+4)]:3==l.ctype&&(l.tabs[r]=i[o]);else if(\"IEND\"==r)break;o+=e,a.readUint(i,o),o+=4}var E;return 0!=d&&((E=l.frames[l.frames.length-1]).data=_decompress(l,u.slice(0,d),E.rect.width,E.rect.height)),l.data=_decompress(l,c,l.width,l.height),delete l.compress,delete l.interlace,delete l.filter,l},toRGBA8:function toRGBA8(e){const t=e.width,r=e.height;if(null==e.tabs.acTL)return[decodeImage(e.data,t,r,e).buffer];const i=[];null==e.frames[0].data&&(e.frames[0].data=e.data);const o=t*r*4,a=new Uint8Array(o),s=new Uint8Array(o),f=new Uint8Array(o);for(let c=0;c<e.frames.length;c++){const u=e.frames[c],h=u.rect.x,d=u.rect.y,A=u.rect.width,g=u.rect.height,p=decodeImage(u.data,A,g,e);if(0!=c)for(var l=0;l<o;l++)f[l]=a[l];if(0==u.blend?_copyTile(p,A,g,a,t,r,h,d,0):1==u.blend&&_copyTile(p,A,g,a,t,r,h,d,1),i.push(a.buffer.slice(0)),0==u.dispose);else if(1==u.dispose)_copyTile(s,A,g,a,t,r,h,d,0);else if(2==u.dispose)for(l=0;l<o;l++)a[l]=f[l]}return i},_paeth:_paeth,_copyTile:_copyTile,_bin:e}}();!function(){const{_copyTile:e}=UPNG,{_bin:t}=UPNG,r=UPNG._paeth;var i={table:function(){const e=new Uint32Array(256);for(let t=0;t<256;t++){let r=t;for(let e=0;e<8;e++)1&r?r=3988292384^r>>>1:r>>>=1;e[t]=r}return e}(),update(e,t,r,o){for(let a=0;a<o;a++)e=i.table[255&(e^t[r+a])]^e>>>8;return e},crc:(e,t,r)=>4294967295^i.update(4294967295,e,t,r)};function addErr(e,t,r,i){t[r]+=e[0]*i>>4,t[r+1]+=e[1]*i>>4,t[r+2]+=e[2]*i>>4,t[r+3]+=e[3]*i>>4}function N(e){return Math.max(0,Math.min(255,e))}function D(e,t){const r=e[0]-t[0],i=e[1]-t[1],o=e[2]-t[2],a=e[3]-t[3];return r*r+i*i+o*o+a*a}function dither(e,t,r,i,o,a,s){null==s&&(s=1);const f=i.length,l=[];for(var c=0;c<f;c++){const e=i[c];l.push([e>>>0&255,e>>>8&255,e>>>16&255,e>>>24&255])}for(c=0;c<f;c++){let e=4294967295;for(var u=0,h=0;h<f;h++){var d=D(l[c],l[h]);h!=c&&d<e&&(e=d,u=h)}}const A=new Uint32Array(o.buffer),g=new Int16Array(t*r*4),p=[0,8,2,10,12,4,14,6,3,11,1,9,15,7,13,5];for(c=0;c<p.length;c++)p[c]=255*((p[c]+.5)/16-.5);for(let o=0;o<r;o++)for(let w=0;w<t;w++){var m;c=4*(o*t+w);if(2!=s)m=[N(e[c]+g[c]),N(e[c+1]+g[c+1]),N(e[c+2]+g[c+2]),N(e[c+3]+g[c+3])];else{d=p[4*(3&o)+(3&w)];m=[N(e[c]+d),N(e[c+1]+d),N(e[c+2]+d),N(e[c+3]+d)]}u=0;let v=16777215;for(h=0;h<f;h++){const e=D(m,l[h]);e<v&&(v=e,u=h)}const b=l[u],y=[m[0]-b[0],m[1]-b[1],m[2]-b[2],m[3]-b[3]];1==s&&(w!=t-1&&addErr(y,g,c+4,7),o!=r-1&&(0!=w&&addErr(y,g,c+4*t-4,3),addErr(y,g,c+4*t,5),w!=t-1&&addErr(y,g,c+4*t+4,1))),a[c>>2]=u,A[c>>2]=i[u]}}function _main(e,r,o,a,s){null==s&&(s={});const{crc:f}=i,l=t.writeUint,c=t.writeUshort,u=t.writeASCII;let h=8;const d=e.frames.length>1;let A,g=!1,p=33+(d?20:0);if(null!=s.sRGB&&(p+=13),null!=s.pHYs&&(p+=21),null!=s.iCCP&&(A=pako.deflate(s.iCCP),p+=21+A.length+4),3==e.ctype){for(var m=e.plte.length,w=0;w<m;w++)e.plte[w]>>>24!=255&&(g=!0);p+=8+3*m+4+(g?8+1*m+4:0)}for(var v=0;v<e.frames.length;v++){d&&(p+=38),p+=(F=e.frames[v]).cimg.length+12,0!=v&&(p+=4)}p+=12;const b=new Uint8Array(p),y=[137,80,78,71,13,10,26,10];for(w=0;w<8;w++)b[w]=y[w];if(l(b,h,13),h+=4,u(b,h,\"IHDR\"),h+=4,l(b,h,r),h+=4,l(b,h,o),h+=4,b[h]=e.depth,h++,b[h]=e.ctype,h++,b[h]=0,h++,b[h]=0,h++,b[h]=0,h++,l(b,h,f(b,h-17,17)),h+=4,null!=s.sRGB&&(l(b,h,1),h+=4,u(b,h,\"sRGB\"),h+=4,b[h]=s.sRGB,h++,l(b,h,f(b,h-5,5)),h+=4),null!=s.iCCP){const e=13+A.length;l(b,h,e),h+=4,u(b,h,\"iCCP\"),h+=4,u(b,h,\"ICC profile\"),h+=11,h+=2,b.set(A,h),h+=A.length,l(b,h,f(b,h-(e+4),e+4)),h+=4}if(null!=s.pHYs&&(l(b,h,9),h+=4,u(b,h,\"pHYs\"),h+=4,l(b,h,s.pHYs[0]),h+=4,l(b,h,s.pHYs[1]),h+=4,b[h]=s.pHYs[2],h++,l(b,h,f(b,h-13,13)),h+=4),d&&(l(b,h,8),h+=4,u(b,h,\"acTL\"),h+=4,l(b,h,e.frames.length),h+=4,l(b,h,null!=s.loop?s.loop:0),h+=4,l(b,h,f(b,h-12,12)),h+=4),3==e.ctype){l(b,h,3*(m=e.plte.length)),h+=4,u(b,h,\"PLTE\"),h+=4;for(w=0;w<m;w++){const t=3*w,r=e.plte[w],i=255&r,o=r>>>8&255,a=r>>>16&255;b[h+t+0]=i,b[h+t+1]=o,b[h+t+2]=a}if(h+=3*m,l(b,h,f(b,h-3*m-4,3*m+4)),h+=4,g){l(b,h,m),h+=4,u(b,h,\"tRNS\"),h+=4;for(w=0;w<m;w++)b[h+w]=e.plte[w]>>>24&255;h+=m,l(b,h,f(b,h-m-4,m+4)),h+=4}}let E=0;for(v=0;v<e.frames.length;v++){var F=e.frames[v];d&&(l(b,h,26),h+=4,u(b,h,\"fcTL\"),h+=4,l(b,h,E++),h+=4,l(b,h,F.rect.width),h+=4,l(b,h,F.rect.height),h+=4,l(b,h,F.rect.x),h+=4,l(b,h,F.rect.y),h+=4,c(b,h,a[v]),h+=2,c(b,h,1e3),h+=2,b[h]=F.dispose,h++,b[h]=F.blend,h++,l(b,h,f(b,h-30,30)),h+=4);const t=F.cimg;l(b,h,(m=t.length)+(0==v?0:4)),h+=4;const r=h;u(b,h,0==v?\"IDAT\":\"fdAT\"),h+=4,0!=v&&(l(b,h,E++),h+=4),b.set(t,h),h+=m,l(b,h,f(b,r,h-r)),h+=4}return l(b,h,0),h+=4,u(b,h,\"IEND\"),h+=4,l(b,h,f(b,h-4,4)),h+=4,b.buffer}function compressPNG(e,t,r){for(let i=0;i<e.frames.length;i++){const o=e.frames[i];o.rect.width;const a=o.rect.height,s=new Uint8Array(a*o.bpl+a);o.cimg=_filterZero(o.img,a,o.bpp,o.bpl,s,t,r)}}function compress(t,r,i,o,a){const s=a[0],f=a[1],l=a[2],c=a[3],u=a[4],h=a[5];let d=6,A=8,g=255;for(var p=0;p<t.length;p++){const e=new Uint8Array(t[p]);for(var m=e.length,w=0;w<m;w+=4)g&=e[w+3]}const v=255!=g,b=function framize(t,r,i,o,a,s){const f=[];for(var l=0;l<t.length;l++){const h=new Uint8Array(t[l]),A=new Uint32Array(h.buffer);var c;let g=0,p=0,m=r,w=i,v=o?1:0;if(0!=l){const b=s||o||1==l||0!=f[l-2].dispose?1:2;let y=0,E=1e9;for(let e=0;e<b;e++){var u=new Uint8Array(t[l-1-e]);const o=new Uint32Array(t[l-1-e]);let s=r,f=i,c=-1,h=-1;for(let e=0;e<i;e++)for(let t=0;t<r;t++){A[d=e*r+t]!=o[d]&&(t<s&&(s=t),t>c&&(c=t),e<f&&(f=e),e>h&&(h=e))}-1==c&&(s=f=c=h=0),a&&(1==(1&s)&&s--,1==(1&f)&&f--);const v=(c-s+1)*(h-f+1);v<E&&(E=v,y=e,g=s,p=f,m=c-s+1,w=h-f+1)}u=new Uint8Array(t[l-1-y]);1==y&&(f[l-1].dispose=2),c=new Uint8Array(m*w*4),e(u,r,i,c,m,w,-g,-p,0),v=e(h,r,i,c,m,w,-g,-p,3)?1:0,1==v?_prepareDiff(h,r,i,c,{x:g,y:p,width:m,height:w}):e(h,r,i,c,m,w,-g,-p,0)}else c=h.slice(0);f.push({rect:{x:g,y:p,width:m,height:w},img:c,blend:v,dispose:0})}if(o)for(l=0;l<f.length;l++){if(1==(A=f[l]).blend)continue;const e=A.rect,o=f[l-1].rect,s=Math.min(e.x,o.x),c=Math.min(e.y,o.y),u={x:s,y:c,width:Math.max(e.x+e.width,o.x+o.width)-s,height:Math.max(e.y+e.height,o.y+o.height)-c};f[l-1].dispose=1,l-1!=0&&_updateFrame(t,r,i,f,l-1,u,a),_updateFrame(t,r,i,f,l,u,a)}let h=0;if(1!=t.length)for(var d=0;d<f.length;d++){var A;h+=(A=f[d]).rect.width*A.rect.height}return f}(t,r,i,s,f,l),y={},E=[],F=[];if(0!=o){const e=[];for(w=0;w<b.length;w++)e.push(b[w].img.buffer);const t=function concatRGBA(e){let t=0;for(var r=0;r<e.length;r++)t+=e[r].byteLength;const i=new Uint8Array(t);let o=0;for(r=0;r<e.length;r++){const t=new Uint8Array(e[r]),a=t.length;for(let e=0;e<a;e+=4){let r=t[e],a=t[e+1],s=t[e+2];const f=t[e+3];0==f&&(r=a=s=0),i[o+e]=r,i[o+e+1]=a,i[o+e+2]=s,i[o+e+3]=f}o+=a}return i.buffer}(e),r=quantize(t,o);for(w=0;w<r.plte.length;w++)E.push(r.plte[w].est.rgba);let i=0;for(w=0;w<b.length;w++){const e=(B=b[w]).img.length;var _=new Uint8Array(r.inds.buffer,i>>2,e>>2);F.push(_);const t=new Uint8Array(r.abuf,i,e);h&&dither(B.img,B.rect.width,B.rect.height,E,t,_),B.img.set(t),i+=e}}else for(p=0;p<b.length;p++){var B=b[p];const e=new Uint32Array(B.img.buffer);var U=B.rect.width;m=e.length,_=new Uint8Array(m);F.push(_);for(w=0;w<m;w++){const t=e[w];if(0!=w&&t==e[w-1])_[w]=_[w-1];else if(w>U&&t==e[w-U])_[w]=_[w-U];else{let e=y[t];if(null==e&&(y[t]=e=E.length,E.push(t),E.length>=300))break;_[w]=e}}}const C=E.length;C<=256&&0==u&&(A=C<=2?1:C<=4?2:C<=16?4:8,A=Math.max(A,c));for(p=0;p<b.length;p++){(B=b[p]).rect.x,B.rect.y;U=B.rect.width;const e=B.rect.height;let t=B.img;new Uint32Array(t.buffer);let r=4*U,i=4;if(C<=256&&0==u){r=Math.ceil(A*U/8);var I=new Uint8Array(r*e);const o=F[p];for(let t=0;t<e;t++){w=t*r;const e=t*U;if(8==A)for(var Q=0;Q<U;Q++)I[w+Q]=o[e+Q];else if(4==A)for(Q=0;Q<U;Q++)I[w+(Q>>1)]|=o[e+Q]<<4-4*(1&Q);else if(2==A)for(Q=0;Q<U;Q++)I[w+(Q>>2)]|=o[e+Q]<<6-2*(3&Q);else if(1==A)for(Q=0;Q<U;Q++)I[w+(Q>>3)]|=o[e+Q]<<7-1*(7&Q)}t=I,d=3,i=1}else if(0==v&&1==b.length){I=new Uint8Array(U*e*3);const o=U*e;for(w=0;w<o;w++){const e=3*w,r=4*w;I[e]=t[r],I[e+1]=t[r+1],I[e+2]=t[r+2]}t=I,d=2,i=3,r=3*U}B.img=t,B.bpl=r,B.bpp=i}return{ctype:d,depth:A,plte:E,frames:b}}function _updateFrame(t,r,i,o,a,s,f){const l=Uint8Array,c=Uint32Array,u=new l(t[a-1]),h=new c(t[a-1]),d=a+1<t.length?new l(t[a+1]):null,A=new l(t[a]),g=new c(A.buffer);let p=r,m=i,w=-1,v=-1;for(let e=0;e<s.height;e++)for(let t=0;t<s.width;t++){const i=s.x+t,f=s.y+e,l=f*r+i,c=g[l];0==c||0==o[a-1].dispose&&h[l]==c&&(null==d||0!=d[4*l+3])||(i<p&&(p=i),i>w&&(w=i),f<m&&(m=f),f>v&&(v=f))}-1==w&&(p=m=w=v=0),f&&(1==(1&p)&&p--,1==(1&m)&&m--),s={x:p,y:m,width:w-p+1,height:v-m+1};const b=o[a];b.rect=s,b.blend=1,b.img=new Uint8Array(s.width*s.height*4),0==o[a-1].dispose?(e(u,r,i,b.img,s.width,s.height,-s.x,-s.y,0),_prepareDiff(A,r,i,b.img,s)):e(A,r,i,b.img,s.width,s.height,-s.x,-s.y,0)}function _prepareDiff(t,r,i,o,a){e(t,r,i,o,a.width,a.height,-a.x,-a.y,2)}function _filterZero(e,t,r,i,o,a,s){const f=[];let l,c=[0,1,2,3,4];-1!=a?c=[a]:(t*i>5e5||1==r)&&(c=[0]),s&&(l={level:0});const u=UZIP;for(var h=0;h<c.length;h++){for(let a=0;a<t;a++)_filterLine(o,e,a,i,r,c[h]);f.push(u.deflate(o,l))}let d,A=1e9;for(h=0;h<f.length;h++)f[h].length<A&&(d=h,A=f[h].length);return f[d]}function _filterLine(e,t,i,o,a,s){const f=i*o;let l=f+i;if(e[l]=s,l++,0==s)if(o<500)for(var c=0;c<o;c++)e[l+c]=t[f+c];else e.set(new Uint8Array(t.buffer,f,o),l);else if(1==s){for(c=0;c<a;c++)e[l+c]=t[f+c];for(c=a;c<o;c++)e[l+c]=t[f+c]-t[f+c-a]+256&255}else if(0==i){for(c=0;c<a;c++)e[l+c]=t[f+c];if(2==s)for(c=a;c<o;c++)e[l+c]=t[f+c];if(3==s)for(c=a;c<o;c++)e[l+c]=t[f+c]-(t[f+c-a]>>1)+256&255;if(4==s)for(c=a;c<o;c++)e[l+c]=t[f+c]-r(t[f+c-a],0,0)+256&255}else{if(2==s)for(c=0;c<o;c++)e[l+c]=t[f+c]+256-t[f+c-o]&255;if(3==s){for(c=0;c<a;c++)e[l+c]=t[f+c]+256-(t[f+c-o]>>1)&255;for(c=a;c<o;c++)e[l+c]=t[f+c]+256-(t[f+c-o]+t[f+c-a]>>1)&255}if(4==s){for(c=0;c<a;c++)e[l+c]=t[f+c]+256-r(0,t[f+c-o],0)&255;for(c=a;c<o;c++)e[l+c]=t[f+c]+256-r(t[f+c-a],t[f+c-o],t[f+c-a-o])&255}}}function quantize(e,t){const r=new Uint8Array(e),i=r.slice(0),o=new Uint32Array(i.buffer),a=getKDtree(i,t),s=a[0],f=a[1],l=r.length,c=new Uint8Array(l>>2);let u;if(r.length<2e7)for(var h=0;h<l;h+=4){u=getNearest(s,d=r[h]*(1/255),A=r[h+1]*(1/255),g=r[h+2]*(1/255),p=r[h+3]*(1/255)),c[h>>2]=u.ind,o[h>>2]=u.est.rgba}else for(h=0;h<l;h+=4){var d=r[h]*(1/255),A=r[h+1]*(1/255),g=r[h+2]*(1/255),p=r[h+3]*(1/255);for(u=s;u.left;)u=planeDst(u.est,d,A,g,p)<=0?u.left:u.right;c[h>>2]=u.ind,o[h>>2]=u.est.rgba}return{abuf:i.buffer,inds:c,plte:f}}function getKDtree(e,t,r){null==r&&(r=1e-4);const i=new Uint32Array(e.buffer),o={i0:0,i1:e.length,bst:null,est:null,tdst:0,left:null,right:null};o.bst=stats(e,o.i0,o.i1),o.est=estats(o.bst);const a=[o];for(;a.length<t;){let t=0,o=0;for(var s=0;s<a.length;s++)a[s].est.L>t&&(t=a[s].est.L,o=s);if(t<r)break;const f=a[o],l=splitPixels(e,i,f.i0,f.i1,f.est.e,f.est.eMq255);if(f.i0>=l||f.i1<=l){f.est.L=0;continue}const c={i0:f.i0,i1:l,bst:null,est:null,tdst:0,left:null,right:null};c.bst=stats(e,c.i0,c.i1),c.est=estats(c.bst);const u={i0:l,i1:f.i1,bst:null,est:null,tdst:0,left:null,right:null};u.bst={R:[],m:[],N:f.bst.N-c.bst.N};for(s=0;s<16;s++)u.bst.R[s]=f.bst.R[s]-c.bst.R[s];for(s=0;s<4;s++)u.bst.m[s]=f.bst.m[s]-c.bst.m[s];u.est=estats(u.bst),f.left=c,f.right=u,a[o]=c,a.push(u)}a.sort(((e,t)=>t.bst.N-e.bst.N));for(s=0;s<a.length;s++)a[s].ind=s;return[o,a]}function getNearest(e,t,r,i,o){if(null==e.left)return e.tdst=function dist(e,t,r,i,o){const a=t-e[0],s=r-e[1],f=i-e[2],l=o-e[3];return a*a+s*s+f*f+l*l}(e.est.q,t,r,i,o),e;const a=planeDst(e.est,t,r,i,o);let s=e.left,f=e.right;a>0&&(s=e.right,f=e.left);const l=getNearest(s,t,r,i,o);if(l.tdst<=a*a)return l;const c=getNearest(f,t,r,i,o);return c.tdst<l.tdst?c:l}function planeDst(e,t,r,i,o){const{e:a}=e;return a[0]*t+a[1]*r+a[2]*i+a[3]*o-e.eMq}function splitPixels(e,t,r,i,o,a){for(i-=4;r<i;){for(;vecDot(e,r,o)<=a;)r+=4;for(;vecDot(e,i,o)>a;)i-=4;if(r>=i)break;const s=t[r>>2];t[r>>2]=t[i>>2],t[i>>2]=s,r+=4,i-=4}for(;vecDot(e,r,o)>a;)r-=4;return r+4}function vecDot(e,t,r){return e[t]*r[0]+e[t+1]*r[1]+e[t+2]*r[2]+e[t+3]*r[3]}function stats(e,t,r){const i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],o=[0,0,0,0],a=r-t>>2;for(let a=t;a<r;a+=4){const t=e[a]*(1/255),r=e[a+1]*(1/255),s=e[a+2]*(1/255),f=e[a+3]*(1/255);o[0]+=t,o[1]+=r,o[2]+=s,o[3]+=f,i[0]+=t*t,i[1]+=t*r,i[2]+=t*s,i[3]+=t*f,i[5]+=r*r,i[6]+=r*s,i[7]+=r*f,i[10]+=s*s,i[11]+=s*f,i[15]+=f*f}return i[4]=i[1],i[8]=i[2],i[9]=i[6],i[12]=i[3],i[13]=i[7],i[14]=i[11],{R:i,m:o,N:a}}function estats(e){const{R:t}=e,{m:r}=e,{N:i}=e,a=r[0],s=r[1],f=r[2],l=r[3],c=0==i?0:1/i,u=[t[0]-a*a*c,t[1]-a*s*c,t[2]-a*f*c,t[3]-a*l*c,t[4]-s*a*c,t[5]-s*s*c,t[6]-s*f*c,t[7]-s*l*c,t[8]-f*a*c,t[9]-f*s*c,t[10]-f*f*c,t[11]-f*l*c,t[12]-l*a*c,t[13]-l*s*c,t[14]-l*f*c,t[15]-l*l*c],h=u,d=o;let A=[Math.random(),Math.random(),Math.random(),Math.random()],g=0,p=0;if(0!=i)for(let e=0;e<16&&(A=d.multVec(h,A),p=Math.sqrt(d.dot(A,A)),A=d.sml(1/p,A),!(0!=e&&Math.abs(p-g)<1e-9));e++)g=p;const m=[a*c,s*c,f*c,l*c];return{Cov:u,q:m,e:A,L:g,eMq255:d.dot(d.sml(255,m),A),eMq:d.dot(A,m),rgba:(Math.round(255*m[3])<<24|Math.round(255*m[2])<<16|Math.round(255*m[1])<<8|Math.round(255*m[0])<<0)>>>0}}var o={multVec:(e,t)=>[e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3],e[4]*t[0]+e[5]*t[1]+e[6]*t[2]+e[7]*t[3],e[8]*t[0]+e[9]*t[1]+e[10]*t[2]+e[11]*t[3],e[12]*t[0]+e[13]*t[1]+e[14]*t[2]+e[15]*t[3]],dot:(e,t)=>e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3],sml:(e,t)=>[e*t[0],e*t[1],e*t[2],e*t[3]]};UPNG.encode=function encode(e,t,r,i,o,a,s){null==i&&(i=0),null==s&&(s=!1);const f=compress(e,t,r,i,[!1,!1,!1,0,s,!1]);return compressPNG(f,-1),_main(f,t,r,o,a)},UPNG.encodeLL=function encodeLL(e,t,r,i,o,a,s,f){const l={ctype:0+(1==i?0:2)+(0==o?0:4),depth:a,frames:[]},c=(i+o)*a,u=c*t;for(let i=0;i<e.length;i++)l.frames.push({rect:{x:0,y:0,width:t,height:r},img:new Uint8Array(e[i]),blend:0,dispose:1,bpp:Math.ceil(c/8),bpl:Math.ceil(u/8)});return compressPNG(l,0,!0),_main(l,t,r,s,f)},UPNG.encode.compress=compress,UPNG.encode.dither=dither,UPNG.quantize=quantize,UPNG.quantize.getKDtree=getKDtree,UPNG.quantize.getNearest=getNearest}();const r={toArrayBuffer(e,t){const i=e.width,o=e.height,a=i<<2,s=e.getContext(\"2d\").getImageData(0,0,i,o),f=new Uint32Array(s.data.buffer),l=(32*i+31)/32<<2,c=l*o,u=122+c,h=new ArrayBuffer(u),d=new DataView(h),A=1<<20;let g,p,m,w,v=A,b=0,y=0,E=0;function set16(e){d.setUint16(y,e,!0),y+=2}function set32(e){d.setUint32(y,e,!0),y+=4}function seek(e){y+=e}set16(19778),set32(u),seek(4),set32(122),set32(108),set32(i),set32(-o>>>0),set16(1),set16(32),set32(3),set32(c),set32(2835),set32(2835),seek(8),set32(16711680),set32(65280),set32(255),set32(4278190080),set32(1466527264),function convert(){for(;b<o&&v>0;){for(w=122+b*l,g=0;g<a;)v--,p=f[E++],m=p>>>24,d.setUint32(w+g,p<<8|m),g+=4;b++}E<f.length?(v=A,setTimeout(convert,r._dly)):t(h)}()},toBlob(e,t){this.toArrayBuffer(e,(e=>{t(new Blob([e],{type:\"image/bmp\"}))}))},_dly:9};var i={CHROME:\"CHROME\",FIREFOX:\"FIREFOX\",DESKTOP_SAFARI:\"DESKTOP_SAFARI\",IE:\"IE\",IOS:\"IOS\",ETC:\"ETC\"},o={[i.CHROME]:16384,[i.FIREFOX]:11180,[i.DESKTOP_SAFARI]:16384,[i.IE]:8192,[i.IOS]:4096,[i.ETC]:8192};const a=\"undefined\"!=typeof window,s=\"undefined\"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope,f=a&&window.cordova&&window.cordova.require&&window.cordova.require(\"cordova/modulemapper\"),CustomFile=(a||s)&&(f&&f.getOriginalSymbol(window,\"File\")||\"undefined\"!=typeof File&&File),CustomFileReader=(a||s)&&(f&&f.getOriginalSymbol(window,\"FileReader\")||\"undefined\"!=typeof FileReader&&FileReader);function getFilefromDataUrl(e,t,r=Date.now()){return new Promise((i=>{const o=e.split(\",\"),a=o[0].match(/:(.*?);/)[1],s=globalThis.atob(o[1]);let f=s.length;const l=new Uint8Array(f);for(;f--;)l[f]=s.charCodeAt(f);const c=new Blob([l],{type:a});c.name=t,c.lastModified=r,i(c)}))}function getDataUrlFromFile(e){return new Promise(((t,r)=>{const i=new CustomFileReader;i.onload=()=>t(i.result),i.onerror=e=>r(e),i.readAsDataURL(e)}))}function loadImage(e){return new Promise(((t,r)=>{const i=new Image;i.onload=()=>t(i),i.onerror=e=>r(e),i.src=e}))}function getBrowserName(){if(void 0!==getBrowserName.cachedResult)return getBrowserName.cachedResult;let e=i.ETC;const{userAgent:t}=navigator;return/Chrom(e|ium)/i.test(t)?e=i.CHROME:/iP(ad|od|hone)/i.test(t)&&/WebKit/i.test(t)?e=i.IOS:/Safari/i.test(t)?e=i.DESKTOP_SAFARI:/Firefox/i.test(t)?e=i.FIREFOX:(/MSIE/i.test(t)||!0==!!document.documentMode)&&(e=i.IE),getBrowserName.cachedResult=e,getBrowserName.cachedResult}function approximateBelowMaximumCanvasSizeOfBrowser(e,t){const r=getBrowserName(),i=o[r];let a=e,s=t,f=a*s;const l=a>s?s/a:a/s;for(;f>i*i;){const e=(i+a)/2,t=(i+s)/2;e<t?(s=t,a=t*l):(s=e*l,a=e),f=a*s}return{width:a,height:s}}function getNewCanvasAndCtx(e,t){let r,i;try{if(r=new OffscreenCanvas(e,t),i=r.getContext(\"2d\"),null===i)throw new Error(\"getContext of OffscreenCanvas returns null\")}catch(e){r=document.createElement(\"canvas\"),i=r.getContext(\"2d\")}return r.width=e,r.height=t,[r,i]}function drawImageInCanvas(e,t){const{width:r,height:i}=approximateBelowMaximumCanvasSizeOfBrowser(e.width,e.height),[o,a]=getNewCanvasAndCtx(r,i);return t&&/jpe?g/.test(t)&&(a.fillStyle=\"white\",a.fillRect(0,0,o.width,o.height)),a.drawImage(e,0,0,o.width,o.height),o}function isIOS(){return void 0!==isIOS.cachedResult||(isIOS.cachedResult=[\"iPad Simulator\",\"iPhone Simulator\",\"iPod Simulator\",\"iPad\",\"iPhone\",\"iPod\"].includes(navigator.platform)||navigator.userAgent.includes(\"Mac\")&&\"undefined\"!=typeof document&&\"ontouchend\"in document),isIOS.cachedResult}function drawFileInCanvas(e,t={}){return new Promise((function(r,o){let a,s;var $Try_2_Post=function(){try{return s=drawImageInCanvas(a,t.fileType||e.type),r([a,s])}catch(e){return o(e)}},$Try_2_Catch=function(t){try{0;var $Try_3_Catch=function(e){try{throw e}catch(e){return o(e)}};try{let t;return getDataUrlFromFile(e).then((function(e){try{return t=e,loadImage(t).then((function(e){try{return a=e,function(){try{return $Try_2_Post()}catch(e){return o(e)}}()}catch(e){return $Try_3_Catch(e)}}),$Try_3_Catch)}catch(e){return $Try_3_Catch(e)}}),$Try_3_Catch)}catch(e){$Try_3_Catch(e)}}catch(e){return o(e)}};try{if(isIOS()||[i.DESKTOP_SAFARI,i.MOBILE_SAFARI].includes(getBrowserName()))throw new Error(\"Skip createImageBitmap on IOS and Safari\");return createImageBitmap(e).then((function(e){try{return a=e,$Try_2_Post()}catch(e){return $Try_2_Catch()}}),$Try_2_Catch)}catch(e){$Try_2_Catch()}}))}function canvasToFile(e,t,i,o,a=1){return new Promise((function(s,f){let l;if(\"image/png\"===t){let c,u,h;return c=e.getContext(\"2d\"),({data:u}=c.getImageData(0,0,e.width,e.height)),h=UPNG.encode([u.buffer],e.width,e.height,4096*a),l=new Blob([h],{type:t}),l.name=i,l.lastModified=o,$If_4.call(this)}{if(\"image/bmp\"===t)return new Promise((t=>r.toBlob(e,t))).then(function(e){try{return l=e,l.name=i,l.lastModified=o,$If_5.call(this)}catch(e){return f(e)}}.bind(this),f);{if(\"function\"==typeof OffscreenCanvas&&e instanceof OffscreenCanvas)return e.convertToBlob({type:t,quality:a}).then(function(e){try{return l=e,l.name=i,l.lastModified=o,$If_6.call(this)}catch(e){return f(e)}}.bind(this),f);{let d;return d=e.toDataURL(t,a),getFilefromDataUrl(d,i,o).then(function(e){try{return l=e,$If_6.call(this)}catch(e){return f(e)}}.bind(this),f)}function $If_6(){return $If_5.call(this)}}function $If_5(){return $If_4.call(this)}}function $If_4(){return s(l)}}))}function cleanupCanvasMemory(e){e.width=0,e.height=0}function isAutoOrientationInBrowser(){return new Promise((function(e,t){let r,i,o,a,s;return void 0!==isAutoOrientationInBrowser.cachedResult?e(isAutoOrientationInBrowser.cachedResult):(r=\"data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAAAAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAEAAgMBEQACEQEDEQH/xABKAAEAAAAAAAAAAAAAAAAAAAALEAEAAAAAAAAAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAAAAAAAAEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/8H//2Q==\",getFilefromDataUrl(\"data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAAAAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAEAAgMBEQACEQEDEQH/xABKAAEAAAAAAAAAAAAAAAAAAAALEAEAAAAAAAAAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAAAAAAAAEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/8H//2Q==\",\"test.jpg\",Date.now()).then((function(r){try{return i=r,drawFileInCanvas(i).then((function(r){try{return o=r[1],canvasToFile(o,i.type,i.name,i.lastModified).then((function(r){try{return a=r,cleanupCanvasMemory(o),drawFileInCanvas(a).then((function(r){try{return s=r[0],isAutoOrientationInBrowser.cachedResult=1===s.width&&2===s.height,e(isAutoOrientationInBrowser.cachedResult)}catch(e){return t(e)}}),t)}catch(e){return t(e)}}),t)}catch(e){return t(e)}}),t)}catch(e){return t(e)}}),t))}))}function getExifOrientation(e){return new Promise(((t,r)=>{const i=new CustomFileReader;i.onload=e=>{const r=new DataView(e.target.result);if(65496!=r.getUint16(0,!1))return t(-2);const i=r.byteLength;let o=2;for(;o<i;){if(r.getUint16(o+2,!1)<=8)return t(-1);const e=r.getUint16(o,!1);if(o+=2,65505==e){if(1165519206!=r.getUint32(o+=2,!1))return t(-1);const e=18761==r.getUint16(o+=6,!1);o+=r.getUint32(o+4,e);const i=r.getUint16(o,e);o+=2;for(let a=0;a<i;a++)if(274==r.getUint16(o+12*a,e))return t(r.getUint16(o+12*a+8,e))}else{if(65280!=(65280&e))break;o+=r.getUint16(o,!1)}}return t(-1)},i.onerror=e=>r(e),i.readAsArrayBuffer(e)}))}function handleMaxWidthOrHeight(e,t){const{width:r}=e,{height:i}=e,{maxWidthOrHeight:o}=t;let a,s=e;return isFinite(o)&&(r>o||i>o)&&([s,a]=getNewCanvasAndCtx(r,i),r>i?(s.width=o,s.height=i/r*o):(s.width=r/i*o,s.height=o),a.drawImage(e,0,0,s.width,s.height),cleanupCanvasMemory(e)),s}function followExifOrientation(e,t){const{width:r}=e,{height:i}=e,[o,a]=getNewCanvasAndCtx(r,i);switch(t>4&&t<9?(o.width=i,o.height=r):(o.width=r,o.height=i),t){case 2:a.transform(-1,0,0,1,r,0);break;case 3:a.transform(-1,0,0,-1,r,i);break;case 4:a.transform(1,0,0,-1,0,i);break;case 5:a.transform(0,1,1,0,0,0);break;case 6:a.transform(0,1,-1,0,i,0);break;case 7:a.transform(0,-1,-1,0,i,r);break;case 8:a.transform(0,-1,1,0,0,r)}return a.drawImage(e,0,0,r,i),cleanupCanvasMemory(e),o}function compress(e,t,r=0){return new Promise((function(i,o){let a,s,f,l,c,u,h,d,A,g,p,m,w,v,b,y,E,F,_,B;function incProgress(e=5){if(t.signal&&t.signal.aborted)throw t.signal.reason;a+=e,t.onProgress(Math.min(a,100))}function setProgress(e){if(t.signal&&t.signal.aborted)throw t.signal.reason;a=Math.min(Math.max(e,a),100),t.onProgress(a)}return a=r,s=t.maxIteration||10,f=1024*t.maxSizeMB*1024,incProgress(),drawFileInCanvas(e,t).then(function(r){try{return[,l]=r,incProgress(),c=handleMaxWidthOrHeight(l,t),incProgress(),new Promise((function(r,i){var o;if(!(o=t.exifOrientation))return getExifOrientation(e).then(function(e){try{return o=e,$If_2.call(this)}catch(e){return i(e)}}.bind(this),i);function $If_2(){return r(o)}return $If_2.call(this)})).then(function(r){try{return u=r,incProgress(),isAutoOrientationInBrowser().then(function(r){try{return h=r?c:followExifOrientation(c,u),incProgress(),d=t.initialQuality||1,A=t.fileType||e.type,canvasToFile(h,A,e.name,e.lastModified,d).then(function(r){try{{if(g=r,incProgress(),p=g.size>f,m=g.size>e.size,!p&&!m)return setProgress(100),i(g);var a;function $Loop_3(){if(s--&&(b>f||b>w)){let t,r;return t=B?.95*_.width:_.width,r=B?.95*_.height:_.height,[E,F]=getNewCanvasAndCtx(t,r),F.drawImage(_,0,0,t,r),d*=\"image/png\"===A?.85:.95,canvasToFile(E,A,e.name,e.lastModified,d).then((function(e){try{return y=e,cleanupCanvasMemory(_),_=E,b=y.size,setProgress(Math.min(99,Math.floor((v-b)/(v-f)*100))),$Loop_3}catch(e){return o(e)}}),o)}return[1]}return w=e.size,v=g.size,b=v,_=h,B=!t.alwaysKeepResolution&&p,(a=function(e){for(;e;){if(e.then)return void e.then(a,o);try{if(e.pop){if(e.length)return e.pop()?$Loop_3_exit.call(this):e;e=$Loop_3}else e=e.call(this)}catch(e){return o(e)}}}.bind(this))($Loop_3);function $Loop_3_exit(){return cleanupCanvasMemory(_),cleanupCanvasMemory(E),cleanupCanvasMemory(c),cleanupCanvasMemory(h),cleanupCanvasMemory(l),setProgress(100),i(y)}}}catch(u){return o(u)}}.bind(this),o)}catch(e){return o(e)}}.bind(this),o)}catch(e){return o(e)}}.bind(this),o)}catch(e){return o(e)}}.bind(this),o)}))}const l=\"\\nlet scriptImported = false\\nself.addEventListener('message', async (e) => {\\n  const { file, id, imageCompressionLibUrl, options } = e.data\\n  options.onProgress = (progress) => self.postMessage({ progress, id })\\n  try {\\n    if (!scriptImported) {\\n      // console.log('[worker] importScripts', imageCompressionLibUrl)\\n      self.importScripts(imageCompressionLibUrl)\\n      scriptImported = true\\n    }\\n    // console.log('[worker] self', self)\\n    const compressedFile = await imageCompression(file, options)\\n    self.postMessage({ file: compressedFile, id })\\n  } catch (e) {\\n    // console.error('[worker] error', e)\\n    self.postMessage({ error: e.message + '\\\\n' + e.stack, id })\\n  }\\n})\\n\";let c;function compressOnWebWorker(e,t){return new Promise(((r,i)=>{c||(c=function createWorkerScriptURL(e){const t=[];return\"function\"==typeof e?t.push(`(${e})()`):t.push(e),URL.createObjectURL(new Blob(t))}(l));const o=new Worker(c);o.addEventListener(\"message\",(function handler(e){if(t.signal&&t.signal.aborted)o.terminate();else if(void 0===e.data.progress){if(e.data.error)return i(new Error(e.data.error)),void o.terminate();r(e.data.file),o.terminate()}else t.onProgress(e.data.progress)})),o.addEventListener(\"error\",i),t.signal&&t.signal.addEventListener(\"abort\",(()=>{i(t.signal.reason),o.terminate()})),o.postMessage({file:e,imageCompressionLibUrl:t.libURL,options:{...t,onProgress:void 0,signal:void 0}})}))}function imageCompression(e,t){return new Promise((function(r,i){let o,a,s,f,l,c;if(o={...t},s=0,({onProgress:f}=o),o.maxSizeMB=o.maxSizeMB||Number.POSITIVE_INFINITY,l=\"boolean\"!=typeof o.useWebWorker||o.useWebWorker,delete o.useWebWorker,o.onProgress=e=>{s=e,\"function\"==typeof f&&f(s)},!(e instanceof Blob||e instanceof CustomFile))return i(new Error(\"The file given is not an instance of Blob or File\"));if(!/^image/.test(e.type))return i(new Error(\"The file given is not an image\"));if(c=\"undefined\"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope,!l||\"function\"!=typeof Worker||c)return compress(e,o).then(function(e){try{return a=e,$If_4.call(this)}catch(e){return i(e)}}.bind(this),i);var u=function(){try{return $If_4.call(this)}catch(e){return i(e)}}.bind(this),$Try_1_Catch=function(t){try{return compress(e,o).then((function(e){try{return a=e,u()}catch(e){return i(e)}}),i)}catch(e){return i(e)}};try{return o.libURL=o.libURL||\"https://cdn.jsdelivr.net/npm/[email protected]/dist/browser-image-compression.js\",compressOnWebWorker(e,o).then((function(e){try{return a=e,u()}catch(e){return $Try_1_Catch()}}),$Try_1_Catch)}catch(e){$Try_1_Catch()}function $If_4(){try{a.name=e.name,a.lastModified=e.lastModified}catch(e){}try{o.preserveExif&&\"image/jpeg\"===e.type&&(!o.fileType||o.fileType&&o.fileType===e.type)&&(a=copyExifWithoutOrientation(e,a))}catch(e){}return r(a)}}))}imageCompression.getDataUrlFromFile=getDataUrlFromFile,imageCompression.getFilefromDataUrl=getFilefromDataUrl,imageCompression.loadImage=loadImage,imageCompression.drawImageInCanvas=drawImageInCanvas,imageCompression.drawFileInCanvas=drawFileInCanvas,imageCompression.canvasToFile=canvasToFile,imageCompression.getExifOrientation=getExifOrientation,imageCompression.handleMaxWidthOrHeight=handleMaxWidthOrHeight,imageCompression.followExifOrientation=followExifOrientation,imageCompression.cleanupCanvasMemory=cleanupCanvasMemory,imageCompression.isAutoOrientationInBrowser=isAutoOrientationInBrowser,imageCompression.approximateBelowMaximumCanvasSizeOfBrowser=approximateBelowMaximumCanvasSizeOfBrowser,imageCompression.copyExifWithoutOrientation=copyExifWithoutOrientation,imageCompression.getBrowserName=getBrowserName,imageCompression.version=\"2.0.2\";\n//# sourceMappingURL=browser-image-compression.mjs.map\n\n\n//# sourceURL=webpack:///./node_modules/browser-image-compression/dist/browser-image-compression.mjs?");
     90
     91/***/ }),
     92
     93/***/ "./node_modules/wasm-feature-detect/dist/esm/index.js":
     94/*!************************************************************!*\
     95  !*** ./node_modules/wasm-feature-detect/dist/esm/index.js ***!
     96  \************************************************************/
     97/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
     98
     99eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"bigInt\": () => (/* binding */ bigInt),\n/* harmony export */   \"bulkMemory\": () => (/* binding */ bulkMemory),\n/* harmony export */   \"exceptions\": () => (/* binding */ exceptions),\n/* harmony export */   \"extendedConst\": () => (/* binding */ extendedConst),\n/* harmony export */   \"gc\": () => (/* binding */ gc),\n/* harmony export */   \"memory64\": () => (/* binding */ memory64),\n/* harmony export */   \"multiValue\": () => (/* binding */ multiValue),\n/* harmony export */   \"mutableGlobals\": () => (/* binding */ mutableGlobals),\n/* harmony export */   \"referenceTypes\": () => (/* binding */ referenceTypes),\n/* harmony export */   \"relaxedSimd\": () => (/* binding */ relaxedSimd),\n/* harmony export */   \"saturatedFloatToInt\": () => (/* binding */ saturatedFloatToInt),\n/* harmony export */   \"signExtensions\": () => (/* binding */ signExtensions),\n/* harmony export */   \"simd\": () => (/* binding */ simd),\n/* harmony export */   \"streamingCompilation\": () => (/* binding */ streamingCompilation),\n/* harmony export */   \"tailCall\": () => (/* binding */ tailCall),\n/* harmony export */   \"threads\": () => (/* binding */ threads)\n/* harmony export */ });\nconst bigInt=()=>(async e=>{try{return(await WebAssembly.instantiate(e)).instance.exports.b(BigInt(0))===BigInt(0)}catch(e){return!1}})(new Uint8Array([0,97,115,109,1,0,0,0,1,6,1,96,1,126,1,126,3,2,1,0,7,5,1,1,98,0,0,10,6,1,4,0,32,0,11])),bulkMemory=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,5,3,1,0,1,10,14,1,12,0,65,0,65,0,65,0,252,10,0,0,11])),exceptions=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,8,1,6,0,6,64,25,11,11])),extendedConst=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,5,3,1,0,1,11,9,1,0,65,1,65,2,106,11,0])),gc=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,10,2,95,1,125,0,96,0,1,107,0,3,2,1,1,10,12,1,10,0,67,0,0,0,0,251,7,0,11])),memory64=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,5,3,1,4,1])),multiValue=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,6,1,96,0,2,127,127,3,2,1,0,10,8,1,6,0,65,0,65,0,11])),mutableGlobals=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,2,8,1,1,97,1,98,3,127,1,6,6,1,127,1,65,0,11,7,5,1,1,97,3,1])),referenceTypes=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,7,1,5,0,208,112,26,11])),relaxedSimd=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,5,1,96,0,1,123,3,2,1,0,10,15,1,13,0,65,1,253,15,65,2,253,15,253,128,2,11])),saturatedFloatToInt=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,12,1,10,0,67,0,0,0,0,252,0,26,11])),signExtensions=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,8,1,6,0,65,0,192,26,11])),simd=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,5,1,96,0,1,123,3,2,1,0,10,10,1,8,0,65,0,253,15,253,98,11])),streamingCompilation=()=>(async()=>\"compileStreaming\"in WebAssembly)(),tailCall=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,6,1,4,0,18,0,11])),threads=()=>(async e=>{try{return\"undefined\"!=typeof MessageChannel&&(new MessageChannel).port1.postMessage(new SharedArrayBuffer(1)),WebAssembly.validate(e)}catch(e){return!1}})(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,5,4,1,3,1,1,10,11,1,9,0,65,0,254,16,2,0,26,11]));\n\n\n//# sourceURL=webpack:///./node_modules/wasm-feature-detect/dist/esm/index.js?");
    50100
    51101/***/ })
     
    93143/******/    })();
    94144/******/   
     145/******/    /* webpack/runtime/ensure chunk */
     146/******/    (() => {
     147/******/        __webpack_require__.f = {};
     148/******/        // This file contains only the entry chunk.
     149/******/        // The chunk loading function for additional chunks
     150/******/        __webpack_require__.e = (chunkId) => {
     151/******/            return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
     152/******/                __webpack_require__.f[key](chunkId, promises);
     153/******/                return promises;
     154/******/            }, []));
     155/******/        };
     156/******/    })();
     157/******/   
    95158/******/    /* webpack/runtime/get javascript chunk filename */
    96159/******/    (() => {
     
    117180/******/    (() => {
    118181/******/        __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
     182/******/    })();
     183/******/   
     184/******/    /* webpack/runtime/load script */
     185/******/    (() => {
     186/******/        var inProgress = {};
     187/******/        // data-webpack is not used as build has no uniqueName
     188/******/        // loadScript function to load a script via script tag
     189/******/        __webpack_require__.l = (url, done, key, chunkId) => {
     190/******/            if(inProgress[url]) { inProgress[url].push(done); return; }
     191/******/            var script, needAttach;
     192/******/            if(key !== undefined) {
     193/******/                var scripts = document.getElementsByTagName("script");
     194/******/                for(var i = 0; i < scripts.length; i++) {
     195/******/                    var s = scripts[i];
     196/******/                    if(s.getAttribute("src") == url) { script = s; break; }
     197/******/                }
     198/******/            }
     199/******/            if(!script) {
     200/******/                needAttach = true;
     201/******/                script = document.createElement('script');
     202/******/       
     203/******/                script.charset = 'utf-8';
     204/******/                script.timeout = 120;
     205/******/                if (__webpack_require__.nc) {
     206/******/                    script.setAttribute("nonce", __webpack_require__.nc);
     207/******/                }
     208/******/       
     209/******/                script.src = url;
     210/******/            }
     211/******/            inProgress[url] = [done];
     212/******/            var onScriptComplete = (prev, event) => {
     213/******/                // avoid mem leaks in IE.
     214/******/                script.onerror = script.onload = null;
     215/******/                clearTimeout(timeout);
     216/******/                var doneFns = inProgress[url];
     217/******/                delete inProgress[url];
     218/******/                script.parentNode && script.parentNode.removeChild(script);
     219/******/                doneFns && doneFns.forEach((fn) => (fn(event)));
     220/******/                if(prev) return prev(event);
     221/******/            }
     222/******/            var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);
     223/******/            script.onerror = onScriptComplete.bind(null, script.onerror);
     224/******/            script.onload = onScriptComplete.bind(null, script.onload);
     225/******/            needAttach && document.head.appendChild(script);
     226/******/        };
    119227/******/    })();
    120228/******/   
     
    161269/******/        };
    162270/******/       
    163 /******/        // no chunk on demand loading
     271/******/        __webpack_require__.f.j = (chunkId, promises) => {
     272/******/                // JSONP chunk loading for javascript
     273/******/                var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
     274/******/                if(installedChunkData !== 0) { // 0 means "already installed".
     275/******/       
     276/******/                    // a Promise means "currently loading".
     277/******/                    if(installedChunkData) {
     278/******/                        promises.push(installedChunkData[2]);
     279/******/                    } else {
     280/******/                        if(true) { // all chunks have JS
     281/******/                            // setup Promise in chunk cache
     282/******/                            var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
     283/******/                            promises.push(installedChunkData[2] = promise);
     284/******/       
     285/******/                            // start chunk loading
     286/******/                            var url = __webpack_require__.p + __webpack_require__.u(chunkId);
     287/******/                            // create error before stack unwound to get useful stacktrace later
     288/******/                            var error = new Error();
     289/******/                            var loadingEnded = (event) => {
     290/******/                                if(__webpack_require__.o(installedChunks, chunkId)) {
     291/******/                                    installedChunkData = installedChunks[chunkId];
     292/******/                                    if(installedChunkData !== 0) installedChunks[chunkId] = undefined;
     293/******/                                    if(installedChunkData) {
     294/******/                                        var errorType = event && (event.type === 'load' ? 'missing' : event.type);
     295/******/                                        var realSrc = event && event.target && event.target.src;
     296/******/                                        error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
     297/******/                                        error.name = 'ChunkLoadError';
     298/******/                                        error.type = errorType;
     299/******/                                        error.request = realSrc;
     300/******/                                        installedChunkData[1](error);
     301/******/                                    }
     302/******/                                }
     303/******/                            };
     304/******/                            __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId);
     305/******/                        } else installedChunks[chunkId] = 0;
     306/******/                    }
     307/******/                }
     308/******/        };
    164309/******/       
    165310/******/        // no prefetching
     
    173318/******/        // no on chunks loaded
    174319/******/       
    175 /******/        // no jsonp function
     320/******/        // install a JSONP callback for chunk loading
     321/******/        var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
     322/******/            var [chunkIds, moreModules, runtime] = data;
     323/******/            // add "moreModules" to the modules object,
     324/******/            // then flag all "chunkIds" as loaded and fire callback
     325/******/            var moduleId, chunkId, i = 0;
     326/******/            if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
     327/******/                for(moduleId in moreModules) {
     328/******/                    if(__webpack_require__.o(moreModules, moduleId)) {
     329/******/                        __webpack_require__.m[moduleId] = moreModules[moduleId];
     330/******/                    }
     331/******/                }
     332/******/                if(runtime) var result = runtime(__webpack_require__);
     333/******/            }
     334/******/            if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
     335/******/            for(;i < chunkIds.length; i++) {
     336/******/                chunkId = chunkIds[i];
     337/******/                if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
     338/******/                    installedChunks[chunkId][0]();
     339/******/                }
     340/******/                installedChunks[chunkId] = 0;
     341/******/            }
     342/******/       
     343/******/        }
     344/******/       
     345/******/        var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || [];
     346/******/        chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
     347/******/        chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
    176348/******/    })();
    177349/******/   
  • squeeze/trunk/assets/js/assets_js_worker_js.bundle.js

    r3311866 r3345284  
    1717/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
    1818
    19 eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _jsquash_avif__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @jsquash/avif */ \"./node_modules/@jsquash/avif/decode.js\");\n/* harmony import */ var _jsquash_avif__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @jsquash/avif */ \"./node_modules/@jsquash/avif/encode.js\");\n/* harmony import */ var _jsquash_webp__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @jsquash/webp */ \"./node_modules/@jsquash/webp/decode.js\");\n/* harmony import */ var _jsquash_webp__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @jsquash/webp */ \"./node_modules/@jsquash/webp/encode.js\");\n/* harmony import */ var _jsquash_jpeg__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @jsquash/jpeg */ \"./node_modules/@jsquash/jpeg/decode.js\");\n/* harmony import */ var _jsquash_jpeg__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @jsquash/jpeg */ \"./node_modules/@jsquash/jpeg/encode.js\");\n/* harmony import */ var _jsquash_png__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @jsquash/png */ \"./node_modules/@jsquash/png/decode.js\");\n/* harmony import */ var _jsquash_png__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @jsquash/png */ \"./node_modules/@jsquash/png/encode.js\");\n/* harmony import */ var _jsquash_resize__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @jsquash/resize */ \"./node_modules/@jsquash/resize/index.js\");\n/* harmony import */ var browser_image_compression__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! browser-image-compression */ \"./node_modules/browser-image-compression/dist/browser-image-compression.mjs\");\n// Description: Web Worker for image compression\r\n\r\n\r\n\r\n\r\n\r\n//import optimise from '@jsquash/oxipng/optimise';\r\n\r\n\r\n\r\n\"use strict\";\r\n\r\nlet options; // plugin options\r\n\r\n/**\r\n   * Decode image buffer and return image data\r\n   * @param {string} sourceType  - avif, jpeg, png, webp\r\n   * @param {object} fileBuffer - The ArrayBuffer object is used to represent a generic raw binary data buffer.\r\n   * @returns {object | Error} - Image data object or throws an Error\r\n   */\r\nconst decode = async (sourceType, fileBuffer) => {\r\n  switch (sourceType) {\r\n    case 'avif':\r\n      return await _jsquash_avif__WEBPACK_IMPORTED_MODULE_1__[\"default\"](fileBuffer);\r\n    case 'jpeg':\r\n      return await _jsquash_jpeg__WEBPACK_IMPORTED_MODULE_2__[\"default\"](fileBuffer);\r\n    case 'png':\r\n      return await _jsquash_png__WEBPACK_IMPORTED_MODULE_3__[\"default\"](fileBuffer);\r\n    case 'webp':\r\n      return await _jsquash_webp__WEBPACK_IMPORTED_MODULE_4__[\"default\"](fileBuffer);\r\n    default:\r\n      throw new Error(`Unknown source type: ${sourceType}`);\r\n  }\r\n}\r\n\r\n/**\r\n * \r\n * @param {string} outputType - avif, jpeg, png, webp \r\n * @param {object} imageData - Image data object after decoding\r\n * @returns {ArrayBuffer | false} - Compressed image buffer or false if error\r\n */\r\nconst encode = async (outputType, imageData) => {\r\n  try {\r\n    switch (outputType) {\r\n      case 'avif':\r\n        const avifOptions = {}\r\n        for (const [key, value] of Object.entries(options)) {\r\n          if (key.includes('avif')) {\r\n            const keyName = key.replace('avif_', '')\r\n            avifOptions[keyName] = value\r\n          }\r\n        }\r\n        return await _jsquash_avif__WEBPACK_IMPORTED_MODULE_5__[\"default\"](imageData, avifOptions);\r\n      case 'jpeg':\r\n        const jpegOptions = {}\r\n        for (const [key, value] of Object.entries(options)) {\r\n          if (key.includes('jpeg')) {\r\n            const keyName = key.replace('jpeg_', '')\r\n            jpegOptions[keyName] = value\r\n          }\r\n        }\r\n        return await _jsquash_jpeg__WEBPACK_IMPORTED_MODULE_6__[\"default\"](imageData, jpegOptions);\r\n      case 'png':\r\n        const pngOptions = {}\r\n        for (const [key, value] of Object.entries(options)) {\r\n          if (key.includes('png')) {\r\n            const keyName = key.replace('png_', '')\r\n            pngOptions[keyName] = value\r\n          }\r\n        }\r\n        return await _jsquash_png__WEBPACK_IMPORTED_MODULE_7__[\"default\"](imageData, pngOptions);\r\n      case 'webp':\r\n        const webpOptions = {}\r\n        for (const [key, value] of Object.entries(options)) {\r\n          if (key.includes('webp')) {\r\n            const keyName = key.replace('webp_', '')\r\n            webpOptions[keyName] = value\r\n          }\r\n        }\r\n        return await _jsquash_webp__WEBPACK_IMPORTED_MODULE_8__[\"default\"](imageData, webpOptions);\r\n      default:\r\n        throw new Error(`Unknown output type: ${outputType}`);\r\n    }\r\n  } catch (error) {\r\n    //console.error(error)\r\n    throw new Error(`Error encoding image: ${error.message}`)\r\n  }\r\n\r\n}\r\n\r\n/**\r\n * Convert image buffer from one format to another\r\n * @param {string} sourceType - avif, jpeg, png, webp\r\n * @param {string} outputType - avif, jpeg, png, webp\r\n * @param {object} fileBuffer - The ArrayBuffer object is used to represent a generic raw binary data buffer.\r\n * @returns {Promise} - Compressed image buffer or false if error\r\n */\r\nconst convert = async (sourceType, outputType, fileBuffer, resizeOptions) => {\r\n  try {\r\n    if (outputType === 'png') { // TBD: https://github.com/jamsinclair/jSquash/tree/main/packages/oxipng#activate-multithreading\r\n\r\n      //fileBuffer = await optimise(fileBuffer, pngOptions);\r\n\r\n      \r\n      return fileBuffer;\r\n\r\n    }\r\n\r\n    const imageData = await decode(sourceType, fileBuffer);\r\n\r\n    \r\n    return encode(outputType, imageData);\r\n  } catch (error) {\r\n    console.error('Error during image processing:', error);\r\n    throw new Error('Failed to process image, check the console for more information.');\r\n  }\r\n}\r\n\r\n/**\r\n * Convert Blob to base64 encoded image string\r\n * @param {object} blob - The Blob object represents a blob, which is a file-like object of immutable, raw data.\r\n * @returns {Promise<string>} - Base64 encoded image string\r\n */\r\nconst blobToBase64 = (blob) => {\r\n  return new Promise((resolve, _) => {\r\n    const reader = new FileReader();\r\n    reader.onloadend = () => resolve(reader.result);\r\n    reader.readAsDataURL(blob);\r\n  });\r\n}\r\n\r\nconst showOutput = async (imageBuffer, outputType) => {\r\n  if (!imageBuffer) {\r\n    return false;\r\n  }\r\n  const imageBlob = new Blob([imageBuffer], { type: `image/${outputType}` });\r\n  const base64String = await blobToBase64(imageBlob);\r\n\r\n  return base64String;\r\n}\r\n\r\nconst fetchImageBuffer = async (url, name, mime, outputType) => {\r\n  const response = await fetch(url);\r\n  if (!response.ok) {\r\n    return false;\r\n  }\r\n\r\n  const blob = await response.blob();\r\n\r\n  if (outputType === 'png') {\r\n    // For PNG, we need to return blob\r\n    return blob;\r\n  }\r\n\r\n  const metadata = {\r\n    type: mime\r\n  }\r\n\r\n  const imageObj = new File([blob], name, metadata);\r\n  const fileBuffer = await imageObj.arrayBuffer();\r\n\r\n  return fileBuffer;\r\n}\r\n\r\n/**\r\n * Compresses a JPEG image.\r\n * @param {Object} params - The parameters for compression.\r\n * @param {string} params.url - The URL of the image.\r\n * @param {string} params.name - The name of the image file.\r\n * @param {string} params.sourceType - The source type of the image.\r\n * @param {string} params.outputType - The desired output type.\r\n * @param {string} params.mime - The MIME type of the image.\r\n * @param {Object} params.resizeOptions - The options for resizing the image.\r\n * @returns {Promise<string>} - The base64 encoded compressed image.\r\n */\r\nconst compressJPEG = async ({ fileBuffer, name, sourceType, outputType, mime, resizeOptions }) => {\r\n  const imageBuffer = await convert(sourceType, outputType, fileBuffer, resizeOptions);\r\n  const base64 = await showOutput(imageBuffer, outputType);\r\n\r\n  return base64;\r\n}\r\n\r\n/**\r\n * Compresses a PNG image.\r\n * @param {Object} params - The parameters for compression.\r\n * @param {string} params.url - The URL of the image.\r\n * @param {Object} params.options - The options for PNG compression.\r\n * @param {string} params.outputType - The desired output type.\r\n * @param {Object} params.resizeOptions - The options for resizing the image.\r\n * @returns {Promise<string>} - The base64 encoded compressed image.\r\n */\r\nconst compressPNG = async ({ imageFile, outputType, resizeOptions }) => {\r\n  const pngOptions = {};\r\n  for (const [key, value] of Object.entries(options)) {\r\n    if (key.includes('png')) {\r\n      const keyName = key.replace('png_', '');\r\n      pngOptions[keyName] = value;\r\n    }\r\n  }\r\n  /*\r\n  const fileBuffer = await fetch(url).then(res => res.arrayBuffer());\r\n  const imageBuffer = await convert(outputType, outputType, fileBuffer, resizeOptions, pngOptions);\r\n  const base64 = await showOutput(imageBuffer, outputType);\r\n\r\n  return base64;\r\n  //*/\r\n  const browserImageCompressionOptions = {\r\n    //maxSizeMB: 0.5,\r\n    maxWidthOrHeight: Number.POSITIVE_INFINITY,\r\n    initialQuality: pngOptions?.quality,\r\n    useWebWorker: false,\r\n  }\r\n  //const imageFile = await fetch(url).then(res => res.blob());\r\n  try {\r\n    const compressedFile = await (0,browser_image_compression__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(imageFile, browserImageCompressionOptions);\r\n    const fileBuffer = await compressedFile.arrayBuffer();\r\n    const imageBuffer = await convert(outputType, outputType, fileBuffer, resizeOptions);\r\n    const base64 = await showOutput(imageBuffer, outputType);\r\n    //const base64 = await blobToBase64(compressedFile);\r\n    return base64;\r\n  } catch (error) {\r\n    console.log(error);\r\n  }\r\n}\r\n\r\n/**\r\n * Compresses a WEBP image.\r\n * @param {Object} params - The parameters for compression.\r\n * @param {string} params.url - The URL of the image.\r\n * @param {string} params.name - The name of the image file.\r\n * @param {string} params.sourceType - The source type of the image.\r\n * @param {string} params.outputType - The desired output type.\r\n * @param {string} params.mime - The MIME type of the image.\r\n * @param {Object} params.resizeOptions - The options for resizing the image.\r\n * @returns {Promise<string>} - The base64 encoded compressed image.\r\n */\r\nconst compressWEBP = async ({ fileBuffer, name, sourceType, outputType, mime, resizeOptions }) => {\r\n\r\n  const imageBuffer = await convert(sourceType, outputType, fileBuffer, resizeOptions);\r\n  const base64 = await showOutput(imageBuffer, outputType);\r\n\r\n  return base64;\r\n}\r\n\r\n/**\r\n * Compresses an AVIF image.\r\n * @param {Object} params - The parameters for compression.\r\n * @param {string} params.url - The URL of the image.\r\n * @param {string} params.name - The name of the image file.\r\n * @param {string} params.sourceType - The source type of the image.\r\n * @param {string} params.outputType - The desired output type.\r\n * @param {string} params.mime - The MIME type of the image.\r\n * @param {Object} params.resizeOptions - The options for resizing the image.\r\n * @returns {Promise<string>} - The base64 encoded compressed image.\r\n */\r\nconst compressAVIF = async ({ fileBuffer, name, sourceType, outputType, mime, resizeOptions }) => {\r\n\r\n  const imageBuffer = await convert(sourceType, outputType, fileBuffer, resizeOptions);\r\n  const base64 = await showOutput(imageBuffer, outputType);\r\n\r\n  return base64;\r\n}\r\n\r\n\r\n\r\nconst compressAndAssign = async (compressFunction, { url, name, sourceType, outputType, mime, isPreview, file }) => {\r\n\r\n  let fileBuffer;\r\n\r\n  if (url) {\r\n    fileBuffer = await fetchImageBuffer(url, name, mime, outputType);\r\n  } else if (file) {\r\n    // If file is provided, use it directly\r\n    const fileObj = new File([file], name, { type: mime });\r\n    fileBuffer = await fileObj.arrayBuffer();\r\n  }\r\n\r\n  if (!fileBuffer || fileBuffer.byteLength === 0) {\r\n    throw new Error(`Fetched image from ${url} is empty.`);\r\n  }\r\n\r\n  const resizeOptions =  {};\r\n  let base64;\r\n\r\n  if (compressFunction === compressPNG) {\r\n    base64 = await compressFunction({ imageFile: fileBuffer, outputType, resizeOptions });\r\n  } else {\r\n    base64 = await compressFunction({ fileBuffer, name, sourceType, outputType, mime, resizeOptions });\r\n  }\r\n\r\n  return base64;\r\n}\r\n\r\nconst compressAndAssignThumbs = async (compressFunction, { name, sourceType, outputType, mime, sizes, isAllSizes = false }, skipFull = false) => {\r\n  const compressThumbs = options.compress_thumbs;\r\n  const base64Sizes = {}\r\n\r\n  if (!sizes) {\r\n    return base64Sizes;\r\n  }\r\n\r\n  for (const [key, value] of Object.entries(sizes)) {\r\n    if (!(key in compressThumbs) && !isAllSizes) {\r\n      continue;\r\n    }\r\n\r\n    if (skipFull && key === 'full') { // skip full size if no scaled image\r\n      continue;\r\n    }\r\n\r\n    const sizeURL = value.url;\r\n    const sizeWidth = value.width;\r\n    const sizeHeight = value.height;\r\n    const sizeName = `${name}-${sizeWidth}x${sizeHeight}`;\r\n    let sizeBase64;\r\n    let fileBuffer;\r\n\r\n    if (sizeURL) {\r\n      fileBuffer = await fetchImageBuffer(sizeURL, name, mime, outputType);\r\n    }\r\n\r\n    if (!fileBuffer || fileBuffer.byteLength === 0) {\r\n      console.warn(`Fetched image from ${sizeURL} is empty.`)\r\n      continue;\r\n    }\r\n\r\n    if (compressFunction === compressPNG) {\r\n      sizeBase64 = await compressFunction({ imageFile: fileBuffer, outputType });\r\n    } else {\r\n      sizeBase64 = await compressFunction({ fileBuffer: fileBuffer, name: sizeName, sourceType, outputType, mime });\r\n    }\r\n\r\n    Object.assign(base64Sizes, { [key]: { 'url': sizeURL, 'base64': sizeBase64 } });\r\n  }\r\n\r\n  return base64Sizes;\r\n}\r\n\r\nonmessage = async function (e) {\r\n  //console.log('Worker: Message received from main script', e.data, );\r\n  const { format, url, name, sourceType, outputType, mime, sizes, skipFull, isPreview, file } = e.data;\r\n  options = e.data.options;\r\n  //console.log(options.max_width, options.max_height, 'max_width max_height');\r\n\r\n  try {\r\n    let base64, base64Sizes, base64Webp, base64SizesWebp;\r\n\r\n    switch (format) {\r\n      case 'avif':\r\n        base64 = await compressAndAssign(compressAVIF, { url, name, sourceType, outputType, mime, isPreview, file });\r\n        base64Sizes = await compressAndAssignThumbs(compressAVIF, { name, sourceType, outputType, mime, sizes }, skipFull);\r\n        break;\r\n      case 'jpeg':\r\n        base64 = await compressAndAssign(compressJPEG, { url, name, sourceType, outputType, mime, isPreview, file });\r\n        base64Sizes = await compressAndAssignThumbs(compressJPEG, { name, sourceType, outputType, mime, sizes }, skipFull);\r\n        \r\n        if (options.auto_webp) {\r\n          base64Webp = await compressAndAssign(compressWEBP, { url, name, sourceType, outputType: 'webp', mime, isPreview, file });\r\n          base64SizesWebp = await compressAndAssignThumbs(compressWEBP, { name, sourceType, outputType: 'webp', mime, sizes, isAllSizes: true }, skipFull);\r\n        }\r\n\r\n        break;\r\n      case 'png':\r\n        base64 = await compressAndAssign(compressPNG, { url, name, sourceType, outputType, mime, isPreview, file });\r\n        base64Sizes = await compressAndAssignThumbs(compressPNG, { name, sourceType, outputType, mime, sizes }, skipFull);\r\n        \r\n        if (options.auto_webp) {\r\n          base64Webp = await compressAndAssign(compressWEBP, { url, name, sourceType, outputType: 'webp', mime, isPreview, file });\r\n          base64SizesWebp = await compressAndAssignThumbs(compressWEBP, { name, sourceType, outputType: 'webp', mime, sizes, isAllSizes: true }, skipFull);\r\n        }\r\n        \r\n        break;\r\n      case 'webp':\r\n        base64 = await compressAndAssign(compressWEBP, { url, name, sourceType, outputType, mime, isPreview, file });\r\n        base64Sizes = await compressAndAssignThumbs(compressWEBP, { name, sourceType, outputType, mime, sizes }, skipFull);\r\n        break;\r\n    }\r\n\r\n    postMessage({\r\n      'base64': base64,\r\n      'base64Sizes': base64Sizes,\r\n      'base64Webp': base64Webp,\r\n      'base64SizesWebp': base64SizesWebp\r\n    });\r\n  } catch (error) {\r\n    console.error(error);\r\n    postMessage({\r\n      'error': error\r\n    });\r\n  }\r\n}\n\n//# sourceURL=webpack:///./assets/js/worker.js?");
     19eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _jsquash_avif__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @jsquash/avif */ \"./node_modules/@jsquash/avif/decode.js\");\n/* harmony import */ var _jsquash_avif__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @jsquash/avif */ \"./node_modules/@jsquash/avif/encode.js\");\n/* harmony import */ var _jsquash_webp__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @jsquash/webp */ \"./node_modules/@jsquash/webp/decode.js\");\n/* harmony import */ var _jsquash_webp__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @jsquash/webp */ \"./node_modules/@jsquash/webp/encode.js\");\n/* harmony import */ var _jsquash_jpeg__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @jsquash/jpeg */ \"./node_modules/@jsquash/jpeg/decode.js\");\n/* harmony import */ var _jsquash_jpeg__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @jsquash/jpeg */ \"./node_modules/@jsquash/jpeg/encode.js\");\n/* harmony import */ var _jsquash_png__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @jsquash/png */ \"./node_modules/@jsquash/png/decode.js\");\n/* harmony import */ var _jsquash_png__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @jsquash/png */ \"./node_modules/@jsquash/png/encode.js\");\n/* harmony import */ var _jsquash_resize__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @jsquash/resize */ \"./node_modules/@jsquash/resize/index.js\");\n// Description: Web Worker for image compression\r\n\r\n\r\n\r\n\r\n\r\n//import optimise from '@jsquash/oxipng/optimise';\r\n\r\n\r\n\"use strict\";\r\n\r\nlet options; // plugin options\r\n\r\n// RPC stands for Remote Procedure Call.\r\n// It’s a fancy name for \"calling a function that runs somewhere else, as if it was local\".\r\n\r\n//This is a MessagePort object used to communicate with the main thread.\r\n//It’s initially null and must be assigned from the outside when the main thread sends it to this worker via postMessage(..., [port]).\r\nlet rpcPort = null;    // will be set when main thread transfers a MessagePort\r\n\r\n//Just a sequential number to ensure that every request has a unique ID, even if multiple requests happen at the same timestamp.\r\nlet rpcCounter = 1;\r\n\r\n// makes unique ID for each RPC call\r\n// example: 1633036800000-abc123-1\r\nfunction makeId() {\r\n  return `${Date.now()}-${Math.random().toString(36).slice(2)}-${rpcCounter++}`;\r\n}\r\n\r\n/**\r\n * Call main thread to run imageCompression(...) there.\r\n * imageCompression function cannot be called directly from the worker. - causing error on mobile\r\n * - fileOrArrayBuffer: Blob or ArrayBuffer\r\n * - mime: e.g. 'image/png' or 'image/jpeg'\r\n * - options: options to pass to imageCompression\r\n * Returns: Promise<ArrayBuffer> (compressed image as ArrayBuffer)\r\n */\r\nfunction compressOnMainThread(fileOrArrayBuffer, mime = 'image/png', options = {}) {\r\n\r\n  //If rpcPort hasn’t been set yet, reject the Promise immediately.\r\n  //This prevents trying to send messages when there’s no communication channel.\r\n  if (!rpcPort) {\r\n    return Promise.reject(new Error('No RPC port available to main thread. Ensure main thread transferred a MessagePort.'));\r\n  }\r\n\r\n  return new Promise((resolve, reject) => {\r\n    const id = makeId();\r\n\r\n    // Listen for messages from the main thread\r\n    function onMsg(ev) {\r\n      const d = ev.data;\r\n      if (!d || d.id !== id) return; // ignores unrelated messages by checking d.id.\r\n      rpcPort.removeEventListener('message', onMsg); // Removes the event listener (avoids memory leaks).\r\n      if (d.ok) resolve(d.arrayBuffer); // Resolves with the compressed image data if d.ok is true.\r\n      else reject(d.error || new Error('Compression failed on main thread')); // Rejects if there was an error.\r\n    }\r\n\r\n    rpcPort.addEventListener('message', onMsg);\r\n\r\n    // In some cases (like MessageChannel in a worker), you must call .start() to begin receiving messages.\r\n    // In others, it’s automatic — hence the try/catch.\r\n    try { rpcPort.start(); } catch (e) { /* start may be no-op */ }\r\n\r\n    // Transfer ArrayBuffer if present for zero-copy\r\n    if (fileOrArrayBuffer instanceof ArrayBuffer) {\r\n      // It’s transferable, meaning ownership moves to the main thread without copying.\r\n      // Faster and memory-efficient.\r\n      rpcPort.postMessage({ id, action: 'imageCompression', fileOrArrayBuffer, mime, options }, [fileOrArrayBuffer]);\r\n    } else {\r\n      // Blob cannot be transferred, post it as-is (main thread will accept)\r\n      rpcPort.postMessage({ id, action: 'imageCompression', fileOrArrayBuffer, mime, options });\r\n    }\r\n  });\r\n}\r\n\r\n/**\r\n * Decode image buffer and return image data\r\n * @param {string} sourceType  - avif, jpeg, png, webp\r\n * @param {object} fileBuffer - The ArrayBuffer object is used to represent a generic raw binary data buffer.\r\n * @returns {object | Error} - Image data object or throws an Error\r\n */\r\nconst decode = async (sourceType, fileBuffer) => {\r\n  switch (sourceType) {\r\n    case 'avif':\r\n      return await _jsquash_avif__WEBPACK_IMPORTED_MODULE_0__[\"default\"](fileBuffer);\r\n    case 'jpeg':\r\n      return await _jsquash_jpeg__WEBPACK_IMPORTED_MODULE_1__[\"default\"](fileBuffer);\r\n    case 'png':\r\n      return await _jsquash_png__WEBPACK_IMPORTED_MODULE_2__[\"default\"](fileBuffer);\r\n    case 'webp':\r\n      return await _jsquash_webp__WEBPACK_IMPORTED_MODULE_3__[\"default\"](fileBuffer);\r\n    default:\r\n      throw new Error(`Unknown source type: ${sourceType}`);\r\n  }\r\n}\r\n\r\n/**\r\n * \r\n * @param {string} outputType - avif, jpeg, png, webp \r\n * @param {object} imageData - Image data object after decoding\r\n * @returns {ArrayBuffer | false} - Compressed image buffer or false if error\r\n */\r\nconst encode = async (outputType, imageData) => {\r\n  try {\r\n    switch (outputType) {\r\n      case 'avif':\r\n        const avifOptions = {}\r\n        for (const [key, value] of Object.entries(options)) {\r\n          if (key.includes('avif')) {\r\n            const keyName = key.replace('avif_', '')\r\n            avifOptions[keyName] = value\r\n          }\r\n        }\r\n        return await _jsquash_avif__WEBPACK_IMPORTED_MODULE_4__[\"default\"](imageData, avifOptions);\r\n      case 'jpeg':\r\n        const jpegOptions = {}\r\n        for (const [key, value] of Object.entries(options)) {\r\n          if (key.includes('jpeg')) {\r\n            const keyName = key.replace('jpeg_', '')\r\n            jpegOptions[keyName] = value\r\n          }\r\n        }\r\n        return await _jsquash_jpeg__WEBPACK_IMPORTED_MODULE_5__[\"default\"](imageData, jpegOptions);\r\n      case 'png':\r\n        const pngOptions = {}\r\n        for (const [key, value] of Object.entries(options)) {\r\n          if (key.includes('png')) {\r\n            const keyName = key.replace('png_', '')\r\n            pngOptions[keyName] = value\r\n          }\r\n        }\r\n        return await _jsquash_png__WEBPACK_IMPORTED_MODULE_6__[\"default\"](imageData, pngOptions);\r\n      case 'webp':\r\n        const webpOptions = {}\r\n        for (const [key, value] of Object.entries(options)) {\r\n          if (key.includes('webp')) {\r\n            const keyName = key.replace('webp_', '')\r\n            webpOptions[keyName] = value\r\n          }\r\n        }\r\n        return await _jsquash_webp__WEBPACK_IMPORTED_MODULE_7__[\"default\"](imageData, webpOptions);\r\n      default:\r\n        throw new Error(`Unknown output type: ${outputType}`);\r\n    }\r\n  } catch (error) {\r\n    //console.error(error)\r\n    throw new Error(`Error encoding image: ${error.message}`)\r\n  }\r\n\r\n}\r\n\r\n/**\r\n * Convert image buffer from one format to another\r\n * @param {string} sourceType - avif, jpeg, png, webp\r\n * @param {string} outputType - avif, jpeg, png, webp\r\n * @param {object} fileBuffer - The ArrayBuffer object is used to represent a generic raw binary data buffer.\r\n * @returns {Promise} - Compressed image buffer or false if error\r\n */\r\nconst convert = async (sourceType, outputType, fileBuffer, resizeOptions) => {\r\n  try {\r\n    //console.log(`Converting from ${sourceType} to ${outputType}`);\r\n    if (outputType === 'png') {\r\n\r\n      \r\n      return fileBuffer;\r\n\r\n    }\r\n\r\n    //*\r\n    if (sourceType === 'jpeg') {\r\n      fileBuffer = await compressOnMainThread(\r\n        fileBuffer,\r\n        'image/jpeg',\r\n        {useWebWorker: true}\r\n      );\r\n    }\r\n    //*/\r\n\r\n    const imageData = await decode(sourceType, fileBuffer);\r\n\r\n    \r\n    return encode(outputType, imageData);\r\n  } catch (error) {\r\n    console.error('Error during image processing:', error);\r\n    throw new Error('Failed to process image, check the console for more information. ' + error);\r\n  }\r\n}\r\n\r\n/**\r\n * Convert Blob to base64 encoded image string\r\n * @param {object} blob - The Blob object represents a blob, which is a file-like object of immutable, raw data.\r\n * @returns {Promise<string>} - Base64 encoded image string\r\n */\r\nconst blobToBase64 = (blob) => {\r\n  return new Promise((resolve, _) => {\r\n    const reader = new FileReader();\r\n    reader.onloadend = () => resolve(reader.result);\r\n    reader.readAsDataURL(blob);\r\n  });\r\n}\r\n\r\nconst showOutput = async (imageBuffer, outputType) => {\r\n  if (!imageBuffer) {\r\n    return false;\r\n  }\r\n  const imageBlob = new Blob([imageBuffer], { type: `image/${outputType}` });\r\n  const base64String = await blobToBase64(imageBlob);\r\n\r\n  return base64String;\r\n}\r\n\r\nconst fetchImageBuffer = async (url, name, mime, outputType) => {\r\n  const response = await fetch(url);\r\n  if (!response.ok) {\r\n    return false;\r\n  }\r\n\r\n  const blob = await response.blob();\r\n\r\n  if (outputType === 'png') {\r\n    // For PNG, we need to return blob\r\n    return blob;\r\n  }\r\n\r\n  const metadata = {\r\n    type: mime\r\n  }\r\n\r\n  const imageObj = new File([blob], name, metadata);\r\n  const fileBuffer = await imageObj.arrayBuffer();\r\n\r\n  return fileBuffer;\r\n}\r\n\r\n/**\r\n * Compresses a JPEG image.\r\n * @param {Object} params - The parameters for compression.\r\n * @param {string} params.sourceType - The source type of the image.\r\n * @param {string} params.outputType - The desired output type.\r\n * @param {Object} params.resizeOptions - The options for resizing the image.\r\n * @returns {Promise<string>} - The base64 encoded compressed image.\r\n */\r\nconst compressJPEG = async ({ fileBuffer, sourceType, outputType, resizeOptions }) => {\r\n  const imageBuffer = await convert(sourceType, outputType, fileBuffer, resizeOptions);\r\n  const base64 = await showOutput(imageBuffer, outputType);\r\n\r\n  return base64;\r\n}\r\n\r\n/**\r\n * Compresses a PNG image.\r\n * @param {Object} params - The parameters for compression.\r\n * @param {string} params.outputType - The desired output type.\r\n * @param {Object} params.resizeOptions - The options for resizing the image.\r\n * @returns {Promise<string>} - The base64 encoded compressed image.\r\n */\r\nconst compressPNG = async ({ fileBuffer, outputType, resizeOptions }) => {\r\n  const pngOptions = {};\r\n  for (const [key, value] of Object.entries(options)) {\r\n    if (key.includes('png')) {\r\n      const keyName = key.replace('png_', '');\r\n      pngOptions[keyName] = value;\r\n    }\r\n  }\r\n  \r\n  const browserImageCompressionOptions = {\r\n    maxSizeMB: Number.POSITIVE_INFINITY,\r\n    maxWidthOrHeight: Number.POSITIVE_INFINITY,\r\n    initialQuality: pngOptions?.quality,\r\n    useWebWorker: true,\r\n  }\r\n\r\n  //if (fileBuffer instanceof ArrayBuffer) { // for thumbnails\r\n    //fileBuffer = new Blob([fileBuffer], { type: 'image/png' });\r\n  //}\r\n\r\n  try {\r\n    // Use main thread to run imageCompression to avoid \"Image\" missing in worker on iOS\r\n    const compressedFileBuffer = await compressOnMainThread(\r\n      fileBuffer,\r\n      'image/png',\r\n      browserImageCompressionOptions\r\n    );\r\n\r\n    const imageBuffer = await convert('png', outputType, compressedFileBuffer, resizeOptions);\r\n    const base64 = await showOutput(imageBuffer, outputType);\r\n    return base64;\r\n  } catch (error) {\r\n    console.error(error);\r\n    throw new Error('Failed to process PNG, check the console for more information.');\r\n  }\r\n}\r\n\r\n/**\r\n * Compresses a WEBP image.\r\n * @param {Object} params - The parameters for compression.\r\n * @param {string} params.sourceType - The source type of the image.\r\n * @param {string} params.outputType - The desired output type.\r\n * @param {Object} params.resizeOptions - The options for resizing the image.\r\n * @returns {Promise<string>} - The base64 encoded compressed image.\r\n */\r\nconst compressWEBP = async ({ fileBuffer, sourceType, outputType, resizeOptions }) => {\r\n\r\n  const imageBuffer = await convert(sourceType, outputType, fileBuffer, resizeOptions);\r\n  const base64 = await showOutput(imageBuffer, outputType);\r\n\r\n  return base64;\r\n}\r\n\r\n/**\r\n * Compresses an AVIF image.\r\n * @param {Object} params - The parameters for compression.\r\n * @param {string} params.sourceType - The source type of the image.\r\n * @param {string} params.outputType - The desired output type.\r\n * @param {Object} params.resizeOptions - The options for resizing the image.\r\n * @returns {Promise<string>} - The base64 encoded compressed image.\r\n */\r\nconst compressAVIF = async ({ fileBuffer, sourceType, outputType, resizeOptions }) => {\r\n\r\n  const imageBuffer = await convert(sourceType, outputType, fileBuffer, resizeOptions);\r\n  const base64 = await showOutput(imageBuffer, outputType);\r\n\r\n  return base64;\r\n}\r\n\r\n\r\n\r\n// get proportional dimensions for thumbnail\r\n// based on original image dimensions and thumbnail size name\r\nconst getThumbnailDimensions = (thumbnailDimensions, originalImageDimensions) => {\r\n  const { width: originalWidth, height: originalHeight } = originalImageDimensions;\r\n  const aspectRatioHeight = originalHeight / originalWidth;\r\n  const aspectRatioWidth = originalWidth / originalHeight;\r\n  let sizeWidth, sizeHeight;\r\n\r\n  thumbnailDimensions.width = thumbnailDimensions.width === 0 ? 9999 : thumbnailDimensions.width;\r\n  thumbnailDimensions.height = thumbnailDimensions.height === 0 ? 9999 : thumbnailDimensions.height;\r\n  \r\n  if (originalWidth > originalHeight) {\r\n    sizeWidth = thumbnailDimensions.width;\r\n    sizeHeight = Math.round((originalHeight / originalWidth) * sizeWidth);\r\n  }\r\n  else {\r\n    sizeHeight = thumbnailDimensions.height;\r\n    sizeWidth = Math.round((originalWidth / originalHeight) * sizeHeight);\r\n  }\r\n\r\n  // Ensure both dimensions are within the max values\r\n  if (sizeWidth > thumbnailDimensions.width) {\r\n    sizeWidth = thumbnailDimensions.width;\r\n    sizeHeight = thumbnailDimensions.width * aspectRatioHeight;\r\n  }\r\n\r\n  if (sizeHeight > thumbnailDimensions.height) {\r\n    sizeHeight = thumbnailDimensions.height;\r\n    sizeWidth = thumbnailDimensions.height / aspectRatioWidth;\r\n  }\r\n  return { width: sizeWidth, height: sizeHeight };\r\n}\r\n\r\nconst getImageDimensions = async (file) => {\r\n  let blob;\r\n  if (file instanceof Blob) {\r\n    blob = file;\r\n  } else if (file instanceof ArrayBuffer) {\r\n    blob = new Blob([file]);\r\n  } else {\r\n    throw new Error('Unsupported file type for getImageDimensions');\r\n  }\r\n  const bitmap = await createImageBitmap(blob);\r\n  return { width: bitmap.width, height: bitmap.height };\r\n}\r\n\r\nconst compressAndAssign = async (compressFunction, { url, name, sourceType, outputType, mime, isPreview, file }) => {\r\n\r\n  //console.log('Compressing image:', name, sourceType, outputType);\r\n\r\n  if (!url && !file) {\r\n    return '';\r\n  }\r\n\r\n  let fileBuffer;\r\n\r\n  if (url) {\r\n    fileBuffer = await fetchImageBuffer(url, name, mime, outputType);\r\n  } else if (file) {\r\n    // If file is provided, use it directly\r\n    fileBuffer = await file.arrayBuffer();\r\n  }\r\n\r\n  if (!fileBuffer || fileBuffer.byteLength === 0) {\r\n    throw new Error(`Fetched image from ${url} is empty.`);\r\n  }\r\n\r\n  const resizeOptions =  {};\r\n  let base64;\r\n\r\n  if (compressFunction === compressPNG) {\r\n    base64 = await compressFunction({ fileBuffer, outputType, resizeOptions });\r\n  } else {\r\n    base64 = await compressFunction({ fileBuffer, sourceType, outputType, resizeOptions, file });\r\n  }\r\n\r\n  return base64;\r\n}\r\n\r\nconst compressAndAssignThumbs = async (compressFunction, { name, sourceType, outputType, mime, sizes, isAllSizes = false, file }, skipFull = false) => {\r\n  const compressThumbs = options.compress_thumbs;\r\n  const base64Sizes = {}\r\n  let imageDimensions;\r\n\r\n  if (!sizes) {\r\n    return base64Sizes;\r\n  }\r\n\r\n  if (file) {\r\n    imageDimensions = await getImageDimensions(file);\r\n  }\r\n\r\n  for (const [key, value] of Object.entries(sizes)) {\r\n    if (!(key in compressThumbs) && !isAllSizes) {\r\n      continue;\r\n    }\r\n\r\n    if (skipFull && key === 'full') { // skip full size if no scaled image\r\n      continue;\r\n    }\r\n\r\n    //console.log('Processing size:', key, value);\r\n\r\n    const sizeURL = value.url;\r\n    const sizeWidth = value.width;\r\n    const sizeHeight = value.height;\r\n    const sizeCrop = value.crop || false;\r\n    let sizeBase64;\r\n    let fileBuffer;\r\n    //const resizeOptions = {};\r\n    const resizeOptions =  {};\r\n\r\n    if (resizeOptions?.needResize) {\r\n      continue;\r\n    }\r\n\r\n    if (sizeURL) {\r\n      fileBuffer = await fetchImageBuffer(sizeURL, name, mime, outputType);\r\n    } else if (file) {\r\n      // this method is used for squeezing thumbnails before generating them, so we need to calculate dimensions based on original image\r\n      const sizeDimensions = getThumbnailDimensions({width: sizeWidth, height: sizeHeight}, imageDimensions);\r\n      //console.log('sizeDimensions', sizeDimensions, sizeWidth, sizeHeight, imageDimensions);\r\n\r\n      // If file is provided, use it directly\r\n      const fileObj = new File([file], name, { type: mime });\r\n      fileBuffer = await fileObj.arrayBuffer();\r\n      resizeOptions['needResize'] = true;\r\n      resizeOptions['fitMethod'] = 'contain';\r\n      resizeOptions['width'] = sizeCrop ? sizeWidth : Math.round(sizeDimensions.width);\r\n      resizeOptions['height'] = sizeCrop ? sizeHeight : Math.round(sizeDimensions.height);\r\n    }\r\n\r\n    if (!fileBuffer || fileBuffer.byteLength === 0) {\r\n      console.warn(`Fetched image from ${sizeURL} is empty.`)\r\n      continue;\r\n    }\r\n\r\n    if (compressFunction === compressPNG) {\r\n      sizeBase64 = await compressFunction({ fileBuffer, outputType, resizeOptions });\r\n    } else {\r\n      sizeBase64 = await compressFunction({ fileBuffer, sourceType, outputType, mime, resizeOptions });\r\n    }\r\n\r\n    Object.assign(base64Sizes, { [key]: { 'url': sizeURL, 'base64': sizeBase64, 'width': resizeOptions['width'] ?? sizeWidth, 'height': resizeOptions['height'] ?? sizeHeight } });\r\n    \r\n  }\r\n\r\n  return base64Sizes;\r\n}\r\n\r\nonmessage = async function (e) {\r\n  if (e.ports && e.ports[0]) {\r\n    rpcPort = e.ports[0];\r\n    try { rpcPort.start(); } catch (err) { /* some browsers require start() */ }\r\n  }\r\n\r\n  const action = e.data.action;\r\n\r\n  if (action === 'compress') {\r\n\r\n    //console.log('Worker: Message received from main script', JSON.stringify(e.data, null, 2));\r\n    const { format, url, name, sourceType, outputType, mime, sizes, skipFull, isPreview, file, base64Compressed, base64WebpCompressed, type } = e.data;\r\n    options = e.data.options;\r\n\r\n    try {\r\n      let base64 = base64Compressed || ''; // base64Compressed is used for already compressed image, e.g. during image upload\r\n      let base64Webp = base64WebpCompressed || '';\r\n      let base64Sizes, base64SizesWebp;\r\n      const base64Args = { url, name, sourceType, outputType, mime, isPreview, file };\r\n      const base64SizesArgs = { name, sourceType, outputType, mime, sizes, file };\r\n\r\n      switch (format) {\r\n        case 'avif':\r\n          base64 = base64 ? base64Compressed : await compressAndAssign(compressAVIF, base64Args);\r\n          base64Sizes = await compressAndAssignThumbs(compressAVIF, base64SizesArgs, skipFull);\r\n          break;\r\n        case 'jpeg':\r\n          if ( options.direct_webp && type !== 'path' ) {\r\n            base64Args.outputType = 'webp';\r\n            base64SizesArgs.outputType = 'webp';\r\n            //base64SizesArgs.isAllSizes = true; // to convert all sizes to webp\r\n            base64 = base64 ? base64Compressed : await compressAndAssign(compressJPEG, base64Args);\r\n            base64Sizes = await compressAndAssignThumbs(compressJPEG, base64SizesArgs, skipFull);\r\n          } else {\r\n            base64 = base64 ? base64Compressed : await compressAndAssign(compressJPEG, base64Args); // take compressed image if available (e.g. during image upload)\r\n            base64Sizes = await compressAndAssignThumbs(compressJPEG, base64SizesArgs, skipFull);\r\n\r\n            if (options.auto_webp) {\r\n              base64Args.outputType = 'webp';\r\n              base64SizesArgs.outputType = 'webp';\r\n              base64SizesArgs.isAllSizes = true; // to convert all sizes to webp\r\n              base64Webp = base64Webp ? base64WebpCompressed : await compressAndAssign(compressJPEG, base64Args);\r\n              base64SizesWebp = await compressAndAssignThumbs(compressJPEG, base64SizesArgs, skipFull);\r\n            }\r\n          }\r\n\r\n          break;\r\n        case 'png':\r\n          if ( options.direct_webp && type !== 'path' ) {\r\n            base64Args.outputType = 'webp';\r\n            base64SizesArgs.outputType = 'webp';\r\n            //base64SizesArgs.isAllSizes = true; // to compress all sizes to webp\r\n            base64 = base64 ? base64Compressed : await compressAndAssign(compressPNG, base64Args);\r\n            base64Sizes = await compressAndAssignThumbs(compressPNG, base64SizesArgs, skipFull);\r\n          } else {\r\n            base64 = base64 ? base64Compressed : await compressAndAssign(compressPNG, base64Args); // take compressed image if available (e.g. during image upload)\r\n            base64Sizes = await compressAndAssignThumbs(compressPNG, base64SizesArgs, skipFull);\r\n\r\n            if (options.auto_webp) {\r\n              base64Args.outputType = 'webp';\r\n              base64SizesArgs.outputType = 'webp';\r\n              base64SizesArgs.isAllSizes = true; // to compress all sizes to webp\r\n              base64Webp = base64Webp ? base64WebpCompressed : await compressAndAssign(compressPNG, base64Args);\r\n              base64SizesWebp = await compressAndAssignThumbs(compressPNG, base64SizesArgs, skipFull);\r\n            }\r\n          }\r\n          \r\n          break;\r\n        case 'webp':\r\n          base64 = base64 ? base64Compressed : await compressAndAssign(compressWEBP, base64Args);\r\n          base64Sizes = await compressAndAssignThumbs(compressWEBP, base64SizesArgs, skipFull);\r\n          break;\r\n      }\r\n\r\n      postMessage({\r\n        'base64': base64,\r\n        'base64Sizes': base64Sizes,\r\n        'base64Webp': base64Webp,\r\n        'base64SizesWebp': base64SizesWebp,\r\n        'isDirectWebp': options.direct_webp,\r\n      });\r\n    } catch (error) {\r\n      console.error(error);\r\n      postMessage({\r\n        'error': error\r\n      });\r\n    }\r\n  }\r\n}\n\n//# sourceURL=webpack:///./assets/js/worker.js?");
    2020
    2121/***/ })
     
    5454/******/        // Load entry module and return exports
    5555/******/        // This entry module depends on other loaded chunks and execution need to be delayed
    56 /******/        var __webpack_exports__ = __webpack_require__.O(undefined, ["vendors-node_modules_jsquash_avif_decode_js-node_modules_jsquash_avif_encode_js-node_modules_-515c76"], () => (__webpack_require__("./assets/js/worker.js")))
     56/******/        var __webpack_exports__ = __webpack_require__.O(undefined, ["vendors-node_modules_jsquash_avif_decode_js-node_modules_jsquash_avif_encode_js-node_modules_-88b2ac"], () => (__webpack_require__("./assets/js/worker.js")))
    5757/******/        __webpack_exports__ = __webpack_require__.O(__webpack_exports__);
    5858/******/        return __webpack_exports__;
     
    219219/******/        var next = __webpack_require__.x;
    220220/******/        __webpack_require__.x = () => {
    221 /******/            return __webpack_require__.e("vendors-node_modules_jsquash_avif_decode_js-node_modules_jsquash_avif_encode_js-node_modules_-515c76").then(next);
     221/******/            return __webpack_require__.e("vendors-node_modules_jsquash_avif_decode_js-node_modules_jsquash_avif_encode_js-node_modules_-88b2ac").then(next);
    222222/******/        };
    223223/******/    })();
  • squeeze/trunk/assets/js/editor.bundle.js

    r3311866 r3345284  
    1717/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
    1818
    19 eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _squeeze_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./squeeze.js */ \"./assets/js/squeeze.js\");\n/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./helpers.js */ \"./assets/js/helpers.js\");\n/* harmony import */ var _handlers_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./handlers.js */ \"./assets/js/handlers.js\");\n\r\n\r\n\r\n\r\n\"use strict\";\r\n\r\nconst { sprintf, __ } = wp.i18n; // Import __() from wp.i18n\r\n\r\nconst Squeeze = new _squeeze_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"](squeezeOptions);\r\nconst compressOptions = JSON.parse(squeezeOptions.options);\r\n\r\nconst addFilter = wp.hooks.addFilter;\r\nconst createHigherOrderComponent = wp.compose.createHigherOrderComponent;\r\nconst { createElement: el, Fragment } = wp.element;\r\n\r\n// import Spinner component\r\nconst { Spinner } = wp.components;\r\n\r\nasync function handleCompressOnUpload(media) {\r\n  const fileSubType = media.mime_type.split('/')[1];\r\n\r\n  if (_helpers_js__WEBPACK_IMPORTED_MODULE_1__.maybeCompressAttachment(media.media_type, fileSubType, compressOptions)) {\r\n    console.log('Compressing image:', media.id, media.source_url);\r\n    window.onbeforeunload = _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleOnLeave;\r\n\r\n    try {\r\n      const attachmentResponse = await Squeeze.getAttachment(media.id);\r\n      if (attachmentResponse.success === false) {\r\n        window.onbeforeunload = null;\r\n        console.error(sprintf(__('Error fetching attachment: %s', 'squeeze'), attachmentResponse.data));\r\n        return;\r\n      }\r\n      //console.log('Attachment data:', attachmentResponse);\r\n      const attachmentData = attachmentResponse.data;\r\n\r\n      if (attachmentData.is_squeezed) {\r\n        console.log('Image already compressed:', attachmentData.id);\r\n        window.onbeforeunload = null;\r\n        return;\r\n      }\r\n\r\n      const attachment = {\r\n        attributes: {\r\n          url: attachmentData.url,\r\n          mime: attachmentData.mime,\r\n          name: attachmentData.name,\r\n          filename: attachmentData.filename,\r\n          id: attachmentData.id,\r\n          sizes: attachmentData.sizes,\r\n        }\r\n      }\r\n      const compressData = await Squeeze.handleCompress(attachment);\r\n      const uploadData = await Squeeze.handleUpload({ attachment, base64: compressData });\r\n\r\n      if (uploadData.success) {\r\n        console.log('Image uploaded successfully:', uploadData);\r\n        window.onbeforeunload = null;\r\n      } else {\r\n        window.onbeforeunload = null;\r\n        console.error(sprintf(__('Error uploading image: %s', 'squeeze'), uploadData.data));\r\n      }\r\n    } catch (error) {\r\n      console.error(error);\r\n      window.onbeforeunload = null;\r\n    }\r\n  }\r\n}\r\n\r\n// Add custom attribute to core/image block\r\nwp.hooks.addFilter(\r\n  'blocks.registerBlockType',\r\n  'my-namespace/add-compressing-attribute',\r\n  (settings, name) => {\r\n    if (name === 'core/image') {\r\n      return {\r\n        ...settings,\r\n        attributes: {\r\n          ...settings.attributes,\r\n          isSqueezing: {\r\n            type: 'boolean',\r\n            default: false,\r\n          },\r\n        },\r\n      };\r\n    }\r\n    return settings;\r\n  }\r\n);\r\n\r\nconst withImageOnSelect = createHigherOrderComponent(\r\n  function (BlockEdit) {\r\n    return function (props) {\r\n      const { attributes } = props;\r\n      // Only target the core/image block\r\n      if (props.name !== 'core/image') {\r\n        // If not the core/image block, return the original BlockEdit\r\n        return el(BlockEdit, props);\r\n      }\r\n\r\n      const { isSqueezing } = attributes;\r\n\r\n      // While compressing, render the original editor plus a Spinner overlay\r\n      if (isSqueezing) {\r\n        //console.log('withImageOnSelect', props);\r\n\r\n        return el(\r\n          Fragment,\r\n          {},\r\n          // The normal block edit, dimmed\r\n          el(\r\n            'div',\r\n            { style: { position: 'relative' } },\r\n            el(BlockEdit, props),\r\n            el(\r\n              'div',\r\n              { style: { position: 'absolute', backgroundColor: 'rgba(255,255,255,0.5)', pointerEvents: 'none', width: '100%', height: '100%', left: '0%', top: '0%' } },\r\n            ),\r\n            // Spinner absolutely centered\r\n            el(\r\n              'div',\r\n              {\r\n                style: {\r\n                  position: 'absolute',\r\n                  top: '50%',\r\n                  left: '50%',\r\n                  transform: 'translate(-50%, -50%)',\r\n                  pointerEvents: 'none',\r\n                },\r\n              },\r\n              el(Spinner, { size: 50 }),\r\n              __('Squeezing image…', 'squeeze')\r\n            )\r\n          ),\r\n\r\n        );\r\n      }\r\n\r\n      return el(BlockEdit, props);\r\n\r\n    };\r\n  },\r\n  'withImageOnSelect'\r\n);\r\n\r\n// Inject our HOC into Gutenberg’s BlockEdit pipeline\r\naddFilter(\r\n  'editor.BlockEdit',\r\n  'myplugin/with-image-onselect',\r\n  withImageOnSelect\r\n);\r\n\r\nwp.domReady(function () {\r\n  wp.apiFetch.use(function (options, next) {\r\n    //console.log('API Request:', options);  // Log all requests\r\n    const result = next(options);\r\n    if (options.path && options.path.startsWith('/wp/v2/media') && options.method === 'POST') {\r\n      result.then(function (response) {\r\n        if (response && response.id && response.media_type === 'image') {\r\n          const mediaId = response.id;\r\n          setTimeout(() => {\r\n            const blocks = wp.data.select('core/block-editor').getBlocks();\r\n            blocks.forEach(block => { // TBD: add support for multiple images upload (gallery block)\r\n              if (block.name === 'core/image' && block.attributes.id === mediaId) {\r\n                wp.data.dispatch('core/block-editor').updateBlockAttributes(block.clientId, { isSqueezing: true });\r\n                handleCompressOnUpload(response).then(() => {\r\n                  wp.data.dispatch('core/block-editor').updateBlockAttributes(block.clientId, { isSqueezing: false });\r\n                });\r\n              }\r\n            });\r\n          }, 100); // Delay to ensure block attributes are updated\r\n        }\r\n      });\r\n    }\r\n    return result;\r\n  });\r\n});\n\n//# sourceURL=webpack:///./assets/js/editor.js?");
     19eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _squeeze_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./squeeze.js */ \"./assets/js/squeeze.js\");\n/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./helpers.js */ \"./assets/js/helpers.js\");\n/* harmony import */ var _handlers_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./handlers.js */ \"./assets/js/handlers.js\");\n\r\n\r\n\r\n\r\n\"use strict\";\r\n\r\nconst { sprintf, __ } = wp.i18n; // Import __() from wp.i18n\r\n\r\nconst Squeeze = new _squeeze_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"](squeezeOptions);\r\nconst compressOptions = JSON.parse(squeezeOptions.options);\r\n\r\nconst addFilter = wp.hooks.addFilter;\r\nconst createHigherOrderComponent = wp.compose.createHigherOrderComponent;\r\nconst { createElement: el, Fragment } = wp.element;\r\n\r\n// import Spinner component\r\nconst { Spinner } = wp.components;\r\n\r\n// Add custom attribute to core/image and generateblocks/media blocks\r\nwp.hooks.addFilter(\r\n  'blocks.registerBlockType',\r\n  'squeeze/add-compressing-attribute',\r\n  (settings, name) => {\r\n    if (name === 'core/image' || name === 'generateblocks/media') {\r\n      return {\r\n        ...settings,\r\n        attributes: {\r\n          ...settings.attributes,\r\n          isSqueezing: {\r\n            type: 'boolean',\r\n            default: false,\r\n          },\r\n        },\r\n      };\r\n    }\r\n    return settings;\r\n  }\r\n);\r\n\r\nconst withImageOnSelect = createHigherOrderComponent(\r\n  function (BlockEdit) {\r\n    return function (props) {\r\n      const { attributes } = props;\r\n      // Only target the core/image block\r\n      if (props.name !== 'core/image' && props.name !== 'generateblocks/media') {\r\n        // If not the core/image block, return the original BlockEdit\r\n        return el(BlockEdit, props);\r\n      }\r\n\r\n      const { isSqueezing } = attributes;\r\n\r\n      // While compressing, render the original editor plus a Spinner overlay\r\n      if (isSqueezing) {\r\n\r\n        return el(\r\n          Fragment,\r\n          {},\r\n          // The normal block edit, dimmed\r\n          el(\r\n            'div',\r\n            { style: { position: 'relative' } },\r\n            el(BlockEdit, props),\r\n            el(\r\n              'div',\r\n              { style: { position: 'absolute', backgroundColor: 'rgba(255,255,255,0.5)', pointerEvents: 'none', width: '100%', height: '100%', left: '0%', top: '0%' } },\r\n            ),\r\n            // Spinner absolutely centered\r\n            el(\r\n              'div',\r\n              {\r\n                style: {\r\n                  position: 'absolute',\r\n                  top: '50%',\r\n                  left: '50%',\r\n                  transform: 'translate(-50%, -50%)',\r\n                  pointerEvents: 'none',\r\n                },\r\n              },\r\n              el(Spinner, { size: 50 }),\r\n              __('Squeezing image…', 'squeeze')\r\n            )\r\n          ),\r\n\r\n        );\r\n      }\r\n\r\n      return el(BlockEdit, props);\r\n\r\n    };\r\n  },\r\n  'withImageOnSelect'\r\n);\r\n\r\n// Inject our HOC into Gutenberg’s BlockEdit pipeline\r\naddFilter(\r\n  'editor.BlockEdit',\r\n  'squeeze/with-image-onselect',\r\n  withImageOnSelect\r\n);\r\n\r\n/**\r\n * Handles the compression of thumbnails after the image has been uploaded.\r\n * This function checks if the file is an image, determines if it should be compressed,\r\n * fetches the attachment data, and then compresses and uploads the image.\r\n * It also handles the original file and WebP conversion if specified in the options.\r\n * @param {object} file - The file attachment object.\r\n * @returns {Promise<void>}\r\n */\r\nasync function handleCompressThumbs(file) {\r\n  const fileType = file.mime_type.split('/')[0];\r\n  const fileSubType = file.mime_type.split('/')[1];\r\n\r\n  if (!_helpers_js__WEBPACK_IMPORTED_MODULE_1__.maybeCompressAttachment(fileType, fileSubType, compressOptions)) {\r\n    return;\r\n  }\r\n\r\n  //console.log('Compressing image:', file.id, file.source_url);\r\n  window.onbeforeunload = _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleOnLeave;\r\n\r\n  try {\r\n    const attachmentResponse = await Squeeze.getAttachment(file.id);\r\n\r\n    if (attachmentResponse.success === false) {\r\n      window.onbeforeunload = null;\r\n      console.error(sprintf(__('Error fetching attachment: %s', 'squeeze'), attachmentResponse.data));\r\n      return;\r\n    }\r\n\r\n    const attachmentData = attachmentResponse.data;\r\n\r\n    if (attachmentData.is_squeezed) {\r\n      console.warn('Image already compressed:', attachmentData.id);\r\n      window.onbeforeunload = null;\r\n      return;\r\n    }\r\n\r\n    const attachment = {\r\n      attributes: {\r\n        url: attachmentData.url,\r\n        mime: attachmentData.mime,\r\n        name: attachmentData.name,\r\n        filename: attachmentData.filename,\r\n        id: attachmentData.id,\r\n        sizes: attachmentData.sizes,\r\n      }\r\n    }\r\n\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_1__.extendAttachment(attachment, file);\r\n\r\n    const compressData = await Squeeze.handleCompress(attachment);\r\n    const uploadData = await Squeeze.handleUpload({ attachment, base64: compressData });\r\n\r\n    if (uploadData.success) {\r\n      //console.log('Image uploaded successfully:', uploadData);\r\n      window.onbeforeunload = null;\r\n    } else {\r\n      window.onbeforeunload = null;\r\n      console.error(sprintf(__('Error uploading image: %s', 'squeeze'), uploadData.data));\r\n    }\r\n  } catch (error) {\r\n    console.error(error);\r\n    window.onbeforeunload = null;\r\n  }\r\n}\r\n\r\n/**\r\n * Walk through all blocks and compress thumbnails for the given media ID.\r\n * This function checks if the block or any of its inner blocks matches the media ID,\r\n * and if so, it compresses the thumbnails using handleCompressThumbs.\r\n * @param {integer} mediaId - The ID of the media item to compress.\r\n * @param {object} response - The response object containing the media data.\r\n * @returns {Promise<void>}\r\n */\r\nfunction squeezeAndUpdateThumbs(mediaId, response) {\r\n  //console.log('squeezeAndUpdateThumbs', mediaId, response);\r\n  return new Promise((resolve) => {\r\n    setTimeout(() => {\r\n      const blocks = wp.data.select('core/block-editor').getBlocks();\r\n      // collect all handleCompressThumbs() calls\r\n      const all = blocks.map(block => {\r\n        // Check if the block or any of its innerBlocks matches the mediaId\r\n        const matchesMedia = (block.attributes.id === mediaId) || (block.attributes.mediaId === mediaId);\r\n\r\n        // Helper to recursively check innerBlocks\r\n        function hasMatchingInnerBlock(innerBlocks) {\r\n          if (!innerBlocks || !innerBlocks.length) return false;\r\n          return innerBlocks.some(innerBlock => {\r\n            if (\r\n              innerBlock.attributes.id === mediaId ||\r\n              innerBlock.attributes.mediaId === mediaId\r\n            ) {\r\n              return true;\r\n            }\r\n            return hasMatchingInnerBlock(innerBlock.innerBlocks);\r\n          });\r\n        }\r\n\r\n        const isMatchingInnerBlock = hasMatchingInnerBlock(block.innerBlocks);\r\n\r\n        if (!matchesMedia && !isMatchingInnerBlock) {\r\n          return null;\r\n        }\r\n\r\n        // mark squeezing start\r\n        if (isMatchingInnerBlock) {\r\n          block.innerBlocks.forEach(innerBlock => {\r\n            if (innerBlock.attributes.id === mediaId || innerBlock.attributes.mediaId === mediaId) {\r\n               wp.data.dispatch('core/block-editor').updateBlockAttributes(innerBlock.clientId, { isSqueezing: true });\r\n            }\r\n          });\r\n        } else {\r\n          wp.data.dispatch('core/block-editor')\r\n            .updateBlockAttributes(block.clientId, { isSqueezing: true });\r\n        }\r\n        // compress, then mark squeezing end\r\n        return handleCompressThumbs(response)\r\n          .then(() => {\r\n            if (isMatchingInnerBlock) {\r\n              block.innerBlocks.forEach(innerBlock => {\r\n                if (innerBlock.attributes.id === mediaId || innerBlock.attributes.mediaId === mediaId) {\r\n                  wp.data.dispatch('core/block-editor').updateBlockAttributes(innerBlock.clientId, { isSqueezing: false });\r\n                }\r\n              });\r\n            } else {\r\n              wp.data.dispatch('core/block-editor')\r\n                .updateBlockAttributes(block.clientId, { isSqueezing: false });\r\n            }\r\n          });\r\n      }).filter(p => p); // remove nulls\r\n      \r\n      // when all compress‐promises settle (or immediately, if none)\r\n      Promise.all(all).then(() => {\r\n        resolve();\r\n      });\r\n    }, 100); // ensure attributes are ready\r\n  });\r\n}\r\n\r\n// Compress the original before upload and thumbnails after upload\r\nwp.domReady(function () {\r\n  // Middleware to intercept and modify the upload request\r\n  wp.apiFetch.use(async (options, next) => {\r\n    if (options.method === 'POST' && options.path.startsWith('/wp/v2/media')) {\r\n\r\n      const formData = options.body;\r\n\r\n      if (!(formData instanceof FormData) || !formData.has('file')) {\r\n        return next(options);\r\n      }\r\n\r\n      const file = formData.get('file');\r\n\r\n      if (file && !file.type.startsWith('image/')) {\r\n        //console.log('Not an image file:', file);\r\n        return next(options); // Proceed without modification\r\n      }\r\n\r\n      const fileType = file.type.split('/')[0];\r\n      const fileSubType = file.type.split('/')[1];\r\n      let originalFile = file;\r\n\r\n      if (!_helpers_js__WEBPACK_IMPORTED_MODULE_1__.maybeCompressAttachment(fileType, fileSubType, compressOptions)) {\r\n        //console.log('Compression not needed for:', file.name);\r\n        return next(options); // Proceed without modification\r\n      }\r\n\r\n      \r\n\r\n      const noticeId = 'compression-notice';\r\n      // Show compression notice\r\n      wp.data.dispatch('core/notices').createNotice(\r\n        'info',\r\n        __('Squeezing the image...', 'squeeze'),\r\n        { id: noticeId, isDismissible: false }\r\n      )\r\n\r\n      try {\r\n        //console.time('Compressing image:', file.name);\r\n        window.onbeforeunload = _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleOnLeave;\r\n\r\n        // Compress the file\r\n        //console.log('Compressing image:', file.name, file.size, file.type);\r\n        const base64Obj = await Squeeze.compressBeforeUpload(file);\r\n        if (!base64Obj || !base64Obj.base64) {\r\n          console.warn('Compression skipped or failed for:', file.name, base64Obj);\r\n          return next(options); // Proceed without modification\r\n        }\r\n\r\n        if (compressOptions.backup_original) {\r\n          //console.log('Backing up original file:', file.name);\r\n          const originalBlob = file instanceof Blob ? file : new Blob([file], { type: file.type });\r\n          const isDirectWebp = compressOptions?.direct_webp && file.type !== 'image/webp';\r\n          // If direct WebP conversion is enabled, convert the original file to WebP\r\n          originalFile = isDirectWebp ? await Squeeze.convertFileToWebp(originalBlob) : originalBlob; // Use the original file from the attachment\r\n        }\r\n\r\n        const newFormData = new FormData();\r\n        const imageBlob = _helpers_js__WEBPACK_IMPORTED_MODULE_1__.base64ToBlob(base64Obj.base64, file.type);\r\n\r\n        newFormData.append('file', imageBlob, file.name);\r\n\r\n        // Preserve other FormData fields (e.g., title, alt)\r\n        for (const [key, value] of options.body.entries()) {\r\n          if (key !== 'file') {\r\n            newFormData.append(key, value);\r\n          }\r\n        }\r\n\r\n        //console.log('New FormData:', newFormData);\r\n\r\n        options.body = newFormData;\r\n\r\n        const response = await next(options);\r\n\r\n        if (response && response.id && response.media_type === 'image') {\r\n          \r\n          response.base64 = base64Obj.base64; // Add the base64 data to the response\r\n          response.base64Webp = base64Obj?.base64Webp; // Add the WebP base64 data to the response\r\n          if (compressOptions.backup_original) {\r\n            response.originalFile = originalFile; // Add the original file to the response\r\n          }\r\n\r\n          const mediaId = response.id;\r\n          squeezeAndUpdateThumbs(mediaId, response)\r\n            .then(() => {\r\n              // Dismiss the compression notice\r\n              wp.data.dispatch('core/notices').removeNotice('compression-notice');\r\n              window.onbeforeunload = null;\r\n              //console.timeEnd('Compressing image:', file.name);\r\n            })\r\n            .catch(error => {\r\n              console.error('Error during squeeze and update:', error);\r\n              // Show error notice\r\n              wp.data.dispatch('core/notices').createNotice(\r\n                'error',\r\n                sprintf(__('Error squeezing the image: %s', 'squeeze'), error.message),\r\n                { id: noticeId, isDismissible: true }\r\n              );\r\n              window.onbeforeunload = null;\r\n            });\r\n\r\n        }\r\n\r\n        return response; // Return the modified response\r\n\r\n      } catch (error) {\r\n        wp.data.dispatch('core/notices').removeNotice('compression-notice');\r\n        console.error('Error during image compression:', error);\r\n        // Show error notice\r\n        wp.data.dispatch('core/notices').createNotice(\r\n          'error',\r\n          sprintf(__('Error squeezing the image: %s', 'squeeze'), error?.message || error),\r\n          { id: noticeId, isDismissible: true }\r\n        );\r\n        window.onbeforeunload = null;\r\n        return next(options); // Proceed without modification\r\n      }\r\n    }\r\n\r\n    return next(options);\r\n\r\n  });\r\n});\n\n//# sourceURL=webpack:///./assets/js/editor.js?");
    2020
    2121/***/ }),
     
    2727/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
    2828
    29 eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"handleBulkButtonClick\": () => (/* binding */ handleBulkButtonClick),\n/* harmony export */   \"handleBulkFromPage\": () => (/* binding */ handleBulkFromPage),\n/* harmony export */   \"handleBulkToggle\": () => (/* binding */ handleBulkToggle),\n/* harmony export */   \"handleButtonsClick\": () => (/* binding */ handleButtonsClick),\n/* harmony export */   \"handleClosePathDialog\": () => (/* binding */ handleClosePathDialog),\n/* harmony export */   \"handleDirectoryCheck\": () => (/* binding */ handleDirectoryCheck),\n/* harmony export */   \"handleDirectoryClick\": () => (/* binding */ handleDirectoryClick),\n/* harmony export */   \"handleFetchImagesFromPage\": () => (/* binding */ handleFetchImagesFromPage),\n/* harmony export */   \"handleMultiFileFormUpload\": () => (/* binding */ handleMultiFileFormUpload),\n/* harmony export */   \"handleOnLeave\": () => (/* binding */ handleOnLeave),\n/* harmony export */   \"handleRecursiveUpload\": () => (/* binding */ handleRecursiveUpload),\n/* harmony export */   \"handleRestoreBtnClick\": () => (/* binding */ handleRestoreBtnClick),\n/* harmony export */   \"handleSingleBtnClick\": () => (/* binding */ handleSingleBtnClick)\n/* harmony export */ });\n/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./helpers.js */ \"./assets/js/helpers.js\");\n/* harmony import */ var _squeeze_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./squeeze.js */ \"./assets/js/squeeze.js\");\n\r\n\r\n\r\n\r\n\r\n\r\nconst { __ } = wp.i18n; // Import __() from wp.i18n\r\nconst Squeeze = new _squeeze_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"](squeezeOptions);\r\n\r\nconst updateUI = (initId, response) => {\r\n  const statusEl = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.postsFilterForm?.querySelector(`#post-${initId} .column-squeeze .squeeze_status`);\r\n  if (statusEl) statusEl.innerHTML = response.data;\r\n\r\n  const gridItem = document.querySelector(`.media-frame.mode-grid .attachment[data-id=\"${initId}\"]`);\r\n  if (gridItem) {\r\n    const centered = gridItem.querySelector('.centered');\r\n    const progress = gridItem.querySelector('.media-progress-bar');\r\n    if (centered) centered.style.display = 'block';\r\n    if (progress) progress.remove();\r\n    gridItem.classList.remove('uploading');\r\n  }\r\n};\r\n\r\nconst getTotalPages = (path) => {\r\n  const selectors = {\r\n    uncompressed: \"input[name='squeeze_bulk_uncompressed_pages']\",\r\n    all: \"input[name='squeeze_bulk_total_pages']\"\r\n  };\r\n  const sel = selectors[path];\r\n  const val = sel && document.querySelector(sel)?.value;\r\n  return Number(val) || 1;\r\n};\r\n\r\nconst checkPaused = (data, page) => {\r\n  if (!_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.isPaused) return false;\r\n  handleBulkPause(data, page);\r\n  return true;\r\n};\r\n\r\nconst logAndThumbnail = async (filename, response, wrapper) => {\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(response.data, {\r\n    mediaLogWrapper: wrapper,\r\n    iconId: response.success ? 'check-mark-circle-icon' : 'ban-sign-icon'\r\n  });\r\n\r\n  const titleEl = wrapper.querySelector('h3');\r\n  if (titleEl && response.filename) {\r\n    titleEl.textContent = `${__('Media', 'squeeze')} ${filename} (${response.filename}):`;\r\n  }\r\n\r\n  const thumbUrl = response.sizes?.thumbnail?.url || response.url;\r\n  if (thumbUrl) {\r\n    const thumb = document.createElement('div');\r\n    thumb.classList.add('media-log-thumbnail');\r\n    thumb.innerHTML = `<img src=\"${thumbUrl}\" alt=\"${filename}\"/>`;\r\n    wrapper.appendChild(thumb);\r\n  }\r\n};\r\n\r\nconst handleDirectoryCheck = (event) => {\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.savePathBtn.disabled = !_helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.dirContainer.querySelector(\"input[type='checkbox']:checked\");\r\n};\r\n\r\nconst handleClosePathDialog = (event) => {\r\n  if (!event.target.contains(_helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.pathDialog)) return;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.pathDialog.close();\r\n};\r\n\r\nconst handleBulkToggle = (event, process, mediaIDs, page = 1) => {\r\n  const isPaused = event.target.dataset.running === 'true';\r\n\r\n  event.target.dataset.running = isPaused ? 'false' : 'true';\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.updateButtonText(event.target, isPaused ? __('Resume bulk squeezing', 'squeeze') : __('Pause bulk squeezing', 'squeeze'), isPaused ? '#play-button-round-icon' : '#pause-button-icon');\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.isPaused = isPaused;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.process = process;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs = mediaIDs;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page = page;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.target = event.target;\r\n\r\n  console.log('handleBulkToggle', _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData);\r\n\r\n  return isPaused;\r\n};\r\n\r\n// Handle single compress button click\r\n// manually pass Squeeze, because of the dynamic options update in the Preview Mode\r\nconst handleSingleBtnClick = async (event, Squeeze) => {\r\n  const attachmentID = event.target.dataset.attachment;\r\n  const squeezeStatus = event.target.closest(\"td\").querySelector(\".squeeze_status\");\r\n\r\n  try {\r\n    wp.media.attachment(attachmentID).fetch().then(async (data) => {\r\n      const attachment = { attributes: data };\r\n\r\n      try {\r\n        const compressData = await Squeeze.handleCompress(attachment);\r\n        const response = await Squeeze.handleUpload({ attachment, base64: compressData });\r\n\r\n        //squeezeStatus.innerHTML = response?.data?.message ?? response;\r\n        squeezeStatus.innerHTML = response?.data ?? response;\r\n\r\n        if (event.target.closest(\"td.field\")) {\r\n          const table = event.target.closest(\"td\")?.querySelector(\".squeeze_status .squeeze-comparison-table\");\r\n          if (table) {\r\n            const td = document.createElement(\"td\");\r\n            td.classList.add(\"field\");\r\n            td.style.width = \"100%\";\r\n            td.appendChild(table);\r\n            event.target.closest(\"tr\").appendChild(td);\r\n          }\r\n        }\r\n        // TBD: add file size label to the attachment info\r\n        /*\r\n        if (event.target.closest('.attachment-info')) {\r\n          const fileSizeLabel = event.target.closest('.attachment-info').querySelector('.file-size');\r\n          if (fileSizeLabel) {\r\n            const fileSize = response?.data?.sizes?.scaled?.compressed_size ?? response?.data?.sizes?.original?.compressed_size ?? null;\r\n            if (fileSize) {\r\n              const humanFileSize = SqueezeHelpers.humanFileSize(fileSize, true);\r\n              fileSizeLabel.innerHTML = fileSizeLabel.innerHTML.replace(/(<\\/strong>\\s*)(.*)/, `$1${humanFileSize}`);\r\n            }\r\n          }\r\n        }\r\n        */\r\n      } catch (error) {\r\n        console.error(error);\r\n        squeezeStatus.innerHTML = error;\r\n      } finally {\r\n        _helpers_js__WEBPACK_IMPORTED_MODULE_0__.removeAllButtons(event.target.closest(\"td\")?.querySelectorAll(`button`));\r\n        window.onbeforeunload = null;\r\n      }\r\n    });\r\n  } catch (error) {\r\n    console.error(error);\r\n    squeezeStatus.innerHTML = error;\r\n    event.target.remove();\r\n  }\r\n};\r\n\r\nconst handleRestoreBtnClick = async (event) => {\r\n  const attachmentID = event.target.dataset.attachment;\r\n\r\n  event.target.disabled = true;\r\n  event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = '⏳ ' + __('Restore in process...', 'squeeze');\r\n\r\n  try {\r\n    const response = await Squeeze.handleRestore(attachmentID);\r\n    event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = response.data;\r\n  } catch (error) {\r\n    console.error(error);\r\n    event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = error;\r\n  } finally {\r\n    event.target.closest('td').querySelector(`[name='squeeze_compress_again']`).disabled = false;\r\n    event.target.remove();\r\n    window.onbeforeunload = null;\r\n  }\r\n};\r\n\r\nconst handleBulkButtonClick = async (event, process, mediaIDs, currentPage) => {\r\n  if (mediaIDs.length === 0) return;\r\n\r\n  const totalPages = getTotalPages(process);\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.disableBulkButtons();\r\n  window.onbeforeunload = handleOnLeave;\r\n\r\n  if (_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.process === process) {\r\n    if (_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs/*.length > 0*/) {\r\n      mediaIDs = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs;\r\n    }\r\n    if (_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page) {\r\n      currentPage = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page;\r\n    }\r\n  }\r\n\r\n  const isPaused = handleBulkToggle(event, process, mediaIDs, currentPage);\r\n  if (isPaused) {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.updateButtonText(event.target, __('Pausing...', 'squeeze'), '#pause-button-icon');\r\n    return;\r\n  } else {\r\n    event.target.disabled = false;\r\n  }\r\n\r\n  try {\r\n    const finalResponse = await handleRecursiveUpload(process, mediaIDs, currentPage, true);\r\n\r\n    if (finalResponse?.mediaIDs) {\r\n      if (finalResponse.mediaIDs.length === 0 && finalResponse.page >= totalPages) {\r\n        alert(__('All images have been processed!', 'squeeze'));\r\n        window.onbeforeunload = null;\r\n        _helpers_js__WEBPACK_IMPORTED_MODULE_0__.restoreBulkButtons();\r\n      }\r\n    }\r\n  } catch (error) {\r\n    console.error(error);\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.restoreBulkButtons();\r\n    window.onbeforeunload = null;\r\n    alert(__('An error has occured. Check the console for details.', 'squeeze'));\r\n  }\r\n};\r\n\r\n// manually pass Squeeze, because of the dynamic options update in the Preview Mode\r\nconst handleButtonsClick = async (event, Squeeze) => {\r\n  const singleBtnName = 'squeeze_compress_single';\r\n  const compressAgainBtnName = 'squeeze_compress_again';\r\n  const restoreBtnName = 'squeeze_restore';\r\n\r\n  if (event.target.getAttribute(\"name\") === singleBtnName || event.target.getAttribute(\"name\") === compressAgainBtnName) {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.disableAllButtons(event.target.closest(\"td\").querySelectorAll(`button`));\r\n    event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = '⏳ ' + __('Squeezing...', 'squeeze');\r\n    window.onbeforeunload = handleOnLeave;\r\n    handleSingleBtnClick(event, Squeeze);\r\n  }\r\n\r\n  if (event.target.getAttribute(\"name\") === restoreBtnName) {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.disableAllButtons(event.target.closest(\"td\").querySelectorAll(`button`));\r\n    window.onbeforeunload = handleOnLeave;\r\n    handleRestoreBtnClick(event);\r\n  }\r\n};\r\n\r\nconst handleDirectoryClick = async (event) => {\r\n  if (event.target !== event.currentTarget) return;\r\n\r\n  const currentDir = event.target.closest(\".directory-item\");\r\n  const currentPath = currentDir.dataset.path;\r\n  const parentPath = currentDir.dataset.parent;\r\n\r\n  if (parentPath === '/' || currentDir.classList.contains(\"loading\")) return;\r\n\r\n  if (currentDir.classList.contains(\"loaded\")) {\r\n    currentDir.classList.toggle(\"opened\");\r\n    return;\r\n  }\r\n\r\n  currentDir.classList.add(\"loading\");\r\n\r\n  const subDirs = await Squeeze.getDirectories(currentPath);\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.renderDirectories(subDirs, currentDir, {\r\n    handleDirectoryClick,\r\n    handleDirectoryCheck\r\n  });\r\n\r\n  currentDir.classList.remove(\"loading\");\r\n  currentDir.classList.add(\"loaded\", \"opened\");\r\n}\r\n\r\n/**\r\n * Hadnle warning on page leave\r\n*/\r\nconst handleOnLeave = () => {\r\n  const urlParams = new URLSearchParams(window.location.search);\r\n  const page = urlParams.get('page');\r\n  const isUploadPage = window.location.href.includes('upload.php');\r\n  const isMediaNewPage = window.location.href.includes('media-new.php');\r\n  const isAttachmentPage = window.location.href.includes('post.php') && urlParams.get('action') === 'edit';\r\n\r\n  if (page === 'squeeze-bulk' || isMediaNewPage || isAttachmentPage) {\r\n    return __('Are you sure you want to leave this page? The squeezing process will be terminated!', 'squeeze');\r\n  }\r\n  if (isUploadPage) {\r\n    return __('Are you sure you want to leave this page? The settings will not be saved!', 'squeeze');\r\n  }\r\n};\r\n\r\nconst handleBulkPause = (data, currentPage) => {\r\n  window.onbeforeunload = null;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(__('Bulk squeezing has been paused!', 'squeeze'), { isPause: true });\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs = data;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page = currentPage;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.target.disabled = false;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.updateButtonText(_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.target, __('Resume bulk squeezing', 'squeeze'), '#play-button-round-icon');\r\n};\r\n\r\nconst handleUpdateChart = (uncompressedImagesCount) => {\r\n  const chartValue = document.querySelector(\".squeeze-bulk-media-stats-chart-value > text\");\r\n  const chartBar = document.querySelector(\".squeeze-bulk-media-stats-chart\");\r\n  const squeezedImages = document.querySelector(\".squeeze-bulk-media-stats-item-value\");\r\n\r\n  if (!chartValue || !chartBar) return;\r\n\r\n  const imagesLeft = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.totalImages - uncompressedImagesCount;\r\n  const percentage = parseFloat((imagesLeft / _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.totalImages) * 100).toFixed(2);\r\n  const dasharray = percentage * 560 / 100;\r\n  chartValue.textContent = `${percentage}%`;\r\n  chartBar.style.setProperty('--squeeze-dasharray', dasharray);\r\n\r\n  if (squeezedImages) {\r\n    squeezedImages.textContent = `${imagesLeft} / ${_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.totalImages}`;\r\n  }\r\n};\r\n\r\nconst handleRecursiveUpload = async (path, data, currentPage, isUpdateChart = false) => {\r\n\r\n  if (!Array.isArray(data)) return { success: false, data: 'No data provided!', mediaIDs: [] }; // when bulk directory path has no images\r\n  \r\n  const totalPages = getTotalPages(path);\r\n\r\n  if (data.length === 0) {\r\n    currentPage += 1;\r\n    if (currentPage > totalPages || !_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.lastId) return { success: true, data: __('No more images found!', 'squeeze'), mediaIDs: [], page: currentPage };\r\n\r\n    const maybeGetNextMediaIDs = await Squeeze.getNextAttachments(currentPage, path, _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.lastId);\r\n    if (maybeGetNextMediaIDs.success && maybeGetNextMediaIDs.data.length > 0) {\r\n      const nextMediaIDs = maybeGetNextMediaIDs.data;\r\n      return handleRecursiveUpload(path, nextMediaIDs, currentPage, isUpdateChart);\r\n    } else {\r\n      return { success: true, data: __('No more images found!', 'squeeze'), mediaIDs: [], page: currentPage };\r\n    }\r\n  }\r\n\r\n  const initData = [...data];  // initial data\r\n\r\n  const filename = data[0]?.filename ? data[0].filename : `ID #${data[0]}`;\r\n  const mediaLogWrapper = await _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(`${__('Start squeezing...', 'squeeze')}`, { title: filename, isStart: true });\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.lastId = data[0] || 0; // update lastId to the last processed ID\r\n\r\n  try {\r\n    const response = await Squeeze.handleBulkUpload(path, data);\r\n\r\n    await logAndThumbnail(filename, response, mediaLogWrapper);\r\n\r\n    if (isUpdateChart && path !== 'all') {\r\n      let uncompressedImagesCount = 0;\r\n      if (path === 'uncompressed') {\r\n        _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.uncompressedImages = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.uncompressedImages - 1 || 0;\r\n        uncompressedImagesCount = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.uncompressedImages;\r\n      } else if (path === 'path') {\r\n        uncompressedImagesCount = response.mediaIDs.length;\r\n      }\r\n      handleUpdateChart(uncompressedImagesCount);\r\n    }\r\n\r\n    if (checkPaused(data, currentPage)) {\r\n      return { success: false, data: 'Process has been paused!', mediaIDs: data, page: currentPage };\r\n    }\r\n\r\n    updateUI(initData[0], response);\r\n\r\n    if (response.mediaIDs.length > 0) {\r\n      return handleRecursiveUpload(path, response.mediaIDs, currentPage, isUpdateChart);\r\n    } else {\r\n      currentPage += 1;\r\n      if (currentPage > totalPages) return { ...response, page: currentPage };\r\n\r\n      const lastId = initData[initData.length - 1];\r\n      const maybeGetNextMediaIDs = await Squeeze.getNextAttachments(currentPage, path, lastId);\r\n      if (maybeGetNextMediaIDs.success && maybeGetNextMediaIDs.data.length > 0) {\r\n        const nextMediaIDs = maybeGetNextMediaIDs.data;\r\n        return handleRecursiveUpload(path, nextMediaIDs, currentPage, isUpdateChart);\r\n      }\r\n    }\r\n\r\n    return response;\r\n\r\n  } catch (error) {\r\n    console.error(error);\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(`${error}`, { mediaLogWrapper, iconId: 'ban-sign-icon' });\r\n\r\n    if (data.length > 0) {\r\n      return handleRecursiveUpload(path, data, currentPage, isUpdateChart);\r\n    } else {\r\n      currentPage += 1;\r\n      if (currentPage > totalPages) return { success: false, data: error, mediaIDs: [], page: currentPage };\r\n\r\n      const lastId = initData[initData.length - 1];\r\n      const maybeGetNextMediaIDs = await Squeeze.getNextAttachments(currentPage, path, lastId);\r\n      if (maybeGetNextMediaIDs.success && maybeGetNextMediaIDs.data.length > 0) {\r\n        const nextMediaIDs = maybeGetNextMediaIDs.data;\r\n        return handleRecursiveUpload(path, nextMediaIDs, currentPage, isUpdateChart);\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\n\r\n\r\nconst handleMultiFileFormUpload = (compressOptions) => {\r\n  if (typeof wpUploaderInit === 'undefined' || typeof plupload === 'undefined' || typeof uploader === 'undefined') return;\r\n\r\n  const SqueezeUploader = uploader;\r\n\r\n  SqueezeUploader.bind('FilesAdded', function (up, files) { });\r\n\r\n  SqueezeUploader.bind('FileUploaded', function (up, file, response) {\r\n    const fileMime = file.type;\r\n    const fileType = fileMime.split('/')[0];\r\n    const fileSubType = fileMime.split('/')[1];\r\n\r\n    if (!_helpers_js__WEBPACK_IMPORTED_MODULE_0__.maybeCompressAttachment(fileType, fileSubType, compressOptions)) return;\r\n\r\n    const fileID = file.id;\r\n    const attachmentID = response.response;\r\n    const mediaItem = document.getElementById(`media-item-${fileID}`);\r\n\r\n    window.onbeforeunload = handleOnLeave;\r\n\r\n    /**\r\n     * Wait for media item to load( 'async-upload.php' )\r\n     * Ping every 1 second until the media item is loaded\r\n     * @returns Promise\r\n    */\r\n    const waitForItemLoad = () => {\r\n      return new Promise((resolve) => {\r\n        let interval = setInterval(() => {\r\n          if (mediaItem.querySelector('.media-item-wrapper')) {\r\n            mediaItem.querySelector('.media-item-wrapper').innerHTML += `\r\n              <div class=\"progress\">\r\n                <div class=\"percent\">${__('Squeezing...', 'squeeze')}</div>\r\n                <div class=\"bar\" style=\"width: 200px;\"></div>\r\n              </div>\r\n            `;\r\n            clearInterval(interval);\r\n            resolve();\r\n          }\r\n        }, 1000);\r\n      });\r\n    };\r\n\r\n    waitForItemLoad().then(() => {\r\n      try {\r\n        wp.media.attachment(attachmentID).fetch().then(async function (data) {\r\n          const attachment = { attributes: data };\r\n\r\n          try {\r\n            const compressData = await Squeeze.handleCompress(attachment);\r\n            const uploadData = await Squeeze.handleUpload({ attachment, base64: compressData });\r\n\r\n            if (uploadData.success) {\r\n              window.onbeforeunload = null;\r\n              mediaItem.innerHTML += `<div class=\"squeeze_status\">${uploadData.data}</div>`;\r\n              mediaItem.querySelector('.progress')?.remove();\r\n            } else {\r\n              alert(uploadData?.data ?? uploadData);\r\n              window.onbeforeunload = null;\r\n              mediaItem.querySelector('.progress')?.remove();\r\n            }\r\n          } catch (error) {\r\n            console.error(error);\r\n            mediaItem.innerHTML += error;\r\n            window.onbeforeunload = null;\r\n            mediaItem.querySelector('.progress')?.remove();\r\n          }\r\n        });\r\n      } catch (error) {\r\n        console.error(error);\r\n        mediaItem.innerHTML += error;\r\n        window.onbeforeunload = null;\r\n        mediaItem.querySelector('.progress')?.remove();\r\n      }\r\n    });\r\n  });\r\n\r\n  SqueezeUploader.bind('UploadComplete', function (up, files) { });\r\n};\n\n//# sourceURL=webpack:///./assets/js/handlers.js?");
     29eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"handleBulkButtonClick\": () => (/* binding */ handleBulkButtonClick),\n/* harmony export */   \"handleBulkFromPage\": () => (/* binding */ handleBulkFromPage),\n/* harmony export */   \"handleBulkToggle\": () => (/* binding */ handleBulkToggle),\n/* harmony export */   \"handleButtonsClick\": () => (/* binding */ handleButtonsClick),\n/* harmony export */   \"handleClosePathDialog\": () => (/* binding */ handleClosePathDialog),\n/* harmony export */   \"handleCompressBeforeUpload\": () => (/* binding */ handleCompressBeforeUpload),\n/* harmony export */   \"handleDirectoryCheck\": () => (/* binding */ handleDirectoryCheck),\n/* harmony export */   \"handleDirectoryClick\": () => (/* binding */ handleDirectoryClick),\n/* harmony export */   \"handleFetchImagesFromPage\": () => (/* binding */ handleFetchImagesFromPage),\n/* harmony export */   \"handleMultiFileFormUpload\": () => (/* binding */ handleMultiFileFormUpload),\n/* harmony export */   \"handleOnLeave\": () => (/* binding */ handleOnLeave),\n/* harmony export */   \"handleRecursiveUpload\": () => (/* binding */ handleRecursiveUpload),\n/* harmony export */   \"handleRestoreBtnClick\": () => (/* binding */ handleRestoreBtnClick),\n/* harmony export */   \"handleSingleBtnClick\": () => (/* binding */ handleSingleBtnClick)\n/* harmony export */ });\n/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./helpers.js */ \"./assets/js/helpers.js\");\n/* harmony import */ var _squeeze_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./squeeze.js */ \"./assets/js/squeeze.js\");\n\r\n\r\n\r\n\r\n\r\n\r\nconst { __ } = wp.i18n; // Import __() from wp.i18n\r\nconst Squeeze = new _squeeze_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"](squeezeOptions);\r\n\r\nconst updateUI = (initId, response) => {\r\n  const statusEl = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.postsFilterForm?.querySelector(`#post-${initId} .column-squeeze .squeeze_status`);\r\n  if (statusEl) statusEl.innerHTML = response?.data?.message ?? response?.data ?? response;\r\n\r\n  const gridItem = document.querySelector(`.media-frame.mode-grid .attachment[data-id=\"${initId}\"]`);\r\n  if (gridItem) {\r\n    const centered = gridItem.querySelector('.centered');\r\n    const progress = gridItem.querySelector('.media-progress-bar');\r\n    if (centered) centered.style.display = 'block';\r\n    if (progress) progress.remove();\r\n    gridItem.classList.remove('uploading');\r\n  }\r\n};\r\n\r\nconst getTotalPages = (path) => {\r\n  const selectors = {\r\n    uncompressed: \"input[name='squeeze_bulk_uncompressed_pages']\",\r\n    all: \"input[name='squeeze_bulk_total_pages']\"\r\n  };\r\n  const sel = selectors[path];\r\n  const val = sel && document.querySelector(sel)?.value;\r\n  return Number(val) || 1;\r\n};\r\n\r\nconst checkPaused = (data, page) => {\r\n  if (!_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.isPaused) return false;\r\n  handleBulkPause(data, page);\r\n  return true;\r\n};\r\n\r\nconst logAndThumbnail = async (filename, response, wrapper) => {\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(response?.data?.message ?? response?.data, {\r\n    mediaLogWrapper: wrapper,\r\n    iconId: response.success ? 'check-mark-circle-icon' : 'ban-sign-icon'\r\n  });\r\n\r\n  const titleEl = wrapper?.querySelector('h3');\r\n  if (titleEl && response?.data?.filename) {\r\n    titleEl.textContent = `${__('Media', 'squeeze')} ${filename} (${response.data.filename}):`;\r\n  }\r\n\r\n  const thumbUrl = response?.data?.sizes?.thumbnail?.url || response?.data?.url || response?.url;\r\n  if (thumbUrl) {\r\n    const thumb = document.createElement('div');\r\n    thumb.classList.add('media-log-thumbnail');\r\n    thumb.innerHTML = `<img src=\"${thumbUrl}\" alt=\"${filename}\"/>`;\r\n    wrapper?.appendChild(thumb);\r\n  }\r\n};\r\n\r\nconst handleDirectoryCheck = (event) => {\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.savePathBtn.disabled = !_helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.dirContainer.querySelector(\"input[type='checkbox']:checked\");\r\n};\r\n\r\nconst handleClosePathDialog = (event) => {\r\n  if (!event.target.contains(_helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.pathDialog)) return;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.pathDialog.close();\r\n};\r\n\r\nconst handleBulkToggle = (event, process, mediaIDs, page = 1) => {\r\n  const isPaused = event.target.dataset.running === 'true';\r\n\r\n  event.target.dataset.running = isPaused ? 'false' : 'true';\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.updateButtonText(event.target, isPaused ? __('Resume bulk squeezing', 'squeeze') : __('Pause bulk squeezing', 'squeeze'), isPaused ? '#play-button-round-icon' : '#pause-button-icon');\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.isPaused = isPaused;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.process = process;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs = mediaIDs;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page = page;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.target = event.target;\r\n\r\n  //console.log('handleBulkToggle', cachedMediaData);\r\n\r\n  return isPaused;\r\n};\r\n\r\n// Handle single compress button click\r\n// manually pass Squeeze, because of the dynamic options update in the Preview Mode\r\nconst handleSingleBtnClick = async (event, Squeeze) => {\r\n  const attachmentID = event.target.dataset.attachment;\r\n  const squeezeStatus = event.target.closest(\"td\").querySelector(\".squeeze_status\");\r\n\r\n  try {\r\n    wp.media.attachment(attachmentID).fetch().then(async (data) => {\r\n      const attachment = { attributes: data };\r\n\r\n      try {\r\n        const compressData = await Squeeze.handleCompress(attachment);\r\n        const response = await Squeeze.handleUpload({ attachment, base64: compressData });\r\n\r\n        squeezeStatus.innerHTML = response?.data?.message ?? response?.data ?? response;\r\n\r\n        if (event.target.closest(\"td.field\")) {\r\n          const table = event.target.closest(\"td\")?.querySelector(\".squeeze_status .squeeze-comparison-table\");\r\n          if (table) {\r\n            const td = document.createElement(\"td\");\r\n            td.classList.add(\"field\");\r\n            td.style.width = \"100%\";\r\n            td.appendChild(table);\r\n            event.target.closest(\"tr\").appendChild(td);\r\n          }\r\n        }\r\n        // TBD: add file size label to the attachment info\r\n        /*\r\n        if (event.target.closest('.attachment-info')) {\r\n          const fileSizeLabel = event.target.closest('.attachment-info').querySelector('.file-size');\r\n          if (fileSizeLabel) {\r\n            const fileSize = response?.data?.sizes?.scaled?.compressed_size ?? response?.data?.sizes?.original?.compressed_size ?? null;\r\n            if (fileSize) {\r\n              const humanFileSize = SqueezeHelpers.humanFileSize(fileSize, true);\r\n              fileSizeLabel.innerHTML = fileSizeLabel.innerHTML.replace(/(<\\/strong>\\s*)(.*)/, `$1${humanFileSize}`);\r\n            }\r\n          }\r\n        }\r\n        */\r\n      } catch (error) {\r\n        console.error(error);\r\n        squeezeStatus.innerHTML = error?.message ?? error;\r\n      } finally {\r\n        _helpers_js__WEBPACK_IMPORTED_MODULE_0__.removeAllButtons(event.target.closest(\"td\")?.querySelectorAll(`button`));\r\n        window.onbeforeunload = null;\r\n      }\r\n    });\r\n  } catch (error) {\r\n    console.error(error);\r\n    squeezeStatus.innerHTML = error?.message ?? error;\r\n    event.target.remove();\r\n  }\r\n};\r\n\r\nconst handleRestoreBtnClick = async (event) => {\r\n  const attachmentID = event.target.dataset.attachment;\r\n\r\n  event.target.disabled = true;\r\n  event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = '⏳ ' + __('Restore in process...', 'squeeze');\r\n\r\n  try {\r\n    const response = await Squeeze.handleRestore(attachmentID);\r\n    event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = response?.data ?? response;\r\n  } catch (error) {\r\n    console.error(error);\r\n    event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = error?.message ?? JSON.stringify(error, null, 2);\r\n  } finally {\r\n    event.target.closest('td').querySelector(`[name='squeeze_compress_again']`).disabled = false;\r\n    event.target.remove();\r\n    window.onbeforeunload = null;\r\n  }\r\n};\r\n\r\nconst handleBulkButtonClick = async (event, process, mediaIDs, currentPage) => {\r\n  if (mediaIDs.length === 0) return;\r\n\r\n  const totalPages = getTotalPages(process);\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.disableBulkButtons();\r\n  window.onbeforeunload = handleOnLeave;\r\n\r\n  if (_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.process === process) {\r\n    if (_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs/*.length > 0*/) {\r\n      mediaIDs = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs;\r\n    }\r\n    if (_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page) {\r\n      currentPage = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page;\r\n    }\r\n  }\r\n\r\n  const isPaused = handleBulkToggle(event, process, mediaIDs, currentPage);\r\n  if (isPaused) {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.updateButtonText(event.target, __('Pausing...', 'squeeze'), '#pause-button-icon');\r\n    return;\r\n  } else {\r\n    event.target.disabled = false;\r\n  }\r\n\r\n  try {\r\n    const finalResponse = await handleRecursiveUpload(process, mediaIDs, currentPage, true);\r\n\r\n    if (finalResponse?.mediaIDs) {\r\n      if (finalResponse.mediaIDs.length === 0 && finalResponse.page >= totalPages) {\r\n        alert(__('All images have been processed!', 'squeeze'));\r\n        window.onbeforeunload = null;\r\n        _helpers_js__WEBPACK_IMPORTED_MODULE_0__.restoreBulkButtons();\r\n      }\r\n    }\r\n  } catch (error) {\r\n    console.error(error);\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.restoreBulkButtons();\r\n    window.onbeforeunload = null;\r\n    alert(__('An error has occured. Check the console for details.', 'squeeze'));\r\n  }\r\n};\r\n\r\n// manually pass Squeeze, because of the dynamic options update in the Preview Mode\r\nconst handleButtonsClick = async (event, Squeeze) => {\r\n  const singleBtnName = 'squeeze_compress_single';\r\n  const compressAgainBtnName = 'squeeze_compress_again';\r\n  const restoreBtnName = 'squeeze_restore';\r\n\r\n  if (event.target.getAttribute(\"name\") === singleBtnName || event.target.getAttribute(\"name\") === compressAgainBtnName) {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.disableAllButtons(event.target.closest(\"td\").querySelectorAll(`button`));\r\n    event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = '⏳ ' + __('Squeezing...', 'squeeze');\r\n    window.onbeforeunload = handleOnLeave;\r\n    handleSingleBtnClick(event, Squeeze);\r\n  }\r\n\r\n  if (event.target.getAttribute(\"name\") === restoreBtnName) {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.disableAllButtons(event.target.closest(\"td\").querySelectorAll(`button`));\r\n    window.onbeforeunload = handleOnLeave;\r\n    handleRestoreBtnClick(event);\r\n  }\r\n};\r\n\r\nconst handleDirectoryClick = async (event) => {\r\n  if (event.target !== event.currentTarget) return;\r\n\r\n  const currentDir = event.target.closest(\".directory-item\");\r\n  const currentPath = currentDir.dataset.path;\r\n  const parentPath = currentDir.dataset.parent;\r\n\r\n  if (parentPath === '/' || currentDir.classList.contains(\"loading\")) return;\r\n\r\n  if (currentDir.classList.contains(\"loaded\")) {\r\n    currentDir.classList.toggle(\"opened\");\r\n    return;\r\n  }\r\n\r\n  currentDir.classList.add(\"loading\");\r\n\r\n  const subDirs = await Squeeze.getDirectories(currentPath);\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.renderDirectories(subDirs, currentDir, {\r\n    handleDirectoryClick,\r\n    handleDirectoryCheck\r\n  });\r\n\r\n  currentDir.classList.remove(\"loading\");\r\n  currentDir.classList.add(\"loaded\", \"opened\");\r\n}\r\n\r\n/**\r\n * Hadnle warning on page leave\r\n*/\r\nconst handleOnLeave = () => {\r\n  const urlParams = new URLSearchParams(window.location.search);\r\n  const page = urlParams.get('page');\r\n  const isUploadPage = window.location.href.includes('upload.php');\r\n  const isMediaNewPage = window.location.href.includes('media-new.php');\r\n  const isAttachmentPage = window.location.href.includes('post.php') && urlParams.get('action') === 'edit';\r\n\r\n  if (page === 'squeeze-bulk' || isMediaNewPage || isAttachmentPage) {\r\n    return __('Are you sure you want to leave this page? The squeezing process will be terminated!', 'squeeze');\r\n  }\r\n  if (isUploadPage) {\r\n    return __('Are you sure you want to leave this page? The settings will not be saved!', 'squeeze');\r\n  }\r\n};\r\n\r\nconst handleBulkPause = (data, currentPage) => {\r\n  window.onbeforeunload = null;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(__('Bulk squeezing has been paused!', 'squeeze'), { isPause: true });\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs = data;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page = currentPage;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.target.disabled = false;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.updateButtonText(_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.target, __('Resume bulk squeezing', 'squeeze'), '#play-button-round-icon');\r\n};\r\n\r\nconst handleUpdateChart = (uncompressedImagesCount) => {\r\n  const chartValue = document.querySelector(\".squeeze-bulk-media-stats-chart-value > text\");\r\n  const chartBar = document.querySelector(\".squeeze-bulk-media-stats-chart\");\r\n  const squeezedImages = document.querySelector(\".squeeze-bulk-media-stats-item-value\");\r\n\r\n  if (!chartValue || !chartBar) return;\r\n\r\n  const imagesLeft = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.totalImages - uncompressedImagesCount;\r\n  const percentage = parseFloat((imagesLeft / _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.totalImages) * 100).toFixed(2);\r\n  const dasharray = percentage * 560 / 100;\r\n  chartValue.textContent = `${percentage}%`;\r\n  chartBar.style.setProperty('--squeeze-dasharray', dasharray);\r\n\r\n  if (squeezedImages) {\r\n    squeezedImages.textContent = `${imagesLeft} / ${_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.totalImages}`;\r\n  }\r\n};\r\n\r\nconst handleRecursiveUpload = async (path, data, currentPage, isUpdateChart = false) => {\r\n\r\n  if (!Array.isArray(data)) return { success: false, data: 'No data provided!', mediaIDs: [] }; // when bulk directory path has no images\r\n\r\n  const totalPages = getTotalPages(path);\r\n\r\n  if (data.length === 0) {\r\n    currentPage += 1;\r\n    if (currentPage > totalPages || !_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.lastId) return { success: true, data: __('No more images found!', 'squeeze'), mediaIDs: [], page: currentPage };\r\n\r\n    const maybeGetNextMediaIDs = await Squeeze.getNextAttachments(currentPage, path, _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.lastId);\r\n    if (maybeGetNextMediaIDs.success && maybeGetNextMediaIDs.data.length > 0) {\r\n      const nextMediaIDs = maybeGetNextMediaIDs.data;\r\n      return handleRecursiveUpload(path, nextMediaIDs, currentPage, isUpdateChart);\r\n    } else {\r\n      return { success: true, data: __('No more images found!', 'squeeze'), mediaIDs: [], page: currentPage };\r\n    }\r\n  }\r\n\r\n  const initData = [...data];  // initial data\r\n\r\n  const filename = data[0]?.filename ? data[0].filename : `ID #${data[0]}`;\r\n  const mediaLogWrapper = await _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(`${__('Start squeezing...', 'squeeze')}`, { title: filename, isStart: true });\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.lastId = data[0] || 0; // update lastId to the last processed ID\r\n\r\n  try {\r\n    const response = await Squeeze.handleBulkUpload(path, data);\r\n\r\n    //console.log('handleRecursiveUpload response', response);\r\n\r\n    await logAndThumbnail(filename, response, mediaLogWrapper);\r\n\r\n    if (isUpdateChart && path !== 'all') {\r\n      let uncompressedImagesCount = 0;\r\n      if (path === 'uncompressed') {\r\n        _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.uncompressedImages = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.uncompressedImages - 1 || 0;\r\n        uncompressedImagesCount = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.uncompressedImages;\r\n      } else if (path === 'path') {\r\n        uncompressedImagesCount = response.mediaIDs.length;\r\n      }\r\n      handleUpdateChart(uncompressedImagesCount);\r\n    }\r\n\r\n    if (checkPaused(data, currentPage)) {\r\n      return { success: false, data: 'Process has been paused!', mediaIDs: data, page: currentPage };\r\n    }\r\n\r\n    updateUI(initData[0], response);\r\n\r\n    if (response.mediaIDs.length > 0) {\r\n      return handleRecursiveUpload(path, response.mediaIDs, currentPage, isUpdateChart);\r\n    } else {\r\n      currentPage += 1;\r\n      if (currentPage > totalPages) return { ...response, page: currentPage };\r\n\r\n      const lastId = initData[initData.length - 1];\r\n      const maybeGetNextMediaIDs = await Squeeze.getNextAttachments(currentPage, path, lastId);\r\n      if (maybeGetNextMediaIDs.success && maybeGetNextMediaIDs.data.length > 0) {\r\n        const nextMediaIDs = maybeGetNextMediaIDs.data;\r\n        return handleRecursiveUpload(path, nextMediaIDs, currentPage, isUpdateChart);\r\n      }\r\n    }\r\n\r\n    return response;\r\n\r\n  } catch (error) {\r\n    console.error(error);\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(`${error}`, { mediaLogWrapper, iconId: 'ban-sign-icon' });\r\n\r\n    if (data.length > 0) {\r\n      return handleRecursiveUpload(path, data, currentPage, isUpdateChart);\r\n    } else {\r\n      currentPage += 1;\r\n      if (currentPage > totalPages) return { success: false, data: error, mediaIDs: [], page: currentPage };\r\n\r\n      const lastId = initData[initData.length - 1];\r\n      const maybeGetNextMediaIDs = await Squeeze.getNextAttachments(currentPage, path, lastId);\r\n      if (maybeGetNextMediaIDs.success && maybeGetNextMediaIDs.data.length > 0) {\r\n        const nextMediaIDs = maybeGetNextMediaIDs.data;\r\n        return handleRecursiveUpload(path, nextMediaIDs, currentPage, isUpdateChart);\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\n\r\n\r\n/**\r\n * Handles the compression of image before upload using Squeeze.\r\n * It compresses only the original image, not the thumbnails.\r\n * \r\n * @param {object} up - The plupload instance\r\n * @param {object} pluploadFile - The file to be compressed\r\n * @param {object} compressOptions - The compression options object\r\n * @returns {boolean} - Returns false to prevent further processing of the file\r\n */\r\nconst handleCompressBeforeUpload = async (up, pluploadFile, compressOptions) => {\r\n  if (typeof Squeeze === 'undefined') return;\r\n  if (typeof Squeeze.compressBeforeUpload !== 'function') {\r\n    console.warn('Squeeze.compressBeforeUpload is not a function');\r\n    return;\r\n  }\r\n  \r\n  if (pluploadFile?._isSqueezed || pluploadFile?._isExcluded || pluploadFile?._isFailed) {\r\n    //console.warn('File is already compressed:', pluploadFile);\r\n    return; // Skip files that are already compressed\r\n  }\r\n  // Check if the file is an image based on its MIME type\r\n  if (!pluploadFile.type.startsWith('image/')) {\r\n    //console.warn('File is not an image:', pluploadFile.name);\r\n    return; // Skip non-image files\r\n  }\r\n\r\n  const file = pluploadFile.getNative() || pluploadFile.getSource();\r\n\r\n  const type = file?.type?.split('/')[0] ?? '';\r\n  const subtype = file?.type?.split('/')[1] ?? '';\r\n\r\n  if (!_helpers_js__WEBPACK_IMPORTED_MODULE_0__.maybeCompressAttachment(type, subtype, compressOptions)) {\r\n    //console.warn('Skipping compression for:', pluploadFile.name);\r\n    return; // Skip compression for this file\r\n  }\r\n\r\n  //console.time('BeforeUpload')\r\n\r\n  up.stop();\r\n  window.onbeforeunload = handleOnLeave;\r\n  \r\n  \r\n\r\n  try {\r\n    let originalFile = file;\r\n    const base64Obj = await Squeeze.compressBeforeUpload(file);\r\n    if (!base64Obj || !base64Obj.base64) {\r\n      console.warn('Compression skipped or failed for:', file.name);\r\n      pluploadFile.status = plupload.QUEUED;\r\n      pluploadFile.loaded = 0;\r\n      pluploadFile._isFailed = true; // Mark the file as failed\r\n      //window.onbeforeunload = null;\r\n      setTimeout(() => up.start(), 0);\r\n      return; // Skip further processing if compression failed or was skipped\r\n    }\r\n    \r\n    const isDirectWebp = compressOptions?.direct_webp && file.type !== 'image/webp';\r\n    const isBackupOriginal = compressOptions?.backup_original;\r\n\r\n    if (isBackupOriginal) {\r\n      // If backup original is enabled, convert the original file to WebP if it's not already\r\n      if (isDirectWebp) {\r\n        originalFile = await Squeeze.convertFileToWebp(file);\r\n      } else {\r\n        originalFile = file; // Keep the original file as is\r\n      }\r\n      pluploadFile.originalFile = originalFile; // Store the original file in the pluploadFile object\r\n    }\r\n\r\n    const compressedFile = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.base64ToFile(base64Obj.base64, file.name, file.type);\r\n    const newSource = new mOxie.File(null, compressedFile);\r\n\r\n    if (!newSource) {\r\n      console.error('Failed to create new mOxie.File from base64 data');\r\n      return; // Exit if newSource is not created\r\n    }\r\n\r\n    //console.log('Compressed file created:', newSource);\r\n\r\n    // Override the file's getSource method to return the new compressed source\r\n    pluploadFile.getSource = function () {\r\n      return newSource;\r\n    };\r\n\r\n    // Reset status back to QUEUED\r\n    pluploadFile.status = plupload.QUEUED;\r\n    pluploadFile.loaded = 0;\r\n    pluploadFile._isSqueezed = true; // Mark the file as compressed\r\n    pluploadFile.base64 = base64Obj.base64; // Store the base64 data of the compressed image in the attachment\r\n    pluploadFile.base64Webp = base64Obj?.base64Webp; // Store the WebP base64 data of the compressed image in the attachment\r\n    \r\n    // In the next tick, restart the queue\r\n    setTimeout(() => up.start(), 0);\r\n\r\n    //window.onbeforeunload = null;\r\n\r\n  } catch (error) {\r\n    console.error('Error during compression before upload:', error);\r\n    pluploadFile.status = plupload.QUEUED;\r\n    pluploadFile.loaded = 0;\r\n    pluploadFile._isFailed = true; // Mark the file as failed\r\n    setTimeout(() => up.start(), 0);\r\n    return false;\r\n  }\r\n\r\n  return true;\r\n}\r\n\r\nconst handleMultiFileFormUpload = (compressOptions) => {\r\n  if (typeof wpUploaderInit === 'undefined' || typeof plupload === 'undefined' || typeof uploader === 'undefined') return;\r\n\r\n  const SqueezeUploader = uploader;\r\n\r\n  SqueezeUploader.bind('BeforeUpload', async function (up, pluploadFile) {\r\n    handleCompressBeforeUpload(up, pluploadFile, compressOptions)\r\n  });\r\n\r\n  SqueezeUploader.bind('FileUploaded', function (up, file, response) {\r\n    //console.log('FileUploaded', file, response);\r\n    const fileMime = file.type;\r\n    const fileType = fileMime.split('/')[0];\r\n    const fileSubType = fileMime.split('/')[1];\r\n\r\n    if (!_helpers_js__WEBPACK_IMPORTED_MODULE_0__.maybeCompressAttachment(fileType, fileSubType, compressOptions)) return;\r\n\r\n    /**\r\n     * Wait for media item to load( 'async-upload.php' )\r\n     * Ping every 1 second until the media item is loaded\r\n     * @returns Promise\r\n    */\r\n    const waitForItemLoad = (addProgressBar = true) => {\r\n      return new Promise((resolve) => {\r\n        let interval = setInterval(() => {\r\n          if (mediaItem.querySelector('.media-item-wrapper')) {\r\n            if (addProgressBar) {\r\n              mediaItem.querySelector('.media-item-wrapper').innerHTML += `\r\n                <div class=\"progress\">\r\n                  <div class=\"percent\">${__('Squeezing...', 'squeeze')}</div>\r\n                  <div class=\"bar\" style=\"width: 200px;\"></div>\r\n                </div>\r\n              `;\r\n            }\r\n            clearInterval(interval);\r\n            resolve();\r\n          }\r\n        }, 1000);\r\n      });\r\n    };\r\n\r\n    const fileID = file.id;\r\n    const attachmentID = response.response;\r\n    const mediaItem = document.getElementById(`media-item-${fileID}`);\r\n\r\n    if (file?._isExcluded) {\r\n      console.warn('File is excluded from compression:', file.name);\r\n      waitForItemLoad(false).then(() => {\r\n        mediaItem.innerHTML += `<div class=\"squeeze_status\">${__('File is excluded from compression:', 'squeeze')} ${file.name}</div>`;\r\n      });\r\n      window.onbeforeunload = null;\r\n      return;\r\n    }\r\n\r\n    if (file?._isFailed) {\r\n      console.warn('File compression failed:', file.name);\r\n      waitForItemLoad(false).then(() => {\r\n        mediaItem.innerHTML += `<div class=\"squeeze_status\">${__('File compression failed:', 'squeeze')} ${file.name}</div>`;\r\n      });\r\n      window.onbeforeunload = null;\r\n      return;\r\n    }\r\n\r\n    window.onbeforeunload = handleOnLeave;\r\n\r\n    waitForItemLoad().then(() => {\r\n      try {\r\n        wp.media.attachment(attachmentID).fetch().then(async function (data) {\r\n          //console.log('Fetched attachment data:', data);\r\n          const attachment = { attributes: data };\r\n\r\n          _helpers_js__WEBPACK_IMPORTED_MODULE_0__.extendAttachment(attachment, file);\r\n\r\n          try {\r\n            const compressData = await Squeeze.handleCompress(attachment);\r\n            const uploadData = await Squeeze.handleUpload({ attachment, base64: compressData });\r\n\r\n            if (uploadData.success) {\r\n              window.onbeforeunload = null;\r\n              mediaItem.innerHTML += `<div class=\"squeeze_status\">${uploadData?.data?.message}</div>`;\r\n              mediaItem.querySelector('.progress')?.remove();\r\n            } else {\r\n              mediaItem.innerHTML += uploadData?.data?.message ?? uploadData?.data ?? uploadData;\r\n              window.onbeforeunload = null;\r\n              mediaItem.querySelector('.progress')?.remove();\r\n            }\r\n          } catch (error) {\r\n            console.error(error);\r\n            mediaItem.innerHTML += error;\r\n            window.onbeforeunload = null;\r\n            mediaItem.querySelector('.progress')?.remove();\r\n          }\r\n        });\r\n      } catch (error) {\r\n        console.error(error);\r\n        mediaItem.innerHTML += error;\r\n        window.onbeforeunload = null;\r\n        mediaItem.querySelector('.progress')?.remove();\r\n      }\r\n    });\r\n  });\r\n}\r\n\r\n\n\n//# sourceURL=webpack:///./assets/js/handlers.js?");
    3030
    3131/***/ }),
     
    3737/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
    3838
    39 eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"base64SizeInBytes\": () => (/* binding */ base64SizeInBytes),\n/* harmony export */   \"base64ToBlob\": () => (/* binding */ base64ToBlob),\n/* harmony export */   \"cachedMediaData\": () => (/* binding */ cachedMediaData),\n/* harmony export */   \"disableAllButtons\": () => (/* binding */ disableAllButtons),\n/* harmony export */   \"disableBulkButtons\": () => (/* binding */ disableBulkButtons),\n/* harmony export */   \"elements\": () => (/* binding */ elements),\n/* harmony export */   \"humanFileSize\": () => (/* binding */ humanFileSize),\n/* harmony export */   \"isDocHidden\": () => (/* binding */ isDocHidden),\n/* harmony export */   \"logMessage\": () => (/* binding */ logMessage),\n/* harmony export */   \"maybeCompressAttachment\": () => (/* binding */ maybeCompressAttachment),\n/* harmony export */   \"populatePathInput\": () => (/* binding */ populatePathInput),\n/* harmony export */   \"removeAllButtons\": () => (/* binding */ removeAllButtons),\n/* harmony export */   \"renderDirectories\": () => (/* binding */ renderDirectories),\n/* harmony export */   \"renderTemplate\": () => (/* binding */ renderTemplate),\n/* harmony export */   \"restoreBulkButtons\": () => (/* binding */ restoreBulkButtons),\n/* harmony export */   \"updateButtonText\": () => (/* binding */ updateButtonText)\n/* harmony export */ });\n\r\n\r\nconst { __ } = wp.i18n; // Import __() from wp.i18n\r\n\r\n// move static helper functions here\r\nconst elements = {\r\n  bulkBtn: document.querySelector(\"[name='squeeze_bulk']\"),\r\n  bulkAgainBtn: document.querySelector(\"[name='squeeze_bulk_again']\"),\r\n  bulkPathBtn: document.querySelector(\"[name='squeeze_bulk_path_button']\"),\r\n  selectPathBtn: document.querySelector(\"[name='squeeze_select_path_button']\"),\r\n  savePathBtn: document.querySelector(\"[name='squeeze_save_path_button']\"),\r\n  pathDialog: document.getElementById(\"squeeze-path-dialog\"),\r\n  closePathDialogBtn: document.querySelector(\"[name='squeeze_close_path_dialog_button']\"),\r\n  pathInput: document.querySelector(\"[name='squeeze_bulk_path']\"),\r\n  pathList: document.querySelector(\".squeeze-path-list\"),\r\n  postsFilterForm: document.querySelector(\"#posts-filter\"),\r\n  dirContainer: document.getElementById(\"squeeze-bulk-directory-list\"),\r\n  bulkLogInput: document.querySelector(\"#squeeze-log-data\"),\r\n  pauseBulkBtn: document.querySelector(\"[name='squeeze_pause_page_bulk']\")\r\n}\r\n\r\nconst cachedMediaData = {\r\n  isPaused: false,\r\n  page: 1,\r\n  process: '',\r\n  mediaIDs: [],\r\n  lastId: 0,\r\n  totalImages: document.querySelector(\"[name='squeeze_bulk_total_images']\")?.value || 0,\r\n  uncompressedImages: document.querySelector(\"[name='squeeze_bulk_uncompressed_images']\")?.value || 0,\r\n  target: null\r\n}\r\n\r\nconst loadTemplate = async (templatePath, data) => {\r\n  const response = await fetch(templatePath);\r\n  let template = await response.text();\r\n\r\n  // Process sub-templates\r\n  const subTemplateRegex = /\\{\\{\\>\\s*(.*?)\\s*\\}\\}/g;\r\n  let match;\r\n  while ((match = subTemplateRegex.exec(template)) !== null) {\r\n    const subTemplatePath = `${squeezeOptions.templateBase}/${match[1].trim()}.html`;\r\n    const subTemplate = await loadTemplate(subTemplatePath, data);\r\n    template = template.replace(match[0], subTemplate);\r\n  }\r\n\r\n  // Function to safely evaluate conditions (supports boolean variables, expressions, AND/OR)\r\n  const evaluateCondition = (condition, data) => {\r\n    try {\r\n      // Convert standalone boolean variables (e.g., webp_lossless) to data['webp_lossless']\r\n      condition = condition.replace(/\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b/g, (match) =>\r\n        match in data ? `data['${match}']` : match\r\n      );\r\n\r\n      return new Function(\"data\", `with(data) { return ${condition}; }`)(data);\r\n    } catch (e) {\r\n      console.error(\"Error evaluating condition:\", condition, e);\r\n      return false;\r\n    }\r\n  };\r\n\r\n  // Recursive function to process nested if-else conditions\r\n  const processIfStatements = (template) => {\r\n    return template.replace(/\\{\\{#if ([\\s\\S]*?)\\}\\}([\\s\\S]*?)\\{\\{\\/if\\}\\}/g, (match, condition, content) => {\r\n      condition = condition.trim();\r\n      const conditionResult = evaluateCondition(condition, data);\r\n\r\n      // Extract and split the if-else blocks\r\n      const elseMatch = content.match(/\\{\\{#else\\}\\}([\\s\\S]*)/);\r\n      const trueBlock = elseMatch ? content.replace(/\\{\\{#else\\}\\}([\\s\\S]*)/, \"\") : content;\r\n      const falseBlock = elseMatch ? elseMatch[1] : \"\";\r\n\r\n      // Process nested if statements recursively\r\n      return processIfStatements(conditionResult ? trueBlock : falseBlock);\r\n    });\r\n  };\r\n\r\n  // Apply recursive processing of if conditions\r\n  template = processIfStatements(template);\r\n\r\n  // Replace variables\r\n  return template.replace(/\\{\\{(.*?)\\}\\}/g, (match, key) => data[key.trim()] || '');\r\n}\r\n\r\nconst renderTemplate = async (templatePath, data, target = null) => {\r\n  const renderedHTML = await loadTemplate(templatePath, data);\r\n\r\n  // Create a temporary container to parse HTML\r\n  const tempContainer = document.createElement(\"template\");\r\n  tempContainer.innerHTML = renderedHTML.trim();\r\n\r\n  if (!target) {\r\n    return tempContainer.content.firstChild;\r\n  }\r\n\r\n  target.appendChild(tempContainer.content.firstChild);\r\n\r\n  // Return the last element of the rendered template\r\n  return target.lastElementChild;\r\n}\r\n\r\nconst logMessage = async (msg, options = {}) => {\r\n  const { mediaLogWrapper = null, isStart = false, isPause = false } = options;\r\n  let { title = '', iconId = 'check-mark-circle-icon' } = options;\r\n\r\n  if (!elements.bulkLogInput) return;\r\n\r\n  if (isStart || isPause) {\r\n    iconId = isPause ? 'pause-button-icon' : 'image-file-icon';\r\n    title = isPause ? __('Bulk squeezing has been paused!', 'squeeze') : `${__('Media', 'squeeze')} ${title}:`;\r\n    return await renderTemplate(squeezeOptions.templates.logWrapper, { title: title, msg: msg, iconId: iconId, isStart: isStart, isPause: isPause }, elements.bulkLogInput);\r\n  } else {\r\n    if (mediaLogWrapper) {\r\n      const process = mediaLogWrapper.querySelector(\".media-log-process\");\r\n      const step = await renderTemplate(squeezeOptions.templates.logStep, { msg: msg, iconId: iconId }, process);\r\n\r\n      if (msg.includes('squeeze-comparison-table')) {\r\n        const comparisonTable = step.querySelector('.squeeze-comparison-table');\r\n        const toggleBtn = await renderTemplate(squeezeOptions.templates.logDetailsButton, { buttonText: __('Show details', 'squeeze') }, mediaLogWrapper);\r\n\r\n        toggleBtn.addEventListener(\"click\", () => {\r\n          comparisonTable.classList.toggle(\"show\");\r\n          toggleBtn.textContent = comparisonTable.classList.contains(\"show\") ? __('Hide details', 'squeeze') : __('Show details', 'squeeze');\r\n        });\r\n        step.closest(\".media-log-wrapper\").appendChild(comparisonTable);\r\n        step.closest(\".media-log-wrapper\").appendChild(toggleBtn);\r\n      }\r\n    } else {\r\n      elements.bulkLogInput.innerHTML += msg + `<br>`;\r\n    }\r\n  }\r\n}\r\n\r\nconst restoreBulkButtons = () => {\r\n  elements.bulkBtn.disabled = false;\r\n  elements.bulkAgainBtn.disabled = false;\r\n  elements.bulkPathBtn.disabled = false;\r\n  elements.selectPathBtn.disabled = false;\r\n  updateButtonText(elements.bulkBtn, __('Run Bulk Squeeze', 'squeeze'), '#play-button-round-icon');\r\n  updateButtonText(elements.bulkAgainBtn, __('Repeat Bulk Squeeze', 'squeeze'), '#combine-left-right-outline-icon');\r\n  updateButtonText(elements.bulkPathBtn, __('Run Directory Squeeze', 'squeeze'), '#play-button-round-icon');\r\n  elements.bulkBtn.dataset.running = 'false';\r\n  elements.bulkAgainBtn.dataset.running = 'false';\r\n  elements.bulkPathBtn.dataset.running = 'false';\r\n\r\n  cachedMediaData.process = '';\r\n  cachedMediaData.mediaIDs = [];\r\n  cachedMediaData.page = 1;\r\n}\r\n\r\nconst disableBulkButtons = () => {\r\n  elements.bulkBtn.disabled = true;\r\n  elements.bulkAgainBtn.disabled = true;\r\n  elements.bulkPathBtn.disabled = true;\r\n  elements.selectPathBtn.disabled = true;\r\n}\r\n\r\nconst disableAllButtons = (buttons) => {\r\n  if (!buttons) return;\r\n  buttons.forEach((btn) => btn.disabled = true);\r\n}\r\n\r\nconst removeAllButtons = (buttons) => {\r\n  if (!buttons) return;\r\n  buttons.forEach((btn) => btn.remove());\r\n}\r\n\r\nconst updateButtonText = (button, text, svgAnchor = false) => {\r\n  button.childNodes.forEach((node) => {\r\n    if (node.nodeName === '#text' && node.textContent.trim() !== '') {\r\n      node.textContent = text;\r\n    }\r\n    if (svgAnchor && node.nodeName === 'svg') {\r\n      node.querySelector('use').setAttribute('xlink:href', svgAnchor);\r\n    }\r\n  });\r\n}\r\n\r\n// Function to render directories in the dialog\r\nconst renderDirectories = async (dirs, parentDir = null, listeners = {}) => {\r\n  if (!dirs) return;\r\n  if (typeof dirs === 'object') dirs = Object.values(dirs);\r\n  if (!elements.dirContainer.classList.contains(\"loaded\")) elements.dirContainer.innerHTML = \"\";\r\n\r\n  if (dirs.length === 0 && !parentDir) {\r\n    const listItem = await renderTemplate(squeezeOptions.templates.directoryItemEmpty, { emptyText: __('No directories found!', 'squeeze') }, elements.dirContainer);\r\n    return;\r\n  }\r\n\r\n  const selectedFolders = JSON.parse(elements.pathInput.value);\r\n  let target;\r\n\r\n  for (const dir of dirs) {\r\n    const listItemClasses = [];\r\n\r\n    if (dir.parent === '/') {\r\n      listItemClasses.push(\"loaded\", \"opened\");\r\n    }\r\n\r\n    if (parentDir) {\r\n      target = parentDir;\r\n    } else if (dir.parent) {\r\n      const parentElement = elements.dirContainer.querySelector(`[data-path=\"${dir.parent}\"]`);\r\n      if (parentElement) {\r\n        target = parentElement;\r\n      } else {\r\n        target = elements.dirContainer;\r\n      }\r\n    } else {\r\n      target = elements.dirContainer;\r\n    }\r\n\r\n    const listItem = await renderTemplate(\r\n      squeezeOptions.templates.directoryItem,\r\n      {\r\n        parent: dir.parent,\r\n        path: dir.path,\r\n        label: dir.name,\r\n        classes: listItemClasses.join(\" \"),\r\n        isWritable: dir.is_writeable && !(Array.isArray(selectedFolders) && selectedFolders.includes(dir.path)),\r\n        isChecked: dir.is_writeable && Array.isArray(selectedFolders) && selectedFolders.includes(dir.path),\r\n      },\r\n      target\r\n    )\r\n\r\n    listItem.querySelector(\"label\").addEventListener(\"click\", listeners.handleDirectoryClick);\r\n    listItem.querySelector(\"input[type='checkbox']\")?.addEventListener(\"change\", listeners.handleDirectoryCheck);\r\n  }\r\n\r\n  elements.dirContainer.classList.add(\"loaded\");\r\n}\r\n\r\nconst populatePathInput = async () => {\r\n  const path = elements.pathInput.value;\r\n  if (!path) return;\r\n\r\n  try {\r\n    const selectedFolders = JSON.parse(path);\r\n    const inputs = elements.pathList.querySelectorAll(\".squeeze-path-list__item\");\r\n\r\n    inputs.forEach(input => input.remove());\r\n\r\n    for (const folder of selectedFolders) {\r\n      const input = await renderTemplate(squeezeOptions.templates.pathListItem, { folder: folder }, elements.pathList);\r\n    }\r\n  } catch (error) {\r\n    alert(__('Error parsing path input!', 'squeeze'));\r\n    console.error('Error parsing path input:', error);\r\n  }\r\n}\r\n\r\nconst getHiddenProp = () => {\r\n  var prefixes = ['webkit', 'moz', 'ms', 'o'];\r\n\r\n  // if 'hidden' is natively supported just return it\r\n  if ('hidden' in document) return 'hidden';\r\n\r\n  // otherwise loop over all the known prefixes until we find one\r\n  for (let i = 0; i < prefixes.length; i++) {\r\n    if ((prefixes[i] + 'Hidden') in document)\r\n      return prefixes[i] + 'Hidden';\r\n  }\r\n\r\n  // otherwise it's not supported\r\n  return null;\r\n}\r\n\r\nconst isDocHidden = () => {\r\n  const prop = getHiddenProp();\r\n  if (!prop) return false;\r\n\r\n  return document[prop];\r\n}\r\n\r\n/**\r\n * @see https://stackoverflow.com/a/20732091\r\n */\r\nconst humanFileSize = (size) => {\r\n  let i = size == 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024));\r\n  return +((size / Math.pow(1024, i)).toFixed(2)) * 1 + ' ' + ['B', 'KB', 'MB', 'GB', 'TB'][i];\r\n}\r\n\r\nconst base64SizeInBytes = (base64) => {\r\n  // Remove data URL prefix if present\r\n  const base64String = base64.split(',')[1] || base64;  \r\n\r\n  // Calculate padding characters ('=' at the end of Base64)\r\n  const padding = (base64String.match(/=+$/) || [\"\"])[0].length;\r\n\r\n  // Compute byte size\r\n  return (base64String.length * 3) / 4 - padding;\r\n}\r\n\r\nconst maybeCompressAttachment = (attachmentType, attachmentSubType, compressOptions) => {\r\n  const isAutoCompress = compressOptions.auto_compress;\r\n  const allowedMimeTypes = ['jpeg', 'png', 'webp', 'avif'];\r\n  const isImage = attachmentType === 'image' && allowedMimeTypes.includes(attachmentSubType);\r\n\r\n  return isImage && isAutoCompress;\r\n};\r\n\r\nconst base64ToBlob = (base64, type = 'image/jpeg') => {\r\n  // Remove data URL prefix if present\r\n  const base64String = base64.split(',')[1] || base64;\r\n\r\n  // Decode Base64 string\r\n  const byteCharacters = atob(base64String);\r\n  const byteNumbers = new Array(byteCharacters.length);\r\n  \r\n  for (let i = 0; i < byteCharacters.length; i++) {\r\n    byteNumbers[i] = byteCharacters.charCodeAt(i);\r\n  }\r\n\r\n  const byteArray = new Uint8Array(byteNumbers);\r\n  return new Blob([byteArray], { type: type });\r\n}\n\n//# sourceURL=webpack:///./assets/js/helpers.js?");
     39eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"base64SizeInBytes\": () => (/* binding */ base64SizeInBytes),\n/* harmony export */   \"base64ToBlob\": () => (/* binding */ base64ToBlob),\n/* harmony export */   \"base64ToFile\": () => (/* binding */ base64ToFile),\n/* harmony export */   \"cachedMediaData\": () => (/* binding */ cachedMediaData),\n/* harmony export */   \"disableAllButtons\": () => (/* binding */ disableAllButtons),\n/* harmony export */   \"disableBulkButtons\": () => (/* binding */ disableBulkButtons),\n/* harmony export */   \"elements\": () => (/* binding */ elements),\n/* harmony export */   \"extendAttachment\": () => (/* binding */ extendAttachment),\n/* harmony export */   \"fileToBase64\": () => (/* binding */ fileToBase64),\n/* harmony export */   \"getFileFromUrl\": () => (/* binding */ getFileFromUrl),\n/* harmony export */   \"handleRemovePathButton\": () => (/* binding */ handleRemovePathButton),\n/* harmony export */   \"humanFileSize\": () => (/* binding */ humanFileSize),\n/* harmony export */   \"isDocHidden\": () => (/* binding */ isDocHidden),\n/* harmony export */   \"logMessage\": () => (/* binding */ logMessage),\n/* harmony export */   \"maybeCompressAttachment\": () => (/* binding */ maybeCompressAttachment),\n/* harmony export */   \"objectToFormData\": () => (/* binding */ objectToFormData),\n/* harmony export */   \"populatePathInput\": () => (/* binding */ populatePathInput),\n/* harmony export */   \"removeAllButtons\": () => (/* binding */ removeAllButtons),\n/* harmony export */   \"renderDirectories\": () => (/* binding */ renderDirectories),\n/* harmony export */   \"renderTemplate\": () => (/* binding */ renderTemplate),\n/* harmony export */   \"restoreBulkButtons\": () => (/* binding */ restoreBulkButtons),\n/* harmony export */   \"updateButtonText\": () => (/* binding */ updateButtonText)\n/* harmony export */ });\n\r\n\r\nconst { __ } = wp.i18n; // Import __() from wp.i18n\r\n\r\n// move static helper functions here\r\nconst elements = {\r\n  bulkBtn: document.querySelector(\"[name='squeeze_bulk']\"),\r\n  bulkAgainBtn: document.querySelector(\"[name='squeeze_bulk_again']\"),\r\n  bulkPathBtn: document.querySelector(\"[name='squeeze_bulk_path_button']\"),\r\n  bulkPathRemoveBtns: document.querySelectorAll(\".squeeze-path-list__remove\"),\r\n  selectPathBtn: document.querySelector(\"[name='squeeze_select_path_button']\"),\r\n  savePathBtn: document.querySelector(\"[name='squeeze_save_path_button']\"),\r\n  pathDialog: document.getElementById(\"squeeze-path-dialog\"),\r\n  closePathDialogBtn: document.querySelector(\"[name='squeeze_close_path_dialog_button']\"),\r\n  pathInput: document.querySelector(\"[name='squeeze_bulk_path']\"),\r\n  pathList: document.querySelector(\".squeeze-path-list\"),\r\n  postsFilterForm: document.querySelector(\"#posts-filter\"),\r\n  dirContainer: document.getElementById(\"squeeze-bulk-directory-list\"),\r\n  bulkLogInput: document.querySelector(\"#squeeze-log-data\"),\r\n  pauseBulkBtn: document.querySelector(\"[name='squeeze_pause_page_bulk']\")\r\n}\r\n\r\nconst cachedMediaData = {\r\n  isPaused: false,\r\n  page: 1,\r\n  process: '',\r\n  mediaIDs: [],\r\n  lastId: 0,\r\n  totalImages: document.querySelector(\"[name='squeeze_bulk_total_images']\")?.value || 0,\r\n  uncompressedImages: document.querySelector(\"[name='squeeze_bulk_uncompressed_images']\")?.value || 0,\r\n  target: null\r\n}\r\n\r\nconst loadTemplate = async (templatePath, data) => {\r\n  const response = await fetch(templatePath);\r\n  let template = await response.text();\r\n\r\n  // Process sub-templates\r\n  const subTemplateRegex = /\\{\\{\\>\\s*(.*?)\\s*\\}\\}/g;\r\n  let match;\r\n  while ((match = subTemplateRegex.exec(template)) !== null) {\r\n    const subTemplatePath = `${squeezeOptions.templateBase}/${match[1].trim()}.html`;\r\n    const subTemplate = await loadTemplate(subTemplatePath, data);\r\n    template = template.replace(match[0], subTemplate);\r\n  }\r\n\r\n  // Function to safely evaluate conditions (supports boolean variables, expressions, AND/OR)\r\n  const evaluateCondition = (condition, data) => {\r\n    try {\r\n      // Convert standalone boolean variables (e.g., webp_lossless) to data['webp_lossless']\r\n      condition = condition.replace(/\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b/g, (match) =>\r\n        match in data ? `data['${match}']` : match\r\n      );\r\n\r\n      return new Function(\"data\", `with(data) { return ${condition}; }`)(data);\r\n    } catch (e) {\r\n      console.error(\"Error evaluating condition:\", condition, e);\r\n      return false;\r\n    }\r\n  };\r\n\r\n  // Recursive function to process nested if-else conditions\r\n  const processIfStatements = (template) => {\r\n    return template.replace(/\\{\\{#if ([\\s\\S]*?)\\}\\}([\\s\\S]*?)\\{\\{\\/if\\}\\}/g, (match, condition, content) => {\r\n      condition = condition.trim();\r\n      const conditionResult = evaluateCondition(condition, data);\r\n\r\n      // Extract and split the if-else blocks\r\n      const elseMatch = content.match(/\\{\\{#else\\}\\}([\\s\\S]*)/);\r\n      const trueBlock = elseMatch ? content.replace(/\\{\\{#else\\}\\}([\\s\\S]*)/, \"\") : content;\r\n      const falseBlock = elseMatch ? elseMatch[1] : \"\";\r\n\r\n      // Process nested if statements recursively\r\n      return processIfStatements(conditionResult ? trueBlock : falseBlock);\r\n    });\r\n  };\r\n\r\n  // Apply recursive processing of if conditions\r\n  template = processIfStatements(template);\r\n\r\n  // Replace variables\r\n  return template.replace(/\\{\\{(.*?)\\}\\}/g, (match, key) => data[key.trim()] || '');\r\n}\r\n\r\nconst renderTemplate = async (templatePath, data, target = null) => {\r\n  const renderedHTML = await loadTemplate(templatePath, data);\r\n\r\n  // Create a temporary container to parse HTML\r\n  const tempContainer = document.createElement(\"template\");\r\n  tempContainer.innerHTML = renderedHTML.trim();\r\n\r\n  if (!target) {\r\n    return tempContainer.content.firstChild;\r\n  }\r\n\r\n  target.appendChild(tempContainer.content.firstChild);\r\n\r\n  // Return the last element of the rendered template\r\n  return target.lastElementChild;\r\n}\r\n\r\nconst logMessage = async (msg, options = {}) => {\r\n  const { mediaLogWrapper = null, isStart = false, isPause = false } = options;\r\n  let { title = '', iconId = 'check-mark-circle-icon' } = options;\r\n\r\n  if (!elements.bulkLogInput) return;\r\n\r\n  if (isStart || isPause) {\r\n    iconId = isPause ? 'pause-button-icon' : 'image-file-icon';\r\n    title = isPause ? __('Bulk squeezing has been paused!', 'squeeze') : `${__('Media', 'squeeze')} ${title}:`;\r\n    return await renderTemplate(squeezeOptions.templates.logWrapper, { title: title, msg: msg, iconId: iconId, isStart: isStart, isPause: isPause }, elements.bulkLogInput);\r\n  } else {\r\n    if (mediaLogWrapper) {\r\n      const process = mediaLogWrapper.querySelector(\".media-log-process\");\r\n      const step = await renderTemplate(squeezeOptions.templates.logStep, { msg: msg, iconId: iconId }, process);\r\n\r\n      if (msg && msg.includes('squeeze-comparison-table')) {\r\n        const comparisonTable = step.querySelector('.squeeze-comparison-table');\r\n        const toggleBtn = await renderTemplate(squeezeOptions.templates.logDetailsButton, { buttonText: __('Show details', 'squeeze') }, mediaLogWrapper);\r\n\r\n        toggleBtn.addEventListener(\"click\", () => {\r\n          comparisonTable.classList.toggle(\"show\");\r\n          toggleBtn.textContent = comparisonTable.classList.contains(\"show\") ? __('Hide details', 'squeeze') : __('Show details', 'squeeze');\r\n        });\r\n        step.closest(\".media-log-wrapper\").appendChild(comparisonTable);\r\n        step.closest(\".media-log-wrapper\").appendChild(toggleBtn);\r\n      }\r\n    } else {\r\n      elements.bulkLogInput.innerHTML += msg + `<br>`;\r\n    }\r\n  }\r\n}\r\n\r\nconst restoreBulkButtons = () => {\r\n  elements.bulkBtn.disabled = false;\r\n  elements.bulkAgainBtn.disabled = false;\r\n  elements.bulkPathBtn.disabled = false;\r\n  elements.selectPathBtn.disabled = false;\r\n  updateButtonText(elements.bulkBtn, __('Run Bulk Squeeze', 'squeeze'), '#play-button-round-icon');\r\n  updateButtonText(elements.bulkAgainBtn, __('Repeat Bulk Squeeze', 'squeeze'), '#combine-left-right-outline-icon');\r\n  updateButtonText(elements.bulkPathBtn, __('Run Directory Squeeze', 'squeeze'), '#play-button-round-icon');\r\n  elements.bulkBtn.dataset.running = 'false';\r\n  elements.bulkAgainBtn.dataset.running = 'false';\r\n  elements.bulkPathBtn.dataset.running = 'false';\r\n  elements.bulkPathRemoveBtns?.forEach((btn) => {\r\n    btn.disabled = false;\r\n  });\r\n\r\n  cachedMediaData.process = '';\r\n  cachedMediaData.mediaIDs = [];\r\n  cachedMediaData.page = 1;\r\n}\r\n\r\nconst disableBulkButtons = () => {\r\n  elements.bulkBtn.disabled = true;\r\n  elements.bulkAgainBtn.disabled = true;\r\n  elements.bulkPathBtn.disabled = true;\r\n  elements.selectPathBtn.disabled = true;\r\n  elements.bulkPathRemoveBtns?.forEach((btn) => btn.disabled = true);\r\n}\r\n\r\nconst disableAllButtons = (buttons) => {\r\n  if (!buttons) return;\r\n  buttons.forEach((btn) => btn.disabled = true);\r\n}\r\n\r\nconst removeAllButtons = (buttons) => {\r\n  if (!buttons) return;\r\n  buttons.forEach((btn) => btn.remove());\r\n}\r\n\r\nconst updateButtonText = (button, text, svgAnchor = false) => {\r\n  button.childNodes.forEach((node) => {\r\n    if (node.nodeName === '#text' && node.textContent.trim() !== '') {\r\n      node.textContent = text;\r\n    }\r\n    if (svgAnchor && node.nodeName === 'svg') {\r\n      node.querySelector('use').setAttribute('xlink:href', svgAnchor);\r\n    }\r\n  });\r\n}\r\n\r\n// Function to render directories in the dialog\r\nconst renderDirectories = async (dirs, parentDir = null, listeners = {}) => {\r\n  if (!dirs) return;\r\n  if (typeof dirs === 'object') dirs = Object.values(dirs);\r\n  if (!elements.dirContainer.classList.contains(\"loaded\")) elements.dirContainer.innerHTML = \"\";\r\n\r\n  if (dirs.length === 0 && !parentDir) {\r\n    const listItem = await renderTemplate(squeezeOptions.templates.directoryItemEmpty, { emptyText: __('No directories found!', 'squeeze') }, elements.dirContainer);\r\n    return;\r\n  }\r\n\r\n  const selectedFolders = JSON.parse(elements.pathInput.value);\r\n  let target;\r\n\r\n  for (const dir of dirs) {\r\n    const listItemClasses = [];\r\n\r\n    if (dir.parent === '/') {\r\n      listItemClasses.push(\"loaded\", \"opened\");\r\n    }\r\n\r\n    if (parentDir) {\r\n      target = parentDir;\r\n    } else if (dir.parent) {\r\n      const parentElement = elements.dirContainer.querySelector(`[data-path=\"${dir.parent}\"]`);\r\n      if (parentElement) {\r\n        target = parentElement;\r\n      } else {\r\n        target = elements.dirContainer;\r\n      }\r\n    } else {\r\n      target = elements.dirContainer;\r\n    }\r\n\r\n    const listItem = await renderTemplate(\r\n      squeezeOptions.templates.directoryItem,\r\n      {\r\n        parent: dir.parent,\r\n        path: dir.path,\r\n        label: dir.name,\r\n        classes: listItemClasses.join(\" \"),\r\n        isWritable: dir.is_writeable && !(Array.isArray(selectedFolders) && selectedFolders.includes(dir.path)),\r\n        isChecked: dir.is_writeable && Array.isArray(selectedFolders) && selectedFolders.includes(dir.path),\r\n      },\r\n      target\r\n    )\r\n\r\n    listItem.querySelector(\"label\").addEventListener(\"click\", listeners.handleDirectoryClick);\r\n    listItem.querySelector(\"input[type='checkbox']\")?.addEventListener(\"change\", listeners.handleDirectoryCheck);\r\n  }\r\n\r\n  elements.dirContainer.classList.add(\"loaded\");\r\n}\r\n\r\nconst handleRemovePathButton = (e) => {\r\n  e.preventDefault();\r\n  const item = e.target.closest(\".squeeze-path-list__item\");\r\n  if (item) {\r\n    item.remove();\r\n    const currentPaths = Array.from(elements.pathList.querySelectorAll(\".squeeze-path-list__input\"))\r\n      .map(input => input.value.trim())\r\n      .filter(value => value !== '');\r\n    elements.pathInput.value = JSON.stringify(currentPaths);\r\n  }\r\n}\r\n\r\nconst populatePathInput = async () => {\r\n  const path = elements.pathInput.value;\r\n  if (!path) return;\r\n\r\n  try {\r\n    const selectedFolders = JSON.parse(path);\r\n    const items = elements.pathList.querySelectorAll(\".squeeze-path-list__item\");\r\n\r\n    items.forEach(item => item.remove());\r\n\r\n    for (const folder of selectedFolders) {\r\n      const item = await renderTemplate(squeezeOptions.templates.pathListItem, { folder: folder }, elements.pathList);\r\n      const removeButton = item.querySelector(\".squeeze-path-list__remove\");\r\n      removeButton.addEventListener(\"click\", handleRemovePathButton);\r\n\r\n    }\r\n  } catch (error) {\r\n    alert(__('Error parsing path input!', 'squeeze'));\r\n    console.error('Error parsing path input:', error);\r\n  }\r\n}\r\n\r\nconst getHiddenProp = () => {\r\n  var prefixes = ['webkit', 'moz', 'ms', 'o'];\r\n\r\n  // if 'hidden' is natively supported just return it\r\n  if ('hidden' in document) return 'hidden';\r\n\r\n  // otherwise loop over all the known prefixes until we find one\r\n  for (let i = 0; i < prefixes.length; i++) {\r\n    if ((prefixes[i] + 'Hidden') in document)\r\n      return prefixes[i] + 'Hidden';\r\n  }\r\n\r\n  // otherwise it's not supported\r\n  return null;\r\n}\r\n\r\nconst isDocHidden = () => {\r\n  const prop = getHiddenProp();\r\n  if (!prop) return false;\r\n\r\n  return document[prop];\r\n}\r\n\r\n/**\r\n * @see https://stackoverflow.com/a/20732091\r\n */\r\nconst humanFileSize = (size) => {\r\n  let i = size == 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024));\r\n  return +((size / Math.pow(1024, i)).toFixed(2)) * 1 + ' ' + ['B', 'KB', 'MB', 'GB', 'TB'][i];\r\n}\r\n\r\nconst base64SizeInBytes = (base64) => {\r\n  // Remove data URL prefix if present\r\n  const base64String = base64.split(',')[1] || base64;  \r\n\r\n  // Calculate padding characters ('=' at the end of Base64)\r\n  const padding = (base64String.match(/=+$/) || [\"\"])[0].length;\r\n\r\n  // Compute byte size\r\n  return (base64String.length * 3) / 4 - padding;\r\n}\r\n\r\nconst maybeCompressAttachment = (attachmentType, attachmentSubType, compressOptions = null) => {\r\n  const isAutoCompress = compressOptions?.auto_compress ?? true;\r\n  const allowedMimeTypes = ['jpeg', 'png', 'webp', 'avif'];\r\n  const isImage = attachmentType === 'image' && allowedMimeTypes.includes(attachmentSubType);\r\n\r\n  return isImage && isAutoCompress;\r\n};\r\n\r\nconst base64ToBlob = (base64, type = 'image/jpeg') => {\r\n  // Remove data URL prefix if present\r\n  const base64String = base64.split(',')[1] || base64;\r\n\r\n  // Decode Base64 string\r\n  const byteCharacters = atob(base64String);\r\n  const byteNumbers = new Array(byteCharacters.length);\r\n  \r\n  for (let i = 0; i < byteCharacters.length; i++) {\r\n    byteNumbers[i] = byteCharacters.charCodeAt(i);\r\n  }\r\n\r\n  const byteArray = new Uint8Array(byteNumbers);\r\n  return new Blob([byteArray], { type: type });\r\n}\r\n\r\nconst base64ToFile = (base64, fileName = 'image.jpg', type = 'image/jpeg') => {\r\n  const blob = base64ToBlob(base64, type);\r\n  return new File([blob], fileName, { type: type });\r\n}\r\n\r\nconst fileToBase64 = (file) => {\r\n  return new Promise((resolve, reject) => {\r\n    const reader = new FileReader();\r\n    reader.onload = () => resolve(reader.result);\r\n    reader.onerror = (error) => reject(error);\r\n    reader.readAsDataURL(file);\r\n  });\r\n}\r\n\r\nfunction objectToFormData(obj, fd = null, parentKey = null) {\r\n  const formData = fd || new FormData();\r\n\r\n  for (const key in obj) {\r\n    if (!obj.hasOwnProperty(key)) continue;\r\n    const value = obj[key];\r\n\r\n    // build the form key: either \"foo\", \"parent[foo]\" or \"parent[]\" for arrays\r\n    const formKey = parentKey\r\n      ? Array.isArray(obj)\r\n        ? `${parentKey}[]`\r\n        : `${parentKey}[${key}]`\r\n      : key;\r\n\r\n    // Files or Blobs go straight in\r\n    if (value instanceof File || value instanceof Blob) {\r\n      formData.append(formKey, value, value.name);\r\n    }\r\n    // Arrays: recurse so they become key[]=val0, key[]=val1…\r\n    else if (Array.isArray(value)) {\r\n      objectToFormData(value, formData, formKey);\r\n    }\r\n    // Plain objects: recurse so they become key[subkey]=subval\r\n    else if (\r\n      value !== null &&\r\n      typeof value === 'object' &&\r\n      !(value instanceof Date)\r\n    ) {\r\n      objectToFormData(value, formData, formKey);\r\n    }\r\n    // Dates: convert to ISO string (or format as you like)\r\n    else if (value instanceof Date) {\r\n      formData.append(formKey, value.toISOString());\r\n    }\r\n    // Everything else (number, string, boolean, null, undefined)\r\n    else {\r\n      // Explicitly convert undefined to empty string so PHP sees it\r\n      const stringVal =\r\n        value === undefined || value === null ? '' : String(value);\r\n      formData.append(formKey, stringVal);\r\n    }\r\n  }\r\n\r\n  return formData;\r\n}\r\n\r\n/**\r\n * Extend the attachment object with additional data from the file.\r\n * @param {object} attachment \r\n * @param {object} file \r\n * @returns {object} — the extended attachment object.\r\n */\r\nconst extendAttachment = async (attachment, file) => {\r\n  if (typeof attachment !== 'object' || !attachment.attributes) {\r\n    console.warn('Invalid attachment object:', attachment);\r\n    return;\r\n  }\r\n\r\n  const attributes = attachment.attributes;\r\n\r\n  if (file?.base64) {\r\n    attributes.base64Compressed = file.base64; // Use the base64 data from the attachment\r\n  }\r\n\r\n  if (file?.base64Webp) {\r\n    attributes.base64WebpCompressed = file.base64Webp; // Use the WebP base64 data from the attachment\r\n  }\r\n\r\n  if (file?.originalFile) {\r\n    attributes.originalFile = file.originalFile; // Use the original file from the attachment to be able to create a backup\r\n  }\r\n\r\n  return attachment;\r\n}\r\n\r\nconst getFileFromUrl = async (url, filename, format) => {\r\n  const response = await fetch(url);\r\n  const blob = await response.blob();\r\n  const mimeType = format ? `image/${format}` : blob.type;\r\n  return new File([blob], filename, { type: mimeType });\r\n}\n\n//# sourceURL=webpack:///./assets/js/helpers.js?");
    4040
    4141/***/ }),
     
    4747/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
    4848
    49 eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ SQUEEZE)\n/* harmony export */ });\n\r\n\r\nconst { __ } = wp.i18n; // Import __() from wp.i18n\r\n\r\nclass SQUEEZE {\r\n\r\n  constructor(squeeze) {\r\n    this.options = JSON.parse(squeeze.options); // plugin options\r\n    this.nonce = squeeze.nonce; // nonce\r\n    this.ajaxUrl = squeeze.ajaxUrl; // ajax url\r\n    this.timeout = parseInt(this.options.timeout) * 1000; // convert to milliseconds\r\n    this.poolSize = navigator.hardwareConcurrency || 1; // number of threads\r\n  }\r\n\r\n  handleCompress = async ( attachment ) => {\r\n    const attachmentData = attachment.attributes;\r\n    const url = attachmentData?.originalImageURL ?? attachmentData.url;\r\n    const mime = attachmentData.mime;\r\n    const name = attachmentData.name;\r\n    const filename = attachmentData?.originalImageName ?? attachmentData.filename;\r\n    const attachmentID = attachmentData.id;\r\n    const sizes = attachmentData.sizes;\r\n    const format = mime.split(\"/\")[1];\r\n    const sourceType = format;\r\n    const outputType = format;\r\n    const skipFull = attachmentData.originalImageName === undefined ? true : false;\r\n    const timeout = this.timeout;\r\n    const isPreview = attachmentData?.isPreview ?? false;\r\n    const file = attachmentData?.file ?? null;\r\n\r\n    //console.log(attachmentData, 'attachmentData')\r\n\r\n    const worker = new Worker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u(\"assets_js_worker_js\"), __webpack_require__.b), {type: undefined}); // worker url\r\n    worker.postMessage({\r\n      action: 'compress',\r\n      format,\r\n      url,\r\n      name,\r\n      sourceType,\r\n      outputType,\r\n      mime,\r\n      sizes,\r\n      skipFull,\r\n      timeout,\r\n      isPreview,\r\n      file,\r\n      options: this.options,\r\n      //urlOriginal: urlOriginal,\r\n    });\r\n\r\n    return new Promise((resolve, reject) => {\r\n      const timeoutId = setTimeout(() => {\r\n        worker.terminate();\r\n        console.warn('Worker terminated');\r\n        reject(__('Request timed out.', 'squeeze'));\r\n      }, timeout);\r\n\r\n      worker.onmessage = (event) => {\r\n        clearTimeout(timeoutId);\r\n        if (event.data.error) {\r\n          reject(event.data.error);\r\n        } else {\r\n          resolve(event.data);\r\n        }\r\n        worker.terminate();\r\n      };\r\n\r\n      worker.onerror = (error) => {\r\n        clearTimeout(timeoutId);\r\n        reject(`Worker error: ${error.message}`);\r\n      };\r\n    });\r\n\r\n  }\r\n\r\n  handleUpload = async ({ attachment, base64, type = 'uncompressed', mediaIDs = [] }) => {\r\n\r\n    const attachmentData = attachment.attributes;\r\n    const url = attachmentData?.originalImageURL ?? attachmentData.url;\r\n    const mime = attachmentData.mime;\r\n    const filename = attachmentData?.originalImageName ?? attachmentData.filename;\r\n    const attachmentID = attachmentData.id;\r\n    const format = mime.split(\"/\")[1];\r\n    const sizes = attachmentData.sizes;\r\n\r\n    //console.log(attachmentData, 'attachmentData')\r\n\r\n    const data = {\r\n      action: 'squeeze_update_attachment',\r\n      _ajax_nonce: this.nonce,\r\n      filename: filename,\r\n      type: 'image',\r\n      format: format,\r\n      base64: base64.base64,\r\n      base64Sizes: base64.base64Sizes,\r\n      base64Webp: base64.base64Webp,\r\n      base64SizesWebp: base64.base64SizesWebp,\r\n      attachmentID: attachmentID,\r\n      url: url,\r\n      process: type,\r\n    }\r\n\r\n    console.log(data, 'squeeze_update_attachment') \r\n\r\n    try {\r\n      const uploadResponse = await jQuery.ajax({\r\n      url: this.ajaxUrl, // + '111',\r\n      type: 'POST',\r\n      data: data,\r\n      });\r\n\r\n      //if (type === 'uncompressed' || type === 'all' || type === 'path') {\r\n      //if (uploadResponse.success) {\r\n        uploadResponse['mediaIDs'] = mediaIDs;\r\n      //}\r\n\r\n      uploadResponse['filename'] = filename;\r\n      uploadResponse['url'] = url;\r\n      uploadResponse['sizes'] = sizes;\r\n\r\n      return uploadResponse;\r\n      \r\n    } catch (error) {\r\n      return {\r\n      'mediaIDs': mediaIDs,\r\n      'data': error.message,\r\n      'success': false\r\n      };\r\n    }\r\n\r\n  }\r\n\r\n  handleBulkUpload = async (type = 'uncompressed', mediaIDs = []) => {\r\n    let currentID;\r\n    let attachment;\r\n\r\n    switch (type) {\r\n      case 'all':\r\n      case 'uncompressed':\r\n        currentID = mediaIDs[0];\r\n        break;\r\n      case 'path':\r\n        currentID = mediaIDs[0]?.filename;\r\n        break;\r\n      default:\r\n        currentID = 0;\r\n        break;\r\n    }\r\n\r\n    if (type === 'path') {\r\n\r\n      \r\n\r\n      attachment = {\r\n        attributes: {\r\n          url: mediaIDs[0].url,\r\n          mime: mediaIDs[0].mime,\r\n          name: mediaIDs[0].name,\r\n          filename: mediaIDs[0].filename,\r\n          id: mediaIDs[0].id,\r\n          sizes: mediaIDs[0]?.sizes,\r\n        }\r\n      }\r\n\r\n    } else {\r\n\r\n      const attachmentResponse = await this.getAttachment(currentID); \r\n      if (attachmentResponse.success === false) {\r\n        if (Array.isArray(mediaIDs)) mediaIDs.shift();\r\n        return {\r\n          'mediaIDs': mediaIDs,\r\n          'data': attachmentResponse.data\r\n        }\r\n      }\r\n      const attachmentData = attachmentResponse.data;\r\n      attachment = {\r\n        attributes: {\r\n          url: attachmentData.url,\r\n          mime: attachmentData.mime,\r\n          name: attachmentData.name,\r\n          filename: attachmentData.filename,\r\n          id: attachmentData.id,\r\n          sizes: attachmentData.sizes,\r\n        }\r\n      }\r\n\r\n    }\r\n\r\n    if (Array.isArray(mediaIDs)) mediaIDs.shift();\r\n\r\n    const mediaType = attachment.attributes.mime.split(\"/\")[0];\r\n    const mediaSubType = attachment.attributes.mime.split(\"/\")[1];\r\n\r\n    if (!this.maybeCompressAttachment(mediaType, mediaSubType)) {\r\n      return {\r\n        'mediaIDs': mediaIDs,\r\n        'data': __('Skipped', 'squeeze')\r\n      }\r\n    }\r\n\r\n    try {\r\n      const compressData = await this.handleCompress( attachment );\r\n      const uploadData = await this.handleUpload({ attachment: attachment, base64: compressData, type: type, mediaIDs: mediaIDs })\r\n\r\n      return uploadData;\r\n\r\n    } catch (error) {\r\n      return {\r\n        'mediaIDs': mediaIDs,\r\n        'data': error.message,\r\n        'success': false\r\n      }\r\n    }\r\n\r\n  }\r\n\r\n  maybeCompressAttachment = (attachmentType, attachmentSubType) => {\r\n    const allowedMimeTypes = ['jpeg', 'png', 'webp', 'avif'];\r\n    const isImage = attachmentType === 'image' && allowedMimeTypes.includes(attachmentSubType)\r\n\r\n    if (isImage) {\r\n      return true;\r\n    }\r\n\r\n    return false;\r\n  }\r\n\r\n  \r\n\r\n  handleRestore = async (attachmentID) => {\r\n    const data = {\r\n      action: 'squeeze_restore_attachment',\r\n      _ajax_nonce: this.nonce,\r\n      attachmentID: attachmentID,\r\n    };\r\n\r\n    const response = await jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  };\r\n\r\n  // Get list of attachments by path\r\n  getAttachmentsByPath = async (path) => {\r\n\r\n    const data = {\r\n      action: 'squeeze_get_attachment_by_path',\r\n      path: path,\r\n      _ajax_nonce: this.nonce,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  getAttachment = async (attachmentID) => {\r\n    const data = {\r\n      action: 'squeeze_get_attachment',\r\n      _ajax_nonce: this.nonce,\r\n      attachmentID: attachmentID,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  getNextAttachments = async (page = 1, type = 'uncompressed', lastId = 0) => {\r\n    const data = {\r\n      action: 'squeeze_get_next_attachments',\r\n      _ajax_nonce: this.nonce,\r\n      page: page,\r\n      type: type,\r\n      lastId: lastId,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  getDirectories = async (parentDir = false) => {\r\n    const data = {\r\n      action: 'squeeze_get_directories',\r\n      _ajax_nonce: this.nonce,\r\n    }\r\n\r\n    if (parentDir) {\r\n      data['parentDir'] = parentDir;\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  \r\n\r\n  setOptions = async (options) => {\r\n    const data = {\r\n      action: 'squeeze_set_options',\r\n      _ajax_nonce: this.nonce,\r\n      options: options,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  /*\r\n  getSizesFromFile = (file) => {\r\n    if (!file) return;\r\n\r\n    // get list of thumbnails from file\r\n    const sizes = {};\r\n    \r\n    const fd = new FormData();\r\n    fd.append('action', 'squeeze_get_sizes_from_file');\r\n    fd.append('_ajax_nonce', this.nonce);\r\n    fd.append('file', file);\r\n\r\n    jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: fd,\r\n      processData: false,\r\n      contentType: false,\r\n      async: false, // synchronous request\r\n    }).done((response) => {\r\n      console.log(response, 'getSizesFromFile response');\r\n      if (response.success) {\r\n        Object.keys(response.data).forEach((size) => {\r\n          sizes[size] = response.data[size];\r\n        });\r\n      } else {\r\n        console.error('Error getting sizes from file:', response.data);\r\n      }\r\n    }).fail((error) => {\r\n      console.error('AJAX error:', error);\r\n    });\r\n\r\n    return sizes;\r\n\r\n  }\r\n  */\r\n\r\n}\n\n//# sourceURL=webpack:///./assets/js/squeeze.js?");
     49eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ SQUEEZE)\n/* harmony export */ });\n/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./helpers.js */ \"./assets/js/helpers.js\");\n/* harmony import */ var browser_image_compression__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! browser-image-compression */ \"./node_modules/browser-image-compression/dist/browser-image-compression.mjs\");\n/* harmony import */ var _jsquash_webp__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @jsquash/webp */ \"./node_modules/@jsquash/webp/encode.js\");\n\r\n\r\n\r\n\r\n\r\n\r\nconst { __ } = wp.i18n; // Import __() from wp.i18n\r\n\r\nclass SQUEEZE {\r\n\r\n  constructor(squeeze) {\r\n    this.options = JSON.parse(squeeze.options); // plugin options\r\n    this.nonce = squeeze.nonce; // nonce\r\n    this.ajaxUrl = squeeze.ajaxUrl; // ajax url\r\n    this.timeout = parseInt(this.options.timeout) * 1000; // convert to milliseconds\r\n    this.poolSize = navigator.hardwareConcurrency || 1; // number of threads\r\n  }\r\n\r\n  handleCompress = async ( attachment, type = 'uncompressed' ) => {\r\n    const attachmentData = attachment.attributes;\r\n    const url = attachmentData?.originalImageURL ?? attachmentData.url;\r\n    const mime = attachmentData.mime;\r\n    const name = attachmentData.name;\r\n    const filename = attachmentData?.originalImageName ?? attachmentData.filename;\r\n    const attachmentID = attachmentData.id;\r\n    const sizes = attachmentData.sizes;\r\n    const format = mime.split(\"/\")[1];\r\n    const sourceType = format;\r\n    const outputType = format;\r\n    const skipFull = attachmentData?.skipFull ?? attachmentData.originalImageName === undefined ? true : false;\r\n    const timeout = this.timeout;\r\n    const isPreview = attachmentData?.isPreview ?? false;\r\n    const file = attachmentData?.file ?? null; // the original file, it passed for the newly uploaded attachment to compress it\r\n\r\n    // the original compressed image base64, it passed when the attachment was already compressed and we need to compress thumbs only\r\n    // we pass it in order to prevent re-compressing the original image when we need to compress thumbs only\r\n    const base64Compressed = attachmentData?.base64Compressed ?? null; \r\n    const base64WebpCompressed = attachmentData?.base64WebpCompressed ?? null; // the original compressed webp image base64\r\n\r\n    const worker = new Worker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u(\"assets_js_worker_js\"), __webpack_require__.b), {type: undefined}); // worker url\r\n    const channel = new MessageChannel();\r\n    worker.postMessage({\r\n      action: 'compress',\r\n      format,\r\n      url,\r\n      name,\r\n      sourceType,\r\n      outputType,\r\n      mime,\r\n      sizes,\r\n      skipFull,\r\n      timeout,\r\n      isPreview,\r\n      file,\r\n      base64Compressed,\r\n      base64WebpCompressed,\r\n      type,\r\n      options: this.options,\r\n      //urlOriginal: urlOriginal,\r\n    }, [channel.port2]);\r\n\r\n    // Listen for compression requests from the worker via port1\r\n    channel.port1.onmessage = async (ev) => {\r\n      //console.log(\"Worker received compression request:\", ev.data);\r\n      const { id, action, fileOrArrayBuffer, mime, options } = ev.data;\r\n      if (action !== 'imageCompression') return;\r\n\r\n      try {\r\n        // Accept ArrayBuffer or Blob\r\n        const blob = (fileOrArrayBuffer instanceof ArrayBuffer)\r\n          ? new Blob([this.toUint8Array(fileOrArrayBuffer)], { type: mime })\r\n          : fileOrArrayBuffer;\r\n\r\n        const compressedBlob = await (0,browser_image_compression__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(blob, { useWebWorker: true, ...(options || {}) });\r\n\r\n        // quick checks\r\n        //console.log('compressedBlob.type, size:', compressedBlob.type, compressedBlob.size);\r\n        // normalize final binary\r\n        const compressedArrayBuffer = await compressedBlob.arrayBuffer();\r\n\r\n        // Reply with the compressed ArrayBuffer (transfer to avoid copy)\r\n        channel.port1.postMessage({ id, ok: true, arrayBuffer: compressedArrayBuffer }, [compressedArrayBuffer]);\r\n      } catch (err) {\r\n        channel.port1.postMessage({ id, ok: false, error: err.message || String(err) });\r\n      }\r\n    }\r\n\r\n    return new Promise((resolve, reject) => {\r\n      const timeoutId = setTimeout(() => {\r\n        worker.terminate();\r\n        console.warn('Worker compress terminated', name, sourceType, outputType);\r\n        reject(__('Request timed out.', 'squeeze'));\r\n      }, timeout);\r\n\r\n      worker.onmessage = (event) => {\r\n        clearTimeout(timeoutId);\r\n        if (event.data.error) {\r\n          reject(event.data.error);\r\n        } else {\r\n          resolve(event.data);\r\n        }\r\n        worker.terminate();\r\n      };\r\n\r\n      worker.onerror = (error) => {\r\n        clearTimeout(timeoutId);\r\n        reject(`Worker error: ${error.message}`);\r\n      };\r\n    });\r\n\r\n  }\r\n\r\n  handleUpload = async ({ attachment, base64, type = 'uncompressed', mediaIDs = [] }) => {\r\n\r\n    const attachmentData = attachment.attributes;\r\n    const url = attachmentData?.originalImageURL ?? attachmentData.url;\r\n    const mime = attachmentData.mime;\r\n    const filename = attachmentData?.originalImageName ?? attachmentData.filename;\r\n    const attachmentID = attachmentData.id;\r\n    const format = base64?.isDirectWebp && type !== 'path' ? 'webp' : mime.split(\"/\")[1];\r\n    const sizes = attachmentData.sizes;\r\n\r\n    const isDirectWebp = base64?.isDirectWebp && mime !== 'image/webp';\r\n    const isBackupOriginal = this.options?.backup_original ?? false; // check if backup original is enabled\r\n    let originalFile = attachmentData?.originalFile ?? null; // the original file, used for creating backup\r\n    \r\n    // if originalFile is not provided, try to get it from the URL\r\n    // used when the attachment needs to be converted to webp from jpg or png\r\n    if (!originalFile && type !== 'path' && isBackupOriginal && isDirectWebp) {\r\n      const file = await (0,_helpers_js__WEBPACK_IMPORTED_MODULE_0__.getFileFromUrl)(url, filename, mime.split(\"/\")[1])\r\n      //console.log('conveting original file to webp', file);\r\n      originalFile = await this.convertFileToWebp(file);\r\n    }\r\n    //console.log('handleUpload attachmentData', attachmentData)\r\n\r\n    const data = {\r\n      action: 'squeeze_update_attachment',\r\n      _ajax_nonce: this.nonce,\r\n      filename: filename,\r\n      type: 'image',\r\n      format: format,\r\n      base64: base64.base64,\r\n      base64Sizes: base64.base64Sizes,\r\n      base64Webp: base64.base64Webp,\r\n      base64SizesWebp: base64.base64SizesWebp,\r\n      attachmentID: attachmentID,\r\n      url: url,\r\n      process: type,\r\n      originalFile: originalFile,\r\n    }\r\n\r\n    const formData = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_0__.objectToFormData)(data);\r\n\r\n    //console.log('squeeze_update_attachment', JSON.stringify(data, null, 2));\r\n\r\n    try {\r\n      const uploadResponse = await jQuery.ajax({\r\n      url: this.ajaxUrl, // + '111',\r\n      type: 'POST',\r\n      data: formData,\r\n      processData: false,  // very important!\r\n      contentType: false,  // very important!\r\n      });\r\n\r\n      //if (uploadResponse.success) {\r\n        uploadResponse['mediaIDs'] = mediaIDs;\r\n      //}\r\n\r\n      if (!uploadResponse?.data?.url) {\r\n        uploadResponse.url = url; // fallback to original URL if not provided\r\n      }\r\n\r\n      //console.log('uploadResponse', JSON.stringify(uploadResponse, null, 2));\r\n\r\n      return uploadResponse;\r\n      \r\n    } catch (error) {\r\n      return {\r\n      'mediaIDs': mediaIDs,\r\n      'data': error.message,\r\n      'success': false\r\n      };\r\n    }\r\n\r\n  }\r\n\r\n  handleBulkUpload = async (type = 'uncompressed', mediaIDs = []) => {\r\n    let currentID;\r\n    let attachment;\r\n\r\n    switch (type) {\r\n      case 'all':\r\n      case 'uncompressed':\r\n        currentID = mediaIDs[0];\r\n        break;\r\n      case 'path':\r\n        currentID = mediaIDs[0]?.filename;\r\n        break;\r\n      default:\r\n        currentID = 0;\r\n        break;\r\n    }\r\n\r\n    if (type === 'path') {\r\n\r\n      \r\n\r\n      attachment = {\r\n        attributes: {\r\n          url: mediaIDs[0].url,\r\n          mime: mediaIDs[0].mime,\r\n          name: mediaIDs[0].name,\r\n          filename: mediaIDs[0].filename,\r\n          id: mediaIDs[0].id,\r\n          sizes: mediaIDs[0]?.sizes,\r\n        }\r\n      }\r\n\r\n    } else {\r\n\r\n      const attachmentResponse = await this.getAttachment(currentID); \r\n      if (attachmentResponse.success === false) {\r\n        if (Array.isArray(mediaIDs)) mediaIDs.shift();\r\n        return {\r\n          'mediaIDs': mediaIDs,\r\n          'data': attachmentResponse.data\r\n        }\r\n      }\r\n      const attachmentData = attachmentResponse.data;\r\n      attachment = {\r\n        attributes: {\r\n          url: attachmentData.url,\r\n          mime: attachmentData.mime,\r\n          name: attachmentData.name,\r\n          filename: attachmentData.filename,\r\n          id: attachmentData.id,\r\n          sizes: attachmentData.sizes,\r\n        }\r\n      }\r\n\r\n    }\r\n\r\n    if (Array.isArray(mediaIDs)) mediaIDs.shift();\r\n\r\n    const mediaType = attachment.attributes.mime.split(\"/\")[0];\r\n    const mediaSubType = attachment.attributes.mime.split(\"/\")[1];\r\n\r\n    if (!(0,_helpers_js__WEBPACK_IMPORTED_MODULE_0__.maybeCompressAttachment)(mediaType, mediaSubType)) {\r\n      return {\r\n        'mediaIDs': mediaIDs,\r\n        'data': __('Skipped', 'squeeze')\r\n      }\r\n    }\r\n\r\n    try {\r\n      const compressData = await this.handleCompress( attachment, type );\r\n      const uploadData = await this.handleUpload({ attachment: attachment, base64: compressData, type: type, mediaIDs: mediaIDs })\r\n\r\n      return uploadData;\r\n\r\n    } catch (error) {\r\n      return {\r\n        'mediaIDs': mediaIDs,\r\n        'data': error?.message ?? error,\r\n        'success': false\r\n      }\r\n    }\r\n\r\n  }\r\n\r\n  \r\n\r\n  handleRestore = async (attachmentID) => {\r\n    const data = {\r\n      action: 'squeeze_restore_attachment',\r\n      _ajax_nonce: this.nonce,\r\n      attachmentID: attachmentID,\r\n    };\r\n\r\n    const response = await jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  };\r\n\r\n  // Get list of attachments by path\r\n  getAttachmentsByPath = async (path) => {\r\n\r\n    const data = {\r\n      action: 'squeeze_get_attachment_by_path',\r\n      path: path,\r\n      _ajax_nonce: this.nonce,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  getAttachment = async (attachmentID) => {\r\n    const data = {\r\n      action: 'squeeze_get_attachment',\r\n      _ajax_nonce: this.nonce,\r\n      attachmentID: attachmentID,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  getNextAttachments = async (page = 1, type = 'uncompressed', lastId = 0) => {\r\n    const data = {\r\n      action: 'squeeze_get_next_attachments',\r\n      _ajax_nonce: this.nonce,\r\n      page: page,\r\n      type: type,\r\n      lastId: lastId,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  getDirectories = async (parentDir = false) => {\r\n    const data = {\r\n      action: 'squeeze_get_directories',\r\n      _ajax_nonce: this.nonce,\r\n    }\r\n\r\n    if (parentDir) {\r\n      data['parentDir'] = parentDir;\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  \r\n\r\n  setOptions = async (options) => {\r\n    const data = {\r\n      action: 'squeeze_set_options',\r\n      _ajax_nonce: this.nonce,\r\n      options: options,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  /**\r\n   * Compresses an image before upload.\r\n   * If the compressSizes parameter is provided, it will compress the sizes specified along with the original image.\r\n   * \r\n   * @param {File} file - The file to be compressed\r\n   * @param {object} compressSizes - Optional sizes for compression\r\n   * @returns {Promise<object|boolean>} - Returns a Promise that resolves to the compressed file as a base64 object or false if the file is invalid\r\n   */\r\n  compressBeforeUpload = async (file, compressSizes = null) => {\r\n    if (!(file instanceof Blob) && !(file instanceof File)) {\r\n      console.error('Invalid file type:', file);\r\n      return false; // Return false if the file is not a Blob or File\r\n    }\r\n\r\n    const attachment = {\r\n      attributes: {\r\n        url: null,\r\n        mime: file.type,\r\n        name: file.name,\r\n        filename: file.name,\r\n        id: 0,\r\n        sizes: compressSizes,\r\n        file: file,\r\n        skipFull: false,\r\n      }\r\n    }\r\n\r\n    try {\r\n      const base64Obj = await this.handleCompress(attachment);\r\n\r\n      return base64Obj; // Return the compressed file as base64Obj\r\n    } catch (error) {\r\n      console.error(error);\r\n      return error; // Return the error for further handling\r\n    }\r\n  }\r\n\r\n  isWebpEncodingSupported = async () => {\r\n    try {\r\n      const canvas = document.createElement('canvas');\r\n      if (!canvas.toDataURL) return false;\r\n      const data = canvas.toDataURL('image/webp');\r\n      // WebP signature starts with \"data:image/webp\"\r\n      return data.indexOf('data:image/webp') === 0;\r\n    } catch (e) {\r\n      return false;\r\n    }\r\n  }\r\n\r\n  handleConvertFileToWebp = async (args) => {\r\n    const timeout = this.timeout;\r\n    \r\n    const { file, sourceType, name } = args;\r\n    const fileBuffer = await file.arrayBuffer();\r\n    const mime = sourceType === 'png' ? 'image/png' : 'image/jpeg';\r\n    const inputBlob = new Blob([fileBuffer], { type: mime });\r\n    // compression options you can tune\r\n    const imageCompressionOptions = {\r\n      useWebWorker: true,\r\n      fileType: 'image/webp',\r\n    };\r\n\r\n    return new Promise(async (resolve, reject) => {\r\n      const timeoutId = setTimeout(() => {\r\n      console.warn('Worker convertToWebp terminated', name);\r\n      reject(new Error(__('Request timed out.', 'squeeze')));\r\n      }, timeout);\r\n\r\n      try {\r\n\r\n        const compressedBlob = await (0,browser_image_compression__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(inputBlob, imageCompressionOptions);\r\n\r\n        // quick checks\r\n        //console.log('compressedBlob.type, size:', compressedBlob.type, compressedBlob.size);\r\n        // normalize final binary\r\n        const webpArrayBuffer = await compressedBlob.arrayBuffer();\r\n\r\n        const webpName = name.replace(/\\.\\w+$/, '.webp');\r\n        const webpFile = new File([webpArrayBuffer], webpName, { type: 'image/webp', lastModified: Date.now() });\r\n\r\n        clearTimeout(timeoutId);\r\n        resolve({ webpFile }); // must return object with webpFile prop\r\n      } catch (error) {\r\n        clearTimeout(timeoutId);\r\n        console.error('Error during image processing:', error);\r\n        reject(error);\r\n      }\r\n    });\r\n    \r\n  }\r\n\r\n  // helper: normalize buffer-like inputs to Uint8Array\r\n  toUint8Array = (bufferLike) => {\r\n    if (bufferLike instanceof Uint8Array) return bufferLike;\r\n    if (bufferLike instanceof ArrayBuffer) return new Uint8Array(bufferLike);\r\n    if (ArrayBuffer.isView(bufferLike)) return new Uint8Array(bufferLike.buffer, bufferLike.byteOffset, bufferLike.byteLength);\r\n    // Node Buffer (in some environments) has .buffer and .byteOffset\r\n    if (bufferLike && typeof bufferLike === 'object' && bufferLike.buffer) {\r\n      return new Uint8Array(bufferLike.buffer, bufferLike.byteOffset || 0, bufferLike.byteLength || bufferLike.length);\r\n    }\r\n    throw new Error('Unsupported buffer type: ' + Object.prototype.toString.call(bufferLike));\r\n  }\r\n\r\n  /**\r\n   * Convert an image File to WebP.\r\n   *\r\n   * @param {File} inputFile  — the original image File (e.g. JPEG, PNG).\r\n   * @returns {Promise<File>} — a Promise that resolves to a WebP File.\r\n   */\r\n  convertFileToWebp = async (inputFile) => {\r\n    // Ensure it’s an image\r\n    if (!inputFile.type.startsWith('image/')) {\r\n      throw new Error('Input must be an image File');\r\n    }\r\n    const args = {\r\n      file: inputFile,\r\n      sourceType: inputFile.type.split('/')[1], // e.g. 'jpeg', 'png'\r\n      name: inputFile.name,\r\n    }\r\n    const webpSupported = await this.isWebpEncodingSupported();\r\n    try {\r\n      // Convert the image to WebP\r\n      let webpData;\r\n      if (webpSupported) {\r\n        webpData = await this.handleConvertFileToWebp(args);\r\n      } else {\r\n        console.warn('WebP encoding not supported on this device. Using original format instead.');\r\n        const webpName = args.name.replace(/\\.\\w+$/, '.webp');\r\n        webpData = await this.convertToWebpWithJsquash(inputFile, webpName);\r\n      }\r\n      if (!webpData || !webpData.webpFile) {\r\n        throw new Error('Failed to convert image to WebP');\r\n      }\r\n\r\n      return webpData.webpFile; // Return the WebP File\r\n\r\n    } catch (error) {\r\n      console.error('Error converting image to WebP:', error);\r\n      throw error; // Re-throw the error for further handling\r\n    }\r\n\r\n  }\r\n\r\n  /**\r\n * Convert an input (File | Blob | ArrayBuffer | Uint8Array) to a WebP File using @jsquash/webp.\r\n * @param {File|Blob|ArrayBuffer|Uint8Array} input\r\n * @param {string} outputName - desired filename for the .webp output\r\n * @param {{quality?: number, lossless?: boolean, method?: number}} [opts] - encoder options (quality 0-100)\r\n * @returns {Promise<File>} - WebP File\r\n */\r\n  convertToWebpWithJsquash = async (input, outputName = 'out.webp', opts = { quality: 100 }) => {\r\n    // Normalize input to Blob\r\n    let blob;\r\n    if (input instanceof Blob) {\r\n      blob = input;\r\n    } else if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) {\r\n      blob = new Blob([input]);\r\n    } else {\r\n      throw new Error('Unsupported input type. Provide File, Blob, ArrayBuffer or TypedArray.');\r\n    }\r\n\r\n    // Load image into <img>\r\n    const dataURL = await new Promise((resolve, reject) => {\r\n      const fr = new FileReader();\r\n      fr.onload = () => resolve(fr.result);\r\n      fr.onerror = reject;\r\n      fr.readAsDataURL(blob);\r\n    });\r\n\r\n    const img = await new Promise((resolve, reject) => {\r\n      const i = new Image();\r\n      i.onload = () => resolve(i);\r\n      i.onerror = () => reject(new Error('Failed to load image for conversion'));\r\n      i.src = dataURL;\r\n      // avoid cross-origin taint if data-url is used\r\n    });\r\n\r\n    // Draw to canvas and extract ImageData\r\n    const canvas = document.createElement('canvas');\r\n    canvas.width = img.naturalWidth || img.width;\r\n    canvas.height = img.naturalHeight || img.height;\r\n    const ctx = canvas.getContext('2d');\r\n    ctx.drawImage(img, 0, 0);\r\n    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\r\n\r\n    // encode -> returns ArrayBuffer (WASM libwebp)\r\n    // opts example: { quality: 75, lossless: false, method: 4 }\r\n    const webpArrayBuffer = await (0,_jsquash_webp__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(imageData, opts);\r\n\r\n    // Validate a little (size)\r\n    if (!webpArrayBuffer || webpArrayBuffer.byteLength < 20) {\r\n      throw new Error('jsquash produced an invalid WebP buffer');\r\n    }\r\n\r\n    // Wrap into File\r\n    const webpFile = new File([webpArrayBuffer], outputName.replace(/\\.\\w+$/, '.webp'), {\r\n      type: 'image/webp',\r\n      lastModified: Date.now(),\r\n    });\r\n\r\n    return {webpFile};\r\n  }\r\n\r\n}\n\n//# sourceURL=webpack:///./assets/js/squeeze.js?");
     50
     51/***/ }),
     52
     53/***/ "./node_modules/@jsquash/webp/encode.js":
     54/*!**********************************************!*\
     55  !*** ./node_modules/@jsquash/webp/encode.js ***!
     56  \**********************************************/
     57/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
     58
     59eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ encode),\n/* harmony export */   \"init\": () => (/* binding */ init)\n/* harmony export */ });\n/* harmony import */ var _meta_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./meta.js */ \"./node_modules/@jsquash/webp/meta.js\");\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils.js */ \"./node_modules/@jsquash/webp/utils.js\");\n/* harmony import */ var wasm_feature_detect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! wasm-feature-detect */ \"./node_modules/wasm-feature-detect/dist/esm/index.js\");\n/**\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *     http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n\nlet emscriptenModule;\nasync function init(module, moduleOptionOverrides) {\n    if (await (0,wasm_feature_detect__WEBPACK_IMPORTED_MODULE_0__.simd)()) {\n        const webpEncoder = await __webpack_require__.e(/*! import() */ \"vendors-node_modules_jsquash_webp_codec_enc_webp_enc_simd_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./codec/enc/webp_enc_simd.js */ \"./node_modules/@jsquash/webp/codec/enc/webp_enc_simd.js\"));\n        emscriptenModule = (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.initEmscriptenModule)(webpEncoder.default, module, moduleOptionOverrides);\n        return emscriptenModule;\n    }\n    const webpEncoder = await __webpack_require__.e(/*! import() */ \"vendors-node_modules_jsquash_webp_codec_enc_webp_enc_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./codec/enc/webp_enc.js */ \"./node_modules/@jsquash/webp/codec/enc/webp_enc.js\"));\n    emscriptenModule = (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.initEmscriptenModule)(webpEncoder.default, module, moduleOptionOverrides);\n    return emscriptenModule;\n}\nasync function encode(data, options = {}) {\n    if (!emscriptenModule)\n        emscriptenModule = init();\n    const _options = { ..._meta_js__WEBPACK_IMPORTED_MODULE_2__.defaultOptions, ...options };\n    const module = await emscriptenModule;\n    const result = module.encode(data.data, data.width, data.height, _options);\n    if (!result)\n        throw new Error('Encoding error.');\n    return result.buffer;\n}\n\n\n//# sourceURL=webpack:///./node_modules/@jsquash/webp/encode.js?");
     60
     61/***/ }),
     62
     63/***/ "./node_modules/@jsquash/webp/meta.js":
     64/*!********************************************!*\
     65  !*** ./node_modules/@jsquash/webp/meta.js ***!
     66  \********************************************/
     67/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
     68
     69eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"defaultOptions\": () => (/* binding */ defaultOptions),\n/* harmony export */   \"extension\": () => (/* binding */ extension),\n/* harmony export */   \"label\": () => (/* binding */ label),\n/* harmony export */   \"mimeType\": () => (/* binding */ mimeType)\n/* harmony export */ });\nconst label = 'WebP';\nconst mimeType = 'image/webp';\nconst extension = 'webp';\n// These come from struct WebPConfig in encode.h.\nconst defaultOptions = {\n    quality: 75,\n    target_size: 0,\n    target_PSNR: 0,\n    method: 4,\n    sns_strength: 50,\n    filter_strength: 60,\n    filter_sharpness: 0,\n    filter_type: 1,\n    partitions: 0,\n    segments: 4,\n    pass: 1,\n    show_compressed: 0,\n    preprocessing: 0,\n    autofilter: 0,\n    partition_limit: 0,\n    alpha_compression: 1,\n    alpha_filtering: 1,\n    alpha_quality: 100,\n    lossless: 0,\n    exact: 0,\n    image_hint: 0,\n    emulate_jpeg_size: 0,\n    thread_level: 0,\n    low_memory: 0,\n    near_lossless: 100,\n    use_delta_palette: 0,\n    use_sharp_yuv: 0,\n};\n\n\n//# sourceURL=webpack:///./node_modules/@jsquash/webp/meta.js?");
     70
     71/***/ }),
     72
     73/***/ "./node_modules/@jsquash/webp/utils.js":
     74/*!*********************************************!*\
     75  !*** ./node_modules/@jsquash/webp/utils.js ***!
     76  \*********************************************/
     77/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
     78
     79eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"initEmscriptenModule\": () => (/* binding */ initEmscriptenModule)\n/* harmony export */ });\n/**\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *     http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Notice: I (Jamie Sinclair) have modified this file to allow manual instantiation of the Wasm Module.\n */\nfunction initEmscriptenModule(moduleFactory, wasmModule, moduleOptionOverrides = {}) {\n    let instantiateWasm;\n    if (wasmModule) {\n        instantiateWasm = (imports, callback) => {\n            const instance = new WebAssembly.Instance(wasmModule, imports);\n            callback(instance);\n            return instance.exports;\n        };\n    }\n    return moduleFactory({\n        // Just to be safe, don't automatically invoke any wasm functions\n        noInitialRun: true,\n        instantiateWasm,\n        ...moduleOptionOverrides,\n    });\n}\n\n\n//# sourceURL=webpack:///./node_modules/@jsquash/webp/utils.js?");
     80
     81/***/ }),
     82
     83/***/ "./node_modules/browser-image-compression/dist/browser-image-compression.mjs":
     84/*!***********************************************************************************!*\
     85  !*** ./node_modules/browser-image-compression/dist/browser-image-compression.mjs ***!
     86  \***********************************************************************************/
     87/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
     88
     89eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ imageCompression)\n/* harmony export */ });\n/**\n * Browser Image Compression\n * v2.0.2\n * by Donald <[email protected]>\n * https://github.com/Donaldcwl/browser-image-compression\n */\n\nfunction _mergeNamespaces(e,t){return t.forEach((function(t){t&&\"string\"!=typeof t&&!Array.isArray(t)&&Object.keys(t).forEach((function(r){if(\"default\"!==r&&!(r in e)){var i=Object.getOwnPropertyDescriptor(t,r);Object.defineProperty(e,r,i.get?i:{enumerable:!0,get:function(){return t[r]}})}}))})),Object.freeze(e)}function copyExifWithoutOrientation(e,t){return new Promise((function(r,i){let o;return getApp1Segment(e).then((function(e){try{return o=e,r(new Blob([t.slice(0,2),o,t.slice(2)],{type:\"image/jpeg\"}))}catch(e){return i(e)}}),i)}))}const getApp1Segment=e=>new Promise(((t,r)=>{const i=new FileReader;i.addEventListener(\"load\",(({target:{result:e}})=>{const i=new DataView(e);let o=0;if(65496!==i.getUint16(o))return r(\"not a valid JPEG\");for(o+=2;;){const a=i.getUint16(o);if(65498===a)break;const s=i.getUint16(o+2);if(65505===a&&1165519206===i.getUint32(o+4)){const a=o+10;let f;switch(i.getUint16(a)){case 18761:f=!0;break;case 19789:f=!1;break;default:return r(\"TIFF header contains invalid endian\")}if(42!==i.getUint16(a+2,f))return r(\"TIFF header contains invalid version\");const l=i.getUint32(a+4,f),c=a+l+2+12*i.getUint16(a+l,f);for(let e=a+l+2;e<c;e+=12){if(274==i.getUint16(e,f)){if(3!==i.getUint16(e+2,f))return r(\"Orientation data type is invalid\");if(1!==i.getUint32(e+4,f))return r(\"Orientation data count is invalid\");i.setUint16(e+8,1,f);break}}return t(e.slice(o,o+2+s))}o+=2+s}return t(new Blob)})),i.readAsArrayBuffer(e)}));var e={},t={get exports(){return e},set exports(t){e=t}};!function(e){var r,i,UZIP={};t.exports=UZIP,UZIP.parse=function(e,t){for(var r=UZIP.bin.readUshort,i=UZIP.bin.readUint,o=0,a={},s=new Uint8Array(e),f=s.length-4;101010256!=i(s,f);)f--;o=f;o+=4;var l=r(s,o+=4);r(s,o+=2);var c=i(s,o+=2),u=i(s,o+=4);o+=4,o=u;for(var h=0;h<l;h++){i(s,o),o+=4,o+=4,o+=4,i(s,o+=4);c=i(s,o+=4);var d=i(s,o+=4),A=r(s,o+=4),g=r(s,o+2),p=r(s,o+4);o+=6;var m=i(s,o+=8);o+=4,o+=A+g+p,UZIP._readLocal(s,m,a,c,d,t)}return a},UZIP._readLocal=function(e,t,r,i,o,a){var s=UZIP.bin.readUshort,f=UZIP.bin.readUint;f(e,t),s(e,t+=4),s(e,t+=2);var l=s(e,t+=2);f(e,t+=2),f(e,t+=4),t+=4;var c=s(e,t+=8),u=s(e,t+=2);t+=2;var h=UZIP.bin.readUTF8(e,t,c);if(t+=c,t+=u,a)r[h]={size:o,csize:i};else{var d=new Uint8Array(e.buffer,t);if(0==l)r[h]=new Uint8Array(d.buffer.slice(t,t+i));else{if(8!=l)throw\"unknown compression method: \"+l;var A=new Uint8Array(o);UZIP.inflateRaw(d,A),r[h]=A}}},UZIP.inflateRaw=function(e,t){return UZIP.F.inflate(e,t)},UZIP.inflate=function(e,t){return e[0],e[1],UZIP.inflateRaw(new Uint8Array(e.buffer,e.byteOffset+2,e.length-6),t)},UZIP.deflate=function(e,t){null==t&&(t={level:6});var r=0,i=new Uint8Array(50+Math.floor(1.1*e.length));i[r]=120,i[r+1]=156,r+=2,r=UZIP.F.deflateRaw(e,i,r,t.level);var o=UZIP.adler(e,0,e.length);return i[r+0]=o>>>24&255,i[r+1]=o>>>16&255,i[r+2]=o>>>8&255,i[r+3]=o>>>0&255,new Uint8Array(i.buffer,0,r+4)},UZIP.deflateRaw=function(e,t){null==t&&(t={level:6});var r=new Uint8Array(50+Math.floor(1.1*e.length)),i=UZIP.F.deflateRaw(e,r,i,t.level);return new Uint8Array(r.buffer,0,i)},UZIP.encode=function(e,t){null==t&&(t=!1);var r=0,i=UZIP.bin.writeUint,o=UZIP.bin.writeUshort,a={};for(var s in e){var f=!UZIP._noNeed(s)&&!t,l=e[s],c=UZIP.crc.crc(l,0,l.length);a[s]={cpr:f,usize:l.length,crc:c,file:f?UZIP.deflateRaw(l):l}}for(var s in a)r+=a[s].file.length+30+46+2*UZIP.bin.sizeUTF8(s);r+=22;var u=new Uint8Array(r),h=0,d=[];for(var s in a){var A=a[s];d.push(h),h=UZIP._writeHeader(u,h,s,A,0)}var g=0,p=h;for(var s in a){A=a[s];d.push(h),h=UZIP._writeHeader(u,h,s,A,1,d[g++])}var m=h-p;return i(u,h,101010256),h+=4,o(u,h+=4,g),o(u,h+=2,g),i(u,h+=2,m),i(u,h+=4,p),h+=4,h+=2,u.buffer},UZIP._noNeed=function(e){var t=e.split(\".\").pop().toLowerCase();return-1!=\"png,jpg,jpeg,zip\".indexOf(t)},UZIP._writeHeader=function(e,t,r,i,o,a){var s=UZIP.bin.writeUint,f=UZIP.bin.writeUshort,l=i.file;return s(e,t,0==o?67324752:33639248),t+=4,1==o&&(t+=2),f(e,t,20),f(e,t+=2,0),f(e,t+=2,i.cpr?8:0),s(e,t+=2,0),s(e,t+=4,i.crc),s(e,t+=4,l.length),s(e,t+=4,i.usize),f(e,t+=4,UZIP.bin.sizeUTF8(r)),f(e,t+=2,0),t+=2,1==o&&(t+=2,t+=2,s(e,t+=6,a),t+=4),t+=UZIP.bin.writeUTF8(e,t,r),0==o&&(e.set(l,t),t+=l.length),t},UZIP.crc={table:function(){for(var e=new Uint32Array(256),t=0;t<256;t++){for(var r=t,i=0;i<8;i++)1&r?r=3988292384^r>>>1:r>>>=1;e[t]=r}return e}(),update:function(e,t,r,i){for(var o=0;o<i;o++)e=UZIP.crc.table[255&(e^t[r+o])]^e>>>8;return e},crc:function(e,t,r){return 4294967295^UZIP.crc.update(4294967295,e,t,r)}},UZIP.adler=function(e,t,r){for(var i=1,o=0,a=t,s=t+r;a<s;){for(var f=Math.min(a+5552,s);a<f;)o+=i+=e[a++];i%=65521,o%=65521}return o<<16|i},UZIP.bin={readUshort:function(e,t){return e[t]|e[t+1]<<8},writeUshort:function(e,t,r){e[t]=255&r,e[t+1]=r>>8&255},readUint:function(e,t){return 16777216*e[t+3]+(e[t+2]<<16|e[t+1]<<8|e[t])},writeUint:function(e,t,r){e[t]=255&r,e[t+1]=r>>8&255,e[t+2]=r>>16&255,e[t+3]=r>>24&255},readASCII:function(e,t,r){for(var i=\"\",o=0;o<r;o++)i+=String.fromCharCode(e[t+o]);return i},writeASCII:function(e,t,r){for(var i=0;i<r.length;i++)e[t+i]=r.charCodeAt(i)},pad:function(e){return e.length<2?\"0\"+e:e},readUTF8:function(e,t,r){for(var i,o=\"\",a=0;a<r;a++)o+=\"%\"+UZIP.bin.pad(e[t+a].toString(16));try{i=decodeURIComponent(o)}catch(i){return UZIP.bin.readASCII(e,t,r)}return i},writeUTF8:function(e,t,r){for(var i=r.length,o=0,a=0;a<i;a++){var s=r.charCodeAt(a);if(0==(4294967168&s))e[t+o]=s,o++;else if(0==(4294965248&s))e[t+o]=192|s>>6,e[t+o+1]=128|s>>0&63,o+=2;else if(0==(4294901760&s))e[t+o]=224|s>>12,e[t+o+1]=128|s>>6&63,e[t+o+2]=128|s>>0&63,o+=3;else{if(0!=(4292870144&s))throw\"e\";e[t+o]=240|s>>18,e[t+o+1]=128|s>>12&63,e[t+o+2]=128|s>>6&63,e[t+o+3]=128|s>>0&63,o+=4}}return o},sizeUTF8:function(e){for(var t=e.length,r=0,i=0;i<t;i++){var o=e.charCodeAt(i);if(0==(4294967168&o))r++;else if(0==(4294965248&o))r+=2;else if(0==(4294901760&o))r+=3;else{if(0!=(4292870144&o))throw\"e\";r+=4}}return r}},UZIP.F={},UZIP.F.deflateRaw=function(e,t,r,i){var o=[[0,0,0,0,0],[4,4,8,4,0],[4,5,16,8,0],[4,6,16,16,0],[4,10,16,32,0],[8,16,32,32,0],[8,16,128,128,0],[8,32,128,256,0],[32,128,258,1024,1],[32,258,258,4096,1]][i],a=UZIP.F.U,s=UZIP.F._goodIndex;UZIP.F._hash;var f=UZIP.F._putsE,l=0,c=r<<3,u=0,h=e.length;if(0==i){for(;l<h;){f(t,c,l+(_=Math.min(65535,h-l))==h?1:0),c=UZIP.F._copyExact(e,l,_,t,c+8),l+=_}return c>>>3}var d=a.lits,A=a.strt,g=a.prev,p=0,m=0,w=0,v=0,b=0,y=0;for(h>2&&(A[y=UZIP.F._hash(e,0)]=0),l=0;l<h;l++){if(b=y,l+1<h-2){y=UZIP.F._hash(e,l+1);var E=l+1&32767;g[E]=A[y],A[y]=E}if(u<=l){(p>14e3||m>26697)&&h-l>100&&(u<l&&(d[p]=l-u,p+=2,u=l),c=UZIP.F._writeBlock(l==h-1||u==h?1:0,d,p,v,e,w,l-w,t,c),p=m=v=0,w=l);var F=0;l<h-2&&(F=UZIP.F._bestMatch(e,l,g,b,Math.min(o[2],h-l),o[3]));var _=F>>>16,B=65535&F;if(0!=F){B=65535&F;var U=s(_=F>>>16,a.of0);a.lhst[257+U]++;var C=s(B,a.df0);a.dhst[C]++,v+=a.exb[U]+a.dxb[C],d[p]=_<<23|l-u,d[p+1]=B<<16|U<<8|C,p+=2,u=l+_}else a.lhst[e[l]]++;m++}}for(w==l&&0!=e.length||(u<l&&(d[p]=l-u,p+=2,u=l),c=UZIP.F._writeBlock(1,d,p,v,e,w,l-w,t,c),p=0,m=0,p=m=v=0,w=l);0!=(7&c);)c++;return c>>>3},UZIP.F._bestMatch=function(e,t,r,i,o,a){var s=32767&t,f=r[s],l=s-f+32768&32767;if(f==s||i!=UZIP.F._hash(e,t-l))return 0;for(var c=0,u=0,h=Math.min(32767,t);l<=h&&0!=--a&&f!=s;){if(0==c||e[t+c]==e[t+c-l]){var d=UZIP.F._howLong(e,t,l);if(d>c){if(u=l,(c=d)>=o)break;l+2<d&&(d=l+2);for(var A=0,g=0;g<d-2;g++){var p=t-l+g+32768&32767,m=p-r[p]+32768&32767;m>A&&(A=m,f=p)}}}l+=(s=f)-(f=r[s])+32768&32767}return c<<16|u},UZIP.F._howLong=function(e,t,r){if(e[t]!=e[t-r]||e[t+1]!=e[t+1-r]||e[t+2]!=e[t+2-r])return 0;var i=t,o=Math.min(e.length,t+258);for(t+=3;t<o&&e[t]==e[t-r];)t++;return t-i},UZIP.F._hash=function(e,t){return(e[t]<<8|e[t+1])+(e[t+2]<<4)&65535},UZIP.saved=0,UZIP.F._writeBlock=function(e,t,r,i,o,a,s,f,l){var c,u,h,d,A,g,p,m,w,v=UZIP.F.U,b=UZIP.F._putsF,y=UZIP.F._putsE;v.lhst[256]++,u=(c=UZIP.F.getTrees())[0],h=c[1],d=c[2],A=c[3],g=c[4],p=c[5],m=c[6],w=c[7];var E=32+(0==(l+3&7)?0:8-(l+3&7))+(s<<3),F=i+UZIP.F.contSize(v.fltree,v.lhst)+UZIP.F.contSize(v.fdtree,v.dhst),_=i+UZIP.F.contSize(v.ltree,v.lhst)+UZIP.F.contSize(v.dtree,v.dhst);_+=14+3*p+UZIP.F.contSize(v.itree,v.ihst)+(2*v.ihst[16]+3*v.ihst[17]+7*v.ihst[18]);for(var B=0;B<286;B++)v.lhst[B]=0;for(B=0;B<30;B++)v.dhst[B]=0;for(B=0;B<19;B++)v.ihst[B]=0;var U=E<F&&E<_?0:F<_?1:2;if(b(f,l,e),b(f,l+1,U),l+=3,0==U){for(;0!=(7&l);)l++;l=UZIP.F._copyExact(o,a,s,f,l)}else{var C,I;if(1==U&&(C=v.fltree,I=v.fdtree),2==U){UZIP.F.makeCodes(v.ltree,u),UZIP.F.revCodes(v.ltree,u),UZIP.F.makeCodes(v.dtree,h),UZIP.F.revCodes(v.dtree,h),UZIP.F.makeCodes(v.itree,d),UZIP.F.revCodes(v.itree,d),C=v.ltree,I=v.dtree,y(f,l,A-257),y(f,l+=5,g-1),y(f,l+=5,p-4),l+=4;for(var Q=0;Q<p;Q++)y(f,l+3*Q,v.itree[1+(v.ordr[Q]<<1)]);l+=3*p,l=UZIP.F._codeTiny(m,v.itree,f,l),l=UZIP.F._codeTiny(w,v.itree,f,l)}for(var M=a,x=0;x<r;x+=2){for(var S=t[x],R=S>>>23,T=M+(8388607&S);M<T;)l=UZIP.F._writeLit(o[M++],C,f,l);if(0!=R){var O=t[x+1],P=O>>16,H=O>>8&255,L=255&O;y(f,l=UZIP.F._writeLit(257+H,C,f,l),R-v.of0[H]),l+=v.exb[H],b(f,l=UZIP.F._writeLit(L,I,f,l),P-v.df0[L]),l+=v.dxb[L],M+=R}}l=UZIP.F._writeLit(256,C,f,l)}return l},UZIP.F._copyExact=function(e,t,r,i,o){var a=o>>>3;return i[a]=r,i[a+1]=r>>>8,i[a+2]=255-i[a],i[a+3]=255-i[a+1],a+=4,i.set(new Uint8Array(e.buffer,t,r),a),o+(r+4<<3)},UZIP.F.getTrees=function(){for(var e=UZIP.F.U,t=UZIP.F._hufTree(e.lhst,e.ltree,15),r=UZIP.F._hufTree(e.dhst,e.dtree,15),i=[],o=UZIP.F._lenCodes(e.ltree,i),a=[],s=UZIP.F._lenCodes(e.dtree,a),f=0;f<i.length;f+=2)e.ihst[i[f]]++;for(f=0;f<a.length;f+=2)e.ihst[a[f]]++;for(var l=UZIP.F._hufTree(e.ihst,e.itree,7),c=19;c>4&&0==e.itree[1+(e.ordr[c-1]<<1)];)c--;return[t,r,l,o,s,c,i,a]},UZIP.F.getSecond=function(e){for(var t=[],r=0;r<e.length;r+=2)t.push(e[r+1]);return t},UZIP.F.nonZero=function(e){for(var t=\"\",r=0;r<e.length;r+=2)0!=e[r+1]&&(t+=(r>>1)+\",\");return t},UZIP.F.contSize=function(e,t){for(var r=0,i=0;i<t.length;i++)r+=t[i]*e[1+(i<<1)];return r},UZIP.F._codeTiny=function(e,t,r,i){for(var o=0;o<e.length;o+=2){var a=e[o],s=e[o+1];i=UZIP.F._writeLit(a,t,r,i);var f=16==a?2:17==a?3:7;a>15&&(UZIP.F._putsE(r,i,s,f),i+=f)}return i},UZIP.F._lenCodes=function(e,t){for(var r=e.length;2!=r&&0==e[r-1];)r-=2;for(var i=0;i<r;i+=2){var o=e[i+1],a=i+3<r?e[i+3]:-1,s=i+5<r?e[i+5]:-1,f=0==i?-1:e[i-1];if(0==o&&a==o&&s==o){for(var l=i+5;l+2<r&&e[l+2]==o;)l+=2;(c=Math.min(l+1-i>>>1,138))<11?t.push(17,c-3):t.push(18,c-11),i+=2*c-2}else if(o==f&&a==o&&s==o){for(l=i+5;l+2<r&&e[l+2]==o;)l+=2;var c=Math.min(l+1-i>>>1,6);t.push(16,c-3),i+=2*c-2}else t.push(o,0)}return r>>>1},UZIP.F._hufTree=function(e,t,r){var i=[],o=e.length,a=t.length,s=0;for(s=0;s<a;s+=2)t[s]=0,t[s+1]=0;for(s=0;s<o;s++)0!=e[s]&&i.push({lit:s,f:e[s]});var f=i.length,l=i.slice(0);if(0==f)return 0;if(1==f){var c=i[0].lit;l=0==c?1:0;return t[1+(c<<1)]=1,t[1+(l<<1)]=1,1}i.sort((function(e,t){return e.f-t.f}));var u=i[0],h=i[1],d=0,A=1,g=2;for(i[0]={lit:-1,f:u.f+h.f,l:u,r:h,d:0};A!=f-1;)u=d!=A&&(g==f||i[d].f<i[g].f)?i[d++]:i[g++],h=d!=A&&(g==f||i[d].f<i[g].f)?i[d++]:i[g++],i[A++]={lit:-1,f:u.f+h.f,l:u,r:h};var p=UZIP.F.setDepth(i[A-1],0);for(p>r&&(UZIP.F.restrictDepth(l,r,p),p=r),s=0;s<f;s++)t[1+(l[s].lit<<1)]=l[s].d;return p},UZIP.F.setDepth=function(e,t){return-1!=e.lit?(e.d=t,t):Math.max(UZIP.F.setDepth(e.l,t+1),UZIP.F.setDepth(e.r,t+1))},UZIP.F.restrictDepth=function(e,t,r){var i=0,o=1<<r-t,a=0;for(e.sort((function(e,t){return t.d==e.d?e.f-t.f:t.d-e.d})),i=0;i<e.length&&e[i].d>t;i++){var s=e[i].d;e[i].d=t,a+=o-(1<<r-s)}for(a>>>=r-t;a>0;){(s=e[i].d)<t?(e[i].d++,a-=1<<t-s-1):i++}for(;i>=0;i--)e[i].d==t&&a<0&&(e[i].d--,a++);0!=a&&console.log(\"debt left\")},UZIP.F._goodIndex=function(e,t){var r=0;return t[16|r]<=e&&(r|=16),t[8|r]<=e&&(r|=8),t[4|r]<=e&&(r|=4),t[2|r]<=e&&(r|=2),t[1|r]<=e&&(r|=1),r},UZIP.F._writeLit=function(e,t,r,i){return UZIP.F._putsF(r,i,t[e<<1]),i+t[1+(e<<1)]},UZIP.F.inflate=function(e,t){var r=Uint8Array;if(3==e[0]&&0==e[1])return t||new r(0);var i=UZIP.F,o=i._bitsF,a=i._bitsE,s=i._decodeTiny,f=i.makeCodes,l=i.codes2map,c=i._get17,u=i.U,h=null==t;h&&(t=new r(e.length>>>2<<3));for(var d,A,g=0,p=0,m=0,w=0,v=0,b=0,y=0,E=0,F=0;0==g;)if(g=o(e,F,1),p=o(e,F+1,2),F+=3,0!=p){if(h&&(t=UZIP.F._check(t,E+(1<<17))),1==p&&(d=u.flmap,A=u.fdmap,b=511,y=31),2==p){m=a(e,F,5)+257,w=a(e,F+5,5)+1,v=a(e,F+10,4)+4,F+=14;for(var _=0;_<38;_+=2)u.itree[_]=0,u.itree[_+1]=0;var B=1;for(_=0;_<v;_++){var U=a(e,F+3*_,3);u.itree[1+(u.ordr[_]<<1)]=U,U>B&&(B=U)}F+=3*v,f(u.itree,B),l(u.itree,B,u.imap),d=u.lmap,A=u.dmap,F=s(u.imap,(1<<B)-1,m+w,e,F,u.ttree);var C=i._copyOut(u.ttree,0,m,u.ltree);b=(1<<C)-1;var I=i._copyOut(u.ttree,m,w,u.dtree);y=(1<<I)-1,f(u.ltree,C),l(u.ltree,C,d),f(u.dtree,I),l(u.dtree,I,A)}for(;;){var Q=d[c(e,F)&b];F+=15&Q;var M=Q>>>4;if(M>>>8==0)t[E++]=M;else{if(256==M)break;var x=E+M-254;if(M>264){var S=u.ldef[M-257];x=E+(S>>>3)+a(e,F,7&S),F+=7&S}var R=A[c(e,F)&y];F+=15&R;var T=R>>>4,O=u.ddef[T],P=(O>>>4)+o(e,F,15&O);for(F+=15&O,h&&(t=UZIP.F._check(t,E+(1<<17)));E<x;)t[E]=t[E++-P],t[E]=t[E++-P],t[E]=t[E++-P],t[E]=t[E++-P];E=x}}}else{0!=(7&F)&&(F+=8-(7&F));var H=4+(F>>>3),L=e[H-4]|e[H-3]<<8;h&&(t=UZIP.F._check(t,E+L)),t.set(new r(e.buffer,e.byteOffset+H,L),E),F=H+L<<3,E+=L}return t.length==E?t:t.slice(0,E)},UZIP.F._check=function(e,t){var r=e.length;if(t<=r)return e;var i=new Uint8Array(Math.max(r<<1,t));return i.set(e,0),i},UZIP.F._decodeTiny=function(e,t,r,i,o,a){for(var s=UZIP.F._bitsE,f=UZIP.F._get17,l=0;l<r;){var c=e[f(i,o)&t];o+=15&c;var u=c>>>4;if(u<=15)a[l]=u,l++;else{var h=0,d=0;16==u?(d=3+s(i,o,2),o+=2,h=a[l-1]):17==u?(d=3+s(i,o,3),o+=3):18==u&&(d=11+s(i,o,7),o+=7);for(var A=l+d;l<A;)a[l]=h,l++}}return o},UZIP.F._copyOut=function(e,t,r,i){for(var o=0,a=0,s=i.length>>>1;a<r;){var f=e[a+t];i[a<<1]=0,i[1+(a<<1)]=f,f>o&&(o=f),a++}for(;a<s;)i[a<<1]=0,i[1+(a<<1)]=0,a++;return o},UZIP.F.makeCodes=function(e,t){for(var r,i,o,a,s=UZIP.F.U,f=e.length,l=s.bl_count,c=0;c<=t;c++)l[c]=0;for(c=1;c<f;c+=2)l[e[c]]++;var u=s.next_code;for(r=0,l[0]=0,i=1;i<=t;i++)r=r+l[i-1]<<1,u[i]=r;for(o=0;o<f;o+=2)0!=(a=e[o+1])&&(e[o]=u[a],u[a]++)},UZIP.F.codes2map=function(e,t,r){for(var i=e.length,o=UZIP.F.U.rev15,a=0;a<i;a+=2)if(0!=e[a+1])for(var s=a>>1,f=e[a+1],l=s<<4|f,c=t-f,u=e[a]<<c,h=u+(1<<c);u!=h;){r[o[u]>>>15-t]=l,u++}},UZIP.F.revCodes=function(e,t){for(var r=UZIP.F.U.rev15,i=15-t,o=0;o<e.length;o+=2){var a=e[o]<<t-e[o+1];e[o]=r[a]>>>i}},UZIP.F._putsE=function(e,t,r){r<<=7&t;var i=t>>>3;e[i]|=r,e[i+1]|=r>>>8},UZIP.F._putsF=function(e,t,r){r<<=7&t;var i=t>>>3;e[i]|=r,e[i+1]|=r>>>8,e[i+2]|=r>>>16},UZIP.F._bitsE=function(e,t,r){return(e[t>>>3]|e[1+(t>>>3)]<<8)>>>(7&t)&(1<<r)-1},UZIP.F._bitsF=function(e,t,r){return(e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)&(1<<r)-1},UZIP.F._get17=function(e,t){return(e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)},UZIP.F._get25=function(e,t){return(e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16|e[3+(t>>>3)]<<24)>>>(7&t)},UZIP.F.U=(r=Uint16Array,i=Uint32Array,{next_code:new r(16),bl_count:new r(16),ordr:[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],of0:[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,999,999,999],exb:[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0],ldef:new r(32),df0:[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,65535,65535],dxb:[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0],ddef:new i(32),flmap:new r(512),fltree:[],fdmap:new r(32),fdtree:[],lmap:new r(32768),ltree:[],ttree:[],dmap:new r(32768),dtree:[],imap:new r(512),itree:[],rev15:new r(32768),lhst:new i(286),dhst:new i(30),ihst:new i(19),lits:new i(15e3),strt:new r(65536),prev:new r(32768)}),function(){for(var e=UZIP.F.U,t=0;t<32768;t++){var r=t;r=(4278255360&(r=(4042322160&(r=(3435973836&(r=(2863311530&r)>>>1|(1431655765&r)<<1))>>>2|(858993459&r)<<2))>>>4|(252645135&r)<<4))>>>8|(16711935&r)<<8,e.rev15[t]=(r>>>16|r<<16)>>>17}function pushV(e,t,r){for(;0!=t--;)e.push(0,r)}for(t=0;t<32;t++)e.ldef[t]=e.of0[t]<<3|e.exb[t],e.ddef[t]=e.df0[t]<<4|e.dxb[t];pushV(e.fltree,144,8),pushV(e.fltree,112,9),pushV(e.fltree,24,7),pushV(e.fltree,8,8),UZIP.F.makeCodes(e.fltree,9),UZIP.F.codes2map(e.fltree,9,e.flmap),UZIP.F.revCodes(e.fltree,9),pushV(e.fdtree,32,5),UZIP.F.makeCodes(e.fdtree,5),UZIP.F.codes2map(e.fdtree,5,e.fdmap),UZIP.F.revCodes(e.fdtree,5),pushV(e.itree,19,0),pushV(e.ltree,286,0),pushV(e.dtree,30,0),pushV(e.ttree,320,0)}()}();var UZIP=_mergeNamespaces({__proto__:null,default:e},[e]);const UPNG=function(){var e={nextZero(e,t){for(;0!=e[t];)t++;return t},readUshort:(e,t)=>e[t]<<8|e[t+1],writeUshort(e,t,r){e[t]=r>>8&255,e[t+1]=255&r},readUint:(e,t)=>16777216*e[t]+(e[t+1]<<16|e[t+2]<<8|e[t+3]),writeUint(e,t,r){e[t]=r>>24&255,e[t+1]=r>>16&255,e[t+2]=r>>8&255,e[t+3]=255&r},readASCII(e,t,r){let i=\"\";for(let o=0;o<r;o++)i+=String.fromCharCode(e[t+o]);return i},writeASCII(e,t,r){for(let i=0;i<r.length;i++)e[t+i]=r.charCodeAt(i)},readBytes(e,t,r){const i=[];for(let o=0;o<r;o++)i.push(e[t+o]);return i},pad:e=>e.length<2?`0${e}`:e,readUTF8(t,r,i){let o,a=\"\";for(let o=0;o<i;o++)a+=`%${e.pad(t[r+o].toString(16))}`;try{o=decodeURIComponent(a)}catch(o){return e.readASCII(t,r,i)}return o}};function decodeImage(t,r,i,o){const a=r*i,s=_getBPP(o),f=Math.ceil(r*s/8),l=new Uint8Array(4*a),c=new Uint32Array(l.buffer),{ctype:u}=o,{depth:h}=o,d=e.readUshort;if(6==u){const e=a<<2;if(8==h)for(var A=0;A<e;A+=4)l[A]=t[A],l[A+1]=t[A+1],l[A+2]=t[A+2],l[A+3]=t[A+3];if(16==h)for(A=0;A<e;A++)l[A]=t[A<<1]}else if(2==u){const e=o.tabs.tRNS;if(null==e){if(8==h)for(A=0;A<a;A++){var g=3*A;c[A]=255<<24|t[g+2]<<16|t[g+1]<<8|t[g]}if(16==h)for(A=0;A<a;A++){g=6*A;c[A]=255<<24|t[g+4]<<16|t[g+2]<<8|t[g]}}else{var p=e[0];const r=e[1],i=e[2];if(8==h)for(A=0;A<a;A++){var m=A<<2;g=3*A;c[A]=255<<24|t[g+2]<<16|t[g+1]<<8|t[g],t[g]==p&&t[g+1]==r&&t[g+2]==i&&(l[m+3]=0)}if(16==h)for(A=0;A<a;A++){m=A<<2,g=6*A;c[A]=255<<24|t[g+4]<<16|t[g+2]<<8|t[g],d(t,g)==p&&d(t,g+2)==r&&d(t,g+4)==i&&(l[m+3]=0)}}}else if(3==u){const e=o.tabs.PLTE,s=o.tabs.tRNS,c=s?s.length:0;if(1==h)for(var w=0;w<i;w++){var v=w*f,b=w*r;for(A=0;A<r;A++){m=b+A<<2;var y=3*(E=t[v+(A>>3)]>>7-((7&A)<<0)&1);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255}}if(2==h)for(w=0;w<i;w++)for(v=w*f,b=w*r,A=0;A<r;A++){m=b+A<<2,y=3*(E=t[v+(A>>2)]>>6-((3&A)<<1)&3);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255}if(4==h)for(w=0;w<i;w++)for(v=w*f,b=w*r,A=0;A<r;A++){m=b+A<<2,y=3*(E=t[v+(A>>1)]>>4-((1&A)<<2)&15);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255}if(8==h)for(A=0;A<a;A++){var E;m=A<<2,y=3*(E=t[A]);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255}}else if(4==u){if(8==h)for(A=0;A<a;A++){m=A<<2;var F=t[_=A<<1];l[m]=F,l[m+1]=F,l[m+2]=F,l[m+3]=t[_+1]}if(16==h)for(A=0;A<a;A++){var _;m=A<<2,F=t[_=A<<2];l[m]=F,l[m+1]=F,l[m+2]=F,l[m+3]=t[_+2]}}else if(0==u)for(p=o.tabs.tRNS?o.tabs.tRNS:-1,w=0;w<i;w++){const e=w*f,i=w*r;if(1==h)for(var B=0;B<r;B++){var U=(F=255*(t[e+(B>>>3)]>>>7-(7&B)&1))==255*p?0:255;c[i+B]=U<<24|F<<16|F<<8|F}else if(2==h)for(B=0;B<r;B++){U=(F=85*(t[e+(B>>>2)]>>>6-((3&B)<<1)&3))==85*p?0:255;c[i+B]=U<<24|F<<16|F<<8|F}else if(4==h)for(B=0;B<r;B++){U=(F=17*(t[e+(B>>>1)]>>>4-((1&B)<<2)&15))==17*p?0:255;c[i+B]=U<<24|F<<16|F<<8|F}else if(8==h)for(B=0;B<r;B++){U=(F=t[e+B])==p?0:255;c[i+B]=U<<24|F<<16|F<<8|F}else if(16==h)for(B=0;B<r;B++){F=t[e+(B<<1)],U=d(t,e+(B<<1))==p?0:255;c[i+B]=U<<24|F<<16|F<<8|F}}return l}function _decompress(e,r,i,o){const a=_getBPP(e),s=Math.ceil(i*a/8),f=new Uint8Array((s+1+e.interlace)*o);return r=e.tabs.CgBI?t(r,f):_inflate(r,f),0==e.interlace?r=_filterZero(r,e,0,i,o):1==e.interlace&&(r=function _readInterlace(e,t){const r=t.width,i=t.height,o=_getBPP(t),a=o>>3,s=Math.ceil(r*o/8),f=new Uint8Array(i*s);let l=0;const c=[0,0,4,0,2,0,1],u=[0,4,0,2,0,1,0],h=[8,8,8,4,4,2,2],d=[8,8,4,4,2,2,1];let A=0;for(;A<7;){const p=h[A],m=d[A];let w=0,v=0,b=c[A];for(;b<i;)b+=p,v++;let y=u[A];for(;y<r;)y+=m,w++;const E=Math.ceil(w*o/8);_filterZero(e,t,l,w,v);let F=0,_=c[A];for(;_<i;){let t=u[A],i=l+F*E<<3;for(;t<r;){var g;if(1==o)g=(g=e[i>>3])>>7-(7&i)&1,f[_*s+(t>>3)]|=g<<7-((7&t)<<0);if(2==o)g=(g=e[i>>3])>>6-(7&i)&3,f[_*s+(t>>2)]|=g<<6-((3&t)<<1);if(4==o)g=(g=e[i>>3])>>4-(7&i)&15,f[_*s+(t>>1)]|=g<<4-((1&t)<<2);if(o>=8){const r=_*s+t*a;for(let t=0;t<a;t++)f[r+t]=e[(i>>3)+t]}i+=o,t+=m}F++,_+=p}w*v!=0&&(l+=v*(1+E)),A+=1}return f}(r,e)),r}function _inflate(e,r){return t(new Uint8Array(e.buffer,2,e.length-6),r)}var t=function(){const e={H:{}};return e.H.N=function(t,r){const i=Uint8Array;let o,a,s=0,f=0,l=0,c=0,u=0,h=0,d=0,A=0,g=0;if(3==t[0]&&0==t[1])return r||new i(0);const p=e.H,m=p.b,w=p.e,v=p.R,b=p.n,y=p.A,E=p.Z,F=p.m,_=null==r;for(_&&(r=new i(t.length>>>2<<5));0==s;)if(s=m(t,g,1),f=m(t,g+1,2),g+=3,0!=f){if(_&&(r=e.H.W(r,A+(1<<17))),1==f&&(o=F.J,a=F.h,h=511,d=31),2==f){l=w(t,g,5)+257,c=w(t,g+5,5)+1,u=w(t,g+10,4)+4,g+=14;let e=1;for(var B=0;B<38;B+=2)F.Q[B]=0,F.Q[B+1]=0;for(B=0;B<u;B++){const r=w(t,g+3*B,3);F.Q[1+(F.X[B]<<1)]=r,r>e&&(e=r)}g+=3*u,b(F.Q,e),y(F.Q,e,F.u),o=F.w,a=F.d,g=v(F.u,(1<<e)-1,l+c,t,g,F.v);const r=p.V(F.v,0,l,F.C);h=(1<<r)-1;const i=p.V(F.v,l,c,F.D);d=(1<<i)-1,b(F.C,r),y(F.C,r,o),b(F.D,i),y(F.D,i,a)}for(;;){const e=o[E(t,g)&h];g+=15&e;const i=e>>>4;if(i>>>8==0)r[A++]=i;else{if(256==i)break;{let e=A+i-254;if(i>264){const r=F.q[i-257];e=A+(r>>>3)+w(t,g,7&r),g+=7&r}const o=a[E(t,g)&d];g+=15&o;const s=o>>>4,f=F.c[s],l=(f>>>4)+m(t,g,15&f);for(g+=15&f;A<e;)r[A]=r[A++-l],r[A]=r[A++-l],r[A]=r[A++-l],r[A]=r[A++-l];A=e}}}}else{0!=(7&g)&&(g+=8-(7&g));const o=4+(g>>>3),a=t[o-4]|t[o-3]<<8;_&&(r=e.H.W(r,A+a)),r.set(new i(t.buffer,t.byteOffset+o,a),A),g=o+a<<3,A+=a}return r.length==A?r:r.slice(0,A)},e.H.W=function(e,t){const r=e.length;if(t<=r)return e;const i=new Uint8Array(r<<1);return i.set(e,0),i},e.H.R=function(t,r,i,o,a,s){const f=e.H.e,l=e.H.Z;let c=0;for(;c<i;){const e=t[l(o,a)&r];a+=15&e;const i=e>>>4;if(i<=15)s[c]=i,c++;else{let e=0,t=0;16==i?(t=3+f(o,a,2),a+=2,e=s[c-1]):17==i?(t=3+f(o,a,3),a+=3):18==i&&(t=11+f(o,a,7),a+=7);const r=c+t;for(;c<r;)s[c]=e,c++}}return a},e.H.V=function(e,t,r,i){let o=0,a=0;const s=i.length>>>1;for(;a<r;){const r=e[a+t];i[a<<1]=0,i[1+(a<<1)]=r,r>o&&(o=r),a++}for(;a<s;)i[a<<1]=0,i[1+(a<<1)]=0,a++;return o},e.H.n=function(t,r){const i=e.H.m,o=t.length;let a,s,f;let l;const c=i.j;for(var u=0;u<=r;u++)c[u]=0;for(u=1;u<o;u+=2)c[t[u]]++;const h=i.K;for(a=0,c[0]=0,s=1;s<=r;s++)a=a+c[s-1]<<1,h[s]=a;for(f=0;f<o;f+=2)l=t[f+1],0!=l&&(t[f]=h[l],h[l]++)},e.H.A=function(t,r,i){const o=t.length,a=e.H.m.r;for(let e=0;e<o;e+=2)if(0!=t[e+1]){const o=e>>1,s=t[e+1],f=o<<4|s,l=r-s;let c=t[e]<<l;const u=c+(1<<l);for(;c!=u;){i[a[c]>>>15-r]=f,c++}}},e.H.l=function(t,r){const i=e.H.m.r,o=15-r;for(let e=0;e<t.length;e+=2){const a=t[e]<<r-t[e+1];t[e]=i[a]>>>o}},e.H.M=function(e,t,r){r<<=7&t;const i=t>>>3;e[i]|=r,e[i+1]|=r>>>8},e.H.I=function(e,t,r){r<<=7&t;const i=t>>>3;e[i]|=r,e[i+1]|=r>>>8,e[i+2]|=r>>>16},e.H.e=function(e,t,r){return(e[t>>>3]|e[1+(t>>>3)]<<8)>>>(7&t)&(1<<r)-1},e.H.b=function(e,t,r){return(e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)&(1<<r)-1},e.H.Z=function(e,t){return(e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)},e.H.i=function(e,t){return(e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16|e[3+(t>>>3)]<<24)>>>(7&t)},e.H.m=function(){const e=Uint16Array,t=Uint32Array;return{K:new e(16),j:new e(16),X:[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],S:[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,999,999,999],T:[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0],q:new e(32),p:[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,65535,65535],z:[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0],c:new t(32),J:new e(512),_:[],h:new e(32),$:[],w:new e(32768),C:[],v:[],d:new e(32768),D:[],u:new e(512),Q:[],r:new e(32768),s:new t(286),Y:new t(30),a:new t(19),t:new t(15e3),k:new e(65536),g:new e(32768)}}(),function(){const t=e.H.m;for(var r=0;r<32768;r++){let e=r;e=(2863311530&e)>>>1|(1431655765&e)<<1,e=(3435973836&e)>>>2|(858993459&e)<<2,e=(4042322160&e)>>>4|(252645135&e)<<4,e=(4278255360&e)>>>8|(16711935&e)<<8,t.r[r]=(e>>>16|e<<16)>>>17}function n(e,t,r){for(;0!=t--;)e.push(0,r)}for(r=0;r<32;r++)t.q[r]=t.S[r]<<3|t.T[r],t.c[r]=t.p[r]<<4|t.z[r];n(t._,144,8),n(t._,112,9),n(t._,24,7),n(t._,8,8),e.H.n(t._,9),e.H.A(t._,9,t.J),e.H.l(t._,9),n(t.$,32,5),e.H.n(t.$,5),e.H.A(t.$,5,t.h),e.H.l(t.$,5),n(t.Q,19,0),n(t.C,286,0),n(t.D,30,0),n(t.v,320,0)}(),e.H.N}();function _getBPP(e){return[1,null,3,1,2,null,4][e.ctype]*e.depth}function _filterZero(e,t,r,i,o){let a=_getBPP(t);const s=Math.ceil(i*a/8);let f,l;a=Math.ceil(a/8);let c=e[r],u=0;if(c>1&&(e[r]=[0,0,1][c-2]),3==c)for(u=a;u<s;u++)e[u+1]=e[u+1]+(e[u+1-a]>>>1)&255;for(let t=0;t<o;t++)if(f=r+t*s,l=f+t+1,c=e[l-1],u=0,0==c)for(;u<s;u++)e[f+u]=e[l+u];else if(1==c){for(;u<a;u++)e[f+u]=e[l+u];for(;u<s;u++)e[f+u]=e[l+u]+e[f+u-a]}else if(2==c)for(;u<s;u++)e[f+u]=e[l+u]+e[f+u-s];else if(3==c){for(;u<a;u++)e[f+u]=e[l+u]+(e[f+u-s]>>>1);for(;u<s;u++)e[f+u]=e[l+u]+(e[f+u-s]+e[f+u-a]>>>1)}else{for(;u<a;u++)e[f+u]=e[l+u]+_paeth(0,e[f+u-s],0);for(;u<s;u++)e[f+u]=e[l+u]+_paeth(e[f+u-a],e[f+u-s],e[f+u-a-s])}return e}function _paeth(e,t,r){const i=e+t-r,o=i-e,a=i-t,s=i-r;return o*o<=a*a&&o*o<=s*s?e:a*a<=s*s?t:r}function _IHDR(t,r,i){i.width=e.readUint(t,r),r+=4,i.height=e.readUint(t,r),r+=4,i.depth=t[r],r++,i.ctype=t[r],r++,i.compress=t[r],r++,i.filter=t[r],r++,i.interlace=t[r],r++}function _copyTile(e,t,r,i,o,a,s,f,l){const c=Math.min(t,o),u=Math.min(r,a);let h=0,d=0;for(let r=0;r<u;r++)for(let a=0;a<c;a++)if(s>=0&&f>=0?(h=r*t+a<<2,d=(f+r)*o+s+a<<2):(h=(-f+r)*t-s+a<<2,d=r*o+a<<2),0==l)i[d]=e[h],i[d+1]=e[h+1],i[d+2]=e[h+2],i[d+3]=e[h+3];else if(1==l){var A=e[h+3]*(1/255),g=e[h]*A,p=e[h+1]*A,m=e[h+2]*A,w=i[d+3]*(1/255),v=i[d]*w,b=i[d+1]*w,y=i[d+2]*w;const t=1-A,r=A+w*t,o=0==r?0:1/r;i[d+3]=255*r,i[d+0]=(g+v*t)*o,i[d+1]=(p+b*t)*o,i[d+2]=(m+y*t)*o}else if(2==l){A=e[h+3],g=e[h],p=e[h+1],m=e[h+2],w=i[d+3],v=i[d],b=i[d+1],y=i[d+2];A==w&&g==v&&p==b&&m==y?(i[d]=0,i[d+1]=0,i[d+2]=0,i[d+3]=0):(i[d]=g,i[d+1]=p,i[d+2]=m,i[d+3]=A)}else if(3==l){A=e[h+3],g=e[h],p=e[h+1],m=e[h+2],w=i[d+3],v=i[d],b=i[d+1],y=i[d+2];if(A==w&&g==v&&p==b&&m==y)continue;if(A<220&&w>20)return!1}return!0}return{decode:function decode(r){const i=new Uint8Array(r);let o=8;const a=e,s=a.readUshort,f=a.readUint,l={tabs:{},frames:[]},c=new Uint8Array(i.length);let u,h=0,d=0;const A=[137,80,78,71,13,10,26,10];for(var g=0;g<8;g++)if(i[g]!=A[g])throw\"The input is not a PNG file!\";for(;o<i.length;){const e=a.readUint(i,o);o+=4;const r=a.readASCII(i,o,4);if(o+=4,\"IHDR\"==r)_IHDR(i,o,l);else if(\"iCCP\"==r){for(var p=o;0!=i[p];)p++;a.readASCII(i,o,p-o),i[p+1];const s=i.slice(p+2,o+e);let f=null;try{f=_inflate(s)}catch(e){f=t(s)}l.tabs[r]=f}else if(\"CgBI\"==r)l.tabs[r]=i.slice(o,o+4);else if(\"IDAT\"==r){for(g=0;g<e;g++)c[h+g]=i[o+g];h+=e}else if(\"acTL\"==r)l.tabs[r]={num_frames:f(i,o),num_plays:f(i,o+4)},u=new Uint8Array(i.length);else if(\"fcTL\"==r){if(0!=d)(E=l.frames[l.frames.length-1]).data=_decompress(l,u.slice(0,d),E.rect.width,E.rect.height),d=0;const e={x:f(i,o+12),y:f(i,o+16),width:f(i,o+4),height:f(i,o+8)};let t=s(i,o+22);t=s(i,o+20)/(0==t?100:t);const r={rect:e,delay:Math.round(1e3*t),dispose:i[o+24],blend:i[o+25]};l.frames.push(r)}else if(\"fdAT\"==r){for(g=0;g<e-4;g++)u[d+g]=i[o+g+4];d+=e-4}else if(\"pHYs\"==r)l.tabs[r]=[a.readUint(i,o),a.readUint(i,o+4),i[o+8]];else if(\"cHRM\"==r){l.tabs[r]=[];for(g=0;g<8;g++)l.tabs[r].push(a.readUint(i,o+4*g))}else if(\"tEXt\"==r||\"zTXt\"==r){null==l.tabs[r]&&(l.tabs[r]={});var m=a.nextZero(i,o),w=a.readASCII(i,o,m-o),v=o+e-m-1;if(\"tEXt\"==r)y=a.readASCII(i,m+1,v);else{var b=_inflate(i.slice(m+2,m+2+v));y=a.readUTF8(b,0,b.length)}l.tabs[r][w]=y}else if(\"iTXt\"==r){null==l.tabs[r]&&(l.tabs[r]={});m=0,p=o;m=a.nextZero(i,p);w=a.readASCII(i,p,m-p);const t=i[p=m+1];var y;i[p+1],p+=2,m=a.nextZero(i,p),a.readASCII(i,p,m-p),p=m+1,m=a.nextZero(i,p),a.readUTF8(i,p,m-p);v=e-((p=m+1)-o);if(0==t)y=a.readUTF8(i,p,v);else{b=_inflate(i.slice(p,p+v));y=a.readUTF8(b,0,b.length)}l.tabs[r][w]=y}else if(\"PLTE\"==r)l.tabs[r]=a.readBytes(i,o,e);else if(\"hIST\"==r){const e=l.tabs.PLTE.length/3;l.tabs[r]=[];for(g=0;g<e;g++)l.tabs[r].push(s(i,o+2*g))}else if(\"tRNS\"==r)3==l.ctype?l.tabs[r]=a.readBytes(i,o,e):0==l.ctype?l.tabs[r]=s(i,o):2==l.ctype&&(l.tabs[r]=[s(i,o),s(i,o+2),s(i,o+4)]);else if(\"gAMA\"==r)l.tabs[r]=a.readUint(i,o)/1e5;else if(\"sRGB\"==r)l.tabs[r]=i[o];else if(\"bKGD\"==r)0==l.ctype||4==l.ctype?l.tabs[r]=[s(i,o)]:2==l.ctype||6==l.ctype?l.tabs[r]=[s(i,o),s(i,o+2),s(i,o+4)]:3==l.ctype&&(l.tabs[r]=i[o]);else if(\"IEND\"==r)break;o+=e,a.readUint(i,o),o+=4}var E;return 0!=d&&((E=l.frames[l.frames.length-1]).data=_decompress(l,u.slice(0,d),E.rect.width,E.rect.height)),l.data=_decompress(l,c,l.width,l.height),delete l.compress,delete l.interlace,delete l.filter,l},toRGBA8:function toRGBA8(e){const t=e.width,r=e.height;if(null==e.tabs.acTL)return[decodeImage(e.data,t,r,e).buffer];const i=[];null==e.frames[0].data&&(e.frames[0].data=e.data);const o=t*r*4,a=new Uint8Array(o),s=new Uint8Array(o),f=new Uint8Array(o);for(let c=0;c<e.frames.length;c++){const u=e.frames[c],h=u.rect.x,d=u.rect.y,A=u.rect.width,g=u.rect.height,p=decodeImage(u.data,A,g,e);if(0!=c)for(var l=0;l<o;l++)f[l]=a[l];if(0==u.blend?_copyTile(p,A,g,a,t,r,h,d,0):1==u.blend&&_copyTile(p,A,g,a,t,r,h,d,1),i.push(a.buffer.slice(0)),0==u.dispose);else if(1==u.dispose)_copyTile(s,A,g,a,t,r,h,d,0);else if(2==u.dispose)for(l=0;l<o;l++)a[l]=f[l]}return i},_paeth:_paeth,_copyTile:_copyTile,_bin:e}}();!function(){const{_copyTile:e}=UPNG,{_bin:t}=UPNG,r=UPNG._paeth;var i={table:function(){const e=new Uint32Array(256);for(let t=0;t<256;t++){let r=t;for(let e=0;e<8;e++)1&r?r=3988292384^r>>>1:r>>>=1;e[t]=r}return e}(),update(e,t,r,o){for(let a=0;a<o;a++)e=i.table[255&(e^t[r+a])]^e>>>8;return e},crc:(e,t,r)=>4294967295^i.update(4294967295,e,t,r)};function addErr(e,t,r,i){t[r]+=e[0]*i>>4,t[r+1]+=e[1]*i>>4,t[r+2]+=e[2]*i>>4,t[r+3]+=e[3]*i>>4}function N(e){return Math.max(0,Math.min(255,e))}function D(e,t){const r=e[0]-t[0],i=e[1]-t[1],o=e[2]-t[2],a=e[3]-t[3];return r*r+i*i+o*o+a*a}function dither(e,t,r,i,o,a,s){null==s&&(s=1);const f=i.length,l=[];for(var c=0;c<f;c++){const e=i[c];l.push([e>>>0&255,e>>>8&255,e>>>16&255,e>>>24&255])}for(c=0;c<f;c++){let e=4294967295;for(var u=0,h=0;h<f;h++){var d=D(l[c],l[h]);h!=c&&d<e&&(e=d,u=h)}}const A=new Uint32Array(o.buffer),g=new Int16Array(t*r*4),p=[0,8,2,10,12,4,14,6,3,11,1,9,15,7,13,5];for(c=0;c<p.length;c++)p[c]=255*((p[c]+.5)/16-.5);for(let o=0;o<r;o++)for(let w=0;w<t;w++){var m;c=4*(o*t+w);if(2!=s)m=[N(e[c]+g[c]),N(e[c+1]+g[c+1]),N(e[c+2]+g[c+2]),N(e[c+3]+g[c+3])];else{d=p[4*(3&o)+(3&w)];m=[N(e[c]+d),N(e[c+1]+d),N(e[c+2]+d),N(e[c+3]+d)]}u=0;let v=16777215;for(h=0;h<f;h++){const e=D(m,l[h]);e<v&&(v=e,u=h)}const b=l[u],y=[m[0]-b[0],m[1]-b[1],m[2]-b[2],m[3]-b[3]];1==s&&(w!=t-1&&addErr(y,g,c+4,7),o!=r-1&&(0!=w&&addErr(y,g,c+4*t-4,3),addErr(y,g,c+4*t,5),w!=t-1&&addErr(y,g,c+4*t+4,1))),a[c>>2]=u,A[c>>2]=i[u]}}function _main(e,r,o,a,s){null==s&&(s={});const{crc:f}=i,l=t.writeUint,c=t.writeUshort,u=t.writeASCII;let h=8;const d=e.frames.length>1;let A,g=!1,p=33+(d?20:0);if(null!=s.sRGB&&(p+=13),null!=s.pHYs&&(p+=21),null!=s.iCCP&&(A=pako.deflate(s.iCCP),p+=21+A.length+4),3==e.ctype){for(var m=e.plte.length,w=0;w<m;w++)e.plte[w]>>>24!=255&&(g=!0);p+=8+3*m+4+(g?8+1*m+4:0)}for(var v=0;v<e.frames.length;v++){d&&(p+=38),p+=(F=e.frames[v]).cimg.length+12,0!=v&&(p+=4)}p+=12;const b=new Uint8Array(p),y=[137,80,78,71,13,10,26,10];for(w=0;w<8;w++)b[w]=y[w];if(l(b,h,13),h+=4,u(b,h,\"IHDR\"),h+=4,l(b,h,r),h+=4,l(b,h,o),h+=4,b[h]=e.depth,h++,b[h]=e.ctype,h++,b[h]=0,h++,b[h]=0,h++,b[h]=0,h++,l(b,h,f(b,h-17,17)),h+=4,null!=s.sRGB&&(l(b,h,1),h+=4,u(b,h,\"sRGB\"),h+=4,b[h]=s.sRGB,h++,l(b,h,f(b,h-5,5)),h+=4),null!=s.iCCP){const e=13+A.length;l(b,h,e),h+=4,u(b,h,\"iCCP\"),h+=4,u(b,h,\"ICC profile\"),h+=11,h+=2,b.set(A,h),h+=A.length,l(b,h,f(b,h-(e+4),e+4)),h+=4}if(null!=s.pHYs&&(l(b,h,9),h+=4,u(b,h,\"pHYs\"),h+=4,l(b,h,s.pHYs[0]),h+=4,l(b,h,s.pHYs[1]),h+=4,b[h]=s.pHYs[2],h++,l(b,h,f(b,h-13,13)),h+=4),d&&(l(b,h,8),h+=4,u(b,h,\"acTL\"),h+=4,l(b,h,e.frames.length),h+=4,l(b,h,null!=s.loop?s.loop:0),h+=4,l(b,h,f(b,h-12,12)),h+=4),3==e.ctype){l(b,h,3*(m=e.plte.length)),h+=4,u(b,h,\"PLTE\"),h+=4;for(w=0;w<m;w++){const t=3*w,r=e.plte[w],i=255&r,o=r>>>8&255,a=r>>>16&255;b[h+t+0]=i,b[h+t+1]=o,b[h+t+2]=a}if(h+=3*m,l(b,h,f(b,h-3*m-4,3*m+4)),h+=4,g){l(b,h,m),h+=4,u(b,h,\"tRNS\"),h+=4;for(w=0;w<m;w++)b[h+w]=e.plte[w]>>>24&255;h+=m,l(b,h,f(b,h-m-4,m+4)),h+=4}}let E=0;for(v=0;v<e.frames.length;v++){var F=e.frames[v];d&&(l(b,h,26),h+=4,u(b,h,\"fcTL\"),h+=4,l(b,h,E++),h+=4,l(b,h,F.rect.width),h+=4,l(b,h,F.rect.height),h+=4,l(b,h,F.rect.x),h+=4,l(b,h,F.rect.y),h+=4,c(b,h,a[v]),h+=2,c(b,h,1e3),h+=2,b[h]=F.dispose,h++,b[h]=F.blend,h++,l(b,h,f(b,h-30,30)),h+=4);const t=F.cimg;l(b,h,(m=t.length)+(0==v?0:4)),h+=4;const r=h;u(b,h,0==v?\"IDAT\":\"fdAT\"),h+=4,0!=v&&(l(b,h,E++),h+=4),b.set(t,h),h+=m,l(b,h,f(b,r,h-r)),h+=4}return l(b,h,0),h+=4,u(b,h,\"IEND\"),h+=4,l(b,h,f(b,h-4,4)),h+=4,b.buffer}function compressPNG(e,t,r){for(let i=0;i<e.frames.length;i++){const o=e.frames[i];o.rect.width;const a=o.rect.height,s=new Uint8Array(a*o.bpl+a);o.cimg=_filterZero(o.img,a,o.bpp,o.bpl,s,t,r)}}function compress(t,r,i,o,a){const s=a[0],f=a[1],l=a[2],c=a[3],u=a[4],h=a[5];let d=6,A=8,g=255;for(var p=0;p<t.length;p++){const e=new Uint8Array(t[p]);for(var m=e.length,w=0;w<m;w+=4)g&=e[w+3]}const v=255!=g,b=function framize(t,r,i,o,a,s){const f=[];for(var l=0;l<t.length;l++){const h=new Uint8Array(t[l]),A=new Uint32Array(h.buffer);var c;let g=0,p=0,m=r,w=i,v=o?1:0;if(0!=l){const b=s||o||1==l||0!=f[l-2].dispose?1:2;let y=0,E=1e9;for(let e=0;e<b;e++){var u=new Uint8Array(t[l-1-e]);const o=new Uint32Array(t[l-1-e]);let s=r,f=i,c=-1,h=-1;for(let e=0;e<i;e++)for(let t=0;t<r;t++){A[d=e*r+t]!=o[d]&&(t<s&&(s=t),t>c&&(c=t),e<f&&(f=e),e>h&&(h=e))}-1==c&&(s=f=c=h=0),a&&(1==(1&s)&&s--,1==(1&f)&&f--);const v=(c-s+1)*(h-f+1);v<E&&(E=v,y=e,g=s,p=f,m=c-s+1,w=h-f+1)}u=new Uint8Array(t[l-1-y]);1==y&&(f[l-1].dispose=2),c=new Uint8Array(m*w*4),e(u,r,i,c,m,w,-g,-p,0),v=e(h,r,i,c,m,w,-g,-p,3)?1:0,1==v?_prepareDiff(h,r,i,c,{x:g,y:p,width:m,height:w}):e(h,r,i,c,m,w,-g,-p,0)}else c=h.slice(0);f.push({rect:{x:g,y:p,width:m,height:w},img:c,blend:v,dispose:0})}if(o)for(l=0;l<f.length;l++){if(1==(A=f[l]).blend)continue;const e=A.rect,o=f[l-1].rect,s=Math.min(e.x,o.x),c=Math.min(e.y,o.y),u={x:s,y:c,width:Math.max(e.x+e.width,o.x+o.width)-s,height:Math.max(e.y+e.height,o.y+o.height)-c};f[l-1].dispose=1,l-1!=0&&_updateFrame(t,r,i,f,l-1,u,a),_updateFrame(t,r,i,f,l,u,a)}let h=0;if(1!=t.length)for(var d=0;d<f.length;d++){var A;h+=(A=f[d]).rect.width*A.rect.height}return f}(t,r,i,s,f,l),y={},E=[],F=[];if(0!=o){const e=[];for(w=0;w<b.length;w++)e.push(b[w].img.buffer);const t=function concatRGBA(e){let t=0;for(var r=0;r<e.length;r++)t+=e[r].byteLength;const i=new Uint8Array(t);let o=0;for(r=0;r<e.length;r++){const t=new Uint8Array(e[r]),a=t.length;for(let e=0;e<a;e+=4){let r=t[e],a=t[e+1],s=t[e+2];const f=t[e+3];0==f&&(r=a=s=0),i[o+e]=r,i[o+e+1]=a,i[o+e+2]=s,i[o+e+3]=f}o+=a}return i.buffer}(e),r=quantize(t,o);for(w=0;w<r.plte.length;w++)E.push(r.plte[w].est.rgba);let i=0;for(w=0;w<b.length;w++){const e=(B=b[w]).img.length;var _=new Uint8Array(r.inds.buffer,i>>2,e>>2);F.push(_);const t=new Uint8Array(r.abuf,i,e);h&&dither(B.img,B.rect.width,B.rect.height,E,t,_),B.img.set(t),i+=e}}else for(p=0;p<b.length;p++){var B=b[p];const e=new Uint32Array(B.img.buffer);var U=B.rect.width;m=e.length,_=new Uint8Array(m);F.push(_);for(w=0;w<m;w++){const t=e[w];if(0!=w&&t==e[w-1])_[w]=_[w-1];else if(w>U&&t==e[w-U])_[w]=_[w-U];else{let e=y[t];if(null==e&&(y[t]=e=E.length,E.push(t),E.length>=300))break;_[w]=e}}}const C=E.length;C<=256&&0==u&&(A=C<=2?1:C<=4?2:C<=16?4:8,A=Math.max(A,c));for(p=0;p<b.length;p++){(B=b[p]).rect.x,B.rect.y;U=B.rect.width;const e=B.rect.height;let t=B.img;new Uint32Array(t.buffer);let r=4*U,i=4;if(C<=256&&0==u){r=Math.ceil(A*U/8);var I=new Uint8Array(r*e);const o=F[p];for(let t=0;t<e;t++){w=t*r;const e=t*U;if(8==A)for(var Q=0;Q<U;Q++)I[w+Q]=o[e+Q];else if(4==A)for(Q=0;Q<U;Q++)I[w+(Q>>1)]|=o[e+Q]<<4-4*(1&Q);else if(2==A)for(Q=0;Q<U;Q++)I[w+(Q>>2)]|=o[e+Q]<<6-2*(3&Q);else if(1==A)for(Q=0;Q<U;Q++)I[w+(Q>>3)]|=o[e+Q]<<7-1*(7&Q)}t=I,d=3,i=1}else if(0==v&&1==b.length){I=new Uint8Array(U*e*3);const o=U*e;for(w=0;w<o;w++){const e=3*w,r=4*w;I[e]=t[r],I[e+1]=t[r+1],I[e+2]=t[r+2]}t=I,d=2,i=3,r=3*U}B.img=t,B.bpl=r,B.bpp=i}return{ctype:d,depth:A,plte:E,frames:b}}function _updateFrame(t,r,i,o,a,s,f){const l=Uint8Array,c=Uint32Array,u=new l(t[a-1]),h=new c(t[a-1]),d=a+1<t.length?new l(t[a+1]):null,A=new l(t[a]),g=new c(A.buffer);let p=r,m=i,w=-1,v=-1;for(let e=0;e<s.height;e++)for(let t=0;t<s.width;t++){const i=s.x+t,f=s.y+e,l=f*r+i,c=g[l];0==c||0==o[a-1].dispose&&h[l]==c&&(null==d||0!=d[4*l+3])||(i<p&&(p=i),i>w&&(w=i),f<m&&(m=f),f>v&&(v=f))}-1==w&&(p=m=w=v=0),f&&(1==(1&p)&&p--,1==(1&m)&&m--),s={x:p,y:m,width:w-p+1,height:v-m+1};const b=o[a];b.rect=s,b.blend=1,b.img=new Uint8Array(s.width*s.height*4),0==o[a-1].dispose?(e(u,r,i,b.img,s.width,s.height,-s.x,-s.y,0),_prepareDiff(A,r,i,b.img,s)):e(A,r,i,b.img,s.width,s.height,-s.x,-s.y,0)}function _prepareDiff(t,r,i,o,a){e(t,r,i,o,a.width,a.height,-a.x,-a.y,2)}function _filterZero(e,t,r,i,o,a,s){const f=[];let l,c=[0,1,2,3,4];-1!=a?c=[a]:(t*i>5e5||1==r)&&(c=[0]),s&&(l={level:0});const u=UZIP;for(var h=0;h<c.length;h++){for(let a=0;a<t;a++)_filterLine(o,e,a,i,r,c[h]);f.push(u.deflate(o,l))}let d,A=1e9;for(h=0;h<f.length;h++)f[h].length<A&&(d=h,A=f[h].length);return f[d]}function _filterLine(e,t,i,o,a,s){const f=i*o;let l=f+i;if(e[l]=s,l++,0==s)if(o<500)for(var c=0;c<o;c++)e[l+c]=t[f+c];else e.set(new Uint8Array(t.buffer,f,o),l);else if(1==s){for(c=0;c<a;c++)e[l+c]=t[f+c];for(c=a;c<o;c++)e[l+c]=t[f+c]-t[f+c-a]+256&255}else if(0==i){for(c=0;c<a;c++)e[l+c]=t[f+c];if(2==s)for(c=a;c<o;c++)e[l+c]=t[f+c];if(3==s)for(c=a;c<o;c++)e[l+c]=t[f+c]-(t[f+c-a]>>1)+256&255;if(4==s)for(c=a;c<o;c++)e[l+c]=t[f+c]-r(t[f+c-a],0,0)+256&255}else{if(2==s)for(c=0;c<o;c++)e[l+c]=t[f+c]+256-t[f+c-o]&255;if(3==s){for(c=0;c<a;c++)e[l+c]=t[f+c]+256-(t[f+c-o]>>1)&255;for(c=a;c<o;c++)e[l+c]=t[f+c]+256-(t[f+c-o]+t[f+c-a]>>1)&255}if(4==s){for(c=0;c<a;c++)e[l+c]=t[f+c]+256-r(0,t[f+c-o],0)&255;for(c=a;c<o;c++)e[l+c]=t[f+c]+256-r(t[f+c-a],t[f+c-o],t[f+c-a-o])&255}}}function quantize(e,t){const r=new Uint8Array(e),i=r.slice(0),o=new Uint32Array(i.buffer),a=getKDtree(i,t),s=a[0],f=a[1],l=r.length,c=new Uint8Array(l>>2);let u;if(r.length<2e7)for(var h=0;h<l;h+=4){u=getNearest(s,d=r[h]*(1/255),A=r[h+1]*(1/255),g=r[h+2]*(1/255),p=r[h+3]*(1/255)),c[h>>2]=u.ind,o[h>>2]=u.est.rgba}else for(h=0;h<l;h+=4){var d=r[h]*(1/255),A=r[h+1]*(1/255),g=r[h+2]*(1/255),p=r[h+3]*(1/255);for(u=s;u.left;)u=planeDst(u.est,d,A,g,p)<=0?u.left:u.right;c[h>>2]=u.ind,o[h>>2]=u.est.rgba}return{abuf:i.buffer,inds:c,plte:f}}function getKDtree(e,t,r){null==r&&(r=1e-4);const i=new Uint32Array(e.buffer),o={i0:0,i1:e.length,bst:null,est:null,tdst:0,left:null,right:null};o.bst=stats(e,o.i0,o.i1),o.est=estats(o.bst);const a=[o];for(;a.length<t;){let t=0,o=0;for(var s=0;s<a.length;s++)a[s].est.L>t&&(t=a[s].est.L,o=s);if(t<r)break;const f=a[o],l=splitPixels(e,i,f.i0,f.i1,f.est.e,f.est.eMq255);if(f.i0>=l||f.i1<=l){f.est.L=0;continue}const c={i0:f.i0,i1:l,bst:null,est:null,tdst:0,left:null,right:null};c.bst=stats(e,c.i0,c.i1),c.est=estats(c.bst);const u={i0:l,i1:f.i1,bst:null,est:null,tdst:0,left:null,right:null};u.bst={R:[],m:[],N:f.bst.N-c.bst.N};for(s=0;s<16;s++)u.bst.R[s]=f.bst.R[s]-c.bst.R[s];for(s=0;s<4;s++)u.bst.m[s]=f.bst.m[s]-c.bst.m[s];u.est=estats(u.bst),f.left=c,f.right=u,a[o]=c,a.push(u)}a.sort(((e,t)=>t.bst.N-e.bst.N));for(s=0;s<a.length;s++)a[s].ind=s;return[o,a]}function getNearest(e,t,r,i,o){if(null==e.left)return e.tdst=function dist(e,t,r,i,o){const a=t-e[0],s=r-e[1],f=i-e[2],l=o-e[3];return a*a+s*s+f*f+l*l}(e.est.q,t,r,i,o),e;const a=planeDst(e.est,t,r,i,o);let s=e.left,f=e.right;a>0&&(s=e.right,f=e.left);const l=getNearest(s,t,r,i,o);if(l.tdst<=a*a)return l;const c=getNearest(f,t,r,i,o);return c.tdst<l.tdst?c:l}function planeDst(e,t,r,i,o){const{e:a}=e;return a[0]*t+a[1]*r+a[2]*i+a[3]*o-e.eMq}function splitPixels(e,t,r,i,o,a){for(i-=4;r<i;){for(;vecDot(e,r,o)<=a;)r+=4;for(;vecDot(e,i,o)>a;)i-=4;if(r>=i)break;const s=t[r>>2];t[r>>2]=t[i>>2],t[i>>2]=s,r+=4,i-=4}for(;vecDot(e,r,o)>a;)r-=4;return r+4}function vecDot(e,t,r){return e[t]*r[0]+e[t+1]*r[1]+e[t+2]*r[2]+e[t+3]*r[3]}function stats(e,t,r){const i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],o=[0,0,0,0],a=r-t>>2;for(let a=t;a<r;a+=4){const t=e[a]*(1/255),r=e[a+1]*(1/255),s=e[a+2]*(1/255),f=e[a+3]*(1/255);o[0]+=t,o[1]+=r,o[2]+=s,o[3]+=f,i[0]+=t*t,i[1]+=t*r,i[2]+=t*s,i[3]+=t*f,i[5]+=r*r,i[6]+=r*s,i[7]+=r*f,i[10]+=s*s,i[11]+=s*f,i[15]+=f*f}return i[4]=i[1],i[8]=i[2],i[9]=i[6],i[12]=i[3],i[13]=i[7],i[14]=i[11],{R:i,m:o,N:a}}function estats(e){const{R:t}=e,{m:r}=e,{N:i}=e,a=r[0],s=r[1],f=r[2],l=r[3],c=0==i?0:1/i,u=[t[0]-a*a*c,t[1]-a*s*c,t[2]-a*f*c,t[3]-a*l*c,t[4]-s*a*c,t[5]-s*s*c,t[6]-s*f*c,t[7]-s*l*c,t[8]-f*a*c,t[9]-f*s*c,t[10]-f*f*c,t[11]-f*l*c,t[12]-l*a*c,t[13]-l*s*c,t[14]-l*f*c,t[15]-l*l*c],h=u,d=o;let A=[Math.random(),Math.random(),Math.random(),Math.random()],g=0,p=0;if(0!=i)for(let e=0;e<16&&(A=d.multVec(h,A),p=Math.sqrt(d.dot(A,A)),A=d.sml(1/p,A),!(0!=e&&Math.abs(p-g)<1e-9));e++)g=p;const m=[a*c,s*c,f*c,l*c];return{Cov:u,q:m,e:A,L:g,eMq255:d.dot(d.sml(255,m),A),eMq:d.dot(A,m),rgba:(Math.round(255*m[3])<<24|Math.round(255*m[2])<<16|Math.round(255*m[1])<<8|Math.round(255*m[0])<<0)>>>0}}var o={multVec:(e,t)=>[e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3],e[4]*t[0]+e[5]*t[1]+e[6]*t[2]+e[7]*t[3],e[8]*t[0]+e[9]*t[1]+e[10]*t[2]+e[11]*t[3],e[12]*t[0]+e[13]*t[1]+e[14]*t[2]+e[15]*t[3]],dot:(e,t)=>e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3],sml:(e,t)=>[e*t[0],e*t[1],e*t[2],e*t[3]]};UPNG.encode=function encode(e,t,r,i,o,a,s){null==i&&(i=0),null==s&&(s=!1);const f=compress(e,t,r,i,[!1,!1,!1,0,s,!1]);return compressPNG(f,-1),_main(f,t,r,o,a)},UPNG.encodeLL=function encodeLL(e,t,r,i,o,a,s,f){const l={ctype:0+(1==i?0:2)+(0==o?0:4),depth:a,frames:[]},c=(i+o)*a,u=c*t;for(let i=0;i<e.length;i++)l.frames.push({rect:{x:0,y:0,width:t,height:r},img:new Uint8Array(e[i]),blend:0,dispose:1,bpp:Math.ceil(c/8),bpl:Math.ceil(u/8)});return compressPNG(l,0,!0),_main(l,t,r,s,f)},UPNG.encode.compress=compress,UPNG.encode.dither=dither,UPNG.quantize=quantize,UPNG.quantize.getKDtree=getKDtree,UPNG.quantize.getNearest=getNearest}();const r={toArrayBuffer(e,t){const i=e.width,o=e.height,a=i<<2,s=e.getContext(\"2d\").getImageData(0,0,i,o),f=new Uint32Array(s.data.buffer),l=(32*i+31)/32<<2,c=l*o,u=122+c,h=new ArrayBuffer(u),d=new DataView(h),A=1<<20;let g,p,m,w,v=A,b=0,y=0,E=0;function set16(e){d.setUint16(y,e,!0),y+=2}function set32(e){d.setUint32(y,e,!0),y+=4}function seek(e){y+=e}set16(19778),set32(u),seek(4),set32(122),set32(108),set32(i),set32(-o>>>0),set16(1),set16(32),set32(3),set32(c),set32(2835),set32(2835),seek(8),set32(16711680),set32(65280),set32(255),set32(4278190080),set32(1466527264),function convert(){for(;b<o&&v>0;){for(w=122+b*l,g=0;g<a;)v--,p=f[E++],m=p>>>24,d.setUint32(w+g,p<<8|m),g+=4;b++}E<f.length?(v=A,setTimeout(convert,r._dly)):t(h)}()},toBlob(e,t){this.toArrayBuffer(e,(e=>{t(new Blob([e],{type:\"image/bmp\"}))}))},_dly:9};var i={CHROME:\"CHROME\",FIREFOX:\"FIREFOX\",DESKTOP_SAFARI:\"DESKTOP_SAFARI\",IE:\"IE\",IOS:\"IOS\",ETC:\"ETC\"},o={[i.CHROME]:16384,[i.FIREFOX]:11180,[i.DESKTOP_SAFARI]:16384,[i.IE]:8192,[i.IOS]:4096,[i.ETC]:8192};const a=\"undefined\"!=typeof window,s=\"undefined\"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope,f=a&&window.cordova&&window.cordova.require&&window.cordova.require(\"cordova/modulemapper\"),CustomFile=(a||s)&&(f&&f.getOriginalSymbol(window,\"File\")||\"undefined\"!=typeof File&&File),CustomFileReader=(a||s)&&(f&&f.getOriginalSymbol(window,\"FileReader\")||\"undefined\"!=typeof FileReader&&FileReader);function getFilefromDataUrl(e,t,r=Date.now()){return new Promise((i=>{const o=e.split(\",\"),a=o[0].match(/:(.*?);/)[1],s=globalThis.atob(o[1]);let f=s.length;const l=new Uint8Array(f);for(;f--;)l[f]=s.charCodeAt(f);const c=new Blob([l],{type:a});c.name=t,c.lastModified=r,i(c)}))}function getDataUrlFromFile(e){return new Promise(((t,r)=>{const i=new CustomFileReader;i.onload=()=>t(i.result),i.onerror=e=>r(e),i.readAsDataURL(e)}))}function loadImage(e){return new Promise(((t,r)=>{const i=new Image;i.onload=()=>t(i),i.onerror=e=>r(e),i.src=e}))}function getBrowserName(){if(void 0!==getBrowserName.cachedResult)return getBrowserName.cachedResult;let e=i.ETC;const{userAgent:t}=navigator;return/Chrom(e|ium)/i.test(t)?e=i.CHROME:/iP(ad|od|hone)/i.test(t)&&/WebKit/i.test(t)?e=i.IOS:/Safari/i.test(t)?e=i.DESKTOP_SAFARI:/Firefox/i.test(t)?e=i.FIREFOX:(/MSIE/i.test(t)||!0==!!document.documentMode)&&(e=i.IE),getBrowserName.cachedResult=e,getBrowserName.cachedResult}function approximateBelowMaximumCanvasSizeOfBrowser(e,t){const r=getBrowserName(),i=o[r];let a=e,s=t,f=a*s;const l=a>s?s/a:a/s;for(;f>i*i;){const e=(i+a)/2,t=(i+s)/2;e<t?(s=t,a=t*l):(s=e*l,a=e),f=a*s}return{width:a,height:s}}function getNewCanvasAndCtx(e,t){let r,i;try{if(r=new OffscreenCanvas(e,t),i=r.getContext(\"2d\"),null===i)throw new Error(\"getContext of OffscreenCanvas returns null\")}catch(e){r=document.createElement(\"canvas\"),i=r.getContext(\"2d\")}return r.width=e,r.height=t,[r,i]}function drawImageInCanvas(e,t){const{width:r,height:i}=approximateBelowMaximumCanvasSizeOfBrowser(e.width,e.height),[o,a]=getNewCanvasAndCtx(r,i);return t&&/jpe?g/.test(t)&&(a.fillStyle=\"white\",a.fillRect(0,0,o.width,o.height)),a.drawImage(e,0,0,o.width,o.height),o}function isIOS(){return void 0!==isIOS.cachedResult||(isIOS.cachedResult=[\"iPad Simulator\",\"iPhone Simulator\",\"iPod Simulator\",\"iPad\",\"iPhone\",\"iPod\"].includes(navigator.platform)||navigator.userAgent.includes(\"Mac\")&&\"undefined\"!=typeof document&&\"ontouchend\"in document),isIOS.cachedResult}function drawFileInCanvas(e,t={}){return new Promise((function(r,o){let a,s;var $Try_2_Post=function(){try{return s=drawImageInCanvas(a,t.fileType||e.type),r([a,s])}catch(e){return o(e)}},$Try_2_Catch=function(t){try{0;var $Try_3_Catch=function(e){try{throw e}catch(e){return o(e)}};try{let t;return getDataUrlFromFile(e).then((function(e){try{return t=e,loadImage(t).then((function(e){try{return a=e,function(){try{return $Try_2_Post()}catch(e){return o(e)}}()}catch(e){return $Try_3_Catch(e)}}),$Try_3_Catch)}catch(e){return $Try_3_Catch(e)}}),$Try_3_Catch)}catch(e){$Try_3_Catch(e)}}catch(e){return o(e)}};try{if(isIOS()||[i.DESKTOP_SAFARI,i.MOBILE_SAFARI].includes(getBrowserName()))throw new Error(\"Skip createImageBitmap on IOS and Safari\");return createImageBitmap(e).then((function(e){try{return a=e,$Try_2_Post()}catch(e){return $Try_2_Catch()}}),$Try_2_Catch)}catch(e){$Try_2_Catch()}}))}function canvasToFile(e,t,i,o,a=1){return new Promise((function(s,f){let l;if(\"image/png\"===t){let c,u,h;return c=e.getContext(\"2d\"),({data:u}=c.getImageData(0,0,e.width,e.height)),h=UPNG.encode([u.buffer],e.width,e.height,4096*a),l=new Blob([h],{type:t}),l.name=i,l.lastModified=o,$If_4.call(this)}{if(\"image/bmp\"===t)return new Promise((t=>r.toBlob(e,t))).then(function(e){try{return l=e,l.name=i,l.lastModified=o,$If_5.call(this)}catch(e){return f(e)}}.bind(this),f);{if(\"function\"==typeof OffscreenCanvas&&e instanceof OffscreenCanvas)return e.convertToBlob({type:t,quality:a}).then(function(e){try{return l=e,l.name=i,l.lastModified=o,$If_6.call(this)}catch(e){return f(e)}}.bind(this),f);{let d;return d=e.toDataURL(t,a),getFilefromDataUrl(d,i,o).then(function(e){try{return l=e,$If_6.call(this)}catch(e){return f(e)}}.bind(this),f)}function $If_6(){return $If_5.call(this)}}function $If_5(){return $If_4.call(this)}}function $If_4(){return s(l)}}))}function cleanupCanvasMemory(e){e.width=0,e.height=0}function isAutoOrientationInBrowser(){return new Promise((function(e,t){let r,i,o,a,s;return void 0!==isAutoOrientationInBrowser.cachedResult?e(isAutoOrientationInBrowser.cachedResult):(r=\"data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAAAAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAEAAgMBEQACEQEDEQH/xABKAAEAAAAAAAAAAAAAAAAAAAALEAEAAAAAAAAAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAAAAAAAAEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/8H//2Q==\",getFilefromDataUrl(\"data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAAAAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAEAAgMBEQACEQEDEQH/xABKAAEAAAAAAAAAAAAAAAAAAAALEAEAAAAAAAAAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAAAAAAAAEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/8H//2Q==\",\"test.jpg\",Date.now()).then((function(r){try{return i=r,drawFileInCanvas(i).then((function(r){try{return o=r[1],canvasToFile(o,i.type,i.name,i.lastModified).then((function(r){try{return a=r,cleanupCanvasMemory(o),drawFileInCanvas(a).then((function(r){try{return s=r[0],isAutoOrientationInBrowser.cachedResult=1===s.width&&2===s.height,e(isAutoOrientationInBrowser.cachedResult)}catch(e){return t(e)}}),t)}catch(e){return t(e)}}),t)}catch(e){return t(e)}}),t)}catch(e){return t(e)}}),t))}))}function getExifOrientation(e){return new Promise(((t,r)=>{const i=new CustomFileReader;i.onload=e=>{const r=new DataView(e.target.result);if(65496!=r.getUint16(0,!1))return t(-2);const i=r.byteLength;let o=2;for(;o<i;){if(r.getUint16(o+2,!1)<=8)return t(-1);const e=r.getUint16(o,!1);if(o+=2,65505==e){if(1165519206!=r.getUint32(o+=2,!1))return t(-1);const e=18761==r.getUint16(o+=6,!1);o+=r.getUint32(o+4,e);const i=r.getUint16(o,e);o+=2;for(let a=0;a<i;a++)if(274==r.getUint16(o+12*a,e))return t(r.getUint16(o+12*a+8,e))}else{if(65280!=(65280&e))break;o+=r.getUint16(o,!1)}}return t(-1)},i.onerror=e=>r(e),i.readAsArrayBuffer(e)}))}function handleMaxWidthOrHeight(e,t){const{width:r}=e,{height:i}=e,{maxWidthOrHeight:o}=t;let a,s=e;return isFinite(o)&&(r>o||i>o)&&([s,a]=getNewCanvasAndCtx(r,i),r>i?(s.width=o,s.height=i/r*o):(s.width=r/i*o,s.height=o),a.drawImage(e,0,0,s.width,s.height),cleanupCanvasMemory(e)),s}function followExifOrientation(e,t){const{width:r}=e,{height:i}=e,[o,a]=getNewCanvasAndCtx(r,i);switch(t>4&&t<9?(o.width=i,o.height=r):(o.width=r,o.height=i),t){case 2:a.transform(-1,0,0,1,r,0);break;case 3:a.transform(-1,0,0,-1,r,i);break;case 4:a.transform(1,0,0,-1,0,i);break;case 5:a.transform(0,1,1,0,0,0);break;case 6:a.transform(0,1,-1,0,i,0);break;case 7:a.transform(0,-1,-1,0,i,r);break;case 8:a.transform(0,-1,1,0,0,r)}return a.drawImage(e,0,0,r,i),cleanupCanvasMemory(e),o}function compress(e,t,r=0){return new Promise((function(i,o){let a,s,f,l,c,u,h,d,A,g,p,m,w,v,b,y,E,F,_,B;function incProgress(e=5){if(t.signal&&t.signal.aborted)throw t.signal.reason;a+=e,t.onProgress(Math.min(a,100))}function setProgress(e){if(t.signal&&t.signal.aborted)throw t.signal.reason;a=Math.min(Math.max(e,a),100),t.onProgress(a)}return a=r,s=t.maxIteration||10,f=1024*t.maxSizeMB*1024,incProgress(),drawFileInCanvas(e,t).then(function(r){try{return[,l]=r,incProgress(),c=handleMaxWidthOrHeight(l,t),incProgress(),new Promise((function(r,i){var o;if(!(o=t.exifOrientation))return getExifOrientation(e).then(function(e){try{return o=e,$If_2.call(this)}catch(e){return i(e)}}.bind(this),i);function $If_2(){return r(o)}return $If_2.call(this)})).then(function(r){try{return u=r,incProgress(),isAutoOrientationInBrowser().then(function(r){try{return h=r?c:followExifOrientation(c,u),incProgress(),d=t.initialQuality||1,A=t.fileType||e.type,canvasToFile(h,A,e.name,e.lastModified,d).then(function(r){try{{if(g=r,incProgress(),p=g.size>f,m=g.size>e.size,!p&&!m)return setProgress(100),i(g);var a;function $Loop_3(){if(s--&&(b>f||b>w)){let t,r;return t=B?.95*_.width:_.width,r=B?.95*_.height:_.height,[E,F]=getNewCanvasAndCtx(t,r),F.drawImage(_,0,0,t,r),d*=\"image/png\"===A?.85:.95,canvasToFile(E,A,e.name,e.lastModified,d).then((function(e){try{return y=e,cleanupCanvasMemory(_),_=E,b=y.size,setProgress(Math.min(99,Math.floor((v-b)/(v-f)*100))),$Loop_3}catch(e){return o(e)}}),o)}return[1]}return w=e.size,v=g.size,b=v,_=h,B=!t.alwaysKeepResolution&&p,(a=function(e){for(;e;){if(e.then)return void e.then(a,o);try{if(e.pop){if(e.length)return e.pop()?$Loop_3_exit.call(this):e;e=$Loop_3}else e=e.call(this)}catch(e){return o(e)}}}.bind(this))($Loop_3);function $Loop_3_exit(){return cleanupCanvasMemory(_),cleanupCanvasMemory(E),cleanupCanvasMemory(c),cleanupCanvasMemory(h),cleanupCanvasMemory(l),setProgress(100),i(y)}}}catch(u){return o(u)}}.bind(this),o)}catch(e){return o(e)}}.bind(this),o)}catch(e){return o(e)}}.bind(this),o)}catch(e){return o(e)}}.bind(this),o)}))}const l=\"\\nlet scriptImported = false\\nself.addEventListener('message', async (e) => {\\n  const { file, id, imageCompressionLibUrl, options } = e.data\\n  options.onProgress = (progress) => self.postMessage({ progress, id })\\n  try {\\n    if (!scriptImported) {\\n      // console.log('[worker] importScripts', imageCompressionLibUrl)\\n      self.importScripts(imageCompressionLibUrl)\\n      scriptImported = true\\n    }\\n    // console.log('[worker] self', self)\\n    const compressedFile = await imageCompression(file, options)\\n    self.postMessage({ file: compressedFile, id })\\n  } catch (e) {\\n    // console.error('[worker] error', e)\\n    self.postMessage({ error: e.message + '\\\\n' + e.stack, id })\\n  }\\n})\\n\";let c;function compressOnWebWorker(e,t){return new Promise(((r,i)=>{c||(c=function createWorkerScriptURL(e){const t=[];return\"function\"==typeof e?t.push(`(${e})()`):t.push(e),URL.createObjectURL(new Blob(t))}(l));const o=new Worker(c);o.addEventListener(\"message\",(function handler(e){if(t.signal&&t.signal.aborted)o.terminate();else if(void 0===e.data.progress){if(e.data.error)return i(new Error(e.data.error)),void o.terminate();r(e.data.file),o.terminate()}else t.onProgress(e.data.progress)})),o.addEventListener(\"error\",i),t.signal&&t.signal.addEventListener(\"abort\",(()=>{i(t.signal.reason),o.terminate()})),o.postMessage({file:e,imageCompressionLibUrl:t.libURL,options:{...t,onProgress:void 0,signal:void 0}})}))}function imageCompression(e,t){return new Promise((function(r,i){let o,a,s,f,l,c;if(o={...t},s=0,({onProgress:f}=o),o.maxSizeMB=o.maxSizeMB||Number.POSITIVE_INFINITY,l=\"boolean\"!=typeof o.useWebWorker||o.useWebWorker,delete o.useWebWorker,o.onProgress=e=>{s=e,\"function\"==typeof f&&f(s)},!(e instanceof Blob||e instanceof CustomFile))return i(new Error(\"The file given is not an instance of Blob or File\"));if(!/^image/.test(e.type))return i(new Error(\"The file given is not an image\"));if(c=\"undefined\"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope,!l||\"function\"!=typeof Worker||c)return compress(e,o).then(function(e){try{return a=e,$If_4.call(this)}catch(e){return i(e)}}.bind(this),i);var u=function(){try{return $If_4.call(this)}catch(e){return i(e)}}.bind(this),$Try_1_Catch=function(t){try{return compress(e,o).then((function(e){try{return a=e,u()}catch(e){return i(e)}}),i)}catch(e){return i(e)}};try{return o.libURL=o.libURL||\"https://cdn.jsdelivr.net/npm/[email protected]/dist/browser-image-compression.js\",compressOnWebWorker(e,o).then((function(e){try{return a=e,u()}catch(e){return $Try_1_Catch()}}),$Try_1_Catch)}catch(e){$Try_1_Catch()}function $If_4(){try{a.name=e.name,a.lastModified=e.lastModified}catch(e){}try{o.preserveExif&&\"image/jpeg\"===e.type&&(!o.fileType||o.fileType&&o.fileType===e.type)&&(a=copyExifWithoutOrientation(e,a))}catch(e){}return r(a)}}))}imageCompression.getDataUrlFromFile=getDataUrlFromFile,imageCompression.getFilefromDataUrl=getFilefromDataUrl,imageCompression.loadImage=loadImage,imageCompression.drawImageInCanvas=drawImageInCanvas,imageCompression.drawFileInCanvas=drawFileInCanvas,imageCompression.canvasToFile=canvasToFile,imageCompression.getExifOrientation=getExifOrientation,imageCompression.handleMaxWidthOrHeight=handleMaxWidthOrHeight,imageCompression.followExifOrientation=followExifOrientation,imageCompression.cleanupCanvasMemory=cleanupCanvasMemory,imageCompression.isAutoOrientationInBrowser=isAutoOrientationInBrowser,imageCompression.approximateBelowMaximumCanvasSizeOfBrowser=approximateBelowMaximumCanvasSizeOfBrowser,imageCompression.copyExifWithoutOrientation=copyExifWithoutOrientation,imageCompression.getBrowserName=getBrowserName,imageCompression.version=\"2.0.2\";\n//# sourceMappingURL=browser-image-compression.mjs.map\n\n\n//# sourceURL=webpack:///./node_modules/browser-image-compression/dist/browser-image-compression.mjs?");
     90
     91/***/ }),
     92
     93/***/ "./node_modules/wasm-feature-detect/dist/esm/index.js":
     94/*!************************************************************!*\
     95  !*** ./node_modules/wasm-feature-detect/dist/esm/index.js ***!
     96  \************************************************************/
     97/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
     98
     99eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"bigInt\": () => (/* binding */ bigInt),\n/* harmony export */   \"bulkMemory\": () => (/* binding */ bulkMemory),\n/* harmony export */   \"exceptions\": () => (/* binding */ exceptions),\n/* harmony export */   \"extendedConst\": () => (/* binding */ extendedConst),\n/* harmony export */   \"gc\": () => (/* binding */ gc),\n/* harmony export */   \"memory64\": () => (/* binding */ memory64),\n/* harmony export */   \"multiValue\": () => (/* binding */ multiValue),\n/* harmony export */   \"mutableGlobals\": () => (/* binding */ mutableGlobals),\n/* harmony export */   \"referenceTypes\": () => (/* binding */ referenceTypes),\n/* harmony export */   \"relaxedSimd\": () => (/* binding */ relaxedSimd),\n/* harmony export */   \"saturatedFloatToInt\": () => (/* binding */ saturatedFloatToInt),\n/* harmony export */   \"signExtensions\": () => (/* binding */ signExtensions),\n/* harmony export */   \"simd\": () => (/* binding */ simd),\n/* harmony export */   \"streamingCompilation\": () => (/* binding */ streamingCompilation),\n/* harmony export */   \"tailCall\": () => (/* binding */ tailCall),\n/* harmony export */   \"threads\": () => (/* binding */ threads)\n/* harmony export */ });\nconst bigInt=()=>(async e=>{try{return(await WebAssembly.instantiate(e)).instance.exports.b(BigInt(0))===BigInt(0)}catch(e){return!1}})(new Uint8Array([0,97,115,109,1,0,0,0,1,6,1,96,1,126,1,126,3,2,1,0,7,5,1,1,98,0,0,10,6,1,4,0,32,0,11])),bulkMemory=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,5,3,1,0,1,10,14,1,12,0,65,0,65,0,65,0,252,10,0,0,11])),exceptions=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,8,1,6,0,6,64,25,11,11])),extendedConst=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,5,3,1,0,1,11,9,1,0,65,1,65,2,106,11,0])),gc=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,10,2,95,1,125,0,96,0,1,107,0,3,2,1,1,10,12,1,10,0,67,0,0,0,0,251,7,0,11])),memory64=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,5,3,1,4,1])),multiValue=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,6,1,96,0,2,127,127,3,2,1,0,10,8,1,6,0,65,0,65,0,11])),mutableGlobals=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,2,8,1,1,97,1,98,3,127,1,6,6,1,127,1,65,0,11,7,5,1,1,97,3,1])),referenceTypes=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,7,1,5,0,208,112,26,11])),relaxedSimd=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,5,1,96,0,1,123,3,2,1,0,10,15,1,13,0,65,1,253,15,65,2,253,15,253,128,2,11])),saturatedFloatToInt=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,12,1,10,0,67,0,0,0,0,252,0,26,11])),signExtensions=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,8,1,6,0,65,0,192,26,11])),simd=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,5,1,96,0,1,123,3,2,1,0,10,10,1,8,0,65,0,253,15,253,98,11])),streamingCompilation=()=>(async()=>\"compileStreaming\"in WebAssembly)(),tailCall=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,6,1,4,0,18,0,11])),threads=()=>(async e=>{try{return\"undefined\"!=typeof MessageChannel&&(new MessageChannel).port1.postMessage(new SharedArrayBuffer(1)),WebAssembly.validate(e)}catch(e){return!1}})(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,5,4,1,3,1,1,10,11,1,9,0,65,0,254,16,2,0,26,11]));\n\n\n//# sourceURL=webpack:///./node_modules/wasm-feature-detect/dist/esm/index.js?");
    50100
    51101/***/ })
     
    93143/******/    })();
    94144/******/   
     145/******/    /* webpack/runtime/ensure chunk */
     146/******/    (() => {
     147/******/        __webpack_require__.f = {};
     148/******/        // This file contains only the entry chunk.
     149/******/        // The chunk loading function for additional chunks
     150/******/        __webpack_require__.e = (chunkId) => {
     151/******/            return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
     152/******/                __webpack_require__.f[key](chunkId, promises);
     153/******/                return promises;
     154/******/            }, []));
     155/******/        };
     156/******/    })();
     157/******/   
    95158/******/    /* webpack/runtime/get javascript chunk filename */
    96159/******/    (() => {
     
    117180/******/    (() => {
    118181/******/        __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
     182/******/    })();
     183/******/   
     184/******/    /* webpack/runtime/load script */
     185/******/    (() => {
     186/******/        var inProgress = {};
     187/******/        // data-webpack is not used as build has no uniqueName
     188/******/        // loadScript function to load a script via script tag
     189/******/        __webpack_require__.l = (url, done, key, chunkId) => {
     190/******/            if(inProgress[url]) { inProgress[url].push(done); return; }
     191/******/            var script, needAttach;
     192/******/            if(key !== undefined) {
     193/******/                var scripts = document.getElementsByTagName("script");
     194/******/                for(var i = 0; i < scripts.length; i++) {
     195/******/                    var s = scripts[i];
     196/******/                    if(s.getAttribute("src") == url) { script = s; break; }
     197/******/                }
     198/******/            }
     199/******/            if(!script) {
     200/******/                needAttach = true;
     201/******/                script = document.createElement('script');
     202/******/       
     203/******/                script.charset = 'utf-8';
     204/******/                script.timeout = 120;
     205/******/                if (__webpack_require__.nc) {
     206/******/                    script.setAttribute("nonce", __webpack_require__.nc);
     207/******/                }
     208/******/       
     209/******/                script.src = url;
     210/******/            }
     211/******/            inProgress[url] = [done];
     212/******/            var onScriptComplete = (prev, event) => {
     213/******/                // avoid mem leaks in IE.
     214/******/                script.onerror = script.onload = null;
     215/******/                clearTimeout(timeout);
     216/******/                var doneFns = inProgress[url];
     217/******/                delete inProgress[url];
     218/******/                script.parentNode && script.parentNode.removeChild(script);
     219/******/                doneFns && doneFns.forEach((fn) => (fn(event)));
     220/******/                if(prev) return prev(event);
     221/******/            }
     222/******/            var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);
     223/******/            script.onerror = onScriptComplete.bind(null, script.onerror);
     224/******/            script.onload = onScriptComplete.bind(null, script.onload);
     225/******/            needAttach && document.head.appendChild(script);
     226/******/        };
    119227/******/    })();
    120228/******/   
     
    161269/******/        };
    162270/******/       
    163 /******/        // no chunk on demand loading
     271/******/        __webpack_require__.f.j = (chunkId, promises) => {
     272/******/                // JSONP chunk loading for javascript
     273/******/                var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
     274/******/                if(installedChunkData !== 0) { // 0 means "already installed".
     275/******/       
     276/******/                    // a Promise means "currently loading".
     277/******/                    if(installedChunkData) {
     278/******/                        promises.push(installedChunkData[2]);
     279/******/                    } else {
     280/******/                        if(true) { // all chunks have JS
     281/******/                            // setup Promise in chunk cache
     282/******/                            var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
     283/******/                            promises.push(installedChunkData[2] = promise);
     284/******/       
     285/******/                            // start chunk loading
     286/******/                            var url = __webpack_require__.p + __webpack_require__.u(chunkId);
     287/******/                            // create error before stack unwound to get useful stacktrace later
     288/******/                            var error = new Error();
     289/******/                            var loadingEnded = (event) => {
     290/******/                                if(__webpack_require__.o(installedChunks, chunkId)) {
     291/******/                                    installedChunkData = installedChunks[chunkId];
     292/******/                                    if(installedChunkData !== 0) installedChunks[chunkId] = undefined;
     293/******/                                    if(installedChunkData) {
     294/******/                                        var errorType = event && (event.type === 'load' ? 'missing' : event.type);
     295/******/                                        var realSrc = event && event.target && event.target.src;
     296/******/                                        error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
     297/******/                                        error.name = 'ChunkLoadError';
     298/******/                                        error.type = errorType;
     299/******/                                        error.request = realSrc;
     300/******/                                        installedChunkData[1](error);
     301/******/                                    }
     302/******/                                }
     303/******/                            };
     304/******/                            __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId);
     305/******/                        } else installedChunks[chunkId] = 0;
     306/******/                    }
     307/******/                }
     308/******/        };
    164309/******/       
    165310/******/        // no prefetching
     
    173318/******/        // no on chunks loaded
    174319/******/       
    175 /******/        // no jsonp function
     320/******/        // install a JSONP callback for chunk loading
     321/******/        var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
     322/******/            var [chunkIds, moreModules, runtime] = data;
     323/******/            // add "moreModules" to the modules object,
     324/******/            // then flag all "chunkIds" as loaded and fire callback
     325/******/            var moduleId, chunkId, i = 0;
     326/******/            if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
     327/******/                for(moduleId in moreModules) {
     328/******/                    if(__webpack_require__.o(moreModules, moduleId)) {
     329/******/                        __webpack_require__.m[moduleId] = moreModules[moduleId];
     330/******/                    }
     331/******/                }
     332/******/                if(runtime) var result = runtime(__webpack_require__);
     333/******/            }
     334/******/            if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
     335/******/            for(;i < chunkIds.length; i++) {
     336/******/                chunkId = chunkIds[i];
     337/******/                if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
     338/******/                    installedChunks[chunkId][0]();
     339/******/                }
     340/******/                installedChunks[chunkId] = 0;
     341/******/            }
     342/******/       
     343/******/        }
     344/******/       
     345/******/        var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || [];
     346/******/        chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
     347/******/        chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
    176348/******/    })();
    177349/******/   
  • squeeze/trunk/assets/js/script.bundle.js

    r3311866 r3345284  
    1717/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
    1818
    19 eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"handleBulkButtonClick\": () => (/* binding */ handleBulkButtonClick),\n/* harmony export */   \"handleBulkFromPage\": () => (/* binding */ handleBulkFromPage),\n/* harmony export */   \"handleBulkToggle\": () => (/* binding */ handleBulkToggle),\n/* harmony export */   \"handleButtonsClick\": () => (/* binding */ handleButtonsClick),\n/* harmony export */   \"handleClosePathDialog\": () => (/* binding */ handleClosePathDialog),\n/* harmony export */   \"handleDirectoryCheck\": () => (/* binding */ handleDirectoryCheck),\n/* harmony export */   \"handleDirectoryClick\": () => (/* binding */ handleDirectoryClick),\n/* harmony export */   \"handleFetchImagesFromPage\": () => (/* binding */ handleFetchImagesFromPage),\n/* harmony export */   \"handleMultiFileFormUpload\": () => (/* binding */ handleMultiFileFormUpload),\n/* harmony export */   \"handleOnLeave\": () => (/* binding */ handleOnLeave),\n/* harmony export */   \"handleRecursiveUpload\": () => (/* binding */ handleRecursiveUpload),\n/* harmony export */   \"handleRestoreBtnClick\": () => (/* binding */ handleRestoreBtnClick),\n/* harmony export */   \"handleSingleBtnClick\": () => (/* binding */ handleSingleBtnClick)\n/* harmony export */ });\n/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./helpers.js */ \"./assets/js/helpers.js\");\n/* harmony import */ var _squeeze_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./squeeze.js */ \"./assets/js/squeeze.js\");\n\r\n\r\n\r\n\r\n\r\n\r\nconst { __ } = wp.i18n; // Import __() from wp.i18n\r\nconst Squeeze = new _squeeze_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"](squeezeOptions);\r\n\r\nconst updateUI = (initId, response) => {\r\n  const statusEl = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.postsFilterForm?.querySelector(`#post-${initId} .column-squeeze .squeeze_status`);\r\n  if (statusEl) statusEl.innerHTML = response.data;\r\n\r\n  const gridItem = document.querySelector(`.media-frame.mode-grid .attachment[data-id=\"${initId}\"]`);\r\n  if (gridItem) {\r\n    const centered = gridItem.querySelector('.centered');\r\n    const progress = gridItem.querySelector('.media-progress-bar');\r\n    if (centered) centered.style.display = 'block';\r\n    if (progress) progress.remove();\r\n    gridItem.classList.remove('uploading');\r\n  }\r\n};\r\n\r\nconst getTotalPages = (path) => {\r\n  const selectors = {\r\n    uncompressed: \"input[name='squeeze_bulk_uncompressed_pages']\",\r\n    all: \"input[name='squeeze_bulk_total_pages']\"\r\n  };\r\n  const sel = selectors[path];\r\n  const val = sel && document.querySelector(sel)?.value;\r\n  return Number(val) || 1;\r\n};\r\n\r\nconst checkPaused = (data, page) => {\r\n  if (!_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.isPaused) return false;\r\n  handleBulkPause(data, page);\r\n  return true;\r\n};\r\n\r\nconst logAndThumbnail = async (filename, response, wrapper) => {\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(response.data, {\r\n    mediaLogWrapper: wrapper,\r\n    iconId: response.success ? 'check-mark-circle-icon' : 'ban-sign-icon'\r\n  });\r\n\r\n  const titleEl = wrapper.querySelector('h3');\r\n  if (titleEl && response.filename) {\r\n    titleEl.textContent = `${__('Media', 'squeeze')} ${filename} (${response.filename}):`;\r\n  }\r\n\r\n  const thumbUrl = response.sizes?.thumbnail?.url || response.url;\r\n  if (thumbUrl) {\r\n    const thumb = document.createElement('div');\r\n    thumb.classList.add('media-log-thumbnail');\r\n    thumb.innerHTML = `<img src=\"${thumbUrl}\" alt=\"${filename}\"/>`;\r\n    wrapper.appendChild(thumb);\r\n  }\r\n};\r\n\r\nconst handleDirectoryCheck = (event) => {\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.savePathBtn.disabled = !_helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.dirContainer.querySelector(\"input[type='checkbox']:checked\");\r\n};\r\n\r\nconst handleClosePathDialog = (event) => {\r\n  if (!event.target.contains(_helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.pathDialog)) return;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.pathDialog.close();\r\n};\r\n\r\nconst handleBulkToggle = (event, process, mediaIDs, page = 1) => {\r\n  const isPaused = event.target.dataset.running === 'true';\r\n\r\n  event.target.dataset.running = isPaused ? 'false' : 'true';\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.updateButtonText(event.target, isPaused ? __('Resume bulk squeezing', 'squeeze') : __('Pause bulk squeezing', 'squeeze'), isPaused ? '#play-button-round-icon' : '#pause-button-icon');\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.isPaused = isPaused;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.process = process;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs = mediaIDs;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page = page;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.target = event.target;\r\n\r\n  console.log('handleBulkToggle', _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData);\r\n\r\n  return isPaused;\r\n};\r\n\r\n// Handle single compress button click\r\n// manually pass Squeeze, because of the dynamic options update in the Preview Mode\r\nconst handleSingleBtnClick = async (event, Squeeze) => {\r\n  const attachmentID = event.target.dataset.attachment;\r\n  const squeezeStatus = event.target.closest(\"td\").querySelector(\".squeeze_status\");\r\n\r\n  try {\r\n    wp.media.attachment(attachmentID).fetch().then(async (data) => {\r\n      const attachment = { attributes: data };\r\n\r\n      try {\r\n        const compressData = await Squeeze.handleCompress(attachment);\r\n        const response = await Squeeze.handleUpload({ attachment, base64: compressData });\r\n\r\n        //squeezeStatus.innerHTML = response?.data?.message ?? response;\r\n        squeezeStatus.innerHTML = response?.data ?? response;\r\n\r\n        if (event.target.closest(\"td.field\")) {\r\n          const table = event.target.closest(\"td\")?.querySelector(\".squeeze_status .squeeze-comparison-table\");\r\n          if (table) {\r\n            const td = document.createElement(\"td\");\r\n            td.classList.add(\"field\");\r\n            td.style.width = \"100%\";\r\n            td.appendChild(table);\r\n            event.target.closest(\"tr\").appendChild(td);\r\n          }\r\n        }\r\n        // TBD: add file size label to the attachment info\r\n        /*\r\n        if (event.target.closest('.attachment-info')) {\r\n          const fileSizeLabel = event.target.closest('.attachment-info').querySelector('.file-size');\r\n          if (fileSizeLabel) {\r\n            const fileSize = response?.data?.sizes?.scaled?.compressed_size ?? response?.data?.sizes?.original?.compressed_size ?? null;\r\n            if (fileSize) {\r\n              const humanFileSize = SqueezeHelpers.humanFileSize(fileSize, true);\r\n              fileSizeLabel.innerHTML = fileSizeLabel.innerHTML.replace(/(<\\/strong>\\s*)(.*)/, `$1${humanFileSize}`);\r\n            }\r\n          }\r\n        }\r\n        */\r\n      } catch (error) {\r\n        console.error(error);\r\n        squeezeStatus.innerHTML = error;\r\n      } finally {\r\n        _helpers_js__WEBPACK_IMPORTED_MODULE_0__.removeAllButtons(event.target.closest(\"td\")?.querySelectorAll(`button`));\r\n        window.onbeforeunload = null;\r\n      }\r\n    });\r\n  } catch (error) {\r\n    console.error(error);\r\n    squeezeStatus.innerHTML = error;\r\n    event.target.remove();\r\n  }\r\n};\r\n\r\nconst handleRestoreBtnClick = async (event) => {\r\n  const attachmentID = event.target.dataset.attachment;\r\n\r\n  event.target.disabled = true;\r\n  event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = '⏳ ' + __('Restore in process...', 'squeeze');\r\n\r\n  try {\r\n    const response = await Squeeze.handleRestore(attachmentID);\r\n    event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = response.data;\r\n  } catch (error) {\r\n    console.error(error);\r\n    event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = error;\r\n  } finally {\r\n    event.target.closest('td').querySelector(`[name='squeeze_compress_again']`).disabled = false;\r\n    event.target.remove();\r\n    window.onbeforeunload = null;\r\n  }\r\n};\r\n\r\nconst handleBulkButtonClick = async (event, process, mediaIDs, currentPage) => {\r\n  if (mediaIDs.length === 0) return;\r\n\r\n  const totalPages = getTotalPages(process);\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.disableBulkButtons();\r\n  window.onbeforeunload = handleOnLeave;\r\n\r\n  if (_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.process === process) {\r\n    if (_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs/*.length > 0*/) {\r\n      mediaIDs = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs;\r\n    }\r\n    if (_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page) {\r\n      currentPage = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page;\r\n    }\r\n  }\r\n\r\n  const isPaused = handleBulkToggle(event, process, mediaIDs, currentPage);\r\n  if (isPaused) {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.updateButtonText(event.target, __('Pausing...', 'squeeze'), '#pause-button-icon');\r\n    return;\r\n  } else {\r\n    event.target.disabled = false;\r\n  }\r\n\r\n  try {\r\n    const finalResponse = await handleRecursiveUpload(process, mediaIDs, currentPage, true);\r\n\r\n    if (finalResponse?.mediaIDs) {\r\n      if (finalResponse.mediaIDs.length === 0 && finalResponse.page >= totalPages) {\r\n        alert(__('All images have been processed!', 'squeeze'));\r\n        window.onbeforeunload = null;\r\n        _helpers_js__WEBPACK_IMPORTED_MODULE_0__.restoreBulkButtons();\r\n      }\r\n    }\r\n  } catch (error) {\r\n    console.error(error);\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.restoreBulkButtons();\r\n    window.onbeforeunload = null;\r\n    alert(__('An error has occured. Check the console for details.', 'squeeze'));\r\n  }\r\n};\r\n\r\n// manually pass Squeeze, because of the dynamic options update in the Preview Mode\r\nconst handleButtonsClick = async (event, Squeeze) => {\r\n  const singleBtnName = 'squeeze_compress_single';\r\n  const compressAgainBtnName = 'squeeze_compress_again';\r\n  const restoreBtnName = 'squeeze_restore';\r\n\r\n  if (event.target.getAttribute(\"name\") === singleBtnName || event.target.getAttribute(\"name\") === compressAgainBtnName) {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.disableAllButtons(event.target.closest(\"td\").querySelectorAll(`button`));\r\n    event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = '⏳ ' + __('Squeezing...', 'squeeze');\r\n    window.onbeforeunload = handleOnLeave;\r\n    handleSingleBtnClick(event, Squeeze);\r\n  }\r\n\r\n  if (event.target.getAttribute(\"name\") === restoreBtnName) {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.disableAllButtons(event.target.closest(\"td\").querySelectorAll(`button`));\r\n    window.onbeforeunload = handleOnLeave;\r\n    handleRestoreBtnClick(event);\r\n  }\r\n};\r\n\r\nconst handleDirectoryClick = async (event) => {\r\n  if (event.target !== event.currentTarget) return;\r\n\r\n  const currentDir = event.target.closest(\".directory-item\");\r\n  const currentPath = currentDir.dataset.path;\r\n  const parentPath = currentDir.dataset.parent;\r\n\r\n  if (parentPath === '/' || currentDir.classList.contains(\"loading\")) return;\r\n\r\n  if (currentDir.classList.contains(\"loaded\")) {\r\n    currentDir.classList.toggle(\"opened\");\r\n    return;\r\n  }\r\n\r\n  currentDir.classList.add(\"loading\");\r\n\r\n  const subDirs = await Squeeze.getDirectories(currentPath);\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.renderDirectories(subDirs, currentDir, {\r\n    handleDirectoryClick,\r\n    handleDirectoryCheck\r\n  });\r\n\r\n  currentDir.classList.remove(\"loading\");\r\n  currentDir.classList.add(\"loaded\", \"opened\");\r\n}\r\n\r\n/**\r\n * Hadnle warning on page leave\r\n*/\r\nconst handleOnLeave = () => {\r\n  const urlParams = new URLSearchParams(window.location.search);\r\n  const page = urlParams.get('page');\r\n  const isUploadPage = window.location.href.includes('upload.php');\r\n  const isMediaNewPage = window.location.href.includes('media-new.php');\r\n  const isAttachmentPage = window.location.href.includes('post.php') && urlParams.get('action') === 'edit';\r\n\r\n  if (page === 'squeeze-bulk' || isMediaNewPage || isAttachmentPage) {\r\n    return __('Are you sure you want to leave this page? The squeezing process will be terminated!', 'squeeze');\r\n  }\r\n  if (isUploadPage) {\r\n    return __('Are you sure you want to leave this page? The settings will not be saved!', 'squeeze');\r\n  }\r\n};\r\n\r\nconst handleBulkPause = (data, currentPage) => {\r\n  window.onbeforeunload = null;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(__('Bulk squeezing has been paused!', 'squeeze'), { isPause: true });\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs = data;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page = currentPage;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.target.disabled = false;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.updateButtonText(_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.target, __('Resume bulk squeezing', 'squeeze'), '#play-button-round-icon');\r\n};\r\n\r\nconst handleUpdateChart = (uncompressedImagesCount) => {\r\n  const chartValue = document.querySelector(\".squeeze-bulk-media-stats-chart-value > text\");\r\n  const chartBar = document.querySelector(\".squeeze-bulk-media-stats-chart\");\r\n  const squeezedImages = document.querySelector(\".squeeze-bulk-media-stats-item-value\");\r\n\r\n  if (!chartValue || !chartBar) return;\r\n\r\n  const imagesLeft = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.totalImages - uncompressedImagesCount;\r\n  const percentage = parseFloat((imagesLeft / _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.totalImages) * 100).toFixed(2);\r\n  const dasharray = percentage * 560 / 100;\r\n  chartValue.textContent = `${percentage}%`;\r\n  chartBar.style.setProperty('--squeeze-dasharray', dasharray);\r\n\r\n  if (squeezedImages) {\r\n    squeezedImages.textContent = `${imagesLeft} / ${_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.totalImages}`;\r\n  }\r\n};\r\n\r\nconst handleRecursiveUpload = async (path, data, currentPage, isUpdateChart = false) => {\r\n\r\n  if (!Array.isArray(data)) return { success: false, data: 'No data provided!', mediaIDs: [] }; // when bulk directory path has no images\r\n  \r\n  const totalPages = getTotalPages(path);\r\n\r\n  if (data.length === 0) {\r\n    currentPage += 1;\r\n    if (currentPage > totalPages || !_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.lastId) return { success: true, data: __('No more images found!', 'squeeze'), mediaIDs: [], page: currentPage };\r\n\r\n    const maybeGetNextMediaIDs = await Squeeze.getNextAttachments(currentPage, path, _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.lastId);\r\n    if (maybeGetNextMediaIDs.success && maybeGetNextMediaIDs.data.length > 0) {\r\n      const nextMediaIDs = maybeGetNextMediaIDs.data;\r\n      return handleRecursiveUpload(path, nextMediaIDs, currentPage, isUpdateChart);\r\n    } else {\r\n      return { success: true, data: __('No more images found!', 'squeeze'), mediaIDs: [], page: currentPage };\r\n    }\r\n  }\r\n\r\n  const initData = [...data];  // initial data\r\n\r\n  const filename = data[0]?.filename ? data[0].filename : `ID #${data[0]}`;\r\n  const mediaLogWrapper = await _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(`${__('Start squeezing...', 'squeeze')}`, { title: filename, isStart: true });\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.lastId = data[0] || 0; // update lastId to the last processed ID\r\n\r\n  try {\r\n    const response = await Squeeze.handleBulkUpload(path, data);\r\n\r\n    await logAndThumbnail(filename, response, mediaLogWrapper);\r\n\r\n    if (isUpdateChart && path !== 'all') {\r\n      let uncompressedImagesCount = 0;\r\n      if (path === 'uncompressed') {\r\n        _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.uncompressedImages = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.uncompressedImages - 1 || 0;\r\n        uncompressedImagesCount = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.uncompressedImages;\r\n      } else if (path === 'path') {\r\n        uncompressedImagesCount = response.mediaIDs.length;\r\n      }\r\n      handleUpdateChart(uncompressedImagesCount);\r\n    }\r\n\r\n    if (checkPaused(data, currentPage)) {\r\n      return { success: false, data: 'Process has been paused!', mediaIDs: data, page: currentPage };\r\n    }\r\n\r\n    updateUI(initData[0], response);\r\n\r\n    if (response.mediaIDs.length > 0) {\r\n      return handleRecursiveUpload(path, response.mediaIDs, currentPage, isUpdateChart);\r\n    } else {\r\n      currentPage += 1;\r\n      if (currentPage > totalPages) return { ...response, page: currentPage };\r\n\r\n      const lastId = initData[initData.length - 1];\r\n      const maybeGetNextMediaIDs = await Squeeze.getNextAttachments(currentPage, path, lastId);\r\n      if (maybeGetNextMediaIDs.success && maybeGetNextMediaIDs.data.length > 0) {\r\n        const nextMediaIDs = maybeGetNextMediaIDs.data;\r\n        return handleRecursiveUpload(path, nextMediaIDs, currentPage, isUpdateChart);\r\n      }\r\n    }\r\n\r\n    return response;\r\n\r\n  } catch (error) {\r\n    console.error(error);\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(`${error}`, { mediaLogWrapper, iconId: 'ban-sign-icon' });\r\n\r\n    if (data.length > 0) {\r\n      return handleRecursiveUpload(path, data, currentPage, isUpdateChart);\r\n    } else {\r\n      currentPage += 1;\r\n      if (currentPage > totalPages) return { success: false, data: error, mediaIDs: [], page: currentPage };\r\n\r\n      const lastId = initData[initData.length - 1];\r\n      const maybeGetNextMediaIDs = await Squeeze.getNextAttachments(currentPage, path, lastId);\r\n      if (maybeGetNextMediaIDs.success && maybeGetNextMediaIDs.data.length > 0) {\r\n        const nextMediaIDs = maybeGetNextMediaIDs.data;\r\n        return handleRecursiveUpload(path, nextMediaIDs, currentPage, isUpdateChart);\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\n\r\n\r\nconst handleMultiFileFormUpload = (compressOptions) => {\r\n  if (typeof wpUploaderInit === 'undefined' || typeof plupload === 'undefined' || typeof uploader === 'undefined') return;\r\n\r\n  const SqueezeUploader = uploader;\r\n\r\n  SqueezeUploader.bind('FilesAdded', function (up, files) { });\r\n\r\n  SqueezeUploader.bind('FileUploaded', function (up, file, response) {\r\n    const fileMime = file.type;\r\n    const fileType = fileMime.split('/')[0];\r\n    const fileSubType = fileMime.split('/')[1];\r\n\r\n    if (!_helpers_js__WEBPACK_IMPORTED_MODULE_0__.maybeCompressAttachment(fileType, fileSubType, compressOptions)) return;\r\n\r\n    const fileID = file.id;\r\n    const attachmentID = response.response;\r\n    const mediaItem = document.getElementById(`media-item-${fileID}`);\r\n\r\n    window.onbeforeunload = handleOnLeave;\r\n\r\n    /**\r\n     * Wait for media item to load( 'async-upload.php' )\r\n     * Ping every 1 second until the media item is loaded\r\n     * @returns Promise\r\n    */\r\n    const waitForItemLoad = () => {\r\n      return new Promise((resolve) => {\r\n        let interval = setInterval(() => {\r\n          if (mediaItem.querySelector('.media-item-wrapper')) {\r\n            mediaItem.querySelector('.media-item-wrapper').innerHTML += `\r\n              <div class=\"progress\">\r\n                <div class=\"percent\">${__('Squeezing...', 'squeeze')}</div>\r\n                <div class=\"bar\" style=\"width: 200px;\"></div>\r\n              </div>\r\n            `;\r\n            clearInterval(interval);\r\n            resolve();\r\n          }\r\n        }, 1000);\r\n      });\r\n    };\r\n\r\n    waitForItemLoad().then(() => {\r\n      try {\r\n        wp.media.attachment(attachmentID).fetch().then(async function (data) {\r\n          const attachment = { attributes: data };\r\n\r\n          try {\r\n            const compressData = await Squeeze.handleCompress(attachment);\r\n            const uploadData = await Squeeze.handleUpload({ attachment, base64: compressData });\r\n\r\n            if (uploadData.success) {\r\n              window.onbeforeunload = null;\r\n              mediaItem.innerHTML += `<div class=\"squeeze_status\">${uploadData.data}</div>`;\r\n              mediaItem.querySelector('.progress')?.remove();\r\n            } else {\r\n              alert(uploadData?.data ?? uploadData);\r\n              window.onbeforeunload = null;\r\n              mediaItem.querySelector('.progress')?.remove();\r\n            }\r\n          } catch (error) {\r\n            console.error(error);\r\n            mediaItem.innerHTML += error;\r\n            window.onbeforeunload = null;\r\n            mediaItem.querySelector('.progress')?.remove();\r\n          }\r\n        });\r\n      } catch (error) {\r\n        console.error(error);\r\n        mediaItem.innerHTML += error;\r\n        window.onbeforeunload = null;\r\n        mediaItem.querySelector('.progress')?.remove();\r\n      }\r\n    });\r\n  });\r\n\r\n  SqueezeUploader.bind('UploadComplete', function (up, files) { });\r\n};\n\n//# sourceURL=webpack:///./assets/js/handlers.js?");
     19eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"handleBulkButtonClick\": () => (/* binding */ handleBulkButtonClick),\n/* harmony export */   \"handleBulkFromPage\": () => (/* binding */ handleBulkFromPage),\n/* harmony export */   \"handleBulkToggle\": () => (/* binding */ handleBulkToggle),\n/* harmony export */   \"handleButtonsClick\": () => (/* binding */ handleButtonsClick),\n/* harmony export */   \"handleClosePathDialog\": () => (/* binding */ handleClosePathDialog),\n/* harmony export */   \"handleCompressBeforeUpload\": () => (/* binding */ handleCompressBeforeUpload),\n/* harmony export */   \"handleDirectoryCheck\": () => (/* binding */ handleDirectoryCheck),\n/* harmony export */   \"handleDirectoryClick\": () => (/* binding */ handleDirectoryClick),\n/* harmony export */   \"handleFetchImagesFromPage\": () => (/* binding */ handleFetchImagesFromPage),\n/* harmony export */   \"handleMultiFileFormUpload\": () => (/* binding */ handleMultiFileFormUpload),\n/* harmony export */   \"handleOnLeave\": () => (/* binding */ handleOnLeave),\n/* harmony export */   \"handleRecursiveUpload\": () => (/* binding */ handleRecursiveUpload),\n/* harmony export */   \"handleRestoreBtnClick\": () => (/* binding */ handleRestoreBtnClick),\n/* harmony export */   \"handleSingleBtnClick\": () => (/* binding */ handleSingleBtnClick)\n/* harmony export */ });\n/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./helpers.js */ \"./assets/js/helpers.js\");\n/* harmony import */ var _squeeze_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./squeeze.js */ \"./assets/js/squeeze.js\");\n\r\n\r\n\r\n\r\n\r\n\r\nconst { __ } = wp.i18n; // Import __() from wp.i18n\r\nconst Squeeze = new _squeeze_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"](squeezeOptions);\r\n\r\nconst updateUI = (initId, response) => {\r\n  const statusEl = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.postsFilterForm?.querySelector(`#post-${initId} .column-squeeze .squeeze_status`);\r\n  if (statusEl) statusEl.innerHTML = response?.data?.message ?? response?.data ?? response;\r\n\r\n  const gridItem = document.querySelector(`.media-frame.mode-grid .attachment[data-id=\"${initId}\"]`);\r\n  if (gridItem) {\r\n    const centered = gridItem.querySelector('.centered');\r\n    const progress = gridItem.querySelector('.media-progress-bar');\r\n    if (centered) centered.style.display = 'block';\r\n    if (progress) progress.remove();\r\n    gridItem.classList.remove('uploading');\r\n  }\r\n};\r\n\r\nconst getTotalPages = (path) => {\r\n  const selectors = {\r\n    uncompressed: \"input[name='squeeze_bulk_uncompressed_pages']\",\r\n    all: \"input[name='squeeze_bulk_total_pages']\"\r\n  };\r\n  const sel = selectors[path];\r\n  const val = sel && document.querySelector(sel)?.value;\r\n  return Number(val) || 1;\r\n};\r\n\r\nconst checkPaused = (data, page) => {\r\n  if (!_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.isPaused) return false;\r\n  handleBulkPause(data, page);\r\n  return true;\r\n};\r\n\r\nconst logAndThumbnail = async (filename, response, wrapper) => {\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(response?.data?.message ?? response?.data, {\r\n    mediaLogWrapper: wrapper,\r\n    iconId: response.success ? 'check-mark-circle-icon' : 'ban-sign-icon'\r\n  });\r\n\r\n  const titleEl = wrapper?.querySelector('h3');\r\n  if (titleEl && response?.data?.filename) {\r\n    titleEl.textContent = `${__('Media', 'squeeze')} ${filename} (${response.data.filename}):`;\r\n  }\r\n\r\n  const thumbUrl = response?.data?.sizes?.thumbnail?.url || response?.data?.url || response?.url;\r\n  if (thumbUrl) {\r\n    const thumb = document.createElement('div');\r\n    thumb.classList.add('media-log-thumbnail');\r\n    thumb.innerHTML = `<img src=\"${thumbUrl}\" alt=\"${filename}\"/>`;\r\n    wrapper?.appendChild(thumb);\r\n  }\r\n};\r\n\r\nconst handleDirectoryCheck = (event) => {\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.savePathBtn.disabled = !_helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.dirContainer.querySelector(\"input[type='checkbox']:checked\");\r\n};\r\n\r\nconst handleClosePathDialog = (event) => {\r\n  if (!event.target.contains(_helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.pathDialog)) return;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.elements.pathDialog.close();\r\n};\r\n\r\nconst handleBulkToggle = (event, process, mediaIDs, page = 1) => {\r\n  const isPaused = event.target.dataset.running === 'true';\r\n\r\n  event.target.dataset.running = isPaused ? 'false' : 'true';\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.updateButtonText(event.target, isPaused ? __('Resume bulk squeezing', 'squeeze') : __('Pause bulk squeezing', 'squeeze'), isPaused ? '#play-button-round-icon' : '#pause-button-icon');\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.isPaused = isPaused;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.process = process;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs = mediaIDs;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page = page;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.target = event.target;\r\n\r\n  //console.log('handleBulkToggle', cachedMediaData);\r\n\r\n  return isPaused;\r\n};\r\n\r\n// Handle single compress button click\r\n// manually pass Squeeze, because of the dynamic options update in the Preview Mode\r\nconst handleSingleBtnClick = async (event, Squeeze) => {\r\n  const attachmentID = event.target.dataset.attachment;\r\n  const squeezeStatus = event.target.closest(\"td\").querySelector(\".squeeze_status\");\r\n\r\n  try {\r\n    wp.media.attachment(attachmentID).fetch().then(async (data) => {\r\n      const attachment = { attributes: data };\r\n\r\n      try {\r\n        const compressData = await Squeeze.handleCompress(attachment);\r\n        const response = await Squeeze.handleUpload({ attachment, base64: compressData });\r\n\r\n        squeezeStatus.innerHTML = response?.data?.message ?? response?.data ?? response;\r\n\r\n        if (event.target.closest(\"td.field\")) {\r\n          const table = event.target.closest(\"td\")?.querySelector(\".squeeze_status .squeeze-comparison-table\");\r\n          if (table) {\r\n            const td = document.createElement(\"td\");\r\n            td.classList.add(\"field\");\r\n            td.style.width = \"100%\";\r\n            td.appendChild(table);\r\n            event.target.closest(\"tr\").appendChild(td);\r\n          }\r\n        }\r\n        // TBD: add file size label to the attachment info\r\n        /*\r\n        if (event.target.closest('.attachment-info')) {\r\n          const fileSizeLabel = event.target.closest('.attachment-info').querySelector('.file-size');\r\n          if (fileSizeLabel) {\r\n            const fileSize = response?.data?.sizes?.scaled?.compressed_size ?? response?.data?.sizes?.original?.compressed_size ?? null;\r\n            if (fileSize) {\r\n              const humanFileSize = SqueezeHelpers.humanFileSize(fileSize, true);\r\n              fileSizeLabel.innerHTML = fileSizeLabel.innerHTML.replace(/(<\\/strong>\\s*)(.*)/, `$1${humanFileSize}`);\r\n            }\r\n          }\r\n        }\r\n        */\r\n      } catch (error) {\r\n        console.error(error);\r\n        squeezeStatus.innerHTML = error?.message ?? error;\r\n      } finally {\r\n        _helpers_js__WEBPACK_IMPORTED_MODULE_0__.removeAllButtons(event.target.closest(\"td\")?.querySelectorAll(`button`));\r\n        window.onbeforeunload = null;\r\n      }\r\n    });\r\n  } catch (error) {\r\n    console.error(error);\r\n    squeezeStatus.innerHTML = error?.message ?? error;\r\n    event.target.remove();\r\n  }\r\n};\r\n\r\nconst handleRestoreBtnClick = async (event) => {\r\n  const attachmentID = event.target.dataset.attachment;\r\n\r\n  event.target.disabled = true;\r\n  event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = '⏳ ' + __('Restore in process...', 'squeeze');\r\n\r\n  try {\r\n    const response = await Squeeze.handleRestore(attachmentID);\r\n    event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = response?.data ?? response;\r\n  } catch (error) {\r\n    console.error(error);\r\n    event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = error?.message ?? JSON.stringify(error, null, 2);\r\n  } finally {\r\n    event.target.closest('td').querySelector(`[name='squeeze_compress_again']`).disabled = false;\r\n    event.target.remove();\r\n    window.onbeforeunload = null;\r\n  }\r\n};\r\n\r\nconst handleBulkButtonClick = async (event, process, mediaIDs, currentPage) => {\r\n  if (mediaIDs.length === 0) return;\r\n\r\n  const totalPages = getTotalPages(process);\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.disableBulkButtons();\r\n  window.onbeforeunload = handleOnLeave;\r\n\r\n  if (_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.process === process) {\r\n    if (_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs/*.length > 0*/) {\r\n      mediaIDs = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs;\r\n    }\r\n    if (_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page) {\r\n      currentPage = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page;\r\n    }\r\n  }\r\n\r\n  const isPaused = handleBulkToggle(event, process, mediaIDs, currentPage);\r\n  if (isPaused) {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.updateButtonText(event.target, __('Pausing...', 'squeeze'), '#pause-button-icon');\r\n    return;\r\n  } else {\r\n    event.target.disabled = false;\r\n  }\r\n\r\n  try {\r\n    const finalResponse = await handleRecursiveUpload(process, mediaIDs, currentPage, true);\r\n\r\n    if (finalResponse?.mediaIDs) {\r\n      if (finalResponse.mediaIDs.length === 0 && finalResponse.page >= totalPages) {\r\n        alert(__('All images have been processed!', 'squeeze'));\r\n        window.onbeforeunload = null;\r\n        _helpers_js__WEBPACK_IMPORTED_MODULE_0__.restoreBulkButtons();\r\n      }\r\n    }\r\n  } catch (error) {\r\n    console.error(error);\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.restoreBulkButtons();\r\n    window.onbeforeunload = null;\r\n    alert(__('An error has occured. Check the console for details.', 'squeeze'));\r\n  }\r\n};\r\n\r\n// manually pass Squeeze, because of the dynamic options update in the Preview Mode\r\nconst handleButtonsClick = async (event, Squeeze) => {\r\n  const singleBtnName = 'squeeze_compress_single';\r\n  const compressAgainBtnName = 'squeeze_compress_again';\r\n  const restoreBtnName = 'squeeze_restore';\r\n\r\n  if (event.target.getAttribute(\"name\") === singleBtnName || event.target.getAttribute(\"name\") === compressAgainBtnName) {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.disableAllButtons(event.target.closest(\"td\").querySelectorAll(`button`));\r\n    event.target.closest(\"td\").querySelector(\".squeeze_status\").innerHTML = '⏳ ' + __('Squeezing...', 'squeeze');\r\n    window.onbeforeunload = handleOnLeave;\r\n    handleSingleBtnClick(event, Squeeze);\r\n  }\r\n\r\n  if (event.target.getAttribute(\"name\") === restoreBtnName) {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.disableAllButtons(event.target.closest(\"td\").querySelectorAll(`button`));\r\n    window.onbeforeunload = handleOnLeave;\r\n    handleRestoreBtnClick(event);\r\n  }\r\n};\r\n\r\nconst handleDirectoryClick = async (event) => {\r\n  if (event.target !== event.currentTarget) return;\r\n\r\n  const currentDir = event.target.closest(\".directory-item\");\r\n  const currentPath = currentDir.dataset.path;\r\n  const parentPath = currentDir.dataset.parent;\r\n\r\n  if (parentPath === '/' || currentDir.classList.contains(\"loading\")) return;\r\n\r\n  if (currentDir.classList.contains(\"loaded\")) {\r\n    currentDir.classList.toggle(\"opened\");\r\n    return;\r\n  }\r\n\r\n  currentDir.classList.add(\"loading\");\r\n\r\n  const subDirs = await Squeeze.getDirectories(currentPath);\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.renderDirectories(subDirs, currentDir, {\r\n    handleDirectoryClick,\r\n    handleDirectoryCheck\r\n  });\r\n\r\n  currentDir.classList.remove(\"loading\");\r\n  currentDir.classList.add(\"loaded\", \"opened\");\r\n}\r\n\r\n/**\r\n * Hadnle warning on page leave\r\n*/\r\nconst handleOnLeave = () => {\r\n  const urlParams = new URLSearchParams(window.location.search);\r\n  const page = urlParams.get('page');\r\n  const isUploadPage = window.location.href.includes('upload.php');\r\n  const isMediaNewPage = window.location.href.includes('media-new.php');\r\n  const isAttachmentPage = window.location.href.includes('post.php') && urlParams.get('action') === 'edit';\r\n\r\n  if (page === 'squeeze-bulk' || isMediaNewPage || isAttachmentPage) {\r\n    return __('Are you sure you want to leave this page? The squeezing process will be terminated!', 'squeeze');\r\n  }\r\n  if (isUploadPage) {\r\n    return __('Are you sure you want to leave this page? The settings will not be saved!', 'squeeze');\r\n  }\r\n};\r\n\r\nconst handleBulkPause = (data, currentPage) => {\r\n  window.onbeforeunload = null;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(__('Bulk squeezing has been paused!', 'squeeze'), { isPause: true });\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.mediaIDs = data;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.page = currentPage;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.target.disabled = false;\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.updateButtonText(_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.target, __('Resume bulk squeezing', 'squeeze'), '#play-button-round-icon');\r\n};\r\n\r\nconst handleUpdateChart = (uncompressedImagesCount) => {\r\n  const chartValue = document.querySelector(\".squeeze-bulk-media-stats-chart-value > text\");\r\n  const chartBar = document.querySelector(\".squeeze-bulk-media-stats-chart\");\r\n  const squeezedImages = document.querySelector(\".squeeze-bulk-media-stats-item-value\");\r\n\r\n  if (!chartValue || !chartBar) return;\r\n\r\n  const imagesLeft = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.totalImages - uncompressedImagesCount;\r\n  const percentage = parseFloat((imagesLeft / _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.totalImages) * 100).toFixed(2);\r\n  const dasharray = percentage * 560 / 100;\r\n  chartValue.textContent = `${percentage}%`;\r\n  chartBar.style.setProperty('--squeeze-dasharray', dasharray);\r\n\r\n  if (squeezedImages) {\r\n    squeezedImages.textContent = `${imagesLeft} / ${_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.totalImages}`;\r\n  }\r\n};\r\n\r\nconst handleRecursiveUpload = async (path, data, currentPage, isUpdateChart = false) => {\r\n\r\n  if (!Array.isArray(data)) return { success: false, data: 'No data provided!', mediaIDs: [] }; // when bulk directory path has no images\r\n\r\n  const totalPages = getTotalPages(path);\r\n\r\n  if (data.length === 0) {\r\n    currentPage += 1;\r\n    if (currentPage > totalPages || !_helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.lastId) return { success: true, data: __('No more images found!', 'squeeze'), mediaIDs: [], page: currentPage };\r\n\r\n    const maybeGetNextMediaIDs = await Squeeze.getNextAttachments(currentPage, path, _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.lastId);\r\n    if (maybeGetNextMediaIDs.success && maybeGetNextMediaIDs.data.length > 0) {\r\n      const nextMediaIDs = maybeGetNextMediaIDs.data;\r\n      return handleRecursiveUpload(path, nextMediaIDs, currentPage, isUpdateChart);\r\n    } else {\r\n      return { success: true, data: __('No more images found!', 'squeeze'), mediaIDs: [], page: currentPage };\r\n    }\r\n  }\r\n\r\n  const initData = [...data];  // initial data\r\n\r\n  const filename = data[0]?.filename ? data[0].filename : `ID #${data[0]}`;\r\n  const mediaLogWrapper = await _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(`${__('Start squeezing...', 'squeeze')}`, { title: filename, isStart: true });\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.lastId = data[0] || 0; // update lastId to the last processed ID\r\n\r\n  try {\r\n    const response = await Squeeze.handleBulkUpload(path, data);\r\n\r\n    //console.log('handleRecursiveUpload response', response);\r\n\r\n    await logAndThumbnail(filename, response, mediaLogWrapper);\r\n\r\n    if (isUpdateChart && path !== 'all') {\r\n      let uncompressedImagesCount = 0;\r\n      if (path === 'uncompressed') {\r\n        _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.uncompressedImages = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.uncompressedImages - 1 || 0;\r\n        uncompressedImagesCount = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.cachedMediaData.uncompressedImages;\r\n      } else if (path === 'path') {\r\n        uncompressedImagesCount = response.mediaIDs.length;\r\n      }\r\n      handleUpdateChart(uncompressedImagesCount);\r\n    }\r\n\r\n    if (checkPaused(data, currentPage)) {\r\n      return { success: false, data: 'Process has been paused!', mediaIDs: data, page: currentPage };\r\n    }\r\n\r\n    updateUI(initData[0], response);\r\n\r\n    if (response.mediaIDs.length > 0) {\r\n      return handleRecursiveUpload(path, response.mediaIDs, currentPage, isUpdateChart);\r\n    } else {\r\n      currentPage += 1;\r\n      if (currentPage > totalPages) return { ...response, page: currentPage };\r\n\r\n      const lastId = initData[initData.length - 1];\r\n      const maybeGetNextMediaIDs = await Squeeze.getNextAttachments(currentPage, path, lastId);\r\n      if (maybeGetNextMediaIDs.success && maybeGetNextMediaIDs.data.length > 0) {\r\n        const nextMediaIDs = maybeGetNextMediaIDs.data;\r\n        return handleRecursiveUpload(path, nextMediaIDs, currentPage, isUpdateChart);\r\n      }\r\n    }\r\n\r\n    return response;\r\n\r\n  } catch (error) {\r\n    console.error(error);\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_0__.logMessage(`${error}`, { mediaLogWrapper, iconId: 'ban-sign-icon' });\r\n\r\n    if (data.length > 0) {\r\n      return handleRecursiveUpload(path, data, currentPage, isUpdateChart);\r\n    } else {\r\n      currentPage += 1;\r\n      if (currentPage > totalPages) return { success: false, data: error, mediaIDs: [], page: currentPage };\r\n\r\n      const lastId = initData[initData.length - 1];\r\n      const maybeGetNextMediaIDs = await Squeeze.getNextAttachments(currentPage, path, lastId);\r\n      if (maybeGetNextMediaIDs.success && maybeGetNextMediaIDs.data.length > 0) {\r\n        const nextMediaIDs = maybeGetNextMediaIDs.data;\r\n        return handleRecursiveUpload(path, nextMediaIDs, currentPage, isUpdateChart);\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\n\r\n\r\n/**\r\n * Handles the compression of image before upload using Squeeze.\r\n * It compresses only the original image, not the thumbnails.\r\n * \r\n * @param {object} up - The plupload instance\r\n * @param {object} pluploadFile - The file to be compressed\r\n * @param {object} compressOptions - The compression options object\r\n * @returns {boolean} - Returns false to prevent further processing of the file\r\n */\r\nconst handleCompressBeforeUpload = async (up, pluploadFile, compressOptions) => {\r\n  if (typeof Squeeze === 'undefined') return;\r\n  if (typeof Squeeze.compressBeforeUpload !== 'function') {\r\n    console.warn('Squeeze.compressBeforeUpload is not a function');\r\n    return;\r\n  }\r\n  \r\n  if (pluploadFile?._isSqueezed || pluploadFile?._isExcluded || pluploadFile?._isFailed) {\r\n    //console.warn('File is already compressed:', pluploadFile);\r\n    return; // Skip files that are already compressed\r\n  }\r\n  // Check if the file is an image based on its MIME type\r\n  if (!pluploadFile.type.startsWith('image/')) {\r\n    //console.warn('File is not an image:', pluploadFile.name);\r\n    return; // Skip non-image files\r\n  }\r\n\r\n  const file = pluploadFile.getNative() || pluploadFile.getSource();\r\n\r\n  const type = file?.type?.split('/')[0] ?? '';\r\n  const subtype = file?.type?.split('/')[1] ?? '';\r\n\r\n  if (!_helpers_js__WEBPACK_IMPORTED_MODULE_0__.maybeCompressAttachment(type, subtype, compressOptions)) {\r\n    //console.warn('Skipping compression for:', pluploadFile.name);\r\n    return; // Skip compression for this file\r\n  }\r\n\r\n  //console.time('BeforeUpload')\r\n\r\n  up.stop();\r\n  window.onbeforeunload = handleOnLeave;\r\n  \r\n  \r\n\r\n  try {\r\n    let originalFile = file;\r\n    const base64Obj = await Squeeze.compressBeforeUpload(file);\r\n    if (!base64Obj || !base64Obj.base64) {\r\n      console.warn('Compression skipped or failed for:', file.name);\r\n      pluploadFile.status = plupload.QUEUED;\r\n      pluploadFile.loaded = 0;\r\n      pluploadFile._isFailed = true; // Mark the file as failed\r\n      //window.onbeforeunload = null;\r\n      setTimeout(() => up.start(), 0);\r\n      return; // Skip further processing if compression failed or was skipped\r\n    }\r\n    \r\n    const isDirectWebp = compressOptions?.direct_webp && file.type !== 'image/webp';\r\n    const isBackupOriginal = compressOptions?.backup_original;\r\n\r\n    if (isBackupOriginal) {\r\n      // If backup original is enabled, convert the original file to WebP if it's not already\r\n      if (isDirectWebp) {\r\n        originalFile = await Squeeze.convertFileToWebp(file);\r\n      } else {\r\n        originalFile = file; // Keep the original file as is\r\n      }\r\n      pluploadFile.originalFile = originalFile; // Store the original file in the pluploadFile object\r\n    }\r\n\r\n    const compressedFile = _helpers_js__WEBPACK_IMPORTED_MODULE_0__.base64ToFile(base64Obj.base64, file.name, file.type);\r\n    const newSource = new mOxie.File(null, compressedFile);\r\n\r\n    if (!newSource) {\r\n      console.error('Failed to create new mOxie.File from base64 data');\r\n      return; // Exit if newSource is not created\r\n    }\r\n\r\n    //console.log('Compressed file created:', newSource);\r\n\r\n    // Override the file's getSource method to return the new compressed source\r\n    pluploadFile.getSource = function () {\r\n      return newSource;\r\n    };\r\n\r\n    // Reset status back to QUEUED\r\n    pluploadFile.status = plupload.QUEUED;\r\n    pluploadFile.loaded = 0;\r\n    pluploadFile._isSqueezed = true; // Mark the file as compressed\r\n    pluploadFile.base64 = base64Obj.base64; // Store the base64 data of the compressed image in the attachment\r\n    pluploadFile.base64Webp = base64Obj?.base64Webp; // Store the WebP base64 data of the compressed image in the attachment\r\n    \r\n    // In the next tick, restart the queue\r\n    setTimeout(() => up.start(), 0);\r\n\r\n    //window.onbeforeunload = null;\r\n\r\n  } catch (error) {\r\n    console.error('Error during compression before upload:', error);\r\n    pluploadFile.status = plupload.QUEUED;\r\n    pluploadFile.loaded = 0;\r\n    pluploadFile._isFailed = true; // Mark the file as failed\r\n    setTimeout(() => up.start(), 0);\r\n    return false;\r\n  }\r\n\r\n  return true;\r\n}\r\n\r\nconst handleMultiFileFormUpload = (compressOptions) => {\r\n  if (typeof wpUploaderInit === 'undefined' || typeof plupload === 'undefined' || typeof uploader === 'undefined') return;\r\n\r\n  const SqueezeUploader = uploader;\r\n\r\n  SqueezeUploader.bind('BeforeUpload', async function (up, pluploadFile) {\r\n    handleCompressBeforeUpload(up, pluploadFile, compressOptions)\r\n  });\r\n\r\n  SqueezeUploader.bind('FileUploaded', function (up, file, response) {\r\n    //console.log('FileUploaded', file, response);\r\n    const fileMime = file.type;\r\n    const fileType = fileMime.split('/')[0];\r\n    const fileSubType = fileMime.split('/')[1];\r\n\r\n    if (!_helpers_js__WEBPACK_IMPORTED_MODULE_0__.maybeCompressAttachment(fileType, fileSubType, compressOptions)) return;\r\n\r\n    /**\r\n     * Wait for media item to load( 'async-upload.php' )\r\n     * Ping every 1 second until the media item is loaded\r\n     * @returns Promise\r\n    */\r\n    const waitForItemLoad = (addProgressBar = true) => {\r\n      return new Promise((resolve) => {\r\n        let interval = setInterval(() => {\r\n          if (mediaItem.querySelector('.media-item-wrapper')) {\r\n            if (addProgressBar) {\r\n              mediaItem.querySelector('.media-item-wrapper').innerHTML += `\r\n                <div class=\"progress\">\r\n                  <div class=\"percent\">${__('Squeezing...', 'squeeze')}</div>\r\n                  <div class=\"bar\" style=\"width: 200px;\"></div>\r\n                </div>\r\n              `;\r\n            }\r\n            clearInterval(interval);\r\n            resolve();\r\n          }\r\n        }, 1000);\r\n      });\r\n    };\r\n\r\n    const fileID = file.id;\r\n    const attachmentID = response.response;\r\n    const mediaItem = document.getElementById(`media-item-${fileID}`);\r\n\r\n    if (file?._isExcluded) {\r\n      console.warn('File is excluded from compression:', file.name);\r\n      waitForItemLoad(false).then(() => {\r\n        mediaItem.innerHTML += `<div class=\"squeeze_status\">${__('File is excluded from compression:', 'squeeze')} ${file.name}</div>`;\r\n      });\r\n      window.onbeforeunload = null;\r\n      return;\r\n    }\r\n\r\n    if (file?._isFailed) {\r\n      console.warn('File compression failed:', file.name);\r\n      waitForItemLoad(false).then(() => {\r\n        mediaItem.innerHTML += `<div class=\"squeeze_status\">${__('File compression failed:', 'squeeze')} ${file.name}</div>`;\r\n      });\r\n      window.onbeforeunload = null;\r\n      return;\r\n    }\r\n\r\n    window.onbeforeunload = handleOnLeave;\r\n\r\n    waitForItemLoad().then(() => {\r\n      try {\r\n        wp.media.attachment(attachmentID).fetch().then(async function (data) {\r\n          //console.log('Fetched attachment data:', data);\r\n          const attachment = { attributes: data };\r\n\r\n          _helpers_js__WEBPACK_IMPORTED_MODULE_0__.extendAttachment(attachment, file);\r\n\r\n          try {\r\n            const compressData = await Squeeze.handleCompress(attachment);\r\n            const uploadData = await Squeeze.handleUpload({ attachment, base64: compressData });\r\n\r\n            if (uploadData.success) {\r\n              window.onbeforeunload = null;\r\n              mediaItem.innerHTML += `<div class=\"squeeze_status\">${uploadData?.data?.message}</div>`;\r\n              mediaItem.querySelector('.progress')?.remove();\r\n            } else {\r\n              mediaItem.innerHTML += uploadData?.data?.message ?? uploadData?.data ?? uploadData;\r\n              window.onbeforeunload = null;\r\n              mediaItem.querySelector('.progress')?.remove();\r\n            }\r\n          } catch (error) {\r\n            console.error(error);\r\n            mediaItem.innerHTML += error;\r\n            window.onbeforeunload = null;\r\n            mediaItem.querySelector('.progress')?.remove();\r\n          }\r\n        });\r\n      } catch (error) {\r\n        console.error(error);\r\n        mediaItem.innerHTML += error;\r\n        window.onbeforeunload = null;\r\n        mediaItem.querySelector('.progress')?.remove();\r\n      }\r\n    });\r\n  });\r\n}\r\n\r\n\n\n//# sourceURL=webpack:///./assets/js/handlers.js?");
    2020
    2121/***/ }),
     
    2727/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
    2828
    29 eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"base64SizeInBytes\": () => (/* binding */ base64SizeInBytes),\n/* harmony export */   \"base64ToBlob\": () => (/* binding */ base64ToBlob),\n/* harmony export */   \"cachedMediaData\": () => (/* binding */ cachedMediaData),\n/* harmony export */   \"disableAllButtons\": () => (/* binding */ disableAllButtons),\n/* harmony export */   \"disableBulkButtons\": () => (/* binding */ disableBulkButtons),\n/* harmony export */   \"elements\": () => (/* binding */ elements),\n/* harmony export */   \"humanFileSize\": () => (/* binding */ humanFileSize),\n/* harmony export */   \"isDocHidden\": () => (/* binding */ isDocHidden),\n/* harmony export */   \"logMessage\": () => (/* binding */ logMessage),\n/* harmony export */   \"maybeCompressAttachment\": () => (/* binding */ maybeCompressAttachment),\n/* harmony export */   \"populatePathInput\": () => (/* binding */ populatePathInput),\n/* harmony export */   \"removeAllButtons\": () => (/* binding */ removeAllButtons),\n/* harmony export */   \"renderDirectories\": () => (/* binding */ renderDirectories),\n/* harmony export */   \"renderTemplate\": () => (/* binding */ renderTemplate),\n/* harmony export */   \"restoreBulkButtons\": () => (/* binding */ restoreBulkButtons),\n/* harmony export */   \"updateButtonText\": () => (/* binding */ updateButtonText)\n/* harmony export */ });\n\r\n\r\nconst { __ } = wp.i18n; // Import __() from wp.i18n\r\n\r\n// move static helper functions here\r\nconst elements = {\r\n  bulkBtn: document.querySelector(\"[name='squeeze_bulk']\"),\r\n  bulkAgainBtn: document.querySelector(\"[name='squeeze_bulk_again']\"),\r\n  bulkPathBtn: document.querySelector(\"[name='squeeze_bulk_path_button']\"),\r\n  selectPathBtn: document.querySelector(\"[name='squeeze_select_path_button']\"),\r\n  savePathBtn: document.querySelector(\"[name='squeeze_save_path_button']\"),\r\n  pathDialog: document.getElementById(\"squeeze-path-dialog\"),\r\n  closePathDialogBtn: document.querySelector(\"[name='squeeze_close_path_dialog_button']\"),\r\n  pathInput: document.querySelector(\"[name='squeeze_bulk_path']\"),\r\n  pathList: document.querySelector(\".squeeze-path-list\"),\r\n  postsFilterForm: document.querySelector(\"#posts-filter\"),\r\n  dirContainer: document.getElementById(\"squeeze-bulk-directory-list\"),\r\n  bulkLogInput: document.querySelector(\"#squeeze-log-data\"),\r\n  pauseBulkBtn: document.querySelector(\"[name='squeeze_pause_page_bulk']\")\r\n}\r\n\r\nconst cachedMediaData = {\r\n  isPaused: false,\r\n  page: 1,\r\n  process: '',\r\n  mediaIDs: [],\r\n  lastId: 0,\r\n  totalImages: document.querySelector(\"[name='squeeze_bulk_total_images']\")?.value || 0,\r\n  uncompressedImages: document.querySelector(\"[name='squeeze_bulk_uncompressed_images']\")?.value || 0,\r\n  target: null\r\n}\r\n\r\nconst loadTemplate = async (templatePath, data) => {\r\n  const response = await fetch(templatePath);\r\n  let template = await response.text();\r\n\r\n  // Process sub-templates\r\n  const subTemplateRegex = /\\{\\{\\>\\s*(.*?)\\s*\\}\\}/g;\r\n  let match;\r\n  while ((match = subTemplateRegex.exec(template)) !== null) {\r\n    const subTemplatePath = `${squeezeOptions.templateBase}/${match[1].trim()}.html`;\r\n    const subTemplate = await loadTemplate(subTemplatePath, data);\r\n    template = template.replace(match[0], subTemplate);\r\n  }\r\n\r\n  // Function to safely evaluate conditions (supports boolean variables, expressions, AND/OR)\r\n  const evaluateCondition = (condition, data) => {\r\n    try {\r\n      // Convert standalone boolean variables (e.g., webp_lossless) to data['webp_lossless']\r\n      condition = condition.replace(/\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b/g, (match) =>\r\n        match in data ? `data['${match}']` : match\r\n      );\r\n\r\n      return new Function(\"data\", `with(data) { return ${condition}; }`)(data);\r\n    } catch (e) {\r\n      console.error(\"Error evaluating condition:\", condition, e);\r\n      return false;\r\n    }\r\n  };\r\n\r\n  // Recursive function to process nested if-else conditions\r\n  const processIfStatements = (template) => {\r\n    return template.replace(/\\{\\{#if ([\\s\\S]*?)\\}\\}([\\s\\S]*?)\\{\\{\\/if\\}\\}/g, (match, condition, content) => {\r\n      condition = condition.trim();\r\n      const conditionResult = evaluateCondition(condition, data);\r\n\r\n      // Extract and split the if-else blocks\r\n      const elseMatch = content.match(/\\{\\{#else\\}\\}([\\s\\S]*)/);\r\n      const trueBlock = elseMatch ? content.replace(/\\{\\{#else\\}\\}([\\s\\S]*)/, \"\") : content;\r\n      const falseBlock = elseMatch ? elseMatch[1] : \"\";\r\n\r\n      // Process nested if statements recursively\r\n      return processIfStatements(conditionResult ? trueBlock : falseBlock);\r\n    });\r\n  };\r\n\r\n  // Apply recursive processing of if conditions\r\n  template = processIfStatements(template);\r\n\r\n  // Replace variables\r\n  return template.replace(/\\{\\{(.*?)\\}\\}/g, (match, key) => data[key.trim()] || '');\r\n}\r\n\r\nconst renderTemplate = async (templatePath, data, target = null) => {\r\n  const renderedHTML = await loadTemplate(templatePath, data);\r\n\r\n  // Create a temporary container to parse HTML\r\n  const tempContainer = document.createElement(\"template\");\r\n  tempContainer.innerHTML = renderedHTML.trim();\r\n\r\n  if (!target) {\r\n    return tempContainer.content.firstChild;\r\n  }\r\n\r\n  target.appendChild(tempContainer.content.firstChild);\r\n\r\n  // Return the last element of the rendered template\r\n  return target.lastElementChild;\r\n}\r\n\r\nconst logMessage = async (msg, options = {}) => {\r\n  const { mediaLogWrapper = null, isStart = false, isPause = false } = options;\r\n  let { title = '', iconId = 'check-mark-circle-icon' } = options;\r\n\r\n  if (!elements.bulkLogInput) return;\r\n\r\n  if (isStart || isPause) {\r\n    iconId = isPause ? 'pause-button-icon' : 'image-file-icon';\r\n    title = isPause ? __('Bulk squeezing has been paused!', 'squeeze') : `${__('Media', 'squeeze')} ${title}:`;\r\n    return await renderTemplate(squeezeOptions.templates.logWrapper, { title: title, msg: msg, iconId: iconId, isStart: isStart, isPause: isPause }, elements.bulkLogInput);\r\n  } else {\r\n    if (mediaLogWrapper) {\r\n      const process = mediaLogWrapper.querySelector(\".media-log-process\");\r\n      const step = await renderTemplate(squeezeOptions.templates.logStep, { msg: msg, iconId: iconId }, process);\r\n\r\n      if (msg.includes('squeeze-comparison-table')) {\r\n        const comparisonTable = step.querySelector('.squeeze-comparison-table');\r\n        const toggleBtn = await renderTemplate(squeezeOptions.templates.logDetailsButton, { buttonText: __('Show details', 'squeeze') }, mediaLogWrapper);\r\n\r\n        toggleBtn.addEventListener(\"click\", () => {\r\n          comparisonTable.classList.toggle(\"show\");\r\n          toggleBtn.textContent = comparisonTable.classList.contains(\"show\") ? __('Hide details', 'squeeze') : __('Show details', 'squeeze');\r\n        });\r\n        step.closest(\".media-log-wrapper\").appendChild(comparisonTable);\r\n        step.closest(\".media-log-wrapper\").appendChild(toggleBtn);\r\n      }\r\n    } else {\r\n      elements.bulkLogInput.innerHTML += msg + `<br>`;\r\n    }\r\n  }\r\n}\r\n\r\nconst restoreBulkButtons = () => {\r\n  elements.bulkBtn.disabled = false;\r\n  elements.bulkAgainBtn.disabled = false;\r\n  elements.bulkPathBtn.disabled = false;\r\n  elements.selectPathBtn.disabled = false;\r\n  updateButtonText(elements.bulkBtn, __('Run Bulk Squeeze', 'squeeze'), '#play-button-round-icon');\r\n  updateButtonText(elements.bulkAgainBtn, __('Repeat Bulk Squeeze', 'squeeze'), '#combine-left-right-outline-icon');\r\n  updateButtonText(elements.bulkPathBtn, __('Run Directory Squeeze', 'squeeze'), '#play-button-round-icon');\r\n  elements.bulkBtn.dataset.running = 'false';\r\n  elements.bulkAgainBtn.dataset.running = 'false';\r\n  elements.bulkPathBtn.dataset.running = 'false';\r\n\r\n  cachedMediaData.process = '';\r\n  cachedMediaData.mediaIDs = [];\r\n  cachedMediaData.page = 1;\r\n}\r\n\r\nconst disableBulkButtons = () => {\r\n  elements.bulkBtn.disabled = true;\r\n  elements.bulkAgainBtn.disabled = true;\r\n  elements.bulkPathBtn.disabled = true;\r\n  elements.selectPathBtn.disabled = true;\r\n}\r\n\r\nconst disableAllButtons = (buttons) => {\r\n  if (!buttons) return;\r\n  buttons.forEach((btn) => btn.disabled = true);\r\n}\r\n\r\nconst removeAllButtons = (buttons) => {\r\n  if (!buttons) return;\r\n  buttons.forEach((btn) => btn.remove());\r\n}\r\n\r\nconst updateButtonText = (button, text, svgAnchor = false) => {\r\n  button.childNodes.forEach((node) => {\r\n    if (node.nodeName === '#text' && node.textContent.trim() !== '') {\r\n      node.textContent = text;\r\n    }\r\n    if (svgAnchor && node.nodeName === 'svg') {\r\n      node.querySelector('use').setAttribute('xlink:href', svgAnchor);\r\n    }\r\n  });\r\n}\r\n\r\n// Function to render directories in the dialog\r\nconst renderDirectories = async (dirs, parentDir = null, listeners = {}) => {\r\n  if (!dirs) return;\r\n  if (typeof dirs === 'object') dirs = Object.values(dirs);\r\n  if (!elements.dirContainer.classList.contains(\"loaded\")) elements.dirContainer.innerHTML = \"\";\r\n\r\n  if (dirs.length === 0 && !parentDir) {\r\n    const listItem = await renderTemplate(squeezeOptions.templates.directoryItemEmpty, { emptyText: __('No directories found!', 'squeeze') }, elements.dirContainer);\r\n    return;\r\n  }\r\n\r\n  const selectedFolders = JSON.parse(elements.pathInput.value);\r\n  let target;\r\n\r\n  for (const dir of dirs) {\r\n    const listItemClasses = [];\r\n\r\n    if (dir.parent === '/') {\r\n      listItemClasses.push(\"loaded\", \"opened\");\r\n    }\r\n\r\n    if (parentDir) {\r\n      target = parentDir;\r\n    } else if (dir.parent) {\r\n      const parentElement = elements.dirContainer.querySelector(`[data-path=\"${dir.parent}\"]`);\r\n      if (parentElement) {\r\n        target = parentElement;\r\n      } else {\r\n        target = elements.dirContainer;\r\n      }\r\n    } else {\r\n      target = elements.dirContainer;\r\n    }\r\n\r\n    const listItem = await renderTemplate(\r\n      squeezeOptions.templates.directoryItem,\r\n      {\r\n        parent: dir.parent,\r\n        path: dir.path,\r\n        label: dir.name,\r\n        classes: listItemClasses.join(\" \"),\r\n        isWritable: dir.is_writeable && !(Array.isArray(selectedFolders) && selectedFolders.includes(dir.path)),\r\n        isChecked: dir.is_writeable && Array.isArray(selectedFolders) && selectedFolders.includes(dir.path),\r\n      },\r\n      target\r\n    )\r\n\r\n    listItem.querySelector(\"label\").addEventListener(\"click\", listeners.handleDirectoryClick);\r\n    listItem.querySelector(\"input[type='checkbox']\")?.addEventListener(\"change\", listeners.handleDirectoryCheck);\r\n  }\r\n\r\n  elements.dirContainer.classList.add(\"loaded\");\r\n}\r\n\r\nconst populatePathInput = async () => {\r\n  const path = elements.pathInput.value;\r\n  if (!path) return;\r\n\r\n  try {\r\n    const selectedFolders = JSON.parse(path);\r\n    const inputs = elements.pathList.querySelectorAll(\".squeeze-path-list__item\");\r\n\r\n    inputs.forEach(input => input.remove());\r\n\r\n    for (const folder of selectedFolders) {\r\n      const input = await renderTemplate(squeezeOptions.templates.pathListItem, { folder: folder }, elements.pathList);\r\n    }\r\n  } catch (error) {\r\n    alert(__('Error parsing path input!', 'squeeze'));\r\n    console.error('Error parsing path input:', error);\r\n  }\r\n}\r\n\r\nconst getHiddenProp = () => {\r\n  var prefixes = ['webkit', 'moz', 'ms', 'o'];\r\n\r\n  // if 'hidden' is natively supported just return it\r\n  if ('hidden' in document) return 'hidden';\r\n\r\n  // otherwise loop over all the known prefixes until we find one\r\n  for (let i = 0; i < prefixes.length; i++) {\r\n    if ((prefixes[i] + 'Hidden') in document)\r\n      return prefixes[i] + 'Hidden';\r\n  }\r\n\r\n  // otherwise it's not supported\r\n  return null;\r\n}\r\n\r\nconst isDocHidden = () => {\r\n  const prop = getHiddenProp();\r\n  if (!prop) return false;\r\n\r\n  return document[prop];\r\n}\r\n\r\n/**\r\n * @see https://stackoverflow.com/a/20732091\r\n */\r\nconst humanFileSize = (size) => {\r\n  let i = size == 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024));\r\n  return +((size / Math.pow(1024, i)).toFixed(2)) * 1 + ' ' + ['B', 'KB', 'MB', 'GB', 'TB'][i];\r\n}\r\n\r\nconst base64SizeInBytes = (base64) => {\r\n  // Remove data URL prefix if present\r\n  const base64String = base64.split(',')[1] || base64;  \r\n\r\n  // Calculate padding characters ('=' at the end of Base64)\r\n  const padding = (base64String.match(/=+$/) || [\"\"])[0].length;\r\n\r\n  // Compute byte size\r\n  return (base64String.length * 3) / 4 - padding;\r\n}\r\n\r\nconst maybeCompressAttachment = (attachmentType, attachmentSubType, compressOptions) => {\r\n  const isAutoCompress = compressOptions.auto_compress;\r\n  const allowedMimeTypes = ['jpeg', 'png', 'webp', 'avif'];\r\n  const isImage = attachmentType === 'image' && allowedMimeTypes.includes(attachmentSubType);\r\n\r\n  return isImage && isAutoCompress;\r\n};\r\n\r\nconst base64ToBlob = (base64, type = 'image/jpeg') => {\r\n  // Remove data URL prefix if present\r\n  const base64String = base64.split(',')[1] || base64;\r\n\r\n  // Decode Base64 string\r\n  const byteCharacters = atob(base64String);\r\n  const byteNumbers = new Array(byteCharacters.length);\r\n  \r\n  for (let i = 0; i < byteCharacters.length; i++) {\r\n    byteNumbers[i] = byteCharacters.charCodeAt(i);\r\n  }\r\n\r\n  const byteArray = new Uint8Array(byteNumbers);\r\n  return new Blob([byteArray], { type: type });\r\n}\n\n//# sourceURL=webpack:///./assets/js/helpers.js?");
     29eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"base64SizeInBytes\": () => (/* binding */ base64SizeInBytes),\n/* harmony export */   \"base64ToBlob\": () => (/* binding */ base64ToBlob),\n/* harmony export */   \"base64ToFile\": () => (/* binding */ base64ToFile),\n/* harmony export */   \"cachedMediaData\": () => (/* binding */ cachedMediaData),\n/* harmony export */   \"disableAllButtons\": () => (/* binding */ disableAllButtons),\n/* harmony export */   \"disableBulkButtons\": () => (/* binding */ disableBulkButtons),\n/* harmony export */   \"elements\": () => (/* binding */ elements),\n/* harmony export */   \"extendAttachment\": () => (/* binding */ extendAttachment),\n/* harmony export */   \"fileToBase64\": () => (/* binding */ fileToBase64),\n/* harmony export */   \"getFileFromUrl\": () => (/* binding */ getFileFromUrl),\n/* harmony export */   \"handleRemovePathButton\": () => (/* binding */ handleRemovePathButton),\n/* harmony export */   \"humanFileSize\": () => (/* binding */ humanFileSize),\n/* harmony export */   \"isDocHidden\": () => (/* binding */ isDocHidden),\n/* harmony export */   \"logMessage\": () => (/* binding */ logMessage),\n/* harmony export */   \"maybeCompressAttachment\": () => (/* binding */ maybeCompressAttachment),\n/* harmony export */   \"objectToFormData\": () => (/* binding */ objectToFormData),\n/* harmony export */   \"populatePathInput\": () => (/* binding */ populatePathInput),\n/* harmony export */   \"removeAllButtons\": () => (/* binding */ removeAllButtons),\n/* harmony export */   \"renderDirectories\": () => (/* binding */ renderDirectories),\n/* harmony export */   \"renderTemplate\": () => (/* binding */ renderTemplate),\n/* harmony export */   \"restoreBulkButtons\": () => (/* binding */ restoreBulkButtons),\n/* harmony export */   \"updateButtonText\": () => (/* binding */ updateButtonText)\n/* harmony export */ });\n\r\n\r\nconst { __ } = wp.i18n; // Import __() from wp.i18n\r\n\r\n// move static helper functions here\r\nconst elements = {\r\n  bulkBtn: document.querySelector(\"[name='squeeze_bulk']\"),\r\n  bulkAgainBtn: document.querySelector(\"[name='squeeze_bulk_again']\"),\r\n  bulkPathBtn: document.querySelector(\"[name='squeeze_bulk_path_button']\"),\r\n  bulkPathRemoveBtns: document.querySelectorAll(\".squeeze-path-list__remove\"),\r\n  selectPathBtn: document.querySelector(\"[name='squeeze_select_path_button']\"),\r\n  savePathBtn: document.querySelector(\"[name='squeeze_save_path_button']\"),\r\n  pathDialog: document.getElementById(\"squeeze-path-dialog\"),\r\n  closePathDialogBtn: document.querySelector(\"[name='squeeze_close_path_dialog_button']\"),\r\n  pathInput: document.querySelector(\"[name='squeeze_bulk_path']\"),\r\n  pathList: document.querySelector(\".squeeze-path-list\"),\r\n  postsFilterForm: document.querySelector(\"#posts-filter\"),\r\n  dirContainer: document.getElementById(\"squeeze-bulk-directory-list\"),\r\n  bulkLogInput: document.querySelector(\"#squeeze-log-data\"),\r\n  pauseBulkBtn: document.querySelector(\"[name='squeeze_pause_page_bulk']\")\r\n}\r\n\r\nconst cachedMediaData = {\r\n  isPaused: false,\r\n  page: 1,\r\n  process: '',\r\n  mediaIDs: [],\r\n  lastId: 0,\r\n  totalImages: document.querySelector(\"[name='squeeze_bulk_total_images']\")?.value || 0,\r\n  uncompressedImages: document.querySelector(\"[name='squeeze_bulk_uncompressed_images']\")?.value || 0,\r\n  target: null\r\n}\r\n\r\nconst loadTemplate = async (templatePath, data) => {\r\n  const response = await fetch(templatePath);\r\n  let template = await response.text();\r\n\r\n  // Process sub-templates\r\n  const subTemplateRegex = /\\{\\{\\>\\s*(.*?)\\s*\\}\\}/g;\r\n  let match;\r\n  while ((match = subTemplateRegex.exec(template)) !== null) {\r\n    const subTemplatePath = `${squeezeOptions.templateBase}/${match[1].trim()}.html`;\r\n    const subTemplate = await loadTemplate(subTemplatePath, data);\r\n    template = template.replace(match[0], subTemplate);\r\n  }\r\n\r\n  // Function to safely evaluate conditions (supports boolean variables, expressions, AND/OR)\r\n  const evaluateCondition = (condition, data) => {\r\n    try {\r\n      // Convert standalone boolean variables (e.g., webp_lossless) to data['webp_lossless']\r\n      condition = condition.replace(/\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b/g, (match) =>\r\n        match in data ? `data['${match}']` : match\r\n      );\r\n\r\n      return new Function(\"data\", `with(data) { return ${condition}; }`)(data);\r\n    } catch (e) {\r\n      console.error(\"Error evaluating condition:\", condition, e);\r\n      return false;\r\n    }\r\n  };\r\n\r\n  // Recursive function to process nested if-else conditions\r\n  const processIfStatements = (template) => {\r\n    return template.replace(/\\{\\{#if ([\\s\\S]*?)\\}\\}([\\s\\S]*?)\\{\\{\\/if\\}\\}/g, (match, condition, content) => {\r\n      condition = condition.trim();\r\n      const conditionResult = evaluateCondition(condition, data);\r\n\r\n      // Extract and split the if-else blocks\r\n      const elseMatch = content.match(/\\{\\{#else\\}\\}([\\s\\S]*)/);\r\n      const trueBlock = elseMatch ? content.replace(/\\{\\{#else\\}\\}([\\s\\S]*)/, \"\") : content;\r\n      const falseBlock = elseMatch ? elseMatch[1] : \"\";\r\n\r\n      // Process nested if statements recursively\r\n      return processIfStatements(conditionResult ? trueBlock : falseBlock);\r\n    });\r\n  };\r\n\r\n  // Apply recursive processing of if conditions\r\n  template = processIfStatements(template);\r\n\r\n  // Replace variables\r\n  return template.replace(/\\{\\{(.*?)\\}\\}/g, (match, key) => data[key.trim()] || '');\r\n}\r\n\r\nconst renderTemplate = async (templatePath, data, target = null) => {\r\n  const renderedHTML = await loadTemplate(templatePath, data);\r\n\r\n  // Create a temporary container to parse HTML\r\n  const tempContainer = document.createElement(\"template\");\r\n  tempContainer.innerHTML = renderedHTML.trim();\r\n\r\n  if (!target) {\r\n    return tempContainer.content.firstChild;\r\n  }\r\n\r\n  target.appendChild(tempContainer.content.firstChild);\r\n\r\n  // Return the last element of the rendered template\r\n  return target.lastElementChild;\r\n}\r\n\r\nconst logMessage = async (msg, options = {}) => {\r\n  const { mediaLogWrapper = null, isStart = false, isPause = false } = options;\r\n  let { title = '', iconId = 'check-mark-circle-icon' } = options;\r\n\r\n  if (!elements.bulkLogInput) return;\r\n\r\n  if (isStart || isPause) {\r\n    iconId = isPause ? 'pause-button-icon' : 'image-file-icon';\r\n    title = isPause ? __('Bulk squeezing has been paused!', 'squeeze') : `${__('Media', 'squeeze')} ${title}:`;\r\n    return await renderTemplate(squeezeOptions.templates.logWrapper, { title: title, msg: msg, iconId: iconId, isStart: isStart, isPause: isPause }, elements.bulkLogInput);\r\n  } else {\r\n    if (mediaLogWrapper) {\r\n      const process = mediaLogWrapper.querySelector(\".media-log-process\");\r\n      const step = await renderTemplate(squeezeOptions.templates.logStep, { msg: msg, iconId: iconId }, process);\r\n\r\n      if (msg && msg.includes('squeeze-comparison-table')) {\r\n        const comparisonTable = step.querySelector('.squeeze-comparison-table');\r\n        const toggleBtn = await renderTemplate(squeezeOptions.templates.logDetailsButton, { buttonText: __('Show details', 'squeeze') }, mediaLogWrapper);\r\n\r\n        toggleBtn.addEventListener(\"click\", () => {\r\n          comparisonTable.classList.toggle(\"show\");\r\n          toggleBtn.textContent = comparisonTable.classList.contains(\"show\") ? __('Hide details', 'squeeze') : __('Show details', 'squeeze');\r\n        });\r\n        step.closest(\".media-log-wrapper\").appendChild(comparisonTable);\r\n        step.closest(\".media-log-wrapper\").appendChild(toggleBtn);\r\n      }\r\n    } else {\r\n      elements.bulkLogInput.innerHTML += msg + `<br>`;\r\n    }\r\n  }\r\n}\r\n\r\nconst restoreBulkButtons = () => {\r\n  elements.bulkBtn.disabled = false;\r\n  elements.bulkAgainBtn.disabled = false;\r\n  elements.bulkPathBtn.disabled = false;\r\n  elements.selectPathBtn.disabled = false;\r\n  updateButtonText(elements.bulkBtn, __('Run Bulk Squeeze', 'squeeze'), '#play-button-round-icon');\r\n  updateButtonText(elements.bulkAgainBtn, __('Repeat Bulk Squeeze', 'squeeze'), '#combine-left-right-outline-icon');\r\n  updateButtonText(elements.bulkPathBtn, __('Run Directory Squeeze', 'squeeze'), '#play-button-round-icon');\r\n  elements.bulkBtn.dataset.running = 'false';\r\n  elements.bulkAgainBtn.dataset.running = 'false';\r\n  elements.bulkPathBtn.dataset.running = 'false';\r\n  elements.bulkPathRemoveBtns?.forEach((btn) => {\r\n    btn.disabled = false;\r\n  });\r\n\r\n  cachedMediaData.process = '';\r\n  cachedMediaData.mediaIDs = [];\r\n  cachedMediaData.page = 1;\r\n}\r\n\r\nconst disableBulkButtons = () => {\r\n  elements.bulkBtn.disabled = true;\r\n  elements.bulkAgainBtn.disabled = true;\r\n  elements.bulkPathBtn.disabled = true;\r\n  elements.selectPathBtn.disabled = true;\r\n  elements.bulkPathRemoveBtns?.forEach((btn) => btn.disabled = true);\r\n}\r\n\r\nconst disableAllButtons = (buttons) => {\r\n  if (!buttons) return;\r\n  buttons.forEach((btn) => btn.disabled = true);\r\n}\r\n\r\nconst removeAllButtons = (buttons) => {\r\n  if (!buttons) return;\r\n  buttons.forEach((btn) => btn.remove());\r\n}\r\n\r\nconst updateButtonText = (button, text, svgAnchor = false) => {\r\n  button.childNodes.forEach((node) => {\r\n    if (node.nodeName === '#text' && node.textContent.trim() !== '') {\r\n      node.textContent = text;\r\n    }\r\n    if (svgAnchor && node.nodeName === 'svg') {\r\n      node.querySelector('use').setAttribute('xlink:href', svgAnchor);\r\n    }\r\n  });\r\n}\r\n\r\n// Function to render directories in the dialog\r\nconst renderDirectories = async (dirs, parentDir = null, listeners = {}) => {\r\n  if (!dirs) return;\r\n  if (typeof dirs === 'object') dirs = Object.values(dirs);\r\n  if (!elements.dirContainer.classList.contains(\"loaded\")) elements.dirContainer.innerHTML = \"\";\r\n\r\n  if (dirs.length === 0 && !parentDir) {\r\n    const listItem = await renderTemplate(squeezeOptions.templates.directoryItemEmpty, { emptyText: __('No directories found!', 'squeeze') }, elements.dirContainer);\r\n    return;\r\n  }\r\n\r\n  const selectedFolders = JSON.parse(elements.pathInput.value);\r\n  let target;\r\n\r\n  for (const dir of dirs) {\r\n    const listItemClasses = [];\r\n\r\n    if (dir.parent === '/') {\r\n      listItemClasses.push(\"loaded\", \"opened\");\r\n    }\r\n\r\n    if (parentDir) {\r\n      target = parentDir;\r\n    } else if (dir.parent) {\r\n      const parentElement = elements.dirContainer.querySelector(`[data-path=\"${dir.parent}\"]`);\r\n      if (parentElement) {\r\n        target = parentElement;\r\n      } else {\r\n        target = elements.dirContainer;\r\n      }\r\n    } else {\r\n      target = elements.dirContainer;\r\n    }\r\n\r\n    const listItem = await renderTemplate(\r\n      squeezeOptions.templates.directoryItem,\r\n      {\r\n        parent: dir.parent,\r\n        path: dir.path,\r\n        label: dir.name,\r\n        classes: listItemClasses.join(\" \"),\r\n        isWritable: dir.is_writeable && !(Array.isArray(selectedFolders) && selectedFolders.includes(dir.path)),\r\n        isChecked: dir.is_writeable && Array.isArray(selectedFolders) && selectedFolders.includes(dir.path),\r\n      },\r\n      target\r\n    )\r\n\r\n    listItem.querySelector(\"label\").addEventListener(\"click\", listeners.handleDirectoryClick);\r\n    listItem.querySelector(\"input[type='checkbox']\")?.addEventListener(\"change\", listeners.handleDirectoryCheck);\r\n  }\r\n\r\n  elements.dirContainer.classList.add(\"loaded\");\r\n}\r\n\r\nconst handleRemovePathButton = (e) => {\r\n  e.preventDefault();\r\n  const item = e.target.closest(\".squeeze-path-list__item\");\r\n  if (item) {\r\n    item.remove();\r\n    const currentPaths = Array.from(elements.pathList.querySelectorAll(\".squeeze-path-list__input\"))\r\n      .map(input => input.value.trim())\r\n      .filter(value => value !== '');\r\n    elements.pathInput.value = JSON.stringify(currentPaths);\r\n  }\r\n}\r\n\r\nconst populatePathInput = async () => {\r\n  const path = elements.pathInput.value;\r\n  if (!path) return;\r\n\r\n  try {\r\n    const selectedFolders = JSON.parse(path);\r\n    const items = elements.pathList.querySelectorAll(\".squeeze-path-list__item\");\r\n\r\n    items.forEach(item => item.remove());\r\n\r\n    for (const folder of selectedFolders) {\r\n      const item = await renderTemplate(squeezeOptions.templates.pathListItem, { folder: folder }, elements.pathList);\r\n      const removeButton = item.querySelector(\".squeeze-path-list__remove\");\r\n      removeButton.addEventListener(\"click\", handleRemovePathButton);\r\n\r\n    }\r\n  } catch (error) {\r\n    alert(__('Error parsing path input!', 'squeeze'));\r\n    console.error('Error parsing path input:', error);\r\n  }\r\n}\r\n\r\nconst getHiddenProp = () => {\r\n  var prefixes = ['webkit', 'moz', 'ms', 'o'];\r\n\r\n  // if 'hidden' is natively supported just return it\r\n  if ('hidden' in document) return 'hidden';\r\n\r\n  // otherwise loop over all the known prefixes until we find one\r\n  for (let i = 0; i < prefixes.length; i++) {\r\n    if ((prefixes[i] + 'Hidden') in document)\r\n      return prefixes[i] + 'Hidden';\r\n  }\r\n\r\n  // otherwise it's not supported\r\n  return null;\r\n}\r\n\r\nconst isDocHidden = () => {\r\n  const prop = getHiddenProp();\r\n  if (!prop) return false;\r\n\r\n  return document[prop];\r\n}\r\n\r\n/**\r\n * @see https://stackoverflow.com/a/20732091\r\n */\r\nconst humanFileSize = (size) => {\r\n  let i = size == 0 ? 0 : Math.floor(Math.log(size) / Math.log(1024));\r\n  return +((size / Math.pow(1024, i)).toFixed(2)) * 1 + ' ' + ['B', 'KB', 'MB', 'GB', 'TB'][i];\r\n}\r\n\r\nconst base64SizeInBytes = (base64) => {\r\n  // Remove data URL prefix if present\r\n  const base64String = base64.split(',')[1] || base64;  \r\n\r\n  // Calculate padding characters ('=' at the end of Base64)\r\n  const padding = (base64String.match(/=+$/) || [\"\"])[0].length;\r\n\r\n  // Compute byte size\r\n  return (base64String.length * 3) / 4 - padding;\r\n}\r\n\r\nconst maybeCompressAttachment = (attachmentType, attachmentSubType, compressOptions = null) => {\r\n  const isAutoCompress = compressOptions?.auto_compress ?? true;\r\n  const allowedMimeTypes = ['jpeg', 'png', 'webp', 'avif'];\r\n  const isImage = attachmentType === 'image' && allowedMimeTypes.includes(attachmentSubType);\r\n\r\n  return isImage && isAutoCompress;\r\n};\r\n\r\nconst base64ToBlob = (base64, type = 'image/jpeg') => {\r\n  // Remove data URL prefix if present\r\n  const base64String = base64.split(',')[1] || base64;\r\n\r\n  // Decode Base64 string\r\n  const byteCharacters = atob(base64String);\r\n  const byteNumbers = new Array(byteCharacters.length);\r\n  \r\n  for (let i = 0; i < byteCharacters.length; i++) {\r\n    byteNumbers[i] = byteCharacters.charCodeAt(i);\r\n  }\r\n\r\n  const byteArray = new Uint8Array(byteNumbers);\r\n  return new Blob([byteArray], { type: type });\r\n}\r\n\r\nconst base64ToFile = (base64, fileName = 'image.jpg', type = 'image/jpeg') => {\r\n  const blob = base64ToBlob(base64, type);\r\n  return new File([blob], fileName, { type: type });\r\n}\r\n\r\nconst fileToBase64 = (file) => {\r\n  return new Promise((resolve, reject) => {\r\n    const reader = new FileReader();\r\n    reader.onload = () => resolve(reader.result);\r\n    reader.onerror = (error) => reject(error);\r\n    reader.readAsDataURL(file);\r\n  });\r\n}\r\n\r\nfunction objectToFormData(obj, fd = null, parentKey = null) {\r\n  const formData = fd || new FormData();\r\n\r\n  for (const key in obj) {\r\n    if (!obj.hasOwnProperty(key)) continue;\r\n    const value = obj[key];\r\n\r\n    // build the form key: either \"foo\", \"parent[foo]\" or \"parent[]\" for arrays\r\n    const formKey = parentKey\r\n      ? Array.isArray(obj)\r\n        ? `${parentKey}[]`\r\n        : `${parentKey}[${key}]`\r\n      : key;\r\n\r\n    // Files or Blobs go straight in\r\n    if (value instanceof File || value instanceof Blob) {\r\n      formData.append(formKey, value, value.name);\r\n    }\r\n    // Arrays: recurse so they become key[]=val0, key[]=val1…\r\n    else if (Array.isArray(value)) {\r\n      objectToFormData(value, formData, formKey);\r\n    }\r\n    // Plain objects: recurse so they become key[subkey]=subval\r\n    else if (\r\n      value !== null &&\r\n      typeof value === 'object' &&\r\n      !(value instanceof Date)\r\n    ) {\r\n      objectToFormData(value, formData, formKey);\r\n    }\r\n    // Dates: convert to ISO string (or format as you like)\r\n    else if (value instanceof Date) {\r\n      formData.append(formKey, value.toISOString());\r\n    }\r\n    // Everything else (number, string, boolean, null, undefined)\r\n    else {\r\n      // Explicitly convert undefined to empty string so PHP sees it\r\n      const stringVal =\r\n        value === undefined || value === null ? '' : String(value);\r\n      formData.append(formKey, stringVal);\r\n    }\r\n  }\r\n\r\n  return formData;\r\n}\r\n\r\n/**\r\n * Extend the attachment object with additional data from the file.\r\n * @param {object} attachment \r\n * @param {object} file \r\n * @returns {object} — the extended attachment object.\r\n */\r\nconst extendAttachment = async (attachment, file) => {\r\n  if (typeof attachment !== 'object' || !attachment.attributes) {\r\n    console.warn('Invalid attachment object:', attachment);\r\n    return;\r\n  }\r\n\r\n  const attributes = attachment.attributes;\r\n\r\n  if (file?.base64) {\r\n    attributes.base64Compressed = file.base64; // Use the base64 data from the attachment\r\n  }\r\n\r\n  if (file?.base64Webp) {\r\n    attributes.base64WebpCompressed = file.base64Webp; // Use the WebP base64 data from the attachment\r\n  }\r\n\r\n  if (file?.originalFile) {\r\n    attributes.originalFile = file.originalFile; // Use the original file from the attachment to be able to create a backup\r\n  }\r\n\r\n  return attachment;\r\n}\r\n\r\nconst getFileFromUrl = async (url, filename, format) => {\r\n  const response = await fetch(url);\r\n  const blob = await response.blob();\r\n  const mimeType = format ? `image/${format}` : blob.type;\r\n  return new File([blob], filename, { type: mimeType });\r\n}\n\n//# sourceURL=webpack:///./assets/js/helpers.js?");
    3030
    3131/***/ }),
     
    3737/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
    3838
    39 eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _squeeze_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./squeeze.js */ \"./assets/js/squeeze.js\");\n/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./helpers.js */ \"./assets/js/helpers.js\");\n/* harmony import */ var _handlers_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./handlers.js */ \"./assets/js/handlers.js\");\n\r\n\r\n\r\n\r\n\r\n\"use strict\";\r\n\r\nconst { sprintf, __ } = wp.i18n; // Import __() from wp.i18n\r\n\r\nconst Squeeze = new _squeeze_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"](squeezeOptions);\r\nconst compressOptions = JSON.parse(squeezeOptions.options);\r\n\r\ndocument.addEventListener(\"click\", (event) => {\r\n  _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleButtonsClick(event, Squeeze); // manually pass Squeeze, because of the dynamic options update in the Preview Mode\r\n});\r\n\r\n_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.bulkBtn?.addEventListener(\"click\", async (event) => {\r\n  let uncompressedIDs = squeezeBulk.unCompressedImages ? squeezeBulk.unCompressedImages.split(\",\") : [];\r\n  let currentPage = _helpers_js__WEBPACK_IMPORTED_MODULE_1__.cachedMediaData.page ?? 1;\r\n\r\n  _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleBulkButtonClick(event, 'uncompressed', uncompressedIDs, currentPage);\r\n});\r\n\r\n_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.bulkAgainBtn?.addEventListener(\"click\", async (event) => {\r\n  let allIDs = squeezeBulk.allImages ? squeezeBulk.allImages.split(\",\") : [];\r\n  let currentPage = _helpers_js__WEBPACK_IMPORTED_MODULE_1__.cachedMediaData.page ?? 1;\r\n\r\n  _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleBulkButtonClick(event, 'all', allIDs, currentPage);\r\n});\r\n\r\n_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.bulkPathBtn?.addEventListener(\"click\", async (event) => {\r\n  const path = _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.pathInput?.value ?? '';\r\n  let bulkPathData;\r\n\r\n  if (!path) {\r\n    alert(__('Please enter a valid path!', 'squeeze'));\r\n    return;\r\n  }\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_1__.disableBulkButtons();\r\n  window.onbeforeunload = _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleOnLeave;\r\n\r\n  if (_helpers_js__WEBPACK_IMPORTED_MODULE_1__.cachedMediaData.process === 'path' && _helpers_js__WEBPACK_IMPORTED_MODULE_1__.cachedMediaData.mediaIDs.length > 0) {\r\n    bulkPathData = _helpers_js__WEBPACK_IMPORTED_MODULE_1__.cachedMediaData.mediaIDs;\r\n  } else {\r\n    const pathData = await Squeeze.getAttachmentsByPath(path);\r\n\r\n    if (pathData.success) {\r\n      bulkPathData = pathData.data;\r\n    } else {\r\n      console.error(pathData.data);\r\n      _helpers_js__WEBPACK_IMPORTED_MODULE_1__.restoreBulkButtons();\r\n      window.onbeforeunload = null;\r\n    }\r\n  }\r\n\r\n  const isPaused = _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleBulkToggle(event, 'path', bulkPathData);\r\n\r\n  if (isPaused) {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_1__.updateButtonText(event.target, __('Pausing...', 'squeeze'), '#pause-button-icon');\r\n    return;\r\n  } else {\r\n    event.target.disabled = false;\r\n  }\r\n\r\n  try {\r\n    const finalResponse = await _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleRecursiveUpload('path', bulkPathData, 1);\r\n\r\n    if (finalResponse?.mediaIDs) {\r\n      if (finalResponse.mediaIDs.length === 0) {\r\n        alert(__('All images have been processed!', 'squeeze'));\r\n        window.onbeforeunload = null;\r\n        _helpers_js__WEBPACK_IMPORTED_MODULE_1__.restoreBulkButtons();\r\n      }\r\n    }\r\n  } catch (error) {\r\n    console.error(error);\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_1__.restoreBulkButtons();\r\n    window.onbeforeunload = null;\r\n    alert(__('An error has occured. Check the console for details.', 'squeeze'));\r\n  }\r\n})\r\n\r\n_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.selectPathBtn?.addEventListener(\"click\", async (event) => {\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.pathDialog.showModal();\r\n\r\n  if (_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.dirContainer.classList.contains(\"loading\")) return;\r\n\r\n  if (_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.dirContainer.classList.contains(\"loaded\")) {\r\n    const selectedFolders = JSON.parse(_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.pathInput.value);\r\n\r\n    if (Array.isArray(selectedFolders)) {\r\n      selectedFolders.forEach((folder) => {\r\n        const checkbox = _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.dirContainer.querySelector(`input[value=\"${folder}\"]`);\r\n        if (checkbox) {\r\n          checkbox.checked = true;\r\n        }\r\n      });\r\n    }\r\n\r\n    return;\r\n\r\n  } else {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.dirContainer.classList.add(\"loading\");\r\n    const folders = await Squeeze.getDirectories();\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_1__.renderDirectories(folders, null, {\r\n      handleDirectoryClick: _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleDirectoryClick,\r\n      handleDirectoryCheck: _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleDirectoryCheck\r\n    });\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.dirContainer.classList.remove(\"loading\");\r\n  }\r\n\r\n\r\n});\r\n\r\n_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.savePathBtn?.addEventListener(\"click\", () => {\r\n  const checkboxes = _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.dirContainer.querySelectorAll(\"input[type='checkbox']\");\r\n  const selectedFolders = Array.from(checkboxes)\r\n    .filter(checkbox => checkbox.checked)\r\n    .map(checkbox => checkbox.value);\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.pathInput.value = JSON.stringify(selectedFolders);\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_1__.populatePathInput();\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.pathDialog.close();\r\n});\r\n\r\n_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.closePathDialogBtn?.addEventListener(\"click\", () => {\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.pathDialog.close();\r\n});\r\n\r\ndocument.addEventListener('click', _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleClosePathDialog);\r\n\r\n_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.postsFilterForm?.addEventListener(\"submit\", async (event) => {\r\n  const dataAction = _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.postsFilterForm.dataset.action;\r\n  const action = event.target.querySelector(\"select[name='action']\").value;\r\n  const submitButtons = event.target.querySelectorAll(\"input[name='bulk_action']\");\r\n\r\n  if (action === 'squeeze_bulk_compress' && dataAction !== 'squeeze_bulk_compressed') {\r\n    event.preventDefault();\r\n    const mediaList = document.querySelectorAll(\"input[name='media[]']:checked\");\r\n    const uncompressedIDs = Array.from(mediaList).map((el) => el.value);\r\n\r\n    if (uncompressedIDs.length === 0) return;\r\n\r\n    window.onbeforeunload = _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleOnLeave;\r\n\r\n    uncompressedIDs.forEach((id) => {\r\n      _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.postsFilterForm.querySelectorAll(`#post-${id} .column-squeeze button`).forEach((btn) => {\r\n        btn.disabled = true;\r\n      });\r\n      const squeezeStatusElement = _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.postsFilterForm.querySelector(`#post-${id} .column-squeeze .squeeze_status`);\r\n      if (squeezeStatusElement) {\r\n        squeezeStatusElement.innerText = '⏳ ' + __('Squeezing...', 'squeeze');\r\n      }\r\n    });\r\n\r\n    submitButtons.forEach((btn) => {\r\n      btn.disabled = true;\r\n      btn.value = __('Squeezing...', 'squeeze');\r\n    });\r\n\r\n    try {\r\n      const finalResponse = await _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleRecursiveUpload('uncompressed', uncompressedIDs, 1);\r\n\r\n      if (finalResponse?.mediaIDs) {\r\n        if (finalResponse.mediaIDs.length === 0) {\r\n          window.onbeforeunload = null;\r\n          _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.postsFilterForm.dataset.action = 'squeeze_bulk_compressed';\r\n          _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.postsFilterForm.submit();\r\n        }\r\n      }\r\n    } catch (error) {\r\n      console.error(error);\r\n      window.onbeforeunload = null;\r\n      alert(__('An error has occured. Check the console for details.', 'squeeze'));\r\n    }\r\n  }\r\n});\r\n\r\n// https://wordpress.stackexchange.com/a/131295/186146 - override wp.Uploader.prototype.success\r\njQuery.extend(wp?.Uploader?.prototype, {\r\n  success: async (attachment) => {\r\n    if (_helpers_js__WEBPACK_IMPORTED_MODULE_1__.maybeCompressAttachment(attachment.attributes.type, attachment.attributes.subtype, compressOptions)) {\r\n\r\n      // set 'uploading' param to true, to pause the uploading process\r\n      window.onbeforeunload = _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleOnLeave;\r\n      attachment.set('uploading', true);\r\n      attachment.set('percent', 0);\r\n      attachment.set('status', 'Squeezing'); // Set status to 'Squeezing' to indicate compression is in progress\r\n\r\n      try {\r\n        const compressData = await Squeeze.handleCompress(attachment);\r\n        attachment.set('percent', 75); // Set percent to 75% to indicate compression is done\r\n        const uploadData = await Squeeze.handleUpload({ attachment, base64: compressData });\r\n\r\n        if (uploadData.success) {\r\n          const compat = attachment.get('compat');\r\n          const tempDiv = document.createElement('div');\r\n          let compatItem = compat.item;\r\n\r\n          tempDiv.innerHTML = compatItem;\r\n          tempDiv.querySelector('.compat-field-squeeze_is_compressed .field').innerHTML = uploadData.data;\r\n          compat.item = tempDiv.innerHTML;\r\n\r\n          attachment.set('compat', compat);\r\n          attachment.set('uploading', false);\r\n          window.onbeforeunload = null;\r\n        } else {\r\n          attachment.set('uploading', false);\r\n          window.onbeforeunload = null;\r\n          alert(uploadData.data);\r\n        }\r\n      } catch (error) {\r\n        console.error(error);\r\n        attachment.set('uploading', false);\r\n        window.onbeforeunload = null;\r\n      }\r\n    }\r\n  },\r\n});\r\n\r\ndocument.onreadystatechange = function () {\r\n  if (document.readyState === \"complete\") { // equivalent to jQuery $(document).ready()\r\n    _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleMultiFileFormUpload(compressOptions);\r\n  }\r\n}\r\n\r\n/**\r\n * Create the toggle preview checkbox\r\n * @param {Integer} attachmentId \r\n * @param {Boolean} isPlaceholder\r\n * @returns HTMLElement\r\n */\r\nconst createTogglePreview = (attachmentId, isPlaceholder = false) => {\r\n\r\n  // Create the toggle\r\n  const toggleWrap = document.createElement('span');\r\n  const toggleInput = document.createElement('input');\r\n  const toggleLabel = document.createElement('label');\r\n\r\n  toggleInput.type = 'checkbox';\r\n  toggleInput.className = 'squeeze-ios8-switch';\r\n  toggleInput.id = 'squeeze-ios8-switch-' + attachmentId;\r\n  toggleLabel.textContent = __('Squeeze Preview', 'squeeze');\r\n  toggleLabel.htmlFor = toggleInput.id;\r\n  toggleWrap.style.marginInlineStart = '1em';\r\n\r\n  if (isPlaceholder) {\r\n    toggleInput.disabled = true;\r\n    toggleLabel.innerHTML += ' ' + sprintf(__('(<a href=\"%s\" target=\"_blank\">premium only</a>)','squeeze'), squeezeOptions.upgradeUrl);\r\n  }\r\n\r\n  toggleWrap.appendChild(toggleInput);\r\n  toggleWrap.appendChild(toggleLabel);\r\n\r\n  return toggleWrap;\r\n}\r\n\r\n\n\n//# sourceURL=webpack:///./assets/js/script.js?");
     39eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _squeeze_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./squeeze.js */ \"./assets/js/squeeze.js\");\n/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./helpers.js */ \"./assets/js/helpers.js\");\n/* harmony import */ var _handlers_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./handlers.js */ \"./assets/js/handlers.js\");\n\r\n\r\n\r\n\r\n\r\n\"use strict\";\r\n\r\nconst { sprintf, __ } = wp.i18n; // Import __() from wp.i18n\r\n\r\nconst Squeeze = new _squeeze_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"](squeezeOptions);\r\nconst compressOptions = JSON.parse(squeezeOptions.options);\r\nconst originalUploaderInit = wp?.Uploader?.prototype?.init;\r\n\r\ndocument.addEventListener(\"click\", (event) => {\r\n  _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleButtonsClick(event, Squeeze); // manually pass Squeeze, because of the dynamic options update in the Preview Mode\r\n});\r\n\r\n_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.bulkBtn?.addEventListener(\"click\", async (event) => {\r\n  let uncompressedIDs = squeezeBulk.unCompressedImages ? squeezeBulk.unCompressedImages.split(\",\") : [];\r\n  let currentPage = _helpers_js__WEBPACK_IMPORTED_MODULE_1__.cachedMediaData.page ?? 1;\r\n\r\n  _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleBulkButtonClick(event, 'uncompressed', uncompressedIDs, currentPage);\r\n});\r\n\r\n_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.bulkAgainBtn?.addEventListener(\"click\", async (event) => {\r\n  let allIDs = squeezeBulk.allImages ? squeezeBulk.allImages.split(\",\") : [];\r\n  let currentPage = _helpers_js__WEBPACK_IMPORTED_MODULE_1__.cachedMediaData.page ?? 1;\r\n\r\n  _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleBulkButtonClick(event, 'all', allIDs, currentPage);\r\n});\r\n\r\n_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.bulkPathBtn?.addEventListener(\"click\", async (event) => {\r\n  const path = _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.pathInput?.value ?? '';\r\n  let bulkPathData;\r\n\r\n  if (path.replace(/\\[\\]/g, '').split(',').length === 0 || !path.replace(/\\[\\]/g, '').split(',')[0] || !path) {\r\n    alert(__('Please enter a valid path!', 'squeeze'));\r\n    return;\r\n  }\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_1__.disableBulkButtons();\r\n  window.onbeforeunload = _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleOnLeave;\r\n\r\n  if (_helpers_js__WEBPACK_IMPORTED_MODULE_1__.cachedMediaData.process === 'path' && _helpers_js__WEBPACK_IMPORTED_MODULE_1__.cachedMediaData.mediaIDs.length > 0) {\r\n    bulkPathData = _helpers_js__WEBPACK_IMPORTED_MODULE_1__.cachedMediaData.mediaIDs;\r\n  } else {\r\n    const pathData = await Squeeze.getAttachmentsByPath(path);\r\n\r\n    if (pathData.success) {\r\n      bulkPathData = pathData.data;\r\n    } else {\r\n      console.error(pathData.data);\r\n      _helpers_js__WEBPACK_IMPORTED_MODULE_1__.restoreBulkButtons();\r\n      window.onbeforeunload = null;\r\n    }\r\n  }\r\n\r\n  const isPaused = _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleBulkToggle(event, 'path', bulkPathData);\r\n\r\n  if (isPaused) {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_1__.updateButtonText(event.target, __('Pausing...', 'squeeze'), '#pause-button-icon');\r\n    return;\r\n  } else {\r\n    event.target.disabled = false;\r\n  }\r\n\r\n  try {\r\n    const finalResponse = await _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleRecursiveUpload('path', bulkPathData, 1);\r\n\r\n    if (finalResponse?.mediaIDs) {\r\n      if (finalResponse.mediaIDs.length === 0) {\r\n        alert(__('All images have been processed!', 'squeeze'));\r\n        window.onbeforeunload = null;\r\n        _helpers_js__WEBPACK_IMPORTED_MODULE_1__.restoreBulkButtons();\r\n      }\r\n    }\r\n  } catch (error) {\r\n    console.error(error);\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_1__.restoreBulkButtons();\r\n    window.onbeforeunload = null;\r\n    alert(__('An error has occured. Check the console for details.', 'squeeze'));\r\n  }\r\n})\r\n\r\n_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.bulkPathRemoveBtns?.forEach((btn) => {\r\n  btn.addEventListener(\"click\", _helpers_js__WEBPACK_IMPORTED_MODULE_1__.handleRemovePathButton);\r\n});\r\n\r\n_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.selectPathBtn?.addEventListener(\"click\", async (event) => {\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.pathDialog.showModal();\r\n\r\n  if (_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.dirContainer.classList.contains(\"loading\")) return;\r\n\r\n  if (_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.dirContainer.classList.contains(\"loaded\")) {\r\n    const selectedFolders = JSON.parse(_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.pathInput.value);\r\n\r\n    if (Array.isArray(selectedFolders)) {\r\n      selectedFolders.forEach((folder) => {\r\n        const checkbox = _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.dirContainer.querySelector(`input[value=\"${folder}\"]`);\r\n        if (checkbox) {\r\n          checkbox.checked = true;\r\n        }\r\n      });\r\n    }\r\n\r\n    return;\r\n\r\n  } else {\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.dirContainer.classList.add(\"loading\");\r\n    const folders = await Squeeze.getDirectories();\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_1__.renderDirectories(folders, null, {\r\n      handleDirectoryClick: _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleDirectoryClick,\r\n      handleDirectoryCheck: _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleDirectoryCheck\r\n    });\r\n    _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.dirContainer.classList.remove(\"loading\");\r\n  }\r\n\r\n\r\n});\r\n\r\n_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.savePathBtn?.addEventListener(\"click\", () => {\r\n  const checkboxes = _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.dirContainer.querySelectorAll(\"input[type='checkbox']\");\r\n  const selectedFolders = Array.from(checkboxes)\r\n    .filter(checkbox => checkbox.checked)\r\n    .map(checkbox => checkbox.value);\r\n\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.pathInput.value = JSON.stringify(selectedFolders);\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_1__.populatePathInput();\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.pathDialog.close();\r\n});\r\n\r\n_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.closePathDialogBtn?.addEventListener(\"click\", () => {\r\n  _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.pathDialog.close();\r\n});\r\n\r\ndocument.addEventListener('click', _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleClosePathDialog);\r\n\r\n_helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.postsFilterForm?.addEventListener(\"submit\", async (event) => {\r\n  const dataAction = _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.postsFilterForm.dataset.action;\r\n  const action = event.target.querySelector(\"select[name='action']\").value;\r\n  const submitButtons = event.target.querySelectorAll(\"input[name='bulk_action']\");\r\n\r\n  if (action === 'squeeze_bulk_compress' && dataAction !== 'squeeze_bulk_compressed') {\r\n    event.preventDefault();\r\n    const mediaList = document.querySelectorAll(\"input[name='media[]']:checked\");\r\n    const uncompressedIDs = Array.from(mediaList).map((el) => el.value);\r\n\r\n    if (uncompressedIDs.length === 0) return;\r\n\r\n    window.onbeforeunload = _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleOnLeave;\r\n\r\n    uncompressedIDs.forEach((id) => {\r\n      _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.postsFilterForm.querySelectorAll(`#post-${id} .column-squeeze button`).forEach((btn) => {\r\n        btn.disabled = true;\r\n      });\r\n      const squeezeStatusElement = _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.postsFilterForm.querySelector(`#post-${id} .column-squeeze .squeeze_status`);\r\n      if (squeezeStatusElement) {\r\n        squeezeStatusElement.innerText = '⏳ ' + __('Squeezing...', 'squeeze');\r\n      }\r\n    });\r\n\r\n    submitButtons.forEach((btn) => {\r\n      btn.disabled = true;\r\n      btn.value = __('Squeezing...', 'squeeze');\r\n    });\r\n\r\n    try {\r\n      const finalResponse = await _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleRecursiveUpload('uncompressed', uncompressedIDs, 1);\r\n\r\n      if (finalResponse?.mediaIDs) {\r\n        if (finalResponse.mediaIDs.length === 0) {\r\n          window.onbeforeunload = null;\r\n          _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.postsFilterForm.dataset.action = 'squeeze_bulk_compressed';\r\n          _helpers_js__WEBPACK_IMPORTED_MODULE_1__.elements.postsFilterForm.submit();\r\n        }\r\n      }\r\n    } catch (error) {\r\n      console.error(error);\r\n      window.onbeforeunload = null;\r\n      alert(__('An error has occured. Check the console for details.', 'squeeze'));\r\n    }\r\n  }\r\n});\r\n\r\n// https://wordpress.stackexchange.com/a/131295/186146 - override wp.Uploader.prototype.success\r\njQuery.extend(wp?.Uploader?.prototype, {\r\n  init: function () {\r\n    if (!originalUploaderInit) {\r\n      console.error('wp.Uploader.prototype.init is not defined');\r\n      return;\r\n    }\r\n\r\n    originalUploaderInit.apply(this, arguments);\r\n    const uploader = this.uploader;\r\n\r\n    uploader.bind('BeforeUpload', async function (up, pluploadFile) {\r\n      _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleCompressBeforeUpload(up, pluploadFile, compressOptions);\r\n    });\r\n\r\n    uploader.bind('FileUploaded', async function (up, file, response) {\r\n      if (file?._isExcluded) {\r\n        console.warn('File is excluded from compression:', file.name);\r\n        window.onbeforeunload = null;\r\n        return;\r\n      }\r\n      if (file?._isFailed) {\r\n        console.warn('File compression failed:', file.name);\r\n        window.onbeforeunload = null;\r\n        return;\r\n      }\r\n\r\n      const attachment = file?.attachment;\r\n\r\n      if (!_helpers_js__WEBPACK_IMPORTED_MODULE_1__.maybeCompressAttachment(attachment?.attributes?.type, attachment?.attributes?.subtype, compressOptions)) {\r\n        //console.warn('Skipping compression for:', attachment?.attributes?.type, attachment?.attributes?.subtype);\r\n        return; // Skip compression for this attachment\r\n      }\r\n      // set 'uploading' param to true, to pause the uploading process\r\n      window.onbeforeunload = _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleOnLeave;\r\n      attachment.set('uploading', true);\r\n      attachment.set('percent', 50);\r\n      attachment.set('status', 'Squeezing'); // Set status to 'Squeezing' to indicate compression is in progress\r\n\r\n      _helpers_js__WEBPACK_IMPORTED_MODULE_1__.extendAttachment(attachment, file);\r\n\r\n      try {\r\n        const compressData = await Squeeze.handleCompress(attachment);\r\n        attachment.set('percent', 75); // Set percent to 75% to indicate compression is done\r\n        const uploadData = await Squeeze.handleUpload({ attachment, base64: compressData });\r\n\r\n        if (uploadData.success) {\r\n          const compat = attachment.get('compat');\r\n          const tempDiv = document.createElement('div');\r\n          let compatItem = compat.item;\r\n\r\n          tempDiv.innerHTML = compatItem;\r\n          tempDiv.querySelector('.compat-field-squeeze_is_compressed .field').innerHTML = uploadData?.data?.message;\r\n          compat.item = tempDiv.innerHTML;\r\n\r\n          attachment.set('compat', compat);\r\n        } else {\r\n          console.warn(uploadData.data);\r\n        }\r\n      } catch (error) {\r\n        console.error(error);\r\n      } finally {\r\n        attachment.set('uploading', false);\r\n        window.onbeforeunload = null;\r\n      }\r\n\r\n      //console.timeEnd('BeforeUpload')\r\n    })\r\n\r\n  },\r\n});\r\n\r\ndocument.onreadystatechange = function () {\r\n  if (document.readyState === \"complete\") { // equivalent to jQuery $(document).ready()\r\n    _handlers_js__WEBPACK_IMPORTED_MODULE_2__.handleMultiFileFormUpload(compressOptions);\r\n  }\r\n}\r\n\r\n/**\r\n * Create the toggle preview checkbox\r\n * @param {Integer} attachmentId \r\n * @param {Boolean} isPlaceholder\r\n * @returns HTMLElement\r\n */\r\nconst createTogglePreview = (attachmentId, isPlaceholder = false) => {\r\n\r\n  // Create the toggle\r\n  const toggleWrap = document.createElement('span');\r\n  const toggleInput = document.createElement('input');\r\n  const toggleLabel = document.createElement('label');\r\n\r\n  toggleInput.type = 'checkbox';\r\n  toggleInput.className = 'squeeze-ios8-switch';\r\n  toggleInput.id = 'squeeze-ios8-switch-' + attachmentId;\r\n  toggleLabel.textContent = __('Squeeze Preview', 'squeeze');\r\n  toggleLabel.htmlFor = toggleInput.id;\r\n  toggleWrap.style.marginInlineStart = '1em';\r\n\r\n  if (isPlaceholder) {\r\n    toggleInput.disabled = true;\r\n    toggleLabel.innerHTML += ' ' + sprintf(__('(<a href=\"%s\" target=\"_blank\">premium only</a>)', 'squeeze'), squeezeOptions.upgradeUrl);\r\n  }\r\n\r\n  toggleWrap.appendChild(toggleInput);\r\n  toggleWrap.appendChild(toggleLabel);\r\n\r\n  return toggleWrap;\r\n}\r\n\r\n\n\n//# sourceURL=webpack:///./assets/js/script.js?");
    4040
    4141/***/ }),
     
    4747/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
    4848
    49 eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ SQUEEZE)\n/* harmony export */ });\n\r\n\r\nconst { __ } = wp.i18n; // Import __() from wp.i18n\r\n\r\nclass SQUEEZE {\r\n\r\n  constructor(squeeze) {\r\n    this.options = JSON.parse(squeeze.options); // plugin options\r\n    this.nonce = squeeze.nonce; // nonce\r\n    this.ajaxUrl = squeeze.ajaxUrl; // ajax url\r\n    this.timeout = parseInt(this.options.timeout) * 1000; // convert to milliseconds\r\n    this.poolSize = navigator.hardwareConcurrency || 1; // number of threads\r\n  }\r\n\r\n  handleCompress = async ( attachment ) => {\r\n    const attachmentData = attachment.attributes;\r\n    const url = attachmentData?.originalImageURL ?? attachmentData.url;\r\n    const mime = attachmentData.mime;\r\n    const name = attachmentData.name;\r\n    const filename = attachmentData?.originalImageName ?? attachmentData.filename;\r\n    const attachmentID = attachmentData.id;\r\n    const sizes = attachmentData.sizes;\r\n    const format = mime.split(\"/\")[1];\r\n    const sourceType = format;\r\n    const outputType = format;\r\n    const skipFull = attachmentData.originalImageName === undefined ? true : false;\r\n    const timeout = this.timeout;\r\n    const isPreview = attachmentData?.isPreview ?? false;\r\n    const file = attachmentData?.file ?? null;\r\n\r\n    //console.log(attachmentData, 'attachmentData')\r\n\r\n    const worker = new Worker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u(\"assets_js_worker_js\"), __webpack_require__.b), {type: undefined}); // worker url\r\n    worker.postMessage({\r\n      action: 'compress',\r\n      format,\r\n      url,\r\n      name,\r\n      sourceType,\r\n      outputType,\r\n      mime,\r\n      sizes,\r\n      skipFull,\r\n      timeout,\r\n      isPreview,\r\n      file,\r\n      options: this.options,\r\n      //urlOriginal: urlOriginal,\r\n    });\r\n\r\n    return new Promise((resolve, reject) => {\r\n      const timeoutId = setTimeout(() => {\r\n        worker.terminate();\r\n        console.warn('Worker terminated');\r\n        reject(__('Request timed out.', 'squeeze'));\r\n      }, timeout);\r\n\r\n      worker.onmessage = (event) => {\r\n        clearTimeout(timeoutId);\r\n        if (event.data.error) {\r\n          reject(event.data.error);\r\n        } else {\r\n          resolve(event.data);\r\n        }\r\n        worker.terminate();\r\n      };\r\n\r\n      worker.onerror = (error) => {\r\n        clearTimeout(timeoutId);\r\n        reject(`Worker error: ${error.message}`);\r\n      };\r\n    });\r\n\r\n  }\r\n\r\n  handleUpload = async ({ attachment, base64, type = 'uncompressed', mediaIDs = [] }) => {\r\n\r\n    const attachmentData = attachment.attributes;\r\n    const url = attachmentData?.originalImageURL ?? attachmentData.url;\r\n    const mime = attachmentData.mime;\r\n    const filename = attachmentData?.originalImageName ?? attachmentData.filename;\r\n    const attachmentID = attachmentData.id;\r\n    const format = mime.split(\"/\")[1];\r\n    const sizes = attachmentData.sizes;\r\n\r\n    //console.log(attachmentData, 'attachmentData')\r\n\r\n    const data = {\r\n      action: 'squeeze_update_attachment',\r\n      _ajax_nonce: this.nonce,\r\n      filename: filename,\r\n      type: 'image',\r\n      format: format,\r\n      base64: base64.base64,\r\n      base64Sizes: base64.base64Sizes,\r\n      base64Webp: base64.base64Webp,\r\n      base64SizesWebp: base64.base64SizesWebp,\r\n      attachmentID: attachmentID,\r\n      url: url,\r\n      process: type,\r\n    }\r\n\r\n    console.log(data, 'squeeze_update_attachment') \r\n\r\n    try {\r\n      const uploadResponse = await jQuery.ajax({\r\n      url: this.ajaxUrl, // + '111',\r\n      type: 'POST',\r\n      data: data,\r\n      });\r\n\r\n      //if (type === 'uncompressed' || type === 'all' || type === 'path') {\r\n      //if (uploadResponse.success) {\r\n        uploadResponse['mediaIDs'] = mediaIDs;\r\n      //}\r\n\r\n      uploadResponse['filename'] = filename;\r\n      uploadResponse['url'] = url;\r\n      uploadResponse['sizes'] = sizes;\r\n\r\n      return uploadResponse;\r\n      \r\n    } catch (error) {\r\n      return {\r\n      'mediaIDs': mediaIDs,\r\n      'data': error.message,\r\n      'success': false\r\n      };\r\n    }\r\n\r\n  }\r\n\r\n  handleBulkUpload = async (type = 'uncompressed', mediaIDs = []) => {\r\n    let currentID;\r\n    let attachment;\r\n\r\n    switch (type) {\r\n      case 'all':\r\n      case 'uncompressed':\r\n        currentID = mediaIDs[0];\r\n        break;\r\n      case 'path':\r\n        currentID = mediaIDs[0]?.filename;\r\n        break;\r\n      default:\r\n        currentID = 0;\r\n        break;\r\n    }\r\n\r\n    if (type === 'path') {\r\n\r\n      \r\n\r\n      attachment = {\r\n        attributes: {\r\n          url: mediaIDs[0].url,\r\n          mime: mediaIDs[0].mime,\r\n          name: mediaIDs[0].name,\r\n          filename: mediaIDs[0].filename,\r\n          id: mediaIDs[0].id,\r\n          sizes: mediaIDs[0]?.sizes,\r\n        }\r\n      }\r\n\r\n    } else {\r\n\r\n      const attachmentResponse = await this.getAttachment(currentID); \r\n      if (attachmentResponse.success === false) {\r\n        if (Array.isArray(mediaIDs)) mediaIDs.shift();\r\n        return {\r\n          'mediaIDs': mediaIDs,\r\n          'data': attachmentResponse.data\r\n        }\r\n      }\r\n      const attachmentData = attachmentResponse.data;\r\n      attachment = {\r\n        attributes: {\r\n          url: attachmentData.url,\r\n          mime: attachmentData.mime,\r\n          name: attachmentData.name,\r\n          filename: attachmentData.filename,\r\n          id: attachmentData.id,\r\n          sizes: attachmentData.sizes,\r\n        }\r\n      }\r\n\r\n    }\r\n\r\n    if (Array.isArray(mediaIDs)) mediaIDs.shift();\r\n\r\n    const mediaType = attachment.attributes.mime.split(\"/\")[0];\r\n    const mediaSubType = attachment.attributes.mime.split(\"/\")[1];\r\n\r\n    if (!this.maybeCompressAttachment(mediaType, mediaSubType)) {\r\n      return {\r\n        'mediaIDs': mediaIDs,\r\n        'data': __('Skipped', 'squeeze')\r\n      }\r\n    }\r\n\r\n    try {\r\n      const compressData = await this.handleCompress( attachment );\r\n      const uploadData = await this.handleUpload({ attachment: attachment, base64: compressData, type: type, mediaIDs: mediaIDs })\r\n\r\n      return uploadData;\r\n\r\n    } catch (error) {\r\n      return {\r\n        'mediaIDs': mediaIDs,\r\n        'data': error.message,\r\n        'success': false\r\n      }\r\n    }\r\n\r\n  }\r\n\r\n  maybeCompressAttachment = (attachmentType, attachmentSubType) => {\r\n    const allowedMimeTypes = ['jpeg', 'png', 'webp', 'avif'];\r\n    const isImage = attachmentType === 'image' && allowedMimeTypes.includes(attachmentSubType)\r\n\r\n    if (isImage) {\r\n      return true;\r\n    }\r\n\r\n    return false;\r\n  }\r\n\r\n  \r\n\r\n  handleRestore = async (attachmentID) => {\r\n    const data = {\r\n      action: 'squeeze_restore_attachment',\r\n      _ajax_nonce: this.nonce,\r\n      attachmentID: attachmentID,\r\n    };\r\n\r\n    const response = await jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  };\r\n\r\n  // Get list of attachments by path\r\n  getAttachmentsByPath = async (path) => {\r\n\r\n    const data = {\r\n      action: 'squeeze_get_attachment_by_path',\r\n      path: path,\r\n      _ajax_nonce: this.nonce,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  getAttachment = async (attachmentID) => {\r\n    const data = {\r\n      action: 'squeeze_get_attachment',\r\n      _ajax_nonce: this.nonce,\r\n      attachmentID: attachmentID,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  getNextAttachments = async (page = 1, type = 'uncompressed', lastId = 0) => {\r\n    const data = {\r\n      action: 'squeeze_get_next_attachments',\r\n      _ajax_nonce: this.nonce,\r\n      page: page,\r\n      type: type,\r\n      lastId: lastId,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  getDirectories = async (parentDir = false) => {\r\n    const data = {\r\n      action: 'squeeze_get_directories',\r\n      _ajax_nonce: this.nonce,\r\n    }\r\n\r\n    if (parentDir) {\r\n      data['parentDir'] = parentDir;\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  \r\n\r\n  setOptions = async (options) => {\r\n    const data = {\r\n      action: 'squeeze_set_options',\r\n      _ajax_nonce: this.nonce,\r\n      options: options,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  /*\r\n  getSizesFromFile = (file) => {\r\n    if (!file) return;\r\n\r\n    // get list of thumbnails from file\r\n    const sizes = {};\r\n    \r\n    const fd = new FormData();\r\n    fd.append('action', 'squeeze_get_sizes_from_file');\r\n    fd.append('_ajax_nonce', this.nonce);\r\n    fd.append('file', file);\r\n\r\n    jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: fd,\r\n      processData: false,\r\n      contentType: false,\r\n      async: false, // synchronous request\r\n    }).done((response) => {\r\n      console.log(response, 'getSizesFromFile response');\r\n      if (response.success) {\r\n        Object.keys(response.data).forEach((size) => {\r\n          sizes[size] = response.data[size];\r\n        });\r\n      } else {\r\n        console.error('Error getting sizes from file:', response.data);\r\n      }\r\n    }).fail((error) => {\r\n      console.error('AJAX error:', error);\r\n    });\r\n\r\n    return sizes;\r\n\r\n  }\r\n  */\r\n\r\n}\n\n//# sourceURL=webpack:///./assets/js/squeeze.js?");
     49eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ SQUEEZE)\n/* harmony export */ });\n/* harmony import */ var _helpers_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./helpers.js */ \"./assets/js/helpers.js\");\n/* harmony import */ var browser_image_compression__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! browser-image-compression */ \"./node_modules/browser-image-compression/dist/browser-image-compression.mjs\");\n/* harmony import */ var _jsquash_webp__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @jsquash/webp */ \"./node_modules/@jsquash/webp/encode.js\");\n\r\n\r\n\r\n\r\n\r\n\r\nconst { __ } = wp.i18n; // Import __() from wp.i18n\r\n\r\nclass SQUEEZE {\r\n\r\n  constructor(squeeze) {\r\n    this.options = JSON.parse(squeeze.options); // plugin options\r\n    this.nonce = squeeze.nonce; // nonce\r\n    this.ajaxUrl = squeeze.ajaxUrl; // ajax url\r\n    this.timeout = parseInt(this.options.timeout) * 1000; // convert to milliseconds\r\n    this.poolSize = navigator.hardwareConcurrency || 1; // number of threads\r\n  }\r\n\r\n  handleCompress = async ( attachment, type = 'uncompressed' ) => {\r\n    const attachmentData = attachment.attributes;\r\n    const url = attachmentData?.originalImageURL ?? attachmentData.url;\r\n    const mime = attachmentData.mime;\r\n    const name = attachmentData.name;\r\n    const filename = attachmentData?.originalImageName ?? attachmentData.filename;\r\n    const attachmentID = attachmentData.id;\r\n    const sizes = attachmentData.sizes;\r\n    const format = mime.split(\"/\")[1];\r\n    const sourceType = format;\r\n    const outputType = format;\r\n    const skipFull = attachmentData?.skipFull ?? attachmentData.originalImageName === undefined ? true : false;\r\n    const timeout = this.timeout;\r\n    const isPreview = attachmentData?.isPreview ?? false;\r\n    const file = attachmentData?.file ?? null; // the original file, it passed for the newly uploaded attachment to compress it\r\n\r\n    // the original compressed image base64, it passed when the attachment was already compressed and we need to compress thumbs only\r\n    // we pass it in order to prevent re-compressing the original image when we need to compress thumbs only\r\n    const base64Compressed = attachmentData?.base64Compressed ?? null; \r\n    const base64WebpCompressed = attachmentData?.base64WebpCompressed ?? null; // the original compressed webp image base64\r\n\r\n    const worker = new Worker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u(\"assets_js_worker_js\"), __webpack_require__.b), {type: undefined}); // worker url\r\n    const channel = new MessageChannel();\r\n    worker.postMessage({\r\n      action: 'compress',\r\n      format,\r\n      url,\r\n      name,\r\n      sourceType,\r\n      outputType,\r\n      mime,\r\n      sizes,\r\n      skipFull,\r\n      timeout,\r\n      isPreview,\r\n      file,\r\n      base64Compressed,\r\n      base64WebpCompressed,\r\n      type,\r\n      options: this.options,\r\n      //urlOriginal: urlOriginal,\r\n    }, [channel.port2]);\r\n\r\n    // Listen for compression requests from the worker via port1\r\n    channel.port1.onmessage = async (ev) => {\r\n      //console.log(\"Worker received compression request:\", ev.data);\r\n      const { id, action, fileOrArrayBuffer, mime, options } = ev.data;\r\n      if (action !== 'imageCompression') return;\r\n\r\n      try {\r\n        // Accept ArrayBuffer or Blob\r\n        const blob = (fileOrArrayBuffer instanceof ArrayBuffer)\r\n          ? new Blob([this.toUint8Array(fileOrArrayBuffer)], { type: mime })\r\n          : fileOrArrayBuffer;\r\n\r\n        const compressedBlob = await (0,browser_image_compression__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(blob, { useWebWorker: true, ...(options || {}) });\r\n\r\n        // quick checks\r\n        //console.log('compressedBlob.type, size:', compressedBlob.type, compressedBlob.size);\r\n        // normalize final binary\r\n        const compressedArrayBuffer = await compressedBlob.arrayBuffer();\r\n\r\n        // Reply with the compressed ArrayBuffer (transfer to avoid copy)\r\n        channel.port1.postMessage({ id, ok: true, arrayBuffer: compressedArrayBuffer }, [compressedArrayBuffer]);\r\n      } catch (err) {\r\n        channel.port1.postMessage({ id, ok: false, error: err.message || String(err) });\r\n      }\r\n    }\r\n\r\n    return new Promise((resolve, reject) => {\r\n      const timeoutId = setTimeout(() => {\r\n        worker.terminate();\r\n        console.warn('Worker compress terminated', name, sourceType, outputType);\r\n        reject(__('Request timed out.', 'squeeze'));\r\n      }, timeout);\r\n\r\n      worker.onmessage = (event) => {\r\n        clearTimeout(timeoutId);\r\n        if (event.data.error) {\r\n          reject(event.data.error);\r\n        } else {\r\n          resolve(event.data);\r\n        }\r\n        worker.terminate();\r\n      };\r\n\r\n      worker.onerror = (error) => {\r\n        clearTimeout(timeoutId);\r\n        reject(`Worker error: ${error.message}`);\r\n      };\r\n    });\r\n\r\n  }\r\n\r\n  handleUpload = async ({ attachment, base64, type = 'uncompressed', mediaIDs = [] }) => {\r\n\r\n    const attachmentData = attachment.attributes;\r\n    const url = attachmentData?.originalImageURL ?? attachmentData.url;\r\n    const mime = attachmentData.mime;\r\n    const filename = attachmentData?.originalImageName ?? attachmentData.filename;\r\n    const attachmentID = attachmentData.id;\r\n    const format = base64?.isDirectWebp && type !== 'path' ? 'webp' : mime.split(\"/\")[1];\r\n    const sizes = attachmentData.sizes;\r\n\r\n    const isDirectWebp = base64?.isDirectWebp && mime !== 'image/webp';\r\n    const isBackupOriginal = this.options?.backup_original ?? false; // check if backup original is enabled\r\n    let originalFile = attachmentData?.originalFile ?? null; // the original file, used for creating backup\r\n    \r\n    // if originalFile is not provided, try to get it from the URL\r\n    // used when the attachment needs to be converted to webp from jpg or png\r\n    if (!originalFile && type !== 'path' && isBackupOriginal && isDirectWebp) {\r\n      const file = await (0,_helpers_js__WEBPACK_IMPORTED_MODULE_0__.getFileFromUrl)(url, filename, mime.split(\"/\")[1])\r\n      //console.log('conveting original file to webp', file);\r\n      originalFile = await this.convertFileToWebp(file);\r\n    }\r\n    //console.log('handleUpload attachmentData', attachmentData)\r\n\r\n    const data = {\r\n      action: 'squeeze_update_attachment',\r\n      _ajax_nonce: this.nonce,\r\n      filename: filename,\r\n      type: 'image',\r\n      format: format,\r\n      base64: base64.base64,\r\n      base64Sizes: base64.base64Sizes,\r\n      base64Webp: base64.base64Webp,\r\n      base64SizesWebp: base64.base64SizesWebp,\r\n      attachmentID: attachmentID,\r\n      url: url,\r\n      process: type,\r\n      originalFile: originalFile,\r\n    }\r\n\r\n    const formData = (0,_helpers_js__WEBPACK_IMPORTED_MODULE_0__.objectToFormData)(data);\r\n\r\n    //console.log('squeeze_update_attachment', JSON.stringify(data, null, 2));\r\n\r\n    try {\r\n      const uploadResponse = await jQuery.ajax({\r\n      url: this.ajaxUrl, // + '111',\r\n      type: 'POST',\r\n      data: formData,\r\n      processData: false,  // very important!\r\n      contentType: false,  // very important!\r\n      });\r\n\r\n      //if (uploadResponse.success) {\r\n        uploadResponse['mediaIDs'] = mediaIDs;\r\n      //}\r\n\r\n      if (!uploadResponse?.data?.url) {\r\n        uploadResponse.url = url; // fallback to original URL if not provided\r\n      }\r\n\r\n      //console.log('uploadResponse', JSON.stringify(uploadResponse, null, 2));\r\n\r\n      return uploadResponse;\r\n      \r\n    } catch (error) {\r\n      return {\r\n      'mediaIDs': mediaIDs,\r\n      'data': error.message,\r\n      'success': false\r\n      };\r\n    }\r\n\r\n  }\r\n\r\n  handleBulkUpload = async (type = 'uncompressed', mediaIDs = []) => {\r\n    let currentID;\r\n    let attachment;\r\n\r\n    switch (type) {\r\n      case 'all':\r\n      case 'uncompressed':\r\n        currentID = mediaIDs[0];\r\n        break;\r\n      case 'path':\r\n        currentID = mediaIDs[0]?.filename;\r\n        break;\r\n      default:\r\n        currentID = 0;\r\n        break;\r\n    }\r\n\r\n    if (type === 'path') {\r\n\r\n      \r\n\r\n      attachment = {\r\n        attributes: {\r\n          url: mediaIDs[0].url,\r\n          mime: mediaIDs[0].mime,\r\n          name: mediaIDs[0].name,\r\n          filename: mediaIDs[0].filename,\r\n          id: mediaIDs[0].id,\r\n          sizes: mediaIDs[0]?.sizes,\r\n        }\r\n      }\r\n\r\n    } else {\r\n\r\n      const attachmentResponse = await this.getAttachment(currentID); \r\n      if (attachmentResponse.success === false) {\r\n        if (Array.isArray(mediaIDs)) mediaIDs.shift();\r\n        return {\r\n          'mediaIDs': mediaIDs,\r\n          'data': attachmentResponse.data\r\n        }\r\n      }\r\n      const attachmentData = attachmentResponse.data;\r\n      attachment = {\r\n        attributes: {\r\n          url: attachmentData.url,\r\n          mime: attachmentData.mime,\r\n          name: attachmentData.name,\r\n          filename: attachmentData.filename,\r\n          id: attachmentData.id,\r\n          sizes: attachmentData.sizes,\r\n        }\r\n      }\r\n\r\n    }\r\n\r\n    if (Array.isArray(mediaIDs)) mediaIDs.shift();\r\n\r\n    const mediaType = attachment.attributes.mime.split(\"/\")[0];\r\n    const mediaSubType = attachment.attributes.mime.split(\"/\")[1];\r\n\r\n    if (!(0,_helpers_js__WEBPACK_IMPORTED_MODULE_0__.maybeCompressAttachment)(mediaType, mediaSubType)) {\r\n      return {\r\n        'mediaIDs': mediaIDs,\r\n        'data': __('Skipped', 'squeeze')\r\n      }\r\n    }\r\n\r\n    try {\r\n      const compressData = await this.handleCompress( attachment, type );\r\n      const uploadData = await this.handleUpload({ attachment: attachment, base64: compressData, type: type, mediaIDs: mediaIDs })\r\n\r\n      return uploadData;\r\n\r\n    } catch (error) {\r\n      return {\r\n        'mediaIDs': mediaIDs,\r\n        'data': error?.message ?? error,\r\n        'success': false\r\n      }\r\n    }\r\n\r\n  }\r\n\r\n  \r\n\r\n  handleRestore = async (attachmentID) => {\r\n    const data = {\r\n      action: 'squeeze_restore_attachment',\r\n      _ajax_nonce: this.nonce,\r\n      attachmentID: attachmentID,\r\n    };\r\n\r\n    const response = await jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  };\r\n\r\n  // Get list of attachments by path\r\n  getAttachmentsByPath = async (path) => {\r\n\r\n    const data = {\r\n      action: 'squeeze_get_attachment_by_path',\r\n      path: path,\r\n      _ajax_nonce: this.nonce,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  getAttachment = async (attachmentID) => {\r\n    const data = {\r\n      action: 'squeeze_get_attachment',\r\n      _ajax_nonce: this.nonce,\r\n      attachmentID: attachmentID,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  getNextAttachments = async (page = 1, type = 'uncompressed', lastId = 0) => {\r\n    const data = {\r\n      action: 'squeeze_get_next_attachments',\r\n      _ajax_nonce: this.nonce,\r\n      page: page,\r\n      type: type,\r\n      lastId: lastId,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  getDirectories = async (parentDir = false) => {\r\n    const data = {\r\n      action: 'squeeze_get_directories',\r\n      _ajax_nonce: this.nonce,\r\n    }\r\n\r\n    if (parentDir) {\r\n      data['parentDir'] = parentDir;\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  \r\n\r\n  setOptions = async (options) => {\r\n    const data = {\r\n      action: 'squeeze_set_options',\r\n      _ajax_nonce: this.nonce,\r\n      options: options,\r\n    }\r\n\r\n    const response = jQuery.ajax({\r\n      url: this.ajaxUrl,\r\n      type: 'POST',\r\n      data: data,\r\n    });\r\n\r\n    return response;\r\n  }\r\n\r\n  /**\r\n   * Compresses an image before upload.\r\n   * If the compressSizes parameter is provided, it will compress the sizes specified along with the original image.\r\n   * \r\n   * @param {File} file - The file to be compressed\r\n   * @param {object} compressSizes - Optional sizes for compression\r\n   * @returns {Promise<object|boolean>} - Returns a Promise that resolves to the compressed file as a base64 object or false if the file is invalid\r\n   */\r\n  compressBeforeUpload = async (file, compressSizes = null) => {\r\n    if (!(file instanceof Blob) && !(file instanceof File)) {\r\n      console.error('Invalid file type:', file);\r\n      return false; // Return false if the file is not a Blob or File\r\n    }\r\n\r\n    const attachment = {\r\n      attributes: {\r\n        url: null,\r\n        mime: file.type,\r\n        name: file.name,\r\n        filename: file.name,\r\n        id: 0,\r\n        sizes: compressSizes,\r\n        file: file,\r\n        skipFull: false,\r\n      }\r\n    }\r\n\r\n    try {\r\n      const base64Obj = await this.handleCompress(attachment);\r\n\r\n      return base64Obj; // Return the compressed file as base64Obj\r\n    } catch (error) {\r\n      console.error(error);\r\n      return error; // Return the error for further handling\r\n    }\r\n  }\r\n\r\n  isWebpEncodingSupported = async () => {\r\n    try {\r\n      const canvas = document.createElement('canvas');\r\n      if (!canvas.toDataURL) return false;\r\n      const data = canvas.toDataURL('image/webp');\r\n      // WebP signature starts with \"data:image/webp\"\r\n      return data.indexOf('data:image/webp') === 0;\r\n    } catch (e) {\r\n      return false;\r\n    }\r\n  }\r\n\r\n  handleConvertFileToWebp = async (args) => {\r\n    const timeout = this.timeout;\r\n    \r\n    const { file, sourceType, name } = args;\r\n    const fileBuffer = await file.arrayBuffer();\r\n    const mime = sourceType === 'png' ? 'image/png' : 'image/jpeg';\r\n    const inputBlob = new Blob([fileBuffer], { type: mime });\r\n    // compression options you can tune\r\n    const imageCompressionOptions = {\r\n      useWebWorker: true,\r\n      fileType: 'image/webp',\r\n    };\r\n\r\n    return new Promise(async (resolve, reject) => {\r\n      const timeoutId = setTimeout(() => {\r\n      console.warn('Worker convertToWebp terminated', name);\r\n      reject(new Error(__('Request timed out.', 'squeeze')));\r\n      }, timeout);\r\n\r\n      try {\r\n\r\n        const compressedBlob = await (0,browser_image_compression__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(inputBlob, imageCompressionOptions);\r\n\r\n        // quick checks\r\n        //console.log('compressedBlob.type, size:', compressedBlob.type, compressedBlob.size);\r\n        // normalize final binary\r\n        const webpArrayBuffer = await compressedBlob.arrayBuffer();\r\n\r\n        const webpName = name.replace(/\\.\\w+$/, '.webp');\r\n        const webpFile = new File([webpArrayBuffer], webpName, { type: 'image/webp', lastModified: Date.now() });\r\n\r\n        clearTimeout(timeoutId);\r\n        resolve({ webpFile }); // must return object with webpFile prop\r\n      } catch (error) {\r\n        clearTimeout(timeoutId);\r\n        console.error('Error during image processing:', error);\r\n        reject(error);\r\n      }\r\n    });\r\n    \r\n  }\r\n\r\n  // helper: normalize buffer-like inputs to Uint8Array\r\n  toUint8Array = (bufferLike) => {\r\n    if (bufferLike instanceof Uint8Array) return bufferLike;\r\n    if (bufferLike instanceof ArrayBuffer) return new Uint8Array(bufferLike);\r\n    if (ArrayBuffer.isView(bufferLike)) return new Uint8Array(bufferLike.buffer, bufferLike.byteOffset, bufferLike.byteLength);\r\n    // Node Buffer (in some environments) has .buffer and .byteOffset\r\n    if (bufferLike && typeof bufferLike === 'object' && bufferLike.buffer) {\r\n      return new Uint8Array(bufferLike.buffer, bufferLike.byteOffset || 0, bufferLike.byteLength || bufferLike.length);\r\n    }\r\n    throw new Error('Unsupported buffer type: ' + Object.prototype.toString.call(bufferLike));\r\n  }\r\n\r\n  /**\r\n   * Convert an image File to WebP.\r\n   *\r\n   * @param {File} inputFile  — the original image File (e.g. JPEG, PNG).\r\n   * @returns {Promise<File>} — a Promise that resolves to a WebP File.\r\n   */\r\n  convertFileToWebp = async (inputFile) => {\r\n    // Ensure it’s an image\r\n    if (!inputFile.type.startsWith('image/')) {\r\n      throw new Error('Input must be an image File');\r\n    }\r\n    const args = {\r\n      file: inputFile,\r\n      sourceType: inputFile.type.split('/')[1], // e.g. 'jpeg', 'png'\r\n      name: inputFile.name,\r\n    }\r\n    const webpSupported = await this.isWebpEncodingSupported();\r\n    try {\r\n      // Convert the image to WebP\r\n      let webpData;\r\n      if (webpSupported) {\r\n        webpData = await this.handleConvertFileToWebp(args);\r\n      } else {\r\n        console.warn('WebP encoding not supported on this device. Using original format instead.');\r\n        const webpName = args.name.replace(/\\.\\w+$/, '.webp');\r\n        webpData = await this.convertToWebpWithJsquash(inputFile, webpName);\r\n      }\r\n      if (!webpData || !webpData.webpFile) {\r\n        throw new Error('Failed to convert image to WebP');\r\n      }\r\n\r\n      return webpData.webpFile; // Return the WebP File\r\n\r\n    } catch (error) {\r\n      console.error('Error converting image to WebP:', error);\r\n      throw error; // Re-throw the error for further handling\r\n    }\r\n\r\n  }\r\n\r\n  /**\r\n * Convert an input (File | Blob | ArrayBuffer | Uint8Array) to a WebP File using @jsquash/webp.\r\n * @param {File|Blob|ArrayBuffer|Uint8Array} input\r\n * @param {string} outputName - desired filename for the .webp output\r\n * @param {{quality?: number, lossless?: boolean, method?: number}} [opts] - encoder options (quality 0-100)\r\n * @returns {Promise<File>} - WebP File\r\n */\r\n  convertToWebpWithJsquash = async (input, outputName = 'out.webp', opts = { quality: 100 }) => {\r\n    // Normalize input to Blob\r\n    let blob;\r\n    if (input instanceof Blob) {\r\n      blob = input;\r\n    } else if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) {\r\n      blob = new Blob([input]);\r\n    } else {\r\n      throw new Error('Unsupported input type. Provide File, Blob, ArrayBuffer or TypedArray.');\r\n    }\r\n\r\n    // Load image into <img>\r\n    const dataURL = await new Promise((resolve, reject) => {\r\n      const fr = new FileReader();\r\n      fr.onload = () => resolve(fr.result);\r\n      fr.onerror = reject;\r\n      fr.readAsDataURL(blob);\r\n    });\r\n\r\n    const img = await new Promise((resolve, reject) => {\r\n      const i = new Image();\r\n      i.onload = () => resolve(i);\r\n      i.onerror = () => reject(new Error('Failed to load image for conversion'));\r\n      i.src = dataURL;\r\n      // avoid cross-origin taint if data-url is used\r\n    });\r\n\r\n    // Draw to canvas and extract ImageData\r\n    const canvas = document.createElement('canvas');\r\n    canvas.width = img.naturalWidth || img.width;\r\n    canvas.height = img.naturalHeight || img.height;\r\n    const ctx = canvas.getContext('2d');\r\n    ctx.drawImage(img, 0, 0);\r\n    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\r\n\r\n    // encode -> returns ArrayBuffer (WASM libwebp)\r\n    // opts example: { quality: 75, lossless: false, method: 4 }\r\n    const webpArrayBuffer = await (0,_jsquash_webp__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(imageData, opts);\r\n\r\n    // Validate a little (size)\r\n    if (!webpArrayBuffer || webpArrayBuffer.byteLength < 20) {\r\n      throw new Error('jsquash produced an invalid WebP buffer');\r\n    }\r\n\r\n    // Wrap into File\r\n    const webpFile = new File([webpArrayBuffer], outputName.replace(/\\.\\w+$/, '.webp'), {\r\n      type: 'image/webp',\r\n      lastModified: Date.now(),\r\n    });\r\n\r\n    return {webpFile};\r\n  }\r\n\r\n}\n\n//# sourceURL=webpack:///./assets/js/squeeze.js?");
     50
     51/***/ }),
     52
     53/***/ "./node_modules/@jsquash/webp/encode.js":
     54/*!**********************************************!*\
     55  !*** ./node_modules/@jsquash/webp/encode.js ***!
     56  \**********************************************/
     57/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
     58
     59eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ encode),\n/* harmony export */   \"init\": () => (/* binding */ init)\n/* harmony export */ });\n/* harmony import */ var _meta_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./meta.js */ \"./node_modules/@jsquash/webp/meta.js\");\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils.js */ \"./node_modules/@jsquash/webp/utils.js\");\n/* harmony import */ var wasm_feature_detect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! wasm-feature-detect */ \"./node_modules/wasm-feature-detect/dist/esm/index.js\");\n/**\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *     http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n\nlet emscriptenModule;\nasync function init(module, moduleOptionOverrides) {\n    if (await (0,wasm_feature_detect__WEBPACK_IMPORTED_MODULE_0__.simd)()) {\n        const webpEncoder = await __webpack_require__.e(/*! import() */ \"vendors-node_modules_jsquash_webp_codec_enc_webp_enc_simd_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./codec/enc/webp_enc_simd.js */ \"./node_modules/@jsquash/webp/codec/enc/webp_enc_simd.js\"));\n        emscriptenModule = (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.initEmscriptenModule)(webpEncoder.default, module, moduleOptionOverrides);\n        return emscriptenModule;\n    }\n    const webpEncoder = await __webpack_require__.e(/*! import() */ \"vendors-node_modules_jsquash_webp_codec_enc_webp_enc_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./codec/enc/webp_enc.js */ \"./node_modules/@jsquash/webp/codec/enc/webp_enc.js\"));\n    emscriptenModule = (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.initEmscriptenModule)(webpEncoder.default, module, moduleOptionOverrides);\n    return emscriptenModule;\n}\nasync function encode(data, options = {}) {\n    if (!emscriptenModule)\n        emscriptenModule = init();\n    const _options = { ..._meta_js__WEBPACK_IMPORTED_MODULE_2__.defaultOptions, ...options };\n    const module = await emscriptenModule;\n    const result = module.encode(data.data, data.width, data.height, _options);\n    if (!result)\n        throw new Error('Encoding error.');\n    return result.buffer;\n}\n\n\n//# sourceURL=webpack:///./node_modules/@jsquash/webp/encode.js?");
     60
     61/***/ }),
     62
     63/***/ "./node_modules/@jsquash/webp/meta.js":
     64/*!********************************************!*\
     65  !*** ./node_modules/@jsquash/webp/meta.js ***!
     66  \********************************************/
     67/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
     68
     69eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"defaultOptions\": () => (/* binding */ defaultOptions),\n/* harmony export */   \"extension\": () => (/* binding */ extension),\n/* harmony export */   \"label\": () => (/* binding */ label),\n/* harmony export */   \"mimeType\": () => (/* binding */ mimeType)\n/* harmony export */ });\nconst label = 'WebP';\nconst mimeType = 'image/webp';\nconst extension = 'webp';\n// These come from struct WebPConfig in encode.h.\nconst defaultOptions = {\n    quality: 75,\n    target_size: 0,\n    target_PSNR: 0,\n    method: 4,\n    sns_strength: 50,\n    filter_strength: 60,\n    filter_sharpness: 0,\n    filter_type: 1,\n    partitions: 0,\n    segments: 4,\n    pass: 1,\n    show_compressed: 0,\n    preprocessing: 0,\n    autofilter: 0,\n    partition_limit: 0,\n    alpha_compression: 1,\n    alpha_filtering: 1,\n    alpha_quality: 100,\n    lossless: 0,\n    exact: 0,\n    image_hint: 0,\n    emulate_jpeg_size: 0,\n    thread_level: 0,\n    low_memory: 0,\n    near_lossless: 100,\n    use_delta_palette: 0,\n    use_sharp_yuv: 0,\n};\n\n\n//# sourceURL=webpack:///./node_modules/@jsquash/webp/meta.js?");
     70
     71/***/ }),
     72
     73/***/ "./node_modules/@jsquash/webp/utils.js":
     74/*!*********************************************!*\
     75  !*** ./node_modules/@jsquash/webp/utils.js ***!
     76  \*********************************************/
     77/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
     78
     79eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"initEmscriptenModule\": () => (/* binding */ initEmscriptenModule)\n/* harmony export */ });\n/**\n * Copyright 2020 Google Inc. All Rights Reserved.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *     http://www.apache.org/licenses/LICENSE-2.0\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * Notice: I (Jamie Sinclair) have modified this file to allow manual instantiation of the Wasm Module.\n */\nfunction initEmscriptenModule(moduleFactory, wasmModule, moduleOptionOverrides = {}) {\n    let instantiateWasm;\n    if (wasmModule) {\n        instantiateWasm = (imports, callback) => {\n            const instance = new WebAssembly.Instance(wasmModule, imports);\n            callback(instance);\n            return instance.exports;\n        };\n    }\n    return moduleFactory({\n        // Just to be safe, don't automatically invoke any wasm functions\n        noInitialRun: true,\n        instantiateWasm,\n        ...moduleOptionOverrides,\n    });\n}\n\n\n//# sourceURL=webpack:///./node_modules/@jsquash/webp/utils.js?");
     80
     81/***/ }),
     82
     83/***/ "./node_modules/browser-image-compression/dist/browser-image-compression.mjs":
     84/*!***********************************************************************************!*\
     85  !*** ./node_modules/browser-image-compression/dist/browser-image-compression.mjs ***!
     86  \***********************************************************************************/
     87/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
     88
     89eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ imageCompression)\n/* harmony export */ });\n/**\n * Browser Image Compression\n * v2.0.2\n * by Donald <[email protected]>\n * https://github.com/Donaldcwl/browser-image-compression\n */\n\nfunction _mergeNamespaces(e,t){return t.forEach((function(t){t&&\"string\"!=typeof t&&!Array.isArray(t)&&Object.keys(t).forEach((function(r){if(\"default\"!==r&&!(r in e)){var i=Object.getOwnPropertyDescriptor(t,r);Object.defineProperty(e,r,i.get?i:{enumerable:!0,get:function(){return t[r]}})}}))})),Object.freeze(e)}function copyExifWithoutOrientation(e,t){return new Promise((function(r,i){let o;return getApp1Segment(e).then((function(e){try{return o=e,r(new Blob([t.slice(0,2),o,t.slice(2)],{type:\"image/jpeg\"}))}catch(e){return i(e)}}),i)}))}const getApp1Segment=e=>new Promise(((t,r)=>{const i=new FileReader;i.addEventListener(\"load\",(({target:{result:e}})=>{const i=new DataView(e);let o=0;if(65496!==i.getUint16(o))return r(\"not a valid JPEG\");for(o+=2;;){const a=i.getUint16(o);if(65498===a)break;const s=i.getUint16(o+2);if(65505===a&&1165519206===i.getUint32(o+4)){const a=o+10;let f;switch(i.getUint16(a)){case 18761:f=!0;break;case 19789:f=!1;break;default:return r(\"TIFF header contains invalid endian\")}if(42!==i.getUint16(a+2,f))return r(\"TIFF header contains invalid version\");const l=i.getUint32(a+4,f),c=a+l+2+12*i.getUint16(a+l,f);for(let e=a+l+2;e<c;e+=12){if(274==i.getUint16(e,f)){if(3!==i.getUint16(e+2,f))return r(\"Orientation data type is invalid\");if(1!==i.getUint32(e+4,f))return r(\"Orientation data count is invalid\");i.setUint16(e+8,1,f);break}}return t(e.slice(o,o+2+s))}o+=2+s}return t(new Blob)})),i.readAsArrayBuffer(e)}));var e={},t={get exports(){return e},set exports(t){e=t}};!function(e){var r,i,UZIP={};t.exports=UZIP,UZIP.parse=function(e,t){for(var r=UZIP.bin.readUshort,i=UZIP.bin.readUint,o=0,a={},s=new Uint8Array(e),f=s.length-4;101010256!=i(s,f);)f--;o=f;o+=4;var l=r(s,o+=4);r(s,o+=2);var c=i(s,o+=2),u=i(s,o+=4);o+=4,o=u;for(var h=0;h<l;h++){i(s,o),o+=4,o+=4,o+=4,i(s,o+=4);c=i(s,o+=4);var d=i(s,o+=4),A=r(s,o+=4),g=r(s,o+2),p=r(s,o+4);o+=6;var m=i(s,o+=8);o+=4,o+=A+g+p,UZIP._readLocal(s,m,a,c,d,t)}return a},UZIP._readLocal=function(e,t,r,i,o,a){var s=UZIP.bin.readUshort,f=UZIP.bin.readUint;f(e,t),s(e,t+=4),s(e,t+=2);var l=s(e,t+=2);f(e,t+=2),f(e,t+=4),t+=4;var c=s(e,t+=8),u=s(e,t+=2);t+=2;var h=UZIP.bin.readUTF8(e,t,c);if(t+=c,t+=u,a)r[h]={size:o,csize:i};else{var d=new Uint8Array(e.buffer,t);if(0==l)r[h]=new Uint8Array(d.buffer.slice(t,t+i));else{if(8!=l)throw\"unknown compression method: \"+l;var A=new Uint8Array(o);UZIP.inflateRaw(d,A),r[h]=A}}},UZIP.inflateRaw=function(e,t){return UZIP.F.inflate(e,t)},UZIP.inflate=function(e,t){return e[0],e[1],UZIP.inflateRaw(new Uint8Array(e.buffer,e.byteOffset+2,e.length-6),t)},UZIP.deflate=function(e,t){null==t&&(t={level:6});var r=0,i=new Uint8Array(50+Math.floor(1.1*e.length));i[r]=120,i[r+1]=156,r+=2,r=UZIP.F.deflateRaw(e,i,r,t.level);var o=UZIP.adler(e,0,e.length);return i[r+0]=o>>>24&255,i[r+1]=o>>>16&255,i[r+2]=o>>>8&255,i[r+3]=o>>>0&255,new Uint8Array(i.buffer,0,r+4)},UZIP.deflateRaw=function(e,t){null==t&&(t={level:6});var r=new Uint8Array(50+Math.floor(1.1*e.length)),i=UZIP.F.deflateRaw(e,r,i,t.level);return new Uint8Array(r.buffer,0,i)},UZIP.encode=function(e,t){null==t&&(t=!1);var r=0,i=UZIP.bin.writeUint,o=UZIP.bin.writeUshort,a={};for(var s in e){var f=!UZIP._noNeed(s)&&!t,l=e[s],c=UZIP.crc.crc(l,0,l.length);a[s]={cpr:f,usize:l.length,crc:c,file:f?UZIP.deflateRaw(l):l}}for(var s in a)r+=a[s].file.length+30+46+2*UZIP.bin.sizeUTF8(s);r+=22;var u=new Uint8Array(r),h=0,d=[];for(var s in a){var A=a[s];d.push(h),h=UZIP._writeHeader(u,h,s,A,0)}var g=0,p=h;for(var s in a){A=a[s];d.push(h),h=UZIP._writeHeader(u,h,s,A,1,d[g++])}var m=h-p;return i(u,h,101010256),h+=4,o(u,h+=4,g),o(u,h+=2,g),i(u,h+=2,m),i(u,h+=4,p),h+=4,h+=2,u.buffer},UZIP._noNeed=function(e){var t=e.split(\".\").pop().toLowerCase();return-1!=\"png,jpg,jpeg,zip\".indexOf(t)},UZIP._writeHeader=function(e,t,r,i,o,a){var s=UZIP.bin.writeUint,f=UZIP.bin.writeUshort,l=i.file;return s(e,t,0==o?67324752:33639248),t+=4,1==o&&(t+=2),f(e,t,20),f(e,t+=2,0),f(e,t+=2,i.cpr?8:0),s(e,t+=2,0),s(e,t+=4,i.crc),s(e,t+=4,l.length),s(e,t+=4,i.usize),f(e,t+=4,UZIP.bin.sizeUTF8(r)),f(e,t+=2,0),t+=2,1==o&&(t+=2,t+=2,s(e,t+=6,a),t+=4),t+=UZIP.bin.writeUTF8(e,t,r),0==o&&(e.set(l,t),t+=l.length),t},UZIP.crc={table:function(){for(var e=new Uint32Array(256),t=0;t<256;t++){for(var r=t,i=0;i<8;i++)1&r?r=3988292384^r>>>1:r>>>=1;e[t]=r}return e}(),update:function(e,t,r,i){for(var o=0;o<i;o++)e=UZIP.crc.table[255&(e^t[r+o])]^e>>>8;return e},crc:function(e,t,r){return 4294967295^UZIP.crc.update(4294967295,e,t,r)}},UZIP.adler=function(e,t,r){for(var i=1,o=0,a=t,s=t+r;a<s;){for(var f=Math.min(a+5552,s);a<f;)o+=i+=e[a++];i%=65521,o%=65521}return o<<16|i},UZIP.bin={readUshort:function(e,t){return e[t]|e[t+1]<<8},writeUshort:function(e,t,r){e[t]=255&r,e[t+1]=r>>8&255},readUint:function(e,t){return 16777216*e[t+3]+(e[t+2]<<16|e[t+1]<<8|e[t])},writeUint:function(e,t,r){e[t]=255&r,e[t+1]=r>>8&255,e[t+2]=r>>16&255,e[t+3]=r>>24&255},readASCII:function(e,t,r){for(var i=\"\",o=0;o<r;o++)i+=String.fromCharCode(e[t+o]);return i},writeASCII:function(e,t,r){for(var i=0;i<r.length;i++)e[t+i]=r.charCodeAt(i)},pad:function(e){return e.length<2?\"0\"+e:e},readUTF8:function(e,t,r){for(var i,o=\"\",a=0;a<r;a++)o+=\"%\"+UZIP.bin.pad(e[t+a].toString(16));try{i=decodeURIComponent(o)}catch(i){return UZIP.bin.readASCII(e,t,r)}return i},writeUTF8:function(e,t,r){for(var i=r.length,o=0,a=0;a<i;a++){var s=r.charCodeAt(a);if(0==(4294967168&s))e[t+o]=s,o++;else if(0==(4294965248&s))e[t+o]=192|s>>6,e[t+o+1]=128|s>>0&63,o+=2;else if(0==(4294901760&s))e[t+o]=224|s>>12,e[t+o+1]=128|s>>6&63,e[t+o+2]=128|s>>0&63,o+=3;else{if(0!=(4292870144&s))throw\"e\";e[t+o]=240|s>>18,e[t+o+1]=128|s>>12&63,e[t+o+2]=128|s>>6&63,e[t+o+3]=128|s>>0&63,o+=4}}return o},sizeUTF8:function(e){for(var t=e.length,r=0,i=0;i<t;i++){var o=e.charCodeAt(i);if(0==(4294967168&o))r++;else if(0==(4294965248&o))r+=2;else if(0==(4294901760&o))r+=3;else{if(0!=(4292870144&o))throw\"e\";r+=4}}return r}},UZIP.F={},UZIP.F.deflateRaw=function(e,t,r,i){var o=[[0,0,0,0,0],[4,4,8,4,0],[4,5,16,8,0],[4,6,16,16,0],[4,10,16,32,0],[8,16,32,32,0],[8,16,128,128,0],[8,32,128,256,0],[32,128,258,1024,1],[32,258,258,4096,1]][i],a=UZIP.F.U,s=UZIP.F._goodIndex;UZIP.F._hash;var f=UZIP.F._putsE,l=0,c=r<<3,u=0,h=e.length;if(0==i){for(;l<h;){f(t,c,l+(_=Math.min(65535,h-l))==h?1:0),c=UZIP.F._copyExact(e,l,_,t,c+8),l+=_}return c>>>3}var d=a.lits,A=a.strt,g=a.prev,p=0,m=0,w=0,v=0,b=0,y=0;for(h>2&&(A[y=UZIP.F._hash(e,0)]=0),l=0;l<h;l++){if(b=y,l+1<h-2){y=UZIP.F._hash(e,l+1);var E=l+1&32767;g[E]=A[y],A[y]=E}if(u<=l){(p>14e3||m>26697)&&h-l>100&&(u<l&&(d[p]=l-u,p+=2,u=l),c=UZIP.F._writeBlock(l==h-1||u==h?1:0,d,p,v,e,w,l-w,t,c),p=m=v=0,w=l);var F=0;l<h-2&&(F=UZIP.F._bestMatch(e,l,g,b,Math.min(o[2],h-l),o[3]));var _=F>>>16,B=65535&F;if(0!=F){B=65535&F;var U=s(_=F>>>16,a.of0);a.lhst[257+U]++;var C=s(B,a.df0);a.dhst[C]++,v+=a.exb[U]+a.dxb[C],d[p]=_<<23|l-u,d[p+1]=B<<16|U<<8|C,p+=2,u=l+_}else a.lhst[e[l]]++;m++}}for(w==l&&0!=e.length||(u<l&&(d[p]=l-u,p+=2,u=l),c=UZIP.F._writeBlock(1,d,p,v,e,w,l-w,t,c),p=0,m=0,p=m=v=0,w=l);0!=(7&c);)c++;return c>>>3},UZIP.F._bestMatch=function(e,t,r,i,o,a){var s=32767&t,f=r[s],l=s-f+32768&32767;if(f==s||i!=UZIP.F._hash(e,t-l))return 0;for(var c=0,u=0,h=Math.min(32767,t);l<=h&&0!=--a&&f!=s;){if(0==c||e[t+c]==e[t+c-l]){var d=UZIP.F._howLong(e,t,l);if(d>c){if(u=l,(c=d)>=o)break;l+2<d&&(d=l+2);for(var A=0,g=0;g<d-2;g++){var p=t-l+g+32768&32767,m=p-r[p]+32768&32767;m>A&&(A=m,f=p)}}}l+=(s=f)-(f=r[s])+32768&32767}return c<<16|u},UZIP.F._howLong=function(e,t,r){if(e[t]!=e[t-r]||e[t+1]!=e[t+1-r]||e[t+2]!=e[t+2-r])return 0;var i=t,o=Math.min(e.length,t+258);for(t+=3;t<o&&e[t]==e[t-r];)t++;return t-i},UZIP.F._hash=function(e,t){return(e[t]<<8|e[t+1])+(e[t+2]<<4)&65535},UZIP.saved=0,UZIP.F._writeBlock=function(e,t,r,i,o,a,s,f,l){var c,u,h,d,A,g,p,m,w,v=UZIP.F.U,b=UZIP.F._putsF,y=UZIP.F._putsE;v.lhst[256]++,u=(c=UZIP.F.getTrees())[0],h=c[1],d=c[2],A=c[3],g=c[4],p=c[5],m=c[6],w=c[7];var E=32+(0==(l+3&7)?0:8-(l+3&7))+(s<<3),F=i+UZIP.F.contSize(v.fltree,v.lhst)+UZIP.F.contSize(v.fdtree,v.dhst),_=i+UZIP.F.contSize(v.ltree,v.lhst)+UZIP.F.contSize(v.dtree,v.dhst);_+=14+3*p+UZIP.F.contSize(v.itree,v.ihst)+(2*v.ihst[16]+3*v.ihst[17]+7*v.ihst[18]);for(var B=0;B<286;B++)v.lhst[B]=0;for(B=0;B<30;B++)v.dhst[B]=0;for(B=0;B<19;B++)v.ihst[B]=0;var U=E<F&&E<_?0:F<_?1:2;if(b(f,l,e),b(f,l+1,U),l+=3,0==U){for(;0!=(7&l);)l++;l=UZIP.F._copyExact(o,a,s,f,l)}else{var C,I;if(1==U&&(C=v.fltree,I=v.fdtree),2==U){UZIP.F.makeCodes(v.ltree,u),UZIP.F.revCodes(v.ltree,u),UZIP.F.makeCodes(v.dtree,h),UZIP.F.revCodes(v.dtree,h),UZIP.F.makeCodes(v.itree,d),UZIP.F.revCodes(v.itree,d),C=v.ltree,I=v.dtree,y(f,l,A-257),y(f,l+=5,g-1),y(f,l+=5,p-4),l+=4;for(var Q=0;Q<p;Q++)y(f,l+3*Q,v.itree[1+(v.ordr[Q]<<1)]);l+=3*p,l=UZIP.F._codeTiny(m,v.itree,f,l),l=UZIP.F._codeTiny(w,v.itree,f,l)}for(var M=a,x=0;x<r;x+=2){for(var S=t[x],R=S>>>23,T=M+(8388607&S);M<T;)l=UZIP.F._writeLit(o[M++],C,f,l);if(0!=R){var O=t[x+1],P=O>>16,H=O>>8&255,L=255&O;y(f,l=UZIP.F._writeLit(257+H,C,f,l),R-v.of0[H]),l+=v.exb[H],b(f,l=UZIP.F._writeLit(L,I,f,l),P-v.df0[L]),l+=v.dxb[L],M+=R}}l=UZIP.F._writeLit(256,C,f,l)}return l},UZIP.F._copyExact=function(e,t,r,i,o){var a=o>>>3;return i[a]=r,i[a+1]=r>>>8,i[a+2]=255-i[a],i[a+3]=255-i[a+1],a+=4,i.set(new Uint8Array(e.buffer,t,r),a),o+(r+4<<3)},UZIP.F.getTrees=function(){for(var e=UZIP.F.U,t=UZIP.F._hufTree(e.lhst,e.ltree,15),r=UZIP.F._hufTree(e.dhst,e.dtree,15),i=[],o=UZIP.F._lenCodes(e.ltree,i),a=[],s=UZIP.F._lenCodes(e.dtree,a),f=0;f<i.length;f+=2)e.ihst[i[f]]++;for(f=0;f<a.length;f+=2)e.ihst[a[f]]++;for(var l=UZIP.F._hufTree(e.ihst,e.itree,7),c=19;c>4&&0==e.itree[1+(e.ordr[c-1]<<1)];)c--;return[t,r,l,o,s,c,i,a]},UZIP.F.getSecond=function(e){for(var t=[],r=0;r<e.length;r+=2)t.push(e[r+1]);return t},UZIP.F.nonZero=function(e){for(var t=\"\",r=0;r<e.length;r+=2)0!=e[r+1]&&(t+=(r>>1)+\",\");return t},UZIP.F.contSize=function(e,t){for(var r=0,i=0;i<t.length;i++)r+=t[i]*e[1+(i<<1)];return r},UZIP.F._codeTiny=function(e,t,r,i){for(var o=0;o<e.length;o+=2){var a=e[o],s=e[o+1];i=UZIP.F._writeLit(a,t,r,i);var f=16==a?2:17==a?3:7;a>15&&(UZIP.F._putsE(r,i,s,f),i+=f)}return i},UZIP.F._lenCodes=function(e,t){for(var r=e.length;2!=r&&0==e[r-1];)r-=2;for(var i=0;i<r;i+=2){var o=e[i+1],a=i+3<r?e[i+3]:-1,s=i+5<r?e[i+5]:-1,f=0==i?-1:e[i-1];if(0==o&&a==o&&s==o){for(var l=i+5;l+2<r&&e[l+2]==o;)l+=2;(c=Math.min(l+1-i>>>1,138))<11?t.push(17,c-3):t.push(18,c-11),i+=2*c-2}else if(o==f&&a==o&&s==o){for(l=i+5;l+2<r&&e[l+2]==o;)l+=2;var c=Math.min(l+1-i>>>1,6);t.push(16,c-3),i+=2*c-2}else t.push(o,0)}return r>>>1},UZIP.F._hufTree=function(e,t,r){var i=[],o=e.length,a=t.length,s=0;for(s=0;s<a;s+=2)t[s]=0,t[s+1]=0;for(s=0;s<o;s++)0!=e[s]&&i.push({lit:s,f:e[s]});var f=i.length,l=i.slice(0);if(0==f)return 0;if(1==f){var c=i[0].lit;l=0==c?1:0;return t[1+(c<<1)]=1,t[1+(l<<1)]=1,1}i.sort((function(e,t){return e.f-t.f}));var u=i[0],h=i[1],d=0,A=1,g=2;for(i[0]={lit:-1,f:u.f+h.f,l:u,r:h,d:0};A!=f-1;)u=d!=A&&(g==f||i[d].f<i[g].f)?i[d++]:i[g++],h=d!=A&&(g==f||i[d].f<i[g].f)?i[d++]:i[g++],i[A++]={lit:-1,f:u.f+h.f,l:u,r:h};var p=UZIP.F.setDepth(i[A-1],0);for(p>r&&(UZIP.F.restrictDepth(l,r,p),p=r),s=0;s<f;s++)t[1+(l[s].lit<<1)]=l[s].d;return p},UZIP.F.setDepth=function(e,t){return-1!=e.lit?(e.d=t,t):Math.max(UZIP.F.setDepth(e.l,t+1),UZIP.F.setDepth(e.r,t+1))},UZIP.F.restrictDepth=function(e,t,r){var i=0,o=1<<r-t,a=0;for(e.sort((function(e,t){return t.d==e.d?e.f-t.f:t.d-e.d})),i=0;i<e.length&&e[i].d>t;i++){var s=e[i].d;e[i].d=t,a+=o-(1<<r-s)}for(a>>>=r-t;a>0;){(s=e[i].d)<t?(e[i].d++,a-=1<<t-s-1):i++}for(;i>=0;i--)e[i].d==t&&a<0&&(e[i].d--,a++);0!=a&&console.log(\"debt left\")},UZIP.F._goodIndex=function(e,t){var r=0;return t[16|r]<=e&&(r|=16),t[8|r]<=e&&(r|=8),t[4|r]<=e&&(r|=4),t[2|r]<=e&&(r|=2),t[1|r]<=e&&(r|=1),r},UZIP.F._writeLit=function(e,t,r,i){return UZIP.F._putsF(r,i,t[e<<1]),i+t[1+(e<<1)]},UZIP.F.inflate=function(e,t){var r=Uint8Array;if(3==e[0]&&0==e[1])return t||new r(0);var i=UZIP.F,o=i._bitsF,a=i._bitsE,s=i._decodeTiny,f=i.makeCodes,l=i.codes2map,c=i._get17,u=i.U,h=null==t;h&&(t=new r(e.length>>>2<<3));for(var d,A,g=0,p=0,m=0,w=0,v=0,b=0,y=0,E=0,F=0;0==g;)if(g=o(e,F,1),p=o(e,F+1,2),F+=3,0!=p){if(h&&(t=UZIP.F._check(t,E+(1<<17))),1==p&&(d=u.flmap,A=u.fdmap,b=511,y=31),2==p){m=a(e,F,5)+257,w=a(e,F+5,5)+1,v=a(e,F+10,4)+4,F+=14;for(var _=0;_<38;_+=2)u.itree[_]=0,u.itree[_+1]=0;var B=1;for(_=0;_<v;_++){var U=a(e,F+3*_,3);u.itree[1+(u.ordr[_]<<1)]=U,U>B&&(B=U)}F+=3*v,f(u.itree,B),l(u.itree,B,u.imap),d=u.lmap,A=u.dmap,F=s(u.imap,(1<<B)-1,m+w,e,F,u.ttree);var C=i._copyOut(u.ttree,0,m,u.ltree);b=(1<<C)-1;var I=i._copyOut(u.ttree,m,w,u.dtree);y=(1<<I)-1,f(u.ltree,C),l(u.ltree,C,d),f(u.dtree,I),l(u.dtree,I,A)}for(;;){var Q=d[c(e,F)&b];F+=15&Q;var M=Q>>>4;if(M>>>8==0)t[E++]=M;else{if(256==M)break;var x=E+M-254;if(M>264){var S=u.ldef[M-257];x=E+(S>>>3)+a(e,F,7&S),F+=7&S}var R=A[c(e,F)&y];F+=15&R;var T=R>>>4,O=u.ddef[T],P=(O>>>4)+o(e,F,15&O);for(F+=15&O,h&&(t=UZIP.F._check(t,E+(1<<17)));E<x;)t[E]=t[E++-P],t[E]=t[E++-P],t[E]=t[E++-P],t[E]=t[E++-P];E=x}}}else{0!=(7&F)&&(F+=8-(7&F));var H=4+(F>>>3),L=e[H-4]|e[H-3]<<8;h&&(t=UZIP.F._check(t,E+L)),t.set(new r(e.buffer,e.byteOffset+H,L),E),F=H+L<<3,E+=L}return t.length==E?t:t.slice(0,E)},UZIP.F._check=function(e,t){var r=e.length;if(t<=r)return e;var i=new Uint8Array(Math.max(r<<1,t));return i.set(e,0),i},UZIP.F._decodeTiny=function(e,t,r,i,o,a){for(var s=UZIP.F._bitsE,f=UZIP.F._get17,l=0;l<r;){var c=e[f(i,o)&t];o+=15&c;var u=c>>>4;if(u<=15)a[l]=u,l++;else{var h=0,d=0;16==u?(d=3+s(i,o,2),o+=2,h=a[l-1]):17==u?(d=3+s(i,o,3),o+=3):18==u&&(d=11+s(i,o,7),o+=7);for(var A=l+d;l<A;)a[l]=h,l++}}return o},UZIP.F._copyOut=function(e,t,r,i){for(var o=0,a=0,s=i.length>>>1;a<r;){var f=e[a+t];i[a<<1]=0,i[1+(a<<1)]=f,f>o&&(o=f),a++}for(;a<s;)i[a<<1]=0,i[1+(a<<1)]=0,a++;return o},UZIP.F.makeCodes=function(e,t){for(var r,i,o,a,s=UZIP.F.U,f=e.length,l=s.bl_count,c=0;c<=t;c++)l[c]=0;for(c=1;c<f;c+=2)l[e[c]]++;var u=s.next_code;for(r=0,l[0]=0,i=1;i<=t;i++)r=r+l[i-1]<<1,u[i]=r;for(o=0;o<f;o+=2)0!=(a=e[o+1])&&(e[o]=u[a],u[a]++)},UZIP.F.codes2map=function(e,t,r){for(var i=e.length,o=UZIP.F.U.rev15,a=0;a<i;a+=2)if(0!=e[a+1])for(var s=a>>1,f=e[a+1],l=s<<4|f,c=t-f,u=e[a]<<c,h=u+(1<<c);u!=h;){r[o[u]>>>15-t]=l,u++}},UZIP.F.revCodes=function(e,t){for(var r=UZIP.F.U.rev15,i=15-t,o=0;o<e.length;o+=2){var a=e[o]<<t-e[o+1];e[o]=r[a]>>>i}},UZIP.F._putsE=function(e,t,r){r<<=7&t;var i=t>>>3;e[i]|=r,e[i+1]|=r>>>8},UZIP.F._putsF=function(e,t,r){r<<=7&t;var i=t>>>3;e[i]|=r,e[i+1]|=r>>>8,e[i+2]|=r>>>16},UZIP.F._bitsE=function(e,t,r){return(e[t>>>3]|e[1+(t>>>3)]<<8)>>>(7&t)&(1<<r)-1},UZIP.F._bitsF=function(e,t,r){return(e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)&(1<<r)-1},UZIP.F._get17=function(e,t){return(e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)},UZIP.F._get25=function(e,t){return(e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16|e[3+(t>>>3)]<<24)>>>(7&t)},UZIP.F.U=(r=Uint16Array,i=Uint32Array,{next_code:new r(16),bl_count:new r(16),ordr:[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],of0:[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,999,999,999],exb:[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0],ldef:new r(32),df0:[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,65535,65535],dxb:[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0],ddef:new i(32),flmap:new r(512),fltree:[],fdmap:new r(32),fdtree:[],lmap:new r(32768),ltree:[],ttree:[],dmap:new r(32768),dtree:[],imap:new r(512),itree:[],rev15:new r(32768),lhst:new i(286),dhst:new i(30),ihst:new i(19),lits:new i(15e3),strt:new r(65536),prev:new r(32768)}),function(){for(var e=UZIP.F.U,t=0;t<32768;t++){var r=t;r=(4278255360&(r=(4042322160&(r=(3435973836&(r=(2863311530&r)>>>1|(1431655765&r)<<1))>>>2|(858993459&r)<<2))>>>4|(252645135&r)<<4))>>>8|(16711935&r)<<8,e.rev15[t]=(r>>>16|r<<16)>>>17}function pushV(e,t,r){for(;0!=t--;)e.push(0,r)}for(t=0;t<32;t++)e.ldef[t]=e.of0[t]<<3|e.exb[t],e.ddef[t]=e.df0[t]<<4|e.dxb[t];pushV(e.fltree,144,8),pushV(e.fltree,112,9),pushV(e.fltree,24,7),pushV(e.fltree,8,8),UZIP.F.makeCodes(e.fltree,9),UZIP.F.codes2map(e.fltree,9,e.flmap),UZIP.F.revCodes(e.fltree,9),pushV(e.fdtree,32,5),UZIP.F.makeCodes(e.fdtree,5),UZIP.F.codes2map(e.fdtree,5,e.fdmap),UZIP.F.revCodes(e.fdtree,5),pushV(e.itree,19,0),pushV(e.ltree,286,0),pushV(e.dtree,30,0),pushV(e.ttree,320,0)}()}();var UZIP=_mergeNamespaces({__proto__:null,default:e},[e]);const UPNG=function(){var e={nextZero(e,t){for(;0!=e[t];)t++;return t},readUshort:(e,t)=>e[t]<<8|e[t+1],writeUshort(e,t,r){e[t]=r>>8&255,e[t+1]=255&r},readUint:(e,t)=>16777216*e[t]+(e[t+1]<<16|e[t+2]<<8|e[t+3]),writeUint(e,t,r){e[t]=r>>24&255,e[t+1]=r>>16&255,e[t+2]=r>>8&255,e[t+3]=255&r},readASCII(e,t,r){let i=\"\";for(let o=0;o<r;o++)i+=String.fromCharCode(e[t+o]);return i},writeASCII(e,t,r){for(let i=0;i<r.length;i++)e[t+i]=r.charCodeAt(i)},readBytes(e,t,r){const i=[];for(let o=0;o<r;o++)i.push(e[t+o]);return i},pad:e=>e.length<2?`0${e}`:e,readUTF8(t,r,i){let o,a=\"\";for(let o=0;o<i;o++)a+=`%${e.pad(t[r+o].toString(16))}`;try{o=decodeURIComponent(a)}catch(o){return e.readASCII(t,r,i)}return o}};function decodeImage(t,r,i,o){const a=r*i,s=_getBPP(o),f=Math.ceil(r*s/8),l=new Uint8Array(4*a),c=new Uint32Array(l.buffer),{ctype:u}=o,{depth:h}=o,d=e.readUshort;if(6==u){const e=a<<2;if(8==h)for(var A=0;A<e;A+=4)l[A]=t[A],l[A+1]=t[A+1],l[A+2]=t[A+2],l[A+3]=t[A+3];if(16==h)for(A=0;A<e;A++)l[A]=t[A<<1]}else if(2==u){const e=o.tabs.tRNS;if(null==e){if(8==h)for(A=0;A<a;A++){var g=3*A;c[A]=255<<24|t[g+2]<<16|t[g+1]<<8|t[g]}if(16==h)for(A=0;A<a;A++){g=6*A;c[A]=255<<24|t[g+4]<<16|t[g+2]<<8|t[g]}}else{var p=e[0];const r=e[1],i=e[2];if(8==h)for(A=0;A<a;A++){var m=A<<2;g=3*A;c[A]=255<<24|t[g+2]<<16|t[g+1]<<8|t[g],t[g]==p&&t[g+1]==r&&t[g+2]==i&&(l[m+3]=0)}if(16==h)for(A=0;A<a;A++){m=A<<2,g=6*A;c[A]=255<<24|t[g+4]<<16|t[g+2]<<8|t[g],d(t,g)==p&&d(t,g+2)==r&&d(t,g+4)==i&&(l[m+3]=0)}}}else if(3==u){const e=o.tabs.PLTE,s=o.tabs.tRNS,c=s?s.length:0;if(1==h)for(var w=0;w<i;w++){var v=w*f,b=w*r;for(A=0;A<r;A++){m=b+A<<2;var y=3*(E=t[v+(A>>3)]>>7-((7&A)<<0)&1);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255}}if(2==h)for(w=0;w<i;w++)for(v=w*f,b=w*r,A=0;A<r;A++){m=b+A<<2,y=3*(E=t[v+(A>>2)]>>6-((3&A)<<1)&3);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255}if(4==h)for(w=0;w<i;w++)for(v=w*f,b=w*r,A=0;A<r;A++){m=b+A<<2,y=3*(E=t[v+(A>>1)]>>4-((1&A)<<2)&15);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255}if(8==h)for(A=0;A<a;A++){var E;m=A<<2,y=3*(E=t[A]);l[m]=e[y],l[m+1]=e[y+1],l[m+2]=e[y+2],l[m+3]=E<c?s[E]:255}}else if(4==u){if(8==h)for(A=0;A<a;A++){m=A<<2;var F=t[_=A<<1];l[m]=F,l[m+1]=F,l[m+2]=F,l[m+3]=t[_+1]}if(16==h)for(A=0;A<a;A++){var _;m=A<<2,F=t[_=A<<2];l[m]=F,l[m+1]=F,l[m+2]=F,l[m+3]=t[_+2]}}else if(0==u)for(p=o.tabs.tRNS?o.tabs.tRNS:-1,w=0;w<i;w++){const e=w*f,i=w*r;if(1==h)for(var B=0;B<r;B++){var U=(F=255*(t[e+(B>>>3)]>>>7-(7&B)&1))==255*p?0:255;c[i+B]=U<<24|F<<16|F<<8|F}else if(2==h)for(B=0;B<r;B++){U=(F=85*(t[e+(B>>>2)]>>>6-((3&B)<<1)&3))==85*p?0:255;c[i+B]=U<<24|F<<16|F<<8|F}else if(4==h)for(B=0;B<r;B++){U=(F=17*(t[e+(B>>>1)]>>>4-((1&B)<<2)&15))==17*p?0:255;c[i+B]=U<<24|F<<16|F<<8|F}else if(8==h)for(B=0;B<r;B++){U=(F=t[e+B])==p?0:255;c[i+B]=U<<24|F<<16|F<<8|F}else if(16==h)for(B=0;B<r;B++){F=t[e+(B<<1)],U=d(t,e+(B<<1))==p?0:255;c[i+B]=U<<24|F<<16|F<<8|F}}return l}function _decompress(e,r,i,o){const a=_getBPP(e),s=Math.ceil(i*a/8),f=new Uint8Array((s+1+e.interlace)*o);return r=e.tabs.CgBI?t(r,f):_inflate(r,f),0==e.interlace?r=_filterZero(r,e,0,i,o):1==e.interlace&&(r=function _readInterlace(e,t){const r=t.width,i=t.height,o=_getBPP(t),a=o>>3,s=Math.ceil(r*o/8),f=new Uint8Array(i*s);let l=0;const c=[0,0,4,0,2,0,1],u=[0,4,0,2,0,1,0],h=[8,8,8,4,4,2,2],d=[8,8,4,4,2,2,1];let A=0;for(;A<7;){const p=h[A],m=d[A];let w=0,v=0,b=c[A];for(;b<i;)b+=p,v++;let y=u[A];for(;y<r;)y+=m,w++;const E=Math.ceil(w*o/8);_filterZero(e,t,l,w,v);let F=0,_=c[A];for(;_<i;){let t=u[A],i=l+F*E<<3;for(;t<r;){var g;if(1==o)g=(g=e[i>>3])>>7-(7&i)&1,f[_*s+(t>>3)]|=g<<7-((7&t)<<0);if(2==o)g=(g=e[i>>3])>>6-(7&i)&3,f[_*s+(t>>2)]|=g<<6-((3&t)<<1);if(4==o)g=(g=e[i>>3])>>4-(7&i)&15,f[_*s+(t>>1)]|=g<<4-((1&t)<<2);if(o>=8){const r=_*s+t*a;for(let t=0;t<a;t++)f[r+t]=e[(i>>3)+t]}i+=o,t+=m}F++,_+=p}w*v!=0&&(l+=v*(1+E)),A+=1}return f}(r,e)),r}function _inflate(e,r){return t(new Uint8Array(e.buffer,2,e.length-6),r)}var t=function(){const e={H:{}};return e.H.N=function(t,r){const i=Uint8Array;let o,a,s=0,f=0,l=0,c=0,u=0,h=0,d=0,A=0,g=0;if(3==t[0]&&0==t[1])return r||new i(0);const p=e.H,m=p.b,w=p.e,v=p.R,b=p.n,y=p.A,E=p.Z,F=p.m,_=null==r;for(_&&(r=new i(t.length>>>2<<5));0==s;)if(s=m(t,g,1),f=m(t,g+1,2),g+=3,0!=f){if(_&&(r=e.H.W(r,A+(1<<17))),1==f&&(o=F.J,a=F.h,h=511,d=31),2==f){l=w(t,g,5)+257,c=w(t,g+5,5)+1,u=w(t,g+10,4)+4,g+=14;let e=1;for(var B=0;B<38;B+=2)F.Q[B]=0,F.Q[B+1]=0;for(B=0;B<u;B++){const r=w(t,g+3*B,3);F.Q[1+(F.X[B]<<1)]=r,r>e&&(e=r)}g+=3*u,b(F.Q,e),y(F.Q,e,F.u),o=F.w,a=F.d,g=v(F.u,(1<<e)-1,l+c,t,g,F.v);const r=p.V(F.v,0,l,F.C);h=(1<<r)-1;const i=p.V(F.v,l,c,F.D);d=(1<<i)-1,b(F.C,r),y(F.C,r,o),b(F.D,i),y(F.D,i,a)}for(;;){const e=o[E(t,g)&h];g+=15&e;const i=e>>>4;if(i>>>8==0)r[A++]=i;else{if(256==i)break;{let e=A+i-254;if(i>264){const r=F.q[i-257];e=A+(r>>>3)+w(t,g,7&r),g+=7&r}const o=a[E(t,g)&d];g+=15&o;const s=o>>>4,f=F.c[s],l=(f>>>4)+m(t,g,15&f);for(g+=15&f;A<e;)r[A]=r[A++-l],r[A]=r[A++-l],r[A]=r[A++-l],r[A]=r[A++-l];A=e}}}}else{0!=(7&g)&&(g+=8-(7&g));const o=4+(g>>>3),a=t[o-4]|t[o-3]<<8;_&&(r=e.H.W(r,A+a)),r.set(new i(t.buffer,t.byteOffset+o,a),A),g=o+a<<3,A+=a}return r.length==A?r:r.slice(0,A)},e.H.W=function(e,t){const r=e.length;if(t<=r)return e;const i=new Uint8Array(r<<1);return i.set(e,0),i},e.H.R=function(t,r,i,o,a,s){const f=e.H.e,l=e.H.Z;let c=0;for(;c<i;){const e=t[l(o,a)&r];a+=15&e;const i=e>>>4;if(i<=15)s[c]=i,c++;else{let e=0,t=0;16==i?(t=3+f(o,a,2),a+=2,e=s[c-1]):17==i?(t=3+f(o,a,3),a+=3):18==i&&(t=11+f(o,a,7),a+=7);const r=c+t;for(;c<r;)s[c]=e,c++}}return a},e.H.V=function(e,t,r,i){let o=0,a=0;const s=i.length>>>1;for(;a<r;){const r=e[a+t];i[a<<1]=0,i[1+(a<<1)]=r,r>o&&(o=r),a++}for(;a<s;)i[a<<1]=0,i[1+(a<<1)]=0,a++;return o},e.H.n=function(t,r){const i=e.H.m,o=t.length;let a,s,f;let l;const c=i.j;for(var u=0;u<=r;u++)c[u]=0;for(u=1;u<o;u+=2)c[t[u]]++;const h=i.K;for(a=0,c[0]=0,s=1;s<=r;s++)a=a+c[s-1]<<1,h[s]=a;for(f=0;f<o;f+=2)l=t[f+1],0!=l&&(t[f]=h[l],h[l]++)},e.H.A=function(t,r,i){const o=t.length,a=e.H.m.r;for(let e=0;e<o;e+=2)if(0!=t[e+1]){const o=e>>1,s=t[e+1],f=o<<4|s,l=r-s;let c=t[e]<<l;const u=c+(1<<l);for(;c!=u;){i[a[c]>>>15-r]=f,c++}}},e.H.l=function(t,r){const i=e.H.m.r,o=15-r;for(let e=0;e<t.length;e+=2){const a=t[e]<<r-t[e+1];t[e]=i[a]>>>o}},e.H.M=function(e,t,r){r<<=7&t;const i=t>>>3;e[i]|=r,e[i+1]|=r>>>8},e.H.I=function(e,t,r){r<<=7&t;const i=t>>>3;e[i]|=r,e[i+1]|=r>>>8,e[i+2]|=r>>>16},e.H.e=function(e,t,r){return(e[t>>>3]|e[1+(t>>>3)]<<8)>>>(7&t)&(1<<r)-1},e.H.b=function(e,t,r){return(e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)&(1<<r)-1},e.H.Z=function(e,t){return(e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16)>>>(7&t)},e.H.i=function(e,t){return(e[t>>>3]|e[1+(t>>>3)]<<8|e[2+(t>>>3)]<<16|e[3+(t>>>3)]<<24)>>>(7&t)},e.H.m=function(){const e=Uint16Array,t=Uint32Array;return{K:new e(16),j:new e(16),X:[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],S:[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,999,999,999],T:[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0],q:new e(32),p:[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,65535,65535],z:[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0],c:new t(32),J:new e(512),_:[],h:new e(32),$:[],w:new e(32768),C:[],v:[],d:new e(32768),D:[],u:new e(512),Q:[],r:new e(32768),s:new t(286),Y:new t(30),a:new t(19),t:new t(15e3),k:new e(65536),g:new e(32768)}}(),function(){const t=e.H.m;for(var r=0;r<32768;r++){let e=r;e=(2863311530&e)>>>1|(1431655765&e)<<1,e=(3435973836&e)>>>2|(858993459&e)<<2,e=(4042322160&e)>>>4|(252645135&e)<<4,e=(4278255360&e)>>>8|(16711935&e)<<8,t.r[r]=(e>>>16|e<<16)>>>17}function n(e,t,r){for(;0!=t--;)e.push(0,r)}for(r=0;r<32;r++)t.q[r]=t.S[r]<<3|t.T[r],t.c[r]=t.p[r]<<4|t.z[r];n(t._,144,8),n(t._,112,9),n(t._,24,7),n(t._,8,8),e.H.n(t._,9),e.H.A(t._,9,t.J),e.H.l(t._,9),n(t.$,32,5),e.H.n(t.$,5),e.H.A(t.$,5,t.h),e.H.l(t.$,5),n(t.Q,19,0),n(t.C,286,0),n(t.D,30,0),n(t.v,320,0)}(),e.H.N}();function _getBPP(e){return[1,null,3,1,2,null,4][e.ctype]*e.depth}function _filterZero(e,t,r,i,o){let a=_getBPP(t);const s=Math.ceil(i*a/8);let f,l;a=Math.ceil(a/8);let c=e[r],u=0;if(c>1&&(e[r]=[0,0,1][c-2]),3==c)for(u=a;u<s;u++)e[u+1]=e[u+1]+(e[u+1-a]>>>1)&255;for(let t=0;t<o;t++)if(f=r+t*s,l=f+t+1,c=e[l-1],u=0,0==c)for(;u<s;u++)e[f+u]=e[l+u];else if(1==c){for(;u<a;u++)e[f+u]=e[l+u];for(;u<s;u++)e[f+u]=e[l+u]+e[f+u-a]}else if(2==c)for(;u<s;u++)e[f+u]=e[l+u]+e[f+u-s];else if(3==c){for(;u<a;u++)e[f+u]=e[l+u]+(e[f+u-s]>>>1);for(;u<s;u++)e[f+u]=e[l+u]+(e[f+u-s]+e[f+u-a]>>>1)}else{for(;u<a;u++)e[f+u]=e[l+u]+_paeth(0,e[f+u-s],0);for(;u<s;u++)e[f+u]=e[l+u]+_paeth(e[f+u-a],e[f+u-s],e[f+u-a-s])}return e}function _paeth(e,t,r){const i=e+t-r,o=i-e,a=i-t,s=i-r;return o*o<=a*a&&o*o<=s*s?e:a*a<=s*s?t:r}function _IHDR(t,r,i){i.width=e.readUint(t,r),r+=4,i.height=e.readUint(t,r),r+=4,i.depth=t[r],r++,i.ctype=t[r],r++,i.compress=t[r],r++,i.filter=t[r],r++,i.interlace=t[r],r++}function _copyTile(e,t,r,i,o,a,s,f,l){const c=Math.min(t,o),u=Math.min(r,a);let h=0,d=0;for(let r=0;r<u;r++)for(let a=0;a<c;a++)if(s>=0&&f>=0?(h=r*t+a<<2,d=(f+r)*o+s+a<<2):(h=(-f+r)*t-s+a<<2,d=r*o+a<<2),0==l)i[d]=e[h],i[d+1]=e[h+1],i[d+2]=e[h+2],i[d+3]=e[h+3];else if(1==l){var A=e[h+3]*(1/255),g=e[h]*A,p=e[h+1]*A,m=e[h+2]*A,w=i[d+3]*(1/255),v=i[d]*w,b=i[d+1]*w,y=i[d+2]*w;const t=1-A,r=A+w*t,o=0==r?0:1/r;i[d+3]=255*r,i[d+0]=(g+v*t)*o,i[d+1]=(p+b*t)*o,i[d+2]=(m+y*t)*o}else if(2==l){A=e[h+3],g=e[h],p=e[h+1],m=e[h+2],w=i[d+3],v=i[d],b=i[d+1],y=i[d+2];A==w&&g==v&&p==b&&m==y?(i[d]=0,i[d+1]=0,i[d+2]=0,i[d+3]=0):(i[d]=g,i[d+1]=p,i[d+2]=m,i[d+3]=A)}else if(3==l){A=e[h+3],g=e[h],p=e[h+1],m=e[h+2],w=i[d+3],v=i[d],b=i[d+1],y=i[d+2];if(A==w&&g==v&&p==b&&m==y)continue;if(A<220&&w>20)return!1}return!0}return{decode:function decode(r){const i=new Uint8Array(r);let o=8;const a=e,s=a.readUshort,f=a.readUint,l={tabs:{},frames:[]},c=new Uint8Array(i.length);let u,h=0,d=0;const A=[137,80,78,71,13,10,26,10];for(var g=0;g<8;g++)if(i[g]!=A[g])throw\"The input is not a PNG file!\";for(;o<i.length;){const e=a.readUint(i,o);o+=4;const r=a.readASCII(i,o,4);if(o+=4,\"IHDR\"==r)_IHDR(i,o,l);else if(\"iCCP\"==r){for(var p=o;0!=i[p];)p++;a.readASCII(i,o,p-o),i[p+1];const s=i.slice(p+2,o+e);let f=null;try{f=_inflate(s)}catch(e){f=t(s)}l.tabs[r]=f}else if(\"CgBI\"==r)l.tabs[r]=i.slice(o,o+4);else if(\"IDAT\"==r){for(g=0;g<e;g++)c[h+g]=i[o+g];h+=e}else if(\"acTL\"==r)l.tabs[r]={num_frames:f(i,o),num_plays:f(i,o+4)},u=new Uint8Array(i.length);else if(\"fcTL\"==r){if(0!=d)(E=l.frames[l.frames.length-1]).data=_decompress(l,u.slice(0,d),E.rect.width,E.rect.height),d=0;const e={x:f(i,o+12),y:f(i,o+16),width:f(i,o+4),height:f(i,o+8)};let t=s(i,o+22);t=s(i,o+20)/(0==t?100:t);const r={rect:e,delay:Math.round(1e3*t),dispose:i[o+24],blend:i[o+25]};l.frames.push(r)}else if(\"fdAT\"==r){for(g=0;g<e-4;g++)u[d+g]=i[o+g+4];d+=e-4}else if(\"pHYs\"==r)l.tabs[r]=[a.readUint(i,o),a.readUint(i,o+4),i[o+8]];else if(\"cHRM\"==r){l.tabs[r]=[];for(g=0;g<8;g++)l.tabs[r].push(a.readUint(i,o+4*g))}else if(\"tEXt\"==r||\"zTXt\"==r){null==l.tabs[r]&&(l.tabs[r]={});var m=a.nextZero(i,o),w=a.readASCII(i,o,m-o),v=o+e-m-1;if(\"tEXt\"==r)y=a.readASCII(i,m+1,v);else{var b=_inflate(i.slice(m+2,m+2+v));y=a.readUTF8(b,0,b.length)}l.tabs[r][w]=y}else if(\"iTXt\"==r){null==l.tabs[r]&&(l.tabs[r]={});m=0,p=o;m=a.nextZero(i,p);w=a.readASCII(i,p,m-p);const t=i[p=m+1];var y;i[p+1],p+=2,m=a.nextZero(i,p),a.readASCII(i,p,m-p),p=m+1,m=a.nextZero(i,p),a.readUTF8(i,p,m-p);v=e-((p=m+1)-o);if(0==t)y=a.readUTF8(i,p,v);else{b=_inflate(i.slice(p,p+v));y=a.readUTF8(b,0,b.length)}l.tabs[r][w]=y}else if(\"PLTE\"==r)l.tabs[r]=a.readBytes(i,o,e);else if(\"hIST\"==r){const e=l.tabs.PLTE.length/3;l.tabs[r]=[];for(g=0;g<e;g++)l.tabs[r].push(s(i,o+2*g))}else if(\"tRNS\"==r)3==l.ctype?l.tabs[r]=a.readBytes(i,o,e):0==l.ctype?l.tabs[r]=s(i,o):2==l.ctype&&(l.tabs[r]=[s(i,o),s(i,o+2),s(i,o+4)]);else if(\"gAMA\"==r)l.tabs[r]=a.readUint(i,o)/1e5;else if(\"sRGB\"==r)l.tabs[r]=i[o];else if(\"bKGD\"==r)0==l.ctype||4==l.ctype?l.tabs[r]=[s(i,o)]:2==l.ctype||6==l.ctype?l.tabs[r]=[s(i,o),s(i,o+2),s(i,o+4)]:3==l.ctype&&(l.tabs[r]=i[o]);else if(\"IEND\"==r)break;o+=e,a.readUint(i,o),o+=4}var E;return 0!=d&&((E=l.frames[l.frames.length-1]).data=_decompress(l,u.slice(0,d),E.rect.width,E.rect.height)),l.data=_decompress(l,c,l.width,l.height),delete l.compress,delete l.interlace,delete l.filter,l},toRGBA8:function toRGBA8(e){const t=e.width,r=e.height;if(null==e.tabs.acTL)return[decodeImage(e.data,t,r,e).buffer];const i=[];null==e.frames[0].data&&(e.frames[0].data=e.data);const o=t*r*4,a=new Uint8Array(o),s=new Uint8Array(o),f=new Uint8Array(o);for(let c=0;c<e.frames.length;c++){const u=e.frames[c],h=u.rect.x,d=u.rect.y,A=u.rect.width,g=u.rect.height,p=decodeImage(u.data,A,g,e);if(0!=c)for(var l=0;l<o;l++)f[l]=a[l];if(0==u.blend?_copyTile(p,A,g,a,t,r,h,d,0):1==u.blend&&_copyTile(p,A,g,a,t,r,h,d,1),i.push(a.buffer.slice(0)),0==u.dispose);else if(1==u.dispose)_copyTile(s,A,g,a,t,r,h,d,0);else if(2==u.dispose)for(l=0;l<o;l++)a[l]=f[l]}return i},_paeth:_paeth,_copyTile:_copyTile,_bin:e}}();!function(){const{_copyTile:e}=UPNG,{_bin:t}=UPNG,r=UPNG._paeth;var i={table:function(){const e=new Uint32Array(256);for(let t=0;t<256;t++){let r=t;for(let e=0;e<8;e++)1&r?r=3988292384^r>>>1:r>>>=1;e[t]=r}return e}(),update(e,t,r,o){for(let a=0;a<o;a++)e=i.table[255&(e^t[r+a])]^e>>>8;return e},crc:(e,t,r)=>4294967295^i.update(4294967295,e,t,r)};function addErr(e,t,r,i){t[r]+=e[0]*i>>4,t[r+1]+=e[1]*i>>4,t[r+2]+=e[2]*i>>4,t[r+3]+=e[3]*i>>4}function N(e){return Math.max(0,Math.min(255,e))}function D(e,t){const r=e[0]-t[0],i=e[1]-t[1],o=e[2]-t[2],a=e[3]-t[3];return r*r+i*i+o*o+a*a}function dither(e,t,r,i,o,a,s){null==s&&(s=1);const f=i.length,l=[];for(var c=0;c<f;c++){const e=i[c];l.push([e>>>0&255,e>>>8&255,e>>>16&255,e>>>24&255])}for(c=0;c<f;c++){let e=4294967295;for(var u=0,h=0;h<f;h++){var d=D(l[c],l[h]);h!=c&&d<e&&(e=d,u=h)}}const A=new Uint32Array(o.buffer),g=new Int16Array(t*r*4),p=[0,8,2,10,12,4,14,6,3,11,1,9,15,7,13,5];for(c=0;c<p.length;c++)p[c]=255*((p[c]+.5)/16-.5);for(let o=0;o<r;o++)for(let w=0;w<t;w++){var m;c=4*(o*t+w);if(2!=s)m=[N(e[c]+g[c]),N(e[c+1]+g[c+1]),N(e[c+2]+g[c+2]),N(e[c+3]+g[c+3])];else{d=p[4*(3&o)+(3&w)];m=[N(e[c]+d),N(e[c+1]+d),N(e[c+2]+d),N(e[c+3]+d)]}u=0;let v=16777215;for(h=0;h<f;h++){const e=D(m,l[h]);e<v&&(v=e,u=h)}const b=l[u],y=[m[0]-b[0],m[1]-b[1],m[2]-b[2],m[3]-b[3]];1==s&&(w!=t-1&&addErr(y,g,c+4,7),o!=r-1&&(0!=w&&addErr(y,g,c+4*t-4,3),addErr(y,g,c+4*t,5),w!=t-1&&addErr(y,g,c+4*t+4,1))),a[c>>2]=u,A[c>>2]=i[u]}}function _main(e,r,o,a,s){null==s&&(s={});const{crc:f}=i,l=t.writeUint,c=t.writeUshort,u=t.writeASCII;let h=8;const d=e.frames.length>1;let A,g=!1,p=33+(d?20:0);if(null!=s.sRGB&&(p+=13),null!=s.pHYs&&(p+=21),null!=s.iCCP&&(A=pako.deflate(s.iCCP),p+=21+A.length+4),3==e.ctype){for(var m=e.plte.length,w=0;w<m;w++)e.plte[w]>>>24!=255&&(g=!0);p+=8+3*m+4+(g?8+1*m+4:0)}for(var v=0;v<e.frames.length;v++){d&&(p+=38),p+=(F=e.frames[v]).cimg.length+12,0!=v&&(p+=4)}p+=12;const b=new Uint8Array(p),y=[137,80,78,71,13,10,26,10];for(w=0;w<8;w++)b[w]=y[w];if(l(b,h,13),h+=4,u(b,h,\"IHDR\"),h+=4,l(b,h,r),h+=4,l(b,h,o),h+=4,b[h]=e.depth,h++,b[h]=e.ctype,h++,b[h]=0,h++,b[h]=0,h++,b[h]=0,h++,l(b,h,f(b,h-17,17)),h+=4,null!=s.sRGB&&(l(b,h,1),h+=4,u(b,h,\"sRGB\"),h+=4,b[h]=s.sRGB,h++,l(b,h,f(b,h-5,5)),h+=4),null!=s.iCCP){const e=13+A.length;l(b,h,e),h+=4,u(b,h,\"iCCP\"),h+=4,u(b,h,\"ICC profile\"),h+=11,h+=2,b.set(A,h),h+=A.length,l(b,h,f(b,h-(e+4),e+4)),h+=4}if(null!=s.pHYs&&(l(b,h,9),h+=4,u(b,h,\"pHYs\"),h+=4,l(b,h,s.pHYs[0]),h+=4,l(b,h,s.pHYs[1]),h+=4,b[h]=s.pHYs[2],h++,l(b,h,f(b,h-13,13)),h+=4),d&&(l(b,h,8),h+=4,u(b,h,\"acTL\"),h+=4,l(b,h,e.frames.length),h+=4,l(b,h,null!=s.loop?s.loop:0),h+=4,l(b,h,f(b,h-12,12)),h+=4),3==e.ctype){l(b,h,3*(m=e.plte.length)),h+=4,u(b,h,\"PLTE\"),h+=4;for(w=0;w<m;w++){const t=3*w,r=e.plte[w],i=255&r,o=r>>>8&255,a=r>>>16&255;b[h+t+0]=i,b[h+t+1]=o,b[h+t+2]=a}if(h+=3*m,l(b,h,f(b,h-3*m-4,3*m+4)),h+=4,g){l(b,h,m),h+=4,u(b,h,\"tRNS\"),h+=4;for(w=0;w<m;w++)b[h+w]=e.plte[w]>>>24&255;h+=m,l(b,h,f(b,h-m-4,m+4)),h+=4}}let E=0;for(v=0;v<e.frames.length;v++){var F=e.frames[v];d&&(l(b,h,26),h+=4,u(b,h,\"fcTL\"),h+=4,l(b,h,E++),h+=4,l(b,h,F.rect.width),h+=4,l(b,h,F.rect.height),h+=4,l(b,h,F.rect.x),h+=4,l(b,h,F.rect.y),h+=4,c(b,h,a[v]),h+=2,c(b,h,1e3),h+=2,b[h]=F.dispose,h++,b[h]=F.blend,h++,l(b,h,f(b,h-30,30)),h+=4);const t=F.cimg;l(b,h,(m=t.length)+(0==v?0:4)),h+=4;const r=h;u(b,h,0==v?\"IDAT\":\"fdAT\"),h+=4,0!=v&&(l(b,h,E++),h+=4),b.set(t,h),h+=m,l(b,h,f(b,r,h-r)),h+=4}return l(b,h,0),h+=4,u(b,h,\"IEND\"),h+=4,l(b,h,f(b,h-4,4)),h+=4,b.buffer}function compressPNG(e,t,r){for(let i=0;i<e.frames.length;i++){const o=e.frames[i];o.rect.width;const a=o.rect.height,s=new Uint8Array(a*o.bpl+a);o.cimg=_filterZero(o.img,a,o.bpp,o.bpl,s,t,r)}}function compress(t,r,i,o,a){const s=a[0],f=a[1],l=a[2],c=a[3],u=a[4],h=a[5];let d=6,A=8,g=255;for(var p=0;p<t.length;p++){const e=new Uint8Array(t[p]);for(var m=e.length,w=0;w<m;w+=4)g&=e[w+3]}const v=255!=g,b=function framize(t,r,i,o,a,s){const f=[];for(var l=0;l<t.length;l++){const h=new Uint8Array(t[l]),A=new Uint32Array(h.buffer);var c;let g=0,p=0,m=r,w=i,v=o?1:0;if(0!=l){const b=s||o||1==l||0!=f[l-2].dispose?1:2;let y=0,E=1e9;for(let e=0;e<b;e++){var u=new Uint8Array(t[l-1-e]);const o=new Uint32Array(t[l-1-e]);let s=r,f=i,c=-1,h=-1;for(let e=0;e<i;e++)for(let t=0;t<r;t++){A[d=e*r+t]!=o[d]&&(t<s&&(s=t),t>c&&(c=t),e<f&&(f=e),e>h&&(h=e))}-1==c&&(s=f=c=h=0),a&&(1==(1&s)&&s--,1==(1&f)&&f--);const v=(c-s+1)*(h-f+1);v<E&&(E=v,y=e,g=s,p=f,m=c-s+1,w=h-f+1)}u=new Uint8Array(t[l-1-y]);1==y&&(f[l-1].dispose=2),c=new Uint8Array(m*w*4),e(u,r,i,c,m,w,-g,-p,0),v=e(h,r,i,c,m,w,-g,-p,3)?1:0,1==v?_prepareDiff(h,r,i,c,{x:g,y:p,width:m,height:w}):e(h,r,i,c,m,w,-g,-p,0)}else c=h.slice(0);f.push({rect:{x:g,y:p,width:m,height:w},img:c,blend:v,dispose:0})}if(o)for(l=0;l<f.length;l++){if(1==(A=f[l]).blend)continue;const e=A.rect,o=f[l-1].rect,s=Math.min(e.x,o.x),c=Math.min(e.y,o.y),u={x:s,y:c,width:Math.max(e.x+e.width,o.x+o.width)-s,height:Math.max(e.y+e.height,o.y+o.height)-c};f[l-1].dispose=1,l-1!=0&&_updateFrame(t,r,i,f,l-1,u,a),_updateFrame(t,r,i,f,l,u,a)}let h=0;if(1!=t.length)for(var d=0;d<f.length;d++){var A;h+=(A=f[d]).rect.width*A.rect.height}return f}(t,r,i,s,f,l),y={},E=[],F=[];if(0!=o){const e=[];for(w=0;w<b.length;w++)e.push(b[w].img.buffer);const t=function concatRGBA(e){let t=0;for(var r=0;r<e.length;r++)t+=e[r].byteLength;const i=new Uint8Array(t);let o=0;for(r=0;r<e.length;r++){const t=new Uint8Array(e[r]),a=t.length;for(let e=0;e<a;e+=4){let r=t[e],a=t[e+1],s=t[e+2];const f=t[e+3];0==f&&(r=a=s=0),i[o+e]=r,i[o+e+1]=a,i[o+e+2]=s,i[o+e+3]=f}o+=a}return i.buffer}(e),r=quantize(t,o);for(w=0;w<r.plte.length;w++)E.push(r.plte[w].est.rgba);let i=0;for(w=0;w<b.length;w++){const e=(B=b[w]).img.length;var _=new Uint8Array(r.inds.buffer,i>>2,e>>2);F.push(_);const t=new Uint8Array(r.abuf,i,e);h&&dither(B.img,B.rect.width,B.rect.height,E,t,_),B.img.set(t),i+=e}}else for(p=0;p<b.length;p++){var B=b[p];const e=new Uint32Array(B.img.buffer);var U=B.rect.width;m=e.length,_=new Uint8Array(m);F.push(_);for(w=0;w<m;w++){const t=e[w];if(0!=w&&t==e[w-1])_[w]=_[w-1];else if(w>U&&t==e[w-U])_[w]=_[w-U];else{let e=y[t];if(null==e&&(y[t]=e=E.length,E.push(t),E.length>=300))break;_[w]=e}}}const C=E.length;C<=256&&0==u&&(A=C<=2?1:C<=4?2:C<=16?4:8,A=Math.max(A,c));for(p=0;p<b.length;p++){(B=b[p]).rect.x,B.rect.y;U=B.rect.width;const e=B.rect.height;let t=B.img;new Uint32Array(t.buffer);let r=4*U,i=4;if(C<=256&&0==u){r=Math.ceil(A*U/8);var I=new Uint8Array(r*e);const o=F[p];for(let t=0;t<e;t++){w=t*r;const e=t*U;if(8==A)for(var Q=0;Q<U;Q++)I[w+Q]=o[e+Q];else if(4==A)for(Q=0;Q<U;Q++)I[w+(Q>>1)]|=o[e+Q]<<4-4*(1&Q);else if(2==A)for(Q=0;Q<U;Q++)I[w+(Q>>2)]|=o[e+Q]<<6-2*(3&Q);else if(1==A)for(Q=0;Q<U;Q++)I[w+(Q>>3)]|=o[e+Q]<<7-1*(7&Q)}t=I,d=3,i=1}else if(0==v&&1==b.length){I=new Uint8Array(U*e*3);const o=U*e;for(w=0;w<o;w++){const e=3*w,r=4*w;I[e]=t[r],I[e+1]=t[r+1],I[e+2]=t[r+2]}t=I,d=2,i=3,r=3*U}B.img=t,B.bpl=r,B.bpp=i}return{ctype:d,depth:A,plte:E,frames:b}}function _updateFrame(t,r,i,o,a,s,f){const l=Uint8Array,c=Uint32Array,u=new l(t[a-1]),h=new c(t[a-1]),d=a+1<t.length?new l(t[a+1]):null,A=new l(t[a]),g=new c(A.buffer);let p=r,m=i,w=-1,v=-1;for(let e=0;e<s.height;e++)for(let t=0;t<s.width;t++){const i=s.x+t,f=s.y+e,l=f*r+i,c=g[l];0==c||0==o[a-1].dispose&&h[l]==c&&(null==d||0!=d[4*l+3])||(i<p&&(p=i),i>w&&(w=i),f<m&&(m=f),f>v&&(v=f))}-1==w&&(p=m=w=v=0),f&&(1==(1&p)&&p--,1==(1&m)&&m--),s={x:p,y:m,width:w-p+1,height:v-m+1};const b=o[a];b.rect=s,b.blend=1,b.img=new Uint8Array(s.width*s.height*4),0==o[a-1].dispose?(e(u,r,i,b.img,s.width,s.height,-s.x,-s.y,0),_prepareDiff(A,r,i,b.img,s)):e(A,r,i,b.img,s.width,s.height,-s.x,-s.y,0)}function _prepareDiff(t,r,i,o,a){e(t,r,i,o,a.width,a.height,-a.x,-a.y,2)}function _filterZero(e,t,r,i,o,a,s){const f=[];let l,c=[0,1,2,3,4];-1!=a?c=[a]:(t*i>5e5||1==r)&&(c=[0]),s&&(l={level:0});const u=UZIP;for(var h=0;h<c.length;h++){for(let a=0;a<t;a++)_filterLine(o,e,a,i,r,c[h]);f.push(u.deflate(o,l))}let d,A=1e9;for(h=0;h<f.length;h++)f[h].length<A&&(d=h,A=f[h].length);return f[d]}function _filterLine(e,t,i,o,a,s){const f=i*o;let l=f+i;if(e[l]=s,l++,0==s)if(o<500)for(var c=0;c<o;c++)e[l+c]=t[f+c];else e.set(new Uint8Array(t.buffer,f,o),l);else if(1==s){for(c=0;c<a;c++)e[l+c]=t[f+c];for(c=a;c<o;c++)e[l+c]=t[f+c]-t[f+c-a]+256&255}else if(0==i){for(c=0;c<a;c++)e[l+c]=t[f+c];if(2==s)for(c=a;c<o;c++)e[l+c]=t[f+c];if(3==s)for(c=a;c<o;c++)e[l+c]=t[f+c]-(t[f+c-a]>>1)+256&255;if(4==s)for(c=a;c<o;c++)e[l+c]=t[f+c]-r(t[f+c-a],0,0)+256&255}else{if(2==s)for(c=0;c<o;c++)e[l+c]=t[f+c]+256-t[f+c-o]&255;if(3==s){for(c=0;c<a;c++)e[l+c]=t[f+c]+256-(t[f+c-o]>>1)&255;for(c=a;c<o;c++)e[l+c]=t[f+c]+256-(t[f+c-o]+t[f+c-a]>>1)&255}if(4==s){for(c=0;c<a;c++)e[l+c]=t[f+c]+256-r(0,t[f+c-o],0)&255;for(c=a;c<o;c++)e[l+c]=t[f+c]+256-r(t[f+c-a],t[f+c-o],t[f+c-a-o])&255}}}function quantize(e,t){const r=new Uint8Array(e),i=r.slice(0),o=new Uint32Array(i.buffer),a=getKDtree(i,t),s=a[0],f=a[1],l=r.length,c=new Uint8Array(l>>2);let u;if(r.length<2e7)for(var h=0;h<l;h+=4){u=getNearest(s,d=r[h]*(1/255),A=r[h+1]*(1/255),g=r[h+2]*(1/255),p=r[h+3]*(1/255)),c[h>>2]=u.ind,o[h>>2]=u.est.rgba}else for(h=0;h<l;h+=4){var d=r[h]*(1/255),A=r[h+1]*(1/255),g=r[h+2]*(1/255),p=r[h+3]*(1/255);for(u=s;u.left;)u=planeDst(u.est,d,A,g,p)<=0?u.left:u.right;c[h>>2]=u.ind,o[h>>2]=u.est.rgba}return{abuf:i.buffer,inds:c,plte:f}}function getKDtree(e,t,r){null==r&&(r=1e-4);const i=new Uint32Array(e.buffer),o={i0:0,i1:e.length,bst:null,est:null,tdst:0,left:null,right:null};o.bst=stats(e,o.i0,o.i1),o.est=estats(o.bst);const a=[o];for(;a.length<t;){let t=0,o=0;for(var s=0;s<a.length;s++)a[s].est.L>t&&(t=a[s].est.L,o=s);if(t<r)break;const f=a[o],l=splitPixels(e,i,f.i0,f.i1,f.est.e,f.est.eMq255);if(f.i0>=l||f.i1<=l){f.est.L=0;continue}const c={i0:f.i0,i1:l,bst:null,est:null,tdst:0,left:null,right:null};c.bst=stats(e,c.i0,c.i1),c.est=estats(c.bst);const u={i0:l,i1:f.i1,bst:null,est:null,tdst:0,left:null,right:null};u.bst={R:[],m:[],N:f.bst.N-c.bst.N};for(s=0;s<16;s++)u.bst.R[s]=f.bst.R[s]-c.bst.R[s];for(s=0;s<4;s++)u.bst.m[s]=f.bst.m[s]-c.bst.m[s];u.est=estats(u.bst),f.left=c,f.right=u,a[o]=c,a.push(u)}a.sort(((e,t)=>t.bst.N-e.bst.N));for(s=0;s<a.length;s++)a[s].ind=s;return[o,a]}function getNearest(e,t,r,i,o){if(null==e.left)return e.tdst=function dist(e,t,r,i,o){const a=t-e[0],s=r-e[1],f=i-e[2],l=o-e[3];return a*a+s*s+f*f+l*l}(e.est.q,t,r,i,o),e;const a=planeDst(e.est,t,r,i,o);let s=e.left,f=e.right;a>0&&(s=e.right,f=e.left);const l=getNearest(s,t,r,i,o);if(l.tdst<=a*a)return l;const c=getNearest(f,t,r,i,o);return c.tdst<l.tdst?c:l}function planeDst(e,t,r,i,o){const{e:a}=e;return a[0]*t+a[1]*r+a[2]*i+a[3]*o-e.eMq}function splitPixels(e,t,r,i,o,a){for(i-=4;r<i;){for(;vecDot(e,r,o)<=a;)r+=4;for(;vecDot(e,i,o)>a;)i-=4;if(r>=i)break;const s=t[r>>2];t[r>>2]=t[i>>2],t[i>>2]=s,r+=4,i-=4}for(;vecDot(e,r,o)>a;)r-=4;return r+4}function vecDot(e,t,r){return e[t]*r[0]+e[t+1]*r[1]+e[t+2]*r[2]+e[t+3]*r[3]}function stats(e,t,r){const i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],o=[0,0,0,0],a=r-t>>2;for(let a=t;a<r;a+=4){const t=e[a]*(1/255),r=e[a+1]*(1/255),s=e[a+2]*(1/255),f=e[a+3]*(1/255);o[0]+=t,o[1]+=r,o[2]+=s,o[3]+=f,i[0]+=t*t,i[1]+=t*r,i[2]+=t*s,i[3]+=t*f,i[5]+=r*r,i[6]+=r*s,i[7]+=r*f,i[10]+=s*s,i[11]+=s*f,i[15]+=f*f}return i[4]=i[1],i[8]=i[2],i[9]=i[6],i[12]=i[3],i[13]=i[7],i[14]=i[11],{R:i,m:o,N:a}}function estats(e){const{R:t}=e,{m:r}=e,{N:i}=e,a=r[0],s=r[1],f=r[2],l=r[3],c=0==i?0:1/i,u=[t[0]-a*a*c,t[1]-a*s*c,t[2]-a*f*c,t[3]-a*l*c,t[4]-s*a*c,t[5]-s*s*c,t[6]-s*f*c,t[7]-s*l*c,t[8]-f*a*c,t[9]-f*s*c,t[10]-f*f*c,t[11]-f*l*c,t[12]-l*a*c,t[13]-l*s*c,t[14]-l*f*c,t[15]-l*l*c],h=u,d=o;let A=[Math.random(),Math.random(),Math.random(),Math.random()],g=0,p=0;if(0!=i)for(let e=0;e<16&&(A=d.multVec(h,A),p=Math.sqrt(d.dot(A,A)),A=d.sml(1/p,A),!(0!=e&&Math.abs(p-g)<1e-9));e++)g=p;const m=[a*c,s*c,f*c,l*c];return{Cov:u,q:m,e:A,L:g,eMq255:d.dot(d.sml(255,m),A),eMq:d.dot(A,m),rgba:(Math.round(255*m[3])<<24|Math.round(255*m[2])<<16|Math.round(255*m[1])<<8|Math.round(255*m[0])<<0)>>>0}}var o={multVec:(e,t)=>[e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3],e[4]*t[0]+e[5]*t[1]+e[6]*t[2]+e[7]*t[3],e[8]*t[0]+e[9]*t[1]+e[10]*t[2]+e[11]*t[3],e[12]*t[0]+e[13]*t[1]+e[14]*t[2]+e[15]*t[3]],dot:(e,t)=>e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3],sml:(e,t)=>[e*t[0],e*t[1],e*t[2],e*t[3]]};UPNG.encode=function encode(e,t,r,i,o,a,s){null==i&&(i=0),null==s&&(s=!1);const f=compress(e,t,r,i,[!1,!1,!1,0,s,!1]);return compressPNG(f,-1),_main(f,t,r,o,a)},UPNG.encodeLL=function encodeLL(e,t,r,i,o,a,s,f){const l={ctype:0+(1==i?0:2)+(0==o?0:4),depth:a,frames:[]},c=(i+o)*a,u=c*t;for(let i=0;i<e.length;i++)l.frames.push({rect:{x:0,y:0,width:t,height:r},img:new Uint8Array(e[i]),blend:0,dispose:1,bpp:Math.ceil(c/8),bpl:Math.ceil(u/8)});return compressPNG(l,0,!0),_main(l,t,r,s,f)},UPNG.encode.compress=compress,UPNG.encode.dither=dither,UPNG.quantize=quantize,UPNG.quantize.getKDtree=getKDtree,UPNG.quantize.getNearest=getNearest}();const r={toArrayBuffer(e,t){const i=e.width,o=e.height,a=i<<2,s=e.getContext(\"2d\").getImageData(0,0,i,o),f=new Uint32Array(s.data.buffer),l=(32*i+31)/32<<2,c=l*o,u=122+c,h=new ArrayBuffer(u),d=new DataView(h),A=1<<20;let g,p,m,w,v=A,b=0,y=0,E=0;function set16(e){d.setUint16(y,e,!0),y+=2}function set32(e){d.setUint32(y,e,!0),y+=4}function seek(e){y+=e}set16(19778),set32(u),seek(4),set32(122),set32(108),set32(i),set32(-o>>>0),set16(1),set16(32),set32(3),set32(c),set32(2835),set32(2835),seek(8),set32(16711680),set32(65280),set32(255),set32(4278190080),set32(1466527264),function convert(){for(;b<o&&v>0;){for(w=122+b*l,g=0;g<a;)v--,p=f[E++],m=p>>>24,d.setUint32(w+g,p<<8|m),g+=4;b++}E<f.length?(v=A,setTimeout(convert,r._dly)):t(h)}()},toBlob(e,t){this.toArrayBuffer(e,(e=>{t(new Blob([e],{type:\"image/bmp\"}))}))},_dly:9};var i={CHROME:\"CHROME\",FIREFOX:\"FIREFOX\",DESKTOP_SAFARI:\"DESKTOP_SAFARI\",IE:\"IE\",IOS:\"IOS\",ETC:\"ETC\"},o={[i.CHROME]:16384,[i.FIREFOX]:11180,[i.DESKTOP_SAFARI]:16384,[i.IE]:8192,[i.IOS]:4096,[i.ETC]:8192};const a=\"undefined\"!=typeof window,s=\"undefined\"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope,f=a&&window.cordova&&window.cordova.require&&window.cordova.require(\"cordova/modulemapper\"),CustomFile=(a||s)&&(f&&f.getOriginalSymbol(window,\"File\")||\"undefined\"!=typeof File&&File),CustomFileReader=(a||s)&&(f&&f.getOriginalSymbol(window,\"FileReader\")||\"undefined\"!=typeof FileReader&&FileReader);function getFilefromDataUrl(e,t,r=Date.now()){return new Promise((i=>{const o=e.split(\",\"),a=o[0].match(/:(.*?);/)[1],s=globalThis.atob(o[1]);let f=s.length;const l=new Uint8Array(f);for(;f--;)l[f]=s.charCodeAt(f);const c=new Blob([l],{type:a});c.name=t,c.lastModified=r,i(c)}))}function getDataUrlFromFile(e){return new Promise(((t,r)=>{const i=new CustomFileReader;i.onload=()=>t(i.result),i.onerror=e=>r(e),i.readAsDataURL(e)}))}function loadImage(e){return new Promise(((t,r)=>{const i=new Image;i.onload=()=>t(i),i.onerror=e=>r(e),i.src=e}))}function getBrowserName(){if(void 0!==getBrowserName.cachedResult)return getBrowserName.cachedResult;let e=i.ETC;const{userAgent:t}=navigator;return/Chrom(e|ium)/i.test(t)?e=i.CHROME:/iP(ad|od|hone)/i.test(t)&&/WebKit/i.test(t)?e=i.IOS:/Safari/i.test(t)?e=i.DESKTOP_SAFARI:/Firefox/i.test(t)?e=i.FIREFOX:(/MSIE/i.test(t)||!0==!!document.documentMode)&&(e=i.IE),getBrowserName.cachedResult=e,getBrowserName.cachedResult}function approximateBelowMaximumCanvasSizeOfBrowser(e,t){const r=getBrowserName(),i=o[r];let a=e,s=t,f=a*s;const l=a>s?s/a:a/s;for(;f>i*i;){const e=(i+a)/2,t=(i+s)/2;e<t?(s=t,a=t*l):(s=e*l,a=e),f=a*s}return{width:a,height:s}}function getNewCanvasAndCtx(e,t){let r,i;try{if(r=new OffscreenCanvas(e,t),i=r.getContext(\"2d\"),null===i)throw new Error(\"getContext of OffscreenCanvas returns null\")}catch(e){r=document.createElement(\"canvas\"),i=r.getContext(\"2d\")}return r.width=e,r.height=t,[r,i]}function drawImageInCanvas(e,t){const{width:r,height:i}=approximateBelowMaximumCanvasSizeOfBrowser(e.width,e.height),[o,a]=getNewCanvasAndCtx(r,i);return t&&/jpe?g/.test(t)&&(a.fillStyle=\"white\",a.fillRect(0,0,o.width,o.height)),a.drawImage(e,0,0,o.width,o.height),o}function isIOS(){return void 0!==isIOS.cachedResult||(isIOS.cachedResult=[\"iPad Simulator\",\"iPhone Simulator\",\"iPod Simulator\",\"iPad\",\"iPhone\",\"iPod\"].includes(navigator.platform)||navigator.userAgent.includes(\"Mac\")&&\"undefined\"!=typeof document&&\"ontouchend\"in document),isIOS.cachedResult}function drawFileInCanvas(e,t={}){return new Promise((function(r,o){let a,s;var $Try_2_Post=function(){try{return s=drawImageInCanvas(a,t.fileType||e.type),r([a,s])}catch(e){return o(e)}},$Try_2_Catch=function(t){try{0;var $Try_3_Catch=function(e){try{throw e}catch(e){return o(e)}};try{let t;return getDataUrlFromFile(e).then((function(e){try{return t=e,loadImage(t).then((function(e){try{return a=e,function(){try{return $Try_2_Post()}catch(e){return o(e)}}()}catch(e){return $Try_3_Catch(e)}}),$Try_3_Catch)}catch(e){return $Try_3_Catch(e)}}),$Try_3_Catch)}catch(e){$Try_3_Catch(e)}}catch(e){return o(e)}};try{if(isIOS()||[i.DESKTOP_SAFARI,i.MOBILE_SAFARI].includes(getBrowserName()))throw new Error(\"Skip createImageBitmap on IOS and Safari\");return createImageBitmap(e).then((function(e){try{return a=e,$Try_2_Post()}catch(e){return $Try_2_Catch()}}),$Try_2_Catch)}catch(e){$Try_2_Catch()}}))}function canvasToFile(e,t,i,o,a=1){return new Promise((function(s,f){let l;if(\"image/png\"===t){let c,u,h;return c=e.getContext(\"2d\"),({data:u}=c.getImageData(0,0,e.width,e.height)),h=UPNG.encode([u.buffer],e.width,e.height,4096*a),l=new Blob([h],{type:t}),l.name=i,l.lastModified=o,$If_4.call(this)}{if(\"image/bmp\"===t)return new Promise((t=>r.toBlob(e,t))).then(function(e){try{return l=e,l.name=i,l.lastModified=o,$If_5.call(this)}catch(e){return f(e)}}.bind(this),f);{if(\"function\"==typeof OffscreenCanvas&&e instanceof OffscreenCanvas)return e.convertToBlob({type:t,quality:a}).then(function(e){try{return l=e,l.name=i,l.lastModified=o,$If_6.call(this)}catch(e){return f(e)}}.bind(this),f);{let d;return d=e.toDataURL(t,a),getFilefromDataUrl(d,i,o).then(function(e){try{return l=e,$If_6.call(this)}catch(e){return f(e)}}.bind(this),f)}function $If_6(){return $If_5.call(this)}}function $If_5(){return $If_4.call(this)}}function $If_4(){return s(l)}}))}function cleanupCanvasMemory(e){e.width=0,e.height=0}function isAutoOrientationInBrowser(){return new Promise((function(e,t){let r,i,o,a,s;return void 0!==isAutoOrientationInBrowser.cachedResult?e(isAutoOrientationInBrowser.cachedResult):(r=\"data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAAAAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAEAAgMBEQACEQEDEQH/xABKAAEAAAAAAAAAAAAAAAAAAAALEAEAAAAAAAAAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAAAAAAAAEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/8H//2Q==\",getFilefromDataUrl(\"data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAAAAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAEAAgMBEQACEQEDEQH/xABKAAEAAAAAAAAAAAAAAAAAAAALEAEAAAAAAAAAAAAAAAAAAAAAAQEAAAAAAAAAAAAAAAAAAAAAEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/8H//2Q==\",\"test.jpg\",Date.now()).then((function(r){try{return i=r,drawFileInCanvas(i).then((function(r){try{return o=r[1],canvasToFile(o,i.type,i.name,i.lastModified).then((function(r){try{return a=r,cleanupCanvasMemory(o),drawFileInCanvas(a).then((function(r){try{return s=r[0],isAutoOrientationInBrowser.cachedResult=1===s.width&&2===s.height,e(isAutoOrientationInBrowser.cachedResult)}catch(e){return t(e)}}),t)}catch(e){return t(e)}}),t)}catch(e){return t(e)}}),t)}catch(e){return t(e)}}),t))}))}function getExifOrientation(e){return new Promise(((t,r)=>{const i=new CustomFileReader;i.onload=e=>{const r=new DataView(e.target.result);if(65496!=r.getUint16(0,!1))return t(-2);const i=r.byteLength;let o=2;for(;o<i;){if(r.getUint16(o+2,!1)<=8)return t(-1);const e=r.getUint16(o,!1);if(o+=2,65505==e){if(1165519206!=r.getUint32(o+=2,!1))return t(-1);const e=18761==r.getUint16(o+=6,!1);o+=r.getUint32(o+4,e);const i=r.getUint16(o,e);o+=2;for(let a=0;a<i;a++)if(274==r.getUint16(o+12*a,e))return t(r.getUint16(o+12*a+8,e))}else{if(65280!=(65280&e))break;o+=r.getUint16(o,!1)}}return t(-1)},i.onerror=e=>r(e),i.readAsArrayBuffer(e)}))}function handleMaxWidthOrHeight(e,t){const{width:r}=e,{height:i}=e,{maxWidthOrHeight:o}=t;let a,s=e;return isFinite(o)&&(r>o||i>o)&&([s,a]=getNewCanvasAndCtx(r,i),r>i?(s.width=o,s.height=i/r*o):(s.width=r/i*o,s.height=o),a.drawImage(e,0,0,s.width,s.height),cleanupCanvasMemory(e)),s}function followExifOrientation(e,t){const{width:r}=e,{height:i}=e,[o,a]=getNewCanvasAndCtx(r,i);switch(t>4&&t<9?(o.width=i,o.height=r):(o.width=r,o.height=i),t){case 2:a.transform(-1,0,0,1,r,0);break;case 3:a.transform(-1,0,0,-1,r,i);break;case 4:a.transform(1,0,0,-1,0,i);break;case 5:a.transform(0,1,1,0,0,0);break;case 6:a.transform(0,1,-1,0,i,0);break;case 7:a.transform(0,-1,-1,0,i,r);break;case 8:a.transform(0,-1,1,0,0,r)}return a.drawImage(e,0,0,r,i),cleanupCanvasMemory(e),o}function compress(e,t,r=0){return new Promise((function(i,o){let a,s,f,l,c,u,h,d,A,g,p,m,w,v,b,y,E,F,_,B;function incProgress(e=5){if(t.signal&&t.signal.aborted)throw t.signal.reason;a+=e,t.onProgress(Math.min(a,100))}function setProgress(e){if(t.signal&&t.signal.aborted)throw t.signal.reason;a=Math.min(Math.max(e,a),100),t.onProgress(a)}return a=r,s=t.maxIteration||10,f=1024*t.maxSizeMB*1024,incProgress(),drawFileInCanvas(e,t).then(function(r){try{return[,l]=r,incProgress(),c=handleMaxWidthOrHeight(l,t),incProgress(),new Promise((function(r,i){var o;if(!(o=t.exifOrientation))return getExifOrientation(e).then(function(e){try{return o=e,$If_2.call(this)}catch(e){return i(e)}}.bind(this),i);function $If_2(){return r(o)}return $If_2.call(this)})).then(function(r){try{return u=r,incProgress(),isAutoOrientationInBrowser().then(function(r){try{return h=r?c:followExifOrientation(c,u),incProgress(),d=t.initialQuality||1,A=t.fileType||e.type,canvasToFile(h,A,e.name,e.lastModified,d).then(function(r){try{{if(g=r,incProgress(),p=g.size>f,m=g.size>e.size,!p&&!m)return setProgress(100),i(g);var a;function $Loop_3(){if(s--&&(b>f||b>w)){let t,r;return t=B?.95*_.width:_.width,r=B?.95*_.height:_.height,[E,F]=getNewCanvasAndCtx(t,r),F.drawImage(_,0,0,t,r),d*=\"image/png\"===A?.85:.95,canvasToFile(E,A,e.name,e.lastModified,d).then((function(e){try{return y=e,cleanupCanvasMemory(_),_=E,b=y.size,setProgress(Math.min(99,Math.floor((v-b)/(v-f)*100))),$Loop_3}catch(e){return o(e)}}),o)}return[1]}return w=e.size,v=g.size,b=v,_=h,B=!t.alwaysKeepResolution&&p,(a=function(e){for(;e;){if(e.then)return void e.then(a,o);try{if(e.pop){if(e.length)return e.pop()?$Loop_3_exit.call(this):e;e=$Loop_3}else e=e.call(this)}catch(e){return o(e)}}}.bind(this))($Loop_3);function $Loop_3_exit(){return cleanupCanvasMemory(_),cleanupCanvasMemory(E),cleanupCanvasMemory(c),cleanupCanvasMemory(h),cleanupCanvasMemory(l),setProgress(100),i(y)}}}catch(u){return o(u)}}.bind(this),o)}catch(e){return o(e)}}.bind(this),o)}catch(e){return o(e)}}.bind(this),o)}catch(e){return o(e)}}.bind(this),o)}))}const l=\"\\nlet scriptImported = false\\nself.addEventListener('message', async (e) => {\\n  const { file, id, imageCompressionLibUrl, options } = e.data\\n  options.onProgress = (progress) => self.postMessage({ progress, id })\\n  try {\\n    if (!scriptImported) {\\n      // console.log('[worker] importScripts', imageCompressionLibUrl)\\n      self.importScripts(imageCompressionLibUrl)\\n      scriptImported = true\\n    }\\n    // console.log('[worker] self', self)\\n    const compressedFile = await imageCompression(file, options)\\n    self.postMessage({ file: compressedFile, id })\\n  } catch (e) {\\n    // console.error('[worker] error', e)\\n    self.postMessage({ error: e.message + '\\\\n' + e.stack, id })\\n  }\\n})\\n\";let c;function compressOnWebWorker(e,t){return new Promise(((r,i)=>{c||(c=function createWorkerScriptURL(e){const t=[];return\"function\"==typeof e?t.push(`(${e})()`):t.push(e),URL.createObjectURL(new Blob(t))}(l));const o=new Worker(c);o.addEventListener(\"message\",(function handler(e){if(t.signal&&t.signal.aborted)o.terminate();else if(void 0===e.data.progress){if(e.data.error)return i(new Error(e.data.error)),void o.terminate();r(e.data.file),o.terminate()}else t.onProgress(e.data.progress)})),o.addEventListener(\"error\",i),t.signal&&t.signal.addEventListener(\"abort\",(()=>{i(t.signal.reason),o.terminate()})),o.postMessage({file:e,imageCompressionLibUrl:t.libURL,options:{...t,onProgress:void 0,signal:void 0}})}))}function imageCompression(e,t){return new Promise((function(r,i){let o,a,s,f,l,c;if(o={...t},s=0,({onProgress:f}=o),o.maxSizeMB=o.maxSizeMB||Number.POSITIVE_INFINITY,l=\"boolean\"!=typeof o.useWebWorker||o.useWebWorker,delete o.useWebWorker,o.onProgress=e=>{s=e,\"function\"==typeof f&&f(s)},!(e instanceof Blob||e instanceof CustomFile))return i(new Error(\"The file given is not an instance of Blob or File\"));if(!/^image/.test(e.type))return i(new Error(\"The file given is not an image\"));if(c=\"undefined\"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope,!l||\"function\"!=typeof Worker||c)return compress(e,o).then(function(e){try{return a=e,$If_4.call(this)}catch(e){return i(e)}}.bind(this),i);var u=function(){try{return $If_4.call(this)}catch(e){return i(e)}}.bind(this),$Try_1_Catch=function(t){try{return compress(e,o).then((function(e){try{return a=e,u()}catch(e){return i(e)}}),i)}catch(e){return i(e)}};try{return o.libURL=o.libURL||\"https://cdn.jsdelivr.net/npm/[email protected]/dist/browser-image-compression.js\",compressOnWebWorker(e,o).then((function(e){try{return a=e,u()}catch(e){return $Try_1_Catch()}}),$Try_1_Catch)}catch(e){$Try_1_Catch()}function $If_4(){try{a.name=e.name,a.lastModified=e.lastModified}catch(e){}try{o.preserveExif&&\"image/jpeg\"===e.type&&(!o.fileType||o.fileType&&o.fileType===e.type)&&(a=copyExifWithoutOrientation(e,a))}catch(e){}return r(a)}}))}imageCompression.getDataUrlFromFile=getDataUrlFromFile,imageCompression.getFilefromDataUrl=getFilefromDataUrl,imageCompression.loadImage=loadImage,imageCompression.drawImageInCanvas=drawImageInCanvas,imageCompression.drawFileInCanvas=drawFileInCanvas,imageCompression.canvasToFile=canvasToFile,imageCompression.getExifOrientation=getExifOrientation,imageCompression.handleMaxWidthOrHeight=handleMaxWidthOrHeight,imageCompression.followExifOrientation=followExifOrientation,imageCompression.cleanupCanvasMemory=cleanupCanvasMemory,imageCompression.isAutoOrientationInBrowser=isAutoOrientationInBrowser,imageCompression.approximateBelowMaximumCanvasSizeOfBrowser=approximateBelowMaximumCanvasSizeOfBrowser,imageCompression.copyExifWithoutOrientation=copyExifWithoutOrientation,imageCompression.getBrowserName=getBrowserName,imageCompression.version=\"2.0.2\";\n//# sourceMappingURL=browser-image-compression.mjs.map\n\n\n//# sourceURL=webpack:///./node_modules/browser-image-compression/dist/browser-image-compression.mjs?");
     90
     91/***/ }),
     92
     93/***/ "./node_modules/wasm-feature-detect/dist/esm/index.js":
     94/*!************************************************************!*\
     95  !*** ./node_modules/wasm-feature-detect/dist/esm/index.js ***!
     96  \************************************************************/
     97/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
     98
     99eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"bigInt\": () => (/* binding */ bigInt),\n/* harmony export */   \"bulkMemory\": () => (/* binding */ bulkMemory),\n/* harmony export */   \"exceptions\": () => (/* binding */ exceptions),\n/* harmony export */   \"extendedConst\": () => (/* binding */ extendedConst),\n/* harmony export */   \"gc\": () => (/* binding */ gc),\n/* harmony export */   \"memory64\": () => (/* binding */ memory64),\n/* harmony export */   \"multiValue\": () => (/* binding */ multiValue),\n/* harmony export */   \"mutableGlobals\": () => (/* binding */ mutableGlobals),\n/* harmony export */   \"referenceTypes\": () => (/* binding */ referenceTypes),\n/* harmony export */   \"relaxedSimd\": () => (/* binding */ relaxedSimd),\n/* harmony export */   \"saturatedFloatToInt\": () => (/* binding */ saturatedFloatToInt),\n/* harmony export */   \"signExtensions\": () => (/* binding */ signExtensions),\n/* harmony export */   \"simd\": () => (/* binding */ simd),\n/* harmony export */   \"streamingCompilation\": () => (/* binding */ streamingCompilation),\n/* harmony export */   \"tailCall\": () => (/* binding */ tailCall),\n/* harmony export */   \"threads\": () => (/* binding */ threads)\n/* harmony export */ });\nconst bigInt=()=>(async e=>{try{return(await WebAssembly.instantiate(e)).instance.exports.b(BigInt(0))===BigInt(0)}catch(e){return!1}})(new Uint8Array([0,97,115,109,1,0,0,0,1,6,1,96,1,126,1,126,3,2,1,0,7,5,1,1,98,0,0,10,6,1,4,0,32,0,11])),bulkMemory=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,5,3,1,0,1,10,14,1,12,0,65,0,65,0,65,0,252,10,0,0,11])),exceptions=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,8,1,6,0,6,64,25,11,11])),extendedConst=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,5,3,1,0,1,11,9,1,0,65,1,65,2,106,11,0])),gc=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,10,2,95,1,125,0,96,0,1,107,0,3,2,1,1,10,12,1,10,0,67,0,0,0,0,251,7,0,11])),memory64=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,5,3,1,4,1])),multiValue=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,6,1,96,0,2,127,127,3,2,1,0,10,8,1,6,0,65,0,65,0,11])),mutableGlobals=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,2,8,1,1,97,1,98,3,127,1,6,6,1,127,1,65,0,11,7,5,1,1,97,3,1])),referenceTypes=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,7,1,5,0,208,112,26,11])),relaxedSimd=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,5,1,96,0,1,123,3,2,1,0,10,15,1,13,0,65,1,253,15,65,2,253,15,253,128,2,11])),saturatedFloatToInt=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,12,1,10,0,67,0,0,0,0,252,0,26,11])),signExtensions=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,8,1,6,0,65,0,192,26,11])),simd=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,5,1,96,0,1,123,3,2,1,0,10,10,1,8,0,65,0,253,15,253,98,11])),streamingCompilation=()=>(async()=>\"compileStreaming\"in WebAssembly)(),tailCall=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,6,1,4,0,18,0,11])),threads=()=>(async e=>{try{return\"undefined\"!=typeof MessageChannel&&(new MessageChannel).port1.postMessage(new SharedArrayBuffer(1)),WebAssembly.validate(e)}catch(e){return!1}})(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,5,4,1,3,1,1,10,11,1,9,0,65,0,254,16,2,0,26,11]));\n\n\n//# sourceURL=webpack:///./node_modules/wasm-feature-detect/dist/esm/index.js?");
    50100
    51101/***/ })
     
    93143/******/    })();
    94144/******/   
     145/******/    /* webpack/runtime/ensure chunk */
     146/******/    (() => {
     147/******/        __webpack_require__.f = {};
     148/******/        // This file contains only the entry chunk.
     149/******/        // The chunk loading function for additional chunks
     150/******/        __webpack_require__.e = (chunkId) => {
     151/******/            return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
     152/******/                __webpack_require__.f[key](chunkId, promises);
     153/******/                return promises;
     154/******/            }, []));
     155/******/        };
     156/******/    })();
     157/******/   
    95158/******/    /* webpack/runtime/get javascript chunk filename */
    96159/******/    (() => {
     
    117180/******/    (() => {
    118181/******/        __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
     182/******/    })();
     183/******/   
     184/******/    /* webpack/runtime/load script */
     185/******/    (() => {
     186/******/        var inProgress = {};
     187/******/        // data-webpack is not used as build has no uniqueName
     188/******/        // loadScript function to load a script via script tag
     189/******/        __webpack_require__.l = (url, done, key, chunkId) => {
     190/******/            if(inProgress[url]) { inProgress[url].push(done); return; }
     191/******/            var script, needAttach;
     192/******/            if(key !== undefined) {
     193/******/                var scripts = document.getElementsByTagName("script");
     194/******/                for(var i = 0; i < scripts.length; i++) {
     195/******/                    var s = scripts[i];
     196/******/                    if(s.getAttribute("src") == url) { script = s; break; }
     197/******/                }
     198/******/            }
     199/******/            if(!script) {
     200/******/                needAttach = true;
     201/******/                script = document.createElement('script');
     202/******/       
     203/******/                script.charset = 'utf-8';
     204/******/                script.timeout = 120;
     205/******/                if (__webpack_require__.nc) {
     206/******/                    script.setAttribute("nonce", __webpack_require__.nc);
     207/******/                }
     208/******/       
     209/******/                script.src = url;
     210/******/            }
     211/******/            inProgress[url] = [done];
     212/******/            var onScriptComplete = (prev, event) => {
     213/******/                // avoid mem leaks in IE.
     214/******/                script.onerror = script.onload = null;
     215/******/                clearTimeout(timeout);
     216/******/                var doneFns = inProgress[url];
     217/******/                delete inProgress[url];
     218/******/                script.parentNode && script.parentNode.removeChild(script);
     219/******/                doneFns && doneFns.forEach((fn) => (fn(event)));
     220/******/                if(prev) return prev(event);
     221/******/            }
     222/******/            var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);
     223/******/            script.onerror = onScriptComplete.bind(null, script.onerror);
     224/******/            script.onload = onScriptComplete.bind(null, script.onload);
     225/******/            needAttach && document.head.appendChild(script);
     226/******/        };
    119227/******/    })();
    120228/******/   
     
    161269/******/        };
    162270/******/       
    163 /******/        // no chunk on demand loading
     271/******/        __webpack_require__.f.j = (chunkId, promises) => {
     272/******/                // JSONP chunk loading for javascript
     273/******/                var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
     274/******/                if(installedChunkData !== 0) { // 0 means "already installed".
     275/******/       
     276/******/                    // a Promise means "currently loading".
     277/******/                    if(installedChunkData) {
     278/******/                        promises.push(installedChunkData[2]);
     279/******/                    } else {
     280/******/                        if(true) { // all chunks have JS
     281/******/                            // setup Promise in chunk cache
     282/******/                            var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
     283/******/                            promises.push(installedChunkData[2] = promise);
     284/******/       
     285/******/                            // start chunk loading
     286/******/                            var url = __webpack_require__.p + __webpack_require__.u(chunkId);
     287/******/                            // create error before stack unwound to get useful stacktrace later
     288/******/                            var error = new Error();
     289/******/                            var loadingEnded = (event) => {
     290/******/                                if(__webpack_require__.o(installedChunks, chunkId)) {
     291/******/                                    installedChunkData = installedChunks[chunkId];
     292/******/                                    if(installedChunkData !== 0) installedChunks[chunkId] = undefined;
     293/******/                                    if(installedChunkData) {
     294/******/                                        var errorType = event && (event.type === 'load' ? 'missing' : event.type);
     295/******/                                        var realSrc = event && event.target && event.target.src;
     296/******/                                        error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
     297/******/                                        error.name = 'ChunkLoadError';
     298/******/                                        error.type = errorType;
     299/******/                                        error.request = realSrc;
     300/******/                                        installedChunkData[1](error);
     301/******/                                    }
     302/******/                                }
     303/******/                            };
     304/******/                            __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId);
     305/******/                        } else installedChunks[chunkId] = 0;
     306/******/                    }
     307/******/                }
     308/******/        };
    164309/******/       
    165310/******/        // no prefetching
     
    173318/******/        // no on chunks loaded
    174319/******/       
    175 /******/        // no jsonp function
     320/******/        // install a JSONP callback for chunk loading
     321/******/        var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
     322/******/            var [chunkIds, moreModules, runtime] = data;
     323/******/            // add "moreModules" to the modules object,
     324/******/            // then flag all "chunkIds" as loaded and fire callback
     325/******/            var moduleId, chunkId, i = 0;
     326/******/            if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
     327/******/                for(moduleId in moreModules) {
     328/******/                    if(__webpack_require__.o(moreModules, moduleId)) {
     329/******/                        __webpack_require__.m[moduleId] = moreModules[moduleId];
     330/******/                    }
     331/******/                }
     332/******/                if(runtime) var result = runtime(__webpack_require__);
     333/******/            }
     334/******/            if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
     335/******/            for(;i < chunkIds.length; i++) {
     336/******/                chunkId = chunkIds[i];
     337/******/                if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
     338/******/                    installedChunks[chunkId][0]();
     339/******/                }
     340/******/                installedChunks[chunkId] = 0;
     341/******/            }
     342/******/       
     343/******/        }
     344/******/       
     345/******/        var chunkLoadingGlobal = self["webpackChunk"] = self["webpackChunk"] || [];
     346/******/        chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
     347/******/        chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
    176348/******/    })();
    177349/******/   
  • squeeze/trunk/assets/templates/path-list-item.html

    r3238524 r3345284  
    1 <input type="text" class="squeeze-path-list__item" value="{{folder}}" readonly />
     1<div class="squeeze-path-list__item">
     2    <input name="squeeze-path-list__item[]" type="text" class="squeeze-path-list__input"
     3        value="{{folder}}" readonly />
     4    <button name="squeeze_remove_path_button" class="squeeze-path-list__remove" type="button">
     5        <svg class="squeeze-icon">
     6            <use xlink:href="#close-round-icon"></use>
     7        </svg>
     8    </button>
     9</div>
  • squeeze/trunk/inc/handlers.php

    r3311866 r3345284  
    5353        }
    5454        $base64 = sanitize_text_field( wp_unslash( $_POST["base64"] ) );
    55         $sizes = ( isset( $_POST["base64Sizes"] ) ? $_POST["base64Sizes"] : array() );
     55        $sizes = ( isset( $_POST["base64Sizes"] ) ? (array) $_POST["base64Sizes"] : array() );
    5656        // DO NOT SANITIZE because it's an array
    5757        $base64_webp = ( isset( $_POST["base64Webp"] ) ? sanitize_text_field( wp_unslash( $_POST["base64Webp"] ) ) : '' );
    58         $sizes_webp = ( isset( $_POST["base64SizesWebp"] ) ? $_POST["base64SizesWebp"] : array() );
     58        $sizes_webp = ( isset( $_POST["base64SizesWebp"] ) ? (array) $_POST["base64SizesWebp"] : array() );
    5959        $file_format = ( isset( $_POST["format"] ) ? sanitize_text_field( wp_unslash( $_POST["format"] ) ) : '' );
    6060        $filename = ( isset( $_POST["filename"] ) ? sanitize_text_field( wp_unslash( $_POST["filename"] ) ) : '' );
    6161        $extension = pathinfo( $filename, PATHINFO_EXTENSION );
    6262        $image_formats = self::$SqueezeHelpers->get_image_formats();
     63        $original_file = ( isset( $_FILES['originalFile'] ) ? $_FILES['originalFile'] : null );
    6364        if ( !in_array( $extension, $image_formats ) || empty( $file_format ) ) {
    6465            wp_send_json_error( '❌ ' . esc_html__( 'Invalid image format', 'squeeze' ) );
     
    7475        }
    7576        $is_backup_original = self::$SqueezeHelpers->get_option( 'backup_original' );
     77        $is_direct_webp = self::$SqueezeHelpers->get_option( 'direct_webp' );
    7678        // Upload path.
    7779        $upload_path = self::$SqueezeHelpers->get_upload_path( $attach_id, $filename, $url );
    7880        $decoded = self::$SqueezeHelpers->decode_base64_image( $base64, $file_format );
     81        $webp_file_path = '';
     82        $old_metadata = wp_get_attachment_metadata( $attach_id );
     83        $old_filename = $filename;
     84        // in case the original file is not webp and we should convert it to webp
     85        // we need to generate a new filename for the webp file
     86        // and update its url
     87        if ( $file_format === 'webp' && $extension !== 'webp' && $is_direct_webp && $process !== 'path' ) {
     88            $file = get_attached_file( $attach_id );
     89            // get the _wp_attached_file meta value which looks like "2023/10/image.jpg"
     90            $path_info = pathinfo( $file );
     91            $dirname = $path_info['dirname'];
     92            //Get a unique filename in that folder
     93            $unique_filename = wp_unique_filename( $dirname, sanitize_file_name( preg_replace( '/\\.[^.]+$/', '.webp', $filename ) ) );
     94            $webp_file_path = trailingslashit( $dirname ) . $unique_filename;
     95            // looks like "E:\Extra-Time\test/wp-content/uploads/2023/10/image.webp"
     96            $filename = basename( $unique_filename );
     97            $url = str_replace( ABSPATH, home_url( '/' ), $webp_file_path );
     98            // convert file path to URL
     99            //wp_send_json_error($filename . ' ' . $url . ' ' . $webp_file_path);
     100        }
     101        if ( $original_file ) {
     102            $sizes['original']['original_size'] = $original_file['size'];
     103        } else {
     104            $sizes['original']['original_size'] = wp_filesize( $upload_path . $filename );
     105        }
     106        $sizes['original']['compressed_size'] = strlen( $decoded );
     107        // check if compressed_size is greater than original_size
     108        if ( $sizes['original']['compressed_size'] > $sizes['original']['original_size'] ) {
     109            wp_send_json_error( '❌ ' . esc_html__( 'Compressed image size is greater than original size', 'squeeze' ) );
     110        }
    79111        if ( $is_backup_original && $process !== 'path' ) {
    80112            // do not backup for non library images
    81113            // backup original
    82             $backup_original_image = self::$SqueezeHelpers->backup_original_image( $upload_path, $filename );
     114            if ( $original_file ) {
     115                $backup_original_image = self::$SqueezeHelpers->backup_original_image( $upload_path, $filename, $original_file['tmp_name'] );
     116            } else {
     117                $backup_original_image = self::$SqueezeHelpers->backup_original_image( $upload_path, $filename );
     118            }
    83119            if ( is_wp_error( $backup_original_image ) ) {
    84120                wp_send_json_error( $backup_original_image->get_error_message() );
    85121            }
    86122        }
    87         $sizes['original']['original_size'] = wp_filesize( $upload_path . $filename );
    88         $sizes['original']['compressed_size'] = strlen( $decoded );
    89123        // Save the image in the uploads directory.
    90124        $upload_image = self::$SqueezeHelpers->upload_image( $upload_path, $filename, $decoded );
     
    97131                wp_send_json_error( $upload_webp->get_error_message() );
    98132            }
    99             self::$SqueezeHelpers->upload_webp_thumbs( $upload_path, $sizes_webp );
     133            $upload_webp_thumbs = self::$SqueezeHelpers->upload_webp_thumbs( $upload_path, $sizes_webp );
    100134            // skip handling errors for webp thumbs, because they are not always required
    101135        }
    102136        // upload thumbnails
    103137        if ( $process !== 'path' ) {
    104             $sizes = self::$SqueezeHelpers->upload_image_thumbs( $upload_path, $sizes, $file_format );
     138            if ( $file_format === 'webp' && $extension !== 'webp' && $is_direct_webp ) {
     139                update_attached_file( $attach_id, $webp_file_path );
     140                // update the _wp_attached_file meta value to the new webp file path
     141                wp_update_post( [
     142                    'ID'             => $attach_id,
     143                    'post_mime_type' => 'image/webp',
     144                ] );
     145                $metadata = wp_generate_attachment_metadata( $attach_id, $webp_file_path );
     146                wp_update_attachment_metadata( $attach_id, $metadata );
     147            }
     148            $sizes = self::$SqueezeHelpers->upload_image_thumbs(
     149                $upload_path,
     150                $sizes,
     151                $file_format,
     152                $filename
     153            );
     154            //wp_send_json_error( print_r($sizes, true) );
    105155            if ( is_wp_error( $sizes ) ) {
    106156                wp_send_json_error( $sizes->get_error_message() );
     157            }
     158            if ( $file_format === 'webp' && $extension !== 'webp' && $is_direct_webp ) {
     159                // remove webp images from the squeeze-webp directory
     160                $this->delete_webp_images( $attach_id, $old_metadata );
     161                // remove original JPG/PNG file if it exists
     162                foreach ( $old_metadata['sizes'] as $size_name => $size_data ) {
     163                    $old_size_filename = $size_data['file'];
     164                    wp_delete_file( $upload_path . $old_size_filename );
     165                }
     166                $old_scaled_filename = basename( $old_metadata['file'] );
     167                wp_delete_file( $upload_path . $old_scaled_filename );
     168                $old_original_path = $upload_path . $old_filename;
     169                wp_delete_file( $old_original_path );
     170                if ( $is_backup_original ) {
     171                    // delete old backup file
     172                    $backup_filename = self::$SqueezeHelpers->create_backup_filename( $old_filename );
     173                    $old_backup_path = $upload_path . $backup_filename;
     174                    wp_delete_file( $old_backup_path );
     175                }
    107176            }
    108177            update_post_meta( $attach_id, "squeeze_is_compressed", true );
     
    114183                'uncompressed_images' => $uncompressed_images,
    115184            ) );
    116             wp_send_json_success( $response_msg );
    117             /*wp_send_json_success(array(
    118                         'message' => $response_msg,
    119                         'sizes' => $sizes,
    120                     ));*/
     185            //wp_send_json_error( print_r($sizes, true) );
     186            //wp_send_json_success($response_msg .  print_r($sizes['scaled']['url'], true) . ' | ' . $filename . ' | ' . pathinfo($filename, PATHINFO_FILENAME) );
     187            //wp_send_json_success($response_msg);
     188            wp_send_json_success( array(
     189                'message'  => $response_msg,
     190                'sizes'    => $sizes,
     191                'filename' => $filename,
     192                'url'      => $url,
     193            ) );
    121194        } else {
    122195            wp_send_json_success( '✅ ' . esc_html__( 'Squeezed successfully', 'squeeze' ) );
     
    134207        if ( $can_restore ) {
    135208            $is_restore_attachment = self::$SqueezeHelpers->restore_attachment( $attach_id );
    136             if ( $is_restore_attachment ) {
     209            if ( !is_wp_error( $is_restore_attachment ) ) {
    137210                wp_send_json_success( '✅ ' . esc_html__( 'Restored successfully', 'squeeze' ) );
    138211            } else {
     
    245318    }
    246319
    247     public function delete_webp_images( $attach_id ) {
     320    public function delete_webp_images( $attach_id, $old_metadata = null ) {
    248321        $original_img_path = wp_get_original_image_path( (int) $attach_id );
    249         $attachment_data = wp_get_attachment_metadata( $attach_id );
     322        $attachment_data = ( $old_metadata ? $old_metadata : wp_get_attachment_metadata( $attach_id ) );
    250323        $delete_webp_images = self::$SqueezeHelpers->delete_webp_images( $original_img_path, $attachment_data );
    251324        return $delete_webp_images;
     
    502575            return $content;
    503576        }
     577        $content_folder = basename( WP_CONTENT_DIR );
    504578        // Regular expression to find JPG and PNG images in src and srcset attributes.
    505         $pattern = '/(\\/\\/.*?\\/wp-content\\/)([^"\\s]+\\.(jpg|jpeg|png))(\\?[^"\\s]*)?/i';
     579        $pattern = '/(\\/\\/.*?\\/' . preg_quote( $content_folder, '/' ) . '\\/)([^"\\s]+\\.(jpg|jpeg|png))(\\?[^"\\s]*)?/i';
    506580        // Callback function to replace the URLs.
    507581        $callback = function ( $matches ) {
     
    556630            $filesize = wp_filesize( $attachment_path );
    557631            $filesize_human = size_format( $filesize );
     632            $image_info = getimagesize( $attachment_path );
     633            $image_width = $image_info[0];
     634            $image_height = $image_info[1];
    558635            $response['filesizeInBytes'] = $filesize;
    559636            $response['filesizeHumanReadable'] = $filesize_human;
     637            $response['width'] = $image_width;
     638            $response['height'] = $image_height;
    560639        }
    561640        return $response;
     
    572651            $attachment_path = get_attached_file( $attachment_id );
    573652            $filesize = wp_filesize( $attachment_path );
     653            $image_info = getimagesize( $attachment_path );
     654            $image_width = $image_info[0];
     655            $image_height = $image_info[1];
    574656            $data['filesize'] = $filesize;
     657            $data['width'] = $image_width;
     658            $data['height'] = $image_height;
    575659        }
    576660        return $data;
  • squeeze/trunk/inc/helpers.php

    r3311866 r3345284  
    2424    }
    2525
    26     public function backup_original_image($upload_path, $filename) {
     26    public function create_backup_filename($filename) {
    2727        $backup_filename = preg_replace("/(\.(?!.*\.))/", '.bak.', $filename);
     28        return $backup_filename;
     29    }
     30
     31    public function backup_original_image($upload_path, $filename, $original_file = null) {
     32        if ( ! function_exists( 'WP_Filesystem' ) ) {
     33            require_once ABSPATH . 'wp-admin/includes/file.php';
     34        }
     35
     36        global $wp_filesystem;
     37
     38        // Initialize the filesystem (this populates $wp_filesystem)
     39        WP_Filesystem();
     40
     41        if ( ! $wp_filesystem || ! method_exists( $wp_filesystem, 'copy' ) ) {
     42            return new \WP_Error( 'squeeze_filesystem_api_error', 'Filesystem API is not available or failed to initialize.' );
     43        }
     44
     45        $backup_filename = $this->create_backup_filename($filename);
    2846        if (!file_exists($upload_path . $backup_filename)) {
    2947            try {
    30                 $upload_backup_file = copy($upload_path . $filename, $upload_path . $backup_filename);
     48                if (!$original_file) {
     49                    $upload_backup_file = $wp_filesystem->copy($upload_path . $filename, $upload_path . $backup_filename, true);
     50                } else {
     51                    $upload_backup_file = move_uploaded_file($original_file, $upload_path . $backup_filename);
     52                }
    3153            } catch (\Exception $e) {
    3254                return new \WP_Error('squeeze_backup_original_image_failed', '❌ '.esc_html__('Backup original image failed', 'squeeze') . ': '. $upload_path . $backup_filename);
     
    4365    }
    4466
    45     public function upload_image($upload_path, $filename, $decoded_image) {
     67    public function upload_image($upload_path, $filename, $decoded_image, $is_file = false) {
     68        if ( ! function_exists( 'WP_Filesystem' ) ) {
     69            require_once ABSPATH . 'wp-admin/includes/file.php';
     70        }
     71
    4672        global $wp_filesystem;
    47         if (empty($wp_filesystem)) {
    48             require_once(ABSPATH . '/wp-admin/includes/file.php');
    49             WP_Filesystem();
    50         }
    51         $upload_file = $wp_filesystem->put_contents($upload_path . $filename, $decoded_image);
     73
     74        // Initialize the filesystem (this populates $wp_filesystem)
     75        WP_Filesystem();
     76
     77        if ( ! $wp_filesystem || ! method_exists( $wp_filesystem, 'copy' ) ) {
     78            return new \WP_Error('squeeze_filesystem_api_error', 'Filesystem API is not available or failed to initialize.');
     79        }
     80
     81        if ($is_file) {
     82            $upload_file = move_uploaded_file($decoded_image, $upload_path . $filename);
     83        } else {
     84            $upload_file = $wp_filesystem->put_contents($upload_path . $filename, $decoded_image);
     85        }
    5286        if (!$upload_file) {
    5387            return new \WP_Error('squeeze_upload_image_failed', '❌ '.esc_html__('Upload image failed', 'squeeze') . ': <br>upload_path: ' . $upload_path . '<br>filename: ' . $filename);
     
    5791    }
    5892
    59     public function upload_image_thumbs($upload_path, $sizes, $file_format) {
     93    public function upload_image_thumbs($upload_path, $sizes, $file_format, $filename = '') {
    6094        if (!is_array($sizes) || empty($sizes)) {
    6195            return new \WP_Error('squeeze_upload_image_thumbs_failed', '❌ '.esc_html__('No image data found', 'squeeze'));
    6296        }
     97
     98        if ( ! function_exists( 'WP_Filesystem' ) ) {
     99            require_once ABSPATH . 'wp-admin/includes/file.php';
     100        }
     101
    63102        global $wp_filesystem;
    64         if (empty($wp_filesystem)) {
    65             require_once(ABSPATH . '/wp-admin/includes/file.php');
    66             WP_Filesystem();
    67         }
     103
     104        // Initialize the filesystem (this populates $wp_filesystem)
     105        WP_Filesystem();
     106
     107        if ( ! $wp_filesystem || ! method_exists( $wp_filesystem, 'copy' ) ) {
     108            return new \WP_Error('squeeze_filesystem_api_error', 'Filesystem API is not available or failed to initialize.');
     109        }
     110       
     111        $is_direct_webp = $this->get_option('direct_webp');
    68112        foreach ($sizes as $size_name => $size_data) {
    69113            if ($size_name === 'original') {
    70114                continue;
    71115            }
     116            $new_size_url = '';
     117            if ($file_format === 'webp' && $is_direct_webp && $filename) {
     118                //$size_data['url'] = preg_replace('/\.[^.]+$/', '.webp', $size_data['url']);
     119
     120                // remove extension from filename if it exists
     121                //$origin_filename = $filename;
     122                $new_filename = pathinfo($filename, PATHINFO_FILENAME); // DO NOT appennd to the $filename, causes bug with complex filenames
     123
     124
     125                // replace the filename in the URL before the last dash
     126                // e.g. 'http://localhost/test/wp-content/uploads/2025/08/image-thumbxsize.jpg' becomes
     127                // 'http://localhost/test/wp-content/uploads/2025/08/$new_filename-thumbxsize.webp'
     128
     129                // 1. Match and capture path, base filename, suffix, and extension
     130                //if (preg_match('/^(.*\/)(.+)-([^-\/]+)\.((?:jpe?g|png))$/i', $size_data['url'], $m)) {
     131                if (preg_match('#^(?P<path>.*/wp-content/uploads/.*/)(?P<base>[^/]+?)(?P<suffix>-(?:\d+x\d+|scaled|rotated))?\.(?P<ext>jpe?g|png)$#i', $size_data['url'], $m)) {
     132                    // $m[1] = the full path including trailing slash
     133                    // $m[2] = the base filename (before the dash)
     134                    // $m[3] = the suffix (between dash and extension)
     135                    // $m[4] = the original extension
     136
     137                    $path      = $m[1];
     138                    //$new_filename  = $m[2];   // <-- this is your variable
     139                    $suffix    = $m[3];
     140
     141                    // 2. Rebuild URL with .webp
     142                    $new_size_url = "{$path}{$new_filename}{$suffix}.webp";
     143                }
     144            }
    72145            $size_base64 = sanitize_text_field($size_data['base64']);
    73146            $size_decoded = $this->decode_base64_image($size_base64, $file_format);
    74             $size_filename = basename(sanitize_url($size_data['url']));
     147            $size_filename = basename(sanitize_url($new_size_url ? $new_size_url : $size_data['url']));
    75148            if ($size_name === 'full') {
    76149                $size_name = 'scaled';
     
    88161    }
    89162
    90     public function upload_webp($upload_path, $base64_webp, $filename) {
     163    public function upload_webp($upload_path, $base64_webp, $filename, $is_file = false) {
    91164        if (!$base64_webp) {
    92165            return new \WP_Error('squeeze_upload_webp_failed', '❌ '.esc_html__('No WebP data found', 'squeeze'));
     
    97170            wp_mkdir_p($upload_webp_path);
    98171        }
    99         $decoded_webp = $this->decode_base64_image($base64_webp, 'webp');
     172        $decoded_webp = $is_file ? $base64_webp : $this->decode_base64_image($base64_webp, 'webp');
    100173        $filename_webp = $filename.'.webp';
    101         $upload_file_webp = $this->upload_image($upload_webp_path, $filename_webp, $decoded_webp);
     174        $upload_file_webp = $this->upload_image($upload_webp_path, $filename_webp, $decoded_webp, $is_file);
    102175
    103176        return $upload_file_webp;
     
    127200
    128201    public function convert_image_path_to_webp_path($image_path) {
    129         $webp_path = preg_replace('/wp-content[\/\\\\]/', 'wp-content/squeeze-webp/', $image_path, 1);
    130         return str_replace(['/', '\\'], '/', $webp_path);
     202        //$webp_path = preg_replace('/wp-content[\/\\\\]/', 'wp-content/squeeze-webp/', $image_path, 1);
     203        //return str_replace(['/', '\\'], '/', $webp_path);
     204
     205        // Grab your actual content folder name (e.g. "wp-content" or custom)
     206        $content_folder = basename( WP_CONTENT_DIR );
     207
     208        // Build a regex to match that folder plus a slash or backslash
     209        $pattern     = sprintf(
     210            '#%s[\\/\\\\]#',
     211            preg_quote( $content_folder, '#' )
     212        );
     213        // Replace with "{folder}/squeeze-webp/"
     214        $replacement = $content_folder . '/squeeze-webp/';
     215
     216        // Do the one-time replacement…
     217        $webp_path = preg_replace( $pattern, $replacement, $image_path, 1 );
     218
     219        // Normalize backslashes to forward slashes and return
     220        return str_replace( '\\', '/', $webp_path );
    131221    }
    132222
     
    140230
    141231    public function restore_attachment($attach_id, $is_bulk = false) {
     232        if ( ! function_exists( 'WP_Filesystem' ) ) {
     233            require_once ABSPATH . 'wp-admin/includes/file.php';
     234        }
     235
     236        global $wp_filesystem;
     237
     238        // Initialize the filesystem (this populates $wp_filesystem)
     239        WP_Filesystem();
     240
     241        if ( ! $wp_filesystem || ! method_exists( $wp_filesystem, 'copy' ) ) {
     242            if ($is_bulk) {
     243                wp_die( 'Filesystem API is not available or failed to initialize.' );
     244            } else {
     245                return new \WP_Error('squeeze_filesystem_api_error', 'Filesystem API is not available or failed to initialize.');
     246            }
     247        }
     248
    142249        $original_img_path = wp_get_original_image_path($attach_id);
    143250        $backup_img_path = preg_replace("/(\.(?!.*\.))/", '.bak.', $original_img_path);
     
    153260        }
    154261
    155         $backup_img = copy($backup_img_path, $original_img_path);
     262        $backup_img = $wp_filesystem->copy($backup_img_path, $original_img_path, true);
    156263        if (!$backup_img) {
    157264            $error_message = '❌ ' . esc_html__('Restore original image failed', 'squeeze');
     
    229336        }
    230337
     338        //$table = print_r($sizes, true);
    231339        $table = '<div class="squeeze-comparison-table">';
    232340        $table .= '<table class="wp-list-table widefat striped">';
     
    235343
    236344        foreach ($sizes as $size_name => $size_data) {
    237             $size_filename = basename(sanitize_url($size_data['url']));
     345            /*if (!isset($size_data['url'])) {
     346                continue;
     347            }*/
     348            //$size_filename = basename(sanitize_url($size_data['url']));
    238349            $original_size = $size_data['original_size'];
    239350            $compressed_size = $size_data['compressed_size'];
     
    435546            'auto_webp' => false, // needs to be false by default, because user has to save settings first in order to flush rewrite rules
    436547            'webp_replace_urls' => false,
     548            'direct_webp' => false,
    437549            'cdn_url' => '',
    438550            'backup_original' => true,
     
    451563        return in_array($option, array_keys($options_defaults)) ? $options_defaults[ $option ] : false;
    452564    }
     565
     566    public function get_thumb_sizes() {
     567        $sizes = wp_get_registered_image_subsizes();
     568        if ( !empty( $sizes ) && is_array( $sizes ) ) {
     569            // Add the scaled image size option if it fits the image dimensions
     570            $big_image_size_threshold = apply_filters('big_image_size_threshold', 2560);
     571            if ( $big_image_size_threshold ) {
     572                $sizes['full'] = array(
     573                    'width' => $big_image_size_threshold,
     574                    'height' => $big_image_size_threshold,
     575                    'crop' => false,
     576                );
     577            }
     578        }
     579        return $sizes;
     580    }
     581
     582    public function is_rest_enabled() {
     583        // Check if REST API is enabled
     584        if ( !function_exists( 'rest_get_server' ) || !rest_get_server() ) {
     585            return false;
     586        }
     587
     588        return (bool) apply_filters( 'rest_enabled', true );
     589    }
    453590}
  • squeeze/trunk/inc/settings.php

    r3311866 r3345284  
    4848        );
    4949        add_action( 'admin_footer', [$this, 'svg_sprite_output'] );
     50        add_action( 'admin_notices', [$this, 'incompatibility_notices'] );
    5051        add_action( 'edit_form_after_title', [$this, 'add_preview_button_placeholder'], 10 );
    5152    }
     
    9192        $directory_path = ( get_transient( 'squeeze_bulk_path' ) ? get_transient( 'squeeze_bulk_path' ) : array('/wp-content/uploads/') );
    9293        $directory_path_json = wp_json_encode( $directory_path );
     94        $is_direct_webp = self::$SqueezeHelpers->get_option( 'direct_webp' );
    9395        ?>
    9496        <div class="wrap">
     
    110112                        </div>
    111113                        <div class="squeeze-box-content">
     114                            <?php
     115            if ( $is_direct_webp ) {
     116                ?>
     117                            <div class="squeeze-box-content__row">
     118                                <div class="squeeze-box-content__col" style="flex: 1;">
     119                                    <div class="squeeze-banner squeeze-banner--warning">
     120                                        <svg class="squeeze-icon">
     121                                            <use xlink:href="#exclamation-triangle-line-icon"></use>
     122                                        </svg>
     123                                        <div class="squeeze-banner__content">
     124                                            <p><?php
     125                esc_html_e( 'Warning! You have enabled Direct WebP image conversion option.', 'squeeze' );
     126                ?></p>
     127                                            <p><?php
     128                esc_html_e( 'All existing JPG/PNG images will be converted to WebP format. Make sure to update your existing image URLs accordingly.', 'squeeze' );
     129                ?></p>
     130                                        </div>
     131                                    </div>
     132                                </div>
     133                            </div>
     134                            <?php
     135            }
     136            ?>
    112137                            <div class="squeeze-box-content__row">
    113138                                <div class="squeeze-box-content__col">
     
    178203            ?></p>
    179204                                    <p><?php
    180             esc_html_e( 'Please backup your images manually before optimising them.', 'squeeze' );
     205            esc_html_e( 'Please backup your images manually before squeezing them.', 'squeeze' );
    181206            ?></p>
    182207                                </div>
     
    197222            foreach ( $directory_path as $path ) {
    198223                ?>
    199                                             <input type="text" class="squeeze-path-list__item" value="<?php
     224                                            <div class="squeeze-path-list__item">
     225                                                <input name="squeeze-path-list__item[]" type="text" class="squeeze-path-list__input" value="<?php
    200226                echo esc_attr( $path );
    201227                ?>" readonly />
     228                                                <button name="squeeze_remove_path_button" class="squeeze-path-list__remove" type="button">
     229                                                    <svg class="squeeze-icon">
     230                                                        <use xlink:href="#close-round-icon"></use>
     231                                                    </svg>
     232                                                </button>
     233                                            </div>
    202234                                        <?php
    203235            }
     
    330362            }
    331363        }
    332         // check if webp-express/webp-express.php plugin is active and show a notice
    333         if ( is_plugin_active( 'webp-express/webp-express.php' ) ) {
    334             add_settings_error(
    335                 'squeeze_notices',
    336                 'squeeze_notices',
    337                 __( 'The WebP Express plugin is active. Please deactivate in order to use WebP serving from Squeeze.', 'squeeze' ),
    338                 'warning'
    339             );
    340         }
    341         // check if image-converter-webp/image-converter-webp.php plugin is active and show a notice
    342         if ( is_plugin_active( 'image-converter-webp/image-converter-webp.php' ) ) {
    343             add_settings_error(
    344                 'squeeze_notices',
    345                 'squeeze_notices',
    346                 __( 'The Image Converter for WebP plugin is active. Please deactivate in order to use WebP serving from Squeeze.', 'squeeze' ),
    347                 'warning'
    348             );
    349         }
     364        /*if (!self::$SqueezeHelpers->is_rest_enabled()) {
     365              add_settings_error(
     366                  'squeeze_notices',
     367                  'squeeze_notices',
     368                  __('The REST API is not enabled on your site. Please enable it in order to use Squeeze plugin.', 'squeeze'),
     369                  'error'
     370              );
     371          }*/
    350372        ?>
    351373        <div class="wrap">
     
    379401        esc_html_e( 'Upgrade', 'squeeze' );
    380402        ?></a>
     403                <?php
     404        ?>
    381405                <?php
    382406        ?>
     
    571595                                <h3 style="text-align: center;">
    572596                                    <?php
    573         echo sprintf( __( 'To upgrade to the Premium version, <a href="%s" target="_blank">click here</a>.', 'device-wrapper' ), esc_url( self::CHECKOUT_URL ) );
     597        echo sprintf( __( 'To upgrade to the Premium version, <a href="%s" target="_blank">click here</a>.', 'squeeze' ), esc_url( self::CHECKOUT_URL ) );
    574598        ?>&nbsp;↗
    575599                                </h3>
     
    577601                        </div>
    578602                    </section>
     603                    <?php
     604        ?>
     605
    579606                    <?php
    580607        ?>
     
    644671        );
    645672        add_settings_field(
     673            'squeeze_setting_direct_webp',
     674            __( 'Direct WebP Conversion', 'squeeze' ) . self::$SqueezeHelpers->get_hint( __( 'Convert all uploaded images to WEBP format and replace the originals. The original JPEG/PNG files are not stored on the server, which reduces disk usage.', 'squeeze' ) ),
     675            [$this, 'options_callback'],
     676            'squeeze_options',
     677            'squeeze_basic_settings',
     678            array(
     679                'label_for'   => 'direct_webp',
     680                'class'       => 'squeeze_setting_direct_webp',
     681                'type'        => 'checkbox',
     682                'has_example' => true,
     683            )
     684        );
     685        add_settings_field(
    646686            'squeeze_setting_auto_webp',
    647             __( 'Generate WEBP', 'squeeze' ) . self::$SqueezeHelpers->get_hint( __( 'Generate and serve WEBP images for all uploaded images. The original image URL remains the same, instead the image will be served in a WEBP format.', 'squeeze' ) ),
     687            __( 'Generate WEBP', 'squeeze' ) . self::$SqueezeHelpers->get_hint( __( 'Instead of the original image URL, the image will be served in WEBP format. WEBP images are stored in a separate directory: wp-content/squeeze-webp.', 'squeeze' ) . ' ' . __( 'This is the old method, in case you already have images being converted using this approach. Otherwise, it is recommended that you use the direct WEBP conversion method above.', 'squeeze' ) ),
    648688            [$this, 'options_callback'],
    649689            'squeeze_options',
    650690            'squeeze_basic_settings',
    651691            array(
    652                 'label_for' => 'auto_webp',
    653                 'class'     => 'squeeze_setting_auto_webp',
    654                 'type'      => 'checkbox',
     692                'label_for'   => 'auto_webp',
     693                'class'       => 'squeeze_setting_auto_webp',
     694                'type'        => 'checkbox',
     695                'has_example' => true,
    655696            )
    656697        );
    657698        add_settings_field(
    658699            'squeeze_setting_webp_replace_urls',
    659             __( 'Replace images URLs', 'squeeze' ) . self::$SqueezeHelpers->get_hint( __( 'If the method above does not work, check this option. It replaces original URLs of images with the related WEBP images.', 'squeeze' ) ),
     700            __( 'Replace images URLs', 'squeeze' ) . self::$SqueezeHelpers->get_hint( __( 'If the method above does not work, try this option. This method replaces the original URLs of the images with related WEBP images.', 'squeeze' ) ),
    660701            [$this, 'options_callback'],
    661702            'squeeze_options',
    662703            'squeeze_basic_settings',
    663704            array(
    664                 'label_for' => 'webp_replace_urls',
    665                 'class'     => 'squeeze_setting_webp_replace_urls',
    666                 'type'      => 'checkbox',
    667                 'hidden'    => ( $auto_webp ? '' : true ),
     705                'label_for'   => 'webp_replace_urls',
     706                'class'       => 'squeeze_setting_webp_replace_urls',
     707                'type'        => 'checkbox',
     708                'has_example' => true,
     709                'hidden'      => ( $auto_webp ? '' : true ),
    668710            )
    669711        );
     
    10951137        $input['auto_webp'] = ( isset( $input['auto_webp'] ) ? boolval( $input['auto_webp'] ) : '0' );
    10961138        $input['webp_replace_urls'] = ( isset( $input['webp_replace_urls'] ) && $input['auto_webp'] ? boolval( $input['webp_replace_urls'] ) : '0' );
     1139        $input['direct_webp'] = ( isset( $input['direct_webp'] ) ? boolval( $input['direct_webp'] ) : '0' );
    10971140        $input['cdn_url'] = ( isset( $input['cdn_url'] ) && $input['auto_webp'] ? $input['cdn_url'] : '' );
    10981141        $input['backup_original'] = ( isset( $input['backup_original'] ) ? boolval( $input['backup_original'] ) : '0' );
     
    11381181        $options = get_option( 'squeeze_options' );
    11391182        $is_hidden = ( isset( $args['hidden'] ) && $args['hidden'] ? 'hidden' : '' );
     1183        $has_example = ( isset( $args['has_example'] ) && $args['has_example'] ? true : false );
    11401184        $extra_classes = [];
    11411185        if ( $is_hidden ) {
     
    12441288                break;
    12451289        }
     1290        if ( $has_example ) {
     1291            $value = ( isset( $options[$label_for] ) ? (bool) $options[$label_for] : $default );
     1292            echo '<div class="squeeze-settings-example squeeze-settings-example--' . $label_for . (( $value ? ' enabled' : '' )) . '">';
     1293            switch ( $label_for ) {
     1294                case 'direct_webp':
     1295                    ?>
     1296                <span class="squeeze-hint"><?php
     1297                    echo __( "Example:", 'squeeze' );
     1298                    ?></span>
     1299                <div class="squeeze-box squeeze-box--fieldset">
     1300                    <div class="squeeze-box-content">
     1301                        <p><strong><?php
     1302                    echo __( 'Before', 'squeeze' );
     1303                    ?></strong></p>
     1304                        <p><span><?php
     1305                    echo __( 'image.jpg', 'squeeze' );
     1306                    ?></span> <span><?php
     1307                    echo __( '500 KB', 'squeeze' );
     1308                    ?></span></p>
     1309                        <p><span><?php
     1310                    echo __( 'image-100x100.jpg', 'squeeze' );
     1311                    ?></span> <span><?php
     1312                    echo __( '98 KB', 'squeeze' );
     1313                    ?></span></p>
     1314                        <p><span><?php
     1315                    echo __( 'image-300x300.jpg', 'squeeze' );
     1316                    ?></span> <span><?php
     1317                    echo __( '230 KB', 'squeeze' );
     1318                    ?></span></p>
     1319                    </div>
     1320                    <div class="squeeze-box-content">
     1321                        <p><strong><?php
     1322                    echo __( 'After', 'squeeze' );
     1323                    ?></strong></p>
     1324                        <p><span class="striked"><?php
     1325                    echo __( 'image.jpg', 'squeeze' );
     1326                    ?></span> <span><?php
     1327                    echo __( '500 KB', 'squeeze' );
     1328                    ?></span></p>
     1329                        <p><span class="striked"><?php
     1330                    echo __( 'image-100x100.jpg', 'squeeze' );
     1331                    ?></span> <span><?php
     1332                    echo __( '98 KB', 'squeeze' );
     1333                    ?></span></p>
     1334                        <p><span class="striked"><?php
     1335                    echo __( 'image-300x300.jpg', 'squeeze' );
     1336                    ?></span> <span><?php
     1337                    echo __( '230 KB', 'squeeze' );
     1338                    ?></span></p>
     1339                        <p><span class="greened"><?php
     1340                    echo __( 'image.webp', 'squeeze' );
     1341                    ?></span> <span><?php
     1342                    echo __( '50 KB', 'squeeze' );
     1343                    ?></span></p>
     1344                        <p><span class="greened"><?php
     1345                    echo __( 'image-100x100.webp', 'squeeze' );
     1346                    ?></span> <span><?php
     1347                    echo __( '5 KB', 'squeeze' );
     1348                    ?></span></p>
     1349                        <p><span class="greened"><?php
     1350                    echo __( 'image-300x300.webp', 'squeeze' );
     1351                    ?></span> <span><?php
     1352                    echo __( '20 KB', 'squeeze' );
     1353                    ?></span></p>
     1354                    </div>
     1355                </div>
     1356                <?php
     1357                    break;
     1358                case 'auto_webp':
     1359                    ?>
     1360                <span class="squeeze-hint"><?php
     1361                    echo __( "Example:", 'squeeze' );
     1362                    ?></span>
     1363                <div class="squeeze-box squeeze-box--fieldset">
     1364                    <div class="squeeze-box-content">
     1365                        <p><strong><?php
     1366                    echo __( 'Before', 'squeeze' );
     1367                    ?></strong></p>
     1368                        <code><?php
     1369                    echo __( '/uploads/2025/07/', 'squeeze' );
     1370                    ?></code>
     1371                        <p><span><?php
     1372                    echo __( 'image.jpg', 'squeeze' );
     1373                    ?></span> <span><?php
     1374                    echo __( '500 KB', 'squeeze' );
     1375                    ?></span></p>
     1376                        <p><span><?php
     1377                    echo __( 'image-100x100.jpg', 'squeeze' );
     1378                    ?></span> <span><?php
     1379                    echo __( '98 KB', 'squeeze' );
     1380                    ?></span></p>
     1381                        <p><span><?php
     1382                    echo __( 'image-300x300.jpg', 'squeeze' );
     1383                    ?></span> <span><?php
     1384                    echo __( '230 KB', 'squeeze' );
     1385                    ?></span></p>
     1386                    </div>
     1387                    <div class="squeeze-box-content">
     1388                        <p><strong><?php
     1389                    echo __( 'After', 'squeeze' );
     1390                    ?></strong></p>
     1391                        <code><?php
     1392                    echo __( '/uploads/2025/07/', 'squeeze' );
     1393                    ?></code>
     1394                        <p><span class="greened"><?php
     1395                    echo __( 'image.jpg', 'squeeze' );
     1396                    ?></span> <span><?php
     1397                    echo __( '100 KB', 'squeeze' );
     1398                    ?></span></p>
     1399                        <p><span class="greened"><?php
     1400                    echo __( 'image-100x100.jpg', 'squeeze' );
     1401                    ?></span> <span><?php
     1402                    echo __( '15 KB', 'squeeze' );
     1403                    ?></span></p>
     1404                        <p><span class="greened"><?php
     1405                    echo __( 'image-300x300.jpg', 'squeeze' );
     1406                    ?></span> <span><?php
     1407                    echo __( '40 KB', 'squeeze' );
     1408                    ?></span></p>
     1409                        <code><?php
     1410                    echo __( '/squeeze-webp/uploads/2025/07/', 'squeeze' );
     1411                    ?></code>
     1412                        <p><span class="greened"><?php
     1413                    echo __( 'image.webp', 'squeeze' );
     1414                    ?></span> <span><?php
     1415                    echo __( '50 KB', 'squeeze' );
     1416                    ?></span></p>
     1417                        <p><span class="greened"><?php
     1418                    echo __( 'image-100x100.webp', 'squeeze' );
     1419                    ?></span> <span><?php
     1420                    echo __( '5 KB', 'squeeze' );
     1421                    ?></span></p>
     1422                        <p><span class="greened"><?php
     1423                    echo __( 'image-300x300.webp', 'squeeze' );
     1424                    ?></span> <span><?php
     1425                    echo __( '20 KB', 'squeeze' );
     1426                    ?></span></p>
     1427                    </div>
     1428                </div>
     1429                <?php
     1430                    break;
     1431                case 'webp_replace_urls':
     1432                    ?>
     1433                <span class="squeeze-hint"><?php
     1434                    echo __( "Example:", 'squeeze' );
     1435                    ?></span>
     1436                <div class="squeeze-box squeeze-box--fieldset">
     1437                    <div class="squeeze-box-content">
     1438                        <img src="<?php
     1439                    echo esc_url( plugin_dir_url( __FILE__ ) . '../assets/images/replace_urls.jpg' );
     1440                    ?>" alt="<?php
     1441                    echo esc_attr__( 'Example image', 'squeeze' );
     1442                    ?>">
     1443                    </div>
     1444                </div>
     1445                <?php
     1446                    break;
     1447            }
     1448            echo '</div>';
     1449        }
    12461450    }
    12471451
     
    12721476    public function setting_upgrade_desc() {
    12731477        echo '<p>' . esc_html__( 'Upgrade to premium version for more features.', 'squeeze' ) . '</p>';
     1478    }
     1479
     1480    public function setting_license_desc() {
    12741481    }
    12751482
     
    14651672    }
    14661673
     1674    public function incompatibility_notices() {
     1675        // Bail if we're not in the admin or the screen helper isn't available.
     1676        if ( !is_admin() || !function_exists( 'get_current_screen' ) ) {
     1677            return;
     1678        }
     1679        $screen = get_current_screen();
     1680        // List of screen IDs where we want the warning.
     1681        $target_screens = array(
     1682            'settings_page_squeeze',
     1683            // options-general.php?page=squeeze
     1684            'media_page_squeeze-bulk',
     1685            // upload.php?page=squeeze-bulk
     1686            'upload',
     1687            // the core Media → Library (list table)
     1688            'media',
     1689            // the core Media → Add New
     1690            'plugins',
     1691        );
     1692        if ( !in_array( $screen->id, $target_screens ) ) {
     1693            return;
     1694        }
     1695        // check if webp-express/webp-express.php plugin is active and show a notice
     1696        if ( is_plugin_active( 'webp-express/webp-express.php' ) ) {
     1697            ?>
     1698            <div class="notice notice-warning is-dismissible">
     1699                <p>
     1700                    <?php
     1701            echo __( 'The WebP Express plugin is active. Please deactivate it in order to use correct WebP serving from <strong>Squeeze plugin</strong>.', 'squeeze' );
     1702            ?>
     1703                </p>
     1704            </div>
     1705            <?php
     1706        }
     1707        // check if image-converter-webp/image-converter-webp.php plugin is active and show a notice
     1708        if ( is_plugin_active( 'image-converter-webp/image-converter-webp.php' ) ) {
     1709            ?>
     1710            <div class="notice notice-warning is-dismissible">
     1711                <p>
     1712                    <?php
     1713            echo __( 'The Image Converter for WebP plugin is active. Please deactivate it in order to use correct WebP serving from <strong>Squeeze plugin</strong>.', 'squeeze' );
     1714            ?>
     1715                </p>
     1716            </div>
     1717            <?php
     1718        }
     1719    }
     1720
    14671721}
  • squeeze/trunk/languages/squeeze-uk-0282bc9bb3139ae7f3090194c10090b4.json

    r3267306 r3345284  
    11{
    2     "translation-revision-date": "2025-04-05 21:59+0300",
     2    "translation-revision-date": "2025-08-10 14:49+0300",
    33    "generator": "WP-CLI\/2.6.0",
    44    "source": "assets\/js\/script.js",
     
    2020                "(<a href=\"%s\" target=\"_blank\">\u0442\u0456\u043b\u044c\u043a\u0438 \u043f\u0440\u0435\u043c\u0456\u0443\u043c<\/a>)"
    2121            ],
    22             "Bulk squeezing has been paused!": [
    23                 "\u0421\u0442\u0438\u0441\u043d\u0435\u043d\u043d\u044f \u0431\u0443\u043b\u043e \u0437\u0443\u043f\u0438\u043d\u0435\u043d\u0435!"
    24             ],
    25             "Resume bulk squeezing": [
    26                 "\u0412\u0456\u0434\u043d\u043e\u0432\u0438\u0442\u0438 \u0441\u0442\u0438\u0441\u043d\u0435\u043d\u043d\u044f"
    27             ],
    28             "Pause bulk squeezing": [
    29                 "\u041f\u0440\u0438\u0437\u0443\u043f\u0438\u043d\u0438\u0442\u0438 \u0441\u0442\u0438\u0441\u043d\u0435\u043d\u043d\u044f"
    30             ],
    31             "Are you sure you want to leave this page? The squeezing process will be terminated!": [
    32                 "\u0412\u0438 \u0432\u043f\u0435\u0432\u043d\u0435\u043d\u0456, \u0449\u043e \u0445\u043e\u0447\u0435\u0442\u0435 \u0437\u0430\u043b\u0438\u0448\u0438\u0442\u0438 \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0443? \u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u0442\u0438\u0441\u043d\u0435\u043d\u043d\u044f \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u044c \u0431\u0443\u0434\u0435 \u043f\u0435\u0440\u0435\u0440\u0432\u0430\u043d\u0438\u0439!"
    33             ],
    34             "Are you sure you want to leave this page? The settings will not be saved!": [
    35                 "\u0412\u0438 \u0432\u043f\u0435\u0432\u043d\u0435\u043d\u0456, \u0449\u043e \u0445\u043e\u0447\u0435\u0442\u0435 \u0437\u0430\u043b\u0438\u0448\u0438\u0442\u0438 \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0443? \u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043d\u0435 \u0431\u0443\u0434\u0443\u0442\u044c \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u0456!"
    36             ],
    37             "Restore in process...": [
    38                 "\u0412\u0456\u0434\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0456..."
    39             ],
    4022            "Squeezing...": [
    4123                "\u0421\u0442\u0438\u0441\u043a\u0430\u043d\u043d\u044f..."
    4224            ],
    43             "Start squeezing...": [
    44                 "\u041f\u043e\u0447\u0438\u043d\u0430\u0454\u043c\u043e \u0441\u0442\u0438\u0441\u043a\u0430\u043d\u043d\u044f..."
     25            "An error has occured. Check the console for details.": [
     26                "\u0412\u0438\u043d\u0438\u043a\u043b\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430. \u041f\u0435\u0440\u0435\u0432\u0456\u0440\u0442\u0435 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u043d\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044c."
    4527            ],
    4628            "Pausing...": [
     
    5032                "\u0412\u0441\u0456 \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f \u0431\u0443\u043b\u0438 \u043e\u0431\u0440\u043e\u0431\u043b\u0435\u043d\u0456!"
    5133            ],
    52             "An error has occured. Check the console for details.": [
    53                 "\u0412\u0438\u043d\u0438\u043a\u043b\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430. \u041f\u0435\u0440\u0435\u0432\u0456\u0440\u0442\u0435 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u043d\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044c."
    54             ],
    5534            "Please enter a valid path!": [
    5635                "\u0411\u0443\u0434\u044c\u0442\u0435 \u043b\u0430\u0441\u043a\u0430\u0432\u0456, \u0432\u0432\u0435\u0434\u0456\u0442\u044c \u043a\u043e\u0440\u0435\u043a\u0442\u043d\u0438\u0439 \u0448\u043b\u044f\u0445 \u0434\u043e \u043f\u0430\u043f\u043a\u0438!"
    57             ],
    58             "Found images on the page:": [
    59                 "\u0417\u043d\u0430\u0439\u0434\u0435\u043d\u043e \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u044c \u043d\u0430 \u0441\u0442\u043e\u0440\u0456\u043d\u0446\u0456:"
    60             ],
    61             "Error:": [
    62                 "\u041f\u043e\u043c\u0438\u043b\u043a\u0430:"
    63             ],
    64             "An error has occurred while fetching images from the page. Check the console for details.": [
    65                 "\u0412\u0438\u043d\u0438\u043a\u043b\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430 \u043f\u0456\u0434 \u0447\u0430\u0441 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u044c \u0437\u0456 \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0438. \u0417\u0432\u0435\u0440\u043d\u0456\u0442\u044c\u0441\u044f \u0434\u043e \u043a\u043e\u043d\u0441\u043e\u043b\u0456 \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u043d\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044c."
    6636            ],
    6737            "Loading Preview...": [
  • squeeze/trunk/languages/squeeze-uk-08ec2477f322448a2db534074ac234a4.json

    r3267306 r3345284  
    11{
    2     "translation-revision-date": "2025-04-05 21:59+0300",
     2    "translation-revision-date": "2025-08-10 14:49+0300",
    33    "generator": "WP-CLI\/2.6.0",
    44    "source": "assets\/js\/4240e511ac61ecfff2d8.js",
  • squeeze/trunk/languages/squeeze-uk-24b88c172a2803f6ee0c4956b1a8afb1.json

    r3267306 r3345284  
    11{
    2     "translation-revision-date": "2025-04-05 21:59+0300",
     2    "translation-revision-date": "2025-08-10 14:49+0300",
    33    "generator": "WP-CLI\/2.6.0",
    44    "source": "assets\/js\/script.bundle.js",
     
    4141                "\u041f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043e"
    4242            ],
     43            "Squeezing...": [
     44                "\u0421\u0442\u0438\u0441\u043a\u0430\u043d\u043d\u044f..."
     45            ],
     46            "An error has occured. Check the console for details.": [
     47                "\u0412\u0438\u043d\u0438\u043a\u043b\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430. \u041f\u0435\u0440\u0435\u0432\u0456\u0440\u0442\u0435 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u043d\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044c."
     48            ],
     49            "Media": [
     50                "\u041c\u0435\u0434\u0456\u0430"
     51            ],
     52            "Resume bulk squeezing": [
     53                "\u0412\u0456\u0434\u043d\u043e\u0432\u0438\u0442\u0438 \u0441\u0442\u0438\u0441\u043d\u0435\u043d\u043d\u044f"
     54            ],
     55            "Pause bulk squeezing": [
     56                "\u041f\u0440\u0438\u0437\u0443\u043f\u0438\u043d\u0438\u0442\u0438 \u0441\u0442\u0438\u0441\u043d\u0435\u043d\u043d\u044f"
     57            ],
     58            "Restore in process...": [
     59                "\u0412\u0456\u0434\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0456..."
     60            ],
     61            "Pausing...": [
     62                "\u041f\u0430\u0443\u0437\u0430..."
     63            ],
     64            "All images have been processed!": [
     65                "\u0412\u0441\u0456 \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f \u0431\u0443\u043b\u0438 \u043e\u0431\u0440\u043e\u0431\u043b\u0435\u043d\u0456!"
     66            ],
     67            "Are you sure you want to leave this page? The squeezing process will be terminated!": [
     68                "\u0412\u0438 \u0432\u043f\u0435\u0432\u043d\u0435\u043d\u0456, \u0449\u043e \u0445\u043e\u0447\u0435\u0442\u0435 \u0437\u0430\u043b\u0438\u0448\u0438\u0442\u0438 \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0443? \u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u0442\u0438\u0441\u043d\u0435\u043d\u043d\u044f \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u044c \u0431\u0443\u0434\u0435 \u043f\u0435\u0440\u0435\u0440\u0432\u0430\u043d\u0438\u0439!"
     69            ],
     70            "Are you sure you want to leave this page? The settings will not be saved!": [
     71                "\u0412\u0438 \u0432\u043f\u0435\u0432\u043d\u0435\u043d\u0456, \u0449\u043e \u0445\u043e\u0447\u0435\u0442\u0435 \u0437\u0430\u043b\u0438\u0448\u0438\u0442\u0438 \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0443? \u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043d\u0435 \u0431\u0443\u0434\u0443\u0442\u044c \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u0456!"
     72            ],
    4373            "Bulk squeezing has been paused!": [
    4474                "\u0421\u0442\u0438\u0441\u043d\u0435\u043d\u043d\u044f \u0431\u0443\u043b\u043e \u0437\u0443\u043f\u0438\u043d\u0435\u043d\u0435!"
    4575            ],
    46             "Media": [
    47                 "\u041c\u0435\u0434\u0456\u0430"
     76            "No more images found!": [
     77                "\u0411\u0456\u043b\u044c\u0448\u0435 \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u044c \u043d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u043e!"
     78            ],
     79            "Start squeezing...": [
     80                "\u041f\u043e\u0447\u0438\u043d\u0430\u0454\u043c\u043e \u0441\u0442\u0438\u0441\u043a\u0430\u043d\u043d\u044f..."
     81            ],
     82            "Found images on the page:": [
     83                "\u0417\u043d\u0430\u0439\u0434\u0435\u043d\u043e \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u044c \u043d\u0430 \u0441\u0442\u043e\u0440\u0456\u043d\u0446\u0456:"
     84            ],
     85            "Error:": [
     86                "\u041f\u043e\u043c\u0438\u043b\u043a\u0430:"
     87            ],
     88            "An error has occurred while fetching images from the page. Check the console for details.": [
     89                "\u0412\u0438\u043d\u0438\u043a\u043b\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430 \u043f\u0456\u0434 \u0447\u0430\u0441 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u044c \u0437\u0456 \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0438. \u0417\u0432\u0435\u0440\u043d\u0456\u0442\u044c\u0441\u044f \u0434\u043e \u043a\u043e\u043d\u0441\u043e\u043b\u0456 \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u043d\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044c."
     90            ],
     91            "File is excluded from compression:": [
     92                "\u0412\u043a\u043b\u0430\u0434\u0435\u043d\u043d\u044f \u0432\u0438\u043a\u043b\u044e\u0447\u0435\u043d\u043e \u0437\u0456 \u0441\u0442\u0438\u0441\u043d\u0435\u043d\u043d\u044f"
     93            ],
     94            "File compression failed:": [
     95                "\u041d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f \u0441\u0442\u0438\u0441\u043d\u0443\u0442\u0438 \u0444\u0430\u0439\u043b:"
    4896            ],
    4997            "Show details": [
     
    59107                "\u041f\u043e\u043c\u0438\u043b\u043a\u0430 \u043f\u0440\u0438 \u043e\u0431\u0440\u043e\u0431\u0446\u0456 \u0448\u043b\u044f\u0445\u0443 \u0434\u043e \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0443!"
    60108            ],
    61             "Resume bulk squeezing": [
    62                 "\u0412\u0456\u0434\u043d\u043e\u0432\u0438\u0442\u0438 \u0441\u0442\u0438\u0441\u043d\u0435\u043d\u043d\u044f"
    63             ],
    64             "Pause bulk squeezing": [
    65                 "\u041f\u0440\u0438\u0437\u0443\u043f\u0438\u043d\u0438\u0442\u0438 \u0441\u0442\u0438\u0441\u043d\u0435\u043d\u043d\u044f"
    66             ],
    67             "Are you sure you want to leave this page? The squeezing process will be terminated!": [
    68                 "\u0412\u0438 \u0432\u043f\u0435\u0432\u043d\u0435\u043d\u0456, \u0449\u043e \u0445\u043e\u0447\u0435\u0442\u0435 \u0437\u0430\u043b\u0438\u0448\u0438\u0442\u0438 \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0443? \u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u0442\u0438\u0441\u043d\u0435\u043d\u043d\u044f \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u044c \u0431\u0443\u0434\u0435 \u043f\u0435\u0440\u0435\u0440\u0432\u0430\u043d\u0438\u0439!"
    69             ],
    70             "Are you sure you want to leave this page? The settings will not be saved!": [
    71                 "\u0412\u0438 \u0432\u043f\u0435\u0432\u043d\u0435\u043d\u0456, \u0449\u043e \u0445\u043e\u0447\u0435\u0442\u0435 \u0437\u0430\u043b\u0438\u0448\u0438\u0442\u0438 \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0443? \u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043d\u0435 \u0431\u0443\u0434\u0443\u0442\u044c \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u0456!"
    72             ],
    73             "Restore in process...": [
    74                 "\u0412\u0456\u0434\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0456..."
    75             ],
    76             "Squeezing...": [
    77                 "\u0421\u0442\u0438\u0441\u043a\u0430\u043d\u043d\u044f..."
    78             ],
    79             "Start squeezing...": [
    80                 "\u041f\u043e\u0447\u0438\u043d\u0430\u0454\u043c\u043e \u0441\u0442\u0438\u0441\u043a\u0430\u043d\u043d\u044f..."
    81             ],
    82             "Pausing...": [
    83                 "\u041f\u0430\u0443\u0437\u0430..."
    84             ],
    85             "All images have been processed!": [
    86                 "\u0412\u0441\u0456 \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f \u0431\u0443\u043b\u0438 \u043e\u0431\u0440\u043e\u0431\u043b\u0435\u043d\u0456!"
    87             ],
    88             "An error has occured. Check the console for details.": [
    89                 "\u0412\u0438\u043d\u0438\u043a\u043b\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430. \u041f\u0435\u0440\u0435\u0432\u0456\u0440\u0442\u0435 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u043d\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044c."
    90             ],
    91109            "Please enter a valid path!": [
    92110                "\u0411\u0443\u0434\u044c\u0442\u0435 \u043b\u0430\u0441\u043a\u0430\u0432\u0456, \u0432\u0432\u0435\u0434\u0456\u0442\u044c \u043a\u043e\u0440\u0435\u043a\u0442\u043d\u0438\u0439 \u0448\u043b\u044f\u0445 \u0434\u043e \u043f\u0430\u043f\u043a\u0438!"
    93             ],
    94             "Found images on the page:": [
    95                 "\u0417\u043d\u0430\u0439\u0434\u0435\u043d\u043e \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u044c \u043d\u0430 \u0441\u0442\u043e\u0440\u0456\u043d\u0446\u0456:"
    96             ],
    97             "Error:": [
    98                 "\u041f\u043e\u043c\u0438\u043b\u043a\u0430:"
    99             ],
    100             "An error has occurred while fetching images from the page. Check the console for details.": [
    101                 "\u0412\u0438\u043d\u0438\u043a\u043b\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430 \u043f\u0456\u0434 \u0447\u0430\u0441 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u044c \u0437\u0456 \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0438. \u0417\u0432\u0435\u0440\u043d\u0456\u0442\u044c\u0441\u044f \u0434\u043e \u043a\u043e\u043d\u0441\u043e\u043b\u0456 \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u043d\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044c."
    102111            ],
    103112            "Loading Preview...": [
  • squeeze/trunk/languages/squeeze-uk-8a8cc8d6792f201000247ed42d4140e8.json

    r3200178 r3345284  
    11{
    2     "translation-revision-date": "2024-11-30 13:36+0200",
     2    "translation-revision-date": "2025-08-10 14:49+0300",
    33    "generator": "WP-CLI\/2.6.0",
    44    "source": "copy.js",
     
    1111                "plural-forms": "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);"
    1212            },
    13             "Are you sure you want to leave this page? The compression process will be terminated!": [
     13            "Squeezing...": [
     14                "\u0421\u0442\u0438\u0441\u043a\u0430\u043d\u043d\u044f..."
     15            ],
     16            "An error has occured. Check the console for details.": [
     17                "\u0412\u0438\u043d\u0438\u043a\u043b\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430. \u041f\u0435\u0440\u0435\u0432\u0456\u0440\u0442\u0435 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u043d\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044c."
     18            ],
     19            "Media": [
     20                "\u041c\u0435\u0434\u0456\u0430"
     21            ],
     22            "Resume bulk squeezing": [
     23                "\u0412\u0456\u0434\u043d\u043e\u0432\u0438\u0442\u0438 \u0441\u0442\u0438\u0441\u043d\u0435\u043d\u043d\u044f"
     24            ],
     25            "Pause bulk squeezing": [
     26                "\u041f\u0440\u0438\u0437\u0443\u043f\u0438\u043d\u0438\u0442\u0438 \u0441\u0442\u0438\u0441\u043d\u0435\u043d\u043d\u044f"
     27            ],
     28            "Restore in process...": [
     29                "\u0412\u0456\u0434\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0456..."
     30            ],
     31            "Pausing...": [
     32                "\u041f\u0430\u0443\u0437\u0430..."
     33            ],
     34            "All images have been processed!": [
     35                "\u0412\u0441\u0456 \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f \u0431\u0443\u043b\u0438 \u043e\u0431\u0440\u043e\u0431\u043b\u0435\u043d\u0456!"
     36            ],
     37            "Are you sure you want to leave this page? The squeezing process will be terminated!": [
    1438                "\u0412\u0438 \u0432\u043f\u0435\u0432\u043d\u0435\u043d\u0456, \u0449\u043e \u0445\u043e\u0447\u0435\u0442\u0435 \u0437\u0430\u043b\u0438\u0448\u0438\u0442\u0438 \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0443? \u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u0442\u0438\u0441\u043d\u0435\u043d\u043d\u044f \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u044c \u0431\u0443\u0434\u0435 \u043f\u0435\u0440\u0435\u0440\u0432\u0430\u043d\u0438\u0439!"
    1539            ],
     
    1741                "\u0412\u0438 \u0432\u043f\u0435\u0432\u043d\u0435\u043d\u0456, \u0449\u043e \u0445\u043e\u0447\u0435\u0442\u0435 \u0437\u0430\u043b\u0438\u0448\u0438\u0442\u0438 \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0443? \u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043d\u0435 \u0431\u0443\u0434\u0443\u0442\u044c \u0437\u0431\u0435\u0440\u0435\u0436\u0435\u043d\u0456!"
    1842            ],
    19             "An error has occured. Check the console for details.": [
    20                 "\u0412\u0438\u043d\u0438\u043a\u043b\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430. \u041f\u0435\u0440\u0435\u0432\u0456\u0440\u0442\u0435 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u043d\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044c."
     43            "Bulk squeezing has been paused!": [
     44                "\u0421\u0442\u0438\u0441\u043d\u0435\u043d\u043d\u044f \u0431\u0443\u043b\u043e \u0437\u0443\u043f\u0438\u043d\u0435\u043d\u0435!"
    2145            ],
    22             "Restore in process...": [
    23                 "\u0412\u0456\u0434\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0456..."
     46            "No more images found!": [
     47                "\u0411\u0456\u043b\u044c\u0448\u0435 \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u044c \u043d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u043e!"
    2448            ],
    25             "Compressing...": [
    26                 "\u0421\u0442\u0438\u0441\u043a\u0430\u0454\u043c\u043e..."
     49            "Start squeezing...": [
     50                "\u041f\u043e\u0447\u0438\u043d\u0430\u0454\u043c\u043e \u0441\u0442\u0438\u0441\u043a\u0430\u043d\u043d\u044f..."
    2751            ],
    28             "Please enter a valid path!": [
    29                 "\u0411\u0443\u0434\u044c\u0442\u0435 \u043b\u0430\u0441\u043a\u0430\u0432\u0456, \u0432\u0432\u0435\u0434\u0456\u0442\u044c \u043a\u043e\u0440\u0435\u043a\u0442\u043d\u0438\u0439 \u0448\u043b\u044f\u0445 \u0434\u043e \u043f\u0430\u043f\u043a\u0438!"
     52            "Found images on the page:": [
     53                "\u0417\u043d\u0430\u0439\u0434\u0435\u043d\u043e \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u044c \u043d\u0430 \u0441\u0442\u043e\u0440\u0456\u043d\u0446\u0456:"
    3054            ],
    31             "Compressed successfully, updating...": [
    32                 "\u0423\u0441\u043f\u0456\u0448\u043d\u043e \u0441\u0442\u0438\u0441\u043d\u0443\u0442\u043e, \u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f..."
     55            "Error:": [
     56                "\u041f\u043e\u043c\u0438\u043b\u043a\u0430:"
    3357            ],
    34             "Updated successfully": [
    35                 "\u041e\u043d\u043e\u0432\u043b\u0435\u043d\u043e \u0443\u0441\u043f\u0456\u0448\u043d\u043e"
    36             ],
    37             "All images have been compressed!": [
    38                 "\u0412\u0441\u0456 \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f \u0431\u0443\u043b\u0438 \u0441\u0442\u0438\u0441\u043d\u0443\u0442\u0456!"
    39             ],
    40             "All images have been re-compressed again!": [
    41                 "\u0412\u0441\u0456 \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f \u0431\u0443\u043b\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0441\u0442\u0438\u0441\u043d\u0443\u0442\u0456!"
     58            "An error has occurred while fetching images from the page. Check the console for details.": [
     59                "\u0412\u0438\u043d\u0438\u043a\u043b\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430 \u043f\u0456\u0434 \u0447\u0430\u0441 \u0437\u0430\u0432\u0430\u043d\u0442\u0430\u0436\u0435\u043d\u043d\u044f \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u044c \u0437\u0456 \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0438. \u0417\u0432\u0435\u0440\u043d\u0456\u0442\u044c\u0441\u044f \u0434\u043e \u043a\u043e\u043d\u0441\u043e\u043b\u0456 \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u043d\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044c."
    4260            ]
    4361        }
  • squeeze/trunk/languages/squeeze-uk-b1f8d5e52cbbc262494fff20eec962fd.json

    r3267306 r3345284  
    11{
    2     "translation-revision-date": "2025-04-05 21:59+0300",
     2    "translation-revision-date": "2025-08-10 14:49+0300",
    33    "generator": "WP-CLI\/2.6.0",
    44    "source": "assets\/js\/squeeze.js",
  • squeeze/trunk/languages/squeeze-uk-e9cc8298549e98be96351e6176bc85d5.json

    r3267306 r3345284  
    11{
    2     "translation-revision-date": "2025-04-05 21:59+0300",
     2    "translation-revision-date": "2025-08-10 14:49+0300",
    33    "generator": "WP-CLI\/2.6.0",
    44    "source": "assets\/js\/helpers.js",
     
    2020                "\u0421\u0442\u0438\u0441\u043d\u0435\u043d\u043d\u044f \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0456\u0432"
    2121            ],
     22            "Media": [
     23                "\u041c\u0435\u0434\u0456\u0430"
     24            ],
    2225            "Bulk squeezing has been paused!": [
    2326                "\u0421\u0442\u0438\u0441\u043d\u0435\u043d\u043d\u044f \u0431\u0443\u043b\u043e \u0437\u0443\u043f\u0438\u043d\u0435\u043d\u0435!"
    24             ],
    25             "Media": [
    26                 "\u041c\u0435\u0434\u0456\u0430"
    2727            ],
    2828            "Show details": [
  • squeeze/trunk/languages/squeeze-uk-ebfe0cea630778e3fc5018cec6e46aac.json

    r3267306 r3345284  
    11{
    2     "translation-revision-date": "2025-04-05 21:59+0300",
     2    "translation-revision-date": "2025-08-10 14:49+0300",
    33    "generator": "WP-CLI\/2.6.0",
    44    "source": "assets\/js\/assets_js_squeeze_js-assets_js_worker_js.script.bundle.js",
  • squeeze/trunk/languages/squeeze-uk-f98be19bec7bc848ce3ed383c60037c1.json

    r3267306 r3345284  
    11{
    2     "translation-revision-date": "2025-04-05 21:59+0300",
     2    "translation-revision-date": "2025-08-10 14:49+0300",
    33    "generator": "WP-CLI\/2.6.0",
    44    "source": "assets\/js\/admin.js",
     
    1111                "plural-forms": "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);"
    1212            },
     13            "Bulk Squeeze": [
     14                "\u041c\u0430\u0441\u043e\u0432\u0435 \u0441\u0442\u0438\u0441\u043d\u0435\u043d\u043d\u044f"
     15            ],
    1316            "Squeeze: All images": [
    1417                "Squeeze: \u0423\u0441\u0456 \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f"
     
    1619            "Non Squeezed Images": [
    1720                "\u041d\u0435 \u0441\u0442\u0438\u0441\u043d\u0443\u0442\u0456 \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f"
     21            ],
     22            "Please select at least one image.": [
     23                "\u0411\u0443\u0434\u044c \u043b\u0430\u0441\u043a\u0430, \u0432\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0445\u043e\u0447\u0430 \u0431 \u043e\u0434\u043d\u0435 \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f."
     24            ],
     25            "Squeezing...": [
     26                "\u0421\u0442\u0438\u0441\u043a\u0430\u043d\u043d\u044f..."
     27            ],
     28            "All images have been processed.": [
     29                "\u0412\u0441\u0456 \u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f \u0431\u0443\u043b\u0438 \u043e\u0431\u0440\u043e\u0431\u043b\u0435\u043d\u0456\u044e"
     30            ],
     31            "An error has occured. Check the console for details.": [
     32                "\u0412\u0438\u043d\u0438\u043a\u043b\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430. \u041f\u0435\u0440\u0435\u0432\u0456\u0440\u0442\u0435 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u043c\u0430\u043d\u043d\u044f \u043f\u043e\u0434\u0440\u043e\u0431\u0438\u0446\u044c."
    1833            ]
    1934        }
  • squeeze/trunk/languages/squeeze-uk.po

    r3267306 r3345284  
    55"Project-Id-Version: Squeeze 1.0\n"
    66"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/squeeze\n"
    7 "POT-Creation-Date: 2025-04-05T18:53:49+00:00\n"
    8 "PO-Revision-Date: 2025-04-05 21:59+0300\n"
     7"POT-Creation-Date: 2025-08-10T11:42:23+00:00\n"
     8"PO-Revision-Date: 2025-08-10 14:49+0300\n"
    99"Last-Translator: \n"
    1010"Language-Team: \n"
     
    4040msgstr ""
    4141
    42 #: freemius.php:12 squeeze.php:283
     42#: freemius.php:12 squeeze.php:369
    4343msgid "Go Premium"
    4444msgstr "Хочу Преміум"
     
    4848msgstr "Вітаємо"
    4949
    50 #: inc/handlers.php:39 inc/handlers.php:173 inc/handlers.php:223
    51 #: inc/handlers.php:635
     50#: inc/handlers.php:50 inc/handlers.php:266 inc/handlers.php:316
     51#: inc/handlers.php:740
    5252msgid "You do not have permission to upload files"
    5353msgstr "У вас немає дозволу на завантаження файлів"
    5454
    55 #: inc/handlers.php:43 inc/helpers.php:60
     55#: inc/handlers.php:54 inc/helpers.php:95
    5656msgid "No image data found"
    5757msgstr "Медіа дані не знайдено"
    5858
    59 #: inc/handlers.php:56 inc/handlers.php:60
     59#: inc/handlers.php:68
    6060msgid "Invalid image format"
    6161msgstr "Невірний формат зображення"
    6262
    63 #: inc/handlers.php:69 inc/handlers.php:149 inc/handlers.php:177
     63#: inc/handlers.php:77 inc/handlers.php:242 inc/handlers.php:270
    6464msgid "Attachment not found"
    6565msgstr "Медіафайл не знайдено"
    6666
    67 #: inc/handlers.php:76 inc/handlers.php:190 inc/settings.php:781
    68 #: assets/js/script.bundle.js:39 assets/js/squeeze.js:150
     67#: inc/handlers.php:84 inc/handlers.php:283 inc/settings.php:958
     68#: assets/js/admin.bundle.js:49 assets/js/editor.bundle.js:49
     69#: assets/js/parallel.js:66 assets/js/script.bundle.js:49
     70#: assets/js/squeeze.js:200
    6971msgid "Attachment is excluded from compression"
    7072msgstr "Вкладення виключено зі стиснення"
    7173
    72 #: inc/handlers.php:76 inc/handlers.php:190 inc/settings.php:781
    73 #: assets/js/script.bundle.js:39 assets/js/squeeze.js:150
     74#: inc/handlers.php:84 inc/handlers.php:283 inc/settings.php:958
     75#: assets/js/admin.bundle.js:49 assets/js/editor.bundle.js:49
     76#: assets/js/script.bundle.js:49 assets/js/squeeze.js:200
    7477msgid "found substring: "
    7578msgstr "знайдено підрядок:"
    7679
    77 #: inc/handlers.php:131 inc/handlers.php:139
     80#: inc/handlers.php:130
     81msgid "Compressed image size is greater than original size"
     82msgstr "Розмір стисненого зображення більший за розмір оригіналу"
     83
     84#: inc/handlers.php:214 inc/handlers.php:232
    7885msgid "Squeezed successfully"
    7986msgstr "Стиснуто успішно"
    8087
    81 #: inc/handlers.php:159
     88#: inc/handlers.php:252
    8289msgid "Restored successfully"
    8390msgstr "Відновлено успішно"
    8491
    85 #: inc/handlers.php:161
     92#: inc/handlers.php:254
    8693msgid "Attachment not restored"
    8794msgstr "Медіафайл не відновлено"
    8895
    89 #: inc/handlers.php:227
     96#: inc/handlers.php:320
    9097msgid "Path not found"
    9198msgstr "Папку не знайдено"
    9299
    93 #: inc/handlers.php:299
     100#: inc/handlers.php:392
    94101msgid "Images were not found in the selected directories"
    95102msgstr "Зображення не знайдено у вибраних каталогах"
    96103
    97 #: inc/handlers.php:328
     104#: inc/handlers.php:425 tests/HandlersTest.php:648 tests/HandlersTest.php:663
     105#: tests/HandlersTest.php:677
    98106msgid "Restore Original Image"
    99107msgstr "Відновити оригінальне зображення"
    100108
    101 #: inc/handlers.php:329
     109#: inc/handlers.php:426 tests/HandlersTest.php:649 tests/HandlersTest.php:664
     110#: tests/HandlersTest.php:678
    102111msgid "Squeeze Image"
    103112msgstr "Стиснути зображення"
    104113
    105 #: inc/handlers.php:330
     114#: inc/handlers.php:427 tests/HandlersTest.php:650 tests/HandlersTest.php:665
     115#: tests/HandlersTest.php:679
    106116msgid "Delete Backup Image"
    107117msgstr "Видалити резервне зображення"
    108118
    109 #: inc/handlers.php:331
     119#: inc/handlers.php:428 tests/HandlersTest.php:651 tests/HandlersTest.php:666
     120#: tests/HandlersTest.php:680
    110121msgid "Delete WEBP Image"
    111122msgstr "Видалити WEBP-зображення"
    112123
    113124#. translators: %d: number of attachments restored
    114 #: inc/handlers.php:392
     125#: inc/handlers.php:489
    115126msgid "%d attachment restored."
    116127msgid_plural "%d attachments restored."
     
    120131
    121132#. translators: %d: number of attachments squeezed
    122 #: inc/handlers.php:405
     133#: inc/handlers.php:502
    123134msgid "%d attachment squeezed."
    124135msgid_plural "%d attachments squeezed."
     
    128139
    129140#. translators: %d: number of backup images deleted
    130 #: inc/handlers.php:418
     141#: inc/handlers.php:515
    131142msgid "%d backup image deleted."
    132143msgid_plural "%d backup images deleted."
     
    136147
    137148#. translators: %d: number of webp images deleted
    138 #: inc/handlers.php:431
     149#: inc/handlers.php:528
    139150msgid "%d WEBP image deleted."
    140151msgid_plural "%d WEBP images deleted."
     
    143154msgstr[2] "Резервних зображень видалено."
    144155
    145 #: inc/handlers.php:474
     156#: inc/handlers.php:576
    146157msgid ""
    147158"Single file upload is not supported for the image compression by Squeeze. "
     
    152163"стиснення."
    153164
    154 #: inc/handlers.php:641
     165#: inc/handlers.php:746
    155166msgid "Options not found"
    156167msgstr "Параметри не знайдено"
    157168
    158 #: inc/handlers.php:647
     169#: inc/handlers.php:752
    159170msgid "Options not saved"
    160171msgstr "Параметри не збережено"
    161172
    162 #: inc/handlers.php:650
     173#: inc/handlers.php:755
    163174msgid "Options saved successfully"
    164175msgstr "Параметри успішно збережено"
    165176
    166 #: inc/helpers.php:29
     177#: inc/helpers.php:54
    167178msgid "Backup original image failed"
    168179msgstr "Не вдалося створити резервну копію оригінального зображення"
    169180
    170 #: inc/helpers.php:52 inc/helpers.php:81
     181#: inc/helpers.php:87 inc/helpers.php:155
    171182msgid "Upload image failed"
    172183msgstr "Не вдалося завантажити зображення"
    173184
    174 #: inc/helpers.php:91 inc/helpers.php:107
     185#: inc/helpers.php:165 inc/helpers.php:181
    175186msgid "No WebP data found"
    176187msgstr "Дані WebP не знайдено"
    177188
    178 #: inc/helpers.php:145
     189#: inc/helpers.php:253
    179190msgid "Backup image not found"
    180191msgstr "Резервне зображення не знайдено"
    181192
    182 #: inc/helpers.php:156
     193#: inc/helpers.php:264
    183194msgid "Restore original image failed"
    184195msgstr "Відновлення оригінального зображення не вдалося"
    185196
    186 #: inc/helpers.php:232
     197#: inc/helpers.php:341
    187198msgid "Size Name"
    188199msgstr "Розмір"
    189200
    190 #: inc/helpers.php:232
     201#: inc/helpers.php:341
    191202msgid "Original Size"
    192203msgstr "Початковий"
    193204
    194 #: inc/helpers.php:232
     205#: inc/helpers.php:341
    195206msgid "Squeezed Size"
    196207msgstr "Стиснутий"
    197208
    198 #: inc/helpers.php:232
     209#: inc/helpers.php:341
    199210msgid "Savings"
    200211msgstr "Збережено"
    201212
    202 #: inc/premium/premium.php:21
     213#: inc/premium/premium.php:22
    203214msgid "Page URL not found"
    204215msgstr "URL-адресу сторінки не знайдено"
    205216
    206 #: inc/premium/premium.php:37
     217#: inc/premium/premium.php:38
    207218msgid "URL is not from the same domain"
    208219msgstr "URL-адреса не з того самого домену"
    209220
    210 #: inc/premium/premium.php:47
     221#: inc/premium/premium.php:48
    211222msgid "Error fetching the page:"
    212223msgstr "Помилка при завантаженні сторінки:"
    213224
    214 #: inc/premium/premium.php:196 inc/premium/premium.php:200
     225#: inc/premium/premium.php:209 inc/premium/premium.php:213
    215226msgid "No images found on the page"
    216227msgstr "На сторінці не знайдено жодного зображення"
    217228
    218 #: inc/premium/premium.php:271 inc/settings.php:37 inc/settings.php:778
    219 #: inc/settings.php:789 inc/settings.php:799
     229#: inc/premium/premium.php:289 inc/settings.php:38 inc/settings.php:955
     230#: inc/settings.php:966 inc/settings.php:976 tests/SettingsTest.php:535
    220231msgid "Squeeze"
    221232msgstr ""
    222233
    223 #: inc/premium/premium.php:281
     234#: inc/premium/premium.php:299
    224235msgid "Squeeze images from this page"
    225236msgstr "Стиснути зображення з цієї сторінки"
    226237
    227 #: inc/premium/premium.php:284
     238#: inc/premium/premium.php:302
    228239msgid "Squeeze images from the current page"
    229240msgstr "Стиснути зображення з поточної сторінки"
    230241
    231 #: inc/premium/premium.php:294 squeeze.php:279 assets/js/script.bundle.js:29
    232 #: assets/js/script.js:848
     242#: inc/premium/premium.php:312 squeeze.php:364 assets/js/script.bundle.js:39
     243#: assets/js/script.js:532
    233244msgid "Settings"
    234245msgstr "Налаштування"
    235246
    236 #: inc/premium/premium.php:297
     247#: inc/premium/premium.php:315
    237248msgid "Squeeze settings"
    238249msgstr "Налаштування Squeeze"
    239250
    240 #: inc/premium/premium.php:354 inc/settings.php:959
    241 #: assets/js/script.bundle.js:29 assets/js/script.js:701
    242 #: assets/js/script.js:756
     251#: inc/premium/premium.php:372 inc/settings.php:1136
     252#: assets/js/script.bundle.js:39 assets/js/script.js:414
     253#: assets/js/script.js:440
    243254msgid "Squeeze Preview"
    244255msgstr "Попередній перегляд"
    245256
    246 #: inc/settings.php:36
     257#: inc/premium/premium.php:380
     258msgid "File name not found"
     259msgstr "Ім'я файлу не знайдено"
     260
     261#: inc/settings.php:37
    247262msgid "Squeeze Settings"
    248263msgstr "Налаштування Squeeze"
    249264
    250 #: inc/settings.php:47 inc/settings.php:48 squeeze.php:280
     265#: inc/settings.php:48 inc/settings.php:49 squeeze.php:365
     266#: assets/js/admin.bundle.js:19 assets/js/admin.js:184 assets/js/admin.js:256
    251267msgid "Bulk Squeeze"
    252268msgstr "Масове стиснення"
    253269
    254 #: inc/settings.php:91
     270#: inc/settings.php:94
    255271msgid "Bulk Media Library Squeeze"
    256272msgstr "Масове стиснення зображень із меідатеки"
    257273
    258 #: inc/settings.php:108
     274#: inc/settings.php:105
     275msgid "Warning! You have enabled Direct WebP image conversion option."
     276msgstr "Увага! Ви увімкнули опцію прямого перетворення зображень WebP."
     277
     278#: inc/settings.php:106
     279msgid ""
     280"All existing JPG/PNG images will be converted to WebP format. Make sure to "
     281"update your existing image URLs accordingly."
     282msgstr ""
     283"Всі існуючі зображення у форматі JPG/PNG будуть конвертовані у формат WebP. "
     284"Переконайтеся, що ви оновили URL-адреси існуючих зображень відповідним чином."
     285
     286#: inc/settings.php:126
    259287msgid "Squeezed images: "
    260288msgstr "Стиснуті зображення:"
    261289
    262 #: inc/settings.php:118 assets/js/helpers.js:136 assets/js/script.bundle.js:19
     290#: inc/settings.php:136 assets/js/admin.bundle.js:39
     291#: assets/js/editor.bundle.js:39 assets/js/helpers.js:139
     292#: assets/js/script.bundle.js:29
    263293msgid "Run Bulk Squeeze"
    264294msgstr "Масове стиснення"
    265295
    266 #: inc/settings.php:124 assets/js/helpers.js:137 assets/js/script.bundle.js:19
     296#: inc/settings.php:142 assets/js/admin.bundle.js:39
     297#: assets/js/editor.bundle.js:39 assets/js/helpers.js:140
     298#: assets/js/script.bundle.js:29
    267299msgid "Repeat Bulk Squeeze"
    268300msgstr "Повторити масове стиснення"
    269301
    270 #: inc/settings.php:132
     302#: inc/settings.php:150
    271303msgid "Directory Squeeze"
    272304msgstr "Стиснення каталогів"
    273305
    274 #: inc/settings.php:140
     306#: inc/settings.php:158
    275307msgid "Warning! Backup option is NOT applicable here."
    276308msgstr "Увага! Опція резервного копіювання тут НЕ застосовується."
    277309
    278 #: inc/settings.php:141
    279 msgid "Please backup your images manually before optimising them."
     310#: inc/settings.php:159
     311msgid "Please backup your images manually before squeezing them."
    280312msgstr ""
    281313"Будь ласка, створіть резервну копію зображень вручну перед оптимізацією."
    282314
    283 #: inc/settings.php:147
     315#: inc/settings.php:165
    284316msgid "Directory Path:"
    285317msgstr "Шлях до каталогу:"
    286318
    287 #: inc/settings.php:161 inc/settings.php:185
     319#: inc/settings.php:186 inc/settings.php:210
    288320msgid "Select Directory"
    289321msgstr "Вибрати каталог"
    290322
    291 #: inc/settings.php:165
     323#: inc/settings.php:190
    292324msgid "Select Directory for Squeeze"
    293325msgstr "Виберіть каталог для стиснення"
    294326
    295 #: inc/settings.php:177
     327#: inc/settings.php:202
    296328msgid "Loading directories..."
    297329msgstr "Завантаження каталогів..."
    298330
    299 #: inc/settings.php:195 assets/js/helpers.js:138 assets/js/script.bundle.js:19
     331#: inc/settings.php:220 assets/js/admin.bundle.js:39
     332#: assets/js/editor.bundle.js:39 assets/js/helpers.js:141
     333#: assets/js/script.bundle.js:29
    300334msgid "Run Directory Squeeze"
    301335msgstr "Стиснення каталогів"
    302336
    303 #: inc/settings.php:208
     337#: inc/settings.php:233
    304338msgid "Single Page Squeeze"
    305339msgstr "Стиснення зображень зі сторінки"
    306340
    307 #: inc/settings.php:228
     341#: inc/settings.php:253
    308342msgid "Fetching images..."
    309343msgstr "Отримання зображень..."
    310344
    311 #: inc/settings.php:239
     345#: inc/settings.php:264
    312346msgid "Pause Squeezing"
    313347msgstr "Призупинити стиснення"
    314348
    315 #: inc/settings.php:255
     349#: inc/settings.php:280
    316350msgid "Processed formats:"
    317351msgstr "Формати, що обробляються:"
    318352
    319 #: inc/settings.php:265
     353#: inc/settings.php:290
    320354msgid "Log will be displayed here"
    321355msgstr "Тут відображатиметься журнал"
    322356
    323 #: inc/settings.php:291
     357#: inc/settings.php:318
    324358msgid ""
    325359"The Apache mod_rewrite module is not enabled on your server OR your server "
     
    329363"сервері не запущено Apache."
    330364
    331 #: inc/settings.php:292
     365#: inc/settings.php:319
    332366msgid ""
    333367"In order to make WebP serving work, you need to check the \"Replace images "
     
    337371"URL-адреси зображень\" АБО увімкнути модуль mod_rewrite."
    338372
    339 #: inc/settings.php:302
    340 msgid ""
    341 "The WebP Express plugin is active. Please deactivate in order to use WebP "
    342 "serving from Squeeze."
    343 msgstr ""
    344 "Плагін WebP Express активовано. Будь ласка, деактивуйте його, щоб "
    345 "використовувати WebP-сервіс від Squeeze."
    346 
    347 #: inc/settings.php:311
    348 msgid ""
    349 "The Image Converter for WebP plugin is active. Please deactivate in order to "
    350 "use WebP serving from Squeeze."
    351 msgstr ""
    352 "Плагін Image Converter for WebP активовано. Будь ласка, деактивуйте, щоб "
    353 "використовувати WebP-сервіс від Squeeze."
    354 
    355 #: inc/settings.php:321 inc/settings.php:342 inc/settings.php:462
     373#: inc/settings.php:339 inc/settings.php:368 inc/settings.php:544
    356374msgid "Basic Settings"
    357375msgstr "Основні налаштування"
    358376
    359 #: inc/settings.php:322 inc/settings.php:355 inc/settings.php:492
     377#: inc/settings.php:340 inc/settings.php:381 inc/settings.php:575
    360378msgid "JPEG Settings"
    361379msgstr "Налаштування JPEG"
    362380
    363 #: inc/settings.php:323 inc/settings.php:379 inc/settings.php:521
     381#: inc/settings.php:341 inc/settings.php:405 inc/settings.php:605
    364382msgid "PNG Settings"
    365383msgstr "Налаштування PNG"
    366384
    367 #: inc/settings.php:324 inc/settings.php:392 inc/settings.php:526
     385#: inc/settings.php:342 inc/settings.php:418 inc/settings.php:609
    368386msgid "WEBP Settings"
    369387msgstr "Налаштування WEBP"
    370388
    371 #: inc/settings.php:325 inc/settings.php:405 inc/settings.php:533
     389#: inc/settings.php:343 inc/settings.php:431 inc/settings.php:616
    372390msgid "AVIF Settings"
    373391msgstr "Налаштування AVIF"
    374392
    375 #: inc/settings.php:327 inc/settings.php:419
     393#: inc/settings.php:344 inc/settings.php:444 squeeze.php:366
     394msgid "Documentation"
     395msgstr "Документація"
     396
     397#: inc/settings.php:346 inc/settings.php:471
    376398msgid "Upgrade"
    377 msgstr ""
    378 
    379 #: inc/settings.php:366
     399msgstr "Преміум тут"
     400
     401#: inc/settings.php:352
     402msgid "Your License"
     403msgstr "Ваша ліцензія"
     404
     405#: inc/settings.php:392
    380406msgid "JPEG Advanced Settings"
    381407msgstr "Розширені налаштування JPEG"
    382408
    383 #: inc/settings.php:426
     409#: inc/settings.php:445
     410msgid "Documentation for Squeeze plugin."
     411msgstr "Документація для плагіна Squeeze."
     412
     413#: inc/settings.php:455
     414msgid ""
     415"For more information, please visit the <a href=\"%s\" target=\"_blank"
     416"\">official documentation website</a>."
     417msgstr ""
     418"Для отримання додаткової інформації, будь ласка, відвідайте <a href=\"%s\" "
     419"target=\"_blank\">офіційний сайт</a>."
     420
     421#: inc/settings.php:478
    384422msgid "Image Comparison"
    385423msgstr "Зображення ДО-ПІСЛЯ"
    386424
    387 #: inc/settings.php:426
     425#: inc/settings.php:478
    388426msgid "Compare original and Squeezed image directly in the Media Library."
    389427msgstr "Порівняйте оригінал і стиснене зображення безпосередньо в медіатеці."
    390428
    391 #: inc/settings.php:427
     429#: inc/settings.php:479
    392430msgid "Resize Original Image"
    393431msgstr "Змінити розмір оригінального зображення"
    394432
    395 #: inc/settings.php:427
     433#: inc/settings.php:479
    396434msgid "Set maximum width and height for the original image."
    397435msgstr "Встановіть максимальну ширину та висоту для вихідного зображення."
    398436
    399 #: inc/settings.php:428
     437#: inc/settings.php:480
    400438msgid "Bulk Squeeze from a Page"
    401439msgstr "Масове вилучення зі сторінки"
    402440
    403 #: inc/settings.php:428
     441#: inc/settings.php:480
    404442msgid "Compress all images from a specific page."
    405443msgstr "Стиснути всі зображення з певної сторінки."
    406444
    407 #: inc/settings.php:429
     445#: inc/settings.php:481
    408446msgid "Image Exclusion"
    409447msgstr "Виключення зображення"
    410448
    411 #: inc/settings.php:429
     449#: inc/settings.php:481
    412450msgid "Exclude specific images from bulk compression."
    413451msgstr "Виключити певні зображення з масового стиснення."
    414452
    415 #: inc/settings.php:447
     453#: inc/settings.php:498
     454msgid ""
     455"To upgrade to the Premium version, <a href=\"%s\" target=\"_blank\">click "
     456"here</a>."
     457msgstr ""
     458"Щоб перейти на Преміум-версію, <a href=\"%s\" target=\"_blank\">натисніть "
     459"тут</a>."
     460
     461#: inc/settings.php:516
     462msgid "Your license hasn't been activated"
     463msgstr "Ваша ліцензія не активована"
     464
     465#: inc/settings.php:521
     466msgid ""
     467"After you entered your license key, you will receive a confirmation email. "
     468"Pleae click on the confirmation button in that email to complete the opt in."
     469msgstr ""
     470"Після того, як ви введете ліцензійний ключ, ви отримаєте лист з "
     471"підтвердженням. Будь ласка, натисніть на кнопку підтвердження в цьому листі, "
     472"щоб завершити реєстрацію."
     473
     474#: inc/settings.php:529
    416475msgid "Save Changes"
    417476msgstr "Зберегти зміни"
    418477
    419 #: inc/settings.php:448
     478#: inc/settings.php:530
    420479msgid "Restore defaults"
    421480msgstr "Відновлення налаштувань за замовчуванням"
    422481
    423 #: inc/settings.php:464
     482#: inc/settings.php:546
    424483msgid "Squeeze on upload"
    425484msgstr "Стискати при завантаженні"
    426485
    427 #: inc/settings.php:465
     486#: inc/settings.php:547
    428487msgid "Backup original image"
    429488msgstr "Створити резервну копію оригінального зображення"
    430489
    431 #: inc/settings.php:467
     490#: inc/settings.php:549
    432491msgid "Image formats"
    433492msgstr "Формати зображення"
    434493
    435 #: inc/settings.php:467
     494#: inc/settings.php:549
    436495msgid "Select which image formats you want to be squeezed."
    437496msgstr "Оберіть які формати зображень ви хочете стискати."
    438497
    439 #: inc/settings.php:469
    440 msgid "Generate WEBP"
    441 msgstr "Згенерувати WEBP"
    442 
    443 #: inc/settings.php:469
    444 msgid ""
    445 "Generate and serve WEBP images for all uploaded images. The original image "
    446 "URL remains the same, instead the image will be served in a WEBP format."
    447 msgstr ""
    448 "Створювати і подавати WEBP-зображення для всіх завантажених зображень. URL-"
    449 "адреса оригінального зображення залишається незмінною, натомість зображення "
    450 "буде подано у форматі WEBP."
    451 
    452 #: inc/settings.php:470
    453 msgid "Replace images URLs"
    454 msgstr "Замінити URL-адреси зображень"
    455 
    456 #: inc/settings.php:470
    457 msgid ""
    458 "If the method above does not work, check this option. It replaces original "
    459 "URLs of images with the related WEBP images."
    460 msgstr ""
    461 "Якщо наведений вище метод не працює, увімкніть цю опцію. Це замінить "
    462 "оригінальні URL-адреси зображень на відповідні WEBP-зображення."
    463 
    464 #: inc/settings.php:474
     498#: inc/settings.php:551
     499msgid "Direct WebP Conversion"
     500msgstr "Пряме перетворення WebP"
     501
     502#: inc/settings.php:551
     503msgid ""
     504"Convert all uploaded images to WEBP format and replace the originals. The "
     505"original JPEG/PNG files are not stored on the server, which reduces disk "
     506"usage."
     507msgstr ""
     508"Конвертувати всі завантажені зображення у формат WEBP і замінити оригінали. "
     509"Оригінальні файли JPEG/PNG не зберігаються на сервері, що зменшує "
     510"використання диска."
     511
     512#: inc/settings.php:552
     513msgid "Generate WEBP <br>(legacy method)"
     514msgstr "Згенерувати WEBP <br>(застарілий метод)"
     515
     516#: inc/settings.php:552
     517msgid ""
     518"Instead of the original image URL, the image will be served in WEBP format. "
     519"WEBP images are stored in a separate directory: wp-content/squeeze-webp."
     520msgstr ""
     521"Замість оригінальної URL-адреси зображення буде подано у форматі WEBP. WEBP-"
     522"зображення зберігаються в окремому каталозі: wp-content/squeeze-webp."
     523
     524#: inc/settings.php:552
     525msgid ""
     526"This is the old method, in case you already have images being converted "
     527"using this approach. Otherwise, it is recommended that you use the direct "
     528"WEBP conversion method above."
     529msgstr ""
     530"Це старий метод, на випадок, якщо у вас вже є зображення, перетворені за "
     531"допомогою цього підходу. В іншому випадку рекомендується використовувати "
     532"метод прямого перетворення WEBP, описаний вище."
     533
     534#: inc/settings.php:553
     535msgid "Replace images URLs <br>(legacy method)"
     536msgstr "Замінити URL-адреси зображень <br>(застарілий метод)"
     537
     538#: inc/settings.php:553
     539msgid ""
     540"If the method above does not work, try this option. This method replaces the "
     541"original URLs of the images with related WEBP images."
     542msgstr ""
     543"Якщо наведений вище метод не працює, спробуйте цей варіант. Цей метод "
     544"замінює оригінальні URL-адреси зображень на відповідні WEBP-зображення."
     545
     546#: inc/settings.php:557
    465547msgid "CDN URL"
    466 msgstr ""
    467 
    468 #: inc/settings.php:474
     548msgstr "URL-адреса CDN"
     549
     550#: inc/settings.php:557
    469551msgid "If your site is using CDN, please enter the URL of your CDN here."
    470552msgstr ""
     
    472554"CDN."
    473555
    474 #: inc/settings.php:477
     556#: inc/settings.php:560
    475557msgid "Squeeze thumbnails"
    476558msgstr "Стиснути мініатюри"
    477559
    478 #: inc/settings.php:477
     560#: inc/settings.php:560
    479561msgid ""
    480562"Choose which image thumbnail sizes you want to squeeze along with the "
     
    484566"оригінальним зображенням."
    485567
    486 #: inc/settings.php:480 inc/settings.php:484
     568#: inc/settings.php:563 inc/settings.php:567
    487569msgid "Max. image width"
    488570msgstr "Максимальна ширина зображення"
    489571
    490 #: inc/settings.php:480 inc/settings.php:484
     572#: inc/settings.php:563 inc/settings.php:567
    491573msgid ""
    492574"Limit a width of an original image. Leave this field empty if you do not "
     
    496578"не хочете обрізати зображення по ширині."
    497579
    498 #: inc/settings.php:481 inc/settings.php:485
     580#: inc/settings.php:564 inc/settings.php:568
    499581msgid "Max. image height"
    500582msgstr "Максимальна висота зображення"
    501583
    502 #: inc/settings.php:481 inc/settings.php:485
     584#: inc/settings.php:564 inc/settings.php:568
    503585msgid ""
    504586"Limit a height of an original image. Leave this field empty if you do not "
     
    508590"не хочете обрізати зображення по висоті."
    509591
    510 #: inc/settings.php:482 inc/settings.php:486
     592#: inc/settings.php:565 inc/settings.php:569
    511593msgid "Excluded images"
    512594msgstr "Виключені зображення"
    513595
    514 #: inc/settings.php:482 inc/settings.php:486
     596#: inc/settings.php:565 inc/settings.php:569
    515597msgid ""
    516598"Enter a list of images that you want to exclude from squeezing. Both full "
     
    520602"використовувати як повні URL-адреси, так і часткові рядки. Один URL на рядок."
    521603
    522 #: inc/settings.php:489
     604#: inc/settings.php:572
    523605msgid "Squeeze timeout"
    524606msgstr "Тайм-аут стискання"
    525607
    526 #: inc/settings.php:489
     608#: inc/settings.php:572
    527609msgid ""
    528610"Time limit for squeezing an image. If you get an error during image "
     
    532614"стискання зображення, спробуйте збільшити це значення."
    533615
    534 #: inc/settings.php:494 inc/settings.php:529 inc/settings.php:535
     616#: inc/settings.php:577 inc/settings.php:607 inc/settings.php:612
     617#: inc/settings.php:618
    535618msgid "Quality"
    536619msgstr "Якість"
    537620
    538 #: inc/settings.php:495
     621#: inc/settings.php:578
    539622msgid "Smoothing"
    540623msgstr "Згладжування"
    541624
    542 #: inc/settings.php:496
     625#: inc/settings.php:579
    543626msgid "Pointless spec compliance"
    544627msgstr ""
    545628
    546 #: inc/settings.php:497
    547 msgid "Arithmetic"
    548 msgstr ""
    549 
    550 #: inc/settings.php:498
     629#: inc/settings.php:582
    551630msgid "Progressive rendering"
    552631msgstr ""
    553632
    554 #: inc/settings.php:499
     633#: inc/settings.php:583
    555634msgid "Optimize Huffman table"
    556635msgstr ""
    557636
    558 #: inc/settings.php:500
     637#: inc/settings.php:584
    559638msgid "Channels"
    560639msgstr ""
    561640
    562 #: inc/settings.php:501
     641#: inc/settings.php:585
    563642msgid "Quantization"
    564643msgstr ""
    565644
    566 #: inc/settings.php:512
     645#: inc/settings.php:596
    567646msgid "Trellis multipass"
    568647msgstr ""
    569648
    570 #: inc/settings.php:513
     649#: inc/settings.php:597
    571650msgid "Optimize zero block runs"
    572651msgstr ""
    573652
    574 #: inc/settings.php:514
     653#: inc/settings.php:598
    575654msgid "Optimize after trellis quantization"
    576655msgstr ""
    577656
    578 #: inc/settings.php:515
     657#: inc/settings.php:599
    579658msgid "Trellis quantization passes"
    580659msgstr ""
    581660
    582 #: inc/settings.php:516
     661#: inc/settings.php:600
    583662msgid "Auto subsample chroma"
    584663msgstr ""
    585664
    586 #: inc/settings.php:517
     665#: inc/settings.php:601
    587666msgid "Subsample chroma by"
    588667msgstr ""
    589668
    590 #: inc/settings.php:518
     669#: inc/settings.php:602
    591670msgid "Separate chroma quality"
    592671msgstr ""
    593672
    594 #: inc/settings.php:519
     673#: inc/settings.php:603
    595674msgid "Chroma quality"
    596675msgstr ""
    597676
    598 #: inc/settings.php:523 inc/settings.php:528
     677#: inc/settings.php:611
    599678msgid "Effort"
    600679msgstr ""
    601680
    602 #: inc/settings.php:524
    603 msgid "Interlace"
    604 msgstr ""
    605 
    606 #: inc/settings.php:530
     681#: inc/settings.php:613
    607682msgid "Lossless"
    608683msgstr ""
    609684
    610 #: inc/settings.php:531
     685#: inc/settings.php:614
    611686msgid "Near lossless"
    612687msgstr ""
    613688
    614 #: inc/settings.php:579
     689#: inc/settings.php:664
    615690msgid "Settings have been updated."
    616691msgstr "Налаштування було оновлено."
    617692
    618 #: inc/settings.php:712
    619 msgid ""
    620 "This feature is available only in the <a href=\"%s\" target=\"_blank"
    621 "\">premium version</a>."
     693#: inc/settings.php:802
     694msgid ""
     695"This feature is available only in the <a href=\"%s\">premium version</a>."
    622696msgstr ""
    623697"Ця функція доступна лише в <a href=\"%s\" target=\"_blank\">преміум-версії</"
    624698"a>."
    625699
    626 #: inc/settings.php:721
     700#: inc/settings.php:816 inc/settings.php:839 inc/settings.php:865
     701msgid "Example:"
     702msgstr "Приклад:"
     703
     704#: inc/settings.php:819 inc/settings.php:842
     705msgid "Before"
     706msgstr "До"
     707
     708#: inc/settings.php:820 inc/settings.php:826 inc/settings.php:844
     709#: inc/settings.php:851
     710msgid "image.jpg"
     711msgstr ""
     712
     713#: inc/settings.php:820 inc/settings.php:826 inc/settings.php:844
     714msgid "500 KB"
     715msgstr ""
     716
     717#: inc/settings.php:821 inc/settings.php:827 inc/settings.php:845
     718#: inc/settings.php:852
     719msgid "image-100x100.jpg"
     720msgstr ""
     721
     722#: inc/settings.php:821 inc/settings.php:827 inc/settings.php:845
     723msgid "98 KB"
     724msgstr ""
     725
     726#: inc/settings.php:822 inc/settings.php:828 inc/settings.php:846
     727#: inc/settings.php:853
     728msgid "image-300x300.jpg"
     729msgstr ""
     730
     731#: inc/settings.php:822 inc/settings.php:828 inc/settings.php:846
     732msgid "230 KB"
     733msgstr ""
     734
     735#: inc/settings.php:825 inc/settings.php:849
     736msgid "After"
     737msgstr "Після"
     738
     739#: inc/settings.php:829 inc/settings.php:855
     740msgid "image.webp"
     741msgstr ""
     742
     743#: inc/settings.php:829 inc/settings.php:855
     744msgid "50 KB"
     745msgstr ""
     746
     747#: inc/settings.php:830 inc/settings.php:856
     748msgid "image-100x100.webp"
     749msgstr ""
     750
     751#: inc/settings.php:830 inc/settings.php:856
     752msgid "5 KB"
     753msgstr ""
     754
     755#: inc/settings.php:831 inc/settings.php:857
     756msgid "image-300x300.webp"
     757msgstr ""
     758
     759#: inc/settings.php:831 inc/settings.php:857
     760msgid "20 KB"
     761msgstr ""
     762
     763#: inc/settings.php:843 inc/settings.php:850
     764msgid "/uploads/2025/07/"
     765msgstr ""
     766
     767#: inc/settings.php:851
     768msgid "100 KB"
     769msgstr ""
     770
     771#: inc/settings.php:852
     772msgid "15 KB"
     773msgstr ""
     774
     775#: inc/settings.php:853
     776msgid "40 KB"
     777msgstr ""
     778
     779#: inc/settings.php:854
     780msgid "/squeeze-webp/uploads/2025/07/"
     781msgstr ""
     782
     783#: inc/settings.php:868
     784msgid "Example image"
     785msgstr "Приклад зображення"
     786
     787#: inc/settings.php:880
    627788msgid "Basic squeezing settings."
    628789msgstr "Основні налаштування стискання зображень."
    629790
    630 #: inc/settings.php:724
     791#: inc/settings.php:883
    631792msgid "Squeezing settings for JPEG images."
    632793msgstr "Налаштування для JPEG зображень."
    633794
    634 #: inc/settings.php:727
     795#: inc/settings.php:886
    635796msgid "More precise settings for experienced users."
    636797msgstr "Більш точні налаштування стиснення для досвідчених користувачів."
    637798
    638 #: inc/settings.php:730
     799#: inc/settings.php:889
    639800msgid "Squeezing settings for PNG images."
    640801msgstr "Налаштування для PNG зображень."
    641802
    642 #: inc/settings.php:733
     803#: inc/settings.php:892
    643804msgid "Squeezing settings for WebP images."
    644805msgstr "Налаштування для WebP зображень."
    645806
    646 #: inc/settings.php:736
     807#: inc/settings.php:895
    647808msgid "Squeezing settings for Avif images."
    648809msgstr "Налаштування для Avif зображень."
    649810
    650 #: inc/settings.php:739
     811#: inc/settings.php:898
    651812msgid "Upgrade to premium version for more features."
    652813msgstr "Оновіть до преміум-версії, щоб отримати більше функцій."
    653814
    654 #: inc/settings.php:748
     815#: inc/settings.php:902
     816msgid ""
     817"To activate your license and manage your account details (e.g. to receive "
     818"security & feature updates notifications), please enter your license key."
     819msgstr ""
     820"Щоб активувати ліцензію та керувати даними свого облікового запису "
     821"(наприклад, отримувати сповіщення про оновлення безпеки та функцій), введіть "
     822"свій ліцензійний ключ."
     823
     824#: inc/settings.php:914
     825msgid "Opt In & Connect"
     826msgstr "Зареєструватися та підключитися"
     827
     828#: inc/settings.php:925
    655829msgid "Settings have been restored."
    656830msgstr "Налаштування відновлено."
    657831
    658 #: inc/settings.php:750
     832#: inc/settings.php:927
    659833msgid "Settings have not been restored."
    660834msgstr "Налаштування не було відновлено."
    661835
    662 #: inc/settings.php:758
     836#: inc/settings.php:935
    663837msgid "Rewrite rules have been flushed."
    664838msgstr "Налаштування посилань було оновлено."
    665839
    666 #: inc/settings.php:784
     840#: inc/settings.php:961
    667841msgid "Squeezed"
    668842msgstr "Стиснутий"
    669843
    670 #: inc/settings.php:785
     844#: inc/settings.php:962
    671845msgid "Restore original"
    672846msgstr "Відновити оригінальне зображення"
    673847
    674 #: inc/settings.php:786
     848#: inc/settings.php:963
    675849msgid "Squeeze again"
    676850msgstr "Стиснути знову"
    677851
    678 #: inc/settings.php:788
     852#: inc/settings.php:965
    679853msgid "Not squeezed"
    680854msgstr "Не стиснутий"
    681855
    682 #: inc/settings.php:869 assets/js/admin.js:161
     856#: inc/settings.php:1046 assets/js/admin.bundle.js:19 assets/js/admin.js:163
    683857msgid "Squeeze: All images"
    684858msgstr "Squeeze: Усі зображення"
    685859
    686 #: inc/settings.php:870 assets/js/admin.js:169
     860#: inc/settings.php:1047 assets/js/admin.bundle.js:19 assets/js/admin.js:171
    687861msgid "Non Squeezed Images"
    688862msgstr "Не стиснуті зображення"
    689863
    690 #: inc/settings.php:961 assets/js/script.bundle.js:29 assets/js/script.js:707
     864#: inc/settings.php:1138 assets/js/script.bundle.js:39 assets/js/script.js:420
    691865msgid "(<a href=\"%s\" target=\"_blank\">premium only</a>)"
    692866msgstr "(<a href=\"%s\" target=\"_blank\">тільки преміум</a>)"
    693867
    694 #: assets/js/4240e511ac61ecfff2d8.js:299
     868#: inc/settings.php:1171
     869msgid ""
     870"The WebP Express plugin is active. Please deactivate it in order to use "
     871"correct WebP serving from <strong>Squeeze plugin</strong>."
     872msgstr ""
     873"Плагін WebP Express активний. Будь ласка, вимкніть його, щоб використовувати "
     874"коректне конвертування WebP зображень з <strong>плагіна Squeeze</strong>."
     875
     876#: inc/settings.php:1183
     877msgid ""
     878"The Image Converter for WebP plugin is active. Please deactivate it in order "
     879"to use correct WebP serving from <strong>Squeeze plugin</strong>."
     880msgstr ""
     881"Плагін Image Converter for WebP активний. Будь ласка, вимкніть його, щоб "
     882"використовувати коректне конвертування WebP зображень з <strong>плагіна "
     883"Squeeze</strong>."
     884
     885#: squeeze.php:186
     886msgid ""
     887"Confirmation email was sent! Please check your inbox to complete the Squeeze "
     888"Premium setup."
     889msgstr ""
     890"Підтвердження відправлено на електронну пошту! Будь ласка, перевірте свою "
     891"поштову скриньку, щоб завершити налаштування Squeeze Premium."
     892
     893#: assets/js/4240e511ac61ecfff2d8.js:299 assets/js/admin.bundle.js:49
    695894#: assets/js/assets_js_squeeze_js-assets_js_worker_js.script.bundle.js:19
    696 #: assets/js/script.bundle.js:39 assets/js/squeeze.js:51
     895#: assets/js/editor.bundle.js:49 assets/js/script.bundle.js:49
     896#: assets/js/squeeze.js:65 assets/js/squeeze.js:494
    697897msgid "Request timed out."
    698898msgstr "Час очікування запиту минув."
    699899
    700 #: assets/js/4240e511ac61ecfff2d8.js:487
     900#: assets/js/4240e511ac61ecfff2d8.js:487 assets/js/admin.bundle.js:49
    701901#: assets/js/assets_js_squeeze_js-assets_js_worker_js.script.bundle.js:19
    702 #: assets/js/script.bundle.js:39 assets/js/squeeze.js:198
     902#: assets/js/editor.bundle.js:49 assets/js/script.bundle.js:49
     903#: assets/js/squeeze.js:248
    703904msgid "Skipped"
    704905msgstr "Пропущено"
    705906
    706 #: assets/js/helpers.js:107 assets/js/script.bundle.js:19
    707 #: assets/js/script.bundle.js:29 assets/js/script.js:50
     907#: assets/js/admin.bundle.js:19 assets/js/admin.js:223
     908msgid "Please select at least one image."
     909msgstr "Будь ласка, виберіть хоча б одне зображення."
     910
     911#: assets/js/admin.bundle.js:19 assets/js/admin.bundle.js:29
     912#: assets/js/admin.js:239 assets/js/editor.bundle.js:29
     913#: assets/js/handlers.js:212 assets/js/handlers.js:619 assets/js/handlers
     914#: copy.js:162 copy.js:513 assets/js/script.bundle.js:19
     915#: assets/js/script.bundle.js:39 assets/js/script.js:160
     916#: assets/js/script.js:166
     917msgid "Squeezing..."
     918msgstr "Стискання..."
     919
     920#: assets/js/admin.bundle.js:19 assets/js/admin.js:246
     921msgid "All images have been processed."
     922msgstr "Всі зображення були обробленію"
     923
     924#: assets/js/admin.bundle.js:19 assets/js/admin.bundle.js:29
     925#: assets/js/admin.js:251 assets/js/editor.bundle.js:29
     926#: assets/js/handlers.js:200 assets/js/handlers.js:420
     927#: assets/js/handlers.js:466 assets/js/handlers copy.js:150 copy.js:431
     928#: copy.js:477 assets/js/script.bundle.js:19 assets/js/script.bundle.js:39
     929#: assets/js/script.js:83 assets/js/script.js:182
     930msgid "An error has occured. Check the console for details."
     931msgstr "Виникла помилка. Перевірте консоль для отримання подробиць."
     932
     933#: assets/js/admin.bundle.js:29 assets/js/admin.bundle.js:39
     934#: assets/js/editor.bundle.js:29 assets/js/editor.bundle.js:39
     935#: assets/js/handlers.js:48 assets/js/handlers copy.js:290
     936#: assets/js/helpers.js:110 assets/js/script.bundle.js:19
     937#: assets/js/script.bundle.js:29
     938msgid "Media"
     939msgstr "Медіа"
     940
     941#: assets/js/admin.bundle.js:29 assets/js/editor.bundle.js:29
     942#: assets/js/handlers.js:73 assets/js/handlers.js:275 assets/js/handlers
     943#: copy.js:23 copy.js:225 assets/js/script.bundle.js:19
     944msgid "Resume bulk squeezing"
     945msgstr "Відновити стиснення"
     946
     947#: assets/js/admin.bundle.js:29 assets/js/editor.bundle.js:29
     948#: assets/js/handlers.js:73 assets/js/handlers copy.js:23
     949#: assets/js/script.bundle.js:19
     950msgid "Pause bulk squeezing"
     951msgstr "Призупинити стиснення"
     952
     953#: assets/js/admin.bundle.js:29 assets/js/editor.bundle.js:29
     954#: assets/js/handlers.js:145 assets/js/handlers copy.js:95
     955#: assets/js/script.bundle.js:19
     956msgid "Restore in process..."
     957msgstr "Відновлення в процесі..."
     958
     959#: assets/js/admin.bundle.js:29 assets/js/editor.bundle.js:29
     960#: assets/js/handlers.js:180 assets/js/handlers.js:447 assets/js/handlers
     961#: copy.js:128 copy.js:458 assets/js/script.bundle.js:19
     962#: assets/js/script.bundle.js:39 assets/js/script.js:63
     963msgid "Pausing..."
     964msgstr "Пауза..."
     965
     966#: assets/js/admin.bundle.js:29 assets/js/editor.bundle.js:29
     967#: assets/js/handlers.js:191 assets/js/handlers.js:458 assets/js/handlers
     968#: copy.js:141 copy.js:469 assets/js/script.bundle.js:19
     969#: assets/js/script.bundle.js:39 assets/js/script.js:74
     970msgid "All images have been processed!"
     971msgstr "Всі зображення були оброблені!"
     972
     973#: assets/js/admin.bundle.js:29 assets/js/editor.bundle.js:29
     974#: assets/js/handlers.js:262 assets/js/handlers copy.js:212
     975#: assets/js/script.bundle.js:19
     976msgid ""
     977"Are you sure you want to leave this page? The squeezing process will be "
     978"terminated!"
     979msgstr ""
     980"Ви впевнені, що хочете залишити сторінку? Процесс стиснення зображень буде "
     981"перерваний!"
     982
     983#: assets/js/admin.bundle.js:29 assets/js/editor.bundle.js:29
     984#: assets/js/handlers.js:265 assets/js/handlers copy.js:215
     985#: assets/js/script.bundle.js:19
     986msgid ""
     987"Are you sure you want to leave this page? The settings will not be saved!"
     988msgstr ""
     989"Ви впевнені, що хочете залишити сторінку? Налаштування не будуть збережені!"
     990
     991#: assets/js/admin.bundle.js:29 assets/js/admin.bundle.js:39
     992#: assets/js/editor.bundle.js:29 assets/js/editor.bundle.js:39
     993#: assets/js/handlers.js:271 assets/js/handlers copy.js:221
     994#: assets/js/helpers.js:110 assets/js/script.bundle.js:19
     995#: assets/js/script.bundle.js:29
    708996msgid "Bulk squeezing has been paused!"
    709997msgstr "Стиснення було зупинене!"
    710998
    711 #: assets/js/helpers.js:107 assets/js/script.bundle.js:19
    712 msgid "Media"
    713 msgstr "Медіа"
    714 
    715 #: assets/js/helpers.js:116 assets/js/helpers.js:120
     999#: assets/js/admin.bundle.js:29 assets/js/editor.bundle.js:29
     1000#: assets/js/handlers.js:306 assets/js/handlers.js:313 assets/js/handlers
     1001#: copy.js:312 copy.js:320 assets/js/script.bundle.js:19
     1002msgid "No more images found!"
     1003msgstr "Більше зображень не знайдено!"
     1004
     1005#: assets/js/admin.bundle.js:29 assets/js/editor.bundle.js:29
     1006#: assets/js/handlers.js:320 assets/js/handlers copy.js:331
     1007#: assets/js/parallel.js:35 assets/js/script.bundle.js:19
     1008msgid "Start squeezing..."
     1009msgstr "Починаємо стискання..."
     1010
     1011#: assets/js/admin.bundle.js:29 assets/js/editor.bundle.js:29
     1012#: assets/js/handlers.js:407 assets/js/handlers copy.js:420
    7161013#: assets/js/script.bundle.js:19
     1014msgid "Found images on the page:"
     1015msgstr "Знайдено зображень на сторінці:"
     1016
     1017#: assets/js/admin.bundle.js:29 assets/js/editor.bundle.js:29
     1018#: assets/js/handlers.js:416 assets/js/handlers copy.js:427
     1019#: assets/js/script.bundle.js:19
     1020msgid "Error:"
     1021msgstr "Помилка:"
     1022
     1023#: assets/js/admin.bundle.js:29 assets/js/editor.bundle.js:29
     1024#: assets/js/handlers.js:423 assets/js/handlers.js:426 assets/js/handlers
     1025#: copy.js:434 copy.js:437 assets/js/script.bundle.js:19
     1026msgid ""
     1027"An error has occurred while fetching images from the page. Check the console "
     1028"for details."
     1029msgstr ""
     1030"Виникла помилка під час завантаження зображень зі сторінки. Зверніться до "
     1031"консолі для отримання подробиць."
     1032
     1033#: assets/js/admin.bundle.js:29 assets/js/editor.bundle.js:29
     1034#: assets/js/handlers.js:638 assets/js/script.bundle.js:19
     1035msgid "File is excluded from compression:"
     1036msgstr "Вкладення виключено зі стиснення"
     1037
     1038#: assets/js/admin.bundle.js:29 assets/js/editor.bundle.js:29
     1039#: assets/js/handlers.js:647 assets/js/script.bundle.js:19
     1040msgid "File compression failed:"
     1041msgstr "Не вдалося стиснути файл:"
     1042
     1043#: assets/js/admin.bundle.js:39 assets/js/editor.bundle.js:39
     1044#: assets/js/helpers.js:119 assets/js/helpers.js:123
     1045#: assets/js/script.bundle.js:29
    7171046msgid "Show details"
    7181047msgstr "Показати деталі"
    7191048
    720 #: assets/js/helpers.js:120 assets/js/script.bundle.js:19
     1049#: assets/js/admin.bundle.js:39 assets/js/editor.bundle.js:39
     1050#: assets/js/helpers.js:123 assets/js/script.bundle.js:29
    7211051msgid "Hide details"
    7221052msgstr "Сховати деталі"
    7231053
    724 #: assets/js/helpers.js:183 assets/js/script.bundle.js:19
     1054#: assets/js/admin.bundle.js:39 assets/js/editor.bundle.js:39
     1055#: assets/js/helpers.js:190 assets/js/script.bundle.js:29
    7251056msgid "No directories found!"
    7261057msgstr "Каталоги не знайдено!"
    7271058
    728 #: assets/js/helpers.js:244 assets/js/script.bundle.js:19
     1059#: assets/js/admin.bundle.js:39 assets/js/editor.bundle.js:39
     1060#: assets/js/helpers.js:266 assets/js/script.bundle.js:29
    7291061msgid "Error parsing path input!"
    7301062msgstr "Помилка при обробці шляху до каталогу!"
    7311063
    732 #: assets/js/script.bundle.js:29 assets/js/script.js:54 assets/js/script.js:61
    733 msgid "Resume bulk squeezing"
    734 msgstr "Відновити стиснення"
    735 
    736 #: assets/js/script.bundle.js:29 assets/js/script.js:61
    737 msgid "Pause bulk squeezing"
    738 msgstr "Призупинити стиснення"
    739 
    740 #: assets/js/script.bundle.js:29 assets/js/script.js:83
    741 msgid ""
    742 "Are you sure you want to leave this page? The squeezing process will be "
    743 "terminated!"
    744 msgstr ""
    745 "Ви впевнені, що хочете залишити сторінку? Процесс стиснення зображень буде "
    746 "перерваний!"
    747 
    748 #: assets/js/script.bundle.js:29 assets/js/script.js:86
    749 msgid ""
    750 "Are you sure you want to leave this page? The settings will not be saved!"
    751 msgstr ""
    752 "Ви впевнені, що хочете залишити сторінку? Налаштування не будуть збережені!"
    753 
    754 #: assets/js/script.bundle.js:29 assets/js/script.js:134
    755 msgid "Restore in process..."
    756 msgstr "Відновлення в процесі..."
    757 
    758 #: assets/js/script.bundle.js:29 assets/js/script.js:156
    759 #: assets/js/script.js:433 assets/js/script.js:439 assets/js/script.js:630
    760 msgid "Squeezing..."
    761 msgstr "Стискання..."
    762 
    763 #: assets/js/script.bundle.js:29 assets/js/script.js:186
    764 msgid "Start squeezing..."
    765 msgstr "Починаємо стискання..."
    766 
    767 #: assets/js/script.bundle.js:29 assets/js/script.js:273
    768 #: assets/js/script.js:340 assets/js/script.js:522
    769 msgid "Pausing..."
    770 msgstr "Пауза..."
    771 
    772 #: assets/js/script.bundle.js:29 assets/js/script.js:284
    773 #: assets/js/script.js:351 assets/js/script.js:533
    774 msgid "All images have been processed!"
    775 msgstr "Всі зображення були оброблені!"
    776 
    777 #: assets/js/script.bundle.js:29 assets/js/script.js:293
    778 #: assets/js/script.js:360 assets/js/script.js:455 assets/js/script.js:495
    779 #: assets/js/script.js:541
    780 msgid "An error has occured. Check the console for details."
    781 msgstr "Виникла помилка. Перевірте консоль для отримання подробиць."
    782 
    783 #: assets/js/script.bundle.js:29 assets/js/script.js:316
     1064#: assets/js/editor.bundle.js:19 assets/js/editor.js:80
     1065#: assets/js/editor__old.js:131
     1066msgid "Squeezing image…"
     1067msgstr "Стискаємо зображення..."
     1068
     1069#: assets/js/editor.bundle.js:19 assets/js/editor.js:125
     1070#: assets/js/editor__old.js:30
     1071msgid "Error fetching attachment: %s"
     1072msgstr "Помилка при завантаженні вкладення: %s"
     1073
     1074#: assets/js/editor.bundle.js:19 assets/js/editor.js:158
     1075#: assets/js/editor__old.js:60
     1076msgid "Error uploading image: %s"
     1077msgstr "Помилка при завантаженні зображення: %s"
     1078
     1079#: assets/js/editor.bundle.js:19 assets/js/editor.js:279
     1080msgid "Squeezing the image..."
     1081msgstr "Стискаємо зображення..."
     1082
     1083#: assets/js/editor.bundle.js:19 assets/js/editor.js:342
     1084#: assets/js/editor.js:358
     1085msgid "Error squeezing the image: %s"
     1086msgstr "Помилка при стисканні зображення: %s"
     1087
     1088#: assets/js/script.bundle.js:39 assets/js/script.js:37
    7841089msgid "Please enter a valid path!"
    7851090msgstr "Будьте ласкаві, введіть коректний шлях до папки!"
    7861091
    787 #: assets/js/script.bundle.js:29 assets/js/script.js:484
    788 msgid "Found images on the page:"
    789 msgstr "Знайдено зображень на сторінці:"
    790 
    791 #: assets/js/script.bundle.js:29 assets/js/script.js:491
    792 msgid "Error:"
    793 msgstr "Помилка:"
    794 
    795 #: assets/js/script.bundle.js:29 assets/js/script.js:498
    796 #: assets/js/script.js:501
    797 msgid ""
    798 "An error has occurred while fetching images from the page. Check the console "
    799 "for details."
    800 msgstr ""
    801 "Виникла помилка під час завантаження зображень зі сторінки. Зверніться до "
    802 "консолі для отримання подробиць."
    803 
    804 #: assets/js/script.bundle.js:29 assets/js/script.js:756
     1092#: assets/js/script.bundle.js:39 assets/js/script.js:440
    8051093msgid "Loading Preview..."
    8061094msgstr "Завантаження попереднього перегляду..."
    8071095
    808 #: assets/js/script.bundle.js:29 assets/js/script.js:849
    809 #: assets/js/script.js:892
     1096#: assets/js/script.bundle.js:39 assets/js/script.js:533
     1097#: assets/js/script.js:576
    8101098msgid "Collapse"
    8111099msgstr "Сховати"
    8121100
    813 #: assets/js/script.bundle.js:29 assets/js/script.js:850
     1101#: assets/js/script.bundle.js:39 assets/js/script.js:534
    8141102msgid "Apply"
    8151103msgstr "Застосувати"
    8161104
    817 #: assets/js/script.bundle.js:29 assets/js/script.js:865
     1105#: assets/js/script.bundle.js:39 assets/js/script.js:549
    8181106msgid ""
    8191107"An error occurred while rendering the preview. Check the console for details."
     
    8221110"консолі для отримання подробиць."
    8231111
    824 #: assets/js/script.bundle.js:29 assets/js/script.js:895
     1112#: assets/js/script.bundle.js:39 assets/js/script.js:579
    8251113msgid "Expand"
    8261114msgstr "Показати"
    8271115
     1116#~ msgid "Generate WEBP"
     1117#~ msgstr "Згенерувати WEBP"
     1118
     1119#~ msgid ""
     1120#~ "Generate and serve WEBP images for all uploaded images. The original "
     1121#~ "image URL remains the same, instead the image will be served in a WEBP "
     1122#~ "format."
     1123#~ msgstr ""
     1124#~ "Створювати і подавати WEBP-зображення для всіх завантажених зображень. "
     1125#~ "URL-адреса оригінального зображення залишається незмінною, натомість "
     1126#~ "зображення буде подано у форматі WEBP."
     1127
    8281128#~ msgid "Upload WEBP image failed"
    8291129#~ msgstr "Не вдалося завантажити WEBP зображення"
     
    8341134#~ msgid "Attachment not updated"
    8351135#~ msgstr "Медіафайл не оновлено"
    836 
    837 #~ msgid "Image is excluded from compression"
    838 #~ msgstr "Вкладення виключено зі стиснення"
    8391136
    8401137#~ msgid "Replace original URLs of images with the related WEBP images."
  • squeeze/trunk/languages/squeeze.pot

    r3267306 r3345284  
    33msgid ""
    44msgstr ""
    5 "Project-Id-Version: Squeeze – Image Optimization & Compression, WebP Conversion 1.6.3\n"
     5"Project-Id-Version: Squeeze – Image Optimization & Compression, WebP Conversion 1.7.0\n"
    66"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/squeeze\n"
    77"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
     
    1010"Content-Type: text/plain; charset=UTF-8\n"
    1111"Content-Transfer-Encoding: 8bit\n"
    12 "POT-Creation-Date: 2025-04-05T18:53:49+00:00\n"
     12"POT-Creation-Date: 2025-08-10T11:42:23+00:00\n"
    1313"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
    1414"X-Generator: WP-CLI 2.6.0\n"
     
    3232
    3333#: freemius.php:12
    34 #: squeeze.php:283
     34#: squeeze.php:369
    3535msgid "Go Premium"
    3636msgstr ""
     
    4141msgstr ""
    4242
    43 #: inc/handlers.php:39
    44 #: inc/handlers.php:173
    45 #: inc/handlers.php:223
    46 #: inc/handlers.php:635
     43#: inc/handlers.php:50
     44#: inc/handlers.php:266
     45#: inc/handlers.php:316
     46#: inc/handlers.php:740
    4747msgid "You do not have permission to upload files"
    4848msgstr ""
    4949
    50 #: inc/handlers.php:43
    51 #: inc/helpers.php:60
     50#: inc/handlers.php:54
     51#: inc/helpers.php:95
    5252msgid "No image data found"
    5353msgstr ""
    5454
    55 #: inc/handlers.php:56
    56 #: inc/handlers.php:60
     55#: inc/handlers.php:68
    5756msgid "Invalid image format"
    5857msgstr ""
    5958
    60 #: inc/handlers.php:69
    61 #: inc/handlers.php:149
    62 #: inc/handlers.php:177
     59#: inc/handlers.php:77
     60#: inc/handlers.php:242
     61#: inc/handlers.php:270
    6362msgid "Attachment not found"
    6463msgstr ""
    6564
    66 #: inc/handlers.php:76
    67 #: inc/handlers.php:190
    68 #: inc/settings.php:781
    69 #: assets/js/script.bundle.js:39
    70 #: assets/js/squeeze.js:150
     65#: inc/handlers.php:84
     66#: inc/handlers.php:283
     67#: inc/settings.php:958
     68#: assets/js/admin.bundle.js:49
     69#: assets/js/editor.bundle.js:49
     70#: assets/js/parallel.js:66
     71#: assets/js/script.bundle.js:49
     72#: assets/js/squeeze.js:200
    7173msgid "Attachment is excluded from compression"
    7274msgstr ""
    7375
    74 #: inc/handlers.php:76
    75 #: inc/handlers.php:190
    76 #: inc/settings.php:781
    77 #: assets/js/script.bundle.js:39
    78 #: assets/js/squeeze.js:150
     76#: inc/handlers.php:84
     77#: inc/handlers.php:283
     78#: inc/settings.php:958
     79#: assets/js/admin.bundle.js:49
     80#: assets/js/editor.bundle.js:49
     81#: assets/js/script.bundle.js:49
     82#: assets/js/squeeze.js:200
    7983msgid "found substring: "
    8084msgstr ""
    8185
    82 #: inc/handlers.php:131
    83 #: inc/handlers.php:139
     86#: inc/handlers.php:130
     87msgid "Compressed image size is greater than original size"
     88msgstr ""
     89
     90#: inc/handlers.php:214
     91#: inc/handlers.php:232
    8492msgid "Squeezed successfully"
    8593msgstr ""
    8694
    87 #: inc/handlers.php:159
     95#: inc/handlers.php:252
    8896msgid "Restored successfully"
    8997msgstr ""
    9098
    91 #: inc/handlers.php:161
     99#: inc/handlers.php:254
    92100msgid "Attachment not restored"
    93101msgstr ""
    94102
    95 #: inc/handlers.php:227
     103#: inc/handlers.php:320
    96104msgid "Path not found"
    97105msgstr ""
    98106
    99 #: inc/handlers.php:299
     107#: inc/handlers.php:392
    100108msgid "Images were not found in the selected directories"
    101109msgstr ""
    102110
    103 #: inc/handlers.php:328
     111#: inc/handlers.php:425
     112#: tests/HandlersTest.php:648
     113#: tests/HandlersTest.php:663
     114#: tests/HandlersTest.php:677
    104115msgid "Restore Original Image"
    105116msgstr ""
    106117
    107 #: inc/handlers.php:329
     118#: inc/handlers.php:426
     119#: tests/HandlersTest.php:649
     120#: tests/HandlersTest.php:664
     121#: tests/HandlersTest.php:678
    108122msgid "Squeeze Image"
    109123msgstr ""
    110124
    111 #: inc/handlers.php:330
     125#: inc/handlers.php:427
     126#: tests/HandlersTest.php:650
     127#: tests/HandlersTest.php:665
     128#: tests/HandlersTest.php:679
    112129msgid "Delete Backup Image"
    113130msgstr ""
    114131
    115 #: inc/handlers.php:331
     132#: inc/handlers.php:428
     133#: tests/HandlersTest.php:651
     134#: tests/HandlersTest.php:666
     135#: tests/HandlersTest.php:680
    116136msgid "Delete WEBP Image"
    117137msgstr ""
    118138
    119139#. translators: %d: number of attachments restored
    120 #: inc/handlers.php:392
     140#: inc/handlers.php:489
    121141msgid "%d attachment restored."
    122142msgid_plural "%d attachments restored."
     
    125145
    126146#. translators: %d: number of attachments squeezed
    127 #: inc/handlers.php:405
     147#: inc/handlers.php:502
    128148msgid "%d attachment squeezed."
    129149msgid_plural "%d attachments squeezed."
     
    132152
    133153#. translators: %d: number of backup images deleted
    134 #: inc/handlers.php:418
     154#: inc/handlers.php:515
    135155msgid "%d backup image deleted."
    136156msgid_plural "%d backup images deleted."
     
    139159
    140160#. translators: %d: number of webp images deleted
    141 #: inc/handlers.php:431
     161#: inc/handlers.php:528
    142162msgid "%d WEBP image deleted."
    143163msgid_plural "%d WEBP images deleted."
     
    145165msgstr[1] ""
    146166
    147 #: inc/handlers.php:474
     167#: inc/handlers.php:576
    148168msgid "Single file upload is not supported for the image compression by Squeeze. Please use multi-file uploader or bulk squeeze."
    149169msgstr ""
    150170
    151 #: inc/handlers.php:641
     171#: inc/handlers.php:746
    152172msgid "Options not found"
    153173msgstr ""
    154174
    155 #: inc/handlers.php:647
     175#: inc/handlers.php:752
    156176msgid "Options not saved"
    157177msgstr ""
    158178
    159 #: inc/handlers.php:650
     179#: inc/handlers.php:755
    160180msgid "Options saved successfully"
    161181msgstr ""
    162182
    163 #: inc/helpers.php:29
     183#: inc/helpers.php:54
    164184msgid "Backup original image failed"
    165185msgstr ""
    166186
    167 #: inc/helpers.php:52
    168 #: inc/helpers.php:81
     187#: inc/helpers.php:87
     188#: inc/helpers.php:155
    169189msgid "Upload image failed"
    170190msgstr ""
    171191
    172 #: inc/helpers.php:91
    173 #: inc/helpers.php:107
     192#: inc/helpers.php:165
     193#: inc/helpers.php:181
    174194msgid "No WebP data found"
    175195msgstr ""
    176196
    177 #: inc/helpers.php:145
     197#: inc/helpers.php:253
    178198msgid "Backup image not found"
    179199msgstr ""
    180200
    181 #: inc/helpers.php:156
     201#: inc/helpers.php:264
    182202msgid "Restore original image failed"
    183203msgstr ""
    184204
    185 #: inc/helpers.php:232
     205#: inc/helpers.php:341
    186206msgid "Size Name"
    187207msgstr ""
    188208
    189 #: inc/helpers.php:232
     209#: inc/helpers.php:341
    190210msgid "Original Size"
    191211msgstr ""
    192212
    193 #: inc/helpers.php:232
     213#: inc/helpers.php:341
    194214msgid "Squeezed Size"
    195215msgstr ""
    196216
    197 #: inc/helpers.php:232
     217#: inc/helpers.php:341
    198218msgid "Savings"
    199219msgstr ""
    200220
    201 #: inc/premium/premium.php:21
     221#: inc/premium/premium.php:22
    202222msgid "Page URL not found"
    203223msgstr ""
    204224
    205 #: inc/premium/premium.php:37
     225#: inc/premium/premium.php:38
    206226msgid "URL is not from the same domain"
    207227msgstr ""
    208228
    209 #: inc/premium/premium.php:47
     229#: inc/premium/premium.php:48
    210230msgid "Error fetching the page:"
    211231msgstr ""
    212232
    213 #: inc/premium/premium.php:196
    214 #: inc/premium/premium.php:200
     233#: inc/premium/premium.php:209
     234#: inc/premium/premium.php:213
    215235msgid "No images found on the page"
    216236msgstr ""
    217237
    218 #: inc/premium/premium.php:271
     238#: inc/premium/premium.php:289
     239#: inc/settings.php:38
     240#: inc/settings.php:955
     241#: inc/settings.php:966
     242#: inc/settings.php:976
     243#: tests/SettingsTest.php:535
     244msgid "Squeeze"
     245msgstr ""
     246
     247#: inc/premium/premium.php:299
     248msgid "Squeeze images from this page"
     249msgstr ""
     250
     251#: inc/premium/premium.php:302
     252msgid "Squeeze images from the current page"
     253msgstr ""
     254
     255#: inc/premium/premium.php:312
     256#: squeeze.php:364
     257#: assets/js/script.bundle.js:39
     258#: assets/js/script.js:532
     259msgid "Settings"
     260msgstr ""
     261
     262#: inc/premium/premium.php:315
     263msgid "Squeeze settings"
     264msgstr ""
     265
     266#: inc/premium/premium.php:372
     267#: inc/settings.php:1136
     268#: assets/js/script.bundle.js:39
     269#: assets/js/script.js:414
     270#: assets/js/script.js:440
     271msgid "Squeeze Preview"
     272msgstr ""
     273
     274#: inc/premium/premium.php:380
     275msgid "File name not found"
     276msgstr ""
     277
    219278#: inc/settings.php:37
    220 #: inc/settings.php:778
    221 #: inc/settings.php:789
    222 #: inc/settings.php:799
    223 msgid "Squeeze"
    224 msgstr ""
    225 
    226 #: inc/premium/premium.php:281
    227 msgid "Squeeze images from this page"
    228 msgstr ""
    229 
    230 #: inc/premium/premium.php:284
    231 msgid "Squeeze images from the current page"
    232 msgstr ""
    233 
    234 #: inc/premium/premium.php:294
    235 #: squeeze.php:279
     279msgid "Squeeze Settings"
     280msgstr ""
     281
     282#: inc/settings.php:48
     283#: inc/settings.php:49
     284#: squeeze.php:365
     285#: assets/js/admin.bundle.js:19
     286#: assets/js/admin.js:184
     287#: assets/js/admin.js:256
     288msgid "Bulk Squeeze"
     289msgstr ""
     290
     291#: inc/settings.php:94
     292msgid "Bulk Media Library Squeeze"
     293msgstr ""
     294
     295#: inc/settings.php:105
     296msgid "Warning! You have enabled Direct WebP image conversion option."
     297msgstr ""
     298
     299#: inc/settings.php:106
     300msgid "All existing JPG/PNG images will be converted to WebP format. Make sure to update your existing image URLs accordingly."
     301msgstr ""
     302
     303#: inc/settings.php:126
     304msgid "Squeezed images: "
     305msgstr ""
     306
     307#: inc/settings.php:136
     308#: assets/js/admin.bundle.js:39
     309#: assets/js/editor.bundle.js:39
     310#: assets/js/helpers.js:139
    236311#: assets/js/script.bundle.js:29
    237 #: assets/js/script.js:848
    238 msgid "Settings"
    239 msgstr ""
    240 
    241 #: inc/premium/premium.php:297
    242 msgid "Squeeze settings"
    243 msgstr ""
    244 
    245 #: inc/premium/premium.php:354
    246 #: inc/settings.php:959
     312msgid "Run Bulk Squeeze"
     313msgstr ""
     314
     315#: inc/settings.php:142
     316#: assets/js/admin.bundle.js:39
     317#: assets/js/editor.bundle.js:39
     318#: assets/js/helpers.js:140
    247319#: assets/js/script.bundle.js:29
    248 #: assets/js/script.js:701
    249 #: assets/js/script.js:756
    250 msgid "Squeeze Preview"
    251 msgstr ""
    252 
    253 #: inc/settings.php:36
    254 msgid "Squeeze Settings"
    255 msgstr ""
    256 
    257 #: inc/settings.php:47
    258 #: inc/settings.php:48
    259 #: squeeze.php:280
    260 msgid "Bulk Squeeze"
    261 msgstr ""
    262 
    263 #: inc/settings.php:91
    264 msgid "Bulk Media Library Squeeze"
    265 msgstr ""
    266 
    267 #: inc/settings.php:108
    268 msgid "Squeezed images: "
    269 msgstr ""
    270 
    271 #: inc/settings.php:118
    272 #: assets/js/helpers.js:136
    273 #: assets/js/script.bundle.js:19
    274 msgid "Run Bulk Squeeze"
    275 msgstr ""
    276 
    277 #: inc/settings.php:124
    278 #: assets/js/helpers.js:137
    279 #: assets/js/script.bundle.js:19
    280320msgid "Repeat Bulk Squeeze"
    281321msgstr ""
    282322
    283 #: inc/settings.php:132
     323#: inc/settings.php:150
    284324msgid "Directory Squeeze"
    285325msgstr ""
    286326
    287 #: inc/settings.php:140
     327#: inc/settings.php:158
    288328msgid "Warning! Backup option is NOT applicable here."
    289329msgstr ""
    290330
    291 #: inc/settings.php:141
    292 msgid "Please backup your images manually before optimising them."
    293 msgstr ""
    294 
    295 #: inc/settings.php:147
     331#: inc/settings.php:159
     332msgid "Please backup your images manually before squeezing them."
     333msgstr ""
     334
     335#: inc/settings.php:165
    296336msgid "Directory Path:"
    297337msgstr ""
    298338
    299 #: inc/settings.php:161
    300 #: inc/settings.php:185
     339#: inc/settings.php:186
     340#: inc/settings.php:210
    301341msgid "Select Directory"
    302342msgstr ""
    303343
    304 #: inc/settings.php:165
     344#: inc/settings.php:190
    305345msgid "Select Directory for Squeeze"
    306346msgstr ""
    307347
    308 #: inc/settings.php:177
     348#: inc/settings.php:202
    309349msgid "Loading directories..."
    310350msgstr ""
    311351
    312 #: inc/settings.php:195
    313 #: assets/js/helpers.js:138
    314 #: assets/js/script.bundle.js:19
     352#: inc/settings.php:220
     353#: assets/js/admin.bundle.js:39
     354#: assets/js/editor.bundle.js:39
     355#: assets/js/helpers.js:141
     356#: assets/js/script.bundle.js:29
    315357msgid "Run Directory Squeeze"
    316358msgstr ""
    317359
    318 #: inc/settings.php:208
     360#: inc/settings.php:233
    319361msgid "Single Page Squeeze"
    320362msgstr ""
    321363
    322 #: inc/settings.php:228
     364#: inc/settings.php:253
    323365msgid "Fetching images..."
    324366msgstr ""
    325367
    326 #: inc/settings.php:239
     368#: inc/settings.php:264
    327369msgid "Pause Squeezing"
    328370msgstr ""
    329371
    330 #: inc/settings.php:255
     372#: inc/settings.php:280
    331373msgid "Processed formats:"
    332374msgstr ""
    333375
    334 #: inc/settings.php:265
     376#: inc/settings.php:290
    335377msgid "Log will be displayed here"
    336378msgstr ""
    337379
    338 #: inc/settings.php:291
     380#: inc/settings.php:318
    339381msgid "The Apache mod_rewrite module is not enabled on your server OR your server is not running Apache."
    340382msgstr ""
    341383
    342 #: inc/settings.php:292
     384#: inc/settings.php:319
    343385msgid "In order to make WebP serving work, you need to check the \"Replace images URLs\" option OR enable the mod_rewrite module."
    344386msgstr ""
    345387
    346 #: inc/settings.php:302
    347 msgid "The WebP Express plugin is active. Please deactivate in order to use WebP serving from Squeeze."
    348 msgstr ""
    349 
    350 #: inc/settings.php:311
    351 msgid "The Image Converter for WebP plugin is active. Please deactivate in order to use WebP serving from Squeeze."
    352 msgstr ""
    353 
    354 #: inc/settings.php:321
     388#: inc/settings.php:339
     389#: inc/settings.php:368
     390#: inc/settings.php:544
     391msgid "Basic Settings"
     392msgstr ""
     393
     394#: inc/settings.php:340
     395#: inc/settings.php:381
     396#: inc/settings.php:575
     397msgid "JPEG Settings"
     398msgstr ""
     399
     400#: inc/settings.php:341
     401#: inc/settings.php:405
     402#: inc/settings.php:605
     403msgid "PNG Settings"
     404msgstr ""
     405
    355406#: inc/settings.php:342
    356 #: inc/settings.php:462
    357 msgid "Basic Settings"
    358 msgstr ""
    359 
    360 #: inc/settings.php:322
    361 #: inc/settings.php:355
    362 #: inc/settings.php:492
    363 msgid "JPEG Settings"
    364 msgstr ""
    365 
    366 #: inc/settings.php:323
    367 #: inc/settings.php:379
     407#: inc/settings.php:418
     408#: inc/settings.php:609
     409msgid "WEBP Settings"
     410msgstr ""
     411
     412#: inc/settings.php:343
     413#: inc/settings.php:431
     414#: inc/settings.php:616
     415msgid "AVIF Settings"
     416msgstr ""
     417
     418#: inc/settings.php:344
     419#: inc/settings.php:444
     420#: squeeze.php:366
     421msgid "Documentation"
     422msgstr ""
     423
     424#: inc/settings.php:346
     425#: inc/settings.php:471
     426msgid "Upgrade"
     427msgstr ""
     428
     429#: inc/settings.php:352
     430msgid "Your License"
     431msgstr ""
     432
     433#: inc/settings.php:392
     434msgid "JPEG Advanced Settings"
     435msgstr ""
     436
     437#: inc/settings.php:445
     438msgid "Documentation for Squeeze plugin."
     439msgstr ""
     440
     441#: inc/settings.php:455
     442msgid "For more information, please visit the <a href=\"%s\" target=\"_blank\">official documentation website</a>."
     443msgstr ""
     444
     445#: inc/settings.php:478
     446msgid "Image Comparison"
     447msgstr ""
     448
     449#: inc/settings.php:478
     450msgid "Compare original and Squeezed image directly in the Media Library."
     451msgstr ""
     452
     453#: inc/settings.php:479
     454msgid "Resize Original Image"
     455msgstr ""
     456
     457#: inc/settings.php:479
     458msgid "Set maximum width and height for the original image."
     459msgstr ""
     460
     461#: inc/settings.php:480
     462msgid "Bulk Squeeze from a Page"
     463msgstr ""
     464
     465#: inc/settings.php:480
     466msgid "Compress all images from a specific page."
     467msgstr ""
     468
     469#: inc/settings.php:481
     470msgid "Image Exclusion"
     471msgstr ""
     472
     473#: inc/settings.php:481
     474msgid "Exclude specific images from bulk compression."
     475msgstr ""
     476
     477#: inc/settings.php:498
     478msgid "To upgrade to the Premium version, <a href=\"%s\" target=\"_blank\">click here</a>."
     479msgstr ""
     480
     481#: inc/settings.php:516
     482msgid "Your license hasn't been activated"
     483msgstr ""
     484
    368485#: inc/settings.php:521
    369 msgid "PNG Settings"
    370 msgstr ""
    371 
    372 #: inc/settings.php:324
    373 #: inc/settings.php:392
    374 #: inc/settings.php:526
    375 msgid "WEBP Settings"
    376 msgstr ""
    377 
    378 #: inc/settings.php:325
    379 #: inc/settings.php:405
    380 #: inc/settings.php:533
    381 msgid "AVIF Settings"
    382 msgstr ""
    383 
    384 #: inc/settings.php:327
    385 #: inc/settings.php:419
    386 msgid "Upgrade"
    387 msgstr ""
    388 
    389 #: inc/settings.php:366
    390 msgid "JPEG Advanced Settings"
    391 msgstr ""
    392 
    393 #: inc/settings.php:426
    394 msgid "Image Comparison"
    395 msgstr ""
    396 
    397 #: inc/settings.php:426
    398 msgid "Compare original and Squeezed image directly in the Media Library."
    399 msgstr ""
    400 
    401 #: inc/settings.php:427
    402 msgid "Resize Original Image"
    403 msgstr ""
    404 
    405 #: inc/settings.php:427
    406 msgid "Set maximum width and height for the original image."
    407 msgstr ""
    408 
    409 #: inc/settings.php:428
    410 msgid "Bulk Squeeze from a Page"
    411 msgstr ""
    412 
    413 #: inc/settings.php:428
    414 msgid "Compress all images from a specific page."
    415 msgstr ""
    416 
    417 #: inc/settings.php:429
    418 msgid "Image Exclusion"
    419 msgstr ""
    420 
    421 #: inc/settings.php:429
    422 msgid "Exclude specific images from bulk compression."
    423 msgstr ""
    424 
    425 #: inc/settings.php:447
     486msgid "After you entered your license key, you will receive a confirmation email. Pleae click on the confirmation button in that email to complete the opt in."
     487msgstr ""
     488
     489#: inc/settings.php:529
    426490msgid "Save Changes"
    427491msgstr ""
    428492
    429 #: inc/settings.php:448
     493#: inc/settings.php:530
    430494msgid "Restore defaults"
    431495msgstr ""
    432496
    433 #: inc/settings.php:464
     497#: inc/settings.php:546
    434498msgid "Squeeze on upload"
    435499msgstr ""
    436500
    437 #: inc/settings.php:465
     501#: inc/settings.php:547
    438502msgid "Backup original image"
    439503msgstr ""
    440504
    441 #: inc/settings.php:467
     505#: inc/settings.php:549
    442506msgid "Image formats"
    443507msgstr ""
    444508
    445 #: inc/settings.php:467
     509#: inc/settings.php:549
    446510msgid "Select which image formats you want to be squeezed."
    447511msgstr ""
    448512
    449 #: inc/settings.php:469
    450 msgid "Generate WEBP"
    451 msgstr ""
    452 
    453 #: inc/settings.php:469
    454 msgid "Generate and serve WEBP images for all uploaded images. The original image URL remains the same, instead the image will be served in a WEBP format."
    455 msgstr ""
    456 
    457 #: inc/settings.php:470
    458 msgid "Replace images URLs"
    459 msgstr ""
    460 
    461 #: inc/settings.php:470
    462 msgid "If the method above does not work, check this option. It replaces original URLs of images with the related WEBP images."
    463 msgstr ""
    464 
    465 #: inc/settings.php:474
     513#: inc/settings.php:551
     514msgid "Direct WebP Conversion"
     515msgstr ""
     516
     517#: inc/settings.php:551
     518msgid "Convert all uploaded images to WEBP format and replace the originals. The original JPEG/PNG files are not stored on the server, which reduces disk usage."
     519msgstr ""
     520
     521#: inc/settings.php:552
     522msgid "Generate WEBP <br>(legacy method)"
     523msgstr ""
     524
     525#: inc/settings.php:552
     526msgid "Instead of the original image URL, the image will be served in WEBP format. WEBP images are stored in a separate directory: wp-content/squeeze-webp."
     527msgstr ""
     528
     529#: inc/settings.php:552
     530msgid "This is the old method, in case you already have images being converted using this approach. Otherwise, it is recommended that you use the direct WEBP conversion method above."
     531msgstr ""
     532
     533#: inc/settings.php:553
     534msgid "Replace images URLs <br>(legacy method)"
     535msgstr ""
     536
     537#: inc/settings.php:553
     538msgid "If the method above does not work, try this option. This method replaces the original URLs of the images with related WEBP images."
     539msgstr ""
     540
     541#: inc/settings.php:557
    466542msgid "CDN URL"
    467543msgstr ""
    468544
    469 #: inc/settings.php:474
     545#: inc/settings.php:557
    470546msgid "If your site is using CDN, please enter the URL of your CDN here."
    471547msgstr ""
    472548
    473 #: inc/settings.php:477
     549#: inc/settings.php:560
    474550msgid "Squeeze thumbnails"
    475551msgstr ""
    476552
    477 #: inc/settings.php:477
     553#: inc/settings.php:560
    478554msgid "Choose which image thumbnail sizes you want to squeeze along with the original image."
    479555msgstr ""
    480556
    481 #: inc/settings.php:480
    482 #: inc/settings.php:484
     557#: inc/settings.php:563
     558#: inc/settings.php:567
    483559msgid "Max. image width"
    484560msgstr ""
    485561
    486 #: inc/settings.php:480
    487 #: inc/settings.php:484
     562#: inc/settings.php:563
     563#: inc/settings.php:567
    488564msgid "Limit a width of an original image. Leave this field empty if you do not want to crop the image by width."
    489565msgstr ""
    490566
    491 #: inc/settings.php:481
    492 #: inc/settings.php:485
     567#: inc/settings.php:564
     568#: inc/settings.php:568
    493569msgid "Max. image height"
    494570msgstr ""
    495571
    496 #: inc/settings.php:481
    497 #: inc/settings.php:485
     572#: inc/settings.php:564
     573#: inc/settings.php:568
    498574msgid "Limit a height of an original image. Leave this field empty if you do not want to crop the image by height."
    499575msgstr ""
    500576
    501 #: inc/settings.php:482
    502 #: inc/settings.php:486
     577#: inc/settings.php:565
     578#: inc/settings.php:569
    503579msgid "Excluded images"
    504580msgstr ""
    505581
    506 #: inc/settings.php:482
    507 #: inc/settings.php:486
     582#: inc/settings.php:565
     583#: inc/settings.php:569
    508584msgid "Enter a list of images that you want to exclude from squeezing. Both full URLs and partial strings can be used. One URL per line."
    509585msgstr ""
    510586
    511 #: inc/settings.php:489
     587#: inc/settings.php:572
    512588msgid "Squeeze timeout"
    513589msgstr ""
    514590
    515 #: inc/settings.php:489
     591#: inc/settings.php:572
    516592msgid "Time limit for squeezing an image. If you get an error during image squeezing, try to increase this value."
    517593msgstr ""
    518594
    519 #: inc/settings.php:494
    520 #: inc/settings.php:529
    521 #: inc/settings.php:535
     595#: inc/settings.php:577
     596#: inc/settings.php:607
     597#: inc/settings.php:612
     598#: inc/settings.php:618
    522599msgid "Quality"
    523600msgstr ""
    524601
    525 #: inc/settings.php:495
     602#: inc/settings.php:578
    526603msgid "Smoothing"
    527604msgstr ""
    528605
    529 #: inc/settings.php:496
     606#: inc/settings.php:579
    530607msgid "Pointless spec compliance"
    531608msgstr ""
    532609
    533 #: inc/settings.php:497
    534 msgid "Arithmetic"
    535 msgstr ""
    536 
    537 #: inc/settings.php:498
     610#: inc/settings.php:582
    538611msgid "Progressive rendering"
    539612msgstr ""
    540613
    541 #: inc/settings.php:499
     614#: inc/settings.php:583
    542615msgid "Optimize Huffman table"
    543616msgstr ""
    544617
    545 #: inc/settings.php:500
     618#: inc/settings.php:584
    546619msgid "Channels"
    547620msgstr ""
    548621
    549 #: inc/settings.php:501
     622#: inc/settings.php:585
    550623msgid "Quantization"
    551624msgstr ""
    552625
    553 #: inc/settings.php:512
     626#: inc/settings.php:596
    554627msgid "Trellis multipass"
    555628msgstr ""
    556629
    557 #: inc/settings.php:513
     630#: inc/settings.php:597
    558631msgid "Optimize zero block runs"
    559632msgstr ""
    560633
    561 #: inc/settings.php:514
     634#: inc/settings.php:598
    562635msgid "Optimize after trellis quantization"
    563636msgstr ""
    564637
    565 #: inc/settings.php:515
     638#: inc/settings.php:599
    566639msgid "Trellis quantization passes"
    567640msgstr ""
    568641
    569 #: inc/settings.php:516
     642#: inc/settings.php:600
    570643msgid "Auto subsample chroma"
    571644msgstr ""
    572645
    573 #: inc/settings.php:517
     646#: inc/settings.php:601
    574647msgid "Subsample chroma by"
    575648msgstr ""
    576649
    577 #: inc/settings.php:518
     650#: inc/settings.php:602
    578651msgid "Separate chroma quality"
    579652msgstr ""
    580653
    581 #: inc/settings.php:519
     654#: inc/settings.php:603
    582655msgid "Chroma quality"
    583656msgstr ""
    584657
    585 #: inc/settings.php:523
    586 #: inc/settings.php:528
     658#: inc/settings.php:611
    587659msgid "Effort"
    588660msgstr ""
    589661
    590 #: inc/settings.php:524
    591 msgid "Interlace"
    592 msgstr ""
    593 
    594 #: inc/settings.php:530
     662#: inc/settings.php:613
    595663msgid "Lossless"
    596664msgstr ""
    597665
    598 #: inc/settings.php:531
     666#: inc/settings.php:614
    599667msgid "Near lossless"
    600668msgstr ""
    601669
    602 #: inc/settings.php:579
     670#: inc/settings.php:664
    603671msgid "Settings have been updated."
    604672msgstr ""
    605673
    606 #: inc/settings.php:712
    607 msgid "This feature is available only in the <a href=\"%s\" target=\"_blank\">premium version</a>."
    608 msgstr ""
    609 
    610 #: inc/settings.php:721
     674#: inc/settings.php:802
     675msgid "This feature is available only in the <a href=\"%s\">premium version</a>."
     676msgstr ""
     677
     678#: inc/settings.php:816
     679#: inc/settings.php:839
     680#: inc/settings.php:865
     681msgid "Example:"
     682msgstr ""
     683
     684#: inc/settings.php:819
     685#: inc/settings.php:842
     686msgid "Before"
     687msgstr ""
     688
     689#: inc/settings.php:820
     690#: inc/settings.php:826
     691#: inc/settings.php:844
     692#: inc/settings.php:851
     693msgid "image.jpg"
     694msgstr ""
     695
     696#: inc/settings.php:820
     697#: inc/settings.php:826
     698#: inc/settings.php:844
     699msgid "500 KB"
     700msgstr ""
     701
     702#: inc/settings.php:821
     703#: inc/settings.php:827
     704#: inc/settings.php:845
     705#: inc/settings.php:852
     706msgid "image-100x100.jpg"
     707msgstr ""
     708
     709#: inc/settings.php:821
     710#: inc/settings.php:827
     711#: inc/settings.php:845
     712msgid "98 KB"
     713msgstr ""
     714
     715#: inc/settings.php:822
     716#: inc/settings.php:828
     717#: inc/settings.php:846
     718#: inc/settings.php:853
     719msgid "image-300x300.jpg"
     720msgstr ""
     721
     722#: inc/settings.php:822
     723#: inc/settings.php:828
     724#: inc/settings.php:846
     725msgid "230 KB"
     726msgstr ""
     727
     728#: inc/settings.php:825
     729#: inc/settings.php:849
     730msgid "After"
     731msgstr ""
     732
     733#: inc/settings.php:829
     734#: inc/settings.php:855
     735msgid "image.webp"
     736msgstr ""
     737
     738#: inc/settings.php:829
     739#: inc/settings.php:855
     740msgid "50 KB"
     741msgstr ""
     742
     743#: inc/settings.php:830
     744#: inc/settings.php:856
     745msgid "image-100x100.webp"
     746msgstr ""
     747
     748#: inc/settings.php:830
     749#: inc/settings.php:856
     750msgid "5 KB"
     751msgstr ""
     752
     753#: inc/settings.php:831
     754#: inc/settings.php:857
     755msgid "image-300x300.webp"
     756msgstr ""
     757
     758#: inc/settings.php:831
     759#: inc/settings.php:857
     760msgid "20 KB"
     761msgstr ""
     762
     763#: inc/settings.php:843
     764#: inc/settings.php:850
     765msgid "/uploads/2025/07/"
     766msgstr ""
     767
     768#: inc/settings.php:851
     769msgid "100 KB"
     770msgstr ""
     771
     772#: inc/settings.php:852
     773msgid "15 KB"
     774msgstr ""
     775
     776#: inc/settings.php:853
     777msgid "40 KB"
     778msgstr ""
     779
     780#: inc/settings.php:854
     781msgid "/squeeze-webp/uploads/2025/07/"
     782msgstr ""
     783
     784#: inc/settings.php:868
     785msgid "Example image"
     786msgstr ""
     787
     788#: inc/settings.php:880
    611789msgid "Basic squeezing settings."
    612790msgstr ""
    613791
    614 #: inc/settings.php:724
     792#: inc/settings.php:883
    615793msgid "Squeezing settings for JPEG images."
    616794msgstr ""
    617795
    618 #: inc/settings.php:727
     796#: inc/settings.php:886
    619797msgid "More precise settings for experienced users."
    620798msgstr ""
    621799
    622 #: inc/settings.php:730
     800#: inc/settings.php:889
    623801msgid "Squeezing settings for PNG images."
    624802msgstr ""
    625803
    626 #: inc/settings.php:733
     804#: inc/settings.php:892
    627805msgid "Squeezing settings for WebP images."
    628806msgstr ""
    629807
    630 #: inc/settings.php:736
     808#: inc/settings.php:895
    631809msgid "Squeezing settings for Avif images."
    632810msgstr ""
    633811
    634 #: inc/settings.php:739
     812#: inc/settings.php:898
    635813msgid "Upgrade to premium version for more features."
    636814msgstr ""
    637815
    638 #: inc/settings.php:748
     816#: inc/settings.php:902
     817msgid "To activate your license and manage your account details (e.g. to receive security & feature updates notifications), please enter your license key."
     818msgstr ""
     819
     820#: inc/settings.php:914
     821msgid "Opt In & Connect"
     822msgstr ""
     823
     824#: inc/settings.php:925
    639825msgid "Settings have been restored."
    640826msgstr ""
    641827
    642 #: inc/settings.php:750
     828#: inc/settings.php:927
    643829msgid "Settings have not been restored."
    644830msgstr ""
    645831
    646 #: inc/settings.php:758
     832#: inc/settings.php:935
    647833msgid "Rewrite rules have been flushed."
    648834msgstr ""
    649835
    650 #: inc/settings.php:784
     836#: inc/settings.php:961
    651837msgid "Squeezed"
    652838msgstr ""
    653839
    654 #: inc/settings.php:785
     840#: inc/settings.php:962
    655841msgid "Restore original"
    656842msgstr ""
    657843
    658 #: inc/settings.php:786
     844#: inc/settings.php:963
    659845msgid "Squeeze again"
    660846msgstr ""
    661847
    662 #: inc/settings.php:788
     848#: inc/settings.php:965
    663849msgid "Not squeezed"
    664850msgstr ""
    665851
    666 #: inc/settings.php:869
    667 #: assets/js/admin.js:161
     852#: inc/settings.php:1046
     853#: assets/js/admin.bundle.js:19
     854#: assets/js/admin.js:163
    668855msgid "Squeeze: All images"
    669856msgstr ""
    670857
    671 #: inc/settings.php:870
    672 #: assets/js/admin.js:169
     858#: inc/settings.php:1047
     859#: assets/js/admin.bundle.js:19
     860#: assets/js/admin.js:171
    673861msgid "Non Squeezed Images"
    674862msgstr ""
    675863
    676 #: inc/settings.php:961
     864#: inc/settings.php:1138
     865#: assets/js/script.bundle.js:39
     866#: assets/js/script.js:420
     867msgid "(<a href=\"%s\" target=\"_blank\">premium only</a>)"
     868msgstr ""
     869
     870#: inc/settings.php:1171
     871msgid "The WebP Express plugin is active. Please deactivate it in order to use correct WebP serving from <strong>Squeeze plugin</strong>."
     872msgstr ""
     873
     874#: inc/settings.php:1183
     875msgid "The Image Converter for WebP plugin is active. Please deactivate it in order to use correct WebP serving from <strong>Squeeze plugin</strong>."
     876msgstr ""
     877
     878#: squeeze.php:186
     879msgid "Confirmation email was sent! Please check your inbox to complete the Squeeze Premium setup."
     880msgstr ""
     881
     882#: assets/js/4240e511ac61ecfff2d8.js:299
     883#: assets/js/admin.bundle.js:49
     884#: assets/js/assets_js_squeeze_js-assets_js_worker_js.script.bundle.js:19
     885#: assets/js/editor.bundle.js:49
     886#: assets/js/script.bundle.js:49
     887#: assets/js/squeeze.js:65
     888#: assets/js/squeeze.js:494
     889msgid "Request timed out."
     890msgstr ""
     891
     892#: assets/js/4240e511ac61ecfff2d8.js:487
     893#: assets/js/admin.bundle.js:49
     894#: assets/js/assets_js_squeeze_js-assets_js_worker_js.script.bundle.js:19
     895#: assets/js/editor.bundle.js:49
     896#: assets/js/script.bundle.js:49
     897#: assets/js/squeeze.js:248
     898msgid "Skipped"
     899msgstr ""
     900
     901#: assets/js/admin.bundle.js:19
     902#: assets/js/admin.js:223
     903msgid "Please select at least one image."
     904msgstr ""
     905
     906#: assets/js/admin.bundle.js:19
     907#: assets/js/admin.bundle.js:29
     908#: assets/js/admin.js:239
     909#: assets/js/editor.bundle.js:29
     910#: assets/js/handlers.js:212
     911#: assets/js/handlers.js:619
     912#: assets/js/handlers copy.js:162
     913#: assets/js/handlers copy.js:513
     914#: assets/js/script.bundle.js:19
     915#: assets/js/script.bundle.js:39
     916#: assets/js/script.js:160
     917#: assets/js/script.js:166
     918msgid "Squeezing..."
     919msgstr ""
     920
     921#: assets/js/admin.bundle.js:19
     922#: assets/js/admin.js:246
     923msgid "All images have been processed."
     924msgstr ""
     925
     926#: assets/js/admin.bundle.js:19
     927#: assets/js/admin.bundle.js:29
     928#: assets/js/admin.js:251
     929#: assets/js/editor.bundle.js:29
     930#: assets/js/handlers.js:200
     931#: assets/js/handlers.js:420
     932#: assets/js/handlers.js:466
     933#: assets/js/handlers copy.js:150
     934#: assets/js/handlers copy.js:431
     935#: assets/js/handlers copy.js:477
     936#: assets/js/script.bundle.js:19
     937#: assets/js/script.bundle.js:39
     938#: assets/js/script.js:83
     939#: assets/js/script.js:182
     940msgid "An error has occured. Check the console for details."
     941msgstr ""
     942
     943#: assets/js/admin.bundle.js:29
     944#: assets/js/admin.bundle.js:39
     945#: assets/js/editor.bundle.js:29
     946#: assets/js/editor.bundle.js:39
     947#: assets/js/handlers.js:48
     948#: assets/js/handlers copy.js:290
     949#: assets/js/helpers.js:110
     950#: assets/js/script.bundle.js:19
    677951#: assets/js/script.bundle.js:29
    678 #: assets/js/script.js:707
    679 msgid "(<a href=\"%s\" target=\"_blank\">premium only</a>)"
    680 msgstr ""
    681 
    682 #: assets/js/4240e511ac61ecfff2d8.js:299
    683 #: assets/js/assets_js_squeeze_js-assets_js_worker_js.script.bundle.js:19
    684 #: assets/js/script.bundle.js:39
    685 #: assets/js/squeeze.js:51
    686 msgid "Request timed out."
    687 msgstr ""
    688 
    689 #: assets/js/4240e511ac61ecfff2d8.js:487
    690 #: assets/js/assets_js_squeeze_js-assets_js_worker_js.script.bundle.js:19
    691 #: assets/js/script.bundle.js:39
    692 #: assets/js/squeeze.js:198
    693 msgid "Skipped"
    694 msgstr ""
    695 
    696 #: assets/js/helpers.js:107
     952msgid "Media"
     953msgstr ""
     954
     955#: assets/js/admin.bundle.js:29
     956#: assets/js/editor.bundle.js:29
     957#: assets/js/handlers.js:73
     958#: assets/js/handlers.js:275
     959#: assets/js/handlers copy.js:23
     960#: assets/js/handlers copy.js:225
     961#: assets/js/script.bundle.js:19
     962msgid "Resume bulk squeezing"
     963msgstr ""
     964
     965#: assets/js/admin.bundle.js:29
     966#: assets/js/editor.bundle.js:29
     967#: assets/js/handlers.js:73
     968#: assets/js/handlers copy.js:23
     969#: assets/js/script.bundle.js:19
     970msgid "Pause bulk squeezing"
     971msgstr ""
     972
     973#: assets/js/admin.bundle.js:29
     974#: assets/js/editor.bundle.js:29
     975#: assets/js/handlers.js:145
     976#: assets/js/handlers copy.js:95
     977#: assets/js/script.bundle.js:19
     978msgid "Restore in process..."
     979msgstr ""
     980
     981#: assets/js/admin.bundle.js:29
     982#: assets/js/editor.bundle.js:29
     983#: assets/js/handlers.js:180
     984#: assets/js/handlers.js:447
     985#: assets/js/handlers copy.js:128
     986#: assets/js/handlers copy.js:458
     987#: assets/js/script.bundle.js:19
     988#: assets/js/script.bundle.js:39
     989#: assets/js/script.js:63
     990msgid "Pausing..."
     991msgstr ""
     992
     993#: assets/js/admin.bundle.js:29
     994#: assets/js/editor.bundle.js:29
     995#: assets/js/handlers.js:191
     996#: assets/js/handlers.js:458
     997#: assets/js/handlers copy.js:141
     998#: assets/js/handlers copy.js:469
     999#: assets/js/script.bundle.js:19
     1000#: assets/js/script.bundle.js:39
     1001#: assets/js/script.js:74
     1002msgid "All images have been processed!"
     1003msgstr ""
     1004
     1005#: assets/js/admin.bundle.js:29
     1006#: assets/js/editor.bundle.js:29
     1007#: assets/js/handlers.js:262
     1008#: assets/js/handlers copy.js:212
     1009#: assets/js/script.bundle.js:19
     1010msgid "Are you sure you want to leave this page? The squeezing process will be terminated!"
     1011msgstr ""
     1012
     1013#: assets/js/admin.bundle.js:29
     1014#: assets/js/editor.bundle.js:29
     1015#: assets/js/handlers.js:265
     1016#: assets/js/handlers copy.js:215
     1017#: assets/js/script.bundle.js:19
     1018msgid "Are you sure you want to leave this page? The settings will not be saved!"
     1019msgstr ""
     1020
     1021#: assets/js/admin.bundle.js:29
     1022#: assets/js/admin.bundle.js:39
     1023#: assets/js/editor.bundle.js:29
     1024#: assets/js/editor.bundle.js:39
     1025#: assets/js/handlers.js:271
     1026#: assets/js/handlers copy.js:221
     1027#: assets/js/helpers.js:110
    6971028#: assets/js/script.bundle.js:19
    6981029#: assets/js/script.bundle.js:29
    699 #: assets/js/script.js:50
    7001030msgid "Bulk squeezing has been paused!"
    7011031msgstr ""
    7021032
    703 #: assets/js/helpers.js:107
    704 #: assets/js/script.bundle.js:19
    705 msgid "Media"
    706 msgstr ""
    707 
    708 #: assets/js/helpers.js:116
    709 #: assets/js/helpers.js:120
    710 #: assets/js/script.bundle.js:19
     1033#: assets/js/admin.bundle.js:29
     1034#: assets/js/editor.bundle.js:29
     1035#: assets/js/handlers.js:306
     1036#: assets/js/handlers.js:313
     1037#: assets/js/handlers copy.js:312
     1038#: assets/js/handlers copy.js:320
     1039#: assets/js/script.bundle.js:19
     1040msgid "No more images found!"
     1041msgstr ""
     1042
     1043#: assets/js/admin.bundle.js:29
     1044#: assets/js/editor.bundle.js:29
     1045#: assets/js/handlers.js:320
     1046#: assets/js/handlers copy.js:331
     1047#: assets/js/parallel.js:35
     1048#: assets/js/script.bundle.js:19
     1049msgid "Start squeezing..."
     1050msgstr ""
     1051
     1052#: assets/js/admin.bundle.js:29
     1053#: assets/js/editor.bundle.js:29
     1054#: assets/js/handlers.js:407
     1055#: assets/js/handlers copy.js:420
     1056#: assets/js/script.bundle.js:19
     1057msgid "Found images on the page:"
     1058msgstr ""
     1059
     1060#: assets/js/admin.bundle.js:29
     1061#: assets/js/editor.bundle.js:29
     1062#: assets/js/handlers.js:416
     1063#: assets/js/handlers copy.js:427
     1064#: assets/js/script.bundle.js:19
     1065msgid "Error:"
     1066msgstr ""
     1067
     1068#: assets/js/admin.bundle.js:29
     1069#: assets/js/editor.bundle.js:29
     1070#: assets/js/handlers.js:423
     1071#: assets/js/handlers.js:426
     1072#: assets/js/handlers copy.js:434
     1073#: assets/js/handlers copy.js:437
     1074#: assets/js/script.bundle.js:19
     1075msgid "An error has occurred while fetching images from the page. Check the console for details."
     1076msgstr ""
     1077
     1078#: assets/js/admin.bundle.js:29
     1079#: assets/js/editor.bundle.js:29
     1080#: assets/js/handlers.js:638
     1081#: assets/js/script.bundle.js:19
     1082msgid "File is excluded from compression:"
     1083msgstr ""
     1084
     1085#: assets/js/admin.bundle.js:29
     1086#: assets/js/editor.bundle.js:29
     1087#: assets/js/handlers.js:647
     1088#: assets/js/script.bundle.js:19
     1089msgid "File compression failed:"
     1090msgstr ""
     1091
     1092#: assets/js/admin.bundle.js:39
     1093#: assets/js/editor.bundle.js:39
     1094#: assets/js/helpers.js:119
     1095#: assets/js/helpers.js:123
     1096#: assets/js/script.bundle.js:29
    7111097msgid "Show details"
    7121098msgstr ""
    7131099
    714 #: assets/js/helpers.js:120
    715 #: assets/js/script.bundle.js:19
     1100#: assets/js/admin.bundle.js:39
     1101#: assets/js/editor.bundle.js:39
     1102#: assets/js/helpers.js:123
     1103#: assets/js/script.bundle.js:29
    7161104msgid "Hide details"
    7171105msgstr ""
    7181106
    719 #: assets/js/helpers.js:183
    720 #: assets/js/script.bundle.js:19
     1107#: assets/js/admin.bundle.js:39
     1108#: assets/js/editor.bundle.js:39
     1109#: assets/js/helpers.js:190
     1110#: assets/js/script.bundle.js:29
    7211111msgid "No directories found!"
    7221112msgstr ""
    7231113
    724 #: assets/js/helpers.js:244
    725 #: assets/js/script.bundle.js:19
     1114#: assets/js/admin.bundle.js:39
     1115#: assets/js/editor.bundle.js:39
     1116#: assets/js/helpers.js:266
     1117#: assets/js/script.bundle.js:29
    7261118msgid "Error parsing path input!"
    7271119msgstr ""
    7281120
    729 #: assets/js/script.bundle.js:29
    730 #: assets/js/script.js:54
    731 #: assets/js/script.js:61
    732 msgid "Resume bulk squeezing"
    733 msgstr ""
    734 
    735 #: assets/js/script.bundle.js:29
    736 #: assets/js/script.js:61
    737 msgid "Pause bulk squeezing"
    738 msgstr ""
    739 
    740 #: assets/js/script.bundle.js:29
    741 #: assets/js/script.js:83
    742 msgid "Are you sure you want to leave this page? The squeezing process will be terminated!"
    743 msgstr ""
    744 
    745 #: assets/js/script.bundle.js:29
    746 #: assets/js/script.js:86
    747 msgid "Are you sure you want to leave this page? The settings will not be saved!"
    748 msgstr ""
    749 
    750 #: assets/js/script.bundle.js:29
    751 #: assets/js/script.js:134
    752 msgid "Restore in process..."
    753 msgstr ""
    754 
    755 #: assets/js/script.bundle.js:29
    756 #: assets/js/script.js:156
    757 #: assets/js/script.js:433
    758 #: assets/js/script.js:439
    759 #: assets/js/script.js:630
    760 msgid "Squeezing..."
    761 msgstr ""
    762 
    763 #: assets/js/script.bundle.js:29
    764 #: assets/js/script.js:186
    765 msgid "Start squeezing..."
    766 msgstr ""
    767 
    768 #: assets/js/script.bundle.js:29
    769 #: assets/js/script.js:273
    770 #: assets/js/script.js:340
    771 #: assets/js/script.js:522
    772 msgid "Pausing..."
    773 msgstr ""
    774 
    775 #: assets/js/script.bundle.js:29
    776 #: assets/js/script.js:284
    777 #: assets/js/script.js:351
     1121#: assets/js/editor.bundle.js:19
     1122#: assets/js/editor.js:80
     1123#: assets/js/editor__old.js:131
     1124msgid "Squeezing image…"
     1125msgstr ""
     1126
     1127#: assets/js/editor.bundle.js:19
     1128#: assets/js/editor.js:125
     1129#: assets/js/editor__old.js:30
     1130msgid "Error fetching attachment: %s"
     1131msgstr ""
     1132
     1133#: assets/js/editor.bundle.js:19
     1134#: assets/js/editor.js:158
     1135#: assets/js/editor__old.js:60
     1136msgid "Error uploading image: %s"
     1137msgstr ""
     1138
     1139#: assets/js/editor.bundle.js:19
     1140#: assets/js/editor.js:279
     1141msgid "Squeezing the image..."
     1142msgstr ""
     1143
     1144#: assets/js/editor.bundle.js:19
     1145#: assets/js/editor.js:342
     1146#: assets/js/editor.js:358
     1147msgid "Error squeezing the image: %s"
     1148msgstr ""
     1149
     1150#: assets/js/script.bundle.js:39
     1151#: assets/js/script.js:37
     1152msgid "Please enter a valid path!"
     1153msgstr ""
     1154
     1155#: assets/js/script.bundle.js:39
     1156#: assets/js/script.js:440
     1157msgid "Loading Preview..."
     1158msgstr ""
     1159
     1160#: assets/js/script.bundle.js:39
    7781161#: assets/js/script.js:533
    779 msgid "All images have been processed!"
    780 msgstr ""
    781 
    782 #: assets/js/script.bundle.js:29
    783 #: assets/js/script.js:293
    784 #: assets/js/script.js:360
    785 #: assets/js/script.js:455
    786 #: assets/js/script.js:495
    787 #: assets/js/script.js:541
    788 msgid "An error has occured. Check the console for details."
    789 msgstr ""
    790 
    791 #: assets/js/script.bundle.js:29
    792 #: assets/js/script.js:316
    793 msgid "Please enter a valid path!"
    794 msgstr ""
    795 
    796 #: assets/js/script.bundle.js:29
    797 #: assets/js/script.js:484
    798 msgid "Found images on the page:"
    799 msgstr ""
    800 
    801 #: assets/js/script.bundle.js:29
    802 #: assets/js/script.js:491
    803 msgid "Error:"
    804 msgstr ""
    805 
    806 #: assets/js/script.bundle.js:29
    807 #: assets/js/script.js:498
    808 #: assets/js/script.js:501
    809 msgid "An error has occurred while fetching images from the page. Check the console for details."
    810 msgstr ""
    811 
    812 #: assets/js/script.bundle.js:29
    813 #: assets/js/script.js:756
    814 msgid "Loading Preview..."
    815 msgstr ""
    816 
    817 #: assets/js/script.bundle.js:29
    818 #: assets/js/script.js:849
    819 #: assets/js/script.js:892
     1162#: assets/js/script.js:576
    8201163msgid "Collapse"
    8211164msgstr ""
    8221165
    823 #: assets/js/script.bundle.js:29
    824 #: assets/js/script.js:850
     1166#: assets/js/script.bundle.js:39
     1167#: assets/js/script.js:534
    8251168msgid "Apply"
    8261169msgstr ""
    8271170
    828 #: assets/js/script.bundle.js:29
    829 #: assets/js/script.js:865
     1171#: assets/js/script.bundle.js:39
     1172#: assets/js/script.js:549
    8301173msgid "An error occurred while rendering the preview. Check the console for details."
    8311174msgstr ""
    8321175
    833 #: assets/js/script.bundle.js:29
    834 #: assets/js/script.js:895
     1176#: assets/js/script.bundle.js:39
     1177#: assets/js/script.js:579
    8351178msgid "Expand"
    8361179msgstr ""
  • squeeze/trunk/readme.txt

    r3311866 r3345284  
    1 === Squeeze – Image Optimization & Compression, WebP Conversion ===
     1=== Squeeze – Image Optimization & Compression, WEBP Conversion ===
    22Contributors: barb0ss
    33Tags: image compression, convert webp, image optimization, compress images, optimize images
     
    55Tested up to: 6.8
    66Requires PHP: 7.3
    7 Stable tag: 1.6.7
     7Stable tag: 1.7.0
    88License: GPLv3
    99License URI: https://www.gnu.org/licenses/gpl-3.0.html
     
    1212
    1313== Description ==
    14 Squeeze plugin optimizes and compresses images on your website directly in your browser. It also converts your images to the modern WebP format.
    15 No extra server used, no limits for images compression.
    16 
    17 [Visit Squeeze official website.](https://pluginarium.com/squeeze/)
    18 
    19 == 🎉 Special Offer: Get 6 months of Premium for FREE! 🎉 ==
    20 I’ve got something exciting for you! The first 20 people to fill out the form on the site will **get Squeeze Premium absolutely FREE** for 6 months.
    21 
    22 No credit card or phone number required, I promise! Just your email and the website address where you'll be installing the Premium version.
    23 
    24 I'm eager to make Squeeze even better, and I need your help. By testing the plugin and sharing your feedback, complaints, and suggestions, you'll play a crucial role in its improvement.
    25 
    26 Don't miss this opportunity to enhance your website's performance and contribute to the development of a powerful tool. Fill out the form now and secure your spot!
    27 
    28 **[Get the Premium version for FREE here!](https://pluginarium.com/squeeze/get-squeeze-premium-for-free/)**
    29 
    30 == How does the Squeeze plugin work? ==
    31 Squeeze plugin compresses images directly from your WordPress Media Library or during the image upload process. All the work is handled directly inside your browser using advanced compression algorithms. That means there’s no third party service for compression images. Thus, you can be sure with the privacy of your images, ensuring data privacy and faster processing.
    32 
    33 [Full documentation is here.](https://pluginarium.com/squeeze/squeeze-documentation/)
    34 
    35 == Key Features ==
    36 * **Performance Boost:** Reduces image sizes to improve website loading speed and overall user experience.
     14Squeeze plugin optimizes and compresses images on your website directly in your browser.
     15It also converts your images to the modern WEBP format, saving your server's disk storage.
     16No third-party server used, no limits for images compression.
     17
     18[Squeeze official website](https://pluginarium.com/squeeze/) | [Plugin's documentation](https://pluginarium.com/squeeze/squeeze-documentation/)
     19
     20== 🌟 New Features in version 1.7 🌟 ==
     21* **Direct WEBP Conversion:** Converts JPG/PNG images to the WEBP format directly, replacing the original images. This will save your disk storage rapidly!
     22**It is recommended to use it for the newly uploaded images only! See the *«How are WEBP images served?»* question in the FAQ section down below.**
     23* **Squeeze images before upload:** Compresses newly added images before they are uploaded to the server. It lowers upload times and less wasted bandwidth on your server.
     24
     25== ✨ Key Features ✨ ==
     26* **Increase Page Speed:** Reduces image sizes to improve website loading speed and overall user experience.
    3727* **WEBP Conversion and Serving:** Convert images to the modern and efficient WEBP format and serve them seamlessly. The plugin adds .htaccess rules to serve WEBP images for supported browsers without changing URLs. Alternatively, enable the "Replace Image URLs" option to explicitly use WEBP versions on all pages.
    3828* **Client-Side Image Squeezing:** Compress images directly in the browser without sending files to external servers
    3929* **Upload Optimization:** Compresses images on-the-fly during the upload process, ensuring optimized images are added to your media library.
     30* **Gutenberg and GenerateBlocks Support:** Squeeze images directly on upload in Gutenberg or GenerateBlocks builder.
    4031* **Bulk Compression:** Allows you to compress multiple images at once from your WordPress Media Library.
    41 * **Custom Path Compression:** Select a folder on your site and compress all the images within that folder.
     32* **Custom Directory Compression:** Select a directory on your site and compress all the images within it.
    4233* **Selective Compression:** Choose which images to compress based on your preferences and requirements.
    4334* **Custom Squeezing Settings:** Adjust compression parameters such as quality level to suit your specific needs.
    4435* **Backup Option:** Creates a backup file to restore a compressed image to the original image.
    45 * **Wide Format Support:** Squeezes images in popular formats, including JPEG, PNG, AVIF, and WebP.
    46 
    47 == Premium Features ==
    48 * **Image Comparison:** Compare original and Squeezed image directly in the Media Library.
     36* **Wide Format Support:** Squeezes images in popular formats, including JPEG, PNG, AVIF, and WEBP.
     37
     38== ⚜️ Premium Features ⚜️ ==
     39* **Image Comparison:** Compare original and Squeezed images directly in the Media Library.
    4940* **Resize Original Image:** Set maximum width and height for the original image.
    5041* **Bulk Squeeze from a Page:** Compress all images from a specific page.
     
    5647**[Explore the Premium version here.](https://pluginarium.com/squeeze/#premium)**
    5748
     49== How does the Squeeze plugin work? ==
     50Squeeze plugin compresses images directly from your WordPress Media Library or during the image upload process. All the work is handled directly inside your browser using advanced compression algorithms. That means there’s no third party service for compression images. Thus, you can be sure with the privacy of your images, ensuring data privacy and faster processing.
     51
     52[Plugin's documentation is available here.](https://pluginarium.com/squeeze/squeeze-documentation/)
     53
    5854== Installation ==
    59551. Download the plugin ZIP file from the WordPress Plugin Directory, or install the plugin via the WordPress plugin installer.
    60562. Extract the ZIP file (if downloaded from WordPress Plugin Directory).
    61 3. Upload the plugin folder to the wp-content/plugins/ directory of your WordPress installation.
     573. Upload the plugin directory to the wp-content/plugins/ directory of your WordPress installation.
    62584. Activate the Squeeze plugin from the WordPress plugins dashboard.
    6359
     
    8682= Can this plugin convert images to the WEBP format? =
    8783
    88 Yes! The Squeeze plugin supports converting images to the WEBP format during the compression process. WEBP is a modern image format that provides superior compression while maintaining high quality, resulting in faster loading times and reduced bandwidth usage. To enable this feature, simply check the "Generate WEBP" option under the Basic Settings tab to output images in WEBP format.
     84Yes! The Squeeze plugin supports converting images to the WEBP format during the compression process. WEBP is a modern image format that provides superior compression while maintaining high quality, resulting in faster loading times and reduced bandwidth usage. To enable this feature, check the "Direct WEBP Conversion" option under the Basic Settings tab to convert images in WEBP format.
    8985
    9086= How are WEBP images served? =
    9187
    92 By default, the Squeeze plugin adds rules to your .htaccess file to serve WEBP images automatically. This means that when a browser supports the WEBP format, the corresponding WEBP version of an image will be served without changing the original image's URL. This allows seamless integration without disrupting your website's existing structure.
    93 If you enable the "Replace Images URLs" option in the plugin settings, the plugin will directly replace all image URLs on your pages with their corresponding WEBP versions. This can be useful for ensuring that WEBP images are explicitly used everywhere on your site.
    94 The generated WEBP images are stored in the wp-content/squeeze-webp folder within your WordPress installation.
     88Squeeze plugin converts your JPG/PNG images into WEBP format replacing the original images.
     89To enable this feature, check the "Direct WEBP Conversion" option under the Basic Settings tab to convert images in WEBP format.
     90
     91**ATTENTION! It is highly recommended to use the "Direct WEBP Conversion" feature only to the newly uploaded images.
     92Otherwise, your existing JPG/PNG images may be broken on your site's frontend because of non-existed URLs.**
     93
     94That means if you have an image in JPG format like `image.jpg`, after conversion to WEBP format it becomes `image.webp`.
     95The existing image on your site's page with URL like `//yoursite.com/wp-content/uploads/2025/08/image.jpg` will be broken, because there is no more `image.jpg` file on your server.
     96So you need to update your image manually for such cases (usually just to re-select it from the Media Library when you edit your page).
     97
     98Previously, the generated WEBP images were stored in the wp-content/squeeze-webp directory within your WordPress installation.
     99That method is not very optimal, because it creates extra images which reduce your server's storage space.
     100However, if you already used that approach, you can keep it enabled for backwards compatibility.
    95101
    96102= Which scripts are used for compressing and converting images?
     
    99105
    100106* MozJPEG: Used for compressing JPEG images.
    101 * Browser Image Compression: Used for compressing PNG images. This is not come from the Squoosh.app, as its OxiPNG takes quite a long time to compress images.
    102 * WebP: Used for converting and compressing images to the modern WEBP format.
     107* Browser Image Compression: Used for compressing PNG images. This does not come from the Squoosh.app, as its OxiPNG takes quite a long time to compress images.
     108* WEBP: Used for converting and compressing images to the modern WEBP format.
    103109* AVIF: An advanced codec for creating lightweight and high-quality AVIF images.
    104110
     
    115121Yes, the plugin provides a bulk compression feature. This saves time and effort compared to compressing images individually.
    116122
    117 = Can I compress images NOT from the Media Library, but from a custom folder? =
    118 
    119 Yes, you can compress images from any folder within your WordPress installation.
     123= Can I compress images NOT from the Media Library, but from a custom directory? =
     124
     125Yes, you can compress images from any directory within your WordPress installation.
    120126
    121127= Can I customize the compression settings? =
     
    128134
    129135== Screenshots ==
    130 1. Compressed image with the Squeeze Plugin
     1361. Compressed image with Squeeze Plugin
    1311372. Squeeze's Bulk Compression Page
    1321383. Squeeze's Restore and Recompress Options
    133 4. Serving WEBP images instead of JPG and PNG. Even though the URL of the image remains the same, the response is in the WEBP format.
    134 5. Replacing images URLs with the corresponding WEBP version. If your server does not support .htaccess file or it is not writable, then you can use this option to replace your images URLs and serve WEBP images.
     1394. Direct conversion of an image into WEBP format. The original image is being replaced by the compressed image in WEBP format.
     1405. A method of replacing images URLs with the corresponding WEBP versions.
    1351416. Squeeze's Basic Settings
    1361427. Squeeze's JPEG compression settings
    1371438. Squeeze's PNG compression settings
    138 9. Squeeze's WebP compression settings
     1449. Squeeze's WEBP compression settings
    13914510. Squeeze's AVIF compression settings
    14014611. Squeeze's Bulk actions in the List view of the Media Library
    14114712. Squeeze's Filter in the Grid view of the Media Library
    142 13. Preview image with live Squeezing options (Premium feature)
    143 14. Bulk Squeeze from a page (Premium feature)
     14813. Squeeze images directly on upload in Gutenberg or GenerateBlocks builder.
     14914. Preview image with live Squeezing options (Premium feature)
     15015. Bulk Squeeze from a page (Premium feature)
    144151
    145152== Changelog ==
     153= 1.7.0 =
     154* Added direct WEBP conversion option
     155* Compress newly uploaded images immediately, before they being uploaded to the server
     156* Skip uploading the compressed image, if it becomes larger than original after compression
     157* Fixed account tab on the Settings page
     158* Added explanation screenshots for some options on the Settings page
    146159= 1.6.7 =
    147160* Added auto-squeezing for the images uploaded via Image block
     
    165178* Refactored PHP and JS code
    166179= 1.5.2 =
    167 * Fixed webp convertion
     180* Fixed WEBP conversion
    168181* Added option to select image formats
    169182= 1.5.1 =
     
    206219* Update settings page layout with tabs
    207220* Add ability to re-compress images
    208 * Add ability to compress images from custom folder
     221* Add ability to compress images from custom directory
    209222= 1.2 =
    210223* Fix minor bug in Media library
     
    215228
    216229== Upgrade Notice ==
     230= 1.7.0 =
     231* Added direct WEBP conversion option
     232* Compress newly uploaded images immediately, not after they being uploaded to the server
     233* Skip uploading the compressed image, if it becomes larger than original after compression
     234* Fixed account tab on the Settings page
     235* Added explanation screenshots for some options on the Settings page
    217236= 1.6.5 =
    218237* Added bulk Squeeze in the Grid mode
     
    232251* Refactored JS: exploded complex functions, add html templates to separate business logic from layouts
    233252= 1.5.2 =
    234 * Fixed webp convertion
     253* Fixed WEBP conversion
    235254* Added option to select image formats
    236255= 1.5.1 =
     
    267286* Update settings page layout with tabs
    268287* Add ability to re-compress images
    269 * Add ability to compress images from custom folder
     288* Add ability to compress images from custom directory
    270289= 1.2 =
    271290* Fix minor bug in Media library
  • squeeze/trunk/squeeze.php

    r3311866 r3345284  
    66 * Author URI:  https://pluginarium.com
    77 * Author:      Bogdan Bendziukov
    8  * Version:     1.6.7
     8 * Version:     1.7.0
    99 *
    1010 * Text Domain: squeeze
     
    2222    exit;
    2323}
     24
    2425class SqueezeInit {
    2526    /**
    2627     * Plugin version
    2728     */
    28     const VERSION = '1.6.7';
     29    const VERSION = '1.7.0';
    2930
    3031    const CHECKOUT_URL = 'https://checkout.freemius.com/plugin/17217/plan/28703/';
     
    9192        );
    9293        add_action( 'enqueue_block_editor_assets', array($this, 'load_editor_assets') );
     94        add_action( 'squeeze_freemius_loaded', array($this, 'load_freemius') );
    9395    }
    9496
     
    101103
    102104    public function load_freemius() {
     105    }
     106
     107    public function opt_in_freemius() {
     108    }
     109
     110    public function freemius_admin_notices() {
    103111    }
    104112
     
    162170                'ajaxUrl'      => admin_url( 'admin-ajax.php' ),
    163171                'nonce'        => wp_create_nonce( 'squeeze-nonce' ),
     172                'restNonce'    => wp_create_nonce( 'wp_rest' ),
    164173                'options'      => wp_json_encode( $js_options ),
    165174                'templateBase' => self::$PLUGIN_URL . 'assets/templates/',
Note: See TracChangeset for help on using the changeset viewer.