From 86f8a7c9772599bc072e9aa145f7f8f0bf62a01c Mon Sep 17 00:00:00 2001 From: 3rdIteration Date: Tue, 7 Jul 2026 03:53:36 +1000 Subject: [PATCH 01/22] feat: add LilyGO T-Deck support + CI build + web flasher --- .github/workflows/build.yml | 68 ++++ .gitignore | 1 + configs/sdkconfig_display_tdeck.defaults | 84 ++++ flasher/branding/logo.svg | 4 + flasher/index.html | 468 +++++++++++++++++++++++ flasher/vendor/esptool-js-0.6.0.js | 2 + flasher/vendor/jszip-3.10.1.min.js | 13 + main/Kconfig.projbuild | 34 +- main/input.c | 2 + main/input/tdeck.inc | 102 +++++ main/power.c | 2 + main/power/tdeck.inc | 152 ++++++++ main/process/dashboard.c | 4 +- main/ui/dashboard.c | 2 +- tools/switch_to.sh | 1 + 15 files changed, 926 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/build.yml create mode 100644 configs/sdkconfig_display_tdeck.defaults create mode 100644 flasher/branding/logo.svg create mode 100644 flasher/index.html create mode 100644 flasher/vendor/esptool-js-0.6.0.js create mode 100644 flasher/vendor/jszip-3.10.1.min.js create mode 100644 main/input/tdeck.inc create mode 100644 main/power/tdeck.inc diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..d04ea4243 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,68 @@ +name: Build T-Deck + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + runs-on: ubuntu-latest + container: espressif/idf:v5.5.4 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Build T-Deck firmware + run: | + cp configs/sdkconfig_display_tdeck.defaults sdkconfig.defaults + idf.py -B build_tdeck set-target esp32s3 + idf.py -B build_tdeck build + + - name: Stage firmware artifacts + run: | + mkdir -p firmware-tdeck/bootloader firmware-tdeck/partition_table + cp build_tdeck/bootloader/bootloader.bin firmware-tdeck/bootloader/ + cp build_tdeck/partition_table/partition-table.bin firmware-tdeck/partition_table/ + cp build_tdeck/ota_data_initial.bin firmware-tdeck/ 2>/dev/null || true + cp build_tdeck/jade.bin firmware-tdeck/ 2>/dev/null || true + cp build_tdeck/flasher_args.json firmware-tdeck/ 2>/dev/null || true + echo "Firmware staged:" + find firmware-tdeck -type f | sort + + - name: Upload firmware artifact + uses: actions/upload-artifact@v4 + with: + name: firmware-tdeck + path: firmware-tdeck/ + retention-days: 90 + + deploy: + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + needs: build + runs-on: ubuntu-latest + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - uses: actions/checkout@v4 + + - name: Download firmware artifact + uses: actions/download-artifact@v4 + with: + name: firmware-tdeck + path: flasher/firmware/tdeck/ + + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@v3 + with: + path: flasher/ + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index 40f79dadc..3710179b1 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ dist/ jade_client.egg-info/ docs/_build/ **/nvs_flash.bin +flasher/firmware/ diff --git a/configs/sdkconfig_display_tdeck.defaults b/configs/sdkconfig_display_tdeck.defaults new file mode 100644 index 000000000..7cca5a62a --- /dev/null +++ b/configs/sdkconfig_display_tdeck.defaults @@ -0,0 +1,84 @@ +# display tdeck +CONFIG_APP_REPRODUCIBLE_BUILD=y +CONFIG_BF20A6_SUPPORT=n +CONFIG_BF3005_SUPPORT=n +CONFIG_BOARD_TYPE_TDECK=y +CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y +CONFIG_BOOTLOADER_LOG_LEVEL_NONE=y +CONFIG_BOOTLOADER_WDT_ENABLE=n +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=517 +CONFIG_BT_NIMBLE_ENABLED=y +CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=11 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5632 +CONFIG_BT_NIMBLE_LOG_LEVEL_NONE=y +CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1 +CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=y +CONFIG_BT_NIMBLE_NVS_PERSIST=y +CONFIG_BT_NIMBLE_ROLE_BROADCASTER=n +CONFIG_BT_NIMBLE_ROLE_CENTRAL=n +CONFIG_BT_NIMBLE_ROLE_OBSERVER=n +CONFIG_BT_NIMBLE_SM_LEGACY=n +CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="j" +CONFIG_BUTTON_LONG_PRESS_HOLD_SERIAL_TIME_MS=100 +CONFIG_BUTTON_LONG_PRESS_TIME_MS=500 +CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_STACK_CHECK_MODE_STRONG=y +CONFIG_COMPILER_WARN_WRITE_STRINGS=y +CONFIG_DEBUG_MODE=y +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y +CONFIG_ESP_CONSOLE_NONE=y +CONFIG_ESP_CONSOLE_SECONDARY_NONE=y +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y +CONFIG_ESP_ERR_TO_NAME_LOOKUP=n +CONFIG_ESP_MAIN_TASK_STACK_SIZE=12288 +CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=n +CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND=n +CONFIG_ESP_SYSTEM_BBPLL_RECALIB=n +CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y +CONFIG_ESP_TASK_WDT_EN=n +CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=n +CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=n +CONFIG_ESP_WIFI_IRAM_OPT=n +CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=n +CONFIG_ESP_WIFI_NVS_ENABLED=n +CONFIG_ESP_WIFI_RX_IRAM_OPT=n +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n +CONFIG_FATFS_LFN_HEAP=y +CONFIG_FATFS_VFS_FSTAT_BLKSIZE=4096 +CONFIG_FATFS_VOLUME_COUNT=1 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=3 +CONFIG_GC0308_SUPPORT=n +CONFIG_GC032A_SUPPORT=n +CONFIG_GC2145_SUPPORT=n +CONFIG_IDF_TARGET="esp32s3" +CONFIG_LIBC_NEWLIB_NANO_FORMAT=y +CONFIG_LOG_DEFAULT_LEVEL_NONE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_NT99141_SUPPORT=n +CONFIG_OV2640_SUPPORT=n +CONFIG_OV3660_SUPPORT=n +CONFIG_OV5640_SUPPORT=n +CONFIG_OV7670_SUPPORT=n +CONFIG_OV7725_SUPPORT=n +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitionss3.csv" +CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP=n +CONFIG_SC030IOT_SUPPORT=n +CONFIG_SPIRAM=y +CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y +CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y +CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=256 +CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=65536 +CONFIG_SPIRAM_MEMTEST=n +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_RODATA=y +CONFIG_SPIRAM_SPEED_80M=y +CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y +CONFIG_SPI_FLASH_VERIFY_WRITE=y +CONFIG_SPI_MASTER_ISR_IN_IRAM=n +CONFIG_SPI_SLAVE_ISR_IN_IRAM=n +CONFIG_TINYUSB_CDC_ENABLED=y +CONFIG_TINYUSB_CDC_RX_BUFSIZE=64 diff --git a/flasher/branding/logo.svg b/flasher/branding/logo.svg new file mode 100644 index 000000000..bac90b1f0 --- /dev/null +++ b/flasher/branding/logo.svg @@ -0,0 +1,4 @@ + + + Jade + diff --git a/flasher/index.html b/flasher/index.html new file mode 100644 index 000000000..574e5bdc4 --- /dev/null +++ b/flasher/index.html @@ -0,0 +1,468 @@ + + + + + + Jade Web Flasher + + + + +
+
+ + + J + +
+

Jade Web Flasher

+ Flash firmware to your device from the browser +
+
+ +
+ Your browser does not support Web Serial. Use Chrome or Edge version 89+. +
+ +
+
Board
+ +
+
+ +
+ + +
+ +
+
+
Firmware Source
+

+ Downloads the latest firmware built from the master branch. +

+
BoardLilyGO T-Deck
+
Chip
+
Flash
+
+
+ +
+
+
Upload Firmware ZIP
+

+ Download a firmware-tdeck.zip artifact from the + Actions tab + and drop it here. +

+
+

Drop ZIP file here or click to browse

+

Supports firmware-tdeck.zip artifacts from CI

+
+ +
+ +
+ +
+ +
+ + + +
+ Ready. Select a firmware source and click "Flash Firmware". +
+
+ + + + + diff --git a/flasher/vendor/esptool-js-0.6.0.js b/flasher/vendor/esptool-js-0.6.0.js new file mode 100644 index 000000000..efa58874e --- /dev/null +++ b/flasher/vendor/esptool-js-0.6.0.js @@ -0,0 +1,2 @@ +class A extends Error{} +/*! pako 2.1.0 https://github.com/nodeca/pako @license (MIT AND Zlib) */function t(A){let t=A.length;for(;--t>=0;)A[t]=0}const e=256,i=286,s=30,a=15,E=new Uint8Array([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]),n=new Uint8Array([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]),r=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]),h=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),g=new Array(576);t(g);const o=new Array(60);t(o);const B=new Array(512);t(B);const w=new Array(256);t(w);const c=new Array(29);t(c);const _=new Array(s);function C(A,t,e,i,s){this.static_tree=A,this.extra_bits=t,this.extra_base=e,this.elems=i,this.max_length=s,this.has_stree=A&&A.length}let I,l,R;function D(A,t){this.dyn_tree=A,this.max_code=0,this.stat_desc=t}t(_);const d=A=>A<256?B[A]:B[256+(A>>>7)],S=(A,t)=>{A.pending_buf[A.pending++]=255&t,A.pending_buf[A.pending++]=t>>>8&255},M=(A,t,e)=>{A.bi_valid>16-e?(A.bi_buf|=t<>16-A.bi_valid,A.bi_valid+=e-16):(A.bi_buf|=t<{M(A,e[2*t],e[2*t+1])},F=(A,t)=>{let e=0;do{e|=1&A,A>>>=1,e<<=1}while(--t>0);return e>>>1},f=(A,t,e)=>{const i=new Array(16);let s,E,n=0;for(s=1;s<=a;s++)n=n+e[s-1]<<1,i[s]=n;for(E=0;E<=t;E++){let t=A[2*E+1];0!==t&&(A[2*E]=F(i[t]++,t))}},T=A=>{let t;for(t=0;t{A.bi_valid>8?S(A,A.bi_buf):A.bi_valid>0&&(A.pending_buf[A.pending++]=A.bi_buf),A.bi_buf=0,A.bi_valid=0},P=(A,t,e,i)=>{const s=2*t,a=2*e;return A[s]{const i=A.heap[e];let s=e<<1;for(;s<=A.heap_len&&(s{let s,a,r,h,g=0;if(0!==A.sym_next)do{s=255&A.pending_buf[A.sym_buf+g++],s+=(255&A.pending_buf[A.sym_buf+g++])<<8,a=A.pending_buf[A.sym_buf+g++],0===s?Q(A,a,t):(r=w[a],Q(A,r+e+1,t),h=E[r],0!==h&&(a-=c[r],M(A,a,h)),s--,r=d(s),Q(A,r,i),h=n[r],0!==h&&(s-=_[r],M(A,s,h)))}while(g{const e=t.dyn_tree,i=t.stat_desc.static_tree,s=t.stat_desc.has_stree,E=t.stat_desc.elems;let n,r,h,g=-1;for(A.heap_len=0,A.heap_max=573,n=0;n>1;n>=1;n--)O(A,e,n);h=E;do{n=A.heap[1],A.heap[1]=A.heap[A.heap_len--],O(A,e,1),r=A.heap[1],A.heap[--A.heap_max]=n,A.heap[--A.heap_max]=r,e[2*h]=e[2*n]+e[2*r],A.depth[h]=(A.depth[n]>=A.depth[r]?A.depth[n]:A.depth[r])+1,e[2*n+1]=e[2*r+1]=h,A.heap[1]=h++,O(A,e,1)}while(A.heap_len>=2);A.heap[--A.heap_max]=A.heap[1],((A,t)=>{const e=t.dyn_tree,i=t.max_code,s=t.stat_desc.static_tree,E=t.stat_desc.has_stree,n=t.stat_desc.extra_bits,r=t.stat_desc.extra_base,h=t.stat_desc.max_length;let g,o,B,w,c,_,C=0;for(w=0;w<=a;w++)A.bl_count[w]=0;for(e[2*A.heap[A.heap_max]+1]=0,g=A.heap_max+1;g<573;g++)o=A.heap[g],w=e[2*e[2*o+1]+1]+1,w>h&&(w=h,C++),e[2*o+1]=w,o>i||(A.bl_count[w]++,c=0,o>=r&&(c=n[o-r]),_=e[2*o],A.opt_len+=_*(w+c),E&&(A.static_len+=_*(s[2*o+1]+c)));if(0!==C){do{for(w=h-1;0===A.bl_count[w];)w--;A.bl_count[w]--,A.bl_count[w+1]+=2,A.bl_count[h]--,C-=2}while(C>0);for(w=h;0!==w;w--)for(o=A.bl_count[w];0!==o;)B=A.heap[--g],B>i||(e[2*B+1]!==w&&(A.opt_len+=(w-e[2*B+1])*e[2*B],e[2*B+1]=w),o--)}})(A,t),f(e,g,A.bl_count)},y=(A,t,e)=>{let i,s,a=-1,E=t[1],n=0,r=7,h=4;for(0===E&&(r=138,h=3),t[2*(e+1)+1]=65535,i=0;i<=e;i++)s=E,E=t[2*(i+1)+1],++n{let i,s,a=-1,E=t[1],n=0,r=7,h=4;for(0===E&&(r=138,h=3),i=0;i<=e;i++)if(s=E,E=t[2*(i+1)+1],!(++n{M(A,0+(i?1:0),3),U(A),S(A,e),S(A,~e),e&&A.pending_buf.set(A.window.subarray(t,t+e),A.pending),A.pending+=e};var Y=(A,t,i,s)=>{let a,E,n=0;A.level>0?(2===A.strm.data_type&&(A.strm.data_type=(A=>{let t,i=4093624447;for(t=0;t<=31;t++,i>>>=1)if(1&i&&0!==A.dyn_ltree[2*t])return 0;if(0!==A.dyn_ltree[18]||0!==A.dyn_ltree[20]||0!==A.dyn_ltree[26])return 1;for(t=32;t{let t;for(y(A,A.dyn_ltree,A.l_desc.max_code),y(A,A.dyn_dtree,A.d_desc.max_code),p(A,A.bl_desc),t=18;t>=3&&0===A.bl_tree[2*h[t]+1];t--);return A.opt_len+=3*(t+1)+5+5+4,t})(A),a=A.opt_len+3+7>>>3,E=A.static_len+3+7>>>3,E<=a&&(a=E)):a=E=i+5,i+4<=a&&-1!==t?H(A,t,i,s):4===A.strategy||E===a?(M(A,2+(s?1:0),3),u(A,g,o)):(M(A,4+(s?1:0),3),((A,t,e,i)=>{let s;for(M(A,t-257,5),M(A,e-1,5),M(A,i-4,4),s=0;s{k||((()=>{let A,t,e,h,D;const d=new Array(16);for(e=0,h=0;h<28;h++)for(c[h]=e,A=0;A<1<>=7;h(A.pending_buf[A.sym_buf+A.sym_next++]=t,A.pending_buf[A.sym_buf+A.sym_next++]=t>>8,A.pending_buf[A.sym_buf+A.sym_next++]=i,0===t?A.dyn_ltree[2*i]++:(A.matches++,t--,A.dyn_ltree[2*(w[i]+e+1)]++,A.dyn_dtree[2*d(t)]++),A.sym_next===A.sym_end),_tr_align:A=>{M(A,2,3),Q(A,256,g),(A=>{16===A.bi_valid?(S(A,A.bi_buf),A.bi_buf=0,A.bi_valid=0):A.bi_valid>=8&&(A.pending_buf[A.pending++]=255&A.bi_buf,A.bi_buf>>=8,A.bi_valid-=8)})(A)}};var b=(A,t,e,i)=>{let s=65535&A,a=A>>>16&65535,E=0;for(;0!==e;){E=e>2e3?2e3:e,e-=E;do{s=s+t[i++]|0,a=a+s|0}while(--E);s%=65521,a%=65521}return s|a<<16};const x=new Uint32Array((()=>{let A,t=[];for(var e=0;e<256;e++){A=e;for(var i=0;i<8;i++)A=1&A?3988292384^A>>>1:A>>>1;t[e]=A}return t})());var K=(A,t,e,i)=>{const s=x,a=i+e;A^=-1;for(let e=i;e>>8^s[255&(A^t[e])];return~A},L={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"},N={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8};const{_tr_init:J,_tr_stored_block:v,_tr_flush_block:z,_tr_tally:j,_tr_align:W}=m,{Z_NO_FLUSH:Z,Z_PARTIAL_FLUSH:X,Z_FULL_FLUSH:V,Z_FINISH:q,Z_BLOCK:$,Z_OK:AA,Z_STREAM_END:tA,Z_STREAM_ERROR:eA,Z_DATA_ERROR:iA,Z_BUF_ERROR:sA,Z_DEFAULT_COMPRESSION:aA,Z_FILTERED:EA,Z_HUFFMAN_ONLY:nA,Z_RLE:rA,Z_FIXED:hA,Z_DEFAULT_STRATEGY:gA,Z_UNKNOWN:oA,Z_DEFLATED:BA}=N,wA=258,cA=262,_A=42,CA=113,IA=666,lA=(A,t)=>(A.msg=L[t],t),RA=A=>2*A-(A>4?9:0),DA=A=>{let t=A.length;for(;--t>=0;)A[t]=0},dA=A=>{let t,e,i,s=A.w_size;t=A.hash_size,i=t;do{e=A.head[--i],A.head[i]=e>=s?e-s:0}while(--t);t=s,i=t;do{e=A.prev[--i],A.prev[i]=e>=s?e-s:0}while(--t)};let SA=(A,t,e)=>(t<{const t=A.state;let e=t.pending;e>A.avail_out&&(e=A.avail_out),0!==e&&(A.output.set(t.pending_buf.subarray(t.pending_out,t.pending_out+e),A.next_out),A.next_out+=e,t.pending_out+=e,A.total_out+=e,A.avail_out-=e,t.pending-=e,0===t.pending&&(t.pending_out=0))},QA=(A,t)=>{z(A,A.block_start>=0?A.block_start:-1,A.strstart-A.block_start,t),A.block_start=A.strstart,MA(A.strm)},FA=(A,t)=>{A.pending_buf[A.pending++]=t},fA=(A,t)=>{A.pending_buf[A.pending++]=t>>>8&255,A.pending_buf[A.pending++]=255&t},TA=(A,t,e,i)=>{let s=A.avail_in;return s>i&&(s=i),0===s?0:(A.avail_in-=s,t.set(A.input.subarray(A.next_in,A.next_in+s),e),1===A.state.wrap?A.adler=b(A.adler,t,s,e):2===A.state.wrap&&(A.adler=K(A.adler,t,s,e)),A.next_in+=s,A.total_in+=s,s)},UA=(A,t)=>{let e,i,s=A.max_chain_length,a=A.strstart,E=A.prev_length,n=A.nice_match;const r=A.strstart>A.w_size-cA?A.strstart-(A.w_size-cA):0,h=A.window,g=A.w_mask,o=A.prev,B=A.strstart+wA;let w=h[a+E-1],c=h[a+E];A.prev_length>=A.good_match&&(s>>=2),n>A.lookahead&&(n=A.lookahead);do{if(e=t,h[e+E]===c&&h[e+E-1]===w&&h[e]===h[a]&&h[++e]===h[a+1]){a+=2,e++;do{}while(h[++a]===h[++e]&&h[++a]===h[++e]&&h[++a]===h[++e]&&h[++a]===h[++e]&&h[++a]===h[++e]&&h[++a]===h[++e]&&h[++a]===h[++e]&&h[++a]===h[++e]&&aE){if(A.match_start=t,E=i,i>=n)break;w=h[a+E-1],c=h[a+E]}}}while((t=o[t&g])>r&&0!=--s);return E<=A.lookahead?E:A.lookahead},PA=A=>{const t=A.w_size;let e,i,s;do{if(i=A.window_size-A.lookahead-A.strstart,A.strstart>=t+(t-cA)&&(A.window.set(A.window.subarray(t,t+t-i),0),A.match_start-=t,A.strstart-=t,A.block_start-=t,A.insert>A.strstart&&(A.insert=A.strstart),dA(A),i+=t),0===A.strm.avail_in)break;if(e=TA(A.strm,A.window,A.strstart+A.lookahead,i),A.lookahead+=e,A.lookahead+A.insert>=3)for(s=A.strstart-A.insert,A.ins_h=A.window[s],A.ins_h=SA(A,A.ins_h,A.window[s+1]);A.insert&&(A.ins_h=SA(A,A.ins_h,A.window[s+3-1]),A.prev[s&A.w_mask]=A.head[A.ins_h],A.head[A.ins_h]=s,s++,A.insert--,!(A.lookahead+A.insert<3)););}while(A.lookahead{let e,i,s,a=A.pending_buf_size-5>A.w_size?A.w_size:A.pending_buf_size-5,E=0,n=A.strm.avail_in;do{if(e=65535,s=A.bi_valid+42>>3,A.strm.avail_outi+A.strm.avail_in&&(e=i+A.strm.avail_in),e>s&&(e=s),e>8,A.pending_buf[A.pending-2]=~e,A.pending_buf[A.pending-1]=~e>>8,MA(A.strm),i&&(i>e&&(i=e),A.strm.output.set(A.window.subarray(A.block_start,A.block_start+i),A.strm.next_out),A.strm.next_out+=i,A.strm.avail_out-=i,A.strm.total_out+=i,A.block_start+=i,e-=i),e&&(TA(A.strm,A.strm.output,A.strm.next_out,e),A.strm.next_out+=e,A.strm.avail_out-=e,A.strm.total_out+=e)}while(0===E);return n-=A.strm.avail_in,n&&(n>=A.w_size?(A.matches=2,A.window.set(A.strm.input.subarray(A.strm.next_in-A.w_size,A.strm.next_in),0),A.strstart=A.w_size,A.insert=A.strstart):(A.window_size-A.strstart<=n&&(A.strstart-=A.w_size,A.window.set(A.window.subarray(A.w_size,A.w_size+A.strstart),0),A.matches<2&&A.matches++,A.insert>A.strstart&&(A.insert=A.strstart)),A.window.set(A.strm.input.subarray(A.strm.next_in-n,A.strm.next_in),A.strstart),A.strstart+=n,A.insert+=n>A.w_size-A.insert?A.w_size-A.insert:n),A.block_start=A.strstart),A.high_waters&&A.block_start>=A.w_size&&(A.block_start-=A.w_size,A.strstart-=A.w_size,A.window.set(A.window.subarray(A.w_size,A.w_size+A.strstart),0),A.matches<2&&A.matches++,s+=A.w_size,A.insert>A.strstart&&(A.insert=A.strstart)),s>A.strm.avail_in&&(s=A.strm.avail_in),s&&(TA(A.strm,A.window,A.strstart,s),A.strstart+=s,A.insert+=s>A.w_size-A.insert?A.w_size-A.insert:s),A.high_water>3,s=A.pending_buf_size-s>65535?65535:A.pending_buf_size-s,a=s>A.w_size?A.w_size:s,i=A.strstart-A.block_start,(i>=a||(i||t===q)&&t!==Z&&0===A.strm.avail_in&&i<=s)&&(e=i>s?s:i,E=t===q&&0===A.strm.avail_in&&e===i?1:0,v(A,A.block_start,e,E),A.block_start+=e,MA(A.strm)),E?3:1)},uA=(A,t)=>{let e,i;for(;;){if(A.lookahead=3&&(A.ins_h=SA(A,A.ins_h,A.window[A.strstart+3-1]),e=A.prev[A.strstart&A.w_mask]=A.head[A.ins_h],A.head[A.ins_h]=A.strstart),0!==e&&A.strstart-e<=A.w_size-cA&&(A.match_length=UA(A,e)),A.match_length>=3)if(i=j(A,A.strstart-A.match_start,A.match_length-3),A.lookahead-=A.match_length,A.match_length<=A.max_lazy_match&&A.lookahead>=3){A.match_length--;do{A.strstart++,A.ins_h=SA(A,A.ins_h,A.window[A.strstart+3-1]),e=A.prev[A.strstart&A.w_mask]=A.head[A.ins_h],A.head[A.ins_h]=A.strstart}while(0!=--A.match_length);A.strstart++}else A.strstart+=A.match_length,A.match_length=0,A.ins_h=A.window[A.strstart],A.ins_h=SA(A,A.ins_h,A.window[A.strstart+1]);else i=j(A,0,A.window[A.strstart]),A.lookahead--,A.strstart++;if(i&&(QA(A,!1),0===A.strm.avail_out))return 1}return A.insert=A.strstart<2?A.strstart:2,t===q?(QA(A,!0),0===A.strm.avail_out?3:4):A.sym_next&&(QA(A,!1),0===A.strm.avail_out)?1:2},pA=(A,t)=>{let e,i,s;for(;;){if(A.lookahead=3&&(A.ins_h=SA(A,A.ins_h,A.window[A.strstart+3-1]),e=A.prev[A.strstart&A.w_mask]=A.head[A.ins_h],A.head[A.ins_h]=A.strstart),A.prev_length=A.match_length,A.prev_match=A.match_start,A.match_length=2,0!==e&&A.prev_length4096)&&(A.match_length=2)),A.prev_length>=3&&A.match_length<=A.prev_length){s=A.strstart+A.lookahead-3,i=j(A,A.strstart-1-A.prev_match,A.prev_length-3),A.lookahead-=A.prev_length-1,A.prev_length-=2;do{++A.strstart<=s&&(A.ins_h=SA(A,A.ins_h,A.window[A.strstart+3-1]),e=A.prev[A.strstart&A.w_mask]=A.head[A.ins_h],A.head[A.ins_h]=A.strstart)}while(0!=--A.prev_length);if(A.match_available=0,A.match_length=2,A.strstart++,i&&(QA(A,!1),0===A.strm.avail_out))return 1}else if(A.match_available){if(i=j(A,0,A.window[A.strstart-1]),i&&QA(A,!1),A.strstart++,A.lookahead--,0===A.strm.avail_out)return 1}else A.match_available=1,A.strstart++,A.lookahead--}return A.match_available&&(i=j(A,0,A.window[A.strstart-1]),A.match_available=0),A.insert=A.strstart<2?A.strstart:2,t===q?(QA(A,!0),0===A.strm.avail_out?3:4):A.sym_next&&(QA(A,!1),0===A.strm.avail_out)?1:2};function yA(A,t,e,i,s){this.good_length=A,this.max_lazy=t,this.nice_length=e,this.max_chain=i,this.func=s}const GA=[new yA(0,0,0,0,OA),new yA(4,4,8,4,uA),new yA(4,5,16,8,uA),new yA(4,6,32,32,uA),new yA(4,4,16,16,pA),new yA(8,16,32,32,pA),new yA(8,16,128,128,pA),new yA(8,32,128,256,pA),new yA(32,128,258,1024,pA),new yA(32,258,258,4096,pA)];function kA(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=BA,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new Uint16Array(1146),this.dyn_dtree=new Uint16Array(122),this.bl_tree=new Uint16Array(78),DA(this.dyn_ltree),DA(this.dyn_dtree),DA(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new Uint16Array(16),this.heap=new Uint16Array(573),DA(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new Uint16Array(573),DA(this.depth),this.sym_buf=0,this.lit_bufsize=0,this.sym_next=0,this.sym_end=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}const HA=A=>{if(!A)return 1;const t=A.state;return!t||t.strm!==A||t.status!==_A&&57!==t.status&&69!==t.status&&73!==t.status&&91!==t.status&&103!==t.status&&t.status!==CA&&t.status!==IA?1:0},YA=A=>{if(HA(A))return lA(A,eA);A.total_in=A.total_out=0,A.data_type=oA;const t=A.state;return t.pending=0,t.pending_out=0,t.wrap<0&&(t.wrap=-t.wrap),t.status=2===t.wrap?57:t.wrap?_A:CA,A.adler=2===t.wrap?0:1,t.last_flush=-2,J(t),AA},mA=A=>{const t=YA(A);var e;return t===AA&&((e=A.state).window_size=2*e.w_size,DA(e.head),e.max_lazy_match=GA[e.level].max_lazy,e.good_match=GA[e.level].good_length,e.nice_match=GA[e.level].nice_length,e.max_chain_length=GA[e.level].max_chain,e.strstart=0,e.block_start=0,e.lookahead=0,e.insert=0,e.match_length=e.prev_length=2,e.match_available=0,e.ins_h=0),t},bA=(A,t,e,i,s,a)=>{if(!A)return eA;let E=1;if(t===aA&&(t=6),i<0?(E=0,i=-i):i>15&&(E=2,i-=16),s<1||s>9||e!==BA||i<8||i>15||t<0||t>9||a<0||a>hA||8===i&&1!==E)return lA(A,eA);8===i&&(i=9);const n=new kA;return A.state=n,n.strm=A,n.status=_A,n.wrap=E,n.gzhead=null,n.w_bits=i,n.w_size=1<bA(A,t,BA,15,8,gA),deflateInit2:bA,deflateReset:mA,deflateResetKeep:YA,deflateSetHeader:(A,t)=>HA(A)||2!==A.state.wrap?eA:(A.state.gzhead=t,AA),deflate:(A,t)=>{if(HA(A)||t>$||t<0)return A?lA(A,eA):eA;const e=A.state;if(!A.output||0!==A.avail_in&&!A.input||e.status===IA&&t!==q)return lA(A,0===A.avail_out?sA:eA);const i=e.last_flush;if(e.last_flush=t,0!==e.pending){if(MA(A),0===A.avail_out)return e.last_flush=-1,AA}else if(0===A.avail_in&&RA(t)<=RA(i)&&t!==q)return lA(A,sA);if(e.status===IA&&0!==A.avail_in)return lA(A,sA);if(e.status===_A&&0===e.wrap&&(e.status=CA),e.status===_A){let t=BA+(e.w_bits-8<<4)<<8,i=-1;if(i=e.strategy>=nA||e.level<2?0:e.level<6?1:6===e.level?2:3,t|=i<<6,0!==e.strstart&&(t|=32),t+=31-t%31,fA(e,t),0!==e.strstart&&(fA(e,A.adler>>>16),fA(e,65535&A.adler)),A.adler=1,e.status=CA,MA(A),0!==e.pending)return e.last_flush=-1,AA}if(57===e.status)if(A.adler=0,FA(e,31),FA(e,139),FA(e,8),e.gzhead)FA(e,(e.gzhead.text?1:0)+(e.gzhead.hcrc?2:0)+(e.gzhead.extra?4:0)+(e.gzhead.name?8:0)+(e.gzhead.comment?16:0)),FA(e,255&e.gzhead.time),FA(e,e.gzhead.time>>8&255),FA(e,e.gzhead.time>>16&255),FA(e,e.gzhead.time>>24&255),FA(e,9===e.level?2:e.strategy>=nA||e.level<2?4:0),FA(e,255&e.gzhead.os),e.gzhead.extra&&e.gzhead.extra.length&&(FA(e,255&e.gzhead.extra.length),FA(e,e.gzhead.extra.length>>8&255)),e.gzhead.hcrc&&(A.adler=K(A.adler,e.pending_buf,e.pending,0)),e.gzindex=0,e.status=69;else if(FA(e,0),FA(e,0),FA(e,0),FA(e,0),FA(e,0),FA(e,9===e.level?2:e.strategy>=nA||e.level<2?4:0),FA(e,3),e.status=CA,MA(A),0!==e.pending)return e.last_flush=-1,AA;if(69===e.status){if(e.gzhead.extra){let t=e.pending,i=(65535&e.gzhead.extra.length)-e.gzindex;for(;e.pending+i>e.pending_buf_size;){let s=e.pending_buf_size-e.pending;if(e.pending_buf.set(e.gzhead.extra.subarray(e.gzindex,e.gzindex+s),e.pending),e.pending=e.pending_buf_size,e.gzhead.hcrc&&e.pending>t&&(A.adler=K(A.adler,e.pending_buf,e.pending-t,t)),e.gzindex+=s,MA(A),0!==e.pending)return e.last_flush=-1,AA;t=0,i-=s}let s=new Uint8Array(e.gzhead.extra);e.pending_buf.set(s.subarray(e.gzindex,e.gzindex+i),e.pending),e.pending+=i,e.gzhead.hcrc&&e.pending>t&&(A.adler=K(A.adler,e.pending_buf,e.pending-t,t)),e.gzindex=0}e.status=73}if(73===e.status){if(e.gzhead.name){let t,i=e.pending;do{if(e.pending===e.pending_buf_size){if(e.gzhead.hcrc&&e.pending>i&&(A.adler=K(A.adler,e.pending_buf,e.pending-i,i)),MA(A),0!==e.pending)return e.last_flush=-1,AA;i=0}t=e.gzindexi&&(A.adler=K(A.adler,e.pending_buf,e.pending-i,i)),e.gzindex=0}e.status=91}if(91===e.status){if(e.gzhead.comment){let t,i=e.pending;do{if(e.pending===e.pending_buf_size){if(e.gzhead.hcrc&&e.pending>i&&(A.adler=K(A.adler,e.pending_buf,e.pending-i,i)),MA(A),0!==e.pending)return e.last_flush=-1,AA;i=0}t=e.gzindexi&&(A.adler=K(A.adler,e.pending_buf,e.pending-i,i))}e.status=103}if(103===e.status){if(e.gzhead.hcrc){if(e.pending+2>e.pending_buf_size&&(MA(A),0!==e.pending))return e.last_flush=-1,AA;FA(e,255&A.adler),FA(e,A.adler>>8&255),A.adler=0}if(e.status=CA,MA(A),0!==e.pending)return e.last_flush=-1,AA}if(0!==A.avail_in||0!==e.lookahead||t!==Z&&e.status!==IA){let i=0===e.level?OA(e,t):e.strategy===nA?((A,t)=>{let e;for(;;){if(0===A.lookahead&&(PA(A),0===A.lookahead)){if(t===Z)return 1;break}if(A.match_length=0,e=j(A,0,A.window[A.strstart]),A.lookahead--,A.strstart++,e&&(QA(A,!1),0===A.strm.avail_out))return 1}return A.insert=0,t===q?(QA(A,!0),0===A.strm.avail_out?3:4):A.sym_next&&(QA(A,!1),0===A.strm.avail_out)?1:2})(e,t):e.strategy===rA?((A,t)=>{let e,i,s,a;const E=A.window;for(;;){if(A.lookahead<=wA){if(PA(A),A.lookahead<=wA&&t===Z)return 1;if(0===A.lookahead)break}if(A.match_length=0,A.lookahead>=3&&A.strstart>0&&(s=A.strstart-1,i=E[s],i===E[++s]&&i===E[++s]&&i===E[++s])){a=A.strstart+wA;do{}while(i===E[++s]&&i===E[++s]&&i===E[++s]&&i===E[++s]&&i===E[++s]&&i===E[++s]&&i===E[++s]&&i===E[++s]&&sA.lookahead&&(A.match_length=A.lookahead)}if(A.match_length>=3?(e=j(A,1,A.match_length-3),A.lookahead-=A.match_length,A.strstart+=A.match_length,A.match_length=0):(e=j(A,0,A.window[A.strstart]),A.lookahead--,A.strstart++),e&&(QA(A,!1),0===A.strm.avail_out))return 1}return A.insert=0,t===q?(QA(A,!0),0===A.strm.avail_out?3:4):A.sym_next&&(QA(A,!1),0===A.strm.avail_out)?1:2})(e,t):GA[e.level].func(e,t);if(3!==i&&4!==i||(e.status=IA),1===i||3===i)return 0===A.avail_out&&(e.last_flush=-1),AA;if(2===i&&(t===X?W(e):t!==$&&(v(e,0,0,!1),t===V&&(DA(e.head),0===e.lookahead&&(e.strstart=0,e.block_start=0,e.insert=0))),MA(A),0===A.avail_out))return e.last_flush=-1,AA}return t!==q?AA:e.wrap<=0?tA:(2===e.wrap?(FA(e,255&A.adler),FA(e,A.adler>>8&255),FA(e,A.adler>>16&255),FA(e,A.adler>>24&255),FA(e,255&A.total_in),FA(e,A.total_in>>8&255),FA(e,A.total_in>>16&255),FA(e,A.total_in>>24&255)):(fA(e,A.adler>>>16),fA(e,65535&A.adler)),MA(A),e.wrap>0&&(e.wrap=-e.wrap),0!==e.pending?AA:tA)},deflateEnd:A=>{if(HA(A))return eA;const t=A.state.status;return A.state=null,t===CA?lA(A,iA):AA},deflateSetDictionary:(A,t)=>{let e=t.length;if(HA(A))return eA;const i=A.state,s=i.wrap;if(2===s||1===s&&i.status!==_A||i.lookahead)return eA;if(1===s&&(A.adler=b(A.adler,t,e,0)),i.wrap=0,e>=i.w_size){0===s&&(DA(i.head),i.strstart=0,i.block_start=0,i.insert=0);let A=new Uint8Array(i.w_size);A.set(t.subarray(e-i.w_size,e),0),t=A,e=i.w_size}const a=A.avail_in,E=A.next_in,n=A.input;for(A.avail_in=e,A.next_in=0,A.input=t,PA(i);i.lookahead>=3;){let A=i.strstart,t=i.lookahead-2;do{i.ins_h=SA(i,i.ins_h,i.window[A+3-1]),i.prev[A&i.w_mask]=i.head[i.ins_h],i.head[i.ins_h]=A,A++}while(--t);i.strstart=A,i.lookahead=2,PA(i)}return i.strstart+=i.lookahead,i.block_start=i.strstart,i.insert=i.lookahead,i.lookahead=0,i.match_length=i.prev_length=2,i.match_available=0,A.next_in=E,A.input=n,A.avail_in=a,i.wrap=s,AA},deflateInfo:"pako deflate (from Nodeca project)"};const KA=(A,t)=>Object.prototype.hasOwnProperty.call(A,t);var LA=function(A){const t=Array.prototype.slice.call(arguments,1);for(;t.length;){const e=t.shift();if(e){if("object"!=typeof e)throw new TypeError(e+"must be non-object");for(const t in e)KA(e,t)&&(A[t]=e[t])}}return A},NA=A=>{let t=0;for(let e=0,i=A.length;e=252?6:A>=248?5:A>=240?4:A>=224?3:A>=192?2:1;vA[254]=vA[254]=1;var zA=A=>{if("function"==typeof TextEncoder&&TextEncoder.prototype.encode)return(new TextEncoder).encode(A);let t,e,i,s,a,E=A.length,n=0;for(s=0;s>>6,t[a++]=128|63&e):e<65536?(t[a++]=224|e>>>12,t[a++]=128|e>>>6&63,t[a++]=128|63&e):(t[a++]=240|e>>>18,t[a++]=128|e>>>12&63,t[a++]=128|e>>>6&63,t[a++]=128|63&e);return t},jA=(A,t)=>{const e=t||A.length;if("function"==typeof TextDecoder&&TextDecoder.prototype.decode)return(new TextDecoder).decode(A.subarray(0,t));let i,s;const a=new Array(2*e);for(s=0,i=0;i4)a[s++]=65533,i+=E-1;else{for(t&=2===E?31:3===E?15:7;E>1&&i1?a[s++]=65533:t<65536?a[s++]=t:(t-=65536,a[s++]=55296|t>>10&1023,a[s++]=56320|1023&t)}}return((A,t)=>{if(t<65534&&A.subarray&&JA)return String.fromCharCode.apply(null,A.length===t?A:A.subarray(0,t));let e="";for(let i=0;i{(t=t||A.length)>A.length&&(t=A.length);let e=t-1;for(;e>=0&&128==(192&A[e]);)e--;return e<0||0===e?t:e+vA[A[e]]>t?e:t};var ZA=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0};const XA=Object.prototype.toString,{Z_NO_FLUSH:VA,Z_SYNC_FLUSH:qA,Z_FULL_FLUSH:$A,Z_FINISH:At,Z_OK:tt,Z_STREAM_END:et,Z_DEFAULT_COMPRESSION:it,Z_DEFAULT_STRATEGY:st,Z_DEFLATED:at}=N;function Et(A){this.options=LA({level:it,method:at,chunkSize:16384,windowBits:15,memLevel:8,strategy:st},A||{});let t=this.options;t.raw&&t.windowBits>0?t.windowBits=-t.windowBits:t.gzip&&t.windowBits>0&&t.windowBits<16&&(t.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new ZA,this.strm.avail_out=0;let e=xA.deflateInit2(this.strm,t.level,t.method,t.windowBits,t.memLevel,t.strategy);if(e!==tt)throw new Error(L[e]);if(t.header&&xA.deflateSetHeader(this.strm,t.header),t.dictionary){let A;if(A="string"==typeof t.dictionary?zA(t.dictionary):"[object ArrayBuffer]"===XA.call(t.dictionary)?new Uint8Array(t.dictionary):t.dictionary,e=xA.deflateSetDictionary(this.strm,A),e!==tt)throw new Error(L[e]);this._dict_set=!0}}function nt(A,t){const e=new Et(t);if(e.push(A,!0),e.err)throw e.msg||L[e.err];return e.result}Et.prototype.push=function(A,t){const e=this.strm,i=this.options.chunkSize;let s,a;if(this.ended)return!1;for(a=t===~~t?t:!0===t?At:VA,"string"==typeof A?e.input=zA(A):"[object ArrayBuffer]"===XA.call(A)?e.input=new Uint8Array(A):e.input=A,e.next_in=0,e.avail_in=e.input.length;;)if(0===e.avail_out&&(e.output=new Uint8Array(i),e.next_out=0,e.avail_out=i),(a===qA||a===$A)&&e.avail_out<=6)this.onData(e.output.subarray(0,e.next_out)),e.avail_out=0;else{if(s=xA.deflate(e,a),s===et)return e.next_out>0&&this.onData(e.output.subarray(0,e.next_out)),s=xA.deflateEnd(this.strm),this.onEnd(s),this.ended=!0,s===tt;if(0!==e.avail_out){if(a>0&&e.next_out>0)this.onData(e.output.subarray(0,e.next_out)),e.avail_out=0;else if(0===e.avail_in)break}else this.onData(e.output)}return!0},Et.prototype.onData=function(A){this.chunks.push(A)},Et.prototype.onEnd=function(A){A===tt&&(this.result=NA(this.chunks)),this.chunks=[],this.err=A,this.msg=this.strm.msg};var rt={Deflate:Et,deflate:nt,deflateRaw:function(A,t){return(t=t||{}).raw=!0,nt(A,t)},gzip:function(A,t){return(t=t||{}).gzip=!0,nt(A,t)},constants:N};const ht=16209;var gt=function(A,t){let e,i,s,a,E,n,r,h,g,o,B,w,c,_,C,I,l,R,D,d,S,M,Q,F;const f=A.state;e=A.next_in,Q=A.input,i=e+(A.avail_in-5),s=A.next_out,F=A.output,a=s-(t-A.avail_out),E=s+(A.avail_out-257),n=f.dmax,r=f.wsize,h=f.whave,g=f.wnext,o=f.window,B=f.hold,w=f.bits,c=f.lencode,_=f.distcode,C=(1<>>24,B>>>=R,w-=R,R=l>>>16&255,0===R)F[s++]=65535&l;else{if(!(16&R)){if(64&R){if(32&R){f.mode=16191;break A}A.msg="invalid literal/length code",f.mode=ht;break A}l=c[(65535&l)+(B&(1<>>=R,w-=R),w<15&&(B+=Q[e++]<>>24,B>>>=R,w-=R,R=l>>>16&255,16&R){if(d=65535&l,R&=15,wn){A.msg="invalid distance too far back",f.mode=ht;break A}if(B>>>=R,w-=R,R=s-a,d>R){if(R=d-R,R>h&&f.sane){A.msg="invalid distance too far back",f.mode=ht;break A}if(S=0,M=o,0===g){if(S+=r-R,R2;)F[s++]=M[S++],F[s++]=M[S++],F[s++]=M[S++],D-=3;D&&(F[s++]=M[S++],D>1&&(F[s++]=M[S++]))}else{S=s-d;do{F[s++]=F[S++],F[s++]=F[S++],F[s++]=F[S++],D-=3}while(D>2);D&&(F[s++]=F[S++],D>1&&(F[s++]=F[S++]))}break}if(64&R){A.msg="invalid distance code",f.mode=ht;break A}l=_[(65535&l)+(B&(1<>3,e-=D,w-=D<<3,B&=(1<{const r=n.bits;let h,g,o,B,w,c,_=0,C=0,I=0,l=0,R=0,D=0,d=0,S=0,M=0,Q=0,F=null;const f=new Uint16Array(16),T=new Uint16Array(16);let U,P,O,u=null;for(_=0;_<=ot;_++)f[_]=0;for(C=0;C=1&&0===f[l];l--);if(R>l&&(R=l),0===l)return s[a++]=20971520,s[a++]=20971520,n.bits=1,0;for(I=1;I0&&(0===A||1!==l))return-1;for(T[1]=0,_=1;_852||2===A&&M>592)return 1;for(;;){U=_-d,E[C]+1=c?(P=u[E[C]-c],O=F[E[C]-c]):(P=96,O=0),h=1<<_-d,g=1<>d)+g]=U<<24|P<<16|O}while(0!==g);for(h=1<<_-1;Q&h;)h>>=1;if(0!==h?(Q&=h-1,Q+=h):Q=0,C++,0==--f[_]){if(_===l)break;_=t[e+E[C]]}if(_>R&&(Q&B)!==o){for(0===d&&(d=R),w+=I,D=_-d,S=1<852||2===A&&M>592)return 1;o=Q&B,s[o]=R<<24|D<<16|w-a}}return 0!==Q&&(s[w+Q]=_-d<<24|64<<16),n.bits=R,0};const{Z_FINISH:It,Z_BLOCK:lt,Z_TREES:Rt,Z_OK:Dt,Z_STREAM_END:dt,Z_NEED_DICT:St,Z_STREAM_ERROR:Mt,Z_DATA_ERROR:Qt,Z_MEM_ERROR:Ft,Z_BUF_ERROR:ft,Z_DEFLATED:Tt}=N,Ut=16180,Pt=16190,Ot=16191,ut=16192,pt=16194,yt=16199,Gt=16200,kt=16206,Ht=16209,Yt=A=>(A>>>24&255)+(A>>>8&65280)+((65280&A)<<8)+((255&A)<<24);function mt(){this.strm=null,this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new Uint16Array(320),this.work=new Uint16Array(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}const bt=A=>{if(!A)return 1;const t=A.state;return!t||t.strm!==A||t.mode16211?1:0},xt=A=>{if(bt(A))return Mt;const t=A.state;return A.total_in=A.total_out=t.total=0,A.msg="",t.wrap&&(A.adler=1&t.wrap),t.mode=Ut,t.last=0,t.havedict=0,t.flags=-1,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new Int32Array(852),t.distcode=t.distdyn=new Int32Array(592),t.sane=1,t.back=-1,Dt},Kt=A=>{if(bt(A))return Mt;const t=A.state;return t.wsize=0,t.whave=0,t.wnext=0,xt(A)},Lt=(A,t)=>{let e;if(bt(A))return Mt;const i=A.state;return t<0?(e=0,t=-t):(e=5+(t>>4),t<48&&(t&=15)),t&&(t<8||t>15)?Mt:(null!==i.window&&i.wbits!==t&&(i.window=null),i.wrap=e,i.wbits=t,Kt(A))},Nt=(A,t)=>{if(!A)return Mt;const e=new mt;A.state=e,e.strm=A,e.window=null,e.mode=Ut;const i=Lt(A,t);return i!==Dt&&(A.state=null),i};let Jt,vt,zt=!0;const jt=A=>{if(zt){Jt=new Int32Array(512),vt=new Int32Array(32);let t=0;for(;t<144;)A.lens[t++]=8;for(;t<256;)A.lens[t++]=9;for(;t<280;)A.lens[t++]=7;for(;t<288;)A.lens[t++]=8;for(Ct(1,A.lens,0,288,Jt,0,A.work,{bits:9}),t=0;t<32;)A.lens[t++]=5;Ct(2,A.lens,0,32,vt,0,A.work,{bits:5}),zt=!1}A.lencode=Jt,A.lenbits=9,A.distcode=vt,A.distbits=5},Wt=(A,t,e,i)=>{let s;const a=A.state;return null===a.window&&(a.wsize=1<=a.wsize?(a.window.set(t.subarray(e-a.wsize,e),0),a.wnext=0,a.whave=a.wsize):(s=a.wsize-a.wnext,s>i&&(s=i),a.window.set(t.subarray(e-i,e-i+s),a.wnext),(i-=s)?(a.window.set(t.subarray(e-i,e),0),a.wnext=i,a.whave=a.wsize):(a.wnext+=s,a.wnext===a.wsize&&(a.wnext=0),a.whaveNt(A,15),inflateInit2:Nt,inflate:(A,t)=>{let e,i,s,a,E,n,r,h,g,o,B,w,c,_,C,I,l,R,D,d,S,M,Q=0;const F=new Uint8Array(4);let f,T;const U=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]);if(bt(A)||!A.output||!A.input&&0!==A.avail_in)return Mt;e=A.state,e.mode===Ot&&(e.mode=ut),E=A.next_out,s=A.output,r=A.avail_out,a=A.next_in,i=A.input,n=A.avail_in,h=e.hold,g=e.bits,o=n,B=r,M=Dt;A:for(;;)switch(e.mode){case Ut:if(0===e.wrap){e.mode=ut;break}for(;g<16;){if(0===n)break A;n--,h+=i[a++]<>>8&255,e.check=K(e.check,F,2,0),h=0,g=0,e.mode=16181;break}if(e.head&&(e.head.done=!1),!(1&e.wrap)||(((255&h)<<8)+(h>>8))%31){A.msg="incorrect header check",e.mode=Ht;break}if((15&h)!==Tt){A.msg="unknown compression method",e.mode=Ht;break}if(h>>>=4,g-=4,S=8+(15&h),0===e.wbits&&(e.wbits=S),S>15||S>e.wbits){A.msg="invalid window size",e.mode=Ht;break}e.dmax=1<>8&1),512&e.flags&&4&e.wrap&&(F[0]=255&h,F[1]=h>>>8&255,e.check=K(e.check,F,2,0)),h=0,g=0,e.mode=16182;case 16182:for(;g<32;){if(0===n)break A;n--,h+=i[a++]<>>8&255,F[2]=h>>>16&255,F[3]=h>>>24&255,e.check=K(e.check,F,4,0)),h=0,g=0,e.mode=16183;case 16183:for(;g<16;){if(0===n)break A;n--,h+=i[a++]<>8),512&e.flags&&4&e.wrap&&(F[0]=255&h,F[1]=h>>>8&255,e.check=K(e.check,F,2,0)),h=0,g=0,e.mode=16184;case 16184:if(1024&e.flags){for(;g<16;){if(0===n)break A;n--,h+=i[a++]<>>8&255,e.check=K(e.check,F,2,0)),h=0,g=0}else e.head&&(e.head.extra=null);e.mode=16185;case 16185:if(1024&e.flags&&(w=e.length,w>n&&(w=n),w&&(e.head&&(S=e.head.extra_len-e.length,e.head.extra||(e.head.extra=new Uint8Array(e.head.extra_len)),e.head.extra.set(i.subarray(a,a+w),S)),512&e.flags&&4&e.wrap&&(e.check=K(e.check,i,w,a)),n-=w,a+=w,e.length-=w),e.length))break A;e.length=0,e.mode=16186;case 16186:if(2048&e.flags){if(0===n)break A;w=0;do{S=i[a+w++],e.head&&S&&e.length<65536&&(e.head.name+=String.fromCharCode(S))}while(S&&w>9&1,e.head.done=!0),A.adler=e.check=0,e.mode=Ot;break;case 16189:for(;g<32;){if(0===n)break A;n--,h+=i[a++]<>>=7&g,g-=7&g,e.mode=kt;break}for(;g<3;){if(0===n)break A;n--,h+=i[a++]<>>=1,g-=1,3&h){case 0:e.mode=16193;break;case 1:if(jt(e),e.mode=yt,t===Rt){h>>>=2,g-=2;break A}break;case 2:e.mode=16196;break;case 3:A.msg="invalid block type",e.mode=Ht}h>>>=2,g-=2;break;case 16193:for(h>>>=7&g,g-=7&g;g<32;){if(0===n)break A;n--,h+=i[a++]<>>16^65535)){A.msg="invalid stored block lengths",e.mode=Ht;break}if(e.length=65535&h,h=0,g=0,e.mode=pt,t===Rt)break A;case pt:e.mode=16195;case 16195:if(w=e.length,w){if(w>n&&(w=n),w>r&&(w=r),0===w)break A;s.set(i.subarray(a,a+w),E),n-=w,a+=w,r-=w,E+=w,e.length-=w;break}e.mode=Ot;break;case 16196:for(;g<14;){if(0===n)break A;n--,h+=i[a++]<>>=5,g-=5,e.ndist=1+(31&h),h>>>=5,g-=5,e.ncode=4+(15&h),h>>>=4,g-=4,e.nlen>286||e.ndist>30){A.msg="too many length or distance symbols",e.mode=Ht;break}e.have=0,e.mode=16197;case 16197:for(;e.have>>=3,g-=3}for(;e.have<19;)e.lens[U[e.have++]]=0;if(e.lencode=e.lendyn,e.lenbits=7,f={bits:e.lenbits},M=Ct(0,e.lens,0,19,e.lencode,0,e.work,f),e.lenbits=f.bits,M){A.msg="invalid code lengths set",e.mode=Ht;break}e.have=0,e.mode=16198;case 16198:for(;e.have>>24,I=Q>>>16&255,l=65535&Q,!(C<=g);){if(0===n)break A;n--,h+=i[a++]<>>=C,g-=C,e.lens[e.have++]=l;else{if(16===l){for(T=C+2;g>>=C,g-=C,0===e.have){A.msg="invalid bit length repeat",e.mode=Ht;break}S=e.lens[e.have-1],w=3+(3&h),h>>>=2,g-=2}else if(17===l){for(T=C+3;g>>=C,g-=C,S=0,w=3+(7&h),h>>>=3,g-=3}else{for(T=C+7;g>>=C,g-=C,S=0,w=11+(127&h),h>>>=7,g-=7}if(e.have+w>e.nlen+e.ndist){A.msg="invalid bit length repeat",e.mode=Ht;break}for(;w--;)e.lens[e.have++]=S}}if(e.mode===Ht)break;if(0===e.lens[256]){A.msg="invalid code -- missing end-of-block",e.mode=Ht;break}if(e.lenbits=9,f={bits:e.lenbits},M=Ct(1,e.lens,0,e.nlen,e.lencode,0,e.work,f),e.lenbits=f.bits,M){A.msg="invalid literal/lengths set",e.mode=Ht;break}if(e.distbits=6,e.distcode=e.distdyn,f={bits:e.distbits},M=Ct(2,e.lens,e.nlen,e.ndist,e.distcode,0,e.work,f),e.distbits=f.bits,M){A.msg="invalid distances set",e.mode=Ht;break}if(e.mode=yt,t===Rt)break A;case yt:e.mode=Gt;case Gt:if(n>=6&&r>=258){A.next_out=E,A.avail_out=r,A.next_in=a,A.avail_in=n,e.hold=h,e.bits=g,gt(A,B),E=A.next_out,s=A.output,r=A.avail_out,a=A.next_in,i=A.input,n=A.avail_in,h=e.hold,g=e.bits,e.mode===Ot&&(e.back=-1);break}for(e.back=0;Q=e.lencode[h&(1<>>24,I=Q>>>16&255,l=65535&Q,!(C<=g);){if(0===n)break A;n--,h+=i[a++]<>R)],C=Q>>>24,I=Q>>>16&255,l=65535&Q,!(R+C<=g);){if(0===n)break A;n--,h+=i[a++]<>>=R,g-=R,e.back+=R}if(h>>>=C,g-=C,e.back+=C,e.length=l,0===I){e.mode=16205;break}if(32&I){e.back=-1,e.mode=Ot;break}if(64&I){A.msg="invalid literal/length code",e.mode=Ht;break}e.extra=15&I,e.mode=16201;case 16201:if(e.extra){for(T=e.extra;g>>=e.extra,g-=e.extra,e.back+=e.extra}e.was=e.length,e.mode=16202;case 16202:for(;Q=e.distcode[h&(1<>>24,I=Q>>>16&255,l=65535&Q,!(C<=g);){if(0===n)break A;n--,h+=i[a++]<>R)],C=Q>>>24,I=Q>>>16&255,l=65535&Q,!(R+C<=g);){if(0===n)break A;n--,h+=i[a++]<>>=R,g-=R,e.back+=R}if(h>>>=C,g-=C,e.back+=C,64&I){A.msg="invalid distance code",e.mode=Ht;break}e.offset=l,e.extra=15&I,e.mode=16203;case 16203:if(e.extra){for(T=e.extra;g>>=e.extra,g-=e.extra,e.back+=e.extra}if(e.offset>e.dmax){A.msg="invalid distance too far back",e.mode=Ht;break}e.mode=16204;case 16204:if(0===r)break A;if(w=B-r,e.offset>w){if(w=e.offset-w,w>e.whave&&e.sane){A.msg="invalid distance too far back",e.mode=Ht;break}w>e.wnext?(w-=e.wnext,c=e.wsize-w):c=e.wnext-w,w>e.length&&(w=e.length),_=e.window}else _=s,c=E-e.offset,w=e.length;w>r&&(w=r),r-=w,e.length-=w;do{s[E++]=_[c++]}while(--w);0===e.length&&(e.mode=Gt);break;case 16205:if(0===r)break A;s[E++]=e.length,r--,e.mode=Gt;break;case kt:if(e.wrap){for(;g<32;){if(0===n)break A;n--,h|=i[a++]<{if(bt(A))return Mt;let t=A.state;return t.window&&(t.window=null),A.state=null,Dt},inflateGetHeader:(A,t)=>{if(bt(A))return Mt;const e=A.state;return 2&e.wrap?(e.head=t,t.done=!1,Dt):Mt},inflateSetDictionary:(A,t)=>{const e=t.length;let i,s,a;return bt(A)?Mt:(i=A.state,0!==i.wrap&&i.mode!==Pt?Mt:i.mode===Pt&&(s=1,s=b(s,t,e,0),s!==i.check)?Qt:(a=Wt(A,t,e,e),a?(i.mode=16210,Ft):(i.havedict=1,Dt)))},inflateInfo:"pako inflate (from Nodeca project)"};var Xt=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1};const Vt=Object.prototype.toString,{Z_NO_FLUSH:qt,Z_FINISH:$t,Z_OK:Ae,Z_STREAM_END:te,Z_NEED_DICT:ee,Z_STREAM_ERROR:ie,Z_DATA_ERROR:se,Z_MEM_ERROR:ae}=N;function Ee(A){this.options=LA({chunkSize:65536,windowBits:15,to:""},A||{});const t=this.options;t.raw&&t.windowBits>=0&&t.windowBits<16&&(t.windowBits=-t.windowBits,0===t.windowBits&&(t.windowBits=-15)),!(t.windowBits>=0&&t.windowBits<16)||A&&A.windowBits||(t.windowBits+=32),t.windowBits>15&&t.windowBits<48&&(15&t.windowBits||(t.windowBits|=15)),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new ZA,this.strm.avail_out=0;let e=Zt.inflateInit2(this.strm,t.windowBits);if(e!==Ae)throw new Error(L[e]);if(this.header=new Xt,Zt.inflateGetHeader(this.strm,this.header),t.dictionary&&("string"==typeof t.dictionary?t.dictionary=zA(t.dictionary):"[object ArrayBuffer]"===Vt.call(t.dictionary)&&(t.dictionary=new Uint8Array(t.dictionary)),t.raw&&(e=Zt.inflateSetDictionary(this.strm,t.dictionary),e!==Ae)))throw new Error(L[e])}function ne(A,t){const e=new Ee(t);if(e.push(A),e.err)throw e.msg||L[e.err];return e.result}Ee.prototype.push=function(A,t){const e=this.strm,i=this.options.chunkSize,s=this.options.dictionary;let a,E,n;if(this.ended)return!1;for(E=t===~~t?t:!0===t?$t:qt,"[object ArrayBuffer]"===Vt.call(A)?e.input=new Uint8Array(A):e.input=A,e.next_in=0,e.avail_in=e.input.length;;){for(0===e.avail_out&&(e.output=new Uint8Array(i),e.next_out=0,e.avail_out=i),a=Zt.inflate(e,E),a===ee&&s&&(a=Zt.inflateSetDictionary(e,s),a===Ae?a=Zt.inflate(e,E):a===se&&(a=ee));e.avail_in>0&&a===te&&e.state.wrap>0&&0!==A[e.next_in];)Zt.inflateReset(e),a=Zt.inflate(e,E);switch(a){case ie:case se:case ee:case ae:return this.onEnd(a),this.ended=!0,!1}if(n=e.avail_out,e.next_out&&(0===e.avail_out||a===te))if("string"===this.options.to){let A=WA(e.output,e.next_out),t=e.next_out-A,s=jA(e.output,A);e.next_out=t,e.avail_out=i-t,t&&e.output.set(e.output.subarray(A,A+t),0),this.onData(s)}else this.onData(e.output.length===e.next_out?e.output:e.output.subarray(0,e.next_out));if(a!==Ae||0!==n){if(a===te)return a=Zt.inflateEnd(this.strm),this.onEnd(a),this.ended=!0,!0;if(0===e.avail_in)break}}return!0},Ee.prototype.onData=function(A){this.chunks.push(A)},Ee.prototype.onEnd=function(A){A===Ae&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=NA(this.chunks)),this.chunks=[],this.err=A,this.msg=this.strm.msg};var re={Inflate:Ee,inflate:ne,inflateRaw:function(A,t){return(t=t||{}).raw=!0,ne(A,t)},ungzip:ne,constants:N};const{Deflate:he,deflate:ge,deflateRaw:oe,gzip:Be}=rt,{Inflate:we,inflate:ce,inflateRaw:_e,ungzip:Ce}=re;var Ie=ge,le=we;function Re(A,t,e=255){const i=A.length%t;if(0!==i){const s=new Uint8Array(t-i).fill(e),a=new Uint8Array(A.length+s.length);return a.set(A),a.set(s,A.length),a}return A}function De(A,t=239){for(let e=0;esetTimeout(t,A)))}class Me{constructor(A,t=!1,e=!0){this.device=A,this.tracing=t,this.slipReaderEnabled=!1,this.baudrate=0,this.traceLog="",this.lastTraceTime=Date.now(),this.buffer=new Uint8Array(0),this.onDeviceLostCallback=null,this.SLIP_END=192,this.SLIP_ESC=219,this.SLIP_ESC_END=220,this.SLIP_ESC_ESC=221,this._DTR_state=!1,this.slipReaderEnabled=e}setDeviceLostCallback(A){this.onDeviceLostCallback=A}updateDevice(A){this.device=A,this.trace("Device reference updated")}getInfo(){const A=this.device.getInfo();return A.usbVendorId&&A.usbProductId?`WebSerial VendorID 0x${A.usbVendorId.toString(16)} ProductID 0x${A.usbProductId.toString(16)}`:""}getPid(){return this.device.getInfo().usbProductId}trace(A){const t=`${`TRACE ${(Date.now()-this.lastTraceTime).toFixed(3)}`} ${A}`;console.log(t),this.traceLog+=t+"\n"}async returnTrace(){try{await navigator.clipboard.writeText(this.traceLog),console.log("Text copied to clipboard!")}catch(A){console.error("Failed to copy text:",A)}}hexify(A){return Array.from(A).map((A=>A.toString(16).padStart(2,"0"))).join("").padEnd(16," ")}hexConvert(A,t=!0){if(t&&A.length>16){let t="",e=A;for(;e.length>0;){const A=e.slice(0,16),i=String.fromCharCode(...A).split("").map((A=>" "===A||A>=" "&&A<="~"&&" "!==A?A:".")).join("");e=e.slice(16),t+=`\n ${this.hexify(A.slice(0,8))} ${this.hexify(A.slice(8))} | ${i}`}return t}return this.hexify(A)}slipWriter(A){const t=[];t.push(192);for(let e=0;e0){i=this.buffer,this.buffer=new Uint8Array(0);break}await Se(1)}if(!i||0===i.length){const A=null===t?"Serial data stream stopped: Possible serial noise or corruption.":"No serial data received.";throw this.tracing&&this.trace(A),new Error(A)}this.tracing&&this.trace(`Read ${i.length} bytes: ${this.hexConvert(i)}`);for(let A=0;AsetTimeout(t,A)))}class Fe{constructor(A,t){this.resetDelay=t,this.transport=A}async reset(){await this.transport.setDTR(!1),await this.transport.setRTS(!0),await Qe(100),await this.transport.setDTR(!0),await this.transport.setRTS(!1),await Qe(this.resetDelay),await this.transport.setDTR(!1)}}class fe{constructor(A){this.transport=A}async reset(){await this.transport.setRTS(!1),await this.transport.setDTR(!1),await Qe(100),await this.transport.setDTR(!0),await this.transport.setRTS(!1),await Qe(100),await this.transport.setRTS(!0),await this.transport.setDTR(!1),await this.transport.setRTS(!0),await Qe(100),await this.transport.setRTS(!1),await this.transport.setDTR(!1)}}class Te{constructor(A,t=!1){this.transport=A,this.usingUsbOtg=t,this.transport=A}async reset(){this.usingUsbOtg?(await Qe(200),await this.transport.setRTS(!1),await Qe(200)):(await Qe(100),await this.transport.setRTS(!1))}}function Ue(A){const t=["D","R","W"],e=A.split("|");for(const A of e){const e=A[0],i=A.slice(1);if(!t.includes(e))return!1;if("D"===e||"R"===e){if("0"!==i&&"1"!==i)return!1}else if("W"===e){const A=parseInt(i);if(isNaN(A)||A<=0)return!1}}return!0}class Pe{constructor(A,t){this.transport=A,this.sequenceString=t,this.transport=A}async reset(){const A={D:async A=>await this.transport.setDTR(A),R:async A=>await this.transport.setRTS(A),W:async A=>await Qe(A)};try{if(!Ue(this.sequenceString))return;const t=this.sequenceString.split("|");for(const e of t){const t=e[0],i=e.slice(1);"W"===t?await A.W(Number(i)):"D"!==t&&"R"!==t||await A[t]("1"===i)}}catch(A){throw new Error("Invalid custom reset sequence")}}}async function Oe(A,t){let e;switch(A){case"ESP32":e=await Promise.resolve().then((function(){return ri}));break;case"ESP32-C2":e=await Promise.resolve().then((function(){return Ci}));break;case"ESP32-C3":e=await Promise.resolve().then((function(){return Qi}));break;case"ESP32-C5":e=await Promise.resolve().then((function(){return pi}));break;case"ESP32-C6":e=await Promise.resolve().then((function(){return xi}));break;case"ESP32-C61":e=await Promise.resolve().then((function(){return Wi}));break;case"ESP32-H2":e=await Promise.resolve().then((function(){return es}));break;case"ESP32-P4":e=t&&t<300?await Promise.resolve().then((function(){return gs})):await Promise.resolve().then((function(){return ls}));break;case"ESP32-S2":e=await Promise.resolve().then((function(){return fs}));break;case"ESP32-S3":e=await Promise.resolve().then((function(){return Gs}));break;case"ESP8266":e=await Promise.resolve().then((function(){return Ls}))}if(e)return{bss_start:e.bss_start,data:e.data,data_start:e.data_start,entry:e.entry,text:e.text,text_start:e.text_start,decodedData:ue(e.data),decodedText:ue(e.text)}}function ue(A){const t=atob(A).split("").map((function(A){return A.charCodeAt(0)}));return new Uint8Array(t)}class pe{constructor(){this.FLASH_SIZES={"1MB":0,"2MB":16,"4MB":32,"8MB":48,"16MB":64,"32MB":80,"64MB":96,"128MB":112},this.FLASH_FREQUENCY={"80m":15,"40m":0,"26m":1,"20m":2}}getEraseSize(A,t){return t}}class ye extends pe{constructor(){super(...arguments),this.CHIP_NAME="ESP8266",this.CHIP_DETECT_MAGIC_VALUE=[4293968129],this.EFUSE_RD_REG_BASE=1072693328,this.UART_CLKDIV_REG=1610612756,this.UART_CLKDIV_MASK=1048575,this.XTAL_CLK_DIVIDER=2,this.FLASH_WRITE_SIZE=16384,this.BOOTLOADER_FLASH_OFFSET=0,this.UART_DATE_REG_ADDR=0,this.FLASH_SIZES={"512KB":0,"256KB":16,"1MB":32,"2MB":48,"4MB":64,"2MB-c1":80,"4MB-c1":96,"8MB":128,"16MB":144},this.FLASH_FREQUENCY={"80m":15,"40m":0,"26m":1,"20m":2},this.MEMORY_MAP=[[1072693248,1072693264,"DPORT"],[1073643520,1073741824,"DRAM"],[1074790400,1074823168,"IRAM"],[1075843088,1076760592,"IROM"]],this.SPI_REG_BASE=1610613248,this.SPI_USR_OFFS=28,this.SPI_USR1_OFFS=32,this.SPI_USR2_OFFS=36,this.SPI_MOSI_DLEN_OFFS=0,this.SPI_MISO_DLEN_OFFS=0,this.SPI_W0_OFFS=64,this.getChipFeatures=async A=>{const t=["WiFi"];return"ESP8285"==await this.getChipDescription(A)&&t.push("Embedded Flash"),t}}async readEfuse(A,t){const e=this.EFUSE_RD_REG_BASE+4*t;return A.debug("Read efuse "+e),await A.readReg(e)}async getChipDescription(A){const t=await this.readEfuse(A,2);return!!(16&await this.readEfuse(A,0)|65536&t)?"ESP8285":"ESP8266EX"}async getCrystalFreq(A){const t=await A.readReg(this.UART_CLKDIV_REG)&this.UART_CLKDIV_MASK,e=A.transport.baudrate*t/1e6/this.XTAL_CLK_DIVIDER;let i;return i=e>33?40:26,Math.abs(i-e)>1&&A.info("WARNING: Detected crystal freq "+e+"MHz is quite different to normalized freq "+i+"MHz. Unsupported crystal in use?"),i}_d2h(A){const t=(+A).toString(16);return 1===t.length?"0"+t:t}async readMac(A){let t=await this.readEfuse(A,0);t>>>=0;let e=await this.readEfuse(A,1);e>>>=0;let i=await this.readEfuse(A,3);i>>>=0;const s=new Uint8Array(6);return 0!=i?(s[0]=i>>16&255,s[1]=i>>8&255,s[2]=255&i):e>>16&255?1==(e>>16&255)?(s[0]=172,s[1]=208,s[2]=116):A.error("Unknown OUI"):(s[0]=24,s[1]=254,s[2]=52),s[3]=e>>8&255,s[4]=255&e,s[5]=t>>24&255,this._d2h(s[0])+":"+this._d2h(s[1])+":"+this._d2h(s[2])+":"+this._d2h(s[3])+":"+this._d2h(s[4])+":"+this._d2h(s[5])}getEraseSize(A,t){return t}}ye.IROM_MAP_START=1075838976,ye.IROM_MAP_END=1076887552;var Ge=Object.freeze({__proto__:null,ESP8266ROM:ye});const ke=233;function He(A,t){return A+(t-1-A%t)}function Ye(A,t){return A[t]|A[t+1]<<8|A[t+2]<<16|A[t+3]<<24}class me{constructor(A,t,e=null,i=0){this.addr=A,this.data=t,this.fileOffs=e,this.flags=i,this.includeInChecksum=!0,0!==this.addr&&this.padToAlignment(4)}copyWithNewAddr(A){return new me(A,this.data,0)}splitImage(A){const t=new me(this.addr,this.data.slice(0,A),0);return this.data=this.data.slice(A),this.addr+=A,this.fileOffs=null,t}toString(){let A=`len 0x${this.data.length.toString(16).padStart(5,"0")} load 0x${this.addr.toString(16).padStart(8,"0")}`;return null!==this.fileOffs&&(A+=` file_offs 0x${this.fileOffs.toString(16).padStart(8,"0")}`),A}getMemoryType(A){return A.ROM_LOADER.MEMORY_MAP.filter((A=>A[0]<=this.addr&&this.addrA[2]))}padToAlignment(A){this.data=Re(this.data,A,0)}}class be extends me{constructor(A,t,e,i){super(t,e,null,i),this.name=A}toString(){return`${this.name} ${super.toString()}`}}class xe{constructor(A){this.SEG_HEADER_LEN=8,this.SHA256_DIGEST_LEN=32,this.ELF_FLAG_WRITE=1,this.ELF_FLAG_READ=2,this.ELF_FLAG_EXEC=4,this.segments=[],this.entrypoint=0,this.elfSha256=null,this.elfSha256Offset=0,this.padToSize=0,this.flashMode=0,this.flashSizeFreq=0,this.checksum=0,this.datalength=0,this.IROM_ALIGN=0,this.MMU_PAGE_SIZE_CONF=[],this.ROM_LOADER=A}loadCommonHeader(t,e,i){const s=t[e],a=t[e+1];if(this.flashMode=t[e+2],this.flashSizeFreq=t[e+3],this.entrypoint=Ye(t,e+4),s!==i)throw new A(`Invalid firmware image magic=0x${s.toString(16)}`);return a}verify(){if(this.segments.length>16)throw new A(`Invalid segment count ${this.segments.length} (max 16). Usually this indicates a linker script problem.`)}loadSegment(t,e,i=!1){const s=e,a=Ye(t,e),E=Ye(t,e+4);this.warnIfUnusualSegment(a,E,i);const n=t.slice(e+8,e+8+E);if(n.length1075838976||A<1073610752||t>65536)&&console.warn(`WARNING: Suspicious segment 0x${A.toString(16)}, length ${t}`)}maybePatchSegmentData(t,e){const i=t.length;if(this.elfSha256Offset>=e&&this.elfSha256Offseti)throw new A(`Cannot place SHA256 digest on segment boundary(elf_sha256_offset=${this.elfSha256Offset}, file_pos=${e}, segment_size=${i})`);const a=s-this.SEG_HEADER_LEN;if(!t.slice(a,a+this.SHA256_DIGEST_LEN).every((A=>0===A)))throw new A(`Contents of segment at SHA256 digest offset 0x${this.elfSha256Offset.toString(16)} are not all zero. Refusing to overwrite.`);if(!this.elfSha256||this.elfSha256.length!==this.SHA256_DIGEST_LEN)throw new A("ELF SHA256 digest is not properly initialized");const E=t.slice(0,a),n=t.slice(a+this.SHA256_DIGEST_LEN),r=E.length+this.elfSha256.length+n.length,h=new Uint8Array(r);return h.set(E,0),h.set(this.elfSha256,E.length),h.set(n,E.length+this.elfSha256.length),h}return t}saveSegment(A,t,e,i=null){const s=this.maybePatchSegmentData(e.data,t),a=new DataView(A.buffer,t);return a.setUint32(0,e.addr,!0),a.setUint32(4,s.length,!0),A.set(s,t+8),null!==i?De(s,i):0}saveFlashSegment(A,t,e,i=null){if("ESP32"===this.ROM_LOADER.CHIP_NAME){const A=(t+e.data.length+this.SEG_HEADER_LEN)%this.IROM_ALIGN;if(A<36){const t=new Uint8Array(e.data.length+(36-A));t.set(e.data),t.fill(0,e.data.length),e.data=t}}return this.saveSegment(A,t,e,i)}readChecksum(A,t){return A[He(t,16)]}calculateChecksum(){let A=239;for(const t of this.segments)t.includeInChecksum&&(A=De(t.data,A));return A}appendChecksum(A,t,e){A[He(t,16)]=e}writeCommonHeader(A,t,e){A[t]=ke,A[t+1]=e,A[t+2]=this.flashMode,A[t+3]=this.flashSizeFreq;new DataView(A.buffer,t+4).setUint32(0,this.entrypoint,!0)}isIromAddr(A){return ye.IROM_MAP_START<=A&&Athis.isIromAddr(A.addr)));if(t.length>0){if(1!==t.length)throw new A(`Found ${t.length} segments that could be irom0. Bad ELF file?`);return t[0]}return null}getNonIromSegments(){const A=this.getIromSegment();return this.segments.filter((t=>t!==A))}sortSegments(){this.segments.length&&this.segments.sort(((A,t)=>A.addr-t.addr))}mergeAdjacentSegments(){if(!this.segments.length)return;const A=[];for(let t=this.segments.length-1;t>0;t--){const e=this.segments[t-1],i=this.segments[t];if(e.getMemoryType(this).join(",")===i.getMemoryType(this).join(",")&&e.includeInChecksum===i.includeInChecksum&&i.addr===e.addr+e.data.length&&(i.flags&this.ELF_FLAG_EXEC)==(e.flags&this.ELF_FLAG_EXEC)){const A=new Uint8Array(e.data.length+i.data.length);A.set(e.data),A.set(i.data,e.data.length),e.data=A}else A.unshift(i)}A.unshift(this.segments[0]),this.segments=A}setMmuPageSize(t){if(this.MMU_PAGE_SIZE_CONF||t===this.IROM_ALIGN){if(this.MMU_PAGE_SIZE_CONF&&!this.MMU_PAGE_SIZE_CONF.includes(t)){const e=this.MMU_PAGE_SIZE_CONF.map((A=>A/1024+"KB")).join(", ");throw new A(`${t} bytes is not a valid ${this.ROM_LOADER.CHIP_NAME} page size, select from ${e}.`)}this.IROM_ALIGN=t}else console.warn(`WARNING: Changing MMU page size is not supported on ${this.ROM_LOADER.CHIP_NAME}! `+(0!==this.IROM_ALIGN?`Defaulting to ${this.IROM_ALIGN/1024}KB.`:""))}}class Ke extends xe{constructor(A,t=null,e=!0,i=!1){super(A),this.securePad=null,this.flashMode=0,this.flashSizeFreq=0,this.version=1,this.WP_PIN_DISABLED=238,this.wpPin=this.WP_PIN_DISABLED,this.clkDrv=0,this.qDrv=0,this.dDrv=0,this.csDrv=0,this.hdDrv=0,this.wpDrv=0,this.chipId=0,this.minRev=0,this.minRevFull=0,this.maxRevFull=0,this.storedDigest=null,this.calcDigest=null,this.dataLength=0,this.IROM_ALIGN=65536,this.ROM_LOADER=A,this.appendDigest=e,this.ramOnlyHeader=i,null!==t&&this.loadFromFile(t)}async loadFromFile(A){const t=A instanceof Uint8Array?A:de(A);let e=0;const i=this.loadCommonHeader(t,e,ke);e+=8,this.loadExtendedHeader(t,e),e+=16;for(let A=0;Athis.isFlashAddr(A.addr))).sort(((A,t)=>A.addr-t.addr)),E=this.segments.filter((A=>!this.isFlashAddr(A.addr))).sort(((A,t)=>A.addr-t.addr));for(let A=0;A0){let t=a[0].addr;for(const e of a.slice(1)){if(Math.floor(e.addr/this.IROM_ALIGN)===Math.floor(t/this.IROM_ALIGN))throw new A(`Segment loaded at 0x${e.addr.toString(16)} lands in same 64KB flash mapping as segment loaded at 0x${t.toString(16)}. Can't generate binary. Suggest changing linker script or ELF to merge sections.`);t=e.addr}}if(this.ramOnlyHeader){for(const A of E)s=this.saveSegment(e,i,A,s),i+=8+A.data.length,t++;this.appendChecksum(e,i,s),i=He(i,16);for(const A of a.reverse()){let a=this.getAlignmentDataNeeded(A,i);if(a>0){a0;){const A=a[0],n=this.getAlignmentDataNeeded(A,i);if(n>0){if(E.length>0&&n>this.SEG_HEADER_LEN){const A=E[0].splitImage(n);0===E[0].data.length&&E.shift(),s=this.saveSegment(e,i,A,s)}else{const A=new me(0,new Uint8Array(n).fill(0),i);s=this.saveSegment(e,i,A,s)}i+=8+n,t++}else{if((i+8)%this.IROM_ALIGN!=A.addr%this.IROM_ALIGN)throw new Error("Flash segment alignment mismatch");s=this.saveFlashSegment(e,i,A,s),a.shift(),i+=8+A.data.length,t++}}for(const A of E)s=this.saveSegment(e,i,A,s),i+=8+A.data.length,t++}if(this.securePad){if(!this.appendDigest)throw new Error("secure_pad only applies if a SHA-256 digest is also appended to the image");const A=(i+this.SEG_HEADER_LEN)%this.IROM_ALIGN,a=16;let E=0;"1"===this.securePad?E=112:"2"===this.securePad&&(E=32);const n=(this.IROM_ALIGN-A-a-E)%this.IROM_ALIGN,r=new me(0,new Uint8Array(n).fill(0),i);s=this.saveSegment(e,i,r,s),i+=8+n,t++}this.ramOnlyHeader||(this.appendChecksum(e,i,s),i=He(i,16));const n=i;if(this.ramOnlyHeader?e[1]=E.length:e[1]=t,this.appendDigest){const A=await crypto.subtle.digest("SHA-256",e.slice(0,n)),t=new Uint8Array(A);e.set(t,n),i+=32}if(this.padToSize&&i%this.padToSize!=0){const A=this.padToSize-i%this.padToSize,t=new Uint8Array(A);t.fill(255),e.set(t,i),i+=A}return e}loadExtendedHeader(A,t){const e=new DataView(A.buffer,t);this.wpPin=e.getUint8(0);const i=e.getUint8(1);[this.clkDrv,this.qDrv]=this.splitByte(i);const s=e.getUint8(2);[this.dDrv,this.csDrv]=this.splitByte(s);const a=e.getUint8(3);[this.hdDrv,this.wpDrv]=this.splitByte(a),this.chipId=e.getUint8(4),this.chipId!==this.ROM_LOADER.IMAGE_CHIP_ID&&console.warn(`Unexpected chip id in image. Expected ${this.ROM_LOADER.IMAGE_CHIP_ID} but value was ${this.chipId}. Is this image for a different chip model?`),this.minRev=e.getUint8(5),this.minRevFull=e.getUint16(6,!0),this.maxRevFull=e.getUint16(8,!0);const E=e.getUint8(15);if(0!==E&&1!==E)throw new Error(`Invalid value for append_digest field (0x${E.toString(16)}). Should be 0 or 1.`);this.appendDigest=1===E}saveExtendedHeader(A,t){const e=new ArrayBuffer(16),i=new DataView(e);i.setUint8(0,this.wpPin),i.setUint8(1,this.joinByte(this.clkDrv,this.qDrv)),i.setUint8(2,this.joinByte(this.dDrv,this.csDrv)),i.setUint8(3,this.joinByte(this.hdDrv,this.wpDrv)),i.setUint8(4,this.ROM_LOADER.IMAGE_CHIP_ID),i.setUint8(5,this.minRev),i.setUint16(6,this.minRevFull,!0),i.setUint16(8,this.maxRevFull,!0);for(let A=9;A<15;A++)i.setUint8(A,0);i.setUint8(15,this.appendDigest?1:0),A.set(new Uint8Array(e),t)}splitByte(A){return[15&A,A>>4&15]}joinByte(A,t){return 15&A|(15&t)<<4}getAlignmentDataNeeded(A,t){const e=A.addr%this.IROM_ALIGN-this.SEG_HEADER_LEN;let i=this.IROM_ALIGN-t%this.IROM_ALIGN+e;return 0===i||i===this.IROM_ALIGN?0:(i-=this.SEG_HEADER_LEN,i<0&&(i+=this.IROM_ALIGN),i)}}class Le extends xe{constructor(A,t=null){super(A),this.version=1,this.ROM_LOADER=A,this.flashMode=0,this.flashSizeFreq=0,null!==t&&this.loadFromFile(t)}loadFromFile(A){const t=A instanceof Uint8Array?A:de(A);let e=0;const i=this.loadCommonHeader(t,e,ke);e+=8;for(let A=0;Anew Fe(A,t),customReset:(A,t)=>new Pe(A,t),hardReset:(A,t)=>new Te(A,t),usbJTAGSerialReset:A=>new fe(A)},A.serialOptions&&(this.serialOptions=A.serialOptions),A.terminal&&(this.terminal=A.terminal,this.terminal.clean()),void 0!==A.debugLogging&&(this.debugLogging=A.debugLogging),A.port&&(this.transport=new Me(A.port)),void 0!==A.enableTracing&&(this.transport.tracing=A.enableTracing),(null===(t=A.resetConstructors)||void 0===t?void 0:t.classicReset)&&(this.resetConstructors.classicReset=null===(e=A.resetConstructors)||void 0===e?void 0:e.classicReset),(null===(i=A.resetConstructors)||void 0===i?void 0:i.customReset)&&(this.resetConstructors.customReset=null===(s=A.resetConstructors)||void 0===s?void 0:s.customReset),(null===(a=A.resetConstructors)||void 0===a?void 0:a.hardReset)&&(this.resetConstructors.hardReset=null===(E=A.resetConstructors)||void 0===E?void 0:E.hardReset),(null===(n=A.resetConstructors)||void 0===n?void 0:n.usbJTAGSerialReset)&&(this.resetConstructors.usbJTAGSerialReset=null===(r=A.resetConstructors)||void 0===r?void 0:r.usbJTAGSerialReset),this.info("esptool.js"),this.info("Serial port "+this.transport.getInfo())}write(A,t=!0){this.terminal?t?this.terminal.writeLine(A):this.terminal.write(A):console.log(A)}error(A,t=!0){this.write(`Error: ${A}`,t)}info(A,t=!0){this.write(A,t)}debug(A,t=!0){this.debugLogging&&this.write(`Debug: ${A}`,t)}_shortToBytearray(A){return new Uint8Array([255&A,A>>8&255])}_intToByteArray(A){return new Uint8Array([255&A,A>>8&255,A>>16&255,A>>24&255])}_byteArrayToShort(A,t){return A|t>>8}_byteArrayToInt(A,t,e,i){return A|t<<8|e<<16|i<<24}_appendBuffer(A,t){const e=new Uint8Array(A.byteLength+t.byteLength);return e.set(new Uint8Array(A),0),e.set(new Uint8Array(t),A.byteLength),e.buffer}_appendArray(A,t){const e=new Uint8Array(A.length+t.length);return e.set(A,0),e.set(t,A.length),e}ui8ToBstr(A){let t="";for(let e=0;e0&&(a=this._appendArray(a,this._intToByteArray(this.chip.UART_DATE_REG_ADDR)),a=this._appendArray(a,this._intToByteArray(0)),a=this._appendArray(a,this._intToByteArray(0)),a=this._appendArray(a,this._intToByteArray(s))),await this.checkCommand("write target memory",this.ESP_WRITE_REG,a)}async sync(){this.debug("Sync");const A=new Uint8Array(36);let t;for(A[0]=7,A[1]=7,A[2]=18,A[3]=32,t=0;t<32;t++)A[4+t]=85;try{let t=await this.command(8,A,void 0,void 0,100);this.syncStubDetected=0===t[0];for(let A=0;A<7;A++)t=await this.readPacket(8,100),this.syncStubDetected=this.syncStubDetected&&0===t[0];return t}catch(A){throw this.debug("Sync err "+A),A}}async _connectAttempt(A="default_reset",t){this.debug("_connect_attempt "+A),t&&await t.reset();const e=this.transport.peek(),i=Array.from(e,(A=>String.fromCharCode(A))).join("").match(/boot:(0x[0-9a-fA-F]+)([\s\S]*?waiting for download)?/);let s=!1,a="",E=!1;i&&(s=!0,a=i[1],E=!!i[2]),this.debug(`bootMode:${a} downloadMode:${E}`);let n="";for(let A=0;A<5;A++)try{this.debug(`Sync connect attempt ${A}`),this.transport.flushInput();const t=await this.sync();return this.debug(t[0].toString()),"success"}catch(A){this.debug(`Error at sync ${A}`),n=A instanceof Error?A.message:"string"==typeof A?A:JSON.stringify(A)}return s&&(n=`Wrong boot mode detected (${a}).\n This chip needs to be in download mode.`,E&&(n="Download mode successfully detected, but getting no sync reply:\n The serial TX path seems to be down.")),n}constructResetSequence(A){if("no_reset"!==A)if("usb_reset"===A||this.transport.getPid()===this.USB_JTAG_SERIAL_PID){if(this.resetConstructors.usbJTAGSerialReset)return this.debug("using USB JTAG Serial Reset"),[this.resetConstructors.usbJTAGSerialReset(this.transport)]}else{const A=50,t=A+500;if(this.resetConstructors.classicReset)return this.debug("using Classic Serial Reset"),[this.resetConstructors.classicReset(this.transport,A),this.resetConstructors.classicReset(this.transport,t)]}return[]}async connect(t="default_reset",e=7,i=!0){let s;this.info("Connecting...",!1),await this.transport.connect(this.romBaudrate,this.serialOptions),this.transport.readLoop();const a=this.constructResetSequence(t);for(let A=0;A0?a[A%a.length]:null;if(s=await this._connectAttempt(t,e),"success"===s)break}if("success"!==s)throw new A("Failed to connect with the device");if(this.debug("Connect attempt successful."),this.info("\n\r",!1),i){const t=await this.readReg(this.CHIP_DETECT_MAGIC_REG_ADDR)>>>0;this.debug("Chip Magic "+t.toString(16));const e=await async function(A){switch(A){case 15736195:{const{ESP32ROM:A}=await Promise.resolve().then((function(){return Js}));return new A}case 203546735:case 1867591791:case 2084675695:{const{ESP32C2ROM:A}=await Promise.resolve().then((function(){return js}));return new A}case 1763790959:case 456216687:case 1216438383:case 1130455151:{const{ESP32C3ROM:A}=await Promise.resolve().then((function(){return zs}));return new A}case 752910447:{const{ESP32C6ROM:A}=await Promise.resolve().then((function(){return Zs}));return new A}case 606167151:case 871374959:case 1333878895:{const{ESP32C61ROM:A}=await Promise.resolve().then((function(){return Xs}));return new A}case 285294703:case 1675706479:case 1607549039:{const{ESP32C5ROM:A}=await Promise.resolve().then((function(){return Vs}));return new A}case 3619110528:case 2548236392:{const{ESP32H2ROM:A}=await Promise.resolve().then((function(){return qs}));return new A}case 9:{const{ESP32S3ROM:A}=await Promise.resolve().then((function(){return $s}));return new A}case 1990:{const{ESP32S2ROM:A}=await Promise.resolve().then((function(){return Aa}));return new A}case 4293968129:{const{ESP8266ROM:A}=await Promise.resolve().then((function(){return Ge}));return new A}case 0:case 182303440:case 117676761:{const{ESP32P4ROM:A}=await Promise.resolve().then((function(){return ta}));return new A}default:return null}}(t);if(null===typeof this.chip)throw new A(`Unexpected CHIP magic value ${t}. Failed to autodetect chip type.`);this.chip=e}}async detectChip(A="default_reset"){await this.connect(A),this.info("Detecting chip type... ",!1),null!=this.chip?this.info(this.chip.CHIP_NAME):this.info("unknown!")}async checkCommand(t="",e=null,i=new Uint8Array(0),s=0,a=0,E=this.DEFAULT_TIMEOUT){this.debug("check_command "+t);const n=await this.command(e,i,s,void 0,E);if(n&&n[1]&&n[1].length0?n[1].slice(0,a):n[0]}async memBegin(t,e,i,s){if(this.IS_STUB){const e=s,i=s+t,a=this.chip.getChipRevision?await this.chip.getChipRevision(this):void 0,E=await Oe(this.chip.CHIP_NAME,a);if(E){const t=[[E.bss_start||E.data_start,E.data_start+E.decodedData.length],[E.text_start,E.text_start+E.decodedText.length]];for(const[s,a]of t)if(es)throw new A(`Software loader is resident at 0x${s.toString(16).padStart(8,"0")}-0x${a.toString(16).padStart(8,"0")}.\n Can't load binary at overlapping address range 0x${e.toString(16).padStart(8,"0")}-0x${i.toString(16).padStart(8,"0")}.\n Either change binary loading address, or use the no-stub option to disable the software loader.`)}}this.debug("mem_begin "+t+" "+e+" "+i+" "+s.toString(16));let a=this._appendArray(this._intToByteArray(t),this._intToByteArray(e));a=this._appendArray(a,this._intToByteArray(i)),a=this._appendArray(a,this._intToByteArray(s)),await this.checkCommand("enter RAM download mode",this.ESP_MEM_BEGIN,a)}checksum(A,t=this.ESP_CHECKSUM_MAGIC){for(let e=0;e{const e=r+this.chip.SPI_MOSI_DLEN_OFFS,i=r+this.chip.SPI_MISO_DLEN_OFFS;A>0&&await this.writeReg(e,A-1),t>0&&await this.writeReg(i,t-1);let s=0;E>0&&(s|=E-1),a>0&&(s|=a-1<{const e=B;let i=(0===t?0:t-1)<<8|(0===A?0:A-1)<<17;E>0&&(i|=E-1),a>0&&(i|=a-1<32)throw new A("Reading more than 32 bits back from a SPI flash operation is unsupported");if(e.length>64)throw new A("Writing more than 64 bytes of data with one SPI command is unsupported");const l=8*e.length,R=await this.readReg(o),D=await this.readReg(w);let d=1<<31;i>0&&(d|=268435456),l>0&&(d|=134217728),a>0&&(d|=n),E>0&&(d|=536870912),await _(l,i),await this.writeReg(o,d);let S,M=7<<28|t;if(await this.writeReg(w,M),s&&a>0&&(this.SPI_ADDR_REG_MSB&&(s<<=32-a),await this.writeReg(g,s)),0==l)await this.writeReg(c,0);else{e=Re(e,4,0);const A=[];for(let t=0;t>>0);let t=c;for(const e of A)await this.writeReg(t,e),t+=4}for(await this.writeReg(h,C),S=0;S<10&&(M=await this.readReg(h)&C,0!=M);S++);if(10===S)throw new A("SPI command did not complete in time");const Q=await this.readReg(c);return await this.writeReg(o,R),await this.writeReg(w,D),Q}async readFlashId(){const A=new Uint8Array(0);return await this.runSpiflashCommand(159,A,24)}async eraseFlash(){this.info("Erasing flash (this may take a while)...");let A=new Date;const t=A.getTime(),e=await this.checkCommand("erase flash",this.ESP_ERASE_FLASH,void 0,void 0,void 0,this.CHIP_ERASE_TIMEOUT);A=new Date;const i=A.getTime();return this.info("Chip erase completed successfully in "+(i-t)/1e3+"s"),e}toHex(A){return Array.prototype.map.call(A,(A=>("00"+A.toString(16)).slice(-2))).join("")}async flashMd5sum(A,t){const e=this.timeoutPerMb(this.MD5_TIMEOUT_PER_MB,t);let i=this._appendArray(this._intToByteArray(A),this._intToByteArray(t));i=this._appendArray(i,this._intToByteArray(0)),i=this._appendArray(i,this._intToByteArray(0));const s=this.IS_STUB?16:32,a=await this.checkCommand("calculate md5sum",this.ESP_SPI_FLASH_MD5,i,void 0,s,e);return this.toHex(a)}async readFlash(t,e,i=null){let s=this._appendArray(this._intToByteArray(t),this._intToByteArray(e));s=this._appendArray(s,this._intToByteArray(4096)),s=this._appendArray(s,this._intToByteArray(1024));const a=await this.checkCommand("read flash",this.ESP_READ_FLASH,s);if(0!=a)throw new A("Failed to read memory: "+a);let E=new Uint8Array(0);for(;E.length0&&(E=this._appendArray(E,t),await this.transport.write(this._intToByteArray(E.length)),i&&i(t,E.length,e))}return E}async runStub(){if(this.syncStubDetected)return this.info("Stub is already running. No upload is necessary."),this.chip;this.info("Uploading stub...");const t=this.chip.getChipRevision?await this.chip.getChipRevision(this):void 0,e=await Oe(this.chip.CHIP_NAME,t);if(void 0===e)throw this.debug("Error loading Stub json"),new Error("Error loading Stub json");const i=[e.decodedText,e.decodedData];for(let A=0;Ae)throw new A(`File ${i+1} doesn't fit in the available flash`)}let e,i;!0===this.IS_STUB&&!0===t.eraseAll&&await this.eraseFlash();for(let s=0;s=e.length;if(!t.compress)throw new A("Yet to handle Non Compressed writes");{const A=_;c.push(E,o);const t=_-A;let e=3e3;this.timeoutPerMb(this.ERASE_WRITE_TIMEOUT_PER_MB,t)>3e3&&(e=this.timeoutPerMb(this.ERASE_WRITE_TIMEOUT_PER_MB,t)),!1===this.IS_STUB&&(w=e),await this.flashDeflBlock(E,r,w),this.IS_STUB&&(w=e)}h+=E.length,C+=a,r++,t.reportProgress&&t.reportProgress(s,h,g)}this.IS_STUB&&(t.compress?await this.flashDeflFinish(!1,w):await this.flashFinish(!1,w)),o=new Date;const I=o.getTime()-B;if(t.compress&&this.info("Wrote "+E+" bytes ("+h+" compressed) at 0x"+i.toString(16)+" in "+I/1e3+" seconds."),a){this.info("File md5: "+a);const t=await this.flashMd5sum(i,E);if(this.info("Flash md5: "+t),new String(t).valueOf()!=new String(a).valueOf())throw new A("MD5 of file does not match data in flash!");this.info("Hash of data verified.")}}this.info("Leaving...")}async flashId(){this.debug("flash_id");const A=await this.readFlashId();this.info("Manufacturer: "+(255&A).toString(16));const t=A>>16&255;this.info("Device: "+(A>>8&255).toString(16)+t.toString(16)),this.info("Detected flash size: "+this.DETECTED_FLASH_SIZES[t])}async detectFlashSize(){this.debug("detectFlashSize");const A=await this.readFlashId()>>16&255;let t=this.DETECTED_FLASH_SIZES[A];return t?this.info("Auto-detected Flash size: "+t):(t="4MB",this.info("Could not auto-detect Flash size. defaulting to 4MB")),t}async softReset(t){if(this.IS_STUB){if("ESP8266"!=this.chip.CHIP_NAME)throw new A("Soft resetting is currently only supported on ESP8266");t?(await this.flashBegin(0,0),await this.flashFinish(!0)):await this.command(this.ESP_RUN_USER_CODE,void 0,void 0,!1)}else{if(t)return;await this.flashBegin(0,0),await this.flashFinish(!1)}}async after(A="hard_reset",t,e){switch(A){case"hard_reset":if(this.resetConstructors.hardReset){this.info("Hard resetting via RTS pin...");const A=this.resetConstructors.hardReset(this.transport,t);await A.reset()}break;case"soft_reset":this.info("Soft resetting..."),await this.softReset(!1);break;case"no_reset_stub":this.info("Staying in flasher stub.");break;case"custom_reset":if(e||this.info("Custom reset sequence not provided, doing nothing."),this.resetConstructors.customReset||this.info("Custom reset constructor not available, doing nothing."),this.resetConstructors.customReset&&e){this.info("Custom resetting using sequence "+e);const A=this.resetConstructors.customReset(this.transport,e);await A.reset()}break;default:this.info("Staying in bootloader."),this.IS_STUB&&this.softReset(!0)}}}const ti=1074521580,ei="CAD0PxwA9D8AAPQ/AMD8PxAA9D82QQAh+v/AIAA4AkH5/8AgACgEICB0nOIGBQAAAEH1/4H2/8AgAKgEiAigoHTgCAALImYC54b0/yHx/8AgADkCHfAAAKDr/T8Ya/0/hIAAAEBAAABYq/0/pOv9PzZBALH5/yCgdBARIOXOAJYaBoH2/5KhAZCZEZqYwCAAuAmR8/+goHSaiMAgAJIYAJCQ9BvJwMD0wCAAwlgAmpvAIACiSQDAIACSGACB6v+QkPSAgPSHmUeB5f+SoQGQmRGamMAgAMgJoeX/seP/h5wXxgEAfOiHGt7GCADAIACJCsAgALkJRgIAwCAAuQrAIACJCZHX/5qIDAnAIACSWAAd8AAA+CD0P/gw9D82QQCR/f/AIACICYCAJFZI/5H6/8AgAIgJgIAkVkj/HfAAAAAQIPQ/ACD0PwAAAAg2QQAQESCl/P8h+v8MCMAgAIJiAJH6/4H4/8AgAJJoAMAgAJgIVnn/wCAAiAJ88oAiMCAgBB3wAAAAAEA2QQAQESDl+/8Wav+B7P+R+//AIACSaADAIACYCFZ5/x3wAAAMQP0/////AAQg9D82QQAh/P84QhaDBhARIGX4/xb6BQz4DAQ3qA2YIoCZEIKgAZBIg0BAdBARICX6/xARICXz/4giDBtAmBGQqwHMFICrAbHt/7CZELHs/8AgAJJrAJHO/8AgAKJpAMAgAKgJVnr/HAkMGkCag5AzwJqIOUKJIh3wAAAskgBANkEAoqDAgf3/4AgAHfAAADZBAIKgwK0Ch5IRoqDbgff/4AgAoqDcRgQAAAAAgqDbh5IIgfL/4AgAoqDdgfD/4AgAHfA2QQA6MsYCAACiAgAbIhARIKX7/zeS8R3wAAAAfNoFQNguBkCc2gVAHNsFQDYhIaLREIH6/+AIAEYLAAAADBRARBFAQ2PNBL0BrQKB9f/gCACgoHT8Ws0EELEgotEQgfH/4AgASiJAM8BWA/0iogsQIrAgoiCy0RCB7P/gCACtAhwLEBEgpff/LQOGAAAioGMd8AAA/GcAQNCSAEAIaABANkEhYqEHwGYRGmZZBiwKYtEQDAVSZhqB9//gCAAMGECIEUe4AkZFAK0GgdT/4AgAhjQAAJKkHVBzwOCZERqZQHdjiQnNB70BIKIggc3/4AgAkqQd4JkRGpmgoHSICYyqDAiCZhZ9CIYWAAAAkqQd4JkREJmAgmkAEBEgJer/vQetARARIKXt/xARICXp/80HELEgYKYggbv/4AgAkqQd4JkRGpmICXAigHBVgDe1sJKhB8CZERqZmAmAdcCXtwJG3P+G5v8MCIJGbKKkGxCqoIHK/+AIAFYK/7KiC6IGbBC7sBARIOWWAPfqEvZHD7KiDRC7sHq7oksAG3eG8f9867eawWZHCIImGje4Aoe1nCKiCxAisGC2IK0CgZv/4AgAEBEgpd//rQIcCxARICXj/xARIKXe/ywKgbH/4AgAHfAIIPQ/cOL6P0gkBkDwIgZANmEAEBEg5cr/EKEggfv/4AgAPQoMEvwqiAGSogCQiBCJARARIKXP/5Hy/6CiAcAgAIIpAKCIIMAgAIJpALIhAKHt/4Hu/+AIAKAjgx3wAAD/DwAANkEAgTv/DBmSSAAwnEGZKJH7/zkYKTgwMLSaIiozMDxBDAIpWDlIEBEgJfj/LQqMGiKgxR3wAABQLQZANkEAQSz/WDRQM2MWYwRYFFpTUFxBRgEAEBEgZcr/iESmGASIJIel7xARIKXC/xZq/6gUzQO9AoHx/+AIAKCgdIxKUqDEUmQFWBQ6VVkUWDQwVcBZNB3wAADA/D9PSEFJqOv9P3DgC0AU4AtADAD0PzhA9D///wAAjIAAABBAAACs6/0/vOv9P2CQ9D//j///ZJD0P2iQ9D9ckPQ/BMD8PwjA/D8E7P0/FAD0P/D//wCo6/0/DMD8PyRA/T98aABA7GcAQFiGAEBsKgZAODIGQBQsBkDMLAZATCwGQDSFAEDMkABAeC4GQDDvBUBYkgBATIIAQDbBACHZ/wwKImEIQqAAge7/4AgAIdT/MdX/xgAASQJLIjcy+BARICXC/wxLosEgEBEgpcX/IqEBEBEg5cD/QYz+kCIRKiQxyv+xyv/AIABJAiFz/gwMDFoyYgCB3P/gCAAxxf9SoQHAIAAoAywKUCIgwCAAKQOBLP/gCACB1f/gCAAhvv/AIAAoAsy6HMMwIhAiwvgMEyCjgwwLgc7/4AgA8bf/DB3CoAGyoAHioQBA3REAzBGAuwGioACBx//gCAAhsP9Rv/4qRGLVK8AgACgEFnL/wCAAOAQMBwwSwCAAeQQiQRAiAwEMKCJBEYJRCXlRJpIHHDd3Eh3GBwAiAwNyAwKAIhFwIiBmQhAoI8AgACgCKVEGAQAcIiJRCRARIGWy/wyLosEQEBEgJbb/ggMDIgMCgIgRIIggIZP/ICD0h7IcoqDAEBEg5bD/oqDuEBEgZbD/EBEg5a7/Rtv/AAAiAwEcNyc3NPYiGEbvAAAAIsIvICB09kJwcYT/cCKgKAKgAgAiwv4gIHQcFye3AkbmAHF//3AioCgCoAIAcsIwcHB0tlfJhuAALEkMByKgwJcYAobeAHlRDHKtBxARIKWp/60HEBEgJan/EBEgpaf/EBEgZaf/DIuiwRAiwv8QESClqv9WIv1GKAAMElZoM4JhD4F6/+AIAIjxoCiDRskAJogFDBJGxwAAeCMoMyCHIICAtFbI/hARICXG/yp3nBrG9/8AoKxBgW7/4AgAVir9ItLwIKfAzCIGnAAAoID0Vhj+hgQAoKD1ifGBZv/gCACI8Vba+oAiwAwYAIgRIKfAJzjhBgQAAACgrEGBXf/gCABW6vgi0vAgp8BWov7GigAADAcioMAmiAIGqQAMBy0HRqcAJrj1Bn0ADBImuAIGoQC4M6gjDAcQESDloP+gJ4OGnAAMGWa4XIhDIKkRDAcioMKHugIGmgC4U6IjApJhDhARIOW//5jhoJeDhg0ADBlmuDGIQyCpEQwHIqDCh7oCRo8AKDO4U6gjIHiCmeEQESDlvP8hL/4MCJjhiWIi0it5IqCYgy0JxoIAkSn+DAeiCQAioMZ3mgJGgQB4I4LI8CKgwIeXAShZDAeSoO9GAgB6o6IKGBt3oJkwhyfyggMFcgMEgIgRcIggcgMGAHcRgHcgggMHgIgBcIgggJnAgqDBDAeQKJPGbQCBEf4ioMaSCAB9CRaZGpg4DAcioMh3GQIGZwAoWJJIAEZiAByJDAcMEpcYAgZiAPhz6GPYU8hDuDOoI4EJ/+AIAAwIfQqgKIMGWwAMEiZIAkZWAJHy/oHy/sAgAHgJMCIRgHcQIHcgqCPAIAB5CZHt/gwLwCAAeAmAdxAgdyDAIAB5CZHp/sAgAHgJgHcQIHcgwCAAeQmR5f7AIAB4CYB3ECAnIMAgACkJgez+4AgABiAAAAAAgJA0DAcioMB3GQIGPQCAhEGLs3z8xg4AqDuJ8ZnhucHJ0YHm/uAIALjBiPEoK3gbqAuY4cjRcHIQJgINwCAA2AogLDDQIhAgdyDAIAB5ChuZsssQhznAxoD/ZkgCRn//DAcioMCGJgAMEia4AsYhACHC/ohTeCOJAiHB/nkCDAIGHQCxvf4MB9gLDBqCyPCdBy0HgCqT0JqDIJkQIqDGd5lgwbf+fQnoDCKgyYc+U4DwFCKgwFavBC0JhgIAACqTmGlLIpkHnQog/sAqfYcy7Rap2PkMeQvGYP8MEmaIGCGn/oIiAIwYgqDIDAd5AiGj/nkCDBKAJ4MMB0YBAAAMByKg/yCgdBARICVy/3CgdBARIGVx/xARICVw/1bytyIDARwnJzcf9jICRtz+IsL9ICB0DPcntwLG2P5xkv5wIqAoAqACAAByoNJ3Ek9yoNR3EncG0v6IM6KiccCqEXgjifGBlv7gCAAhh/6RiP7AIAAoAojxIDQ1wCIRkCIQICMggCKCDApwssKBjf7gCACio+iBiv7gCADGwP4AANhTyEO4M6gjEBEgZXX/Brz+ALIDAyIDAoC7ESC7ILLL8KLDGBARIKWR/wa1/gAiAwNyAwKAIhFwIiBxb/0iwvCIN4AiYxaSq4gXioKAjEFGAgCJ8RARIKVa/4jxmEemGQSYJ5eo6xARIOVS/xZq/6gXzQKywxiBbP7gCACMOjKgxDlXOBcqMzkXODcgI8ApN4ab/iIDA4IDAnLDGIAiETg1gCIgIsLwVsMJ9lIChiUAIqDJRioAMU/+gU/96AMpceCIwIlhiCatCYeyAQw6meGp0enBEBEgpVL/qNGBRv6pAejBoUX+3Qi9B8LBHPLBGInxgU7+4AgAuCbNCqhxmOGgu8C5JqAiwLgDqneoYYjxqrsMCrkDwKmDgLvAoNB0zJri24CtDeCpgxbqAa0IifGZ4cnREBEgpYD/iPGY4cjRiQNGAQAAAAwcnQyMsjg1jHPAPzHAM8CWs/XWfAAioMcpVQZn/lacmSg1FkKZIqDIBvv/qCNWmpiBLf7gCACionHAqhGBJv7gCACBKv7gCACGW/4AACgzFnKWDAqBJP7gCACio+iBHv7gCADgAgAGVP4d8AAAADZBAJ0CgqDAKAOHmQ/MMgwShgcADAIpA3zihg8AJhIHJiIYhgMAAACCoNuAKSOHmSoMIikDfPJGCAAAACKg3CeZCgwSKQMtCAYEAAAAgqDdfPKHmQYMEikDIqDbHfAAAA==",ii=1074520064,si="DMD8P+znC0B/6AtAZ+0LQAbpC0Cf6AtABukLQGXpC0CC6gtA9OoLQJ3qC0CV5wtAGuoLQHTqC0CI6QtAGOsLQLDpC0AY6wtAbegLQMroC0AG6QtAZekLQIXoC0DI6wtAKe0LQLjmC0BL7QtAuOYLQLjmC0C45gtAuOYLQLjmC0C45gtAuOYLQLjmC0Bv6wtAuOYLQEnsC0Ap7QtA",ai=1073605544,Ei=1073528832;var ni={entry:ti,text:ei,text_start:ii,data:si,data_start:ai,bss_start:Ei},ri=Object.freeze({__proto__:null,bss_start:Ei,data:si,data_start:ai,default:ni,entry:ti,text:ei,text_start:ii});const hi=1077413304,gi="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",oi=1077411840,Bi="DEDKP+AIOEAsCThAhAk4QFIKOEC+CjhAbAo4QKgHOEAOCjhATgo4QJgJOEBYBzhAzAk4QFgHOEC6CDhA/gg4QCwJOECECThAzAg4QBIIOEBCCDhAyAg4QBYNOEAsCThA1gs4QMoMOECkBjhA9Aw4QKQGOECkBjhApAY4QKQGOECkBjhApAY4QKQGOECkBjhAcgs4QKQGOEDyCzhAygw4QA==",wi=1070295976,ci=1070219264;var _i={entry:hi,text:gi,text_start:oi,data:Bi,data_start:wi,bss_start:ci},Ci=Object.freeze({__proto__:null,bss_start:ci,data:Bi,data_start:wi,default:_i,entry:hi,text:gi,text_start:oi});const Ii=1077413584,li="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",Ri=1077411840,Di="GEDIP8AKOEAQCzhAaAs4QDYMOECiDDhAUAw4QHIJOEDyCzhAMgw4QHwLOEAiCThAsAs4QCIJOECaCjhA4Ao4QBALOEBoCzhArAo4QNYJOEAgCjhAqAo4QPoOOEAQCzhAug04QLIOOEBiCDhA2g44QGIIOEBiCDhAYgg4QGIIOEBiCDhAYgg4QGIIOEBiCDhAVg04QGIIOEDYDThAsg44QA==",di=1070164916,Si=1070088192;var Mi={entry:Ii,text:li,text_start:Ri,data:Di,data_start:di,bss_start:Si},Qi=Object.freeze({__proto__:null,bss_start:Si,data:Di,data_start:di,default:Mi,entry:Ii,text:li,text_start:Ri});const Fi=1082133128,fi="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",Ti=1082130432,Ui="GACEQOYOgEBQD4BA5A+AQLgQgEAgEYBAzhCAQEINgEB0EIBAtBCAQAAQgEDyDIBAKBCAQPIMgEDEDoBADg+AQFAPgEDkD4BA1g6AQGoNgECYDYBA0g6AQBoTgEBQD4BA3BGAQNYSgEAwDIBA/BKAQDAMgEAwDIBAMAyAQDAMgEAwDIBAMAyAQDAMgEAwDIBAghGAQDAMgED0EYBA1hKAQA==",Pi=1082469304,Oi=1082392576;var ui={entry:Fi,text:fi,text_start:Ti,data:Ui,data_start:Pi,bss_start:Oi},pi=Object.freeze({__proto__:null,bss_start:Oi,data:Ui,data_start:Pi,default:ui,entry:Fi,text:fi,text_start:Ti});const yi=1082132164,Gi="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",ki=1082130432,Hi="FACEQHIKgEDCCoBAGguAQOgLgEBUDIBAAgyAQD4JgECkC4BA5AuAQC4LgEDuCIBAYguAQO4IgEBMCoBAkgqAQMIKgEAaC4BAXgqAQKIJgEDSCYBAWgqAQKwOgEDCCoBAbA2AQGQOgEAuCIBAjA6AQC4IgEAuCIBALgiAQC4IgEAuCIBALgiAQC4IgEAuCIBACA2AQC4IgECKDYBAZA6AQA==",Yi=1082469296,mi=1082392576;var bi={entry:yi,text:Gi,text_start:ki,data:Hi,data_start:Yi,bss_start:mi},xi=Object.freeze({__proto__:null,bss_start:mi,data:Hi,data_start:Yi,default:bi,entry:yi,text:Gi,text_start:ki});const Ki=1082132164,Li="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",Ni=1082130432,Ji="FECAQHQKgEDECoBAHAuAQOoLgEBWDIBABAyAQEAJgECmC4BA5guAQDALgEDwCIBAZAuAQPAIgEBOCoBAlAqAQMQKgEAcC4BAYAqAQKQJgEDUCYBAXAqAQK4OgEDECoBAbg2AQGYOgEAwCIBAjg6AQDAIgEAwCIBAMAiAQDAIgEAwCIBAMAiAQDAIgEAwCIBACg2AQDAIgECMDYBAZg6AQA==",vi=1082223536,zi=1082146816;var ji={entry:Ki,text:Li,text_start:Ni,data:Ji,data_start:vi,bss_start:zi},Wi=Object.freeze({__proto__:null,bss_start:zi,data:Ji,data_start:vi,default:ji,entry:Ki,text:Li,text_start:Ni});const Zi=1082132164,Xi="QREixCbCBsa39wBgEUc3BINA2Mu39ABgEwQEANxAkYuR57JAIkSSREEBgoCIQBxAE3X1D4KX3bcBEbcHAGBOxoOphwBKyDcJg0AmylLEBs4izLcEAGB9WhMJCQDATBN09A8N4PJAYkQjqDQBQknSRLJJIkoFYYKAiECDJwkAE3X1D4KXfRTjGUT/yb8TBwAMlEGqh2MY5QCFR4XGI6AFAHlVgoAFR2OH5gAJRmONxgB9VYKAQgUTB7ANQYVjlecCiUecwfW3kwbADWMW1QCYwRMFAAyCgJMG0A19VWOV1wCYwRMFsA2CgLc1hEBBEZOFhboGxmE/Y0UFBrc3hECThweyA6cHCAPWRwgTdfUPkwYWAMIGwYIjktcIMpcjAKcAA9dHCJFnk4cHBGMe9wI3t4NAEwcHsqFnupcDpgcIt/aDQLc3hECThweyk4YGtmMf5gAjpscII6DXCCOSBwghoPlX4wb1/LJAQQGCgCOm1wgjoOcI3bc3NwBgfEudi/X/NycAYHxLnYv1/4KAQREGxt03tzcAYCOmBwI3BwAImMOYQ33/yFeyQBNF9f8FiUEBgoBBEQbG2T993TcHAEC3NwBgmMM3NwBgHEP9/7JAQQGCgEERIsQ3hINAkwdEAUrAA6kHAQbGJsJjCgkERTc5xb1HEwREAYFEY9YnAQREvYiTtBQAfTeFPxxENwaAABOXxwCZ4DcGAAG39v8AdY+3NgBg2MKQwphCff9BR5HgBUczCelAupcjKCQBHMSyQCJEkkQCSUEBgoABEQbOIswlNzcEhUBsABMFBP+XAID/54Ag8qqHBUWV57JHk/cHID7GiTc3NwBgHEe3BkAAEwUE/9WPHMeyRZcAgP/ngKDvMzWgAPJAYkQFYYKAQRG3h4NABsaTh0cBBUcjgOcAE9fFAJjHBWd9F8zDyMf5jTqVqpWxgYzLI6oHAEE3GcETBVAMskBBAYKAAREizDeEg0CTB0QBJsrER07GBs5KyKqJEwREAWPzlQCuhKnAAylEACaZE1nJABxIY1XwABxEY175ArU9fd1IQCaGzoWXAID/54Cg4hN19Q8BxZMHQAxcyFxAppdcwFxEhY9cxPJAYkTSREJJskkFYYKAaTVtv0ERBsaXAID/54BA1gNFhQGyQHUVEzUVAEEBgoBBEQbGxTcNxbcHg0CThwcA1EOZzjdnCWATB8cQHEM3Bv3/fRbxjzcGAwDxjtWPHMOyQEEBgoBBEQbGbTcRwQ1FskBBARcDgP9nAIPMQREGxibCIsSqhJcAgP/ngODJWTcNyTcHg0CTBgcAg9eGABMEBwCFB8IHwYMjlPYAkwYADGOG1AATB+ADY3X3AG03IxQEALJAIkSSREEBgoBBEQbGEwcADGMa5QATBbANRTcTBcANskBBAVm/EwewDeMb5f5xNxMF0A31t0ERIsQmwgbGKoSzBLUAYxeUALJAIkSSREEBgoADRQQABQRNP+23NXEmy07H/XKFaf10Is1KyVLFVsMGz5OEhPoWkZOHCQemlxgIs4TnACqJJoUuhJcAgP/ngEApk4cJBxgIBWq6l7OKR0Ex5AVnfXWTBYX6kwcHBxMFhfkUCKqXM4XXAJMHBweul7OF1wAqxpcAgP/ngAAmMkXBRZU3AUWFYhaR+kBqRNpESkm6SSpKmkoNYYKAooljc4oAhWlOhtaFSoWXAID/54BAxRN19Q8B7U6G1oUmhZcAgP/ngEAhTpkzBDRBUbcTBTAGVb8TBQAMSb0xcf1yBWdO11LVVtNezwbfIt0m20rZWtFizWbLaslux/13FpETBwcHPpccCLqXPsYjqgf4qokuirKKtov1M5MHAAIZwbcHAgA+hZcAgP/ngOAZhWdj5VcTBWR9eRMJifqTBwQHypcYCDOJ5wBKhZcAgP/ngGAYfXsTDDv5kwyL+RMHBAeTBwQHFAhil+aXgUQzDNcAs4zXAFJNY3xNCWPxpANBqJk/ooUIAY01uTcihgwBSoWXAID/54BAFKKZopRj9UQDs4ekQWPxdwMzBJpAY/OKAFaEIoYMAU6FlwCA/+eAgLQTdfUPVd0CzAFEeV2NTaMJAQBihZcAgP/ngECkffkDRTEB5oWFNGNPBQDj4o3+hWeThwcHopcYCLqX2pcjiqf4BQTxt+MVpf2RR+MF9PYFZ311kwcHB5MFhfoTBYX5FAiqlzOF1wCTBwcHrpezhdcAKsaXAID/54BgCnE9MkXBRWUzUT3BMbcHAgAZ4ZMHAAI+hZcAgP/ngGAHhWIWkfpQalTaVEpZulkqWppaClv6S2pM2kxKTbpNKWGCgLdXQUkZcZOH94QBRYbeotym2srYztbS1NbS2tDezuLM5srqyO7GPs6XAID/54CAnaE5DcE3ZwlgEwfHEBxDtwaDQCOi9gC3Bv3//Rb1j8Fm1Y8cwxU5Bc23JwtgN0fYUJOGx8ETBxeqmMIThgfAIyAGACOgBgCThkfCmMKThwfCmEM3BgQAUY+YwyOgBgC3B4NANzeEQJOHBwATBwe7IaAjoAcAkQfj7ef+RTuRRWgIdTllM7e3g0CThweyIWc+lyMg9wi3B4BANwmDQJOHhw4jIPkAtzmEQEU+EwkJAJOJCbJjBQUQtwcBYEVHI6rnCIVFRUWXAID/54DA8rcFgEABRpOFBQBFRZcAgP/ngMDzt/cAYBFHmMs3BQIAlwCA/+eAAPO3FwlgiF+BRbeEg0BxiWEVEzUVAJcAgP/ngICdwWf9FxMHABCFZkFmtwUAAQFFk4REAbcKg0ANapcAgP/ngICTE4tKASaag6fJCPXfg6vJCIVHI6YJCCMC8QKDxxsACUcjE+ECowLxAgLUTUdjgecIUUdjj+cGKUdjn+cAg8c7AAPHKwCiB9mPEUdjlucAg6eLAJxDPtRFMaFFSBB1NoPHOwADxysAogfZjxFnQQdjdPcEEwWwDRk+EwXADQE+EwXgDik2jTlBt7cFgEABRpOFhQMVRZcAgP/ngMDkNwcAYFxHEwUAApPnFxBcxzG3yUcjE/ECTbcDxxsA0UZj5+YChUZj5uYAAUwTBPAPhah5FxN39w/JRuPo5v63NoRACgeThka7NpcYQwKHkwYHA5P29g8RRuNp1vwTB/cCE3f3D41GY+vmCLc2hEAKB5OGBsA2lxhDAocTB0ACY5jnEALUHUQBRaU0AUVVPPE26TahRUgQfRTRPHX0AUwBRBN19A9xPBN1/A9ZPH024x4E6oPHGwBJR2No9zAJR+N29+r1F5P39w89R+Ng9+o3N4RAigcTBwfBupecQ4KHBUSd63AQgUUBRZfwf//ngABxHeHRRWgQnTwBRDGoBUSB75fwf//ngIB1MzSgACmgIUdjhecABUQBTGG3A6yLAAOkywCzZ4wA0gf19+/wv4V98cFsIpz9HH19MwWMQFXcs3eVAZXjwWwzBYxAY+aMAv18MwWMQFXQMYGX8H//54AAclX5ZpT1tzGBl/B//+eAAHFV8WqU0bdBgZfwf//ngEBwUfkzBJRBwbchR+OJ5/ABTBMEAAwxt0FHzb9BRwVE45zn9oOlywADpYsA5TKxv0FHBUTjkuf2A6cLAZFnY+rnHoOlSwEDpYsA7/D/gDW/QUcFROOS5/SDpwsBEWdjavccA6fLAIOlSwEDpYsAM4TnAu/wb/4jrAQAIySKsDG3A8cEAGMDBxQDp4sAwRcTBAAMYxP3AMBIAUeTBvAOY0b3AoPHWwADx0sAAUyiB9mPA8drAEIHXY+Dx3sA4gfZj+OB9uYTBBAMqb0zhusAA0aGAQUHsY7ht4PHBAD9x9xEY50HFMBII4AEAH21YUdjlucCg6fLAQOniwGDpksBA6YLAYOlywADpYsAl/B//+eAwGAqjDM0oAAptQFMBUQRtRFHBUTjmufmt5cAYLRLZXd9FwVm+Y7RjgOliwC0y/RDgUX5jtGO9MP0S/mO0Y70y7RDdY9Rj7jDl/B//+eAoGMpvRP39wDjFQfqk9xHABOEiwABTH1d43Sc20hEl/B//+eAIEgYRFRAEED5jmMHpwEcQhNH9/99j9mOFMIFDEEE2b8RR6W1QUcFROOX596Dp4sAA6dLASMo+QAjJukAdbuDJckAwReR5YnPAUwTBGAMibsDJwkBY2b3BhP3NwDjGQfiAygJAQFGAUczBehAs4blAGNp9wDjBAbSIyipACMm2QAxuzOG6wAQThEHkMIFRum/IUcFROOR59gDJAkBGcATBIAMIygJACMmCQAzNIAApbMBTBMEIAztsQFMEwSADM2xAUwTBJAM6bkTByANY4PnDBMHQA3jm+e4A8Q7AIPHKwAiBF2Ml/B//+eAwEYDrMQAQRRjc4QBIozjCQy2wEBilDGAnEhjVfAAnERjW/QK7/Cvy3XdyEBihpOFiwGX8H//54DAQgHFkwdADNzI3EDil9zA3ESzh4dB3MSX8H//54CgQSW2CWUTBQVxA6zLAAOkiwCX8H//54CgMrcHAGDYS7cGAAHBFpNXRwESB3WPvYvZj7OHhwMBRbPVhwKX8H//54DAMxMFgD6X8H//54BAL+m8g6ZLAQOmCwGDpcsAA6WLAO/w7/vRtIPFOwCDxysAE4WLAaIF3Y3BFe/wj9V1tO/w78Q9vwPEOwCDxysAE4yLASIEXYzcREEUzeORR4VLY/+HCJMHkAzcyEG0A6cNACLQBUizh+xAPtaDJ4qwY3P0AA1IQsY6xO/wb8AiRzJIN4WDQOKFfBCThkoBEBATBcUCl/B//+eAIDE3t4NAkwhHAYJXA6eIsIOlDQAdjB2PPpyyVyOk6LCqi76VI6C9AJOHSgGdjQHFoWdjl/UAWoXv8C/LI6BtAQnE3ESZw+NPcPdj3wsAkwdwDL23hUu3PYRAt4yDQJONDbuTjEwB6b/jnQuc3ETjigeckweADKm3g6eLAOOTB5zv8C/TCWUTBQVxl/B//+eAoBzv8K/Ol/B//+eA4CBVsgOkywDjDwSY7/Cv0BMFgD6X8H//54BAGu/wT8wClFGy7/DPy/ZQZlTWVEZZtlkmWpZaBlv2S2ZM1kxGTbZNCWGCgAAA",Vi=1082130432,qi="FACDQHIKgEDCCoBAGguAQOgLgEBUDIBAAgyAQD4JgECkC4BA5AuAQC4LgEDuCIBAYguAQO4IgEBMCoBAkgqAQMIKgEAaC4BAXgqAQKIJgEDSCYBAWgqAQKwOgEDCCoBAbA2AQGQOgEAuCIBAjA6AQC4IgEAuCIBALgiAQC4IgEAuCIBALgiAQC4IgEAuCIBACA2AQC4IgECKDYBAZA6AQA==",$i=1082403760,As=1082327040;var ts={entry:Zi,text:Xi,text_start:Vi,data:qi,data_start:$i,bss_start:As},es=Object.freeze({__proto__:null,bss_start:As,data:qi,data_start:$i,default:ts,entry:Zi,text:Xi,text_start:Vi});const is=1341196642,ss="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",as=1341194240,Es="YAD1T3gO8U/GDvFPZA/xT0oQ8U+kEPFPXBDxT8oM8U/+D/FPRhDxT4IP8U96DPFPqg/xT3oM8U9UDvFPkg7xT8YO8U9kD/FPZg7xT/QM8U8oDfFPYg7xT3YU8U/GDvFPGBLxTzYU8U8eC/FPWhTxTx4L8U8eC/FPHgvxTx4L8U8eC/FPHgvxTx4L8U8eC/FPthHxTx4L8U9SE/FPNhTxTw==",ns=1341533180,rs=1341456384;var hs={entry:is,text:ss,text_start:as,data:Es,data_start:ns,bss_start:rs},gs=Object.freeze({__proto__:null,bss_start:rs,data:Es,data_start:ns,default:hs,entry:is,text:ss,text_start:as});const os=1341459344,Bs="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",ws=1341456384,cs="YAD2T8oQ9U80EfVP0BH1T6wS9U8UE/VPwhL1TwQP9U9oEvVPqBL1T+wR9U+0DvVPFBL1T7QO9U+mEPVP8hD1TzQR9U/QEfVPuBD1TywP9U9gD/VPtBD1TxIV9U80EfVP2BP1T9IU9U9YDfVP9hT1T1gN9U9YDfVPWA31T1gN9U9YDfVPWA31T1gN9U9YDfVPdhP1T1gN9U/wE/VP0hT1Tw==",_s=1341598720,Cs=1341521920;var Is={entry:os,text:Bs,text_start:ws,data:cs,data_start:_s,bss_start:Cs},ls=Object.freeze({__proto__:null,bss_start:Cs,data:cs,data_start:_s,default:Is,entry:os,text:Bs,text_start:ws});const Rs=1073907716,Ds="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",ds=1073905664,Ss="WAD9P0uLAkDdiwJA8pACQGaMAkD+iwJAZowCQMWMAkDejQJAUY4CQPmNAkDVigJAd40CQNCNAkDojAJAdI4CQBCNAkB0jgJAy4sCQCqMAkBmjAJAxYwCQOOLAkAXiwJAN48CQKqQAkDqiQJA0ZACQOqJAkDqiQJA6okCQOqJAkDqiQJA6okCQOqJAkDqiQJA1I4CQOqJAkDJjwJAqpACQA==",Ms=1073622012,Qs=1073545216;var Fs={entry:Rs,text:Ds,text_start:ds,data:Ss,data_start:Ms,bss_start:Qs},fs=Object.freeze({__proto__:null,bss_start:Qs,data:Ss,data_start:Ms,default:Fs,entry:Rs,text:Ds,text_start:ds});const Ts=1077381760,Us="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",Ps=1077379072,Os="XADKP16ON0AzjzdAR5Q3QL2PN0BTjzdAvY83QB2QN0A6kTdArJE3QFWRN0DpjTdA0JA3QCyRN0BAkDdA0JE3QGiQN0DQkTdAIY83QH6PN0C9jzdAHZA3QDmPN0AqjjdAkJI3QA2UN0AAjTdALZQ3QACNN0AAjTdAAI03QACNN0AAjTdAAI03QACNN0AAjTdAKpI3QACNN0AlkzdADZQ3QAQInwAAAAAAAAAYAQQIBQAAAAAAAAAIAQQIBgAAAAAAAAAAAQQIIQAAAAAAIAAAEQQI3AAAAAAAIAAAEQQIDAAAAAAAIAAAAQQIEgAAAAAAIAAAESAoDAAQAQAA",us=1070279676,ps=1070202880;var ys={entry:Ts,text:Us,text_start:Ps,data:Os,data_start:us,bss_start:ps},Gs=Object.freeze({__proto__:null,bss_start:ps,data:Os,data_start:us,default:ys,entry:Ts,text:Us,text_start:Ps});const ks=1074843652,Hs="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",Ys=1074843648,ms="CIH+PwUFBAACAwcAAwMLANTXEEAL2BBAOdgQQNbYEECF5xBAOtkQQJDZEEDc2RBAhecQQKLaEEAf2xBA4NsQQIXnEECF5xBAeNwQQIXnEEBV3xBAHOAQQFfgEECF5xBAhecQQPPgEECF5xBA2+EQQIHiEEDA4xBAf+QQQFDlEECF5xBAhecQQIXnEECF5xBAfuYQQIXnEEB05xBAsN0QQKnYEEDC5RBAydoQQBvaEECF5xBACOcQQE/nEECF5xBAhecQQIXnEECF5xBAhecQQIXnEECF5xBAhecQQELaEEB/2hBA2uUQQAEAAAACAAAAAwAAAAQAAAAFAAAABwAAAAkAAAANAAAAEQAAABkAAAAhAAAAMQAAAEEAAABhAAAAgQAAAMEAAAABAQAAgQEAAAECAAABAwAAAQQAAAEGAAABCAAAAQwAAAEQAAABGAAAASAAAAEwAAABQAAAAWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAgAAAAIAAAADAAAAAwAAAAQAAAAEAAAABQAAAAUAAAAGAAAABgAAAAcAAAAHAAAACAAAAAgAAAAJAAAACQAAAAoAAAAKAAAACwAAAAsAAAAMAAAADAAAAA0AAAANAAAAAAAAAAAAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAANAAAADwAAABEAAAATAAAAFwAAABsAAAAfAAAAIwAAACsAAAAzAAAAOwAAAEMAAABTAAAAYwAAAHMAAACDAAAAowAAAMMAAADjAAAAAgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAABAAAAAgAAAAIAAAACAAAAAgAAAAMAAAADAAAAAwAAAAMAAAAEAAAABAAAAAQAAAAEAAAABQAAAAUAAAAFAAAABQAAAAAAAAAAAAAAAAAAABAREgAIBwkGCgULBAwDDQIOAQ8AAQEAAAEAAAAEAAAA",bs=1073720488,xs=1073643776;var Ks={entry:ks,text:Hs,text_start:Ys,data:ms,data_start:bs,bss_start:xs},Ls=Object.freeze({__proto__:null,bss_start:xs,data:ms,data_start:bs,default:Ks,entry:ks,text:Hs,text_start:Ys});class Ns extends pe{constructor(){super(...arguments),this.CHIP_NAME="ESP32",this.IMAGE_CHIP_ID=0,this.EFUSE_RD_REG_BASE=1073061888,this.DR_REG_SYSCON_BASE=1073111040,this.UART_CLKDIV_REG=1072955412,this.UART_CLKDIV_MASK=1048575,this.UART_DATE_REG_ADDR=1610612856,this.XTAL_CLK_DIVIDER=1,this.IROM_MAP_START=1074593792,this.IROM_MAP_END=1077936128,this.DROM_MAP_START=1061158912,this.DROM_MAP_END=1065353216,this.MEMORY_MAP=[[0,65536,"PADDING"],[1061158912,1065353216,"DROM"],[1065353216,1069547520,"EXTRAM_DATA"],[1073217536,1073225728,"RTC_DRAM"],[1073283072,1073741824,"BYTE_ACCESSIBLE"],[1073405952,1073741824,"DRAM"],[1073610752,1073741820,"DIRAM_DRAM"],[1073741824,1074200576,"IROM"],[1074200576,1074233344,"CACHE_PRO"],[1074233344,1074266112,"CACHE_APP"],[1074266112,1074397184,"IRAM"],[1074397184,1074528252,"DIRAM_IRAM"],[1074528256,1074536448,"RTC_IRAM"],[1074593792,1077936128,"IROM"],[1342177280,1342185472,"RTC_DATA"]],this.FLASH_SIZES={"1MB":0,"2MB":16,"4MB":32,"8MB":48,"16MB":64,"32MB":80,"64MB":96,"128MB":112},this.FLASH_FREQUENCY={"80m":15,"40m":0,"26m":1,"20m":2},this.FLASH_WRITE_SIZE=1024,this.BOOTLOADER_FLASH_OFFSET=4096,this.SPI_REG_BASE=1072963584,this.SPI_USR_OFFS=28,this.SPI_USR1_OFFS=32,this.SPI_USR2_OFFS=36,this.SPI_W0_OFFS=128,this.SPI_MOSI_DLEN_OFFS=40,this.SPI_MISO_DLEN_OFFS=44}async readEfuse(A,t){const e=this.EFUSE_RD_REG_BASE+4*t;return A.debug("Read efuse "+e),await A.readReg(e)}async getPkgVersion(A){const t=await this.readEfuse(A,3);let e=t>>9&7;return e+=(t>>2&1)<<3,e}async getChipRevision(A){const t=await this.readEfuse(A,3),e=await this.readEfuse(A,5),i=await A.readReg(this.DR_REG_SYSCON_BASE+124);return 0!=(t>>15&1)?0!=(e>>20&1)?0!=(i>>31&1)?3:2:1:0}async getChipDescription(A){const t=["ESP32-D0WDQ6","ESP32-D0WD","ESP32-D2WD","","ESP32-U4WDH","ESP32-PICO-D4","ESP32-PICO-V3-02"];let e="";const i=await this.getPkgVersion(A),s=await this.getChipRevision(A),a=3==s;return 0!=(1&await this.readEfuse(A,3))&&(t[0]="ESP32-S0WDQ6",t[1]="ESP32-S0WD"),a&&(t[5]="ESP32-PICO-V3"),e=i>=0&&i<=6?t[i]:"Unknown ESP32",!a||0!==i&&1!==i||(e+="-V3"),e+" (revision "+s+")"}async getChipFeatures(A){const t=["Wi-Fi"],e=await this.readEfuse(A,3);0===(2&e)&&t.push(" BT");0!==(1&e)?t.push(" Single Core"):t.push(" Dual Core");if(0!==(8192&e)){0!==(4096&e)?t.push(" 160MHz"):t.push(" 240MHz")}const i=await this.getPkgVersion(A);-1!==[2,4,5,6].indexOf(i)&&t.push(" Embedded Flash"),6===i&&t.push(" Embedded PSRAM");0!==(await this.readEfuse(A,4)>>8&31)&&t.push(" VRef calibration in efuse");0!==(e>>14&1)&&t.push(" BLK3 partially reserved");const s=3&await this.readEfuse(A,6);return t.push(" Coding Scheme "+["None","3/4","Repeat (UNSUPPORTED)","Invalid"][s]),t}async getCrystalFreq(A){const t=await A.readReg(this.UART_CLKDIV_REG)&this.UART_CLKDIV_MASK,e=A.transport.baudrate*t/1e6/this.XTAL_CLK_DIVIDER;let i;return i=e>33?40:26,Math.abs(i-e)>1&&A.info("WARNING: Unsupported crystal in use"),i}_d2h(A){const t=(+A).toString(16);return 1===t.length?"0"+t:t}async readMac(A){let t=await this.readEfuse(A,1);t>>>=0;let e=await this.readEfuse(A,2);e>>>=0;const i=new Uint8Array(6);return i[0]=e>>8&255,i[1]=255&e,i[2]=t>>24&255,i[3]=t>>16&255,i[4]=t>>8&255,i[5]=255&t,this._d2h(i[0])+":"+this._d2h(i[1])+":"+this._d2h(i[2])+":"+this._d2h(i[3])+":"+this._d2h(i[4])+":"+this._d2h(i[5])}}var Js=Object.freeze({__proto__:null,ESP32ROM:Ns});class vs extends Ns{constructor(){super(...arguments),this.CHIP_NAME="ESP32-C3",this.IMAGE_CHIP_ID=5,this.EFUSE_BASE=1610647552,this.MAC_EFUSE_REG=this.EFUSE_BASE+68,this.UART_CLKDIV_REG=1072955412,this.UART_CLKDIV_MASK=1048575,this.UART_DATE_REG_ADDR=1610612860,this.FLASH_WRITE_SIZE=1024,this.BOOTLOADER_FLASH_OFFSET=0,this.SPI_REG_BASE=1610620928,this.SPI_USR_OFFS=24,this.SPI_USR1_OFFS=28,this.SPI_USR2_OFFS=32,this.SPI_MOSI_DLEN_OFFS=36,this.SPI_MISO_DLEN_OFFS=40,this.SPI_W0_OFFS=88,this.IROM_MAP_START=1107296256,this.IROM_MAP_END=1115684864,this.MEMORY_MAP=[[0,65536,"PADDING"],[1006632960,1015021568,"DROM"],[1070071808,1070465024,"DRAM"],[1070104576,1070596096,"BYTE_ACCESSIBLE"],[1072693248,1072824320,"DROM_MASK"],[1073741824,1074135040,"IROM_MASK"],[1107296256,1115684864,"IROM"],[1077395456,1077805056,"IRAM"],[1342177280,1342185472,"RTC_IRAM"],[1342177280,1342185472,"RTC_DRAM"],[1611653120,1611661312,"MEM_INTERNAL2"]]}async getPkgVersion(A){const t=this.EFUSE_BASE+68+12;return await A.readReg(t)>>21&7}async getChipRevision(A){const t=this.EFUSE_BASE+68+12;return(await A.readReg(t)&7<<18)>>18}async getMinorChipVersion(A){const t=this.EFUSE_BASE+68+20,e=await A.readReg(t)>>23&1,i=this.EFUSE_BASE+68+12;return(e<<3)+(await A.readReg(i)>>18&7)}async getMajorChipVersion(A){const t=this.EFUSE_BASE+68+20;return await A.readReg(t)>>24&3}async getChipDescription(A){const t=await this.getPkgVersion(A),e=await this.getMajorChipVersion(A),i=await this.getMinorChipVersion(A);return`${{0:"ESP32-C3 (QFN32)",1:"ESP8685 (QFN28)",2:"ESP32-C3 AZ (QFN32)",3:"ESP8686 (QFN24)"}[t]||"Unknown ESP32-C3"} (revision v${e}.${i})`}async getFlashCap(A){const t=this.EFUSE_BASE+68+12;return await A.readReg(t)>>27&7}async getFlashVendor(A){const t=this.EFUSE_BASE+68+16;return{1:"XMC",2:"GD",3:"FM",4:"TT",5:"ZBIT"}[7&await A.readReg(t)]||""}async getChipFeatures(A){const t=["Wi-Fi","BLE"],e=await this.getFlashCap(A),i=await this.getFlashVendor(A),s={0:null,1:"Embedded Flash 4MB",2:"Embedded Flash 2MB",3:"Embedded Flash 1MB",4:"Embedded Flash 8MB"}[e],a=void 0!==s?s:"Unknown Embedded Flash";return null!==s&&t.push(`${a} (${i})`),t}async getCrystalFreq(A){return 40}_d2h(A){const t=(+A).toString(16);return 1===t.length?"0"+t:t}async readMac(A){let t=await A.readReg(this.MAC_EFUSE_REG);t>>>=0;let e=await A.readReg(this.MAC_EFUSE_REG+4);e=e>>>0&65535;const i=new Uint8Array(6);return i[0]=e>>8&255,i[1]=255&e,i[2]=t>>24&255,i[3]=t>>16&255,i[4]=t>>8&255,i[5]=255&t,this._d2h(i[0])+":"+this._d2h(i[1])+":"+this._d2h(i[2])+":"+this._d2h(i[3])+":"+this._d2h(i[4])+":"+this._d2h(i[5])}getEraseSize(A,t){return t}}var zs=Object.freeze({__proto__:null,ESP32C3ROM:vs});var js=Object.freeze({__proto__:null,ESP32C2ROM:class extends vs{constructor(){super(...arguments),this.CHIP_NAME="ESP32-C2",this.IMAGE_CHIP_ID=12,this.EFUSE_BASE=1610647552,this.MAC_EFUSE_REG=this.EFUSE_BASE+64,this.UART_CLKDIV_REG=1610612756,this.UART_CLKDIV_MASK=1048575,this.UART_DATE_REG_ADDR=1610612860,this.XTAL_CLK_DIVIDER=1,this.FLASH_WRITE_SIZE=1024,this.BOOTLOADER_FLASH_OFFSET=0,this.SPI_REG_BASE=1610620928,this.SPI_USR_OFFS=24,this.SPI_USR1_OFFS=28,this.SPI_USR2_OFFS=32,this.SPI_MOSI_DLEN_OFFS=36,this.SPI_MISO_DLEN_OFFS=40,this.SPI_W0_OFFS=88,this.IROM_MAP_START=1107296256,this.IROM_MAP_END=1111490560,this.MEMORY_MAP=[[0,65536,"PADDING"],[1006632960,1010827264,"DROM"],[1070202880,1070465024,"DRAM"],[1070104576,1070596096,"BYTE_ACCESSIBLE"],[1072693248,1073020928,"DROM_MASK"],[1073741824,1074331648,"IROM_MASK"],[1107296256,1111490560,"IROM"],[1077395456,1077673984,"IRAM"]]}async getPkgVersion(A){const t=this.EFUSE_BASE+64+4;return await A.readReg(t)>>22&7}async getChipRevision(A){const t=this.EFUSE_BASE+64+4;return(await A.readReg(t)&3<<20)>>20}async getChipDescription(A){let t;const e=await this.getPkgVersion(A);t=0===e||1===e?"ESP32-C2":"unknown ESP32-C2";return t+=" (revision "+await this.getChipRevision(A)+")",t}async getChipFeatures(A){return["Wi-Fi","BLE"]}async getCrystalFreq(A){const t=await A.readReg(this.UART_CLKDIV_REG)&this.UART_CLKDIV_MASK,e=A.transport.baudrate*t/1e6/this.XTAL_CLK_DIVIDER;let i;return i=e>33?40:26,Math.abs(i-e)>1&&A.info("WARNING: Unsupported crystal in use"),i}async changeBaudRate(A){26===await this.getCrystalFreq(A)&&A.changeBaud()}_d2h(A){const t=(+A).toString(16);return 1===t.length?"0"+t:t}async readMac(A){let t=await A.readReg(this.MAC_EFUSE_REG);t>>>=0;let e=await A.readReg(this.MAC_EFUSE_REG+4);e=e>>>0&65535;const i=new Uint8Array(6);return i[0]=e>>8&255,i[1]=255&e,i[2]=t>>24&255,i[3]=t>>16&255,i[4]=t>>8&255,i[5]=255&t,this._d2h(i[0])+":"+this._d2h(i[1])+":"+this._d2h(i[2])+":"+this._d2h(i[3])+":"+this._d2h(i[4])+":"+this._d2h(i[5])}getEraseSize(A,t){return t}}});class Ws extends vs{constructor(){super(...arguments),this.CHIP_NAME="ESP32-C6",this.IMAGE_CHIP_ID=13,this.EFUSE_BASE=1611335680,this.EFUSE_BLOCK1_ADDR=this.EFUSE_BASE+68,this.MAC_EFUSE_REG=this.EFUSE_BASE+68,this.UART_CLKDIV_REG=1072955412,this.UART_CLKDIV_MASK=1048575,this.UART_DATE_REG_ADDR=1610612860,this.FLASH_WRITE_SIZE=1024,this.BOOTLOADER_FLASH_OFFSET=0,this.SPI_REG_BASE=1610620928,this.SPI_USR_OFFS=24,this.SPI_USR1_OFFS=28,this.SPI_USR2_OFFS=32,this.SPI_MOSI_DLEN_OFFS=36,this.SPI_MISO_DLEN_OFFS=40,this.SPI_W0_OFFS=88,this.IROM_MAP_START=1107296256,this.IROM_MAP_END=1115684864,this.MEMORY_MAP=[[0,65536,"PADDING"],[1107296256,1124073472,"DROM"],[1082130432,1082654720,"DRAM"],[1082130432,1082654720,"BYTE_ACCESSIBLE"],[1074048e3,1074069504,"DROM_MASK"],[1073741824,1074048e3,"IROM_MASK"],[1107296256,1124073472,"IROM"],[1082130432,1082654720,"IRAM"],[1342177280,1342193664,"RTC_IRAM"],[1342177280,1342193664,"RTC_DRAM"],[1611653120,1611661312,"MEM_INTERNAL2"]]}async getPkgVersion(A){const t=this.EFUSE_BASE+68+12;return await A.readReg(t)>>21&7}async getChipRevision(A){const t=this.EFUSE_BASE+68+12;return(await A.readReg(t)&7<<18)>>18}async getChipDescription(A){let t;t=0===await this.getPkgVersion(A)?"ESP32-C6":"unknown ESP32-C6";return t+=" (revision "+await this.getChipRevision(A)+")",t}async getChipFeatures(A){return["Wi-Fi 6","BT 5","IEEE802.15.4"]}async getCrystalFreq(A){return 40}_d2h(A){const t=(+A).toString(16);return 1===t.length?"0"+t:t}async readMac(A){let t=await A.readReg(this.MAC_EFUSE_REG);t>>>=0;let e=await A.readReg(this.MAC_EFUSE_REG+4);e=e>>>0&65535;const i=new Uint8Array(6);return i[0]=e>>8&255,i[1]=255&e,i[2]=t>>24&255,i[3]=t>>16&255,i[4]=t>>8&255,i[5]=255&t,this._d2h(i[0])+":"+this._d2h(i[1])+":"+this._d2h(i[2])+":"+this._d2h(i[3])+":"+this._d2h(i[4])+":"+this._d2h(i[5])}getEraseSize(A,t){return t}}var Zs=Object.freeze({__proto__:null,ESP32C6ROM:Ws});var Xs=Object.freeze({__proto__:null,ESP32C61ROM:class extends Ws{constructor(){super(...arguments),this.CHIP_NAME="ESP32-C61",this.IMAGE_CHIP_ID=20,this.CHIP_DETECT_MAGIC_VALUE=[871374959,606167151],this.UART_DATE_REG_ADDR=1610612860,this.EFUSE_BASE=1611352064,this.EFUSE_BLOCK1_ADDR=this.EFUSE_BASE+68,this.MAC_EFUSE_REG=this.EFUSE_BASE+68,this.EFUSE_RD_REG_BASE=this.EFUSE_BASE+48,this.EFUSE_PURPOSE_KEY0_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY0_SHIFT=0,this.EFUSE_PURPOSE_KEY1_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY1_SHIFT=4,this.EFUSE_PURPOSE_KEY2_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY2_SHIFT=8,this.EFUSE_PURPOSE_KEY3_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY3_SHIFT=12,this.EFUSE_PURPOSE_KEY4_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY4_SHIFT=16,this.EFUSE_PURPOSE_KEY5_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY5_SHIFT=20,this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT_REG=this.EFUSE_RD_REG_BASE,this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT=1<<20,this.EFUSE_SPI_BOOT_CRYPT_CNT_REG=this.EFUSE_BASE+48,this.EFUSE_SPI_BOOT_CRYPT_CNT_MASK=7<<23,this.EFUSE_SECURE_BOOT_EN_REG=this.EFUSE_BASE+52,this.EFUSE_SECURE_BOOT_EN_MASK=1<<26,this.FLASH_FREQUENCY={"80m":15,"40m":0,"20m":2},this.IROM_MAP_START=1107296256,this.IROM_MAP_END=1115684864,this.MEMORY_MAP=[[0,65536,"PADDING"],[1098907648,1107296256,"DROM"],[1082130432,1082523648,"DRAM"],[1082130432,1082523648,"BYTE_ACCESSIBLE"],[1074048e3,1074069504,"DROM_MASK"],[1073741824,1074048e3,"IROM_MASK"],[1090519040,1098907648,"IROM"],[1082130432,1082523648,"IRAM"],[1342177280,1342193664,"RTC_IRAM"],[1342177280,1342193664,"RTC_DRAM"],[1611653120,1611661312,"MEM_INTERNAL2"]],this.UF2_FAMILY_ID=2010665156,this.EFUSE_MAX_KEY=5,this.KEY_PURPOSES={0:"USER/EMPTY",1:"ECDSA_KEY",2:"XTS_AES_256_KEY_1",3:"XTS_AES_256_KEY_2",4:"XTS_AES_128_KEY",5:"HMAC_DOWN_ALL",6:"HMAC_DOWN_JTAG",7:"HMAC_DOWN_DIGITAL_SIGNATURE",8:"HMAC_UP",9:"SECURE_BOOT_DIGEST0",10:"SECURE_BOOT_DIGEST1",11:"SECURE_BOOT_DIGEST2",12:"KM_INIT_KEY",13:"XTS_AES_256_KEY_1_PSRAM",14:"XTS_AES_256_KEY_2_PSRAM",15:"XTS_AES_128_KEY_PSRAM"}}async getPkgVersion(A){return await A.readReg(this.EFUSE_BLOCK1_ADDR+8)>>26&7}async getMinorChipVersion(A){return 15&await A.readReg(this.EFUSE_BLOCK1_ADDR+8)}async getMajorChipVersion(A){return await A.readReg(this.EFUSE_BLOCK1_ADDR+8)>>4&3}async getChipDescription(A){let t;t=0===await this.getPkgVersion(A)?"ESP32-C61":"unknown ESP32-C61";return`${t} (revision v${await this.getMajorChipVersion(A)}.${await this.getMinorChipVersion(A)})`}async getChipFeatures(A){return["WiFi 6","BT 5"]}async readMac(A){let t=await A.readReg(this.MAC_EFUSE_REG);t>>>=0;let e=await A.readReg(this.MAC_EFUSE_REG+4);e=e>>>0&65535;const i=new Uint8Array(6);return i[0]=e>>8&255,i[1]=255&e,i[2]=t>>24&255,i[3]=t>>16&255,i[4]=t>>8&255,i[5]=255&t,this._d2h(i[0])+":"+this._d2h(i[1])+":"+this._d2h(i[2])+":"+this._d2h(i[3])+":"+this._d2h(i[4])+":"+this._d2h(i[5])}}});var Vs=Object.freeze({__proto__:null,ESP32C5ROM:class extends Ws{constructor(){super(...arguments),this.CHIP_NAME="ESP32-C5",this.IMAGE_CHIP_ID=23,this.BOOTLOADER_FLASH_OFFSET=8192,this.EFUSE_BASE=1611352064,this.EFUSE_BLOCK1_ADDR=this.EFUSE_BASE+68,this.MAC_EFUSE_REG=this.EFUSE_BASE+68,this.UART_CLKDIV_REG=1610612756,this.EFUSE_RD_REG_BASE=this.EFUSE_BASE+48,this.EFUSE_FORCE_USE_KEY_MANAGER_KEY_REG=this.EFUSE_BASE+52,this.EFUSE_FORCE_USE_KEY_MANAGER_KEY_SHIFT=10,this.FORCE_USE_KEY_MANAGER_VAL_XTS_AES_KEY=2,this.EFUSE_PURPOSE_KEY0_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY0_SHIFT=22,this.EFUSE_PURPOSE_KEY1_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY1_SHIFT=27,this.EFUSE_PURPOSE_KEY2_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY2_SHIFT=0,this.EFUSE_PURPOSE_KEY3_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY3_SHIFT=5,this.EFUSE_PURPOSE_KEY4_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY4_SHIFT=10,this.EFUSE_PURPOSE_KEY5_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY5_SHIFT=15,this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT_REG=this.EFUSE_RD_REG_BASE,this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT=1<<20,this.EFUSE_SPI_BOOT_CRYPT_CNT_REG=this.EFUSE_BASE+52,this.EFUSE_SPI_BOOT_CRYPT_CNT_MASK=7<<18,this.EFUSE_SECURE_BOOT_EN_REG=this.EFUSE_BASE+56,this.EFUSE_SECURE_BOOT_EN_MASK=1<<20,this.IROM_MAP_START=1107296256,this.IROM_MAP_END=1140850688,this.DROM_MAP_START=1107296256,this.DROM_MAP_END=1140850688,this.PCR_SYSCLK_CONF_REG=1611227408,this.PCR_SYSCLK_XTAL_FREQ_V=127<<24,this.PCR_SYSCLK_XTAL_FREQ_S=24,this.XTAL_CLK_DIVIDER=1,this.UARTDEV_BUF_NO=1082520852,this.CHIP_DETECT_MAGIC_VALUE=[285294703,1675706479,1607549039],this.FLASH_FREQUENCY={"80m":15,"40m":0,"20m":2},this.MEMORY_MAP=[[0,65536,"PADDING"],[1107296256,1140850688,"DROM"],[1082130432,1082523648,"DRAM"],[1082130432,1082523648,"BYTE_ACCESSIBLE"],[1073979392,1074003968,"DROM_MASK"],[1073741824,1073979392,"IROM_MASK"],[1107296256,1140850688,"IROM"],[1082130432,1082523648,"IRAM"],[1342177280,1342193664,"RTC_IRAM"],[1342177280,1342193664,"RTC_DRAM"],[1611653120,1611661312,"MEM_INTERNAL2"]],this.UF2_FAMILY_ID=4145808195,this.EFUSE_MAX_KEY=5,this.PURPOSE_VAL_XTS_AES128_KEY=4,this.KEY_PURPOSES={0:"USER/EMPTY",1:"ECDSA_KEY",4:"XTS_AES_128_KEY",5:"HMAC_DOWN_ALL",6:"HMAC_DOWN_JTAG",7:"HMAC_DOWN_DIGITAL_SIGNATURE",8:"HMAC_UP",9:"SECURE_BOOT_DIGEST0",10:"SECURE_BOOT_DIGEST1",11:"SECURE_BOOT_DIGEST2",12:"KM_INIT_KEY",15:"XTS_AES_128_PSRAM_KEY",16:"ECDSA_KEY_P192",17:"ECDSA_KEY_P384_L",18:"ECDSA_KEY_P384_H"}}async getPkgVersion(A){return await A.readReg(this.EFUSE_BLOCK1_ADDR+8)>>26&7}async getMinorChipVersion(A){return 15&await A.readReg(this.EFUSE_BLOCK1_ADDR+8)}async getMajorChipVersion(A){return await A.readReg(this.EFUSE_BLOCK1_ADDR+8)>>4&3}async getChipDescription(A){let t;t=0===await this.getPkgVersion(A)?"ESP32-C5":"unknown ESP32-C5";return`${t} (revision v${await this.getMajorChipVersion(A)}.${await this.getMinorChipVersion(A)})`}async getChipFeatures(A){return["Wi-Fi 6 (dual-band)","BT 5 (LE)","IEEE802.15.4","Single Core + LP Core","240MHz"]}async getCrystalFreq(A){const t=await A.readReg(this.UART_CLKDIV_REG)&this.UART_CLKDIV_MASK,e=A.transport.baudrate*t/1e6/this.XTAL_CLK_DIVIDER;let i;return i=e>45?48:e>33?40:26,Math.abs(i-e)>1&&A.info("WARNING: Unsupported crystal in use"),i}async getCrystalFreqRomExpect(A){return(await A.readReg(this.PCR_SYSCLK_CONF_REG)&this.PCR_SYSCLK_XTAL_FREQ_V)>>this.PCR_SYSCLK_XTAL_FREQ_S}async getKeyBlockPurpose(A,t){if(t<0||t>this.EFUSE_MAX_KEY)throw new Error(`Valid key block numbers must be in range 0-${this.EFUSE_MAX_KEY}`);const e=[[this.EFUSE_PURPOSE_KEY0_REG,this.EFUSE_PURPOSE_KEY0_SHIFT],[this.EFUSE_PURPOSE_KEY1_REG,this.EFUSE_PURPOSE_KEY1_SHIFT],[this.EFUSE_PURPOSE_KEY2_REG,this.EFUSE_PURPOSE_KEY2_SHIFT],[this.EFUSE_PURPOSE_KEY3_REG,this.EFUSE_PURPOSE_KEY3_SHIFT],[this.EFUSE_PURPOSE_KEY4_REG,this.EFUSE_PURPOSE_KEY4_SHIFT],[this.EFUSE_PURPOSE_KEY5_REG,this.EFUSE_PURPOSE_KEY5_SHIFT]],[i,s]=e[t];return await A.readReg(i)>>s&31}async isFlashEncryptionKeyValid(A){const t=[];for(let e=0;e<=this.EFUSE_MAX_KEY;e++){const i=await this.getKeyBlockPurpose(A,e);t.push(i)}if(t.some((A=>A===this.PURPOSE_VAL_XTS_AES128_KEY)))return!0;return!!(await A.readReg(this.EFUSE_FORCE_USE_KEY_MANAGER_KEY_REG)>>this.EFUSE_FORCE_USE_KEY_MANAGER_KEY_SHIFT&this.FORCE_USE_KEY_MANAGER_VAL_XTS_AES_KEY)}checkSpiConnection(A,t){if(!t.every((A=>A>=0&&A<=28)))throw new Error("SPI Pin numbers must be in the range 0-28.");t.some((A=>13===A||14===A))&&A.info("GPIO pins 13 and 14 are used by USB-Serial/JTAG, consider using other pins for SPI flash connection.")}async usesUsbJtagSerial(A){const t=this.UARTDEV_BUF_NO;return 3===(255&await A.readReg(t))}async watchdogReset(A){throw A.info("Hard resetting with a watchdog..."),new Error("watchdogReset not yet implemented for ESP32-C5")}async changeBaud(A){if(!A.IS_STUB){const t=await this.getCrystalFreqRomExpect(A),e=await this.getCrystalFreq(A);A.info(`ROM expects crystal freq: ${t} MHz, detected ${e} MHz.`),(48===e&&40===t||40===e&&48===t)&&A.info("Crystal frequency mismatch detected. Baud rate adjustment may be needed but is not fully implemented in this version.")}await A.changeBaud()}}});var qs=Object.freeze({__proto__:null,ESP32H2ROM:class extends Ws{constructor(){super(...arguments),this.CHIP_NAME="ESP32-H2",this.IMAGE_CHIP_ID=16,this.EFUSE_BASE=1611335680,this.EFUSE_BLOCK1_ADDR=this.EFUSE_BASE+68,this.MAC_EFUSE_REG=this.EFUSE_BASE+68,this.UART_CLKDIV_REG=1072955412,this.UART_CLKDIV_MASK=1048575,this.UART_DATE_REG_ADDR=1610612860,this.FLASH_WRITE_SIZE=1024,this.BOOTLOADER_FLASH_OFFSET=0,this.SPI_REG_BASE=1610620928,this.SPI_USR_OFFS=24,this.SPI_USR1_OFFS=28,this.SPI_USR2_OFFS=32,this.SPI_MOSI_DLEN_OFFS=36,this.SPI_MISO_DLEN_OFFS=40,this.SPI_W0_OFFS=88,this.USB_RAM_BLOCK=2048,this.UARTDEV_BUF_NO_USB=3,this.UARTDEV_BUF_NO=1070526796,this.IROM_MAP_START=1107296256,this.IROM_MAP_END=1115684864,this.MEMORY_MAP=[[0,65536,"PADDING"],[1107296256,1124073472,"DROM"],[1082130432,1082654720,"DRAM"],[1082130432,1082654720,"BYTE_ACCESSIBLE"],[1074048e3,1074069504,"DROM_MASK"],[1073741824,1074048e3,"IROM_MASK"],[1107296256,1124073472,"IROM"],[1082130432,1082654720,"IRAM"],[1342177280,1342193664,"RTC_IRAM"],[1342177280,1342193664,"RTC_DRAM"],[1611653120,1611661312,"MEM_INTERNAL2"]]}async getPkgVersion(A){return 7&await A.readReg(this.EFUSE_BLOCK1_ADDR+16)}async getMinorChipVersion(A){return await A.readReg(this.EFUSE_BLOCK1_ADDR+12)>>18&7}async getMajorChipVersion(A){return await A.readReg(this.EFUSE_BLOCK1_ADDR+12)>>21&3}async getChipDescription(A){let t;t=0===await this.getPkgVersion(A)?"ESP32-H2":"unknown ESP32-H2";return`${t} (revision v${await this.getMajorChipVersion(A)}.${await this.getMinorChipVersion(A)})`}async getChipFeatures(A){return["BT 5 (LE)","IEEE802.15.4","Single Core","96MHz"]}async getCrystalFreq(A){return 32}_d2h(A){const t=(+A).toString(16);return 1===t.length?"0"+t:t}async postConnect(A){const t=255&await A.readReg(this.UARTDEV_BUF_NO);A.debug("In _post_connect "+t),t==this.UARTDEV_BUF_NO_USB&&(A.ESP_RAM_BLOCK=this.USB_RAM_BLOCK)}async readMac(A){let t=await A.readReg(this.MAC_EFUSE_REG);t>>>=0;let e=await A.readReg(this.MAC_EFUSE_REG+4);e=e>>>0&65535;const i=new Uint8Array(6);return i[0]=e>>8&255,i[1]=255&e,i[2]=t>>24&255,i[3]=t>>16&255,i[4]=t>>8&255,i[5]=255&t,this._d2h(i[0])+":"+this._d2h(i[1])+":"+this._d2h(i[2])+":"+this._d2h(i[3])+":"+this._d2h(i[4])+":"+this._d2h(i[5])}getEraseSize(A,t){return t}}});var $s=Object.freeze({__proto__:null,ESP32S3ROM:class extends Ns{constructor(){super(...arguments),this.CHIP_NAME="ESP32-S3",this.IMAGE_CHIP_ID=9,this.EFUSE_BASE=1610641408,this.MAC_EFUSE_REG=this.EFUSE_BASE+68,this.EFUSE_BLOCK1_ADDR=this.EFUSE_BASE+68,this.EFUSE_BLOCK2_ADDR=this.EFUSE_BASE+92,this.UART_CLKDIV_REG=1610612756,this.UART_CLKDIV_MASK=1048575,this.UART_DATE_REG_ADDR=1610612864,this.FLASH_WRITE_SIZE=1024,this.BOOTLOADER_FLASH_OFFSET=0,this.SPI_REG_BASE=1610620928,this.SPI_USR_OFFS=24,this.SPI_USR1_OFFS=28,this.SPI_USR2_OFFS=32,this.SPI_MOSI_DLEN_OFFS=36,this.SPI_MISO_DLEN_OFFS=40,this.SPI_W0_OFFS=88,this.USB_RAM_BLOCK=2048,this.UARTDEV_BUF_NO_USB=3,this.UARTDEV_BUF_NO=1070526796,this.IROM_MAP_START=1107296256,this.IROM_MAP_END=1140850688,this.MEMORY_MAP=[[0,65536,"PADDING"],[1006632960,1023410176,"DROM"],[1023410176,1040187392,"EXTRAM_DATA"],[1611653120,1611661312,"RTC_DRAM"],[1070104576,1070596096,"BYTE_ACCESSIBLE"],[1070104576,1077813248,"MEM_INTERNAL"],[1070104576,1070596096,"DRAM"],[1073741824,1073848576,"IROM_MASK"],[1077346304,1077805056,"IRAM"],[1611653120,1611661312,"RTC_IRAM"],[1107296256,1115684864,"IROM"],[1342177280,1342185472,"RTC_DATA"]]}async getChipDescription(A){const t=await this.getMajorChipVersion(A),e=await this.getMinorChipVersion(A);return`${{0:"ESP32-S3 (QFN56)",1:"ESP32-S3-PICO-1 (LGA56)"}[await this.getPkgVersion(A)]||"unknown ESP32-S3"} (revision v${t}.${e})`}async getPkgVersion(A){return await A.readReg(this.EFUSE_BLOCK1_ADDR+12)>>21&7}async getRawMinorChipVersion(A){return((await A.readReg(this.EFUSE_BLOCK1_ADDR+20)>>23&1)<<3)+(await A.readReg(this.EFUSE_BLOCK1_ADDR+12)>>18&7)}async getMinorChipVersion(A){const t=await this.getRawMinorChipVersion(A);return await this.isEco0(A,t)?0:this.getRawMinorChipVersion(A)}async getRawMajorChipVersion(A){return await A.readReg(this.EFUSE_BLOCK1_ADDR+20)>>24&3}async getMajorChipVersion(A){const t=await this.getRawMinorChipVersion(A);return await this.isEco0(A,t)?0:this.getRawMajorChipVersion(A)}async getBlkVersionMajor(A){return 3&await A.readReg(this.EFUSE_BLOCK2_ADDR+16)}async getBlkVersionMinor(A){return await A.readReg(this.EFUSE_BLOCK1_ADDR+12)>>24&7}async isEco0(A,t){return!(7&t)&&1===await this.getBlkVersionMajor(A)&&1===await this.getBlkVersionMinor(A)}async getFlashCap(A){const t=this.EFUSE_BASE+68+12;return await A.readReg(t)>>27&7}async getFlashVendor(A){const t=this.EFUSE_BASE+68+16;return{1:"XMC",2:"GD",3:"FM",4:"TT",5:"BY"}[7&await A.readReg(t)]||""}async getPsramCap(A){const t=this.EFUSE_BASE+68+16;return await A.readReg(t)>>3&3}async getPsramVendor(A){const t=this.EFUSE_BASE+68+16;return{1:"AP_3v3",2:"AP_1v8"}[await A.readReg(t)>>7&3]||""}async getChipFeatures(A){const t=["Wi-Fi","BLE"],e=await this.getFlashCap(A),i=await this.getFlashVendor(A),s={0:null,1:"Embedded Flash 8MB",2:"Embedded Flash 4MB"}[e],a=void 0!==s?s:"Unknown Embedded Flash";null!==s&&t.push(`${a} (${i})`);const E=await this.getPsramCap(A),n=await this.getPsramVendor(A),r={0:null,1:"Embedded PSRAM 8MB",2:"Embedded PSRAM 2MB"}[E],h=void 0!==r?r:"Unknown Embedded PSRAM";return null!==r&&t.push(`${h} (${n})`),t}async getCrystalFreq(A){return 40}_d2h(A){const t=(+A).toString(16);return 1===t.length?"0"+t:t}async postConnect(A){const t=255&await A.readReg(this.UARTDEV_BUF_NO);A.debug("In _post_connect "+t),t==this.UARTDEV_BUF_NO_USB&&(A.ESP_RAM_BLOCK=this.USB_RAM_BLOCK)}async readMac(A){let t=await A.readReg(this.MAC_EFUSE_REG);t>>>=0;let e=await A.readReg(this.MAC_EFUSE_REG+4);e=e>>>0&65535;const i=new Uint8Array(6);return i[0]=e>>8&255,i[1]=255&e,i[2]=t>>24&255,i[3]=t>>16&255,i[4]=t>>8&255,i[5]=255&t,this._d2h(i[0])+":"+this._d2h(i[1])+":"+this._d2h(i[2])+":"+this._d2h(i[3])+":"+this._d2h(i[4])+":"+this._d2h(i[5])}getEraseSize(A,t){return t}}});var Aa=Object.freeze({__proto__:null,ESP32S2ROM:class extends Ns{constructor(){super(...arguments),this.CHIP_NAME="ESP32-S2",this.IMAGE_CHIP_ID=2,this.IROM_MAP_START=1074266112,this.IROM_MAP_END=1085800448,this.DROM_MAP_START=1056964608,this.DROM_MAP_END=1061093376,this.CHIP_DETECT_MAGIC_VALUE=[1990],this.SPI_REG_BASE=1061167104,this.SPI_USR_OFFS=24,this.SPI_USR1_OFFS=28,this.SPI_USR2_OFFS=32,this.SPI_MOSI_DLEN_OFFS=36,this.SPI_MISO_DLEN_OFFS=40,this.SPI_W0_OFFS=88,this.SPI_ADDR_REG_MSB=!1,this.MAC_EFUSE_REG=1061265476,this.UART_CLKDIV_REG=1061158932,this.SUPPORTS_ENCRYPTED_FLASH=!0,this.FLASH_ENCRYPTED_WRITE_ALIGN=16,this.EFUSE_BASE=1061265408,this.EFUSE_RD_REG_BASE=this.EFUSE_BASE+48,this.EFUSE_BLOCK1_ADDR=this.EFUSE_BASE+68,this.EFUSE_BLOCK2_ADDR=this.EFUSE_BASE+92,this.EFUSE_PURPOSE_KEY0_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY0_SHIFT=24,this.EFUSE_PURPOSE_KEY1_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY1_SHIFT=28,this.EFUSE_PURPOSE_KEY2_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY2_SHIFT=0,this.EFUSE_PURPOSE_KEY3_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY3_SHIFT=4,this.EFUSE_PURPOSE_KEY4_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY4_SHIFT=8,this.EFUSE_PURPOSE_KEY5_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY5_SHIFT=12,this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT_REG=this.EFUSE_RD_REG_BASE,this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT=1<<19,this.EFUSE_SPI_BOOT_CRYPT_CNT_REG=this.EFUSE_BASE+52,this.EFUSE_SPI_BOOT_CRYPT_CNT_MASK=7<<18,this.EFUSE_SECURE_BOOT_EN_REG=this.EFUSE_BASE+56,this.EFUSE_SECURE_BOOT_EN_MASK=1<<20,this.EFUSE_RD_REPEAT_DATA3_REG=this.EFUSE_BASE+60,this.EFUSE_RD_REPEAT_DATA3_REG_FLASH_TYPE_MASK=512,this.PURPOSE_VAL_XTS_AES256_KEY_1=2,this.PURPOSE_VAL_XTS_AES256_KEY_2=3,this.PURPOSE_VAL_XTS_AES128_KEY=4,this.UARTDEV_BUF_NO=1073741076,this.UARTDEV_BUF_NO_USB_OTG=2,this.USB_RAM_BLOCK=2048,this.GPIO_STRAP_REG=1061175352,this.GPIO_STRAP_SPI_BOOT_MASK=8,this.GPIO_STRAP_VDDSPI_MASK=16,this.RTC_CNTL_OPTION1_REG=1061191976,this.RTC_CNTL_FORCE_DOWNLOAD_BOOT_MASK=1,this.RTCCNTL_BASE_REG=1061191680,this.RTC_CNTL_WDTCONFIG0_REG=this.RTCCNTL_BASE_REG+148,this.RTC_CNTL_WDTCONFIG1_REG=this.RTCCNTL_BASE_REG+152,this.RTC_CNTL_WDTWPROTECT_REG=this.RTCCNTL_BASE_REG+172,this.RTC_CNTL_WDT_WKEY=1356348065,this.MEMORY_MAP=[[0,65536,"PADDING"],[1056964608,1073217536,"DROM"],[1062207488,1073217536,"EXTRAM_DATA"],[1073340416,1073348608,"RTC_DRAM"],[1073340416,1073741824,"BYTE_ACCESSIBLE"],[1073340416,1074208768,"MEM_INTERNAL"],[1073414144,1073741824,"DRAM"],[1073741824,1073848576,"IROM_MASK"],[1073872896,1074200576,"IRAM"],[1074200576,1074208768,"RTC_IRAM"],[1074266112,1082130432,"IROM"],[1342177280,1342185472,"RTC_DATA"]],this.EFUSE_VDD_SPI_REG=this.EFUSE_BASE+52,this.VDD_SPI_XPD=16,this.VDD_SPI_TIEH=32,this.VDD_SPI_FORCE=64,this.UF2_FAMILY_ID=3218951918,this.EFUSE_MAX_KEY=5,this.KEY_PURPOSES={0:"USER/EMPTY",1:"RESERVED",2:"XTS_AES_256_KEY_1",3:"XTS_AES_256_KEY_2",4:"XTS_AES_128_KEY",5:"HMAC_DOWN_ALL",6:"HMAC_DOWN_JTAG",7:"HMAC_DOWN_DIGITAL_SIGNATURE",8:"HMAC_UP",9:"SECURE_BOOT_DIGEST0",10:"SECURE_BOOT_DIGEST1",11:"SECURE_BOOT_DIGEST2"},this.UART_CLKDIV_MASK=1048575,this.UART_DATE_REG_ADDR=1610612856,this.FLASH_WRITE_SIZE=1024,this.BOOTLOADER_FLASH_OFFSET=4096}async getPkgVersion(A){const t=this.EFUSE_BLOCK1_ADDR+16;return 15&await A.readReg(t)}async getMinorChipVersion(A){return((await A.readReg(this.EFUSE_BLOCK1_ADDR+12)>>20&1)<<3)+(await A.readReg(this.EFUSE_BLOCK1_ADDR+16)>>4&7)}async getMajorChipVersion(A){return await A.readReg(this.EFUSE_BLOCK1_ADDR+12)>>18&3}async getFlashVersion(A){return await A.readReg(this.EFUSE_BLOCK1_ADDR+12)>>21&15}async getChipDescription(A){const t=await this.getFlashCap(A)+100*await this.getPsramCap(A),e=await this.getMajorChipVersion(A),i=await this.getMinorChipVersion(A);return`${{0:"ESP32-S2",1:"ESP32-S2FH2",2:"ESP32-S2FH4",102:"ESP32-S2FNR2",100:"ESP32-S2R2"}[t]||"unknown ESP32-S2"} (revision v${e}.${i})`}async getFlashCap(A){return await this.getFlashVersion(A)}async getPsramVersion(A){const t=this.EFUSE_BLOCK1_ADDR+12;return await A.readReg(t)>>28&15}async getPsramCap(A){return await this.getPsramVersion(A)}async getBlock2Version(A){const t=this.EFUSE_BLOCK2_ADDR+16;return await A.readReg(t)>>4&7}async getChipFeatures(A){const t=["Wi-Fi"],e={0:"No Embedded Flash",1:"Embedded Flash 2MB",2:"Embedded Flash 4MB"}[await this.getFlashCap(A)]||"Unknown Embedded Flash";t.push(e);const i={0:"No Embedded Flash",1:"Embedded PSRAM 2MB",2:"Embedded PSRAM 4MB"}[await this.getPsramCap(A)]||"Unknown Embedded PSRAM";t.push(i);const s={0:"No calibration in BLK2 of efuse",1:"ADC and temperature sensor calibration in BLK2 of efuse V1",2:"ADC and temperature sensor calibration in BLK2 of efuse V2"}[await this.getBlock2Version(A)]||"Unknown Calibration in BLK2";return t.push(s),t}async getCrystalFreq(A){return 40}_d2h(A){const t=(+A).toString(16);return 1===t.length?"0"+t:t}async readMac(A){let t=await A.readReg(this.MAC_EFUSE_REG);t>>>=0;let e=await A.readReg(this.MAC_EFUSE_REG+4);e=e>>>0&65535;const i=new Uint8Array(6);return i[0]=e>>8&255,i[1]=255&e,i[2]=t>>24&255,i[3]=t>>16&255,i[4]=t>>8&255,i[5]=255&t,this._d2h(i[0])+":"+this._d2h(i[1])+":"+this._d2h(i[2])+":"+this._d2h(i[3])+":"+this._d2h(i[4])+":"+this._d2h(i[5])}getEraseSize(A,t){return t}async usingUsbOtg(A){return(255&await A.readReg(this.UARTDEV_BUF_NO))===this.UARTDEV_BUF_NO_USB_OTG}async postConnect(A){const t=await this.usingUsbOtg(A);A.debug("In _post_connect using USB OTG ?"+t),t&&(A.ESP_RAM_BLOCK=this.USB_RAM_BLOCK)}}});var ta=Object.freeze({__proto__:null,ESP32P4ROM:class extends Ns{constructor(){super(...arguments),this.CHIP_NAME="ESP32-P4",this.IMAGE_CHIP_ID=18,this.IROM_MAP_START=1073741824,this.IROM_MAP_END=1275068416,this.DROM_MAP_START=1073741824,this.DROM_MAP_END=1275068416,this.BOOTLOADER_FLASH_OFFSET=8192,this.CHIP_DETECT_MAGIC_VALUE=[0,182303440],this.UART_DATE_REG_ADDR=1343004812,this.EFUSE_BASE=1343410176,this.EFUSE_BLOCK1_ADDR=this.EFUSE_BASE+68,this.MAC_EFUSE_REG=this.EFUSE_BASE+68,this.SPI_REG_BASE=1342754816,this.SPI_USR_OFFS=24,this.SPI_USR1_OFFS=28,this.SPI_USR2_OFFS=32,this.SPI_MOSI_DLEN_OFFS=36,this.SPI_MISO_DLEN_OFFS=40,this.SPI_W0_OFFS=88,this.SPI_ADDR_REG_MSB=!1,this.USES_MAGIC_VALUE=!1,this.EFUSE_RD_REG_BASE=this.EFUSE_BASE+48,this.EFUSE_FORCE_USE_KEY_MANAGER_KEY_REG=this.EFUSE_BASE+52,this.EFUSE_FORCE_USE_KEY_MANAGER_KEY_SHIFT=9,this.FORCE_USE_KEY_MANAGER_VAL_XTS_AES_KEY=2,this.EFUSE_PURPOSE_KEY0_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY0_SHIFT=24,this.EFUSE_PURPOSE_KEY1_REG=this.EFUSE_BASE+52,this.EFUSE_PURPOSE_KEY1_SHIFT=28,this.EFUSE_PURPOSE_KEY2_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY2_SHIFT=0,this.EFUSE_PURPOSE_KEY3_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY3_SHIFT=4,this.EFUSE_PURPOSE_KEY4_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY4_SHIFT=8,this.EFUSE_PURPOSE_KEY5_REG=this.EFUSE_BASE+56,this.EFUSE_PURPOSE_KEY5_SHIFT=12,this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT_REG=this.EFUSE_RD_REG_BASE,this.EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT=1<<20,this.EFUSE_SPI_BOOT_CRYPT_CNT_REG=this.EFUSE_BASE+52,this.EFUSE_SPI_BOOT_CRYPT_CNT_MASK=7<<18,this.EFUSE_SECURE_BOOT_EN_REG=this.EFUSE_BASE+56,this.EFUSE_SECURE_BOOT_EN_MASK=1<<20,this.PURPOSE_VAL_XTS_AES256_KEY_1=2,this.PURPOSE_VAL_XTS_AES256_KEY_2=3,this.PURPOSE_VAL_XTS_AES128_KEY=4,this.SUPPORTS_ENCRYPTED_FLASH=!0,this.FLASH_ENCRYPTED_WRITE_ALIGN=16,this.USB_RAM_BLOCK=2048,this.GPIO_STRAP_REG=1343094840,this.GPIO_STRAP_SPI_BOOT_MASK=8,this.RTC_CNTL_OPTION1_REG=1343291400,this.RTC_CNTL_FORCE_DOWNLOAD_BOOT_MASK=4,this.DR_REG_LPAON_BASE=1343291392,this.DR_REG_PMU_BASE=this.DR_REG_LPAON_BASE+20480,this.DR_REG_LP_SYS_BASE=this.DR_REG_LPAON_BASE+0,this.LP_SYSTEM_REG_ANA_XPD_PAD_GROUP_REG=this.DR_REG_LP_SYS_BASE+268,this.PMU_EXT_LDO_P0_0P1A_ANA_REG=this.DR_REG_PMU_BASE+444,this.PMU_ANA_0P1A_EN_CUR_LIM_0=1<<27,this.PMU_EXT_LDO_P0_0P1A_REG=this.DR_REG_PMU_BASE+440,this.PMU_0P1A_TARGET0_0=255<<23,this.PMU_0P1A_FORCE_TIEH_SEL_0=128,this.PMU_DATE_REG=this.DR_REG_PMU_BASE+1020,this.UARTDEV_BUF_NO_USB_OTG=5,this.UARTDEV_BUF_NO_USB_JTAG_SERIAL=6,this.DR_REG_LP_WDT_BASE=1343315968,this.RTC_CNTL_WDTCONFIG0_REG=this.DR_REG_LP_WDT_BASE+0,this.RTC_CNTL_WDTCONFIG1_REG=this.DR_REG_LP_WDT_BASE+4,this.RTC_CNTL_WDTWPROTECT_REG=this.DR_REG_LP_WDT_BASE+24,this.RTC_CNTL_WDT_WKEY=1356348065,this.RTC_CNTL_SWD_CONF_REG=this.DR_REG_LP_WDT_BASE+28,this.RTC_CNTL_SWD_AUTO_FEED_EN=1<<18,this.RTC_CNTL_SWD_WPROTECT_REG=this.DR_REG_LP_WDT_BASE+32,this.RTC_CNTL_SWD_WKEY=1356348065,this.MEMORY_MAP=[[0,65536,"PADDING"],[1073741824,1275068416,"DROM"],[1341128704,1341784064,"DRAM"],[1341128704,1341784064,"BYTE_ACCESSIBLE"],[1337982976,1338114048,"DROM_MASK"],[1337982976,1338114048,"IROM_MASK"],[1073741824,1275068416,"IROM"],[1341128704,1341784064,"IRAM"],[1343258624,1343291392,"RTC_IRAM"],[1343258624,1343291392,"RTC_DRAM"],[1611653120,1611661312,"MEM_INTERNAL2"]],this.UF2_FAMILY_ID=1026592404,this.EFUSE_MAX_KEY=5,this.KEY_PURPOSES={0:"USER/EMPTY",1:"ECDSA_KEY",2:"XTS_AES_256_KEY_1",3:"XTS_AES_256_KEY_2",4:"XTS_AES_128_KEY",5:"HMAC_DOWN_ALL",6:"HMAC_DOWN_JTAG",7:"HMAC_DOWN_DIGITAL_SIGNATURE",8:"HMAC_UP",9:"SECURE_BOOT_DIGEST0",10:"SECURE_BOOT_DIGEST1",11:"SECURE_BOOT_DIGEST2",12:"KM_INIT_KEY"}}async getPkgVersion(A){const t=this.EFUSE_BLOCK1_ADDR+8;return await A.readReg(t)>>20&7}async getMinorChipVersion(A){const t=this.EFUSE_BLOCK1_ADDR+8;return 15&await A.readReg(t)}async getMajorChipVersion(A){const t=this.EFUSE_BLOCK1_ADDR+8,e=await A.readReg(t);return(e>>23&1)<<2|e>>4&3}async getChipRevision(A){return 100*await this.getMajorChipVersion(A)+await this.getMinorChipVersion(A)}async getStubJsonPath(A){return await this.getChipRevision(A)<300?"./targets/stub_flasher/stub_flasher_32p4rc1.json":"./targets/stub_flasher/stub_flasher_32p4.json"}async getChipDescription(A){return`${{0:"ESP32-P4"}[await this.getPkgVersion(A)]||"Unknown ESP32-P4"} (revision v${await this.getMajorChipVersion(A)}.${await this.getMinorChipVersion(A)})`}async getChipFeatures(A){return["High-Performance MCU"]}async getCrystalFreq(A){return 40}async getFlashVoltage(A){}async overrideVddsdio(A){A.debug("VDD_SDIO overrides are not supported for ESP32-P4")}async readMac(A){let t=await A.readReg(this.MAC_EFUSE_REG);t>>>=0;let e=await A.readReg(this.MAC_EFUSE_REG+4);e=e>>>0&65535;const i=new Uint8Array(6);return i[0]=e>>8&255,i[1]=255&e,i[2]=t>>24&255,i[3]=t>>16&255,i[4]=t>>8&255,i[5]=255&t,this._d2h(i[0])+":"+this._d2h(i[1])+":"+this._d2h(i[2])+":"+this._d2h(i[3])+":"+this._d2h(i[4])+":"+this._d2h(i[5])}async getFlashCryptConfig(A){}async getSecureBootEnabled(A){return!!(await A.readReg(this.EFUSE_SECURE_BOOT_EN_REG)&this.EFUSE_SECURE_BOOT_EN_MASK)}async getUartdevBufNo(A){return(await this.getChipRevision(A)<300?1341390512:1341914800)+24}async usesUsbOtg(A){const t=await this.getUartdevBufNo(A);return(255&await A.readReg(t))===this.UARTDEV_BUF_NO_USB_OTG}async usesUsbJtagSerial(A){const t=await this.getUartdevBufNo(A);return(255&await A.readReg(t))===this.UARTDEV_BUF_NO_USB_JTAG_SERIAL}async getKeyBlockPurpose(A,t){if(t<0||t>this.EFUSE_MAX_KEY)return void A.debug(`Valid key block numbers must be in range 0-${this.EFUSE_MAX_KEY}`);const e=[[this.EFUSE_PURPOSE_KEY0_REG,this.EFUSE_PURPOSE_KEY0_SHIFT],[this.EFUSE_PURPOSE_KEY1_REG,this.EFUSE_PURPOSE_KEY1_SHIFT],[this.EFUSE_PURPOSE_KEY2_REG,this.EFUSE_PURPOSE_KEY2_SHIFT],[this.EFUSE_PURPOSE_KEY3_REG,this.EFUSE_PURPOSE_KEY3_SHIFT],[this.EFUSE_PURPOSE_KEY4_REG,this.EFUSE_PURPOSE_KEY4_SHIFT],[this.EFUSE_PURPOSE_KEY5_REG,this.EFUSE_PURPOSE_KEY5_SHIFT]],[i,s]=e[t];return await A.readReg(i)>>s&15}async isFlashEncryptionKeyValid(A){const t=[];for(let e=0;e<=this.EFUSE_MAX_KEY;e++){const i=await this.getKeyBlockPurpose(A,e);t.push(i)}if(t.some((A=>A===this.PURPOSE_VAL_XTS_AES128_KEY)))return!0;if(t.some((A=>A===this.PURPOSE_VAL_XTS_AES256_KEY_1))&&t.some((A=>A===this.PURPOSE_VAL_XTS_AES256_KEY_2)))return!0;return!!(await A.readReg(this.EFUSE_FORCE_USE_KEY_MANAGER_KEY_REG)>>this.EFUSE_FORCE_USE_KEY_MANAGER_KEY_SHIFT&this.FORCE_USE_KEY_MANAGER_VAL_XTS_AES_KEY)}async postConnect(A){await this.usesUsbOtg(A)&&(A.ESP_RAM_BLOCK=this.USB_RAM_BLOCK),A.IS_STUB||await this.disableWatchdogs(A)}async disableWatchdogs(A){if(await this.usesUsbJtagSerial(A)){await A.writeReg(this.RTC_CNTL_WDTWPROTECT_REG,this.RTC_CNTL_WDT_WKEY),await A.writeReg(this.RTC_CNTL_WDTCONFIG0_REG,0),await A.writeReg(this.RTC_CNTL_WDTWPROTECT_REG,0),await A.writeReg(this.RTC_CNTL_SWD_WPROTECT_REG,this.RTC_CNTL_SWD_WKEY);const t=await A.readReg(this.RTC_CNTL_SWD_CONF_REG);await A.writeReg(this.RTC_CNTL_SWD_CONF_REG,t|this.RTC_CNTL_SWD_AUTO_FEED_EN),await A.writeReg(this.RTC_CNTL_SWD_WPROTECT_REG,0)}}checkSpiConnection(A,t){if(!t.every((A=>A>=0&&A<=54)))throw new Error("SPI Pin numbers must be in the range 0-54.");t.some((A=>24===A||25===A))&&A.debug("GPIO pins 24 and 25 are used by USB-Serial/JTAG, consider using other pins for SPI flash connection.")}async watchdogReset(A){A.info("Hard resetting with a watchdog..."),await A.writeReg(this.RTC_CNTL_WDTWPROTECT_REG,this.RTC_CNTL_WDT_WKEY),await A.writeReg(this.RTC_CNTL_WDTCONFIG1_REG,2e3),await A.writeReg(this.RTC_CNTL_WDTCONFIG0_REG,-805306110),await A.writeReg(this.RTC_CNTL_WDTWPROTECT_REG,0),await new Promise((A=>setTimeout(A,500)))}async powerOnFlash(A){if(await this.getChipRevision(A)<=300)return;await A.writeReg(this.LP_SYSTEM_REG_ANA_XPD_PAD_GROUP_REG,1),await new Promise((A=>setTimeout(A,10)));let t=await A.readReg(this.PMU_EXT_LDO_P0_0P1A_ANA_REG);await A.writeReg(this.PMU_EXT_LDO_P0_0P1A_ANA_REG,t|this.PMU_ANA_0P1A_EN_CUR_LIM_0),t=await A.readReg(this.PMU_EXT_LDO_P0_0P1A_REG),await A.writeReg(this.PMU_EXT_LDO_P0_0P1A_REG,t|this.PMU_0P1A_FORCE_TIEH_SEL_0),t=await A.readReg(this.PMU_DATE_REG),await A.writeReg(this.PMU_DATE_REG,3|t),await new Promise((A=>setTimeout(A,50))),t=await A.readReg(this.PMU_EXT_LDO_P0_0P1A_ANA_REG),await A.writeReg(this.PMU_EXT_LDO_P0_0P1A_ANA_REG,t&~this.PMU_ANA_0P1A_EN_CUR_LIM_0),t=await A.readReg(this.PMU_EXT_LDO_P0_0P1A_REG),await A.writeReg(this.PMU_EXT_LDO_P0_0P1A_REG,t&~this.PMU_0P1A_TARGET0_0),t=await A.readReg(this.PMU_EXT_LDO_P0_0P1A_REG),await A.writeReg(this.PMU_EXT_LDO_P0_0P1A_REG,128|t),t=await A.readReg(this.PMU_EXT_LDO_P0_0P1A_REG),await A.writeReg(this.PMU_EXT_LDO_P0_0P1A_REG,t&~this.PMU_0P1A_FORCE_TIEH_SEL_0),await new Promise((A=>setTimeout(A,1800)))}}});export{Fe as ClassicReset,Pe as CustomReset,Ai as ESPLoader,Te as HardReset,pe as ROM,Me as Transport,fe as UsbJtagSerialReset,ue as decodeBase64Data,Oe as getStubJsonByChipName,Ue as validateCustomResetStringSequence}; diff --git a/flasher/vendor/jszip-3.10.1.min.js b/flasher/vendor/jszip-3.10.1.min.js new file mode 100644 index 000000000..ff4cfd5e8 --- /dev/null +++ b/flasher/vendor/jszip-3.10.1.min.js @@ -0,0 +1,13 @@ +/*! + +JSZip v3.10.1 - A JavaScript class for generating and reading zip files + + +(c) 2009-2016 Stuart Knightley +Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/main/LICENSE.markdown. + +JSZip uses the library pako released under the MIT license : +https://github.com/nodeca/pako/blob/main/LICENSE +*/ + +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).JSZip=e()}}(function(){return function s(a,o,h){function u(r,e){if(!o[r]){if(!a[r]){var t="function"==typeof require&&require;if(!e&&t)return t(r,!0);if(l)return l(r,!0);var n=new Error("Cannot find module '"+r+"'");throw n.code="MODULE_NOT_FOUND",n}var i=o[r]={exports:{}};a[r][0].call(i.exports,function(e){var t=a[r][1][e];return u(t||e)},i,i.exports,s,a,o,h)}return o[r].exports}for(var l="function"==typeof require&&require,e=0;e>2,s=(3&t)<<4|r>>4,a=1>6:64,o=2>4,r=(15&i)<<4|(s=p.indexOf(e.charAt(o++)))>>2,n=(3&s)<<6|(a=p.indexOf(e.charAt(o++))),l[h++]=t,64!==s&&(l[h++]=r),64!==a&&(l[h++]=n);return l}},{"./support":30,"./utils":32}],2:[function(e,t,r){"use strict";var n=e("./external"),i=e("./stream/DataWorker"),s=e("./stream/Crc32Probe"),a=e("./stream/DataLengthProbe");function o(e,t,r,n,i){this.compressedSize=e,this.uncompressedSize=t,this.crc32=r,this.compression=n,this.compressedContent=i}o.prototype={getContentWorker:function(){var e=new i(n.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new a("data_length")),t=this;return e.on("end",function(){if(this.streamInfo.data_length!==t.uncompressedSize)throw new Error("Bug : uncompressed data size mismatch")}),e},getCompressedWorker:function(){return new i(n.Promise.resolve(this.compressedContent)).withStreamInfo("compressedSize",this.compressedSize).withStreamInfo("uncompressedSize",this.uncompressedSize).withStreamInfo("crc32",this.crc32).withStreamInfo("compression",this.compression)}},o.createWorkerFrom=function(e,t,r){return e.pipe(new s).pipe(new a("uncompressedSize")).pipe(t.compressWorker(r)).pipe(new a("compressedSize")).withStreamInfo("compression",t)},t.exports=o},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(e,t,r){"use strict";var n=e("./stream/GenericWorker");r.STORE={magic:"\0\0",compressWorker:function(){return new n("STORE compression")},uncompressWorker:function(){return new n("STORE decompression")}},r.DEFLATE=e("./flate")},{"./flate":7,"./stream/GenericWorker":28}],4:[function(e,t,r){"use strict";var n=e("./utils");var o=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e}return t}();t.exports=function(e,t){return void 0!==e&&e.length?"string"!==n.getTypeOf(e)?function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t[a])];return-1^e}(0|t,e,e.length,0):function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t.charCodeAt(a))];return-1^e}(0|t,e,e.length,0):0}},{"./utils":32}],5:[function(e,t,r){"use strict";r.base64=!1,r.binary=!1,r.dir=!1,r.createFolders=!0,r.date=null,r.compression=null,r.compressionOptions=null,r.comment=null,r.unixPermissions=null,r.dosPermissions=null},{}],6:[function(e,t,r){"use strict";var n=null;n="undefined"!=typeof Promise?Promise:e("lie"),t.exports={Promise:n}},{lie:37}],7:[function(e,t,r){"use strict";var n="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,i=e("pako"),s=e("./utils"),a=e("./stream/GenericWorker"),o=n?"uint8array":"array";function h(e,t){a.call(this,"FlateWorker/"+e),this._pako=null,this._pakoAction=e,this._pakoOptions=t,this.meta={}}r.magic="\b\0",s.inherits(h,a),h.prototype.processChunk=function(e){this.meta=e.meta,null===this._pako&&this._createPako(),this._pako.push(s.transformTo(o,e.data),!1)},h.prototype.flush=function(){a.prototype.flush.call(this),null===this._pako&&this._createPako(),this._pako.push([],!0)},h.prototype.cleanUp=function(){a.prototype.cleanUp.call(this),this._pako=null},h.prototype._createPako=function(){this._pako=new i[this._pakoAction]({raw:!0,level:this._pakoOptions.level||-1});var t=this;this._pako.onData=function(e){t.push({data:e,meta:t.meta})}},r.compressWorker=function(e){return new h("Deflate",e)},r.uncompressWorker=function(){return new h("Inflate",{})}},{"./stream/GenericWorker":28,"./utils":32,pako:38}],8:[function(e,t,r){"use strict";function A(e,t){var r,n="";for(r=0;r>>=8;return n}function n(e,t,r,n,i,s){var a,o,h=e.file,u=e.compression,l=s!==O.utf8encode,f=I.transformTo("string",s(h.name)),c=I.transformTo("string",O.utf8encode(h.name)),d=h.comment,p=I.transformTo("string",s(d)),m=I.transformTo("string",O.utf8encode(d)),_=c.length!==h.name.length,g=m.length!==d.length,b="",v="",y="",w=h.dir,k=h.date,x={crc32:0,compressedSize:0,uncompressedSize:0};t&&!r||(x.crc32=e.crc32,x.compressedSize=e.compressedSize,x.uncompressedSize=e.uncompressedSize);var S=0;t&&(S|=8),l||!_&&!g||(S|=2048);var z=0,C=0;w&&(z|=16),"UNIX"===i?(C=798,z|=function(e,t){var r=e;return e||(r=t?16893:33204),(65535&r)<<16}(h.unixPermissions,w)):(C=20,z|=function(e){return 63&(e||0)}(h.dosPermissions)),a=k.getUTCHours(),a<<=6,a|=k.getUTCMinutes(),a<<=5,a|=k.getUTCSeconds()/2,o=k.getUTCFullYear()-1980,o<<=4,o|=k.getUTCMonth()+1,o<<=5,o|=k.getUTCDate(),_&&(v=A(1,1)+A(B(f),4)+c,b+="up"+A(v.length,2)+v),g&&(y=A(1,1)+A(B(p),4)+m,b+="uc"+A(y.length,2)+y);var E="";return E+="\n\0",E+=A(S,2),E+=u.magic,E+=A(a,2),E+=A(o,2),E+=A(x.crc32,4),E+=A(x.compressedSize,4),E+=A(x.uncompressedSize,4),E+=A(f.length,2),E+=A(b.length,2),{fileRecord:R.LOCAL_FILE_HEADER+E+f+b,dirRecord:R.CENTRAL_FILE_HEADER+A(C,2)+E+A(p.length,2)+"\0\0\0\0"+A(z,4)+A(n,4)+f+b+p}}var I=e("../utils"),i=e("../stream/GenericWorker"),O=e("../utf8"),B=e("../crc32"),R=e("../signature");function s(e,t,r,n){i.call(this,"ZipFileWorker"),this.bytesWritten=0,this.zipComment=t,this.zipPlatform=r,this.encodeFileName=n,this.streamFiles=e,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[]}I.inherits(s,i),s.prototype.push=function(e){var t=e.meta.percent||0,r=this.entriesCount,n=this._sources.length;this.accumulate?this.contentBuffer.push(e):(this.bytesWritten+=e.data.length,i.prototype.push.call(this,{data:e.data,meta:{currentFile:this.currentFile,percent:r?(t+100*(r-n-1))/r:100}}))},s.prototype.openedSource=function(e){this.currentSourceOffset=this.bytesWritten,this.currentFile=e.file.name;var t=this.streamFiles&&!e.file.dir;if(t){var r=n(e,t,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:r.fileRecord,meta:{percent:0}})}else this.accumulate=!0},s.prototype.closedSource=function(e){this.accumulate=!1;var t=this.streamFiles&&!e.file.dir,r=n(e,t,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(r.dirRecord),t)this.push({data:function(e){return R.DATA_DESCRIPTOR+A(e.crc32,4)+A(e.compressedSize,4)+A(e.uncompressedSize,4)}(e),meta:{percent:100}});else for(this.push({data:r.fileRecord,meta:{percent:0}});this.contentBuffer.length;)this.push(this.contentBuffer.shift());this.currentFile=null},s.prototype.flush=function(){for(var e=this.bytesWritten,t=0;t=this.index;t--)r=(r<<8)+this.byteAt(t);return this.index+=e,r},readString:function(e){return n.transformTo("string",this.readData(e))},readData:function(){},lastIndexOfSignature:function(){},readAndCheckSignature:function(){},readDate:function(){var e=this.readInt(4);return new Date(Date.UTC(1980+(e>>25&127),(e>>21&15)-1,e>>16&31,e>>11&31,e>>5&63,(31&e)<<1))}},t.exports=i},{"../utils":32}],19:[function(e,t,r){"use strict";var n=e("./Uint8ArrayReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(e,t,r){"use strict";var n=e("./DataReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.byteAt=function(e){return this.data.charCodeAt(this.zero+e)},i.prototype.lastIndexOfSignature=function(e){return this.data.lastIndexOf(e)-this.zero},i.prototype.readAndCheckSignature=function(e){return e===this.readData(4)},i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./DataReader":18}],21:[function(e,t,r){"use strict";var n=e("./ArrayReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.readData=function(e){if(this.checkOffset(e),0===e)return new Uint8Array(0);var t=this.data.subarray(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./ArrayReader":17}],22:[function(e,t,r){"use strict";var n=e("../utils"),i=e("../support"),s=e("./ArrayReader"),a=e("./StringReader"),o=e("./NodeBufferReader"),h=e("./Uint8ArrayReader");t.exports=function(e){var t=n.getTypeOf(e);return n.checkSupport(t),"string"!==t||i.uint8array?"nodebuffer"===t?new o(e):i.uint8array?new h(n.transformTo("uint8array",e)):new s(n.transformTo("array",e)):new a(e)}},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(e,t,r){"use strict";r.LOCAL_FILE_HEADER="PK",r.CENTRAL_FILE_HEADER="PK",r.CENTRAL_DIRECTORY_END="PK",r.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",r.ZIP64_CENTRAL_DIRECTORY_END="PK",r.DATA_DESCRIPTOR="PK\b"},{}],24:[function(e,t,r){"use strict";var n=e("./GenericWorker"),i=e("../utils");function s(e){n.call(this,"ConvertWorker to "+e),this.destType=e}i.inherits(s,n),s.prototype.processChunk=function(e){this.push({data:i.transformTo(this.destType,e.data),meta:e.meta})},t.exports=s},{"../utils":32,"./GenericWorker":28}],25:[function(e,t,r){"use strict";var n=e("./GenericWorker"),i=e("../crc32");function s(){n.call(this,"Crc32Probe"),this.withStreamInfo("crc32",0)}e("../utils").inherits(s,n),s.prototype.processChunk=function(e){this.streamInfo.crc32=i(e.data,this.streamInfo.crc32||0),this.push(e)},t.exports=s},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(e,t,r){"use strict";var n=e("../utils"),i=e("./GenericWorker");function s(e){i.call(this,"DataLengthProbe for "+e),this.propName=e,this.withStreamInfo(e,0)}n.inherits(s,i),s.prototype.processChunk=function(e){if(e){var t=this.streamInfo[this.propName]||0;this.streamInfo[this.propName]=t+e.data.length}i.prototype.processChunk.call(this,e)},t.exports=s},{"../utils":32,"./GenericWorker":28}],27:[function(e,t,r){"use strict";var n=e("../utils"),i=e("./GenericWorker");function s(e){i.call(this,"DataWorker");var t=this;this.dataIsReady=!1,this.index=0,this.max=0,this.data=null,this.type="",this._tickScheduled=!1,e.then(function(e){t.dataIsReady=!0,t.data=e,t.max=e&&e.length||0,t.type=n.getTypeOf(e),t.isPaused||t._tickAndRepeat()},function(e){t.error(e)})}n.inherits(s,i),s.prototype.cleanUp=function(){i.prototype.cleanUp.call(this),this.data=null},s.prototype.resume=function(){return!!i.prototype.resume.call(this)&&(!this._tickScheduled&&this.dataIsReady&&(this._tickScheduled=!0,n.delay(this._tickAndRepeat,[],this)),!0)},s.prototype._tickAndRepeat=function(){this._tickScheduled=!1,this.isPaused||this.isFinished||(this._tick(),this.isFinished||(n.delay(this._tickAndRepeat,[],this),this._tickScheduled=!0))},s.prototype._tick=function(){if(this.isPaused||this.isFinished)return!1;var e=null,t=Math.min(this.max,this.index+16384);if(this.index>=this.max)return this.end();switch(this.type){case"string":e=this.data.substring(this.index,t);break;case"uint8array":e=this.data.subarray(this.index,t);break;case"array":case"nodebuffer":e=this.data.slice(this.index,t)}return this.index=t,this.push({data:e,meta:{percent:this.max?this.index/this.max*100:0}})},t.exports=s},{"../utils":32,"./GenericWorker":28}],28:[function(e,t,r){"use strict";function n(e){this.name=e||"default",this.streamInfo={},this.generatedError=null,this.extraStreamInfo={},this.isPaused=!0,this.isFinished=!1,this.isLocked=!1,this._listeners={data:[],end:[],error:[]},this.previous=null}n.prototype={push:function(e){this.emit("data",e)},end:function(){if(this.isFinished)return!1;this.flush();try{this.emit("end"),this.cleanUp(),this.isFinished=!0}catch(e){this.emit("error",e)}return!0},error:function(e){return!this.isFinished&&(this.isPaused?this.generatedError=e:(this.isFinished=!0,this.emit("error",e),this.previous&&this.previous.error(e),this.cleanUp()),!0)},on:function(e,t){return this._listeners[e].push(t),this},cleanUp:function(){this.streamInfo=this.generatedError=this.extraStreamInfo=null,this._listeners=[]},emit:function(e,t){if(this._listeners[e])for(var r=0;r "+e:e}},t.exports=n},{}],29:[function(e,t,r){"use strict";var h=e("../utils"),i=e("./ConvertWorker"),s=e("./GenericWorker"),u=e("../base64"),n=e("../support"),a=e("../external"),o=null;if(n.nodestream)try{o=e("../nodejs/NodejsStreamOutputAdapter")}catch(e){}function l(e,o){return new a.Promise(function(t,r){var n=[],i=e._internalType,s=e._outputType,a=e._mimeType;e.on("data",function(e,t){n.push(e),o&&o(t)}).on("error",function(e){n=[],r(e)}).on("end",function(){try{var e=function(e,t,r){switch(e){case"blob":return h.newBlob(h.transformTo("arraybuffer",t),r);case"base64":return u.encode(t);default:return h.transformTo(e,t)}}(s,function(e,t){var r,n=0,i=null,s=0;for(r=0;r>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t}(e)},s.utf8decode=function(e){return h.nodebuffer?o.transformTo("nodebuffer",e).toString("utf-8"):function(e){var t,r,n,i,s=e.length,a=new Array(2*s);for(t=r=0;t>10&1023,a[r++]=56320|1023&n)}return a.length!==r&&(a.subarray?a=a.subarray(0,r):a.length=r),o.applyFromCharCode(a)}(e=o.transformTo(h.uint8array?"uint8array":"array",e))},o.inherits(a,n),a.prototype.processChunk=function(e){var t=o.transformTo(h.uint8array?"uint8array":"array",e.data);if(this.leftOver&&this.leftOver.length){if(h.uint8array){var r=t;(t=new Uint8Array(r.length+this.leftOver.length)).set(this.leftOver,0),t.set(r,this.leftOver.length)}else t=this.leftOver.concat(t);this.leftOver=null}var n=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+u[e[r]]>t?r:t}(t),i=t;n!==t.length&&(h.uint8array?(i=t.subarray(0,n),this.leftOver=t.subarray(n,t.length)):(i=t.slice(0,n),this.leftOver=t.slice(n,t.length))),this.push({data:s.utf8decode(i),meta:e.meta})},a.prototype.flush=function(){this.leftOver&&this.leftOver.length&&(this.push({data:s.utf8decode(this.leftOver),meta:{}}),this.leftOver=null)},s.Utf8DecodeWorker=a,o.inherits(l,n),l.prototype.processChunk=function(e){this.push({data:s.utf8encode(e.data),meta:e.meta})},s.Utf8EncodeWorker=l},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(e,t,a){"use strict";var o=e("./support"),h=e("./base64"),r=e("./nodejsUtils"),u=e("./external");function n(e){return e}function l(e,t){for(var r=0;r>8;this.dir=!!(16&this.externalFileAttributes),0==e&&(this.dosPermissions=63&this.externalFileAttributes),3==e&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||"/"!==this.fileNameStr.slice(-1)||(this.dir=!0)},parseZIP64ExtraField:function(){if(this.extraFields[1]){var e=n(this.extraFields[1].value);this.uncompressedSize===s.MAX_VALUE_32BITS&&(this.uncompressedSize=e.readInt(8)),this.compressedSize===s.MAX_VALUE_32BITS&&(this.compressedSize=e.readInt(8)),this.localHeaderOffset===s.MAX_VALUE_32BITS&&(this.localHeaderOffset=e.readInt(8)),this.diskNumberStart===s.MAX_VALUE_32BITS&&(this.diskNumberStart=e.readInt(4))}},readExtraFields:function(e){var t,r,n,i=e.index+this.extraFieldsLength;for(this.extraFields||(this.extraFields={});e.index+4>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t},r.buf2binstring=function(e){return l(e,e.length)},r.binstring2buf=function(e){for(var t=new h.Buf8(e.length),r=0,n=t.length;r>10&1023,o[n++]=56320|1023&i)}return l(o,n)},r.utf8border=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+u[e[r]]>t?r:t}},{"./common":41}],43:[function(e,t,r){"use strict";t.exports=function(e,t,r,n){for(var i=65535&e|0,s=e>>>16&65535|0,a=0;0!==r;){for(r-=a=2e3>>1:e>>>1;t[r]=e}return t}();t.exports=function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t[a])];return-1^e}},{}],46:[function(e,t,r){"use strict";var h,c=e("../utils/common"),u=e("./trees"),d=e("./adler32"),p=e("./crc32"),n=e("./messages"),l=0,f=4,m=0,_=-2,g=-1,b=4,i=2,v=8,y=9,s=286,a=30,o=19,w=2*s+1,k=15,x=3,S=258,z=S+x+1,C=42,E=113,A=1,I=2,O=3,B=4;function R(e,t){return e.msg=n[t],t}function T(e){return(e<<1)-(4e.avail_out&&(r=e.avail_out),0!==r&&(c.arraySet(e.output,t.pending_buf,t.pending_out,r,e.next_out),e.next_out+=r,t.pending_out+=r,e.total_out+=r,e.avail_out-=r,t.pending-=r,0===t.pending&&(t.pending_out=0))}function N(e,t){u._tr_flush_block(e,0<=e.block_start?e.block_start:-1,e.strstart-e.block_start,t),e.block_start=e.strstart,F(e.strm)}function U(e,t){e.pending_buf[e.pending++]=t}function P(e,t){e.pending_buf[e.pending++]=t>>>8&255,e.pending_buf[e.pending++]=255&t}function L(e,t){var r,n,i=e.max_chain_length,s=e.strstart,a=e.prev_length,o=e.nice_match,h=e.strstart>e.w_size-z?e.strstart-(e.w_size-z):0,u=e.window,l=e.w_mask,f=e.prev,c=e.strstart+S,d=u[s+a-1],p=u[s+a];e.prev_length>=e.good_match&&(i>>=2),o>e.lookahead&&(o=e.lookahead);do{if(u[(r=t)+a]===p&&u[r+a-1]===d&&u[r]===u[s]&&u[++r]===u[s+1]){s+=2,r++;do{}while(u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&sh&&0!=--i);return a<=e.lookahead?a:e.lookahead}function j(e){var t,r,n,i,s,a,o,h,u,l,f=e.w_size;do{if(i=e.window_size-e.lookahead-e.strstart,e.strstart>=f+(f-z)){for(c.arraySet(e.window,e.window,f,f,0),e.match_start-=f,e.strstart-=f,e.block_start-=f,t=r=e.hash_size;n=e.head[--t],e.head[t]=f<=n?n-f:0,--r;);for(t=r=f;n=e.prev[--t],e.prev[t]=f<=n?n-f:0,--r;);i+=f}if(0===e.strm.avail_in)break;if(a=e.strm,o=e.window,h=e.strstart+e.lookahead,u=i,l=void 0,l=a.avail_in,u=x)for(s=e.strstart-e.insert,e.ins_h=e.window[s],e.ins_h=(e.ins_h<=x&&(e.ins_h=(e.ins_h<=x)if(n=u._tr_tally(e,e.strstart-e.match_start,e.match_length-x),e.lookahead-=e.match_length,e.match_length<=e.max_lazy_match&&e.lookahead>=x){for(e.match_length--;e.strstart++,e.ins_h=(e.ins_h<=x&&(e.ins_h=(e.ins_h<=x&&e.match_length<=e.prev_length){for(i=e.strstart+e.lookahead-x,n=u._tr_tally(e,e.strstart-1-e.prev_match,e.prev_length-x),e.lookahead-=e.prev_length-1,e.prev_length-=2;++e.strstart<=i&&(e.ins_h=(e.ins_h<e.pending_buf_size-5&&(r=e.pending_buf_size-5);;){if(e.lookahead<=1){if(j(e),0===e.lookahead&&t===l)return A;if(0===e.lookahead)break}e.strstart+=e.lookahead,e.lookahead=0;var n=e.block_start+r;if((0===e.strstart||e.strstart>=n)&&(e.lookahead=e.strstart-n,e.strstart=n,N(e,!1),0===e.strm.avail_out))return A;if(e.strstart-e.block_start>=e.w_size-z&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):(e.strstart>e.block_start&&(N(e,!1),e.strm.avail_out),A)}),new M(4,4,8,4,Z),new M(4,5,16,8,Z),new M(4,6,32,32,Z),new M(4,4,16,16,W),new M(8,16,32,32,W),new M(8,16,128,128,W),new M(8,32,128,256,W),new M(32,128,258,1024,W),new M(32,258,258,4096,W)],r.deflateInit=function(e,t){return Y(e,t,v,15,8,0)},r.deflateInit2=Y,r.deflateReset=K,r.deflateResetKeep=G,r.deflateSetHeader=function(e,t){return e&&e.state?2!==e.state.wrap?_:(e.state.gzhead=t,m):_},r.deflate=function(e,t){var r,n,i,s;if(!e||!e.state||5>8&255),U(n,n.gzhead.time>>16&255),U(n,n.gzhead.time>>24&255),U(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),U(n,255&n.gzhead.os),n.gzhead.extra&&n.gzhead.extra.length&&(U(n,255&n.gzhead.extra.length),U(n,n.gzhead.extra.length>>8&255)),n.gzhead.hcrc&&(e.adler=p(e.adler,n.pending_buf,n.pending,0)),n.gzindex=0,n.status=69):(U(n,0),U(n,0),U(n,0),U(n,0),U(n,0),U(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),U(n,3),n.status=E);else{var a=v+(n.w_bits-8<<4)<<8;a|=(2<=n.strategy||n.level<2?0:n.level<6?1:6===n.level?2:3)<<6,0!==n.strstart&&(a|=32),a+=31-a%31,n.status=E,P(n,a),0!==n.strstart&&(P(n,e.adler>>>16),P(n,65535&e.adler)),e.adler=1}if(69===n.status)if(n.gzhead.extra){for(i=n.pending;n.gzindex<(65535&n.gzhead.extra.length)&&(n.pending!==n.pending_buf_size||(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending!==n.pending_buf_size));)U(n,255&n.gzhead.extra[n.gzindex]),n.gzindex++;n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),n.gzindex===n.gzhead.extra.length&&(n.gzindex=0,n.status=73)}else n.status=73;if(73===n.status)if(n.gzhead.name){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindexi&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.gzindex=0,n.status=91)}else n.status=91;if(91===n.status)if(n.gzhead.comment){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindexi&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.status=103)}else n.status=103;if(103===n.status&&(n.gzhead.hcrc?(n.pending+2>n.pending_buf_size&&F(e),n.pending+2<=n.pending_buf_size&&(U(n,255&e.adler),U(n,e.adler>>8&255),e.adler=0,n.status=E)):n.status=E),0!==n.pending){if(F(e),0===e.avail_out)return n.last_flush=-1,m}else if(0===e.avail_in&&T(t)<=T(r)&&t!==f)return R(e,-5);if(666===n.status&&0!==e.avail_in)return R(e,-5);if(0!==e.avail_in||0!==n.lookahead||t!==l&&666!==n.status){var o=2===n.strategy?function(e,t){for(var r;;){if(0===e.lookahead&&(j(e),0===e.lookahead)){if(t===l)return A;break}if(e.match_length=0,r=u._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++,r&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):e.last_lit&&(N(e,!1),0===e.strm.avail_out)?A:I}(n,t):3===n.strategy?function(e,t){for(var r,n,i,s,a=e.window;;){if(e.lookahead<=S){if(j(e),e.lookahead<=S&&t===l)return A;if(0===e.lookahead)break}if(e.match_length=0,e.lookahead>=x&&0e.lookahead&&(e.match_length=e.lookahead)}if(e.match_length>=x?(r=u._tr_tally(e,1,e.match_length-x),e.lookahead-=e.match_length,e.strstart+=e.match_length,e.match_length=0):(r=u._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++),r&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):e.last_lit&&(N(e,!1),0===e.strm.avail_out)?A:I}(n,t):h[n.level].func(n,t);if(o!==O&&o!==B||(n.status=666),o===A||o===O)return 0===e.avail_out&&(n.last_flush=-1),m;if(o===I&&(1===t?u._tr_align(n):5!==t&&(u._tr_stored_block(n,0,0,!1),3===t&&(D(n.head),0===n.lookahead&&(n.strstart=0,n.block_start=0,n.insert=0))),F(e),0===e.avail_out))return n.last_flush=-1,m}return t!==f?m:n.wrap<=0?1:(2===n.wrap?(U(n,255&e.adler),U(n,e.adler>>8&255),U(n,e.adler>>16&255),U(n,e.adler>>24&255),U(n,255&e.total_in),U(n,e.total_in>>8&255),U(n,e.total_in>>16&255),U(n,e.total_in>>24&255)):(P(n,e.adler>>>16),P(n,65535&e.adler)),F(e),0=r.w_size&&(0===s&&(D(r.head),r.strstart=0,r.block_start=0,r.insert=0),u=new c.Buf8(r.w_size),c.arraySet(u,t,l-r.w_size,r.w_size,0),t=u,l=r.w_size),a=e.avail_in,o=e.next_in,h=e.input,e.avail_in=l,e.next_in=0,e.input=t,j(r);r.lookahead>=x;){for(n=r.strstart,i=r.lookahead-(x-1);r.ins_h=(r.ins_h<>>=y=v>>>24,p-=y,0===(y=v>>>16&255))C[s++]=65535&v;else{if(!(16&y)){if(0==(64&y)){v=m[(65535&v)+(d&(1<>>=y,p-=y),p<15&&(d+=z[n++]<>>=y=v>>>24,p-=y,!(16&(y=v>>>16&255))){if(0==(64&y)){v=_[(65535&v)+(d&(1<>>=y,p-=y,(y=s-a)>3,d&=(1<<(p-=w<<3))-1,e.next_in=n,e.next_out=s,e.avail_in=n>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function s(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new I.Buf16(320),this.work=new I.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function a(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=P,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new I.Buf32(n),t.distcode=t.distdyn=new I.Buf32(i),t.sane=1,t.back=-1,N):U}function o(e){var t;return e&&e.state?((t=e.state).wsize=0,t.whave=0,t.wnext=0,a(e)):U}function h(e,t){var r,n;return e&&e.state?(n=e.state,t<0?(r=0,t=-t):(r=1+(t>>4),t<48&&(t&=15)),t&&(t<8||15=s.wsize?(I.arraySet(s.window,t,r-s.wsize,s.wsize,0),s.wnext=0,s.whave=s.wsize):(n<(i=s.wsize-s.wnext)&&(i=n),I.arraySet(s.window,t,r-n,i,s.wnext),(n-=i)?(I.arraySet(s.window,t,r-n,n,0),s.wnext=n,s.whave=s.wsize):(s.wnext+=i,s.wnext===s.wsize&&(s.wnext=0),s.whave>>8&255,r.check=B(r.check,E,2,0),l=u=0,r.mode=2;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&u)<<8)+(u>>8))%31){e.msg="incorrect header check",r.mode=30;break}if(8!=(15&u)){e.msg="unknown compression method",r.mode=30;break}if(l-=4,k=8+(15&(u>>>=4)),0===r.wbits)r.wbits=k;else if(k>r.wbits){e.msg="invalid window size",r.mode=30;break}r.dmax=1<>8&1),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=3;case 3:for(;l<32;){if(0===o)break e;o--,u+=n[s++]<>>8&255,E[2]=u>>>16&255,E[3]=u>>>24&255,r.check=B(r.check,E,4,0)),l=u=0,r.mode=4;case 4:for(;l<16;){if(0===o)break e;o--,u+=n[s++]<>8),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=5;case 5:if(1024&r.flags){for(;l<16;){if(0===o)break e;o--,u+=n[s++]<>>8&255,r.check=B(r.check,E,2,0)),l=u=0}else r.head&&(r.head.extra=null);r.mode=6;case 6:if(1024&r.flags&&(o<(d=r.length)&&(d=o),d&&(r.head&&(k=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),I.arraySet(r.head.extra,n,s,d,k)),512&r.flags&&(r.check=B(r.check,n,d,s)),o-=d,s+=d,r.length-=d),r.length))break e;r.length=0,r.mode=7;case 7:if(2048&r.flags){if(0===o)break e;for(d=0;k=n[s+d++],r.head&&k&&r.length<65536&&(r.head.name+=String.fromCharCode(k)),k&&d>9&1,r.head.done=!0),e.adler=r.check=0,r.mode=12;break;case 10:for(;l<32;){if(0===o)break e;o--,u+=n[s++]<>>=7&l,l-=7&l,r.mode=27;break}for(;l<3;){if(0===o)break e;o--,u+=n[s++]<>>=1)){case 0:r.mode=14;break;case 1:if(j(r),r.mode=20,6!==t)break;u>>>=2,l-=2;break e;case 2:r.mode=17;break;case 3:e.msg="invalid block type",r.mode=30}u>>>=2,l-=2;break;case 14:for(u>>>=7&l,l-=7&l;l<32;){if(0===o)break e;o--,u+=n[s++]<>>16^65535)){e.msg="invalid stored block lengths",r.mode=30;break}if(r.length=65535&u,l=u=0,r.mode=15,6===t)break e;case 15:r.mode=16;case 16:if(d=r.length){if(o>>=5,l-=5,r.ndist=1+(31&u),u>>>=5,l-=5,r.ncode=4+(15&u),u>>>=4,l-=4,286>>=3,l-=3}for(;r.have<19;)r.lens[A[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,S={bits:r.lenbits},x=T(0,r.lens,0,19,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg="invalid code lengths set",r.mode=30;break}r.have=0,r.mode=19;case 19:for(;r.have>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=_,l-=_,r.lens[r.have++]=b;else{if(16===b){for(z=_+2;l>>=_,l-=_,0===r.have){e.msg="invalid bit length repeat",r.mode=30;break}k=r.lens[r.have-1],d=3+(3&u),u>>>=2,l-=2}else if(17===b){for(z=_+3;l>>=_)),u>>>=3,l-=3}else{for(z=_+7;l>>=_)),u>>>=7,l-=7}if(r.have+d>r.nlen+r.ndist){e.msg="invalid bit length repeat",r.mode=30;break}for(;d--;)r.lens[r.have++]=k}}if(30===r.mode)break;if(0===r.lens[256]){e.msg="invalid code -- missing end-of-block",r.mode=30;break}if(r.lenbits=9,S={bits:r.lenbits},x=T(D,r.lens,0,r.nlen,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg="invalid literal/lengths set",r.mode=30;break}if(r.distbits=6,r.distcode=r.distdyn,S={bits:r.distbits},x=T(F,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,S),r.distbits=S.bits,x){e.msg="invalid distances set",r.mode=30;break}if(r.mode=20,6===t)break e;case 20:r.mode=21;case 21:if(6<=o&&258<=h){e.next_out=a,e.avail_out=h,e.next_in=s,e.avail_in=o,r.hold=u,r.bits=l,R(e,c),a=e.next_out,i=e.output,h=e.avail_out,s=e.next_in,n=e.input,o=e.avail_in,u=r.hold,l=r.bits,12===r.mode&&(r.back=-1);break}for(r.back=0;g=(C=r.lencode[u&(1<>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=v,l-=v,r.back+=v}if(u>>>=_,l-=_,r.back+=_,r.length=b,0===g){r.mode=26;break}if(32&g){r.back=-1,r.mode=12;break}if(64&g){e.msg="invalid literal/length code",r.mode=30;break}r.extra=15&g,r.mode=22;case 22:if(r.extra){for(z=r.extra;l>>=r.extra,l-=r.extra,r.back+=r.extra}r.was=r.length,r.mode=23;case 23:for(;g=(C=r.distcode[u&(1<>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=v,l-=v,r.back+=v}if(u>>>=_,l-=_,r.back+=_,64&g){e.msg="invalid distance code",r.mode=30;break}r.offset=b,r.extra=15&g,r.mode=24;case 24:if(r.extra){for(z=r.extra;l>>=r.extra,l-=r.extra,r.back+=r.extra}if(r.offset>r.dmax){e.msg="invalid distance too far back",r.mode=30;break}r.mode=25;case 25:if(0===h)break e;if(d=c-h,r.offset>d){if((d=r.offset-d)>r.whave&&r.sane){e.msg="invalid distance too far back",r.mode=30;break}p=d>r.wnext?(d-=r.wnext,r.wsize-d):r.wnext-d,d>r.length&&(d=r.length),m=r.window}else m=i,p=a-r.offset,d=r.length;for(hd?(m=R[T+a[v]],A[I+a[v]]):(m=96,0),h=1<>S)+(u-=h)]=p<<24|m<<16|_|0,0!==u;);for(h=1<>=1;if(0!==h?(E&=h-1,E+=h):E=0,v++,0==--O[b]){if(b===w)break;b=t[r+a[v]]}if(k>>7)]}function U(e,t){e.pending_buf[e.pending++]=255&t,e.pending_buf[e.pending++]=t>>>8&255}function P(e,t,r){e.bi_valid>d-r?(e.bi_buf|=t<>d-e.bi_valid,e.bi_valid+=r-d):(e.bi_buf|=t<>>=1,r<<=1,0<--t;);return r>>>1}function Z(e,t,r){var n,i,s=new Array(g+1),a=0;for(n=1;n<=g;n++)s[n]=a=a+r[n-1]<<1;for(i=0;i<=t;i++){var o=e[2*i+1];0!==o&&(e[2*i]=j(s[o]++,o))}}function W(e){var t;for(t=0;t>1;1<=r;r--)G(e,s,r);for(i=h;r=e.heap[1],e.heap[1]=e.heap[e.heap_len--],G(e,s,1),n=e.heap[1],e.heap[--e.heap_max]=r,e.heap[--e.heap_max]=n,s[2*i]=s[2*r]+s[2*n],e.depth[i]=(e.depth[r]>=e.depth[n]?e.depth[r]:e.depth[n])+1,s[2*r+1]=s[2*n+1]=i,e.heap[1]=i++,G(e,s,1),2<=e.heap_len;);e.heap[--e.heap_max]=e.heap[1],function(e,t){var r,n,i,s,a,o,h=t.dyn_tree,u=t.max_code,l=t.stat_desc.static_tree,f=t.stat_desc.has_stree,c=t.stat_desc.extra_bits,d=t.stat_desc.extra_base,p=t.stat_desc.max_length,m=0;for(s=0;s<=g;s++)e.bl_count[s]=0;for(h[2*e.heap[e.heap_max]+1]=0,r=e.heap_max+1;r<_;r++)p<(s=h[2*h[2*(n=e.heap[r])+1]+1]+1)&&(s=p,m++),h[2*n+1]=s,u>=7;n>>=1)if(1&r&&0!==e.dyn_ltree[2*t])return o;if(0!==e.dyn_ltree[18]||0!==e.dyn_ltree[20]||0!==e.dyn_ltree[26])return h;for(t=32;t>>3,(s=e.static_len+3+7>>>3)<=i&&(i=s)):i=s=r+5,r+4<=i&&-1!==t?J(e,t,r,n):4===e.strategy||s===i?(P(e,2+(n?1:0),3),K(e,z,C)):(P(e,4+(n?1:0),3),function(e,t,r,n){var i;for(P(e,t-257,5),P(e,r-1,5),P(e,n-4,4),i=0;i>>8&255,e.pending_buf[e.d_buf+2*e.last_lit+1]=255&t,e.pending_buf[e.l_buf+e.last_lit]=255&r,e.last_lit++,0===t?e.dyn_ltree[2*r]++:(e.matches++,t--,e.dyn_ltree[2*(A[r]+u+1)]++,e.dyn_dtree[2*N(t)]++),e.last_lit===e.lit_bufsize-1},r._tr_align=function(e){P(e,2,3),L(e,m,z),function(e){16===e.bi_valid?(U(e,e.bi_buf),e.bi_buf=0,e.bi_valid=0):8<=e.bi_valid&&(e.pending_buf[e.pending++]=255&e.bi_buf,e.bi_buf>>=8,e.bi_valid-=8)}(e)}},{"../utils/common":41}],53:[function(e,t,r){"use strict";t.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}},{}],54:[function(e,t,r){(function(e){!function(r,n){"use strict";if(!r.setImmediate){var i,s,t,a,o=1,h={},u=!1,l=r.document,e=Object.getPrototypeOf&&Object.getPrototypeOf(r);e=e&&e.setTimeout?e:r,i="[object process]"==={}.toString.call(r.process)?function(e){process.nextTick(function(){c(e)})}:function(){if(r.postMessage&&!r.importScripts){var e=!0,t=r.onmessage;return r.onmessage=function(){e=!1},r.postMessage("","*"),r.onmessage=t,e}}()?(a="setImmediate$"+Math.random()+"$",r.addEventListener?r.addEventListener("message",d,!1):r.attachEvent("onmessage",d),function(e){r.postMessage(a+e,"*")}):r.MessageChannel?((t=new MessageChannel).port1.onmessage=function(e){c(e.data)},function(e){t.port2.postMessage(e)}):l&&"onreadystatechange"in l.createElement("script")?(s=l.documentElement,function(e){var t=l.createElement("script");t.onreadystatechange=function(){c(e),t.onreadystatechange=null,s.removeChild(t),t=null},s.appendChild(t)}):function(e){setTimeout(c,0,e)},e.setImmediate=function(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),r=0;r #include +#elif defined(CONFIG_BOARD_TYPE_TDECK) +#include #else #include #include diff --git a/main/input/tdeck.inc b/main/input/tdeck.inc new file mode 100644 index 000000000..442688218 --- /dev/null +++ b/main/input/tdeck.inc @@ -0,0 +1,102 @@ +#include "gui.h" +#include "jade_assert.h" +#include "jade_tasks.h" + +#include "button_gpio.h" +#include "iot_button.h" + +#include +#include + +#define BOARD_POWERON_GPIO 10 +#define KB_I2C_ADDR 0x55 +#define KB_I2C_TIMEOUT_MS 50 + +#define TB_LEFT_GPIO 1 +#define TB_RIGHT_GPIO 2 +#define TB_PRESS_GPIO 0 + +static void tdeck_keyboard_task(void* unused) +{ + gpio_set_direction(BOARD_POWERON_GPIO, GPIO_MODE_OUTPUT); + gpio_set_level(BOARD_POWERON_GPIO, 1); + + vTaskDelay(500 / portTICK_PERIOD_MS); + + i2c_master_bus_config_t bus_config = { + .i2c_port = I2C_NUM_0, + .sda_io_num = CONFIG_I2C_SDA, + .scl_io_num = CONFIG_I2C_SCL, + .clk_source = I2C_CLK_SRC_DEFAULT, + .glitch_ignore_cnt = 7, + .flags.enable_internal_pullup = true, + }; + i2c_master_bus_handle_t kb_i2c_bus; + ESP_ERROR_CHECK(i2c_new_master_bus(&bus_config, &kb_i2c_bus)); + + i2c_device_config_t dev_cfg = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = KB_I2C_ADDR, + .scl_speed_hz = CONFIG_I2C_MASTER_CLK, + }; + i2c_master_dev_handle_t kb_i2c_dev; + ESP_ERROR_CHECK(i2c_master_bus_add_device(kb_i2c_bus, &dev_cfg, &kb_i2c_dev)); + + for (;;) { + uint8_t key_byte = 0; + const esp_err_t ret = i2c_master_receive(kb_i2c_dev, &key_byte, 1, KB_I2C_TIMEOUT_MS); + if (ret == ESP_OK && key_byte != 0) { + if (key_byte == 0x0D) { + esp_event_post(GUI_BUTTON_EVENT, BTN_KEYBOARD_ENTER, NULL, 0, portMAX_DELAY); + } else if (key_byte == 0x08) { + esp_event_post(GUI_BUTTON_EVENT, BTN_KEYBOARD_BACKSPACE, NULL, 0, portMAX_DELAY); + } else if (key_byte >= 32 && key_byte < 128) { + esp_event_post(GUI_BUTTON_EVENT, BTN_KEYBOARD_ASCII_OFFSET + key_byte, NULL, 0, portMAX_DELAY); + } + } + vTaskDelay(30 / portTICK_PERIOD_MS); + } + + vTaskDelete(NULL); +} + +static void tb_left_trigger(void* arg, void* ctx) { gui_prev(); } +static void tb_right_trigger(void* arg, void* ctx) { gui_next(); } +static void tb_press_trigger(void* arg, void* ctx) { gui_front_click(); } + +void navigation_init(void) +{ + BaseType_t retval = xTaskCreatePinnedToCore( + &tdeck_keyboard_task, "tdeck_kbd", 3 * 1024, NULL, JADE_TASK_PRIO_WHEEL, NULL, JADE_CORE_SECONDARY); + JADE_ASSERT_MSG(retval == pdPASS, "Failed to create tdeck_keyboard task, xTaskCreatePinnedToCore() returned %d", + retval); + + const button_config_t btn_cfg = { + .long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS, + .short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS, + }; + + button_handle_t btn_left = NULL; + const button_gpio_config_t left_gpio_cfg = { .gpio_num = TB_LEFT_GPIO, .active_level = 0 }; + ESP_ERROR_CHECK(iot_button_new_gpio_device(&btn_cfg, &left_gpio_cfg, &btn_left)); + JADE_ASSERT(btn_left); + ESP_ERROR_CHECK(iot_button_register_cb(btn_left, BUTTON_PRESS_DOWN, NULL, tb_left_trigger, NULL)); + ESP_ERROR_CHECK(iot_button_register_cb(btn_left, BUTTON_LONG_PRESS_HOLD, NULL, tb_left_trigger, NULL)); + + button_handle_t btn_right = NULL; + const button_gpio_config_t right_gpio_cfg = { .gpio_num = TB_RIGHT_GPIO, .active_level = 0 }; + ESP_ERROR_CHECK(iot_button_new_gpio_device(&btn_cfg, &right_gpio_cfg, &btn_right)); + JADE_ASSERT(btn_right); + ESP_ERROR_CHECK(iot_button_register_cb(btn_right, BUTTON_PRESS_DOWN, NULL, tb_right_trigger, NULL)); + ESP_ERROR_CHECK(iot_button_register_cb(btn_right, BUTTON_LONG_PRESS_HOLD, NULL, tb_right_trigger, NULL)); + + button_handle_t btn_press = NULL; + const button_gpio_config_t press_gpio_cfg = { .gpio_num = TB_PRESS_GPIO, .active_level = 0 }; + ESP_ERROR_CHECK(iot_button_new_gpio_device(&btn_cfg, &press_gpio_cfg, &btn_press)); + JADE_ASSERT(btn_press); + ESP_ERROR_CHECK(iot_button_register_cb(btn_press, BUTTON_PRESS_UP, NULL, tb_press_trigger, NULL)); +} + +void select_init(void) +{ +} diff --git a/main/power.c b/main/power.c index 1dd7624ba..7a691eed9 100644 --- a/main/power.c +++ b/main/power.c @@ -33,6 +33,8 @@ #elif defined(CONFIG_BOARD_TYPE_TTGO_TDISPLAY) // T-Display can read battery level but lacks hardware to read charging status #include "power/tdisplay.inc" +#elif defined(CONFIG_BOARD_TYPE_TDECK) +#include "power/tdeck.inc" #else // Stubs for other hw boards (ie. no power management) #include "power/minimal.inc" diff --git a/main/power/tdeck.inc b/main/power/tdeck.inc new file mode 100644 index 000000000..0715a2c2d --- /dev/null +++ b/main/power/tdeck.inc @@ -0,0 +1,152 @@ +#include "jade_assert.h" + +#include +#include +#include +#include +#include +#include + +#include "tusb.h" + +#define BOARD_POWERON_GPIO 10 +#define BACKLIGHT_GPIO 42 +#define BACKLIGHT_STEPS 16 + +#define BATTERY_ADC_CHANNEL ADC_CHANNEL_3 +#define BATTERY_ADC_ATTEN ADC_ATTEN_DB_12 +#define BATTERY_EMA_ALPHA 0.3f + +static adc_oneshot_unit_handle_t adc1_handle = NULL; +static adc_cali_handle_t adc1_cali_chan0_handle = NULL; +static float ema_voltage = 0.0f; +static uint8_t bl_level = 0; + +static void set_backlight(uint8_t value) +{ + if (value > BACKLIGHT_STEPS) { + value = BACKLIGHT_STEPS; + } + if (value == 0) { + gpio_set_level(BACKLIGHT_GPIO, 0); + esp_rom_delay_us(3000); + bl_level = 0; + return; + } + if (bl_level == 0) { + gpio_set_level(BACKLIGHT_GPIO, 1); + bl_level = BACKLIGHT_STEPS; + esp_rom_delay_us(30); + } + const int from = BACKLIGHT_STEPS - bl_level; + const int to = BACKLIGHT_STEPS - value; + const int num = (BACKLIGHT_STEPS + to - from) % BACKLIGHT_STEPS; + for (int i = 0; i < num; i++) { + gpio_set_level(BACKLIGHT_GPIO, 0); + gpio_set_level(BACKLIGHT_GPIO, 1); + } + bl_level = value; +} + +esp_err_t power_init(void) +{ + gpio_set_direction(BOARD_POWERON_GPIO, GPIO_MODE_OUTPUT); + gpio_set_level(BOARD_POWERON_GPIO, 1); + + gpio_set_direction(BACKLIGHT_GPIO, GPIO_MODE_OUTPUT); + gpio_set_level(BACKLIGHT_GPIO, 0); + + adc_oneshot_unit_init_cfg_t init_config1 = { .unit_id = ADC_UNIT_1 }; + ESP_ERROR_CHECK(adc_oneshot_new_unit(&init_config1, &adc1_handle)); + JADE_ASSERT(adc1_handle); + + adc_oneshot_chan_cfg_t config = { .atten = BATTERY_ADC_ATTEN, .bitwidth = ADC_BITWIDTH_DEFAULT }; + ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, BATTERY_ADC_CHANNEL, &config)); + + adc_cali_curve_fitting_config_t cali_config = { + .unit_id = ADC_UNIT_1, + .atten = BATTERY_ADC_ATTEN, + .bitwidth = ADC_BITWIDTH_DEFAULT, + }; + if (adc_cali_create_scheme_curve_fitting(&cali_config, &adc1_cali_chan0_handle) != ESP_OK) { + JADE_LOGW("ADC calibration not available, continuing without it"); + adc1_cali_chan0_handle = NULL; + } + return ESP_OK; +} + +esp_err_t power_shutdown(void) +{ + esp_deep_sleep_start(); + return ESP_OK; +} + +esp_err_t power_screen_on(void) { return ESP_OK; } +esp_err_t power_screen_off(void) { return ESP_OK; } + +esp_err_t power_backlight_on(const uint8_t brightness) +{ + const uint8_t scaled = (brightness * BACKLIGHT_STEPS) / 255; + set_backlight(scaled); + return ESP_OK; +} + +esp_err_t power_backlight_off(void) +{ + set_backlight(0); + return ESP_OK; +} + +esp_err_t power_camera_on(void) { return ESP_OK; } +esp_err_t power_camera_off(void) { return ESP_OK; } + +uint16_t power_get_vbat(void) +{ + JADE_ASSERT(adc1_handle); + int raw_adc, voltage; + ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, BATTERY_ADC_CHANNEL, &raw_adc)); + if (adc1_cali_chan0_handle) { + ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_chan0_handle, raw_adc, &voltage)); + } else { + voltage = (raw_adc * 3300) / 4095; + } + const float ema_v = (ema_voltage > 0) ? ema_voltage : (float)voltage; + ema_voltage = (BATTERY_EMA_ALPHA * voltage) + ((1.0f - BATTERY_EMA_ALPHA) * ema_v); + return (uint16_t)(ema_voltage * 2); +} + +uint8_t power_get_battery_status(void) +{ + const uint16_t vbat = power_get_vbat(); + if (vbat > 4000) return 5; + if (vbat > 3800) return 4; + if (vbat > 3600) return 3; + if (vbat > 3400) return 2; + if (vbat > 3200) return 1; + return 0; +} + +bool power_get_battery_charging(void) +{ + return tud_mounted() && !tud_suspended(); +} + +uint16_t power_get_ibat_charge(void) { return 0; } +uint16_t power_get_ibat_discharge(void) { return 0; } +uint16_t power_get_vusb(void) { return 0; } +uint16_t power_get_iusb(void) { return 0; } +uint16_t power_get_temp(void) { return 0; } + +void disable_usb_host(void) {} +void enable_usb_host(void) {} + +bool usb_is_powered(void) +{ + if (tud_mounted() && !tud_suspended()) { + return true; + } + if (power_get_vbat() < 1000) { + return true; + } + return false; +} diff --git a/main/process/dashboard.c b/main/process/dashboard.c index 67d191d50..1a9085f56 100644 --- a/main/process/dashboard.c +++ b/main/process/dashboard.c @@ -1703,7 +1703,7 @@ static void handle_view_otps(void) // NOTE: Only Jade v1.1's and v2's have brightness controls #if defined(CONFIG_BOARD_TYPE_JADE_V1_1) || defined(CONFIG_BOARD_TYPE_JADE_V2_ANY) \ - || defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) + || defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) || defined(CONFIG_BOARD_TYPE_TDECK) static void handle_screen_brightness(void) { static const char* LABELS[] = { "Min(1)", "Low(2)", "Medium(3)", "High(4)", "Max(5)" }; @@ -2281,7 +2281,7 @@ static void handle_settings(const bool startup_menu) // NOTE: Only Jade v1.1's and v2's have brightness controls #if defined(CONFIG_BOARD_TYPE_JADE_V1_1) || defined(CONFIG_BOARD_TYPE_JADE_V2_ANY) \ - || defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) + || defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) || defined(CONFIG_BOARD_TYPE_TDECK) case BTN_SETTINGS_DISPLAY_BRIGHTNESS: handle_screen_brightness(); break; diff --git a/main/ui/dashboard.c b/main/ui/dashboard.c index b637cfba5..82fca4ed9 100644 --- a/main/ui/dashboard.c +++ b/main/ui/dashboard.c @@ -394,7 +394,7 @@ gui_activity_t* make_display_settings_activity(void) // NOTE: Only Jade v1.1's and v2's have brightness controls // NOTE: Jade v1.1's do not support Flip Orientation because of issues with screen offsets -#if defined(CONFIG_BOARD_TYPE_JADE_V2_ANY) || defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) +#if defined(CONFIG_BOARD_TYPE_JADE_V2_ANY) || defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) || defined(CONFIG_BOARD_TYPE_TDECK) btn_data_t menubtns[] = { { .txt = "Display Brightness", .font = GUI_DEFAULT_FONT, .ev_id = BTN_SETTINGS_DISPLAY_BRIGHTNESS }, { .txt = "Flip Orientation", .font = GUI_DEFAULT_FONT, .ev_id = BTN_SETTINGS_DISPLAY_ORIENTATION }, diff --git a/tools/switch_to.sh b/tools/switch_to.sh index 4fe03df42..b16356add 100755 --- a/tools/switch_to.sh +++ b/tools/switch_to.sh @@ -75,6 +75,7 @@ while true; do jade_v1_1) CONFIG=$1; ARCH="esp32"; shift ;; jade_v2) CONFIG=$1; ARCH="esp32s3"; shift ;; jade_v2c) CONFIG=$1; ARCH="esp32s3"; shift ;; + tdeck) CONFIG=$1; ARCH="esp32s3"; shift ;; qemu) CONFIG=$1; ARCH="esp32"; shift ;; --dev) DEVELOPMENT="y"; shift ;; --noradio) NORADIO=1; shift ;; From 56b45f2e4da60b4d4ddeb5d8ac7cac1737c53276 Mon Sep 17 00:00:00 2001 From: 3rdIteration Date: Tue, 7 Jul 2026 03:55:12 +1000 Subject: [PATCH 02/22] ci: deploy web flasher to gh-pages from any branch --- .github/workflows/build.yml | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d04ea4243..02f186a55 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,7 +2,7 @@ name: Build T-Deck on: push: - branches: [ master ] + branches: [ '**' ] pull_request: branches: [ master ] @@ -40,15 +40,11 @@ jobs: retention-days: 90 deploy: - if: github.event_name == 'push' && github.ref == 'refs/heads/master' + if: github.event_name == 'push' needs: build runs-on: ubuntu-latest permissions: - pages: write - id-token: write - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} + contents: write steps: - uses: actions/checkout@v4 @@ -58,11 +54,10 @@ jobs: name: firmware-tdeck path: flasher/firmware/tdeck/ - - name: Upload Pages artifact - uses: actions/upload-pages-artifact@v3 + - name: Deploy to gh-pages + uses: peaceiris/actions-gh-pages@v3 with: - path: flasher/ - - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v4 + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: flasher/ + destination_dir: . + keep_files: false From 51b7696e6f2097ffccd444db1160e207e35aaa1c Mon Sep 17 00:00:00 2001 From: 3rdIteration Date: Tue, 7 Jul 2026 03:58:06 +1000 Subject: [PATCH 03/22] fix: source IDF env in CI container --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 02f186a55..88a79ce85 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,7 +16,9 @@ jobs: submodules: recursive - name: Build T-Deck firmware + shell: bash run: | + . /opt/esp/idf/export.sh cp configs/sdkconfig_display_tdeck.defaults sdkconfig.defaults idf.py -B build_tdeck set-target esp32s3 idf.py -B build_tdeck build From d67604de68cad4cab1d4d17baae1260014d1929a Mon Sep 17 00:00:00 2001 From: 3rdIteration Date: Tue, 7 Jul 2026 04:09:43 +1000 Subject: [PATCH 04/22] fix: add missing ciFiles element in flasher --- flasher/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/flasher/index.html b/flasher/index.html index 574e5bdc4..efc44d785 100644 --- a/flasher/index.html +++ b/flasher/index.html @@ -144,6 +144,7 @@

Jade Web Flasher

BoardLilyGO T-Deck
Chip
Flash
+
Files
From 66b9e3a88811513d7716c8b19c413b569dd2f276 Mon Sep 17 00:00:00 2001 From: 3rdIteration Date: Tue, 7 Jul 2026 04:20:19 +1000 Subject: [PATCH 05/22] feat: add serial monitor with auto-connect after flashing --- flasher/index.html | 114 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 2 deletions(-) diff --git a/flasher/index.html b/flasher/index.html index efc44d785..78e425ba9 100644 --- a/flasher/index.html +++ b/flasher/index.html @@ -171,6 +171,8 @@

Jade Web Flasher

+ +
@@ -263,6 +269,102 @@

Jade Web Flasher

}); let zipFirmware = null; +let serialMonitor = null; +let serialPort = null; + +const serialDiv = document.getElementById('serialOutput'); +const consoleDiv = document.getElementById('console'); +const serialBtn = document.getElementById('serialBtn'); +const disconnectBtn = document.getElementById('disconnectBtn'); + +function serialWrite(text) { + const last = serialDiv.lastChild; + if (last && last.nodeType === Node.TEXT_NODE) { + last.textContent += text; + } else { + serialDiv.appendChild(document.createTextNode(text)); + } + serialDiv.scrollTop = serialDiv.scrollHeight; + if (serialDiv.children.length > 500) { + serialDiv.removeChild(serialDiv.firstChild); + } +} + +function serialLine(text, cls = '') { + const line = document.createElement('div'); + if (cls) line.className = cls; + line.textContent = text + '\n'; + serialDiv.appendChild(line); + serialDiv.scrollTop = serialDiv.scrollHeight; + if (serialDiv.children.length > 500) { + serialDiv.removeChild(serialDiv.firstChild); + } +} + +async function startSerialMonitor(port) { + serialPort = port; + serialDiv.style.display = 'block'; + consoleDiv.style.display = 'none'; + serialDiv.innerHTML = ''; + + serialBtn.style.display = 'none'; + disconnectBtn.style.display = ''; + document.getElementById('flashBtn').disabled = true; + + serialLine('Serial monitor connected (115200 baud). Press RESET on device if needed.', 'info'); + + let reader; + try { + reader = port.readable.getReader(); + } catch (e) { + serialLine(`Failed to open serial stream: ${e.message}`, 'err'); + await stopSerialMonitor(); + return; + } + const decoder = new TextDecoder(); + serialMonitor = { port, reader }; + + try { + while (serialMonitor) { + const { value, done } = await reader.read(); + if (done || !serialMonitor) break; + const text = decoder.decode(value, { stream: true }); + serialWrite(text); + } + } catch (e) { + if (serialMonitor) serialLine(`Serial disconnected: ${e.message}`, 'err'); + } +} + +async function stopSerialMonitor() { + if (serialMonitor) { + const { port, reader } = serialMonitor; + serialMonitor = null; + try { await reader.cancel(); } catch (_) {} + try { reader.releaseLock(); } catch (_) {} + try { await port.close(); } catch (_) {} + } else if (serialPort) { + try { await serialPort.close(); } catch (_) {} + } + serialPort = null; + serialDiv.style.display = 'none'; + consoleDiv.style.display = ''; + serialBtn.style.display = ''; + disconnectBtn.style.display = 'none'; + document.getElementById('flashBtn').disabled = false; +} + +serialBtn.addEventListener('click', async () => { + try { + const port = await navigator.serial.requestPort(); + await port.open({ baudRate: 115200 }); + await startSerialMonitor(port); + } catch (e) { + log('Serial connect failed: ' + e.message, 'err'); + } +}); + +disconnectBtn.addEventListener('click', stopSerialMonitor); async function handleZip(file) { clearLog(); @@ -399,6 +501,7 @@

Jade Web Flasher

log('\nConnecting to device...'); log('Select the device serial port in the browser prompt.'); + document.getElementById('serialBtn').disabled = true; let transport; try { const port = await navigator.serial.requestPort(); @@ -450,13 +553,20 @@

Jade Web Flasher

log('Resetting device...'); await esploader.after('hard_reset'); - log('Done! Device should reboot.', 'ok'); + + log('Starting serial monitor (115200 baud)...', 'ok'); + await transport.disconnect(); + await port.open({ baudRate: 115200 }); + await startSerialMonitor(port); } catch (e) { log(`\nError: ${e.message}`, 'err'); } finally { btn.disabled = false; - try { if (transport) await transport.disconnect(); } catch (_) {} + document.getElementById('serialBtn').disabled = false; + if (!serialMonitor) { + try { if (transport) await transport.disconnect(); } catch (_) {} + } } }); From 1447a90ac65b11007b565b3bf73f4e1492ce281e Mon Sep 17 00:00:00 2001 From: 3rdIteration Date: Tue, 7 Jul 2026 04:30:15 +1000 Subject: [PATCH 06/22] fix: use IDF flash_files key in flasher_args.json --- flasher/index.html | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/flasher/index.html b/flasher/index.html index 78e425ba9..8e9b21eca 100644 --- a/flasher/index.html +++ b/flasher/index.html @@ -402,6 +402,14 @@

Jade Web Flasher

} function resolveLayout(b, files, args) { + if (args && args.flash_files) { + const entries = []; + for (const [offset, filePath] of Object.entries(args.flash_files)) { + const data = files[filePath]; + if (data) entries.push({ address: parseInt(offset, 16), data, name: filePath }); + } + return entries; + } if (args && args.files) { const entries = []; for (const [name, info] of Object.entries(args.files)) { @@ -426,13 +434,14 @@

Jade Web Flasher

if (argsResp.ok) { args = await argsResp.json(); log('Loaded flasher_args.json.', 'ok'); - for (const [name, info] of Object.entries(args.files || {})) { - const resp = await fetch(`./firmware/${bk}/${info.file}`); + const fileMap = args.flash_files || {}; + for (const [offset, filePath] of Object.entries(fileMap)) { + const resp = await fetch(`./firmware/${bk}/${filePath}`); if (resp.ok) { - files[info.file] = new Uint8Array(await resp.arrayBuffer()); - log(` Loaded ${info.file} (offset ${info.offset})`); + files[filePath] = new Uint8Array(await resp.arrayBuffer()); + log(` Loaded ${filePath} (offset ${offset})`); } else { - throw new Error(`Failed to fetch ${info.file}`); + throw new Error(`Failed to fetch ${filePath}`); } } } else { From 4a48751559a6ff945e4c20fa94fe719f33ed7090 Mon Sep 17 00:00:00 2001 From: 3rdIteration Date: Tue, 7 Jul 2026 04:42:11 +1000 Subject: [PATCH 07/22] feat: add debug build variant with USB-Serial-JTAG console --- .github/workflows/build.yml | 39 +++++---- .../sdkconfig_display_tdeck_debug.defaults | 84 +++++++++++++++++++ flasher/index.html | 32 +++++-- 3 files changed, 133 insertions(+), 22 deletions(-) create mode 100644 configs/sdkconfig_display_tdeck_debug.defaults diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 88a79ce85..c2ef06dea 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,6 +8,11 @@ on: jobs: build: + strategy: + matrix: + variant: + - { name: tdeck, config: sdkconfig_display_tdeck.defaults } + - { name: tdeck-debug, config: sdkconfig_display_tdeck_debug.defaults } runs-on: ubuntu-latest container: espressif/idf:v5.5.4 steps: @@ -15,30 +20,30 @@ jobs: with: submodules: recursive - - name: Build T-Deck firmware + - name: Build ${{ matrix.variant.name }} firmware shell: bash run: | . /opt/esp/idf/export.sh - cp configs/sdkconfig_display_tdeck.defaults sdkconfig.defaults - idf.py -B build_tdeck set-target esp32s3 - idf.py -B build_tdeck build + cp configs/${{ matrix.variant.config }} sdkconfig.defaults + idf.py -B build_${{ matrix.variant.name }} set-target esp32s3 + idf.py -B build_${{ matrix.variant.name }} build - name: Stage firmware artifacts run: | - mkdir -p firmware-tdeck/bootloader firmware-tdeck/partition_table - cp build_tdeck/bootloader/bootloader.bin firmware-tdeck/bootloader/ - cp build_tdeck/partition_table/partition-table.bin firmware-tdeck/partition_table/ - cp build_tdeck/ota_data_initial.bin firmware-tdeck/ 2>/dev/null || true - cp build_tdeck/jade.bin firmware-tdeck/ 2>/dev/null || true - cp build_tdeck/flasher_args.json firmware-tdeck/ 2>/dev/null || true + mkdir -p firmware-${{ matrix.variant.name }}/bootloader firmware-${{ matrix.variant.name }}/partition_table + cp build_${{ matrix.variant.name }}/bootloader/bootloader.bin firmware-${{ matrix.variant.name }}/bootloader/ + cp build_${{ matrix.variant.name }}/partition_table/partition-table.bin firmware-${{ matrix.variant.name }}/partition_table/ + cp build_${{ matrix.variant.name }}/ota_data_initial.bin firmware-${{ matrix.variant.name }}/ 2>/dev/null || true + cp build_${{ matrix.variant.name }}/jade.bin firmware-${{ matrix.variant.name }}/ 2>/dev/null || true + cp build_${{ matrix.variant.name }}/flasher_args.json firmware-${{ matrix.variant.name }}/ 2>/dev/null || true echo "Firmware staged:" - find firmware-tdeck -type f | sort + find firmware-${{ matrix.variant.name }} -type f | sort - name: Upload firmware artifact uses: actions/upload-artifact@v4 with: - name: firmware-tdeck - path: firmware-tdeck/ + name: firmware-${{ matrix.variant.name }} + path: firmware-${{ matrix.variant.name }}/ retention-days: 90 deploy: @@ -50,12 +55,18 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Download firmware artifact + - name: Download normal firmware artifact uses: actions/download-artifact@v4 with: name: firmware-tdeck path: flasher/firmware/tdeck/ + - name: Download debug firmware artifact + uses: actions/download-artifact@v4 + with: + name: firmware-tdeck-debug + path: flasher/firmware/tdeck-debug/ + - name: Deploy to gh-pages uses: peaceiris/actions-gh-pages@v3 with: diff --git a/configs/sdkconfig_display_tdeck_debug.defaults b/configs/sdkconfig_display_tdeck_debug.defaults new file mode 100644 index 000000000..c015f45e7 --- /dev/null +++ b/configs/sdkconfig_display_tdeck_debug.defaults @@ -0,0 +1,84 @@ +# display tdeck (debug: USB-Serial-JTAG console) +CONFIG_APP_REPRODUCIBLE_BUILD=y +CONFIG_BF20A6_SUPPORT=n +CONFIG_BF3005_SUPPORT=n +CONFIG_BOARD_TYPE_TDECK=y +CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y +CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y +CONFIG_BOOTLOADER_WDT_ENABLE=n +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=517 +CONFIG_BT_NIMBLE_ENABLED=y +CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=11 +CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=5632 +CONFIG_BT_NIMBLE_LOG_LEVEL_NONE=y +CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1 +CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=y +CONFIG_BT_NIMBLE_NVS_PERSIST=y +CONFIG_BT_NIMBLE_ROLE_BROADCASTER=n +CONFIG_BT_NIMBLE_ROLE_CENTRAL=n +CONFIG_BT_NIMBLE_ROLE_OBSERVER=n +CONFIG_BT_NIMBLE_SM_LEGACY=n +CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="j" +CONFIG_BUTTON_LONG_PRESS_HOLD_SERIAL_TIME_MS=100 +CONFIG_BUTTON_LONG_PRESS_TIME_MS=500 +CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_STACK_CHECK_MODE_STRONG=y +CONFIG_COMPILER_WARN_WRITE_STRINGS=y +CONFIG_DEBUG_MODE=y +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y +CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y +CONFIG_ESP_ERR_TO_NAME_LOOKUP=n +CONFIG_ESP_MAIN_TASK_STACK_SIZE=12288 +CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=n +CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND=n +CONFIG_ESP_SYSTEM_BBPLL_RECALIB=n +CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y +CONFIG_ESP_TASK_WDT_EN=n +CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=n +CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=n +CONFIG_ESP_WIFI_IRAM_OPT=n +CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=n +CONFIG_ESP_WIFI_NVS_ENABLED=n +CONFIG_ESP_WIFI_RX_IRAM_OPT=n +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n +CONFIG_FATFS_LFN_HEAP=y +CONFIG_FATFS_VFS_FSTAT_BLKSIZE=4096 +CONFIG_FATFS_VOLUME_COUNT=1 +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=3 +CONFIG_GC0308_SUPPORT=n +CONFIG_GC032A_SUPPORT=n +CONFIG_GC2145_SUPPORT=n +CONFIG_IDF_TARGET="esp32s3" +CONFIG_JADE_USE_USB_JTAG_SERIAL=y +CONFIG_LIBC_NEWLIB_NANO_FORMAT=y +CONFIG_LIBC_STDIN_LINE_ENDING_LF=y +CONFIG_LIBC_STDOUT_LINE_ENDING_LF=y +CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_NT99141_SUPPORT=n +CONFIG_OV2640_SUPPORT=n +CONFIG_OV3660_SUPPORT=n +CONFIG_OV5640_SUPPORT=n +CONFIG_OV7670_SUPPORT=n +CONFIG_OV7725_SUPPORT=n +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitionss3.csv" +CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP=n +CONFIG_SC030IOT_SUPPORT=n +CONFIG_SPIRAM=y +CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y +CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y +CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=256 +CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=65536 +CONFIG_SPIRAM_MEMTEST=n +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_RODATA=y +CONFIG_SPIRAM_SPEED_80M=y +CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y +CONFIG_SPI_FLASH_VERIFY_WRITE=y +CONFIG_SPI_MASTER_ISR_IN_IRAM=n +CONFIG_SPI_SLAVE_ISR_IN_IRAM=n diff --git a/flasher/index.html b/flasher/index.html index 8e9b21eca..1eade5dca 100644 --- a/flasher/index.html +++ b/flasher/index.html @@ -127,6 +127,11 @@

Jade Web Flasher

+
Variant
+
@@ -139,9 +144,10 @@

Jade Web Flasher

Firmware Source

- Downloads the latest firmware built from the master branch. + Downloads the latest firmware built from the T-Deck-Plus branch.

BoardLilyGO T-Deck
+
Variant
Chip
Flash
Files
@@ -152,13 +158,13 @@

Jade Web Flasher

Upload Firmware ZIP

- Download a firmware-tdeck.zip artifact from the - Actions tab + Download a firmware-tdeck.zip or firmware-tdeck-debug.zip artifact + from the Actions tab and drop it here.

Drop ZIP file here or click to browse

-

Supports firmware-tdeck.zip artifacts from CI

+

Supports firmware-tdeck.zip and firmware-tdeck-debug.zip artifacts

@@ -224,6 +230,14 @@

Jade Web Flasher

function boardKey() { return document.getElementById('boardSelect').value; } function board() { return BOARDS[boardKey()]; } +function firmwareKey() { + const v = document.getElementById('variantSelect').value; + return boardKey() + (v ? '-' + v : ''); +} +function variantLabel() { + const s = document.getElementById('variantSelect'); + return s.options[s.selectedIndex].text; +} function updateBoardInfo() { const b = board(); @@ -233,11 +247,13 @@

Jade Web Flasher

Layout${b.layout.length} files
`; document.getElementById('ciBoard').textContent = b.name; + document.getElementById('ciVariant').textContent = variantLabel(); document.getElementById('ciChip').textContent = b.chip; document.getElementById('ciFlash').textContent = `${b.flashMode} / ${b.flashFreq} / ${b.flashSize}`; document.getElementById('zipBoard').textContent = b.name; } document.getElementById('boardSelect').addEventListener('change', updateBoardInfo); +document.getElementById('variantSelect').addEventListener('change', updateBoardInfo); updateBoardInfo(); document.querySelectorAll('.tab-btn').forEach(btn => { @@ -425,18 +441,18 @@

Jade Web Flasher

} async function fetchCIFirmware() { - const bk = boardKey(); + const fwKey = firmwareKey(); const b = board(); const files = {}; let args = null; - const argsResp = await fetch(`./firmware/${bk}/flasher_args.json`); + const argsResp = await fetch(`./firmware/${fwKey}/flasher_args.json`); if (argsResp.ok) { args = await argsResp.json(); log('Loaded flasher_args.json.', 'ok'); const fileMap = args.flash_files || {}; for (const [offset, filePath] of Object.entries(fileMap)) { - const resp = await fetch(`./firmware/${bk}/${filePath}`); + const resp = await fetch(`./firmware/${fwKey}/${filePath}`); if (resp.ok) { files[filePath] = new Uint8Array(await resp.arrayBuffer()); log(` Loaded ${filePath} (offset ${offset})`); @@ -447,7 +463,7 @@

Jade Web Flasher

} else { log('Falling back to default layout.', 'warn'); for (const entry of b.layout) { - const resp = await fetch(`./firmware/${bk}/${entry.file}`); + const resp = await fetch(`./firmware/${fwKey}/${entry.file}`); if (resp.ok) { files[entry.file] = new Uint8Array(await resp.arrayBuffer()); log(` Loaded ${entry.file} (offset ${entry.offset})`); From 2e400095b77b8426ad39199164787c93d1068228 Mon Sep 17 00:00:00 2001 From: 3rdIteration Date: Tue, 7 Jul 2026 04:51:10 +1000 Subject: [PATCH 08/22] fix: change panic to reboot + longer INT WDT for debug build --- configs/sdkconfig_display_tdeck_debug.defaults | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configs/sdkconfig_display_tdeck_debug.defaults b/configs/sdkconfig_display_tdeck_debug.defaults index c015f45e7..80bb956fd 100644 --- a/configs/sdkconfig_display_tdeck_debug.defaults +++ b/configs/sdkconfig_display_tdeck_debug.defaults @@ -36,7 +36,8 @@ CONFIG_ESP_MAIN_TASK_STACK_SIZE=12288 CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=n CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND=n CONFIG_ESP_SYSTEM_BBPLL_RECALIB=n -CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=10000 CONFIG_ESP_TASK_WDT_EN=n CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=n CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=n From 3a4624c235917d230b3821523c1cdadc99308747 Mon Sep 17 00:00:00 2001 From: 3rdIteration Date: Tue, 7 Jul 2026 04:59:53 +1000 Subject: [PATCH 09/22] fix: add TinyUSB back to debug config (PHY init required for USB-JTAG) --- configs/sdkconfig_display_tdeck_debug.defaults | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/sdkconfig_display_tdeck_debug.defaults b/configs/sdkconfig_display_tdeck_debug.defaults index 80bb956fd..8bac9347b 100644 --- a/configs/sdkconfig_display_tdeck_debug.defaults +++ b/configs/sdkconfig_display_tdeck_debug.defaults @@ -81,5 +81,7 @@ CONFIG_SPIRAM_RODATA=y CONFIG_SPIRAM_SPEED_80M=y CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y CONFIG_SPI_FLASH_VERIFY_WRITE=y +CONFIG_TINYUSB_CDC_ENABLED=y +CONFIG_TINYUSB_CDC_RX_BUFSIZE=64 CONFIG_SPI_MASTER_ISR_IN_IRAM=n CONFIG_SPI_SLAVE_ISR_IN_IRAM=n From bb716c7905769d3707e0e5c8a65ad238031b2649 Mon Sep 17 00:00:00 2001 From: 3rd Iteration Date: Mon, 6 Jul 2026 15:19:16 -0400 Subject: [PATCH 10/22] fix: stop esptool-js patching bootloader header (ets_loader.c 78 bootloop) Passing explicit flashMode/flashFreq/flashSize makes esptool-js patch the bootloader image header in flash without recomputing the appended SHA-256 digest. The ESP32-S3 ROM verifies that digest when loading the second-stage bootloader, rejects the image (ets_loader.c 78) and the device bootloops. Use 'keep' so the image is written byte-identical to the build output. Co-Authored-By: Claude Fable 5 --- flasher/index.html | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/flasher/index.html b/flasher/index.html index 1eade5dca..fc0ee7231 100644 --- a/flasher/index.html +++ b/flasher/index.html @@ -202,9 +202,12 @@

Jade Web Flasher

tdeck: { name: 'LilyGO T-Deck', chip: 'ESP32-S3', - flashMode: 'qio', - flashFreq: '80m', - flashSize: '16MB', + // 'keep' is required: esptool-js patches the bootloader header when a + // mode/freq/size is given, but does not recompute the appended SHA-256, + // and the ESP32-S3 ROM rejects the image (ets_loader.c 78 bootloop). + flashMode: 'keep', + flashFreq: 'keep', + flashSize: 'keep', layout: [ { offset: '0x0', file: 'bootloader.bin' }, { offset: '0x8000', file: 'partition-table.bin' }, From 1c79e68ecd8ff275666b440f9005a8a7249078af Mon Sep 17 00:00:00 2001 From: 3rd Iteration Date: Mon, 6 Jul 2026 15:21:49 -0400 Subject: [PATCH 11/22] fix: tdeck backlight turned off for all valid brightness levels power_backlight_on() scaled brightness as a 0-255 value, but Jade passes levels BACKLIGHT_MIN..BACKLIGHT_MAX (1..5), so the result was always 0 and the backlight switched off as soon as the stored brightness was applied after boot. Clamp and map levels 1..5 linearly onto dimmer steps 1..16. Co-Authored-By: Claude Fable 5 --- main/power/tdeck.inc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/main/power/tdeck.inc b/main/power/tdeck.inc index 0715a2c2d..4f0a55f7a 100644 --- a/main/power/tdeck.inc +++ b/main/power/tdeck.inc @@ -84,9 +84,17 @@ esp_err_t power_shutdown(void) esp_err_t power_screen_on(void) { return ESP_OK; } esp_err_t power_screen_off(void) { return ESP_OK; } -esp_err_t power_backlight_on(const uint8_t brightness) +esp_err_t power_backlight_on(uint8_t brightness) { - const uint8_t scaled = (brightness * BACKLIGHT_STEPS) / 255; + // Brightness is a level BACKLIGHT_MIN (1) to BACKLIGHT_MAX (5), + // mapped linearly onto dimmer steps 1 to BACKLIGHT_STEPS. + if (brightness < BACKLIGHT_MIN) { + brightness = BACKLIGHT_MIN; + } else if (brightness > BACKLIGHT_MAX) { + brightness = BACKLIGHT_MAX; + } + const uint8_t scaled + = 1 + ((BACKLIGHT_STEPS - 1) * (brightness - BACKLIGHT_MIN)) / (BACKLIGHT_MAX - BACKLIGHT_MIN); set_backlight(scaled); return ESP_OK; } From f601a74263f2267b20bcbb6f51d057b4445327ee Mon Sep 17 00:00:00 2001 From: 3rd Iteration Date: Mon, 6 Jul 2026 15:23:27 -0400 Subject: [PATCH 12/22] refactor: simplify tdeck backlight to plain GPIO on/off for debugging Drop the pulse-train step dimmer; drive the backlight GPIO high for any requested brightness level and low for off. Level-based dimming can be reinstated once the display path is proven out. Co-Authored-By: Claude Fable 5 --- main/power/tdeck.inc | 46 +++++--------------------------------------- 1 file changed, 5 insertions(+), 41 deletions(-) diff --git a/main/power/tdeck.inc b/main/power/tdeck.inc index 4f0a55f7a..29cd130f4 100644 --- a/main/power/tdeck.inc +++ b/main/power/tdeck.inc @@ -1,7 +1,6 @@ #include "jade_assert.h" #include -#include #include #include #include @@ -11,7 +10,6 @@ #define BOARD_POWERON_GPIO 10 #define BACKLIGHT_GPIO 42 -#define BACKLIGHT_STEPS 16 #define BATTERY_ADC_CHANNEL ADC_CHANNEL_3 #define BATTERY_ADC_ATTEN ADC_ATTEN_DB_12 @@ -20,33 +18,6 @@ static adc_oneshot_unit_handle_t adc1_handle = NULL; static adc_cali_handle_t adc1_cali_chan0_handle = NULL; static float ema_voltage = 0.0f; -static uint8_t bl_level = 0; - -static void set_backlight(uint8_t value) -{ - if (value > BACKLIGHT_STEPS) { - value = BACKLIGHT_STEPS; - } - if (value == 0) { - gpio_set_level(BACKLIGHT_GPIO, 0); - esp_rom_delay_us(3000); - bl_level = 0; - return; - } - if (bl_level == 0) { - gpio_set_level(BACKLIGHT_GPIO, 1); - bl_level = BACKLIGHT_STEPS; - esp_rom_delay_us(30); - } - const int from = BACKLIGHT_STEPS - bl_level; - const int to = BACKLIGHT_STEPS - value; - const int num = (BACKLIGHT_STEPS + to - from) % BACKLIGHT_STEPS; - for (int i = 0; i < num; i++) { - gpio_set_level(BACKLIGHT_GPIO, 0); - gpio_set_level(BACKLIGHT_GPIO, 1); - } - bl_level = value; -} esp_err_t power_init(void) { @@ -84,24 +55,17 @@ esp_err_t power_shutdown(void) esp_err_t power_screen_on(void) { return ESP_OK; } esp_err_t power_screen_off(void) { return ESP_OK; } -esp_err_t power_backlight_on(uint8_t brightness) +esp_err_t power_backlight_on(const uint8_t brightness) { - // Brightness is a level BACKLIGHT_MIN (1) to BACKLIGHT_MAX (5), - // mapped linearly onto dimmer steps 1 to BACKLIGHT_STEPS. - if (brightness < BACKLIGHT_MIN) { - brightness = BACKLIGHT_MIN; - } else if (brightness > BACKLIGHT_MAX) { - brightness = BACKLIGHT_MAX; - } - const uint8_t scaled - = 1 + ((BACKLIGHT_STEPS - 1) * (brightness - BACKLIGHT_MIN)) / (BACKLIGHT_MAX - BACKLIGHT_MIN); - set_backlight(scaled); + // On/off only for now: any requested brightness level lights the display. + (void)brightness; + gpio_set_level(BACKLIGHT_GPIO, 1); return ESP_OK; } esp_err_t power_backlight_off(void) { - set_backlight(0); + gpio_set_level(BACKLIGHT_GPIO, 0); return ESP_OK; } From 91178cd3dbeae87b15e361ab41f166cebcafc965 Mon Sep 17 00:00:00 2001 From: 3rd Iteration Date: Mon, 6 Jul 2026 15:49:03 -0400 Subject: [PATCH 13/22] feat: reinstate tdeck stepped backlight with corrected level mapping Restore the pulse-step dimmer, mapping Jade brightness levels BACKLIGHT_MIN..BACKLIGHT_MAX (1..5) linearly onto dimmer steps 1..16 (the earlier code scaled as if brightness were 0-255, always yielding 0). Add short delays around the step pulses to respect dimmer timing. Co-Authored-By: Claude Fable 5 --- main/power/tdeck.inc | 49 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/main/power/tdeck.inc b/main/power/tdeck.inc index 29cd130f4..ceacd3951 100644 --- a/main/power/tdeck.inc +++ b/main/power/tdeck.inc @@ -1,6 +1,7 @@ #include "jade_assert.h" #include +#include #include #include #include @@ -10,6 +11,7 @@ #define BOARD_POWERON_GPIO 10 #define BACKLIGHT_GPIO 42 +#define BACKLIGHT_STEPS 16 #define BATTERY_ADC_CHANNEL ADC_CHANNEL_3 #define BATTERY_ADC_ATTEN ADC_ATTEN_DB_12 @@ -18,6 +20,36 @@ static adc_oneshot_unit_handle_t adc1_handle = NULL; static adc_cali_handle_t adc1_cali_chan0_handle = NULL; static float ema_voltage = 0.0f; +static uint8_t bl_level = 0; + +// The backlight dimmer starts at full brightness on a rising edge after +// being off, and each short low pulse steps it down one level (wrapping +// back to max). Holding the line low for >2.5ms shuts it down. +static void set_backlight(uint8_t value) +{ + if (value > BACKLIGHT_STEPS) { + value = BACKLIGHT_STEPS; + } + if (value == 0) { + gpio_set_level(BACKLIGHT_GPIO, 0); + esp_rom_delay_us(3000); + bl_level = 0; + return; + } + if (bl_level == 0) { + gpio_set_level(BACKLIGHT_GPIO, 1); + esp_rom_delay_us(30); + bl_level = BACKLIGHT_STEPS; + } + const int num = (BACKLIGHT_STEPS + bl_level - value) % BACKLIGHT_STEPS; + for (int i = 0; i < num; i++) { + gpio_set_level(BACKLIGHT_GPIO, 0); + esp_rom_delay_us(1); + gpio_set_level(BACKLIGHT_GPIO, 1); + esp_rom_delay_us(1); + } + bl_level = value; +} esp_err_t power_init(void) { @@ -55,17 +87,24 @@ esp_err_t power_shutdown(void) esp_err_t power_screen_on(void) { return ESP_OK; } esp_err_t power_screen_off(void) { return ESP_OK; } -esp_err_t power_backlight_on(const uint8_t brightness) +esp_err_t power_backlight_on(uint8_t brightness) { - // On/off only for now: any requested brightness level lights the display. - (void)brightness; - gpio_set_level(BACKLIGHT_GPIO, 1); + // Brightness is a level BACKLIGHT_MIN (1) to BACKLIGHT_MAX (5), + // mapped linearly onto dimmer steps 1 to BACKLIGHT_STEPS. + if (brightness < BACKLIGHT_MIN) { + brightness = BACKLIGHT_MIN; + } else if (brightness > BACKLIGHT_MAX) { + brightness = BACKLIGHT_MAX; + } + const uint8_t scaled + = 1 + ((BACKLIGHT_STEPS - 1) * (brightness - BACKLIGHT_MIN)) / (BACKLIGHT_MAX - BACKLIGHT_MIN); + set_backlight(scaled); return ESP_OK; } esp_err_t power_backlight_off(void) { - gpio_set_level(BACKLIGHT_GPIO, 0); + set_backlight(0); return ESP_OK; } From ab4399a03c2f62d81504e900c419b9191af3b9f4 Mon Sep 17 00:00:00 2001 From: 3rd Iteration Date: Mon, 6 Jul 2026 15:49:03 -0400 Subject: [PATCH 14/22] fix: treat tdeck trackball as edge-triggered scroll, not buttons The trackball direction lines toggle level once per step of ball travel; driving them through iot_button meant that whenever a line came to rest low the driver saw a held button and fired LONG_PRESS_HOLD forever, causing runaway scrolling until the ball was nudged. Handle all four direction lines with ANYEDGE GPIO interrupts feeding a queue/watcher task (same pattern as the Jade v1 wheel), with a 2ms debounce. Also wire up the previously unused up/down lines: up scrolls prev, down scrolls next, matching forward/back in vertical UI contexts. Co-Authored-By: Claude Fable 5 --- main/input/tdeck.inc | 85 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 69 insertions(+), 16 deletions(-) diff --git a/main/input/tdeck.inc b/main/input/tdeck.inc index 442688218..2a3ec0fae 100644 --- a/main/input/tdeck.inc +++ b/main/input/tdeck.inc @@ -7,6 +7,7 @@ #include #include +#include #define BOARD_POWERON_GPIO 10 #define KB_I2C_ADDR 0x55 @@ -14,8 +15,14 @@ #define TB_LEFT_GPIO 1 #define TB_RIGHT_GPIO 2 +#define TB_UP_GPIO 3 +#define TB_DOWN_GPIO 15 #define TB_PRESS_GPIO 0 +// Ignore edges arriving faster than this - filters contact noise and +// caps the overall scroll rate +#define TB_DEBOUNCE_US 2000 + static void tdeck_keyboard_task(void* unused) { gpio_set_direction(BOARD_POWERON_GPIO, GPIO_MODE_OUTPUT); @@ -60,10 +67,46 @@ static void tdeck_keyboard_task(void* unused) vTaskDelete(NULL); } -static void tb_left_trigger(void* arg, void* ctx) { gui_prev(); } -static void tb_right_trigger(void* arg, void* ctx) { gui_next(); } static void tb_press_trigger(void* arg, void* ctx) { gui_front_click(); } +// The trackball direction outputs are not buttons - each line toggles +// level once per step of ball travel, so treat every edge as one scroll +// increment (the resting level of a line is arbitrary). +typedef enum { TB_NAV_PREV, TB_NAV_NEXT } tb_nav_t; + +static QueueHandle_t tb_queue = NULL; + +static void tb_isr(void* arg) +{ + static int64_t last_event_us = 0; + const int64_t now = esp_timer_get_time(); + if (now - last_event_us < TB_DEBOUNCE_US) { + return; + } + last_event_us = now; + + const tb_nav_t nav = (tb_nav_t)(uintptr_t)arg; + BaseType_t higher_priority_woken = pdFALSE; + xQueueSendFromISR(tb_queue, &nav, &higher_priority_woken); + if (higher_priority_woken == pdTRUE) { + portYIELD_FROM_ISR(); + } +} + +static void tdeck_trackball_task(void* unused) +{ + for (;;) { + tb_nav_t nav; + if (xQueueReceive(tb_queue, &nav, portMAX_DELAY) == pdTRUE) { + if (nav == TB_NAV_PREV) { + gui_prev(); + } else { + gui_next(); + } + } + } +} + void navigation_init(void) { BaseType_t retval = xTaskCreatePinnedToCore( @@ -71,25 +114,35 @@ void navigation_init(void) JADE_ASSERT_MSG(retval == pdPASS, "Failed to create tdeck_keyboard task, xTaskCreatePinnedToCore() returned %d", retval); + tb_queue = xQueueCreate(8, sizeof(tb_nav_t)); + JADE_ASSERT(tb_queue); + + retval = xTaskCreatePinnedToCore( + &tdeck_trackball_task, "tdeck_tball", 2 * 1024, NULL, JADE_TASK_PRIO_WHEEL, NULL, JADE_CORE_SECONDARY); + JADE_ASSERT_MSG(retval == pdPASS, "Failed to create tdeck_trackball task, xTaskCreatePinnedToCore() returned %d", + retval); + + const gpio_config_t tb_cfg = { + .pin_bit_mask = (1ULL << TB_LEFT_GPIO) | (1ULL << TB_RIGHT_GPIO) | (1ULL << TB_UP_GPIO) + | (1ULL << TB_DOWN_GPIO), + .mode = GPIO_MODE_INPUT, + .pull_up_en = GPIO_PULLUP_ENABLE, + .intr_type = GPIO_INTR_ANYEDGE, + }; + ESP_ERROR_CHECK(gpio_config(&tb_cfg)); + + const esp_err_t rc = gpio_install_isr_service(0); + JADE_ASSERT(rc == ESP_OK || rc == ESP_ERR_INVALID_STATE); + ESP_ERROR_CHECK(gpio_isr_handler_add(TB_LEFT_GPIO, tb_isr, (void*)(uintptr_t)TB_NAV_PREV)); + ESP_ERROR_CHECK(gpio_isr_handler_add(TB_UP_GPIO, tb_isr, (void*)(uintptr_t)TB_NAV_PREV)); + ESP_ERROR_CHECK(gpio_isr_handler_add(TB_RIGHT_GPIO, tb_isr, (void*)(uintptr_t)TB_NAV_NEXT)); + ESP_ERROR_CHECK(gpio_isr_handler_add(TB_DOWN_GPIO, tb_isr, (void*)(uintptr_t)TB_NAV_NEXT)); + const button_config_t btn_cfg = { .long_press_time = CONFIG_BUTTON_LONG_PRESS_TIME_MS, .short_press_time = CONFIG_BUTTON_SHORT_PRESS_TIME_MS, }; - button_handle_t btn_left = NULL; - const button_gpio_config_t left_gpio_cfg = { .gpio_num = TB_LEFT_GPIO, .active_level = 0 }; - ESP_ERROR_CHECK(iot_button_new_gpio_device(&btn_cfg, &left_gpio_cfg, &btn_left)); - JADE_ASSERT(btn_left); - ESP_ERROR_CHECK(iot_button_register_cb(btn_left, BUTTON_PRESS_DOWN, NULL, tb_left_trigger, NULL)); - ESP_ERROR_CHECK(iot_button_register_cb(btn_left, BUTTON_LONG_PRESS_HOLD, NULL, tb_left_trigger, NULL)); - - button_handle_t btn_right = NULL; - const button_gpio_config_t right_gpio_cfg = { .gpio_num = TB_RIGHT_GPIO, .active_level = 0 }; - ESP_ERROR_CHECK(iot_button_new_gpio_device(&btn_cfg, &right_gpio_cfg, &btn_right)); - JADE_ASSERT(btn_right); - ESP_ERROR_CHECK(iot_button_register_cb(btn_right, BUTTON_PRESS_DOWN, NULL, tb_right_trigger, NULL)); - ESP_ERROR_CHECK(iot_button_register_cb(btn_right, BUTTON_LONG_PRESS_HOLD, NULL, tb_right_trigger, NULL)); - button_handle_t btn_press = NULL; const button_gpio_config_t press_gpio_cfg = { .gpio_num = TB_PRESS_GPIO, .active_level = 0 }; ESP_ERROR_CHECK(iot_button_new_gpio_device(&btn_cfg, &press_gpio_cfg, &btn_press)); From b15b49f7315229c2a8c9b184205d6bd5abbc851f Mon Sep 17 00:00:00 2001 From: 3rd Iteration Date: Mon, 6 Jul 2026 16:03:02 -0400 Subject: [PATCH 15/22] fix: physical keyboard handling in mnemonic entry + trackball sensitivity Mnemonic word entry only understood the on-screen keyboard: - letters: the screen posts uppercase A-Z, but the T-Deck keyboard sends lowercase ascii, so typed letters were ignored; accept either case - enter: the on-screen enter button is inactive during mnemonic entry, but a physical keyboard can post BTN_KEYBOARD_ENTER at any time, which set done_entering_words early and tripped the words_entered==nwords assert (mnemonic.c:865); only honour enter when the on-screen button would be active - letter validity: the on-screen keyboard disables letters that match no word, a physical keyboard cannot - reject letters yielding a stem with no matching words (previously would trip the possible_words>0 assert) Also halve trackball sensitivity: require 2 edges per scroll step, with the accumulator reset on direction change or a 300ms pause. Co-Authored-By: Claude Fable 5 --- main/input/tdeck.inc | 21 ++++++++++++++++++++- main/process/mnemonic.c | 21 ++++++++++++++++----- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/main/input/tdeck.inc b/main/input/tdeck.inc index 2a3ec0fae..5fb3bbc16 100644 --- a/main/input/tdeck.inc +++ b/main/input/tdeck.inc @@ -23,6 +23,12 @@ // caps the overall scroll rate #define TB_DEBOUNCE_US 2000 +// Edges required per scroll step - raise to reduce sensitivity +#define TB_EDGES_PER_EVENT 2 + +// Edges further apart than this do not accumulate towards a step +#define TB_GESTURE_TIMEOUT_US 300000 + static void tdeck_keyboard_task(void* unused) { gpio_set_direction(BOARD_POWERON_GPIO, GPIO_MODE_OUTPUT); @@ -79,13 +85,26 @@ static QueueHandle_t tb_queue = NULL; static void tb_isr(void* arg) { static int64_t last_event_us = 0; + static tb_nav_t last_nav = TB_NAV_PREV; + static uint8_t edge_count = 0; + const int64_t now = esp_timer_get_time(); - if (now - last_event_us < TB_DEBOUNCE_US) { + const int64_t elapsed = now - last_event_us; + if (elapsed < TB_DEBOUNCE_US) { return; } last_event_us = now; const tb_nav_t nav = (tb_nav_t)(uintptr_t)arg; + if (nav != last_nav || elapsed > TB_GESTURE_TIMEOUT_US) { + last_nav = nav; + edge_count = 0; + } + if (++edge_count < TB_EDGES_PER_EVENT) { + return; + } + edge_count = 0; + BaseType_t higher_priority_woken = pdFALSE; xQueueSendFromISR(tb_queue, &nav, &higher_priority_woken); if (higher_priority_woken == pdTRUE) { diff --git a/main/process/mnemonic.c b/main/process/mnemonic.c index db726f90b..671197094 100644 --- a/main/process/mnemonic.c +++ b/main/process/mnemonic.c @@ -818,13 +818,24 @@ static size_t get_wordlist_words( // Wait for kb button click gui_activity_wait_event(enter_word_activity, GUI_BUTTON_EVENT, ESP_EVENT_ANY_ID, NULL, &ev_id, NULL, 0); selected_backspace = (ev_id == BTN_KEYBOARD_BACKSPACE); - done_entering_words = (ev_id == BTN_KEYBOARD_ENTER); - if (!selected_backspace && !done_entering_words) { - // Character/letter was clicked - const char letter_selected = ev_id - BTN_KEYBOARD_ASCII_OFFSET; + // A physical keyboard can send 'enter' at any time - only honour it + // where the on-screen enter button would be active (see enable_relevant_chars) + done_entering_words = (ev_id == BTN_KEYBOARD_ENTER && !is_mnemonic && !char_index); + if (!selected_backspace && ev_id >= BTN_KEYBOARD_ASCII_OFFSET) { + // Character/letter was clicked/typed (physical keyboards send lowercase) + const char letter_selected = toupper((int)(ev_id - BTN_KEYBOARD_ASCII_OFFSET)); if (letter_selected >= 'A' && letter_selected <= 'Z') { + // Only accept a letter if some word still matches the new stem - + // the on-screen keyboard disables impossible letters, but a + // physical keyboard cannot word[char_index] = tolower(letter_selected); - word[++char_index] = '\0'; + word[char_index + 1] = '\0'; + if (valid_words(word, char_index + 1, p_filter_words, num_filter_words, possible_word_list, + NUM_WORDS_SELECT, &exact_match)) { + ++char_index; + } else { + word[char_index] = '\0'; + } } } } From be9e8a2ebf3159e9d46798e7668542dc65305619 Mon Sep 17 00:00:00 2001 From: 3rd Iteration Date: Mon, 6 Jul 2026 16:25:34 -0400 Subject: [PATCH 16/22] feat: qwerty on-screen keyboards for devices with a physical keyboard Add HAS_KEYBOARD config (selected by the T-Deck board) and lay out the on-screen keyboards qwerty to match the physical keys: the mnemonic word-entry keyboard and the upper/lower-case passphrase keyboards. The passphrase space key moves to the end of the middle row as qwerty needs all ten bottom-row columns for zxcvbnm plus the control keys. Co-Authored-By: Claude Fable 5 --- main/Kconfig.projbuild | 7 +++++++ main/ui/keyboard.c | 13 +++++++++++++ main/ui/mnemonic.c | 7 +++++++ 3 files changed, 27 insertions(+) diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index 0bd442942..741669d20 100644 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -110,6 +110,7 @@ menu "Blockstream Jade" config BOARD_TYPE_TDECK bool "LilyGO T-Deck (keyboard + trackball)" select HAS_BATTERY + select HAS_KEYBOARD config BOARD_TYPE_TTGO_TWATCHS3 bool "TTGO T-WATCH S3" select HAS_AXP @@ -323,6 +324,12 @@ menu "Blockstream Jade" Enables USB JTAG serial rather than CDC tinyusb, implies no tinyusb/host storage/etc default n + config HAS_KEYBOARD + bool "Device has a physical keyboard" + help + Device has a physical qwerty keyboard - on-screen keyboards + are laid out qwerty to match + config HAS_BATTERY bool "Enable Battery Functions" help diff --git a/main/ui/keyboard.c b/main/ui/keyboard.c index 6d14dfd00..64ac7fb4b 100644 --- a/main/ui/keyboard.c +++ b/main/ui/keyboard.c @@ -40,14 +40,27 @@ static void make_keyboard_screen(link_activity_t* kb_screen_activity, const char // NOTE: final three characters ('|', '>', 'S') are rendered in different symbols fonts // and are buttons for 'backspace', 'shift/next kb', and 'enter/done' (see below) if (kb_type == KB_LOWER_CASE_CHARS) { +#ifdef CONFIG_HAS_KEYBOARD + // Match the physical keyboard layout (space key ends the middle row) + lines[0] = "qwertyuiop"; + lines[1] = "asdfghjkl "; + lines[2] = "zxcvbnm|>S"; +#else lines[0] = "abcdefghij"; lines[1] = "klmnopqrst"; lines[2] = "uvwxyz |>S"; +#endif // 'sizes' ok } else if (kb_type == KB_UPPER_CASE_CHARS) { +#ifdef CONFIG_HAS_KEYBOARD + lines[0] = "QWERTYUIOP"; + lines[1] = "ASDFGHJKL "; + lines[2] = "ZXCVBNM|>S"; +#else lines[0] = "ABCDEFGHIJ"; lines[1] = "KLMNOPQRST"; lines[2] = "UVWXYZ |>S"; +#endif // 'sizes' ok } else if (kb_type == KB_NUMBERS_SYMBOLS) { lines[0] = "1234567890"; diff --git a/main/ui/mnemonic.c b/main/ui/mnemonic.c index a50aded48..6838f331c 100644 --- a/main/ui/mnemonic.c +++ b/main/ui/mnemonic.c @@ -290,9 +290,16 @@ gui_activity_t* make_enter_wordlist_word_activity(gui_view_node_t** titletext, c // second row, keyboard char* lines[NUM_KEYBOARD_ROWS]; +#ifdef CONFIG_HAS_KEYBOARD + // Match the physical keyboard layout + lines[0] = (char[]){ 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P' }; + lines[1] = (char[]){ 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L' }; + lines[2] = (char[]){ 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ' ', '|' }; +#else lines[0] = (char[]){ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J' }; lines[1] = (char[]){ 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S' }; lines[2] = (char[]){ 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', '|' }; +#endif const size_t sizes[NUM_KEYBOARD_ROWS] = { 10, 9, 9 }; JADE_ASSERT(CONFIG_DISPLAY_WIDTH >= 240); From e056c0f9eee96c2f61847274aaffe39e41c8f276 Mon Sep 17 00:00:00 2001 From: 3rd Iteration Date: Mon, 6 Jul 2026 16:53:30 -0400 Subject: [PATCH 17/22] feat: blind passphrase confirmation + PIN entry via physical keyboard Passphrase: replace the show-and-confirm (Yes/No) screen with a second, deliberately blank, keyboard entry titled Confirm Passphrase; the two entries are compared and a mismatch restarts entry from scratch. The old display-confirm activity is removed, and both entry buffers are registered with the sensitive-data stack. PIN/number entry: accept physical keyboard input alongside the wheel. Adds gui_activity_wait_event_of_either_base() so the digit-entry loop can wait on gui navigation and keyboard button events simultaneously. Digits accepted as ascii 0-9 plus the letter keys with digits printed on them on the T-Deck (w,e,r,s,d,f,z,x,c = 1-9); backspace steps back (abandoning entry on the first digit), enter completes index entry. Also log raw keyboard bytes at DEBUG level to identify unmapped keys (eg. the mic key, which carries the printed 0). Co-Authored-By: Claude Fable 5 --- main/gui.c | 25 ++++++++++++++ main/gui.h | 3 ++ main/input/tdeck.inc | 1 + main/process/mnemonic.c | 36 +++++++++++++------ main/ui/digit_entry.c | 76 +++++++++++++++++++++++++++++++++++++++++ main/ui/mnemonic.c | 28 --------------- 6 files changed, 130 insertions(+), 39 deletions(-) diff --git a/main/gui.c b/main/gui.c index 4c6b3ef2b..75ec00ed1 100644 --- a/main/gui.c +++ b/main/gui.c @@ -2767,6 +2767,31 @@ bool gui_activity_wait_event(gui_activity_t* activity, const char* event_base, u return ret == ESP_OK; } +// As gui_activity_wait_event, but registered for (any event id of) two event bases, +// eg. to wait on gui navigation events and keyboard button events at the same time. +bool gui_activity_wait_event_of_either_base(gui_activity_t* activity, const char* event_base1, + const char* event_base2, esp_event_base_t* trigger_event_base, int32_t* trigger_event_id, + void** trigger_event_data, const TickType_t max_wait) +{ + JADE_ASSERT(activity); + JADE_ASSERT(event_base1); + JADE_ASSERT(event_base2); + + // create a new wait-event-data structure and attach to the activity, which takes ownership + wait_event_data_t* const wait_event_data = gui_activity_make_wait_event_data(activity); + JADE_ASSERT(wait_event_data); + + // register both bases against the same wait data so either can wake the caller + gui_activity_register_event(activity, event_base1, ESP_EVENT_ANY_ID, sync_wait_event_handler, wait_event_data); + gui_activity_register_event(activity, event_base2, ESP_EVENT_ANY_ID, sync_wait_event_handler, wait_event_data); + + // immediately start waiting + const esp_err_t ret + = sync_wait_event(wait_event_data, trigger_event_base, trigger_event_id, trigger_event_data, max_wait); + + return ret == ESP_OK; +} + int32_t gui_activity_wait_button(gui_activity_t* activity, const int32_t default_event_id) { int32_t ev_id = default_event_id; diff --git a/main/gui.h b/main/gui.h index 96e4f6624..15b146072 100644 --- a/main/gui.h +++ b/main/gui.h @@ -470,6 +470,9 @@ void gui_activity_register_event( gui_activity_t* activity, const char* event_base, uint32_t event_id, esp_event_handler_t handler, void* args); bool gui_activity_wait_event(gui_activity_t* activity, const char* event_base, uint32_t event_id, esp_event_base_t* trigger_event_base, int32_t* trigger_event_id, void** trigger_event_data, TickType_t max_wait); +bool gui_activity_wait_event_of_either_base(gui_activity_t* activity, const char* event_base1, + const char* event_base2, esp_event_base_t* trigger_event_base, int32_t* trigger_event_id, + void** trigger_event_data, TickType_t max_wait); int32_t gui_activity_wait_button(gui_activity_t* activity, int32_t default_event_id); void gui_set_activity_initial_selection(gui_view_node_t* node); diff --git a/main/input/tdeck.inc b/main/input/tdeck.inc index 5fb3bbc16..a438b38c4 100644 --- a/main/input/tdeck.inc +++ b/main/input/tdeck.inc @@ -59,6 +59,7 @@ static void tdeck_keyboard_task(void* unused) uint8_t key_byte = 0; const esp_err_t ret = i2c_master_receive(kb_i2c_dev, &key_byte, 1, KB_I2C_TIMEOUT_MS); if (ret == ESP_OK && key_byte != 0) { + JADE_LOGD("keyboard key 0x%02x", key_byte); if (key_byte == 0x0D) { esp_event_post(GUI_BUTTON_EVENT, BTN_KEYBOARD_ENTER, NULL, 0, portMAX_DELAY); } else if (key_byte == 0x08) { diff --git a/main/process/mnemonic.c b/main/process/mnemonic.c index 671197094..9ae56d930 100644 --- a/main/process/mnemonic.c +++ b/main/process/mnemonic.c @@ -47,7 +47,6 @@ gui_activity_t* make_enter_wordlist_word_activity(gui_view_node_t** titletext, b size_t keys_len); gui_activity_t* make_calculate_final_word_activity(void); -gui_activity_t* make_confirm_passphrase_activity(const char* passphrase, gui_view_node_t** textbox); gui_activity_t* make_export_qr_overview_activity(const Icon* icon, bool initial); gui_activity_t* make_export_qr_fragment_activity( @@ -1190,13 +1189,9 @@ static void get_freetext_passphrase(char* passphrase, const size_t passphrase_le JADE_ASSERT(passphrase_len); passphrase[0] = '\0'; - // We will need this activity later when confirming - gui_view_node_t* text_to_confirm = NULL; - gui_activity_t* const confirm_passphrase_activity = make_confirm_passphrase_activity(passphrase, &text_to_confirm); - int32_t ev_id; - // For passphrase we want all 4 keyboards keyboard_entry_t kb_entry = { .max_allowed_len = passphrase_len - 1 }; + SENSITIVE_PUSH(kb_entry.strdata, sizeof(kb_entry.strdata)); kb_entry.keyboards[0] = KB_LOWER_CASE_CHARS; kb_entry.keyboards[1] = KB_UPPER_CASE_CHARS; kb_entry.keyboards[2] = KB_NUMBERS_SYMBOLS; @@ -1206,20 +1201,39 @@ static void get_freetext_passphrase(char* passphrase, const size_t passphrase_le make_keyboard_entry_activity(&kb_entry, "Enter Passphrase"); JADE_ASSERT(kb_entry.activity); + // A second, deliberately blank, entry screen to confirm by blind re-entry + // (do not display or pre-populate with the initial entry) + keyboard_entry_t kb_confirm = { .max_allowed_len = passphrase_len - 1 }; + SENSITIVE_PUSH(kb_confirm.strdata, sizeof(kb_confirm.strdata)); + memcpy(kb_confirm.keyboards, kb_entry.keyboards, sizeof(kb_entry.keyboards)); + kb_confirm.num_kbs = kb_entry.num_kbs; + + make_keyboard_entry_activity(&kb_confirm, "Confirm Passphrase"); + JADE_ASSERT(kb_confirm.activity); + bool done = false; while (!done) { // Run the keyboard entry loop to get a typed passphrase run_keyboard_entry_loop(&kb_entry); - // Ask user to confirm passphrase - gui_update_text(text_to_confirm, kb_entry.len > 0 ? kb_entry.strdata : ""); - gui_set_current_activity(confirm_passphrase_activity); - gui_activity_wait_event(confirm_passphrase_activity, GUI_BUTTON_EVENT, ESP_EVENT_ANY_ID, NULL, &ev_id, NULL, 0); - done = (ev_id == BTN_YES); + // Ask user to re-enter the passphrase to confirm + kb_confirm.strdata[0] = '\0'; + kb_confirm.len = 0; + run_keyboard_entry_loop(&kb_confirm); + + done = (kb_entry.len == kb_confirm.len) && !strcmp(kb_entry.strdata, kb_confirm.strdata); + if (!done) { + // Mismatch - start over from scratch + await_error_2("Passphrases do not", "match - please retry"); + kb_entry.strdata[0] = '\0'; + kb_entry.len = 0; + } } JADE_ASSERT(kb_entry.len < passphrase_len); strcpy(passphrase, kb_entry.strdata); + SENSITIVE_POP(kb_confirm.strdata); + SENSITIVE_POP(kb_entry.strdata); } void get_passphrase(char* passphrase, const size_t passphrase_len) diff --git a/main/ui/digit_entry.c b/main/ui/digit_entry.c index c6e2ee84b..7e0b9bd99 100644 --- a/main/ui/digit_entry.c +++ b/main/ui/digit_entry.c @@ -4,6 +4,11 @@ #include "../random.h" #include "../ui.h" +#ifdef CONFIG_HAS_KEYBOARD +#include +#include +#endif + #define CHAR_BACKSPACE '|' #define CHAR_ENTER '~' static const char ENTRY_CHARS[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', CHAR_BACKSPACE, CHAR_ENTER }; @@ -202,6 +207,63 @@ static bool prev_selected_digit(digit_entry_t* digit_entry) return true; } +#ifdef CONFIG_HAS_KEYBOARD +// Map physical key events to digits. Accept actual ascii digits, plus the +// letter keys which have digits printed on them on the T-Deck keyboard: +// w=1 e=2 r=3 s=4 d=5 f=6 z=7 x=8 c=9 (0 is on the mic key). +static int keyboard_event_digit(const int32_t ev_id) +{ + static const char digit_key_aliases[] = "wersdfzxc"; // 1-9 + + if (ev_id <= BTN_KEYBOARD_ASCII_OFFSET) { + return -1; + } + const int ch = tolower(ev_id - BTN_KEYBOARD_ASCII_OFFSET); + if (ch >= '0' && ch <= '9') { + return ch - '0'; + } + const char* const alias = strchr(digit_key_aliases, ch); + if (alias) { + return (alias - digit_key_aliases) + 1; + } + return -1; +} + +// Handle a physical keyboard event - returns true (with 'done' set) when +// entry is complete or abandoned, false to continue the entry loop. +static bool handle_keyboard_event(digit_entry_t* digit_entry, const int32_t ev_id, bool* done) +{ + JADE_ASSERT(digit_entry); + JADE_ASSERT(done); + + if (ev_id == BTN_KEYBOARD_BACKSPACE) { + if (!prev_selected_digit(digit_entry)) { + // Backspace on first digit - entry abandoned + *done = false; + return true; + } + } else if (ev_id == BTN_KEYBOARD_ENTER) { + // Only valid for 'index' entry (short numbers) - PIN requires all digits + if (digit_entry->entry_type == DIGIT_ENTRY_INDEX) { + // Enter on first digit abandons entry, otherwise completes it + *done = (digit_entry->selected_digit > 0); + return true; + } + } else { + const int digit = keyboard_event_digit(ev_id); + if (digit >= 0) { + digit_entry->current_selected_value = digit; + if (!next_selected_digit(digit_entry)) { + // Last digit typed - entry complete + *done = true; + return true; + } + } + } + return false; +} +#endif // CONFIG_HAS_KEYBOARD + // Returns true if number entry completes and digit_entry->digit is valid, // and false if number entry abandoned and digit_entry->digit is not to be used. bool run_digit_entry_loop(digit_entry_t* digit_entry) @@ -211,8 +273,22 @@ bool run_digit_entry_loop(digit_entry_t* digit_entry) int32_t ev_id; while (true) { +#ifdef CONFIG_HAS_KEYBOARD + // Wait for a GUI event or a physical keyboard event + esp_event_base_t ev_base = NULL; + gui_activity_wait_event_of_either_base( + digit_entry->activity, GUI_EVENT, GUI_BUTTON_EVENT, &ev_base, &ev_id, NULL, 0); + if (ev_base == GUI_BUTTON_EVENT) { + bool done = false; + if (handle_keyboard_event(digit_entry, ev_id, &done)) { + return done; + } + continue; + } +#else // wait for a GUI event gui_activity_wait_event(digit_entry->activity, GUI_EVENT, ESP_EVENT_ANY_ID, NULL, &ev_id, NULL, 0); +#endif if (entry_invert_navigation()) { // Swap left/right wheel events if (ev_id == GUI_WHEEL_LEFT_EVENT) { diff --git a/main/ui/mnemonic.c b/main/ui/mnemonic.c index 6838f331c..5b2f236b7 100644 --- a/main/ui/mnemonic.c +++ b/main/ui/mnemonic.c @@ -383,34 +383,6 @@ gui_activity_t* make_calculate_final_word_activity(void) return act; } -gui_activity_t* make_confirm_passphrase_activity(const char* passphrase, gui_view_node_t** textbox) -{ - JADE_ASSERT(passphrase); - JADE_INIT_OUT_PPTR(textbox); - - gui_activity_t* const act = gui_make_activity(); - gui_view_node_t* const parent = add_title_bar(act, "Confirm Passphrase", NULL, 0, NULL); - - gui_view_node_t* vsplit; - gui_make_vsplit(&vsplit, GUI_SPLIT_RELATIVE, 2, 70, 30); - gui_set_parent(vsplit, parent); - - // passphrase - gui_make_text(textbox, passphrase, TFT_WHITE); - gui_set_text_noise(*textbox, TFT_BLACK); - gui_set_parent(*textbox, vsplit); - - gui_set_padding(*textbox, GUI_MARGIN_ALL_DIFFERENT, 12, 2, 0, 4); - gui_set_align(*textbox, GUI_ALIGN_LEFT, GUI_ALIGN_TOP); - - // third row, Yes and No buttons - btn_data_t ftrbtns[] = { { .txt = "No", .font = GUI_DEFAULT_FONT, .ev_id = BTN_NO, .borders = GUI_BORDER_TOPRIGHT }, - { .txt = "Yes", .font = GUI_DEFAULT_FONT, .ev_id = BTN_YES, .borders = GUI_BORDER_TOPLEFT } }; - add_buttons(vsplit, UI_ROW, ftrbtns, 2); - - return act; -} - gui_activity_t* make_export_qr_overview_activity(const Icon* icon, const bool initial) { JADE_ASSERT(icon); From 693a985eac0f2c7f278ccebcd9740709f1399534 Mon Sep 17 00:00:00 2001 From: 3rd Iteration Date: Mon, 6 Jul 2026 20:02:38 -0400 Subject: [PATCH 18/22] fix: parseable firmware version, TDECK board type, SYM-mode PIN digits The CI shallow/tagless checkout (plus the git dubious-ownership error inside the IDF container) made git describe fail, so JADE_VERSION in get_version_info was "1". Companion apps parse this as semver against a minimum firmware version and refuse to proceed (endless get_version_info retries / "please reconnect your hardware wallet"). Fetch full history and tags, mark the workspace safe for git in the container, and log the version at build time. Also report BOARD_TYPE "TDECK" instead of "UNKNOWN", and simplify PIN entry keys to actual ascii digits only - the T-Deck keyboard sends these with the SYM modifier held, so the letter-alias mapping is unnecessary. Co-Authored-By: Claude Fable 5 --- .github/workflows/build.yml | 5 +++++ main/process/ota_defines.h | 2 ++ main/ui/digit_entry.c | 17 +++-------------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c2ef06dea..5691fab04 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,11 +19,16 @@ jobs: - uses: actions/checkout@v4 with: submodules: recursive + # Full history + tags so git describe produces a parseable + # firmware version (companion apps reject e.g. "1") + fetch-depth: 0 - name: Build ${{ matrix.variant.name }} firmware shell: bash run: | . /opt/esp/idf/export.sh + git config --global --add safe.directory "$GITHUB_WORKSPACE" + echo "Firmware version: $(git describe --tags --always --dirty)" cp configs/${{ matrix.variant.config }} sdkconfig.defaults idf.py -B build_${{ matrix.variant.name }} set-target esp32s3 idf.py -B build_${{ matrix.variant.name }} build diff --git a/main/process/ota_defines.h b/main/process/ota_defines.h index bb1541232..b8a386269 100644 --- a/main/process/ota_defines.h +++ b/main/process/ota_defines.h @@ -47,6 +47,8 @@ #define JADE_OTA_BOARD_TYPE "TTGO_TDISPLAYS3PROCAMERA" #elif defined(CONFIG_BOARD_TYPE_WS_TOUCH_LCD2) #define JADE_OTA_BOARD_TYPE "WAVESHARE_TOUCH_LCD2" +#elif defined(CONFIG_BOARD_TYPE_TDECK) +#define JADE_OTA_BOARD_TYPE "TDECK" #elif defined(CONFIG_BOARD_TYPE_QEMU) || defined(CONFIG_BOARD_TYPE_QEMU_LARGER) #define JADE_OTA_BOARD_TYPE "QEMU" #else diff --git a/main/ui/digit_entry.c b/main/ui/digit_entry.c index 7e0b9bd99..bc80e6d01 100644 --- a/main/ui/digit_entry.c +++ b/main/ui/digit_entry.c @@ -4,10 +4,6 @@ #include "../random.h" #include "../ui.h" -#ifdef CONFIG_HAS_KEYBOARD -#include -#include -#endif #define CHAR_BACKSPACE '|' #define CHAR_ENTER '~' @@ -208,24 +204,17 @@ static bool prev_selected_digit(digit_entry_t* digit_entry) } #ifdef CONFIG_HAS_KEYBOARD -// Map physical key events to digits. Accept actual ascii digits, plus the -// letter keys which have digits printed on them on the T-Deck keyboard: -// w=1 e=2 r=3 s=4 d=5 f=6 z=7 x=8 c=9 (0 is on the mic key). +// Map physical key events to digits - only actual ascii digits qualify +// (on the T-Deck keyboard these are typed with the SYM modifier held) static int keyboard_event_digit(const int32_t ev_id) { - static const char digit_key_aliases[] = "wersdfzxc"; // 1-9 - if (ev_id <= BTN_KEYBOARD_ASCII_OFFSET) { return -1; } - const int ch = tolower(ev_id - BTN_KEYBOARD_ASCII_OFFSET); + const int ch = ev_id - BTN_KEYBOARD_ASCII_OFFSET; if (ch >= '0' && ch <= '9') { return ch - '0'; } - const char* const alias = strchr(digit_key_aliases, ch); - if (alias) { - return (alias - digit_key_aliases) + 1; - } return -1; } From e4c56a916ee94a17aada220b3e83c6e6920bfcf8 Mon Sep 17 00:00:00 2001 From: 3rd Iteration Date: Mon, 6 Jul 2026 20:18:11 -0400 Subject: [PATCH 19/22] feat: keyboard backlight tracks the screen backlight Send the keyboard controller brightness command (0x01 ) so the keyboard backlight turns on/off and dims with the screen (levels 1-5 map to 51-255). The request is latched and applied by the keyboard task, which owns the i2c device, retrying until the write succeeds. The Alt+B manual toggle in the keyboard firmware still works. Co-Authored-By: Claude Fable 5 --- main/input/tdeck.inc | 19 +++++++++++++++++++ main/power/tdeck.inc | 7 +++++++ 2 files changed, 26 insertions(+) diff --git a/main/input/tdeck.inc b/main/input/tdeck.inc index a438b38c4..b865b6c63 100644 --- a/main/input/tdeck.inc +++ b/main/input/tdeck.inc @@ -13,6 +13,9 @@ #define KB_I2C_ADDR 0x55 #define KB_I2C_TIMEOUT_MS 50 +// Keyboard controller command: set backlight brightness (0-255, 0 = off) +#define KB_BRIGHTNESS_CMD 0x01 + #define TB_LEFT_GPIO 1 #define TB_RIGHT_GPIO 2 #define TB_UP_GPIO 3 @@ -29,6 +32,13 @@ // Edges further apart than this do not accumulate towards a step #define TB_GESTURE_TIMEOUT_US 300000 +// Pending keyboard backlight level (0-255), or -1 when no change pending. +// Set from other tasks (eg. the screen backlight code) - applied by the +// keyboard task below, which owns the i2c device. +static volatile int16_t kb_backlight_req = -1; + +void tdeck_set_keyboard_backlight(const uint8_t value) { kb_backlight_req = value; } + static void tdeck_keyboard_task(void* unused) { gpio_set_direction(BOARD_POWERON_GPIO, GPIO_MODE_OUTPUT); @@ -56,6 +66,15 @@ static void tdeck_keyboard_task(void* unused) ESP_ERROR_CHECK(i2c_master_bus_add_device(kb_i2c_bus, &dev_cfg, &kb_i2c_dev)); for (;;) { + // Apply any pending keyboard backlight change (retried on failure) + const int16_t kb_bl = kb_backlight_req; + if (kb_bl >= 0) { + const uint8_t cmd[] = { KB_BRIGHTNESS_CMD, (uint8_t)kb_bl }; + if (i2c_master_transmit(kb_i2c_dev, cmd, sizeof(cmd), KB_I2C_TIMEOUT_MS) == ESP_OK) { + kb_backlight_req = -1; + } + } + uint8_t key_byte = 0; const esp_err_t ret = i2c_master_receive(kb_i2c_dev, &key_byte, 1, KB_I2C_TIMEOUT_MS); if (ret == ESP_OK && key_byte != 0) { diff --git a/main/power/tdeck.inc b/main/power/tdeck.inc index ceacd3951..7c8c70fa7 100644 --- a/main/power/tdeck.inc +++ b/main/power/tdeck.inc @@ -13,6 +13,9 @@ #define BACKLIGHT_GPIO 42 #define BACKLIGHT_STEPS 16 +// Implemented in input/tdeck.inc - the keyboard task owns the i2c bus +void tdeck_set_keyboard_backlight(uint8_t value); + #define BATTERY_ADC_CHANNEL ADC_CHANNEL_3 #define BATTERY_ADC_ATTEN ADC_ATTEN_DB_12 #define BATTERY_EMA_ALPHA 0.3f @@ -99,12 +102,16 @@ esp_err_t power_backlight_on(uint8_t brightness) const uint8_t scaled = 1 + ((BACKLIGHT_STEPS - 1) * (brightness - BACKLIGHT_MIN)) / (BACKLIGHT_MAX - BACKLIGHT_MIN); set_backlight(scaled); + + // Have the keyboard backlight track the screen backlight (levels 1-5 -> 51-255) + tdeck_set_keyboard_backlight(brightness * 51); return ESP_OK; } esp_err_t power_backlight_off(void) { set_backlight(0); + tdeck_set_keyboard_backlight(0); return ESP_OK; } From 70194c6b8a755d6305a25501bf864a9917e1508a Mon Sep 17 00:00:00 2001 From: 3rd Iteration Date: Mon, 6 Jul 2026 20:29:46 -0400 Subject: [PATCH 20/22] fix: tdeck battery meter accuracy and usb/charging detection - Average 8 adc samples and use a 2.11 divider multiplier (2.0 nominal plus ~10% load correction, matching other t-deck firmwares) instead of a single noisy sample scaled by 2. - usb/charging detection used tud_mounted(), which is always false on the debug (usb-serial-jtag) build where TinyUSB is never initialised; infer usb connection from usb_serial_jtag_is_connected() there. - Report charging as usb present while below 4300mV - with no charger status line, a higher reading means the charger is holding up the sense node with the battery full. Co-Authored-By: Claude Fable 5 --- main/power/tdeck.inc | 60 ++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/main/power/tdeck.inc b/main/power/tdeck.inc index 7c8c70fa7..f21ccfd9e 100644 --- a/main/power/tdeck.inc +++ b/main/power/tdeck.inc @@ -7,7 +7,11 @@ #include #include +#ifdef CONFIG_JADE_USE_USB_JTAG_SERIAL +#include +#else #include "tusb.h" +#endif #define BOARD_POWERON_GPIO 10 #define BACKLIGHT_GPIO 42 @@ -18,8 +22,29 @@ void tdeck_set_keyboard_backlight(uint8_t value); #define BATTERY_ADC_CHANNEL ADC_CHANNEL_3 #define BATTERY_ADC_ATTEN ADC_ATTEN_DB_12 +#define BATTERY_ADC_SAMPLES 8 #define BATTERY_EMA_ALPHA 0.3f +// Voltage divider ratio is 2.0 (100k/100k) plus ~10% correction for +// undervoltage while the display loads the rail (as per other t-deck +// firmwares, eg. meshtastic) +#define BATTERY_VDIV_MULTIPLIER 2.11f + +// Above this the sense node is being held up by the charger with the +// battery full (charge terminated) rather than actively charging +#define BATTERY_CHARGED_MILLIVOLTS 4300 + +static bool usb_connected(void) +{ +#ifdef CONFIG_JADE_USE_USB_JTAG_SERIAL + // TinyUSB is not initialised in this mode - infer usb connection + // from the usb-serial-jtag peripheral instead + return usb_serial_jtag_is_connected(); +#else + return tud_mounted() && !tud_suspended(); +#endif +} + static adc_oneshot_unit_handle_t adc1_handle = NULL; static adc_cali_handle_t adc1_cali_chan0_handle = NULL; static float ema_voltage = 0.0f; @@ -121,16 +146,26 @@ esp_err_t power_camera_off(void) { return ESP_OK; } uint16_t power_get_vbat(void) { JADE_ASSERT(adc1_handle); - int raw_adc, voltage; - ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, BATTERY_ADC_CHANNEL, &raw_adc)); + + // Average several samples to smooth adc noise + int raw_sum = 0; + for (int i = 0; i < BATTERY_ADC_SAMPLES; ++i) { + int raw_adc; + ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, BATTERY_ADC_CHANNEL, &raw_adc)); + raw_sum += raw_adc; + } + + int voltage; + const int raw_avg = raw_sum / BATTERY_ADC_SAMPLES; if (adc1_cali_chan0_handle) { - ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_chan0_handle, raw_adc, &voltage)); + ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_chan0_handle, raw_avg, &voltage)); } else { - voltage = (raw_adc * 3300) / 4095; + voltage = (raw_avg * 3300) / 4095; } + const float ema_v = (ema_voltage > 0) ? ema_voltage : (float)voltage; ema_voltage = (BATTERY_EMA_ALPHA * voltage) + ((1.0f - BATTERY_EMA_ALPHA) * ema_v); - return (uint16_t)(ema_voltage * 2); + return (uint16_t)(ema_voltage * BATTERY_VDIV_MULTIPLIER); } uint8_t power_get_battery_status(void) @@ -146,7 +181,9 @@ uint8_t power_get_battery_status(void) bool power_get_battery_charging(void) { - return tud_mounted() && !tud_suspended(); + // No charger status line on the t-deck - infer charging from usb + // power being present while the battery is not yet full + return usb_connected() && power_get_vbat() < BATTERY_CHARGED_MILLIVOLTS; } uint16_t power_get_ibat_charge(void) { return 0; } @@ -158,13 +195,4 @@ uint16_t power_get_temp(void) { return 0; } void disable_usb_host(void) {} void enable_usb_host(void) {} -bool usb_is_powered(void) -{ - if (tud_mounted() && !tud_suspended()) { - return true; - } - if (power_get_vbat() < 1000) { - return true; - } - return false; -} +bool usb_is_powered(void) { return usb_connected(); } From c825f30c4e8880b64ba617f26a1cd0bba99ff130 Mon Sep 17 00:00:00 2001 From: 3rd Iteration Date: Mon, 6 Jul 2026 20:39:23 -0400 Subject: [PATCH 21/22] fix: show tdeck battery voltage in device info screen handle_display_battery_volts() only formats a reading for a hardcoded set of boards and falls back to "NO BAT" otherwise; add the tdeck (power_get_vbat() already returns divider-corrected millivolts). Co-Authored-By: Claude Fable 5 --- main/process/dashboard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/process/dashboard.c b/main/process/dashboard.c index 1a9085f56..191e950c7 100644 --- a/main/process/dashboard.c +++ b/main/process/dashboard.c @@ -2039,7 +2039,7 @@ static void handle_display_battery_volts(void) #ifdef CONFIG_HAS_AXP const int ret = snprintf(power_status, sizeof(power_status), "%umv", power_get_vbat()); JADE_ASSERT(ret > 0 && ret < sizeof(power_status)); -#elif defined(CONFIG_BOARD_TYPE_M5_STICKC_PLUS_2) +#elif defined(CONFIG_BOARD_TYPE_M5_STICKC_PLUS_2) || defined(CONFIG_BOARD_TYPE_TDECK) const uint16_t vbat = power_get_vbat(); if (vbat > 0) { const int ret = snprintf(power_status, sizeof(power_status), "%umv", vbat); From 12e940bc010bd8700b66a3b4ab51a9901eb7cc3f Mon Sep 17 00:00:00 2001 From: 3rdIteration Date: Tue, 7 Jul 2026 13:13:21 +1000 Subject: [PATCH 22/22] fix: disable BGR color order for T-Deck (use RGB instead) --- main/Kconfig.projbuild | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index 741669d20..37ce53703 100644 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -514,7 +514,7 @@ menu "Blockstream Jade" default 135 config DCS_ADDRESS_MODE_BGR_SELECTED bool "BGR" - default y if BOARD_TYPE_M5_FIRE || BOARD_TYPE_M5_BLACK_GRAY || BOARD_TYPE_M5_CORES3 || BOARD_TYPE_M5_CORE2 || BOARD_TYPE_TTGO_TDISPLAYS3PROCAMERA || BOARD_TYPE_TDECK + default y if BOARD_TYPE_M5_FIRE || BOARD_TYPE_M5_BLACK_GRAY || BOARD_TYPE_M5_CORES3 || BOARD_TYPE_M5_CORE2 || BOARD_TYPE_TTGO_TDISPLAYS3PROCAMERA config DCS_ADDRESS_MODE_MIRROR_X_SELECTED bool "Mirror X" default y if BOARD_TYPE_JADE_ANY || \