Fix lint issues and lint in CI (#18)

This commit is contained in:
Dave Allie
2026-01-19 21:39:38 +11:00
committed by GitHub
parent fe3afbb4f3
commit 5778e2deda
10 changed files with 359 additions and 44 deletions
+23
View File
@@ -0,0 +1,23 @@
name: CI
'on':
push:
branches: [master]
pull_request:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version-file: .tool-versions
cache: yarn
- name: Install Packages
run: yarn --immutable
- name: Run linter
run: yarn lint
+1
View File
@@ -0,0 +1 @@
npx lint-staged
+1
View File
@@ -0,0 +1 @@
nodejs 24
+10 -1
View File
@@ -7,7 +7,8 @@
"lint:fix": "yarn eslint --max-warnings 0 --cache --fix && yarn prettier --write .",
"dev": "next dev",
"build": "next build",
"start": "next start"
"start": "next start",
"prepare": "husky"
},
"dependencies": {
"@chakra-ui/react": "^3.31.0",
@@ -44,9 +45,17 @@
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.0.1",
"globals": "^16.5.0",
"husky": "^9.1.7",
"lint-staged": "^16.2.7",
"prettier": "^3.8.0",
"typescript": "^5.9.3",
"typescript-eslint": "^8.53.0"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"yarn eslint --cache --fix --max-warnings 0 --no-warn-ignored",
"yarn prettier --write"
]
},
"packageManager": "yarn@4.11.0"
}
+7 -8
View File
@@ -26,7 +26,6 @@ import OtaPartition, { OtaPartitionDetails } from '@/esp/OtaPartition';
import HexSpan from '@/components/HexSpan';
import HexViewer from '@/components/HexViewer';
import { downloadData } from '@/utils/download';
import FileUpload, { FileUploadHandle } from '@/components/FileUpload';
import { FirmwareInfo } from '@/utils/firmwareIdentifier';
function OtadataDebug({ otaPartition }: { otaPartition: OtaPartition }) {
@@ -220,6 +219,7 @@ function FirmwareIdentificationDebug({
case 'crosspoint':
return 'blue';
case 'unknown':
default:
return 'orange';
}
};
@@ -272,9 +272,8 @@ function FirmwareIdentificationDebug({
}
export default function Debug() {
const { actions, debugActions, stepData, isRunning } = useEspOperations();
const { debugActions, stepData, isRunning } = useEspOperations();
const [debugOutputNode, setDebugOutputNode] = useState<ReactNode>(null);
const appPartitionFileInput = React.useRef<FileUploadHandle>(null);
return (
<Flex direction="column" gap="20px">
@@ -284,8 +283,8 @@ export default function Debug() {
<Stack gap={1} color="grey" textStyle="sm">
<p>
These are few tools to help debugging / administering your Xtink
device. They&apos;re designed to be used by those who are
intentionally messing around with their device.
device. Theyre designed to be used by those who are intentionally
messing around with their device.
</p>
<p>
<b>Read otadata partition</b> will read the raw data out of the{' '}
@@ -303,8 +302,8 @@ export default function Debug() {
<Em>otadata</Em> to switch the boot partition.
</p>
<p>
<b>Identify firmware in both partitions</b> will read both app0 and
app1 partitions and automatically identify which firmware is
<b>Identify firmware in both partitions</b> will read both app0
and app1 partitions and automatically identify which firmware is
installed on each (Official English, Official Chinese, CrossPoint
Community, or Custom).
</p>
@@ -414,4 +413,4 @@ export default function Debug() {
) : null}
</Flex>
);
}
}
+16 -16
View File
@@ -48,10 +48,10 @@ export default function Home() {
<Alert.Description>
<Stack>
<p>
I&apos;ve tried to make this foolproof and while the likelihood
of unrecoverable things going wrong is extremely low, it&apos;s
never zero. So proceed with care and make sure to grab a backup
using <b>Save full flash</b> before flashing your device.
Ive tried to make this foolproof and while the likelihood of
unrecoverable things going wrong is extremely low, its never
zero. So proceed with care and make sure to grab a backup using{' '}
<b>Save full flash</b> before flashing your device.
</p>
<p>
Once you start <b>Write flash from file</b> or{' '}
@@ -75,10 +75,10 @@ export default function Home() {
goes wrong.
</p>
<p>
<b>Save full flash</b> will read your device&apos;s flash and save
it as <Em>flash.bin</Em>. This will take around 25 minutes to
complete. You can use that file (or someone else&apos;s) with{' '}
<b>Write full flash from file</b> to overwrite your device&apos;s
<b>Save full flash</b> will read your devices flash and save it
as <Em>flash.bin</Em>. This will take around 25 minutes to
complete. You can use that file (or someone elses) with{' '}
<b>Write full flash from file</b> to overwrite your devices
entire flash.
</p>
</Stack>
@@ -116,8 +116,8 @@ export default function Home() {
<Heading size="xl">OTA fast flash controls</Heading>
<Stack gap={1} color="grey" textStyle="sm">
<p>
Before using this, I&apos;d strongly recommend taking a backup of
your device using <b>Save full flash</b> above.
Before using this, Id strongly recommend taking a backup of your
device using <b>Save full flash</b> above.
</p>
<p>
<b>Flash English/Chinese firmware</b> will download the firmware,
@@ -208,9 +208,9 @@ export default function Home() {
<Alert.Title>Change device language</Alert.Title>
<Alert.Description>
Before starting the process, it is recommended to change the device
language to English. To do this, select "Settings" icon, then
click "OK / Confirm" button and "OK / Confirm" again until English is shown.
Otherwise, the language will still be Chinese after flashing
language to English. To do this, select Settings icon, then click
OK / Confirm button and OK / Confirm again until English is
shown. Otherwise, the language will still be Chinese after flashing
and you may not notice changes.
</Alert.Description>
</Alert.Content>
@@ -221,9 +221,9 @@ export default function Home() {
<Alert.Title>Device restart instructions</Alert.Title>
<Alert.Description>
Once you complete a write operation, you will need to restart your
device by pressing and releasing the small "Reset" button near the bottom
right, followed quickly by pressing and holding of the main power
button for about 3 seconds.
device by pressing and releasing the small Reset button near the
bottom right, followed quickly by pressing and holding of the main
power button for about 3 seconds.
</Alert.Description>
</Alert.Content>
</Alert.Root>
+3 -3
View File
@@ -104,7 +104,7 @@ export default class EspController {
return this.espLoader.readFlash(offset, 0x640000, onPacketReceived);
}
async readAppPartitionForIdentification(
async readAppPartitionForIdentification(
partitionLabel: 'app0' | 'app1',
{
readSize = 0x6400, // Default to 25KB (0x6400) for fast identification
@@ -123,7 +123,7 @@ export default class EspController {
// Optimized read for firmware identification with flexible read size and offset:
// - Default (25KB / 0x6400): Fast path, covers 99% of cases
// - Additional chunks: Specify offset multiples of 25KB until identification succeeds
// In testing, most firmwares are identified within the first 25KB read, so reading the entire
// In testing, most firmwares are identified within the first 25KB read, so reading the entire
// partition is unnecessary in the majority of cases.
const baseOffset = partitionLabel === 'app0' ? 0x10000 : 0x650000;
@@ -183,4 +183,4 @@ export default class EspController {
reportProgress,
});
}
}
}
+13 -6
View File
@@ -23,10 +23,10 @@ export function useEspOperations() {
const wrapWithRunning =
<Args extends unknown[], T>(fn: (...a: Args) => Promise<T>) =>
async (...a: Args) => {
setIsRunning(true);
return fn(...a).finally(() => setIsRunning(false));
};
async (...a: Args) => {
setIsRunning(true);
return fn(...a).finally(() => setIsRunning(false));
};
const flashRemoteFirmware = async (
getFirmware: () => Promise<Uint8Array>,
@@ -416,6 +416,7 @@ export function useEspOperations() {
let info: FirmwareInfo | undefined;
for (let offset = 0; offset < maxReadSize; offset += chunkSize) {
// eslint-disable-next-line no-await-in-loop
const chunk = await espController.readAppPartitionForIdentification(
partitionLabel,
{
@@ -441,7 +442,13 @@ export function useEspOperations() {
}
}
return info ?? { type: 'unknown', version: 'unknown', displayName: 'Custom/Unknown Firmware' }; // Return the last identification result if not found
return (
info ?? {
type: 'unknown',
version: 'unknown',
displayName: 'Custom/Unknown Firmware',
}
); // Return the last identification result if not found
};
const app0Info = await runStep('Read app0 partition', () =>
@@ -486,4 +493,4 @@ export function useEspOperations() {
readAndIdentifyAllFirmware: wrapWithRunning(readAndIdentifyAllFirmware),
},
};
}
}
+14 -10
View File
@@ -19,9 +19,9 @@ function findString(
return -1;
}
for (let i = startOffset; i <= data.length - searchBytes.length; i++) {
for (let i = startOffset; i <= data.length - searchBytes.length; i += 1) {
let match = true;
for (let j = 0; j < searchBytes.length; j++) {
for (let j = 0; j < searchBytes.length; j += 1) {
if (data[i + j] !== searchBytes[j]) {
match = false;
break;
@@ -73,7 +73,7 @@ function extractVersion(data: Uint8Array, searchLimit = 25000): string {
// Try to find V-pattern versions (official firmware)
// Pattern: [any byte]<V3.1.1 or similar
for (let i = 0; i < searchArea.length - 8; i++) {
for (let i = 0; i < searchArea.length - 8; i += 1) {
if (searchArea[i] === 0x56) {
// 'V' character
const chunk = decoder.decode(
@@ -91,12 +91,16 @@ function extractVersion(data: Uint8Array, searchLimit = 25000): string {
const fullString = decoder.decode(searchArea);
// Check for CrossPoint-ESP32-x.x.x pattern
const crossPointMatch = fullString.match(/CrossPoint-ESP32-(\d+\.\d+\.\d+)/);
const crossPointMatch = fullString.match(
/CrossPoint-ESP32-(\d+\.\d+\.\d+)/,
);
if (crossPointMatch) {
return crossPointMatch[1]!;
}
// eslint-disable-next-line no-control-regex
const lines = fullString.split(/[\x00\n]/);
// eslint-disable-next-line no-restricted-syntax
for (const line of lines) {
const match = line.match(/^\d+\.\d+\.\d+$/);
if (match) {
@@ -107,7 +111,7 @@ function extractVersion(data: Uint8Array, searchLimit = 25000): string {
// Also search for version in common patterns
const versionMatch = fullString.match(/(?:Version[:\s]*)(\d+\.\d+\.\d+)/i);
if (versionMatch?.[1]) {
return versionMatch[1] as string;
return versionMatch[1];
}
} catch {
// Decoding failed, continue
@@ -162,7 +166,7 @@ export function identifyFirmware(firmwareData: Uint8Array): FirmwareInfo {
if (findString(areaAfterVersion, 'XTOS') !== -1) {
return {
type: 'official-chinese',
version: version,
version,
displayName: 'Official Chinese',
};
}
@@ -171,7 +175,7 @@ export function identifyFirmware(firmwareData: Uint8Array): FirmwareInfo {
// If we have a V-pattern version, valid ESP32 image, but no XTOS → English
return {
type: 'official-english',
version: version,
version,
displayName: 'Official English',
};
}
@@ -183,7 +187,7 @@ export function identifyFirmware(firmwareData: Uint8Array): FirmwareInfo {
) {
return {
type: 'crosspoint',
version: version,
version,
displayName: 'CrossPoint Community Reader',
};
}
@@ -191,7 +195,7 @@ export function identifyFirmware(firmwareData: Uint8Array): FirmwareInfo {
// Unknown firmware
return {
type: 'unknown',
version: version,
version,
displayName: 'Custom/Unknown Firmware',
};
}
@@ -205,4 +209,4 @@ export function identifyFirmware(firmwareData: Uint8Array): FirmwareInfo {
*/
export function isIdentificationSuccessful(info: FirmwareInfo): boolean {
return info.type !== 'unknown';
}
}
+271
View File
@@ -2438,6 +2438,22 @@ __metadata:
languageName: node
linkType: hard
"ansi-escapes@npm:^7.0.0":
version: 7.2.0
resolution: "ansi-escapes@npm:7.2.0"
dependencies:
environment: "npm:^1.0.0"
checksum: 10c0/b562fd995761fa12f33be316950ee58fda489e125d331bcd9131434969a2eb55dc14e9405f214dcf4697c9d67c576ba0baf6e8f3d52058bf9222c97560b220cb
languageName: node
linkType: hard
"ansi-regex@npm:^6.0.1":
version: 6.2.2
resolution: "ansi-regex@npm:6.2.2"
checksum: 10c0/05d4acb1d2f59ab2cf4b794339c7b168890d44dda4bf0ce01152a8da0213aca207802f930442ce8cd22d7a92f44907664aac6508904e75e038fa944d2601b30f
languageName: node
linkType: hard
"ansi-styles@npm:^4.1.0":
version: 4.3.0
resolution: "ansi-styles@npm:4.3.0"
@@ -2454,6 +2470,13 @@ __metadata:
languageName: node
linkType: hard
"ansi-styles@npm:^6.2.1":
version: 6.2.3
resolution: "ansi-styles@npm:6.2.3"
checksum: 10c0/23b8a4ce14e18fb854693b95351e286b771d23d8844057ed2e7d083cd3e708376c3323707ec6a24365f7d7eda3ca00327fe04092e29e551499ec4c8b7bfac868
languageName: node
linkType: hard
"argparse@npm:^2.0.1":
version: 2.0.1
resolution: "argparse@npm:2.0.1"
@@ -2760,6 +2783,25 @@ __metadata:
languageName: node
linkType: hard
"cli-cursor@npm:^5.0.0":
version: 5.0.0
resolution: "cli-cursor@npm:5.0.0"
dependencies:
restore-cursor: "npm:^5.0.0"
checksum: 10c0/7ec62f69b79f6734ab209a3e4dbdc8af7422d44d360a7cb1efa8a0887bbe466a6e625650c466fe4359aee44dbe2dc0b6994b583d40a05d0808a5cb193641d220
languageName: node
linkType: hard
"cli-truncate@npm:^5.0.0":
version: 5.1.1
resolution: "cli-truncate@npm:5.1.1"
dependencies:
slice-ansi: "npm:^7.1.0"
string-width: "npm:^8.0.0"
checksum: 10c0/3842920829a62f3e041ce39199050c42706c3c9c756a4efc8b86d464e102d1fa031d8b1b9b2e3bb36e1017c763558275472d031bdc884c1eff22a2f20e4f6b0a
languageName: node
linkType: hard
"client-only@npm:0.0.1":
version: 0.0.1
resolution: "client-only@npm:0.0.1"
@@ -2783,6 +2825,20 @@ __metadata:
languageName: node
linkType: hard
"colorette@npm:^2.0.20":
version: 2.0.20
resolution: "colorette@npm:2.0.20"
checksum: 10c0/e94116ff33b0ff56f3b83b9ace895e5bf87c2a7a47b3401b8c3f3226e050d5ef76cf4072fb3325f9dc24d1698f9b730baf4e05eeaf861d74a1883073f4c98a40
languageName: node
linkType: hard
"commander@npm:^14.0.2":
version: 14.0.2
resolution: "commander@npm:14.0.2"
checksum: 10c0/245abd1349dbad5414cb6517b7b5c584895c02c4f7836ff5395f301192b8566f9796c82d7bd6c92d07eba8775fe4df86602fca5d86d8d10bcc2aded1e21c2aeb
languageName: node
linkType: hard
"comment-parser@npm:^1.4.1":
version: 1.4.1
resolution: "comment-parser@npm:1.4.1"
@@ -2983,6 +3039,13 @@ __metadata:
languageName: node
linkType: hard
"emoji-regex@npm:^10.3.0":
version: 10.6.0
resolution: "emoji-regex@npm:10.6.0"
checksum: 10c0/1e4aa097bb007301c3b4b1913879ae27327fdc48e93eeefefe3b87e495eb33c5af155300be951b4349ff6ac084f4403dc9eff970acba7c1c572d89396a9a32d7
languageName: node
linkType: hard
"emoji-regex@npm:^9.2.2":
version: 9.2.2
resolution: "emoji-regex@npm:9.2.2"
@@ -2990,6 +3053,13 @@ __metadata:
languageName: node
linkType: hard
"environment@npm:^1.0.0":
version: 1.1.0
resolution: "environment@npm:1.1.0"
checksum: 10c0/fb26434b0b581ab397039e51ff3c92b34924a98b2039dcb47e41b7bca577b9dbf134a8eadb364415c74464b682e2d3afe1a4c0eb9873dc44ea814c5d3103331d
languageName: node
linkType: hard
"error-ex@npm:^1.3.1":
version: 1.3.4
resolution: "error-ex@npm:1.3.4"
@@ -3529,6 +3599,13 @@ __metadata:
languageName: node
linkType: hard
"eventemitter3@npm:^5.0.1":
version: 5.0.1
resolution: "eventemitter3@npm:5.0.1"
checksum: 10c0/4ba5c00c506e6c786b4d6262cfbce90ddc14c10d4667e5c83ae993c9de88aa856033994dd2b35b83e8dc1170e224e66a319fa80adc4c32adcd2379bbc75da814
languageName: node
linkType: hard
"expect@npm:^30.0.0":
version: 30.2.0
resolution: "expect@npm:30.2.0"
@@ -3686,6 +3763,13 @@ __metadata:
languageName: node
linkType: hard
"get-east-asian-width@npm:^1.0.0, get-east-asian-width@npm:^1.3.0, get-east-asian-width@npm:^1.3.1":
version: 1.4.0
resolution: "get-east-asian-width@npm:1.4.0"
checksum: 10c0/4e481d418e5a32061c36fbb90d1b225a254cc5b2df5f0b25da215dcd335a3c111f0c2023ffda43140727a9cafb62dac41d022da82c08f31083ee89f714ee3b83
languageName: node
linkType: hard
"get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.2.7, get-intrinsic@npm:^1.3.0":
version: 1.3.1
resolution: "get-intrinsic@npm:1.3.1"
@@ -3866,6 +3950,15 @@ __metadata:
languageName: node
linkType: hard
"husky@npm:^9.1.7":
version: 9.1.7
resolution: "husky@npm:9.1.7"
bin:
husky: bin.js
checksum: 10c0/35bb110a71086c48906aa7cd3ed4913fb913823715359d65e32e0b964cb1e255593b0ae8014a5005c66a68e6fa66c38dcfa8056dbbdfb8b0187c0ffe7ee3a58f
languageName: node
linkType: hard
"ignore@npm:^5.2.0":
version: 5.3.2
resolution: "ignore@npm:5.3.2"
@@ -4020,6 +4113,15 @@ __metadata:
languageName: node
linkType: hard
"is-fullwidth-code-point@npm:^5.0.0":
version: 5.1.0
resolution: "is-fullwidth-code-point@npm:5.1.0"
dependencies:
get-east-asian-width: "npm:^1.3.1"
checksum: 10c0/c1172c2e417fb73470c56c431851681591f6a17233603a9e6f94b7ba870b2e8a5266506490573b607fb1081318589372034aa436aec07b465c2029c0bc7f07a4
languageName: node
linkType: hard
"is-generator-function@npm:^1.0.10":
version: 1.1.2
resolution: "is-generator-function@npm:1.1.2"
@@ -4376,6 +4478,37 @@ __metadata:
languageName: node
linkType: hard
"lint-staged@npm:^16.2.7":
version: 16.2.7
resolution: "lint-staged@npm:16.2.7"
dependencies:
commander: "npm:^14.0.2"
listr2: "npm:^9.0.5"
micromatch: "npm:^4.0.8"
nano-spawn: "npm:^2.0.0"
pidtree: "npm:^0.6.0"
string-argv: "npm:^0.3.2"
yaml: "npm:^2.8.1"
bin:
lint-staged: bin/lint-staged.js
checksum: 10c0/9a677c21a8112d823ae5bc565ba2c9e7b803786f2a021c46827a55fe44ed59def96edb24fc99c06a2545cdbbf366022ad82addcb3bf60c712f3b98ef92069717
languageName: node
linkType: hard
"listr2@npm:^9.0.5":
version: 9.0.5
resolution: "listr2@npm:9.0.5"
dependencies:
cli-truncate: "npm:^5.0.0"
colorette: "npm:^2.0.20"
eventemitter3: "npm:^5.0.1"
log-update: "npm:^6.1.0"
rfdc: "npm:^1.4.1"
wrap-ansi: "npm:^9.0.0"
checksum: 10c0/46448d1ba0addc9d71aeafd05bb8e86ded9641ccad930ac302c2bd2ad71580375604743e18586fcb8f11906edf98e8e17fca75ba0759947bf275d381f68e311d
languageName: node
linkType: hard
"locate-path@npm:^6.0.0":
version: 6.0.0
resolution: "locate-path@npm:6.0.0"
@@ -4392,6 +4525,19 @@ __metadata:
languageName: node
linkType: hard
"log-update@npm:^6.1.0":
version: 6.1.0
resolution: "log-update@npm:6.1.0"
dependencies:
ansi-escapes: "npm:^7.0.0"
cli-cursor: "npm:^5.0.0"
slice-ansi: "npm:^7.1.0"
strip-ansi: "npm:^7.1.0"
wrap-ansi: "npm:^9.0.0"
checksum: 10c0/4b350c0a83d7753fea34dcac6cd797d1dc9603291565de009baa4aa91c0447eab0d3815a05c8ec9ac04fdfffb43c82adcdb03ec1fceafd8518e1a8c1cff4ff89
languageName: node
linkType: hard
"loose-envify@npm:^1.4.0":
version: 1.4.0
resolution: "loose-envify@npm:1.4.0"
@@ -4429,6 +4575,13 @@ __metadata:
languageName: node
linkType: hard
"mimic-function@npm:^5.0.0":
version: 5.0.1
resolution: "mimic-function@npm:5.0.1"
checksum: 10c0/f3d9464dd1816ecf6bdf2aec6ba32c0728022039d992f178237d8e289b48764fee4131319e72eedd4f7f094e22ded0af836c3187a7edc4595d28dd74368fd81d
languageName: node
linkType: hard
"minimatch@npm:^3.1.2":
version: 3.1.2
resolution: "minimatch@npm:3.1.2"
@@ -4463,6 +4616,13 @@ __metadata:
languageName: node
linkType: hard
"nano-spawn@npm:^2.0.0":
version: 2.0.0
resolution: "nano-spawn@npm:2.0.0"
checksum: 10c0/d00f9b5739f86e28cb732ffd774793e110810cded246b8393c75c4f22674af47f98ee37b19f022ada2d8c9425f800e841caa0662fbff4c0930a10e39339fb366
languageName: node
linkType: hard
"nanoid@npm:^3.3.6":
version: 3.3.11
resolution: "nanoid@npm:3.3.11"
@@ -4636,6 +4796,15 @@ __metadata:
languageName: node
linkType: hard
"onetime@npm:^7.0.0":
version: 7.0.0
resolution: "onetime@npm:7.0.0"
dependencies:
mimic-function: "npm:^5.0.0"
checksum: 10c0/5cb9179d74b63f52a196a2e7037ba2b9a893245a5532d3f44360012005c9cadb60851d56716ebff18a6f47129dab7168022445df47c2aff3b276d92585ed1221
languageName: node
linkType: hard
"optionator@npm:^0.9.3":
version: 0.9.4
resolution: "optionator@npm:0.9.4"
@@ -4763,6 +4932,15 @@ __metadata:
languageName: node
linkType: hard
"pidtree@npm:^0.6.0":
version: 0.6.0
resolution: "pidtree@npm:0.6.0"
bin:
pidtree: bin/pidtree.js
checksum: 10c0/0829ec4e9209e230f74ebf4265f5ccc9ebfb488334b525cb13f86ff801dca44b362c41252cd43ae4d7653a10a5c6ab3be39d2c79064d6895e0d78dc50a5ed6e9
languageName: node
linkType: hard
"possible-typed-array-names@npm:^1.0.0":
version: 1.1.0
resolution: "possible-typed-array-names@npm:1.1.0"
@@ -4998,6 +5176,23 @@ __metadata:
languageName: node
linkType: hard
"restore-cursor@npm:^5.0.0":
version: 5.1.0
resolution: "restore-cursor@npm:5.1.0"
dependencies:
onetime: "npm:^7.0.0"
signal-exit: "npm:^4.1.0"
checksum: 10c0/c2ba89131eea791d1b25205bdfdc86699767e2b88dee2a590b1a6caa51737deac8bad0260a5ded2f7c074b7db2f3a626bcf1fcf3cdf35974cbeea5e2e6764f60
languageName: node
linkType: hard
"rfdc@npm:^1.4.1":
version: 1.4.1
resolution: "rfdc@npm:1.4.1"
checksum: 10c0/4614e4292356cafade0b6031527eea9bc90f2372a22c012313be1dcc69a3b90c7338158b414539be863fa95bfcb2ddcd0587be696841af4e6679d85e62c060c7
languageName: node
linkType: hard
"safe-array-concat@npm:^1.1.3":
version: 1.1.3
resolution: "safe-array-concat@npm:1.1.3"
@@ -5242,6 +5437,13 @@ __metadata:
languageName: node
linkType: hard
"signal-exit@npm:^4.1.0":
version: 4.1.0
resolution: "signal-exit@npm:4.1.0"
checksum: 10c0/41602dce540e46d599edba9d9860193398d135f7ff72cab629db5171516cfae628d21e7bfccde1bbfdf11c48726bc2a6d1a8fb8701125852fbfda7cf19c6aa83
languageName: node
linkType: hard
"slash@npm:^3.0.0":
version: 3.0.0
resolution: "slash@npm:3.0.0"
@@ -5249,6 +5451,16 @@ __metadata:
languageName: node
linkType: hard
"slice-ansi@npm:^7.1.0":
version: 7.1.2
resolution: "slice-ansi@npm:7.1.2"
dependencies:
ansi-styles: "npm:^6.2.1"
is-fullwidth-code-point: "npm:^5.0.0"
checksum: 10c0/36742f2eb0c03e2e81a38ed14d13a64f7b732fe38c3faf96cce0599788a345011e840db35f1430ca606ea3f8db2abeb92a8d25c2753a819e3babaa10c2e289a2
languageName: node
linkType: hard
"source-map-js@npm:^1.0.2":
version: 1.2.1
resolution: "source-map-js@npm:1.2.1"
@@ -5289,6 +5501,34 @@ __metadata:
languageName: node
linkType: hard
"string-argv@npm:^0.3.2":
version: 0.3.2
resolution: "string-argv@npm:0.3.2"
checksum: 10c0/75c02a83759ad1722e040b86823909d9a2fc75d15dd71ec4b537c3560746e33b5f5a07f7332d1e3f88319909f82190843aa2f0a0d8c8d591ec08e93d5b8dec82
languageName: node
linkType: hard
"string-width@npm:^7.0.0":
version: 7.2.0
resolution: "string-width@npm:7.2.0"
dependencies:
emoji-regex: "npm:^10.3.0"
get-east-asian-width: "npm:^1.0.0"
strip-ansi: "npm:^7.1.0"
checksum: 10c0/eb0430dd43f3199c7a46dcbf7a0b34539c76fe3aa62763d0b0655acdcbdf360b3f66f3d58ca25ba0205f42ea3491fa00f09426d3b7d3040e506878fc7664c9b9
languageName: node
linkType: hard
"string-width@npm:^8.0.0":
version: 8.1.0
resolution: "string-width@npm:8.1.0"
dependencies:
get-east-asian-width: "npm:^1.3.0"
strip-ansi: "npm:^7.1.0"
checksum: 10c0/749b5d0dab2532b4b6b801064230f4da850f57b3891287023117ab63a464ad79dd208f42f793458f48f3ad121fe2e1f01dd525ff27ead957ed9f205e27406593
languageName: node
linkType: hard
"string.prototype.includes@npm:^2.0.1":
version: 2.0.1
resolution: "string.prototype.includes@npm:2.0.1"
@@ -5369,6 +5609,15 @@ __metadata:
languageName: node
linkType: hard
"strip-ansi@npm:^7.1.0":
version: 7.1.2
resolution: "strip-ansi@npm:7.1.2"
dependencies:
ansi-regex: "npm:^6.0.1"
checksum: 10c0/0d6d7a023de33368fd042aab0bf48f4f4077abdfd60e5393e73c7c411e85e1b3a83507c11af2e656188511475776215df9ca589b4da2295c9455cc399ce1858b
languageName: node
linkType: hard
"strip-json-comments@npm:^3.1.1":
version: 3.1.1
resolution: "strip-json-comments@npm:3.1.1"
@@ -5751,6 +6000,17 @@ __metadata:
languageName: node
linkType: hard
"wrap-ansi@npm:^9.0.0":
version: 9.0.2
resolution: "wrap-ansi@npm:9.0.2"
dependencies:
ansi-styles: "npm:^6.2.1"
string-width: "npm:^7.0.0"
strip-ansi: "npm:^7.1.0"
checksum: 10c0/3305839b9a0d6fb930cb63a52f34d3936013d8b0682ff3ec133c9826512620f213800ffa19ea22904876d5b7e9a3c1f40682f03597d986a4ca881fa7b033688c
languageName: node
linkType: hard
"xteink-flasher@workspace:.":
version: 0.0.0-use.local
resolution: "xteink-flasher@workspace:."
@@ -5781,6 +6041,8 @@ __metadata:
eslint-plugin-react-hooks: "npm:^7.0.1"
esptool-js: "patch:esptool-js@npm%3A0.5.7#~/.yarn/patches/esptool-js-npm-0.5.7-bd6223d76a.patch"
globals: "npm:^16.5.0"
husky: "npm:^9.1.7"
lint-staged: "npm:^16.2.7"
next: "npm:16.1.3"
next-themes: "npm:^0.4.6"
prettier: "npm:^3.8.0"
@@ -5807,6 +6069,15 @@ __metadata:
languageName: node
linkType: hard
"yaml@npm:^2.8.1":
version: 2.8.2
resolution: "yaml@npm:2.8.2"
bin:
yaml: bin.mjs
checksum: 10c0/703e4dc1e34b324aa66876d63618dcacb9ed49f7e7fe9b70f1e703645be8d640f68ab84f12b86df8ac960bac37acf5513e115de7c970940617ce0343c8c9cd96
languageName: node
linkType: hard
"yocto-queue@npm:^0.1.0":
version: 0.1.0
resolution: "yocto-queue@npm:0.1.0"