@minecraft-docker/mcctl 1.6.0 → 1.6.2
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/dist/application/index.d.ts +2 -0
- package/dist/application/index.d.ts.map +1 -0
- package/dist/application/index.js +5 -0
- package/dist/application/index.js.map +1 -0
- package/dist/commands/backup.d.ts +16 -0
- package/dist/commands/backup.d.ts.map +1 -0
- package/dist/commands/backup.js +182 -0
- package/dist/commands/backup.js.map +1 -0
- package/dist/commands/ban.d.ts +14 -0
- package/dist/commands/ban.d.ts.map +1 -0
- package/dist/commands/ban.js +418 -0
- package/dist/commands/ban.js.map +1 -0
- package/dist/commands/config.d.ts +18 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +106 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/console/api.d.ts +19 -0
- package/dist/commands/console/api.d.ts.map +1 -0
- package/dist/commands/console/api.js +399 -0
- package/dist/commands/console/api.js.map +1 -0
- package/dist/commands/console/index.d.ts +10 -0
- package/dist/commands/console/index.d.ts.map +1 -0
- package/dist/commands/console/index.js +12 -0
- package/dist/commands/console/index.js.map +1 -0
- package/dist/commands/console/init.d.ts +47 -0
- package/dist/commands/console/init.d.ts.map +1 -0
- package/dist/commands/console/init.js +491 -0
- package/dist/commands/console/init.js.map +1 -0
- package/dist/commands/console/remove.d.ts +25 -0
- package/dist/commands/console/remove.d.ts.map +1 -0
- package/dist/commands/console/remove.js +189 -0
- package/dist/commands/console/remove.js.map +1 -0
- package/dist/commands/console/service.d.ts +40 -0
- package/dist/commands/console/service.d.ts.map +1 -0
- package/dist/commands/console/service.js +321 -0
- package/dist/commands/console/service.js.map +1 -0
- package/dist/commands/console/user.d.ts +17 -0
- package/dist/commands/console/user.d.ts.map +1 -0
- package/dist/commands/console/user.js +431 -0
- package/dist/commands/console/user.js.map +1 -0
- package/dist/commands/create.d.ts +22 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +86 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/delete.d.ts +17 -0
- package/dist/commands/delete.d.ts.map +1 -0
- package/dist/commands/delete.js +74 -0
- package/dist/commands/delete.js.map +1 -0
- package/dist/commands/exec.d.ts +10 -0
- package/dist/commands/exec.d.ts.map +1 -0
- package/dist/commands/exec.js +29 -0
- package/dist/commands/exec.js.map +1 -0
- package/dist/commands/index.d.ts +21 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +23 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.d.ts +9 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +218 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/kick.d.ts +12 -0
- package/dist/commands/kick.d.ts.map +1 -0
- package/dist/commands/kick.js +71 -0
- package/dist/commands/kick.js.map +1 -0
- package/dist/commands/migrate.d.ts +18 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +470 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/mod.d.ts +19 -0
- package/dist/commands/mod.d.ts.map +1 -0
- package/dist/commands/mod.js +441 -0
- package/dist/commands/mod.js.map +1 -0
- package/dist/commands/msg.d.ts +12 -0
- package/dist/commands/msg.d.ts.map +1 -0
- package/dist/commands/msg.js +273 -0
- package/dist/commands/msg.js.map +1 -0
- package/dist/commands/op.d.ts +12 -0
- package/dist/commands/op.d.ts.map +1 -0
- package/dist/commands/op.js +220 -0
- package/dist/commands/op.js.map +1 -0
- package/dist/commands/player-online.d.ts +11 -0
- package/dist/commands/player-online.d.ts.map +1 -0
- package/dist/commands/player-online.js +153 -0
- package/dist/commands/player-online.js.map +1 -0
- package/dist/commands/player.d.ts +18 -0
- package/dist/commands/player.d.ts.map +1 -0
- package/dist/commands/player.js +352 -0
- package/dist/commands/player.js.map +1 -0
- package/dist/commands/server-backup.d.ts +36 -0
- package/dist/commands/server-backup.d.ts.map +1 -0
- package/dist/commands/server-backup.js +320 -0
- package/dist/commands/server-backup.js.map +1 -0
- package/dist/commands/server-restore.d.ts +13 -0
- package/dist/commands/server-restore.d.ts.map +1 -0
- package/dist/commands/server-restore.js +294 -0
- package/dist/commands/server-restore.js.map +1 -0
- package/dist/commands/status.d.ts +13 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +325 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/whitelist.d.ts +12 -0
- package/dist/commands/whitelist.d.ts.map +1 -0
- package/dist/commands/whitelist.js +316 -0
- package/dist/commands/whitelist.js.map +1 -0
- package/dist/commands/world.d.ts +18 -0
- package/dist/commands/world.d.ts.map +1 -0
- package/dist/commands/world.js +238 -0
- package/dist/commands/world.js.map +1 -0
- package/dist/domain/index.d.ts +2 -0
- package/dist/domain/index.d.ts.map +1 -0
- package/dist/domain/index.js +7 -0
- package/dist/domain/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +766 -0
- package/dist/index.js.map +1 -0
- package/dist/infrastructure/adapters/ClackPromptAdapter.d.ts +30 -0
- package/dist/infrastructure/adapters/ClackPromptAdapter.d.ts.map +1 -0
- package/dist/infrastructure/adapters/ClackPromptAdapter.js +430 -0
- package/dist/infrastructure/adapters/ClackPromptAdapter.js.map +1 -0
- package/dist/infrastructure/adapters/Pm2ServiceManagerAdapter.d.ts +78 -0
- package/dist/infrastructure/adapters/Pm2ServiceManagerAdapter.d.ts.map +1 -0
- package/dist/infrastructure/adapters/Pm2ServiceManagerAdapter.js +391 -0
- package/dist/infrastructure/adapters/Pm2ServiceManagerAdapter.js.map +1 -0
- package/dist/infrastructure/adapters/index.d.ts +4 -0
- package/dist/infrastructure/adapters/index.d.ts.map +1 -0
- package/dist/infrastructure/adapters/index.js +6 -0
- package/dist/infrastructure/adapters/index.js.map +1 -0
- package/dist/infrastructure/di/container.d.ts +47 -0
- package/dist/infrastructure/di/container.d.ts.map +1 -0
- package/dist/infrastructure/di/container.js +140 -0
- package/dist/infrastructure/di/container.js.map +1 -0
- package/dist/infrastructure/di/index.d.ts +2 -0
- package/dist/infrastructure/di/index.d.ts.map +1 -0
- package/dist/infrastructure/di/index.js +2 -0
- package/dist/infrastructure/di/index.js.map +1 -0
- package/dist/infrastructure/index.d.ts +5 -0
- package/dist/infrastructure/index.d.ts.map +1 -0
- package/dist/infrastructure/index.js +8 -0
- package/dist/infrastructure/index.js.map +1 -0
- package/dist/lib/admin-config.d.ts +66 -0
- package/dist/lib/admin-config.d.ts.map +1 -0
- package/dist/lib/admin-config.js +130 -0
- package/dist/lib/admin-config.js.map +1 -0
- package/dist/lib/mojang-api.d.ts +51 -0
- package/dist/lib/mojang-api.d.ts.map +1 -0
- package/dist/lib/mojang-api.js +136 -0
- package/dist/lib/mojang-api.js.map +1 -0
- package/dist/lib/player-cache.d.ts +79 -0
- package/dist/lib/player-cache.d.ts.map +1 -0
- package/dist/lib/player-cache.js +302 -0
- package/dist/lib/player-cache.js.map +1 -0
- package/dist/lib/player-json.d.ts +69 -0
- package/dist/lib/player-json.d.ts.map +1 -0
- package/dist/lib/player-json.js +96 -0
- package/dist/lib/player-json.js.map +1 -0
- package/dist/lib/pm2-utils.d.ts +71 -0
- package/dist/lib/pm2-utils.d.ts.map +1 -0
- package/dist/lib/pm2-utils.js +155 -0
- package/dist/lib/pm2-utils.js.map +1 -0
- package/dist/lib/prompts/action-select.d.ts +23 -0
- package/dist/lib/prompts/action-select.d.ts.map +1 -0
- package/dist/lib/prompts/action-select.js +124 -0
- package/dist/lib/prompts/action-select.js.map +1 -0
- package/dist/lib/prompts/index.d.ts +7 -0
- package/dist/lib/prompts/index.d.ts.map +1 -0
- package/dist/lib/prompts/index.js +7 -0
- package/dist/lib/prompts/index.js.map +1 -0
- package/dist/lib/prompts/ip-select.d.ts +25 -0
- package/dist/lib/prompts/ip-select.d.ts.map +1 -0
- package/dist/lib/prompts/ip-select.js +255 -0
- package/dist/lib/prompts/ip-select.js.map +1 -0
- package/dist/lib/prompts/player-select.d.ts +25 -0
- package/dist/lib/prompts/player-select.d.ts.map +1 -0
- package/dist/lib/prompts/player-select.js +122 -0
- package/dist/lib/prompts/player-select.js.map +1 -0
- package/dist/lib/prompts/server-select.d.ts +26 -0
- package/dist/lib/prompts/server-select.d.ts.map +1 -0
- package/dist/lib/prompts/server-select.js +99 -0
- package/dist/lib/prompts/server-select.js.map +1 -0
- package/dist/lib/rcon.d.ts +53 -0
- package/dist/lib/rcon.d.ts.map +1 -0
- package/dist/lib/rcon.js +131 -0
- package/dist/lib/rcon.js.map +1 -0
- package/dist/lib/shell.d.ts +111 -0
- package/dist/lib/shell.d.ts.map +1 -0
- package/dist/lib/shell.js +321 -0
- package/dist/lib/shell.js.map +1 -0
- package/dist/lib/sudo-utils.d.ts +14 -0
- package/dist/lib/sudo-utils.d.ts.map +1 -0
- package/dist/lib/sudo-utils.js +53 -0
- package/dist/lib/sudo-utils.js.map +1 -0
- package/package.json +8 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"player-select.d.ts","sourceRoot":"","sources":["../../../src/lib/prompts/player-select.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAC7B;AAID;;;GAGG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAgF/F;AA2BD;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,SAAuB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoB7F"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Player selection prompt component
|
|
3
|
+
* Reusable prompt for selecting a player from online players or manual entry
|
|
4
|
+
*/
|
|
5
|
+
import { select, text, isCancel } from '@clack/prompts';
|
|
6
|
+
import { colors, log } from '@minecraft-docker/shared';
|
|
7
|
+
import { getOnlinePlayers } from '../rcon.js';
|
|
8
|
+
const MANUAL_ENTRY_VALUE = '__manual__';
|
|
9
|
+
/**
|
|
10
|
+
* Prompt user to select a player
|
|
11
|
+
* Returns the selected player info or null if cancelled
|
|
12
|
+
*/
|
|
13
|
+
export async function selectPlayer(options) {
|
|
14
|
+
const { containerName, message = 'Select player:', allowManualEntry = true, includeOffline = false, } = options;
|
|
15
|
+
// Get online players
|
|
16
|
+
let onlinePlayers = [];
|
|
17
|
+
try {
|
|
18
|
+
const result = await getOnlinePlayers(containerName);
|
|
19
|
+
onlinePlayers = result.players;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// Ignore errors, just show empty list
|
|
23
|
+
}
|
|
24
|
+
// Build options list
|
|
25
|
+
const selectOptions = [];
|
|
26
|
+
// Add online players
|
|
27
|
+
for (const player of onlinePlayers) {
|
|
28
|
+
selectOptions.push({
|
|
29
|
+
value: player,
|
|
30
|
+
label: player,
|
|
31
|
+
hint: colors.green('online'),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
// Add manual entry option if allowed
|
|
35
|
+
if (allowManualEntry) {
|
|
36
|
+
selectOptions.push({
|
|
37
|
+
value: MANUAL_ENTRY_VALUE,
|
|
38
|
+
label: 'Enter player name manually',
|
|
39
|
+
hint: colors.dim('type a name'),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
// If no options available
|
|
43
|
+
if (selectOptions.length === 0) {
|
|
44
|
+
log.error('No players available and manual entry is disabled');
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
// If only manual entry is available
|
|
48
|
+
const firstOption = selectOptions[0];
|
|
49
|
+
if (selectOptions.length === 1 && firstOption && firstOption.value === MANUAL_ENTRY_VALUE) {
|
|
50
|
+
log.info('No players online, entering manual mode');
|
|
51
|
+
const playerName = await promptManualPlayerName();
|
|
52
|
+
if (!playerName)
|
|
53
|
+
return null;
|
|
54
|
+
return { name: playerName, isOnline: false, source: 'manual' };
|
|
55
|
+
}
|
|
56
|
+
const selected = await select({
|
|
57
|
+
message,
|
|
58
|
+
options: selectOptions,
|
|
59
|
+
});
|
|
60
|
+
if (isCancel(selected)) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
// Handle manual entry
|
|
64
|
+
if (selected === MANUAL_ENTRY_VALUE) {
|
|
65
|
+
const playerName = await promptManualPlayerName();
|
|
66
|
+
if (!playerName)
|
|
67
|
+
return null;
|
|
68
|
+
const isOnline = onlinePlayers.some(p => p.toLowerCase() === playerName.toLowerCase());
|
|
69
|
+
return { name: playerName, isOnline, source: 'manual' };
|
|
70
|
+
}
|
|
71
|
+
// Return selected online player
|
|
72
|
+
return {
|
|
73
|
+
name: selected,
|
|
74
|
+
isOnline: true,
|
|
75
|
+
source: 'online',
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Prompt for manual player name entry
|
|
80
|
+
*/
|
|
81
|
+
async function promptManualPlayerName() {
|
|
82
|
+
const playerName = await text({
|
|
83
|
+
message: 'Enter player name:',
|
|
84
|
+
placeholder: 'Notch',
|
|
85
|
+
validate: (value) => {
|
|
86
|
+
if (!value || value.trim().length === 0) {
|
|
87
|
+
return 'Player name is required';
|
|
88
|
+
}
|
|
89
|
+
if (!/^[a-zA-Z0-9_]{3,16}$/.test(value.trim())) {
|
|
90
|
+
return 'Invalid player name (3-16 characters, letters, numbers, underscore)';
|
|
91
|
+
}
|
|
92
|
+
return undefined;
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
if (isCancel(playerName)) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
return playerName.trim();
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Simple text prompt for player name
|
|
102
|
+
*/
|
|
103
|
+
export async function promptPlayerName(message = 'Enter player name:') {
|
|
104
|
+
const playerName = await text({
|
|
105
|
+
message,
|
|
106
|
+
placeholder: 'Notch',
|
|
107
|
+
validate: (value) => {
|
|
108
|
+
if (!value || value.trim().length === 0) {
|
|
109
|
+
return 'Player name is required';
|
|
110
|
+
}
|
|
111
|
+
if (!/^[a-zA-Z0-9_]{3,16}$/.test(value.trim())) {
|
|
112
|
+
return 'Invalid player name (3-16 characters, letters, numbers, underscore)';
|
|
113
|
+
}
|
|
114
|
+
return undefined;
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
if (isCancel(playerName)) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
return playerName.trim();
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=player-select.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"player-select.js","sourceRoot":"","sources":["../../../src/lib/prompts/player-select.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server selection prompt component
|
|
3
|
+
* Reusable prompt for selecting a Minecraft server
|
|
4
|
+
*/
|
|
5
|
+
export interface ServerInfo {
|
|
6
|
+
name: string;
|
|
7
|
+
containerName: string;
|
|
8
|
+
status: 'running' | 'stopped' | 'unknown';
|
|
9
|
+
playerCount?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface ServerSelectOptions {
|
|
12
|
+
message?: string;
|
|
13
|
+
servers: ServerInfo[];
|
|
14
|
+
includeAllOption?: boolean;
|
|
15
|
+
allowOffline?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Prompt user to select a server
|
|
19
|
+
* Returns the server name or null if cancelled
|
|
20
|
+
*/
|
|
21
|
+
export declare function selectServer(options: ServerSelectOptions): Promise<string | null>;
|
|
22
|
+
/**
|
|
23
|
+
* Get list of servers from Docker
|
|
24
|
+
*/
|
|
25
|
+
export declare function getServerList(): Promise<ServerInfo[]>;
|
|
26
|
+
//# sourceMappingURL=server-select.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-select.d.ts","sourceRoot":"","sources":["../../../src/lib/prompts/server-select.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoEvF;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAkC3D"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server selection prompt component
|
|
3
|
+
* Reusable prompt for selecting a Minecraft server
|
|
4
|
+
*/
|
|
5
|
+
import { select, isCancel } from '@clack/prompts';
|
|
6
|
+
import { colors, log } from '@minecraft-docker/shared';
|
|
7
|
+
import { getOnlinePlayerCount } from '../rcon.js';
|
|
8
|
+
/**
|
|
9
|
+
* Prompt user to select a server
|
|
10
|
+
* Returns the server name or null if cancelled
|
|
11
|
+
*/
|
|
12
|
+
export async function selectServer(options) {
|
|
13
|
+
const { servers, message = 'Select server:', includeAllOption = false, allowOffline = false } = options;
|
|
14
|
+
if (servers.length === 0) {
|
|
15
|
+
log.error('No servers found');
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
// Filter to running servers only if not allowing offline
|
|
19
|
+
const availableServers = allowOffline ? servers : servers.filter(s => s.status === 'running');
|
|
20
|
+
if (availableServers.length === 0) {
|
|
21
|
+
log.error('No running servers found');
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
// Fetch player counts for running servers
|
|
25
|
+
const serversWithPlayers = await Promise.all(availableServers.map(async (server) => {
|
|
26
|
+
if (server.status === 'running' && server.playerCount === undefined) {
|
|
27
|
+
try {
|
|
28
|
+
const count = await getOnlinePlayerCount(server.containerName);
|
|
29
|
+
return { ...server, playerCount: count };
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return { ...server, playerCount: 0 };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return server;
|
|
36
|
+
}));
|
|
37
|
+
// Build options list
|
|
38
|
+
const selectOptions = [];
|
|
39
|
+
if (includeAllOption) {
|
|
40
|
+
selectOptions.push({
|
|
41
|
+
value: '__all__',
|
|
42
|
+
label: 'All servers',
|
|
43
|
+
hint: `${serversWithPlayers.length} servers`,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
for (const server of serversWithPlayers) {
|
|
47
|
+
const statusLabel = server.status === 'running'
|
|
48
|
+
? colors.green('online')
|
|
49
|
+
: colors.dim('offline');
|
|
50
|
+
const playerLabel = server.status === 'running' && server.playerCount !== undefined
|
|
51
|
+
? `${server.playerCount} player${server.playerCount !== 1 ? 's' : ''}`
|
|
52
|
+
: '';
|
|
53
|
+
selectOptions.push({
|
|
54
|
+
value: server.name,
|
|
55
|
+
label: server.name,
|
|
56
|
+
hint: [statusLabel, playerLabel].filter(Boolean).join(', '),
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
const selected = await select({
|
|
60
|
+
message,
|
|
61
|
+
options: selectOptions,
|
|
62
|
+
});
|
|
63
|
+
if (isCancel(selected)) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
return selected;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get list of servers from Docker
|
|
70
|
+
*/
|
|
71
|
+
export async function getServerList() {
|
|
72
|
+
// This function should be implemented to get servers from Docker
|
|
73
|
+
// For now, we'll import from the shell executor pattern
|
|
74
|
+
const { execSync } = await import('node:child_process');
|
|
75
|
+
try {
|
|
76
|
+
// Get all mc-* containers
|
|
77
|
+
const output = execSync('docker ps -a --filter "name=mc-" --format "{{.Names}}|{{.Status}}"', { encoding: 'utf-8' });
|
|
78
|
+
const servers = [];
|
|
79
|
+
for (const line of output.trim().split('\n')) {
|
|
80
|
+
if (!line || line.includes('mc-router'))
|
|
81
|
+
continue;
|
|
82
|
+
const [containerName, status] = line.split('|');
|
|
83
|
+
if (!containerName)
|
|
84
|
+
continue;
|
|
85
|
+
const name = containerName.replace('mc-', '');
|
|
86
|
+
const isRunning = status?.toLowerCase().includes('up');
|
|
87
|
+
servers.push({
|
|
88
|
+
name,
|
|
89
|
+
containerName,
|
|
90
|
+
status: isRunning ? 'running' : 'stopped',
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return servers;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=server-select.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-select.js","sourceRoot":"","sources":["../../../src/lib/prompts/server-select.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Result of an RCON command execution
|
|
3
|
+
*/
|
|
4
|
+
export interface RconResult {
|
|
5
|
+
code: number;
|
|
6
|
+
output: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Check if a Docker container is running
|
|
10
|
+
*/
|
|
11
|
+
export declare function isContainerRunning(containerName: string): Promise<boolean>;
|
|
12
|
+
/**
|
|
13
|
+
* Execute RCON command and capture output
|
|
14
|
+
*/
|
|
15
|
+
export declare function execRconWithOutput(containerName: string, command: string[]): Promise<RconResult>;
|
|
16
|
+
/**
|
|
17
|
+
* Get container name from server name
|
|
18
|
+
* Ensures the container name has the 'mc-' prefix
|
|
19
|
+
*/
|
|
20
|
+
export declare function getContainerName(serverName: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Online players result
|
|
23
|
+
*/
|
|
24
|
+
export interface OnlinePlayersResult {
|
|
25
|
+
count: number;
|
|
26
|
+
maxPlayers: number;
|
|
27
|
+
players: string[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Get online players from a server
|
|
31
|
+
*/
|
|
32
|
+
export declare function getOnlinePlayers(containerName: string): Promise<OnlinePlayersResult>;
|
|
33
|
+
/**
|
|
34
|
+
* Get online player count (shortcut)
|
|
35
|
+
*/
|
|
36
|
+
export declare function getOnlinePlayerCount(containerName: string): Promise<number>;
|
|
37
|
+
/**
|
|
38
|
+
* Check if a player is online on a specific server
|
|
39
|
+
*/
|
|
40
|
+
export declare function isPlayerOnline(containerName: string, playerName: string): Promise<boolean>;
|
|
41
|
+
/**
|
|
42
|
+
* Check if player is whitelisted
|
|
43
|
+
*/
|
|
44
|
+
export declare function isPlayerWhitelisted(containerName: string, playerName: string): Promise<boolean>;
|
|
45
|
+
/**
|
|
46
|
+
* Check if player is an operator
|
|
47
|
+
*/
|
|
48
|
+
export declare function isPlayerOperator(containerName: string, playerName: string): Promise<boolean>;
|
|
49
|
+
/**
|
|
50
|
+
* Check if player is banned
|
|
51
|
+
*/
|
|
52
|
+
export declare function isPlayerBanned(containerName: string, playerName: string): Promise<boolean>;
|
|
53
|
+
//# sourceMappingURL=rcon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rcon.d.ts","sourceRoot":"","sources":["../../src/lib/rcon.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAmBhF;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,UAAU,CAAC,CAyBrB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA0B1F;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGjF;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGhG;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAerG;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAWlG;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAShG"}
|
package/dist/lib/rcon.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
/**
|
|
3
|
+
* Check if a Docker container is running
|
|
4
|
+
*/
|
|
5
|
+
export async function isContainerRunning(containerName) {
|
|
6
|
+
return new Promise((resolve) => {
|
|
7
|
+
const child = spawn('docker', ['inspect', '-f', '{{.State.Running}}', containerName], {
|
|
8
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
9
|
+
});
|
|
10
|
+
let output = '';
|
|
11
|
+
child.stdout.on('data', (data) => {
|
|
12
|
+
output += data.toString();
|
|
13
|
+
});
|
|
14
|
+
child.on('close', (code) => {
|
|
15
|
+
resolve(code === 0 && output.trim() === 'true');
|
|
16
|
+
});
|
|
17
|
+
child.on('error', () => {
|
|
18
|
+
resolve(false);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Execute RCON command and capture output
|
|
24
|
+
*/
|
|
25
|
+
export async function execRconWithOutput(containerName, command) {
|
|
26
|
+
return new Promise((resolve) => {
|
|
27
|
+
const child = spawn('docker', ['exec', containerName, 'rcon-cli', ...command], {
|
|
28
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
29
|
+
});
|
|
30
|
+
let output = '';
|
|
31
|
+
let errorOutput = '';
|
|
32
|
+
child.stdout.on('data', (data) => {
|
|
33
|
+
output += data.toString();
|
|
34
|
+
});
|
|
35
|
+
child.stderr.on('data', (data) => {
|
|
36
|
+
errorOutput += data.toString();
|
|
37
|
+
});
|
|
38
|
+
child.on('close', (code) => {
|
|
39
|
+
resolve({ code: code ?? 1, output: output || errorOutput });
|
|
40
|
+
});
|
|
41
|
+
child.on('error', (err) => {
|
|
42
|
+
resolve({ code: 1, output: err.message });
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Get container name from server name
|
|
48
|
+
* Ensures the container name has the 'mc-' prefix
|
|
49
|
+
*/
|
|
50
|
+
export function getContainerName(serverName) {
|
|
51
|
+
return serverName.startsWith('mc-') ? serverName : `mc-${serverName}`;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get online players from a server
|
|
55
|
+
*/
|
|
56
|
+
export async function getOnlinePlayers(containerName) {
|
|
57
|
+
const result = await execRconWithOutput(containerName, ['list']);
|
|
58
|
+
if (result.code !== 0) {
|
|
59
|
+
return { count: 0, maxPlayers: 0, players: [] };
|
|
60
|
+
}
|
|
61
|
+
// Parse output: "There are X of a max Y players online: player1, player2, player3"
|
|
62
|
+
// or "There are 0 of a max Y players online:"
|
|
63
|
+
const match = result.output.match(/There are (\d+) of a max (\d+) players online:?\s*(.*)?/i);
|
|
64
|
+
if (!match) {
|
|
65
|
+
return { count: 0, maxPlayers: 0, players: [] };
|
|
66
|
+
}
|
|
67
|
+
const countStr = match[1];
|
|
68
|
+
const maxStr = match[2];
|
|
69
|
+
const count = countStr ? parseInt(countStr, 10) : 0;
|
|
70
|
+
const maxPlayers = maxStr ? parseInt(maxStr, 10) : 0;
|
|
71
|
+
const playerList = match[3]?.trim();
|
|
72
|
+
const players = playerList
|
|
73
|
+
? playerList.split(',').map(p => p.trim()).filter(Boolean)
|
|
74
|
+
: [];
|
|
75
|
+
return { count, maxPlayers, players };
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Get online player count (shortcut)
|
|
79
|
+
*/
|
|
80
|
+
export async function getOnlinePlayerCount(containerName) {
|
|
81
|
+
const result = await getOnlinePlayers(containerName);
|
|
82
|
+
return result.count;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Check if a player is online on a specific server
|
|
86
|
+
*/
|
|
87
|
+
export async function isPlayerOnline(containerName, playerName) {
|
|
88
|
+
const result = await getOnlinePlayers(containerName);
|
|
89
|
+
return result.players.some(p => p.toLowerCase() === playerName.toLowerCase());
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Check if player is whitelisted
|
|
93
|
+
*/
|
|
94
|
+
export async function isPlayerWhitelisted(containerName, playerName) {
|
|
95
|
+
const result = await execRconWithOutput(containerName, ['whitelist', 'list']);
|
|
96
|
+
if (result.code !== 0) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
// Parse output: "There are X whitelisted players: player1, player2"
|
|
100
|
+
const players = result.output
|
|
101
|
+
.split(':')[1]
|
|
102
|
+
?.split(',')
|
|
103
|
+
.map(p => p.trim().toLowerCase())
|
|
104
|
+
.filter(Boolean) ?? [];
|
|
105
|
+
return players.includes(playerName.toLowerCase());
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Check if player is an operator
|
|
109
|
+
*/
|
|
110
|
+
export async function isPlayerOperator(containerName, playerName) {
|
|
111
|
+
const result = await execRconWithOutput(containerName, ['op', 'list']);
|
|
112
|
+
if (result.code !== 0) {
|
|
113
|
+
// Try alternative: read ops.json parsing would need file access
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
// Parse output varies by server, try common format
|
|
117
|
+
const output = result.output.toLowerCase();
|
|
118
|
+
return output.includes(playerName.toLowerCase());
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Check if player is banned
|
|
122
|
+
*/
|
|
123
|
+
export async function isPlayerBanned(containerName, playerName) {
|
|
124
|
+
const result = await execRconWithOutput(containerName, ['banlist', 'players']);
|
|
125
|
+
if (result.code !== 0) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
const output = result.output.toLowerCase();
|
|
129
|
+
return output.includes(playerName.toLowerCase());
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=rcon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rcon.js","sourceRoot":"","sources":["../../src/lib/rcon.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Paths } from '@minecraft-docker/shared';
|
|
2
|
+
export interface ShellExecutorOptions {
|
|
3
|
+
paths?: Paths;
|
|
4
|
+
sudoPassword?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Shell script executor with environment variable injection
|
|
8
|
+
*/
|
|
9
|
+
export declare class ShellExecutor {
|
|
10
|
+
private readonly paths;
|
|
11
|
+
private readonly env;
|
|
12
|
+
private readonly sudoPassword?;
|
|
13
|
+
constructor(pathsOrOptions?: Paths | ShellExecutorOptions);
|
|
14
|
+
private buildEnv;
|
|
15
|
+
/**
|
|
16
|
+
* Get script path and validate existence
|
|
17
|
+
*/
|
|
18
|
+
private getScriptPath;
|
|
19
|
+
/**
|
|
20
|
+
* Execute a script and return the result
|
|
21
|
+
*/
|
|
22
|
+
exec(script: string, args?: string[]): Promise<number>;
|
|
23
|
+
/**
|
|
24
|
+
* Execute a script interactively (with inherited stdio)
|
|
25
|
+
*/
|
|
26
|
+
execInteractive(script: string, args?: string[]): Promise<number>;
|
|
27
|
+
/**
|
|
28
|
+
* Execute mcctl.sh with arguments
|
|
29
|
+
*/
|
|
30
|
+
mcctl(args: string[]): Promise<number>;
|
|
31
|
+
/**
|
|
32
|
+
* Create a new server
|
|
33
|
+
*/
|
|
34
|
+
createServer(name: string, options?: string[]): Promise<number>;
|
|
35
|
+
/**
|
|
36
|
+
* Delete a server
|
|
37
|
+
*/
|
|
38
|
+
deleteServer(name: string, options?: string[]): Promise<number>;
|
|
39
|
+
/**
|
|
40
|
+
* View logs
|
|
41
|
+
*/
|
|
42
|
+
logs(server: string, options?: string[]): Promise<number>;
|
|
43
|
+
/**
|
|
44
|
+
* Lock operations
|
|
45
|
+
*/
|
|
46
|
+
lock(args: string[]): Promise<number>;
|
|
47
|
+
/**
|
|
48
|
+
* Player lookup
|
|
49
|
+
*/
|
|
50
|
+
player(args: string[]): Promise<number>;
|
|
51
|
+
/**
|
|
52
|
+
* Backup operations
|
|
53
|
+
*/
|
|
54
|
+
backup(args: string[]): Promise<number>;
|
|
55
|
+
/**
|
|
56
|
+
* Run init.sh (for Docker/network setup)
|
|
57
|
+
*/
|
|
58
|
+
initPlatform(options?: string[]): Promise<number>;
|
|
59
|
+
/**
|
|
60
|
+
* Execute docker compose command
|
|
61
|
+
*/
|
|
62
|
+
dockerCompose(args: string[]): Promise<number>;
|
|
63
|
+
/**
|
|
64
|
+
* Get server config.env path
|
|
65
|
+
*/
|
|
66
|
+
getConfigPath(server: string): string;
|
|
67
|
+
/**
|
|
68
|
+
* Read server config.env as key-value pairs
|
|
69
|
+
*/
|
|
70
|
+
readConfig(server: string): Record<string, string> | null;
|
|
71
|
+
/**
|
|
72
|
+
* Write a config value to server's config.env
|
|
73
|
+
* Preserves comments and formatting
|
|
74
|
+
*/
|
|
75
|
+
writeConfigValue(server: string, key: string, value: string): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Execute RCON command on a server
|
|
78
|
+
*/
|
|
79
|
+
execRcon(server: string, command: string[]): Promise<number>;
|
|
80
|
+
/**
|
|
81
|
+
* Start all infrastructure (router + all servers)
|
|
82
|
+
*/
|
|
83
|
+
up(): Promise<number>;
|
|
84
|
+
/**
|
|
85
|
+
* Stop all infrastructure
|
|
86
|
+
*/
|
|
87
|
+
down(): Promise<number>;
|
|
88
|
+
/**
|
|
89
|
+
* Start all Minecraft servers (not router)
|
|
90
|
+
* Uses docker compose up to create containers if they don't exist
|
|
91
|
+
*/
|
|
92
|
+
startAll(): Promise<number>;
|
|
93
|
+
/**
|
|
94
|
+
* Stop all Minecraft servers (not router)
|
|
95
|
+
* Uses docker compose stop for consistency
|
|
96
|
+
*/
|
|
97
|
+
stopAll(): Promise<number>;
|
|
98
|
+
/**
|
|
99
|
+
* Start mc-router only
|
|
100
|
+
*/
|
|
101
|
+
routerStart(): Promise<number>;
|
|
102
|
+
/**
|
|
103
|
+
* Stop mc-router only
|
|
104
|
+
*/
|
|
105
|
+
routerStop(): Promise<number>;
|
|
106
|
+
/**
|
|
107
|
+
* Restart mc-router
|
|
108
|
+
*/
|
|
109
|
+
routerRestart(): Promise<number>;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=shell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../../src/lib/shell.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAA0C,MAAM,0BAA0B,CAAC;AAEzF,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAyB;IAC7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAS;gBAE3B,cAAc,CAAC,EAAE,KAAK,GAAG,oBAAoB;IAczD,OAAO,CAAC,QAAQ;IAkBhB;;OAEG;IACH,OAAO,CAAC,aAAa;IASrB;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAQhE;;OAEG;IACG,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAO3E;;OAEG;IACG,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAI5C;;OAEG;IACG,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAIzE;;OAEG;IACG,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAIzE;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAInE;;OAEG;IACG,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAI3C;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAI7C;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAI7C;;OAEG;IACG,YAAY,CAAC,OAAO,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAI3D;;OAEG;IACG,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAmBpD;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAKrC;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IA0BzD;;;OAGG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAiCrE;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAqBlE;;OAEG;IACG,EAAE,IAAI,OAAO,CAAC,MAAM,CAAC;IAK3B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAkB7B;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAwBjC;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IAuBhC;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;IAKpC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAKnC;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;CAIvC"}
|