@lynxship/cli 0.1.19 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -5
- package/dist/android/signing.d.ts +16 -0
- package/dist/android/signing.d.ts.map +1 -0
- package/dist/android/signing.js +131 -0
- package/dist/android/types.d.ts +12 -0
- package/dist/android/types.d.ts.map +1 -0
- package/dist/android/types.js +1 -0
- package/dist/android-build.d.ts +4 -13
- package/dist/android-build.d.ts.map +1 -1
- package/dist/android-build.js +14 -133
- package/dist/android-toolchain/inspection.d.ts +3 -0
- package/dist/android-toolchain/inspection.d.ts.map +1 -0
- package/dist/android-toolchain/inspection.js +122 -0
- package/dist/android-toolchain/probes.d.ts +23 -0
- package/dist/android-toolchain/probes.d.ts.map +1 -0
- package/dist/android-toolchain/probes.js +183 -0
- package/dist/android-toolchain/types.d.ts +20 -0
- package/dist/android-toolchain/types.d.ts.map +1 -0
- package/dist/android-toolchain/types.js +1 -0
- package/dist/android-toolchain.d.ts +4 -20
- package/dist/android-toolchain.d.ts.map +1 -1
- package/dist/android-toolchain.js +4 -300
- package/dist/app-config.d.ts +25 -0
- package/dist/app-config.d.ts.map +1 -0
- package/dist/app-config.js +106 -0
- package/dist/bundle-build.d.ts.map +1 -1
- package/dist/bundle-build.js +11 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +66 -0
- package/dist/commands/build-execution.d.ts +41 -0
- package/dist/commands/build-execution.d.ts.map +1 -0
- package/dist/commands/build-execution.js +182 -0
- package/dist/commands/configuration.d.ts +19 -0
- package/dist/commands/configuration.d.ts.map +1 -0
- package/dist/commands/configuration.js +174 -0
- package/dist/commands/development.d.ts +22 -0
- package/dist/commands/development.d.ts.map +1 -0
- package/dist/commands/development.js +132 -0
- package/dist/commands/device.d.ts +3 -0
- package/dist/commands/device.d.ts.map +1 -0
- package/dist/commands/device.js +86 -0
- package/dist/commands/doctor.d.ts +18 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +320 -0
- package/dist/commands/help.d.ts +2 -0
- package/dist/commands/help.d.ts.map +1 -0
- package/dist/commands/help.js +118 -0
- package/dist/commands/i18n.d.ts +14 -0
- package/dist/commands/i18n.d.ts.map +1 -0
- package/dist/commands/i18n.js +88 -0
- package/dist/commands/logs.d.ts +3 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +51 -0
- package/dist/commands/metadata.d.ts +3 -0
- package/dist/commands/metadata.d.ts.map +1 -0
- package/dist/commands/metadata.js +45 -0
- package/dist/commands/ota.d.ts +28 -0
- package/dist/commands/ota.d.ts.map +1 -0
- package/dist/commands/ota.js +203 -0
- package/dist/commands/project.d.ts +14 -0
- package/dist/commands/project.d.ts.map +1 -0
- package/dist/commands/project.js +122 -0
- package/dist/commands/remote-build.d.ts +35 -0
- package/dist/commands/remote-build.d.ts.map +1 -0
- package/dist/commands/remote-build.js +73 -0
- package/dist/commands/submit.d.ts +27 -0
- package/dist/commands/submit.d.ts.map +1 -0
- package/dist/commands/submit.js +92 -0
- package/dist/ecosystem.d.ts +9 -0
- package/dist/ecosystem.d.ts.map +1 -0
- package/dist/ecosystem.js +95 -0
- package/dist/frameworks.d.ts.map +1 -1
- package/dist/frameworks.js +5 -1
- package/dist/guidance/catalog.d.ts +3 -0
- package/dist/guidance/catalog.d.ts.map +1 -0
- package/dist/guidance/catalog.js +504 -0
- package/dist/guidance/types.d.ts +10 -0
- package/dist/guidance/types.d.ts.map +1 -0
- package/dist/guidance/types.js +1 -0
- package/dist/guidance.d.ts +2 -9
- package/dist/guidance.d.ts.map +1 -1
- package/dist/guidance.js +1 -502
- package/dist/i18n/discovery.d.ts +14 -0
- package/dist/i18n/discovery.d.ts.map +1 -0
- package/dist/i18n/discovery.js +106 -0
- package/dist/i18n/plan.d.ts +12 -0
- package/dist/i18n/plan.d.ts.map +1 -0
- package/dist/i18n/plan.js +95 -0
- package/dist/i18n/setup.d.ts +11 -0
- package/dist/i18n/setup.d.ts.map +1 -0
- package/dist/i18n/setup.js +47 -0
- package/dist/i18n/types.d.ts +17 -0
- package/dist/i18n/types.d.ts.map +1 -0
- package/dist/i18n/types.js +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2069
- package/dist/ios/assets.d.ts +19 -0
- package/dist/ios/assets.d.ts.map +1 -0
- package/dist/ios/assets.js +128 -0
- package/dist/ios/production-build.d.ts +6 -0
- package/dist/ios/production-build.d.ts.map +1 -0
- package/dist/ios/production-build.js +200 -0
- package/dist/ios/project.d.ts +4 -0
- package/dist/ios/project.d.ts.map +1 -0
- package/dist/ios/project.js +43 -0
- package/dist/ios/simulator-build.d.ts +8 -0
- package/dist/ios/simulator-build.d.ts.map +1 -0
- package/dist/ios/simulator-build.js +188 -0
- package/dist/ios/simulator.d.ts +5 -0
- package/dist/ios/simulator.d.ts.map +1 -0
- package/dist/ios/simulator.js +60 -0
- package/dist/ios/types.d.ts +14 -0
- package/dist/ios/types.d.ts.map +1 -0
- package/dist/ios/types.js +1 -0
- package/dist/ios-build.d.ts +4 -37
- package/dist/ios-build.d.ts.map +1 -1
- package/dist/ios-build.js +3 -575
- package/dist/ios-host.d.ts.map +1 -1
- package/dist/ios-toolchain/inspection.d.ts +4 -0
- package/dist/ios-toolchain/inspection.d.ts.map +1 -0
- package/dist/ios-toolchain/inspection.js +211 -0
- package/dist/ios-toolchain/probes.d.ts +24 -0
- package/dist/ios-toolchain/probes.d.ts.map +1 -0
- package/dist/ios-toolchain/probes.js +127 -0
- package/dist/ios-toolchain/types.d.ts +17 -0
- package/dist/ios-toolchain/types.d.ts.map +1 -0
- package/dist/ios-toolchain/types.js +1 -0
- package/dist/ios-toolchain.d.ts +3 -18
- package/dist/ios-toolchain.d.ts.map +1 -1
- package/dist/ios-toolchain.js +1 -333
- package/dist/plugins/contracts.d.ts +28 -0
- package/dist/plugins/contracts.d.ts.map +1 -0
- package/dist/plugins/contracts.js +1 -0
- package/dist/plugins/discovery.d.ts +19 -0
- package/dist/plugins/discovery.d.ts.map +1 -0
- package/dist/plugins/discovery.js +250 -0
- package/dist/plugins/native-operations.d.ts +28 -0
- package/dist/plugins/native-operations.d.ts.map +1 -0
- package/dist/plugins/native-operations.js +217 -0
- package/dist/plugins/operations.d.ts +9 -0
- package/dist/plugins/operations.d.ts.map +1 -0
- package/dist/plugins/operations.js +76 -0
- package/dist/plugins/validation.d.ts +9 -0
- package/dist/plugins/validation.d.ts.map +1 -0
- package/dist/plugins/validation.js +52 -0
- package/dist/plugins.d.ts +3 -34
- package/dist/plugins.d.ts.map +1 -1
- package/dist/plugins.js +2 -595
- package/dist/process-runner.d.ts +4 -0
- package/dist/process-runner.d.ts.map +1 -1
- package/dist/process-runner.js +14 -0
- package/dist/remote.d.ts +22 -1
- package/dist/remote.d.ts.map +1 -1
- package/dist/remote.js +141 -2
- package/dist/rspeedy-app-config.d.ts +4 -0
- package/dist/rspeedy-app-config.d.ts.map +1 -0
- package/dist/rspeedy-app-config.js +32 -0
- package/dist/runtime/args.d.ts +3 -0
- package/dist/runtime/args.d.ts.map +1 -0
- package/dist/runtime/args.js +11 -0
- package/dist/runtime/build-commands.d.ts +3 -0
- package/dist/runtime/build-commands.d.ts.map +1 -0
- package/dist/runtime/build-commands.js +282 -0
- package/dist/runtime/context.d.ts +63 -0
- package/dist/runtime/context.d.ts.map +1 -0
- package/dist/runtime/context.js +179 -0
- package/dist/runtime/early-commands.d.ts +4 -0
- package/dist/runtime/early-commands.d.ts.map +1 -0
- package/dist/runtime/early-commands.js +284 -0
- package/dist/runtime/project.d.ts +8 -0
- package/dist/runtime/project.d.ts.map +1 -0
- package/dist/runtime/project.js +38 -0
- package/dist/runtime/state.d.ts +47 -0
- package/dist/runtime/state.d.ts.map +1 -0
- package/dist/runtime/state.js +33 -0
- package/dist/secure-store/backends.d.ts +20 -0
- package/dist/secure-store/backends.d.ts.map +1 -0
- package/dist/secure-store/backends.js +248 -0
- package/dist/secure-store/types.d.ts +27 -0
- package/dist/secure-store/types.d.ts.map +1 -0
- package/dist/secure-store/types.js +1 -0
- package/dist/secure-store.d.ts +2 -26
- package/dist/secure-store.d.ts.map +1 -1
- package/dist/secure-store.js +3 -245
- package/dist/ui/components.d.ts.map +1 -1
- package/dist/ui/components.js +2 -1
- package/package.json +7 -4
- package/templates/android-host/app/build.gradle +1 -0
- package/templates/android-host/app/src/main/java/template/MainActivity.java +98 -3
- package/templates/ios-host/__IOS_TARGET_NAME__/DemoLynxProvider.swift +26 -16
- package/templates/ios-host/__IOS_TARGET_NAME__/ViewController.swift +107 -19
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { homedir, platform } from "node:os";
|
|
2
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
3
|
+
import { join, normalize } from "node:path";
|
|
4
|
+
import { captureProcess, commandExists, executableExists, } from "../process-runner.js";
|
|
5
|
+
const agpMinimumGradle = [
|
|
6
|
+
["9.2", "9.4.1"],
|
|
7
|
+
["9.1", "9.3.1"],
|
|
8
|
+
["9.0", "9.1.0"],
|
|
9
|
+
["8.13", "8.13"],
|
|
10
|
+
["8.12", "8.13"],
|
|
11
|
+
["8.11", "8.13"],
|
|
12
|
+
["8.10", "8.11.1"],
|
|
13
|
+
["8.9", "8.11.1"],
|
|
14
|
+
["8.8", "8.10.2"],
|
|
15
|
+
["8.7", "8.9"],
|
|
16
|
+
["8.6", "8.7"],
|
|
17
|
+
["8.5", "8.7"],
|
|
18
|
+
["8.4", "8.6"],
|
|
19
|
+
["8.3", "8.4"],
|
|
20
|
+
["8.2", "8.2"],
|
|
21
|
+
["8.1", "8.0"],
|
|
22
|
+
["8.0", "8.0"],
|
|
23
|
+
["7.4", "7.5"],
|
|
24
|
+
["7.3", "7.4"],
|
|
25
|
+
["7.2", "7.3.3"],
|
|
26
|
+
["7.1", "7.2"],
|
|
27
|
+
["7.0", "7.0"],
|
|
28
|
+
];
|
|
29
|
+
export function readProjectFiles(root) {
|
|
30
|
+
const files = [
|
|
31
|
+
"android/build.gradle",
|
|
32
|
+
"android/build.gradle.kts",
|
|
33
|
+
"android/settings.gradle",
|
|
34
|
+
"android/settings.gradle.kts",
|
|
35
|
+
"android/app/build.gradle",
|
|
36
|
+
"android/app/build.gradle.kts",
|
|
37
|
+
"android/gradle/libs.versions.toml",
|
|
38
|
+
];
|
|
39
|
+
return files
|
|
40
|
+
.filter((file) => existsSync(join(root, file)))
|
|
41
|
+
.map((file) => readFileSync(join(root, file), "utf8"))
|
|
42
|
+
.join("\n");
|
|
43
|
+
}
|
|
44
|
+
export function readWrapperVersion(root) {
|
|
45
|
+
const file = join(root, "android", "gradle", "wrapper", "gradle-wrapper.properties");
|
|
46
|
+
if (!existsSync(file))
|
|
47
|
+
return undefined;
|
|
48
|
+
const content = readFileSync(file, "utf8");
|
|
49
|
+
return content.match(/gradle-([0-9]+(?:\.[0-9]+){1,2})-(?:bin|all)\.zip/)?.[1];
|
|
50
|
+
}
|
|
51
|
+
export function readAndroidInputs(root) {
|
|
52
|
+
const content = readProjectFiles(root);
|
|
53
|
+
const agpVersion = content.match(/com\.android\.(?:application|library)["']?\)?\s+version\s+["']([0-9]+(?:\.[0-9]+){1,2})["']/)?.[1] ??
|
|
54
|
+
content.match(/com\.android\.tools\.build:gradle:([0-9]+(?:\.[0-9]+){1,2})/)?.[1];
|
|
55
|
+
const compileSdk = content.match(/compileSdk(?:Version)?\s*(?:=|\s)\s*["']?(\d+)/)?.[1];
|
|
56
|
+
const buildToolsVersion = content.match(/buildToolsVersion\s*(?:=|\s)\s*["']([^"']+)["']/)?.[1];
|
|
57
|
+
return {
|
|
58
|
+
agpVersion,
|
|
59
|
+
compileSdk: compileSdk ? Number(compileSdk) : undefined,
|
|
60
|
+
buildToolsVersion,
|
|
61
|
+
gradleVersion: readWrapperVersion(root),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
export function versionParts(version) {
|
|
65
|
+
return version.split(".").map((part) => Number(part) || 0);
|
|
66
|
+
}
|
|
67
|
+
export function compareVersions(left, right) {
|
|
68
|
+
const a = versionParts(left);
|
|
69
|
+
const b = versionParts(right);
|
|
70
|
+
for (let index = 0; index < Math.max(a.length, b.length); index += 1) {
|
|
71
|
+
const difference = (a[index] ?? 0) - (b[index] ?? 0);
|
|
72
|
+
if (difference)
|
|
73
|
+
return difference;
|
|
74
|
+
}
|
|
75
|
+
return 0;
|
|
76
|
+
}
|
|
77
|
+
export function requiredGradleForAgp(agp) {
|
|
78
|
+
if (!agp)
|
|
79
|
+
return undefined;
|
|
80
|
+
return agpMinimumGradle.find(([minimum]) => compareVersions(agp, minimum) >= 0)?.[1];
|
|
81
|
+
}
|
|
82
|
+
export function requiredJavaForAgp(agp) {
|
|
83
|
+
if (!agp)
|
|
84
|
+
return 17;
|
|
85
|
+
if (compareVersions(agp, "8.0") >= 0)
|
|
86
|
+
return 17;
|
|
87
|
+
if (compareVersions(agp, "7.0") >= 0)
|
|
88
|
+
return 11;
|
|
89
|
+
return 8;
|
|
90
|
+
}
|
|
91
|
+
export function sdkCandidates() {
|
|
92
|
+
const values = [process.env.ANDROID_SDK_ROOT, process.env.ANDROID_HOME];
|
|
93
|
+
if (platform() === "win32") {
|
|
94
|
+
values.push(process.env.LOCALAPPDATA
|
|
95
|
+
? join(process.env.LOCALAPPDATA, "Android", "Sdk")
|
|
96
|
+
: undefined);
|
|
97
|
+
}
|
|
98
|
+
else if (platform() === "darwin") {
|
|
99
|
+
values.push(join(homedir(), "Library", "Android", "sdk"));
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
values.push(join(homedir(), "Android", "Sdk"));
|
|
103
|
+
}
|
|
104
|
+
return [
|
|
105
|
+
...new Set(values.filter((value) => Boolean(value)).map(normalize)),
|
|
106
|
+
];
|
|
107
|
+
}
|
|
108
|
+
export function sdkExecutable(sdkPath, name) {
|
|
109
|
+
const extension = platform() === "win32" ? ".exe" : "";
|
|
110
|
+
const candidates = [
|
|
111
|
+
join(sdkPath, "platform-tools", `${name}${extension}`),
|
|
112
|
+
...readDirectories(join(sdkPath, "build-tools")).map((version) => join(sdkPath, "build-tools", version, `${name}${extension}`)),
|
|
113
|
+
];
|
|
114
|
+
return candidates.find(executableExists);
|
|
115
|
+
}
|
|
116
|
+
export function readDirectories(directory) {
|
|
117
|
+
try {
|
|
118
|
+
return readdirSync(directory);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
export function sdkManagerPath(sdkPath) {
|
|
125
|
+
const extension = platform() === "win32" ? ".bat" : "";
|
|
126
|
+
const candidates = [
|
|
127
|
+
join(sdkPath, "cmdline-tools", "latest", "bin", `sdkmanager${extension}`),
|
|
128
|
+
...readDirectories(join(sdkPath, "cmdline-tools"))
|
|
129
|
+
.filter((name) => name !== "latest")
|
|
130
|
+
.map((name) => join(sdkPath, "cmdline-tools", name, "bin", `sdkmanager${extension}`)),
|
|
131
|
+
join(sdkPath, "tools", "bin", `sdkmanager${extension}`),
|
|
132
|
+
];
|
|
133
|
+
return (candidates.find(executableExists) ??
|
|
134
|
+
(commandExists("sdkmanager") ? "sdkmanager" : undefined));
|
|
135
|
+
}
|
|
136
|
+
export async function javaVersion(javaPath, cwd) {
|
|
137
|
+
try {
|
|
138
|
+
const result = await captureProcess(javaPath, ["-version"], { cwd });
|
|
139
|
+
const output = `${result.stdout}\n${result.stderr}`;
|
|
140
|
+
const match = output.match(/version\s+["'](\d+)(?:\.(\d+))?/i);
|
|
141
|
+
if (!match)
|
|
142
|
+
return undefined;
|
|
143
|
+
return Number(match[1]) === 1 ? Number(match[2]) : Number(match[1]);
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
export function javaCandidates() {
|
|
150
|
+
const executable = platform() === "win32" ? "java.exe" : "java";
|
|
151
|
+
const values = [
|
|
152
|
+
process.env.JAVA_HOME
|
|
153
|
+
? join(process.env.JAVA_HOME, "bin", executable)
|
|
154
|
+
: undefined,
|
|
155
|
+
commandExists("java") ? "java" : undefined,
|
|
156
|
+
platform() === "win32"
|
|
157
|
+
? join(process.env.LOCALAPPDATA ?? "", "Programs", "Android", "Android Studio", "jbr", "bin", executable)
|
|
158
|
+
: undefined,
|
|
159
|
+
platform() === "win32"
|
|
160
|
+
? join(process.env.PROGRAMFILES ?? "", "Android", "Android Studio", "jbr", "bin", executable)
|
|
161
|
+
: undefined,
|
|
162
|
+
platform() === "win32"
|
|
163
|
+
? join(process.env.PROGRAMFILES ?? "", "Java", "jdk-17", "bin", executable)
|
|
164
|
+
: undefined,
|
|
165
|
+
platform() === "win32"
|
|
166
|
+
? join(process.env.PROGRAMFILES ?? "", "Eclipse Adoptium", "jdk-17", "bin", executable)
|
|
167
|
+
: undefined,
|
|
168
|
+
platform() === "darwin"
|
|
169
|
+
? "/Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java"
|
|
170
|
+
: undefined,
|
|
171
|
+
platform() === "darwin"
|
|
172
|
+
? "/Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java"
|
|
173
|
+
: undefined,
|
|
174
|
+
platform() === "linux" ? "/opt/android-studio/jbr/bin/java" : undefined,
|
|
175
|
+
platform() === "linux"
|
|
176
|
+
? join(homedir(), "android-studio", "jbr", "bin", "java")
|
|
177
|
+
: undefined,
|
|
178
|
+
];
|
|
179
|
+
return values.filter((value) => Boolean(value));
|
|
180
|
+
}
|
|
181
|
+
export function check(name, status, value, fix) {
|
|
182
|
+
return { name, status, ok: status !== "fail", value, fix };
|
|
183
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type ToolchainCheckStatus = "pass" | "warn" | "fail";
|
|
2
|
+
export interface ToolchainCheck {
|
|
3
|
+
name: string;
|
|
4
|
+
status: ToolchainCheckStatus;
|
|
5
|
+
ok: boolean;
|
|
6
|
+
value: string;
|
|
7
|
+
fix?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface AndroidToolchainReport {
|
|
10
|
+
ok: boolean;
|
|
11
|
+
checks: ToolchainCheck[];
|
|
12
|
+
sdkPath?: string;
|
|
13
|
+
compileSdk?: number;
|
|
14
|
+
buildToolsVersion?: string;
|
|
15
|
+
agpVersion?: string;
|
|
16
|
+
gradleVersion?: string;
|
|
17
|
+
javaVersion?: number;
|
|
18
|
+
sdkPackages: string[];
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/android-toolchain/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5D,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,oBAAoB,CAAC;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,23 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
ok: boolean;
|
|
6
|
-
value: string;
|
|
7
|
-
fix?: string;
|
|
8
|
-
}
|
|
9
|
-
export interface AndroidToolchainReport {
|
|
10
|
-
ok: boolean;
|
|
11
|
-
checks: ToolchainCheck[];
|
|
12
|
-
sdkPath?: string;
|
|
13
|
-
compileSdk?: number;
|
|
14
|
-
buildToolsVersion?: string;
|
|
15
|
-
agpVersion?: string;
|
|
16
|
-
gradleVersion?: string;
|
|
17
|
-
javaVersion?: number;
|
|
18
|
-
sdkPackages: string[];
|
|
19
|
-
}
|
|
20
|
-
export declare function inspectAndroidToolchain(root: string): Promise<AndroidToolchainReport>;
|
|
1
|
+
import type { AndroidToolchainReport } from "./android-toolchain/types.js";
|
|
2
|
+
export type { AndroidToolchainReport, ToolchainCheck, ToolchainCheckStatus, } from "./android-toolchain/types.js";
|
|
3
|
+
import { inspectAndroidToolchain } from "./android-toolchain/inspection.js";
|
|
4
|
+
export { inspectAndroidToolchain };
|
|
21
5
|
export declare function fixAndroidToolchain(root: string, report: AndroidToolchainReport, confirm: (message: string) => Promise<boolean>, onOutput?: (line: string) => void): Promise<void>;
|
|
22
6
|
export declare function formatAndroidToolchainFailure(report: AndroidToolchainReport): string;
|
|
23
7
|
//# sourceMappingURL=android-toolchain.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"android-toolchain.d.ts","sourceRoot":"","sources":["../src/android-toolchain.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"android-toolchain.d.ts","sourceRoot":"","sources":["../src/android-toolchain.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAI3E,YAAY,EACV,sBAAsB,EACtB,cAAc,EACd,oBAAoB,GACrB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAE5E,OAAO,EAAE,uBAAuB,EAAE,CAAC;AAEnC,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,sBAAsB,EAC9B,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAC9C,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAChC,OAAO,CAAC,IAAI,CAAC,CAef;AAED,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,sBAAsB,GAC7B,MAAM,CAQR"}
|
|
@@ -1,303 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
const agpMinimumGradle = [
|
|
6
|
-
["9.2", "9.4.1"],
|
|
7
|
-
["9.1", "9.3.1"],
|
|
8
|
-
["9.0", "9.1.0"],
|
|
9
|
-
["8.13", "8.13"],
|
|
10
|
-
["8.12", "8.13"],
|
|
11
|
-
["8.11", "8.13"],
|
|
12
|
-
["8.10", "8.11.1"],
|
|
13
|
-
["8.9", "8.11.1"],
|
|
14
|
-
["8.8", "8.10.2"],
|
|
15
|
-
["8.7", "8.9"],
|
|
16
|
-
["8.6", "8.7"],
|
|
17
|
-
["8.5", "8.7"],
|
|
18
|
-
["8.4", "8.6"],
|
|
19
|
-
["8.3", "8.4"],
|
|
20
|
-
["8.2", "8.2"],
|
|
21
|
-
["8.1", "8.0"],
|
|
22
|
-
["8.0", "8.0"],
|
|
23
|
-
["7.4", "7.5"],
|
|
24
|
-
["7.3", "7.4"],
|
|
25
|
-
["7.2", "7.3.3"],
|
|
26
|
-
["7.1", "7.2"],
|
|
27
|
-
["7.0", "7.0"],
|
|
28
|
-
];
|
|
29
|
-
function readProjectFiles(root) {
|
|
30
|
-
const files = [
|
|
31
|
-
"android/build.gradle",
|
|
32
|
-
"android/build.gradle.kts",
|
|
33
|
-
"android/settings.gradle",
|
|
34
|
-
"android/settings.gradle.kts",
|
|
35
|
-
"android/app/build.gradle",
|
|
36
|
-
"android/app/build.gradle.kts",
|
|
37
|
-
"android/gradle/libs.versions.toml",
|
|
38
|
-
];
|
|
39
|
-
return files
|
|
40
|
-
.filter((file) => existsSync(join(root, file)))
|
|
41
|
-
.map((file) => readFileSync(join(root, file), "utf8"))
|
|
42
|
-
.join("\n");
|
|
43
|
-
}
|
|
44
|
-
function readWrapperVersion(root) {
|
|
45
|
-
const file = join(root, "android", "gradle", "wrapper", "gradle-wrapper.properties");
|
|
46
|
-
if (!existsSync(file))
|
|
47
|
-
return undefined;
|
|
48
|
-
const content = readFileSync(file, "utf8");
|
|
49
|
-
return content.match(/gradle-([0-9]+(?:\.[0-9]+){1,2})-(?:bin|all)\.zip/)?.[1];
|
|
50
|
-
}
|
|
51
|
-
function readAndroidInputs(root) {
|
|
52
|
-
const content = readProjectFiles(root);
|
|
53
|
-
const agpVersion = content.match(/com\.android\.(?:application|library)["']?\)?\s+version\s+["']([0-9]+(?:\.[0-9]+){1,2})["']/)?.[1] ??
|
|
54
|
-
content.match(/com\.android\.tools\.build:gradle:([0-9]+(?:\.[0-9]+){1,2})/)?.[1];
|
|
55
|
-
const compileSdk = content.match(/compileSdk(?:Version)?\s*(?:=|\s)\s*["']?(\d+)/)?.[1];
|
|
56
|
-
const buildToolsVersion = content.match(/buildToolsVersion\s*(?:=|\s)\s*["']([^"']+)["']/)?.[1];
|
|
57
|
-
return {
|
|
58
|
-
agpVersion,
|
|
59
|
-
compileSdk: compileSdk ? Number(compileSdk) : undefined,
|
|
60
|
-
buildToolsVersion,
|
|
61
|
-
gradleVersion: readWrapperVersion(root),
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
function versionParts(version) {
|
|
65
|
-
return version.split(".").map((part) => Number(part) || 0);
|
|
66
|
-
}
|
|
67
|
-
function compareVersions(left, right) {
|
|
68
|
-
const a = versionParts(left);
|
|
69
|
-
const b = versionParts(right);
|
|
70
|
-
for (let index = 0; index < Math.max(a.length, b.length); index += 1) {
|
|
71
|
-
const difference = (a[index] ?? 0) - (b[index] ?? 0);
|
|
72
|
-
if (difference)
|
|
73
|
-
return difference;
|
|
74
|
-
}
|
|
75
|
-
return 0;
|
|
76
|
-
}
|
|
77
|
-
function requiredGradleForAgp(agp) {
|
|
78
|
-
if (!agp)
|
|
79
|
-
return undefined;
|
|
80
|
-
return agpMinimumGradle.find(([minimum]) => compareVersions(agp, minimum) >= 0)?.[1];
|
|
81
|
-
}
|
|
82
|
-
function requiredJavaForAgp(agp) {
|
|
83
|
-
if (!agp)
|
|
84
|
-
return 17;
|
|
85
|
-
if (compareVersions(agp, "8.0") >= 0)
|
|
86
|
-
return 17;
|
|
87
|
-
if (compareVersions(agp, "7.0") >= 0)
|
|
88
|
-
return 11;
|
|
89
|
-
return 8;
|
|
90
|
-
}
|
|
91
|
-
function sdkCandidates() {
|
|
92
|
-
const values = [process.env.ANDROID_SDK_ROOT, process.env.ANDROID_HOME];
|
|
93
|
-
if (platform() === "win32") {
|
|
94
|
-
values.push(process.env.LOCALAPPDATA
|
|
95
|
-
? join(process.env.LOCALAPPDATA, "Android", "Sdk")
|
|
96
|
-
: undefined);
|
|
97
|
-
}
|
|
98
|
-
else if (platform() === "darwin") {
|
|
99
|
-
values.push(join(homedir(), "Library", "Android", "sdk"));
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
values.push(join(homedir(), "Android", "Sdk"));
|
|
103
|
-
}
|
|
104
|
-
return [
|
|
105
|
-
...new Set(values.filter((value) => Boolean(value)).map(normalize)),
|
|
106
|
-
];
|
|
107
|
-
}
|
|
108
|
-
function sdkExecutable(sdkPath, name) {
|
|
109
|
-
const extension = platform() === "win32" ? ".exe" : "";
|
|
110
|
-
const candidates = [
|
|
111
|
-
join(sdkPath, "platform-tools", `${name}${extension}`),
|
|
112
|
-
...readDirectories(join(sdkPath, "build-tools")).map((version) => join(sdkPath, "build-tools", version, `${name}${extension}`)),
|
|
113
|
-
];
|
|
114
|
-
return candidates.find(executableExists);
|
|
115
|
-
}
|
|
116
|
-
function readDirectories(directory) {
|
|
117
|
-
try {
|
|
118
|
-
return readdirSync(directory);
|
|
119
|
-
}
|
|
120
|
-
catch {
|
|
121
|
-
return [];
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
function sdkManagerPath(sdkPath) {
|
|
125
|
-
const extension = platform() === "win32" ? ".bat" : "";
|
|
126
|
-
const candidates = [
|
|
127
|
-
join(sdkPath, "cmdline-tools", "latest", "bin", `sdkmanager${extension}`),
|
|
128
|
-
...readDirectories(join(sdkPath, "cmdline-tools"))
|
|
129
|
-
.filter((name) => name !== "latest")
|
|
130
|
-
.map((name) => join(sdkPath, "cmdline-tools", name, "bin", `sdkmanager${extension}`)),
|
|
131
|
-
join(sdkPath, "tools", "bin", `sdkmanager${extension}`),
|
|
132
|
-
];
|
|
133
|
-
return (candidates.find(executableExists) ??
|
|
134
|
-
(commandExists("sdkmanager") ? "sdkmanager" : undefined));
|
|
135
|
-
}
|
|
136
|
-
async function javaVersion(javaPath, cwd) {
|
|
137
|
-
try {
|
|
138
|
-
const result = await captureProcess(javaPath, ["-version"], { cwd });
|
|
139
|
-
const output = `${result.stdout}\n${result.stderr}`;
|
|
140
|
-
const match = output.match(/version\s+["'](\d+)(?:\.(\d+))?/i);
|
|
141
|
-
if (!match)
|
|
142
|
-
return undefined;
|
|
143
|
-
return Number(match[1]) === 1 ? Number(match[2]) : Number(match[1]);
|
|
144
|
-
}
|
|
145
|
-
catch {
|
|
146
|
-
return undefined;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
function javaCandidates() {
|
|
150
|
-
const executable = platform() === "win32" ? "java.exe" : "java";
|
|
151
|
-
const values = [
|
|
152
|
-
process.env.JAVA_HOME
|
|
153
|
-
? join(process.env.JAVA_HOME, "bin", executable)
|
|
154
|
-
: undefined,
|
|
155
|
-
commandExists("java") ? "java" : undefined,
|
|
156
|
-
platform() === "win32"
|
|
157
|
-
? join(process.env.LOCALAPPDATA ?? "", "Programs", "Android", "Android Studio", "jbr", "bin", executable)
|
|
158
|
-
: undefined,
|
|
159
|
-
platform() === "win32"
|
|
160
|
-
? join(process.env.PROGRAMFILES ?? "", "Android", "Android Studio", "jbr", "bin", executable)
|
|
161
|
-
: undefined,
|
|
162
|
-
platform() === "win32"
|
|
163
|
-
? join(process.env.PROGRAMFILES ?? "", "Java", "jdk-17", "bin", executable)
|
|
164
|
-
: undefined,
|
|
165
|
-
platform() === "win32"
|
|
166
|
-
? join(process.env.PROGRAMFILES ?? "", "Eclipse Adoptium", "jdk-17", "bin", executable)
|
|
167
|
-
: undefined,
|
|
168
|
-
platform() === "darwin"
|
|
169
|
-
? "/Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java"
|
|
170
|
-
: undefined,
|
|
171
|
-
platform() === "darwin"
|
|
172
|
-
? "/Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java"
|
|
173
|
-
: undefined,
|
|
174
|
-
platform() === "linux" ? "/opt/android-studio/jbr/bin/java" : undefined,
|
|
175
|
-
platform() === "linux"
|
|
176
|
-
? join(homedir(), "android-studio", "jbr", "bin", "java")
|
|
177
|
-
: undefined,
|
|
178
|
-
];
|
|
179
|
-
return values.filter((value) => Boolean(value));
|
|
180
|
-
}
|
|
181
|
-
function check(name, status, value, fix) {
|
|
182
|
-
return { name, status, ok: status !== "fail", value, fix };
|
|
183
|
-
}
|
|
184
|
-
export async function inspectAndroidToolchain(root) {
|
|
185
|
-
const inputs = readAndroidInputs(root);
|
|
186
|
-
const checks = [];
|
|
187
|
-
const wrapper = join(root, "android", platform() === "win32" ? "gradlew.bat" : "gradlew");
|
|
188
|
-
const wrapperExists = existsSync(wrapper) &&
|
|
189
|
-
(platform() === "win32" || executableExists(wrapper));
|
|
190
|
-
checks.push(check("gradle-wrapper", wrapperExists ? "pass" : "fail", wrapperExists
|
|
191
|
-
? inputs.gradleVersion
|
|
192
|
-
? `Gradle ${inputs.gradleVersion}`
|
|
193
|
-
: "found · version unknown"
|
|
194
|
-
: "missing", wrapperExists
|
|
195
|
-
? undefined
|
|
196
|
-
: "lynxship android host init --application-id com.example.myapp"));
|
|
197
|
-
const minimumGradle = requiredGradleForAgp(inputs.agpVersion);
|
|
198
|
-
const gradleCompatible = Boolean(inputs.gradleVersion &&
|
|
199
|
-
minimumGradle &&
|
|
200
|
-
compareVersions(inputs.gradleVersion, minimumGradle) >= 0);
|
|
201
|
-
const gradleStatus = !inputs.gradleVersion || !inputs.agpVersion
|
|
202
|
-
? "warn"
|
|
203
|
-
: gradleCompatible
|
|
204
|
-
? "pass"
|
|
205
|
-
: "fail";
|
|
206
|
-
checks.push(check("agp-gradle-compatibility", gradleStatus, inputs.agpVersion && inputs.gradleVersion
|
|
207
|
-
? `AGP ${inputs.agpVersion} · Gradle ${inputs.gradleVersion}${minimumGradle ? ` · minimum Gradle ${minimumGradle}` : ""}`
|
|
208
|
-
: "AGP or wrapper version not detected", gradleStatus === "fail" && minimumGradle
|
|
209
|
-
? `Update the project wrapper to Gradle ${minimumGradle}; do not use a global Gradle installation`
|
|
210
|
-
: undefined));
|
|
211
|
-
const requiredJava = requiredJavaForAgp(inputs.agpVersion);
|
|
212
|
-
let detectedJava;
|
|
213
|
-
let javaPath;
|
|
214
|
-
for (const candidate of javaCandidates()) {
|
|
215
|
-
const version = await javaVersion(candidate, root);
|
|
216
|
-
if (version !== undefined) {
|
|
217
|
-
detectedJava = version;
|
|
218
|
-
javaPath = candidate;
|
|
219
|
-
break;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
const javaStatus = detectedJava === undefined
|
|
223
|
-
? "fail"
|
|
224
|
-
: detectedJava >= requiredJava
|
|
225
|
-
? "pass"
|
|
226
|
-
: "fail";
|
|
227
|
-
checks.push(check("java", javaStatus, detectedJava === undefined
|
|
228
|
-
? "missing"
|
|
229
|
-
: `JDK ${detectedJava}${javaPath === "java" ? " · PATH" : ""}`, javaStatus === "fail"
|
|
230
|
-
? `Install/configure JDK ${requiredJava} and set JAVA_HOME, then run lynxship doctor --platform android`
|
|
231
|
-
: undefined));
|
|
232
|
-
const sdkPath = sdkCandidates().find((candidate) => existsSync(candidate));
|
|
233
|
-
const compileSdk = inputs.compileSdk;
|
|
234
|
-
const buildTools = inputs.buildToolsVersion;
|
|
235
|
-
const platformPackage = compileSdk
|
|
236
|
-
? `platforms;android-${compileSdk}`
|
|
237
|
-
: undefined;
|
|
238
|
-
const buildToolsPackage = buildTools
|
|
239
|
-
? `build-tools;${buildTools}`
|
|
240
|
-
: undefined;
|
|
241
|
-
const missingPackages = [
|
|
242
|
-
platformPackage &&
|
|
243
|
-
sdkPath &&
|
|
244
|
-
!existsSync(join(sdkPath, "platforms", `android-${compileSdk}`))
|
|
245
|
-
? platformPackage
|
|
246
|
-
: undefined,
|
|
247
|
-
buildTools &&
|
|
248
|
-
sdkPath &&
|
|
249
|
-
!existsSync(join(sdkPath, "build-tools", buildTools))
|
|
250
|
-
? buildToolsPackage
|
|
251
|
-
: undefined,
|
|
252
|
-
].filter((value) => Boolean(value));
|
|
253
|
-
const sdkStatus = !sdkPath
|
|
254
|
-
? "fail"
|
|
255
|
-
: missingPackages.length
|
|
256
|
-
? "fail"
|
|
257
|
-
: "pass";
|
|
258
|
-
checks.push(check("android-sdk", sdkStatus, !sdkPath
|
|
259
|
-
? "missing · set ANDROID_HOME or ANDROID_SDK_ROOT"
|
|
260
|
-
: missingPackages.length
|
|
261
|
-
? `missing: ${missingPackages.join(", ")}`
|
|
262
|
-
: sdkPath, sdkStatus === "fail"
|
|
263
|
-
? "Install Android Studio or the Android command-line tools, then run lynxship doctor --platform android --fix"
|
|
264
|
-
: undefined));
|
|
265
|
-
const manager = sdkPath ? sdkManagerPath(sdkPath) : undefined;
|
|
266
|
-
checks.push(check("sdkmanager", manager ? "pass" : sdkPath ? "warn" : "fail", manager
|
|
267
|
-
? "available"
|
|
268
|
-
: sdkPath
|
|
269
|
-
? "missing · use Android Studio SDK Manager"
|
|
270
|
-
: "unavailable until Android SDK is installed", manager && missingPackages.length
|
|
271
|
-
? `sdkmanager ${missingPackages.map((value) => `"${value}"`).join(" ")}`
|
|
272
|
-
: undefined));
|
|
273
|
-
const adb = sdkPath ? sdkExecutable(sdkPath, "adb") : undefined;
|
|
274
|
-
checks.push(check("adb", adb || commandExists("adb") ? "pass" : "warn", adb || commandExists("adb")
|
|
275
|
-
? "Android Platform-Tools available"
|
|
276
|
-
: "missing · required for lynxship run/logs", !adb && !commandExists("adb")
|
|
277
|
-
? "Install Android SDK Platform-Tools, then run adb devices"
|
|
278
|
-
: undefined));
|
|
279
|
-
const apksigner = sdkPath ? sdkExecutable(sdkPath, "apksigner") : undefined;
|
|
280
|
-
checks.push(check("apksigner", apksigner || commandExists("apksigner") ? "pass" : "warn", apksigner || commandExists("apksigner")
|
|
281
|
-
? "Android Build Tools available"
|
|
282
|
-
: "missing · required to verify APK signatures", !apksigner && !commandExists("apksigner")
|
|
283
|
-
? "Install Android SDK Build Tools, then run lynxship doctor --platform android"
|
|
284
|
-
: undefined));
|
|
285
|
-
checks.push(check("android-sdk-licenses", sdkPath && existsSync(join(sdkPath, "licenses")) ? "pass" : "warn", sdkPath && existsSync(join(sdkPath, "licenses"))
|
|
286
|
-
? "license directory found"
|
|
287
|
-
: "not verified", sdkPath ? "sdkmanager --licenses" : undefined));
|
|
288
|
-
const failures = checks.filter((item) => item.status === "fail");
|
|
289
|
-
return {
|
|
290
|
-
ok: failures.length === 0,
|
|
291
|
-
checks,
|
|
292
|
-
sdkPath,
|
|
293
|
-
compileSdk,
|
|
294
|
-
buildToolsVersion: buildTools,
|
|
295
|
-
agpVersion: inputs.agpVersion,
|
|
296
|
-
gradleVersion: inputs.gradleVersion,
|
|
297
|
-
javaVersion: detectedJava,
|
|
298
|
-
sdkPackages: missingPackages,
|
|
299
|
-
};
|
|
300
|
-
}
|
|
1
|
+
import { runProcess } from "./process-runner.js";
|
|
2
|
+
import { sdkManagerPath } from "./android-toolchain/probes.js";
|
|
3
|
+
import { inspectAndroidToolchain } from "./android-toolchain/inspection.js";
|
|
4
|
+
export { inspectAndroidToolchain };
|
|
301
5
|
export async function fixAndroidToolchain(root, report, confirm, onOutput) {
|
|
302
6
|
const managerCheck = report.checks.find((item) => item.name === "sdkmanager");
|
|
303
7
|
const manager = report.sdkPath ? sdkManagerPath(report.sdkPath) : undefined;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type Platform } from "@lynxship/contracts";
|
|
2
|
+
import { type LynxShipAppConfig } from "@lynxship/framework";
|
|
3
|
+
export interface AppConfigFactoryContext {
|
|
4
|
+
readonly command: "build" | "dev" | "doctor";
|
|
5
|
+
readonly env: string;
|
|
6
|
+
}
|
|
7
|
+
export interface LoadedLynxShipAppConfig {
|
|
8
|
+
readonly path: string;
|
|
9
|
+
readonly config: LynxShipAppConfig;
|
|
10
|
+
}
|
|
11
|
+
/** Find the single Sparkling-compatible app config without executing it. */
|
|
12
|
+
export declare function findAppConfig(root: string): string | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Load and validate a Sparkling-style app.config file only on an explicit
|
|
15
|
+
* command path. Discovery remains source-only so `doctor` and project scans
|
|
16
|
+
* never execute arbitrary project modules accidentally.
|
|
17
|
+
*/
|
|
18
|
+
export declare function loadAppConfig(root: string, options?: {
|
|
19
|
+
command?: AppConfigFactoryContext["command"];
|
|
20
|
+
required?: boolean;
|
|
21
|
+
}): Promise<LoadedLynxShipAppConfig | undefined>;
|
|
22
|
+
/** Resolve an app.config asset destination while keeping it inside the project. */
|
|
23
|
+
export declare function resolveAppConfigAssetPath(root: string, config: LoadedLynxShipAppConfig | undefined, platform: Platform, fallback: string): string;
|
|
24
|
+
export declare function resolveAppConfigProjectPath(root: string, value: string | undefined, field: string): string | undefined;
|
|
25
|
+
//# sourceMappingURL=app-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-config.d.ts","sourceRoot":"","sources":["../src/app-config.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiB,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,qBAAqB,CAAC;AAa7B,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAC;IAC7C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;CACpC;AAiBD,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAY9D;AAgCD;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IACP,OAAO,CAAC,EAAE,uBAAuB,CAAC,SAAS,CAAC,CAAC;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACf,GACL,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAAC,CAkD9C;AAED,mFAAmF;AACnF,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,uBAAuB,GAAG,SAAS,EAC3C,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,GACf,MAAM,CAUR;AAED,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,KAAK,EAAE,MAAM,GACZ,MAAM,GAAG,SAAS,CAUpB"}
|