@local-labs-jpollock/local-cli 0.0.1
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/addon-dist/bin/mcp-stdio.js +2808 -0
- package/addon-dist/lib/common/constants.d.ts +22 -0
- package/addon-dist/lib/common/constants.js +26 -0
- package/addon-dist/lib/common/theme.d.ts +68 -0
- package/addon-dist/lib/common/theme.js +126 -0
- package/addon-dist/lib/common/types.d.ts +298 -0
- package/addon-dist/lib/common/types.js +6 -0
- package/addon-dist/lib/main/config/ConnectionInfo.d.ts +25 -0
- package/addon-dist/lib/main/config/ConnectionInfo.js +82 -0
- package/addon-dist/lib/main/index.d.ts +12 -0
- package/addon-dist/lib/main/index.js +3322 -0
- package/addon-dist/lib/main/mcp/McpAuth.d.ts +37 -0
- package/addon-dist/lib/main/mcp/McpAuth.js +87 -0
- package/addon-dist/lib/main/mcp/McpServer.d.ts +67 -0
- package/addon-dist/lib/main/mcp/McpServer.js +343 -0
- package/addon-dist/lib/main/mcp/tools/changePhpVersion.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/changePhpVersion.js +81 -0
- package/addon-dist/lib/main/mcp/tools/cloneSite.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/cloneSite.js +66 -0
- package/addon-dist/lib/main/mcp/tools/createSite.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/createSite.js +137 -0
- package/addon-dist/lib/main/mcp/tools/deleteSite.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/deleteSite.js +72 -0
- package/addon-dist/lib/main/mcp/tools/exportDatabase.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/exportDatabase.js +72 -0
- package/addon-dist/lib/main/mcp/tools/exportSite.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/exportSite.js +103 -0
- package/addon-dist/lib/main/mcp/tools/getLocalInfo.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/getLocalInfo.js +72 -0
- package/addon-dist/lib/main/mcp/tools/getSite.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/getSite.js +68 -0
- package/addon-dist/lib/main/mcp/tools/getSiteLogs.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/getSiteLogs.js +149 -0
- package/addon-dist/lib/main/mcp/tools/helpers.d.ts +59 -0
- package/addon-dist/lib/main/mcp/tools/helpers.js +179 -0
- package/addon-dist/lib/main/mcp/tools/importDatabase.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/importDatabase.js +109 -0
- package/addon-dist/lib/main/mcp/tools/importSite.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/importSite.js +149 -0
- package/addon-dist/lib/main/mcp/tools/index.d.ts +26 -0
- package/addon-dist/lib/main/mcp/tools/index.js +117 -0
- package/addon-dist/lib/main/mcp/tools/listBlueprints.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/listBlueprints.js +54 -0
- package/addon-dist/lib/main/mcp/tools/listServices.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/listServices.js +112 -0
- package/addon-dist/lib/main/mcp/tools/listSites.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/listSites.js +62 -0
- package/addon-dist/lib/main/mcp/tools/openAdminer.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/openAdminer.js +59 -0
- package/addon-dist/lib/main/mcp/tools/openSite.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/openSite.js +62 -0
- package/addon-dist/lib/main/mcp/tools/renameSite.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/renameSite.js +70 -0
- package/addon-dist/lib/main/mcp/tools/restartSite.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/restartSite.js +56 -0
- package/addon-dist/lib/main/mcp/tools/saveBlueprint.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/saveBlueprint.js +89 -0
- package/addon-dist/lib/main/mcp/tools/startSite.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/startSite.js +54 -0
- package/addon-dist/lib/main/mcp/tools/stopSite.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/stopSite.js +54 -0
- package/addon-dist/lib/main/mcp/tools/toggleXdebug.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/toggleXdebug.js +69 -0
- package/addon-dist/lib/main/mcp/tools/trustSsl.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/trustSsl.js +59 -0
- package/addon-dist/lib/main/mcp/tools/wpCli.d.ts +7 -0
- package/addon-dist/lib/main/mcp/tools/wpCli.js +110 -0
- package/addon-dist/lib/main.d.ts +1 -0
- package/addon-dist/lib/main.js +10 -0
- package/addon-dist/lib/renderer/index.d.ts +7 -0
- package/addon-dist/lib/renderer/index.js +479 -0
- package/addon-dist/package.json +73 -0
- package/bin/lwp.js +10 -0
- package/lib/bootstrap/index.d.ts +98 -0
- package/lib/bootstrap/index.js +493 -0
- package/lib/bootstrap/paths.d.ts +28 -0
- package/lib/bootstrap/paths.js +96 -0
- package/lib/client/GraphQLClient.d.ts +38 -0
- package/lib/client/GraphQLClient.js +71 -0
- package/lib/client/index.d.ts +4 -0
- package/lib/client/index.js +10 -0
- package/lib/formatters/index.d.ts +75 -0
- package/lib/formatters/index.js +139 -0
- package/lib/index.d.ts +8 -0
- package/lib/index.js +1173 -0
- package/package.json +72 -0
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MCP Server Addon - Renderer Entry Point
|
|
4
|
+
* Adds MCP Server preferences panel to Local
|
|
5
|
+
*
|
|
6
|
+
* Uses class components for compatibility with Local's Electron environment.
|
|
7
|
+
*/
|
|
8
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const react_1 = __importDefault(require("react"));
|
|
13
|
+
const theme_1 = require("../common/theme");
|
|
14
|
+
// MCP Preferences Panel Component (Class-based for Local compatibility)
|
|
15
|
+
class McpPreferencesPanel extends react_1.default.Component {
|
|
16
|
+
constructor() {
|
|
17
|
+
super(...arguments);
|
|
18
|
+
this.state = {
|
|
19
|
+
status: null,
|
|
20
|
+
connectionInfo: null,
|
|
21
|
+
loading: true,
|
|
22
|
+
copied: false,
|
|
23
|
+
actionInProgress: false,
|
|
24
|
+
activeTab: 'status',
|
|
25
|
+
colors: (0, theme_1.getThemeColors)(),
|
|
26
|
+
};
|
|
27
|
+
this.fetchStatus = async () => {
|
|
28
|
+
try {
|
|
29
|
+
const result = (await this.props.electron?.ipcRenderer?.invoke('mcp:getStatus'));
|
|
30
|
+
if (result) {
|
|
31
|
+
this.setState({ status: result });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
console.error('Failed to fetch MCP status:', error);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
this.fetchConnectionInfo = async () => {
|
|
39
|
+
try {
|
|
40
|
+
const result = (await this.props.electron?.ipcRenderer?.invoke('mcp:getConnectionInfo'));
|
|
41
|
+
if (result) {
|
|
42
|
+
this.setState({ connectionInfo: result });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
console.error('Failed to fetch connection info:', error);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
this.handleCopyStdioConfig = () => {
|
|
50
|
+
const config = {
|
|
51
|
+
mcpServers: {
|
|
52
|
+
local: {
|
|
53
|
+
type: 'stdio',
|
|
54
|
+
command: 'node',
|
|
55
|
+
args: ['/path/to/local-addon-mcp-server/bin/mcp-stdio.js'],
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
navigator.clipboard.writeText(JSON.stringify(config, null, 2));
|
|
60
|
+
this.setState({ copied: true });
|
|
61
|
+
setTimeout(() => this.setState({ copied: false }), 2000);
|
|
62
|
+
};
|
|
63
|
+
this.handleCopySseConfig = () => {
|
|
64
|
+
const { connectionInfo } = this.state;
|
|
65
|
+
if (connectionInfo) {
|
|
66
|
+
const config = {
|
|
67
|
+
mcpServers: {
|
|
68
|
+
local: {
|
|
69
|
+
url: `${connectionInfo.url}/mcp/sse`,
|
|
70
|
+
transport: 'sse',
|
|
71
|
+
headers: {
|
|
72
|
+
Authorization: `Bearer ${connectionInfo.authToken}`,
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
navigator.clipboard.writeText(JSON.stringify(config, null, 2));
|
|
78
|
+
this.setState({ copied: true });
|
|
79
|
+
setTimeout(() => this.setState({ copied: false }), 2000);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
this.handleTestConnection = async () => {
|
|
83
|
+
const { connectionInfo } = this.state;
|
|
84
|
+
try {
|
|
85
|
+
const response = await fetch(`http://127.0.0.1:${connectionInfo?.port}/health`);
|
|
86
|
+
const data = await response.json();
|
|
87
|
+
if (data.status === 'ok') {
|
|
88
|
+
alert('Connection successful! MCP server is healthy.');
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
alert('Connection failed: Server returned unexpected response');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
96
|
+
alert(`Connection failed: ${message}`);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
this.handleStartStop = async () => {
|
|
100
|
+
const { status } = this.state;
|
|
101
|
+
this.setState({ actionInProgress: true });
|
|
102
|
+
try {
|
|
103
|
+
if (status?.running) {
|
|
104
|
+
await this.props.electron?.ipcRenderer?.invoke('mcp:stop');
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
await this.props.electron?.ipcRenderer?.invoke('mcp:start');
|
|
108
|
+
}
|
|
109
|
+
await this.fetchStatus();
|
|
110
|
+
await this.fetchConnectionInfo();
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
114
|
+
alert(`Action failed: ${message}`);
|
|
115
|
+
}
|
|
116
|
+
finally {
|
|
117
|
+
this.setState({ actionInProgress: false });
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
this.handleRestart = async () => {
|
|
121
|
+
this.setState({ actionInProgress: true });
|
|
122
|
+
try {
|
|
123
|
+
await this.props.electron?.ipcRenderer?.invoke('mcp:restart');
|
|
124
|
+
await this.fetchStatus();
|
|
125
|
+
await this.fetchConnectionInfo();
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
129
|
+
alert(`Restart failed: ${message}`);
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
this.setState({ actionInProgress: false });
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
this.handleRegenerateToken = async () => {
|
|
136
|
+
if (!confirm('Regenerate authentication token? You will need to update your AI tool configuration.')) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
this.setState({ actionInProgress: true });
|
|
140
|
+
try {
|
|
141
|
+
const result = (await this.props.electron?.ipcRenderer?.invoke('mcp:regenerateToken'));
|
|
142
|
+
if (result?.success) {
|
|
143
|
+
await this.fetchConnectionInfo();
|
|
144
|
+
alert('Token regenerated successfully. Please update your AI tool configuration.');
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
alert(`Failed to regenerate token: ${result?.error}`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
152
|
+
alert(`Failed to regenerate token: ${message}`);
|
|
153
|
+
}
|
|
154
|
+
finally {
|
|
155
|
+
this.setState({ actionInProgress: false });
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
componentDidMount() {
|
|
160
|
+
this.init();
|
|
161
|
+
this.statusInterval = setInterval(() => this.fetchStatus(), 5000);
|
|
162
|
+
this.themeCleanup = (0, theme_1.onThemeChange)(() => {
|
|
163
|
+
this.setState({ colors: (0, theme_1.getThemeColors)() });
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
componentWillUnmount() {
|
|
167
|
+
if (this.statusInterval) {
|
|
168
|
+
clearInterval(this.statusInterval);
|
|
169
|
+
}
|
|
170
|
+
if (this.themeCleanup) {
|
|
171
|
+
this.themeCleanup();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
async init() {
|
|
175
|
+
await Promise.all([this.fetchStatus(), this.fetchConnectionInfo()]);
|
|
176
|
+
this.setState({ loading: false });
|
|
177
|
+
}
|
|
178
|
+
getStatusColor() {
|
|
179
|
+
const { status, colors } = this.state;
|
|
180
|
+
if (!status)
|
|
181
|
+
return colors.textMuted;
|
|
182
|
+
if (status.running)
|
|
183
|
+
return colors.successText;
|
|
184
|
+
return colors.errorText;
|
|
185
|
+
}
|
|
186
|
+
getStatusText() {
|
|
187
|
+
const { loading, status } = this.state;
|
|
188
|
+
if (loading)
|
|
189
|
+
return 'Loading...';
|
|
190
|
+
if (!status)
|
|
191
|
+
return 'Unknown';
|
|
192
|
+
if (status.running)
|
|
193
|
+
return 'Running';
|
|
194
|
+
return 'Stopped';
|
|
195
|
+
}
|
|
196
|
+
formatUptime(seconds) {
|
|
197
|
+
if (seconds < 60)
|
|
198
|
+
return `${Math.floor(seconds)}s`;
|
|
199
|
+
if (seconds < 3600)
|
|
200
|
+
return `${Math.floor(seconds / 60)}m`;
|
|
201
|
+
return `${Math.floor(seconds / 3600)}h ${Math.floor((seconds % 3600) / 60)}m`;
|
|
202
|
+
}
|
|
203
|
+
getTabStyle(isActive) {
|
|
204
|
+
const { colors } = this.state;
|
|
205
|
+
return {
|
|
206
|
+
padding: '8px 16px',
|
|
207
|
+
border: 'none',
|
|
208
|
+
borderBottom: isActive ? `2px solid ${colors.primary}` : '2px solid transparent',
|
|
209
|
+
backgroundColor: 'transparent',
|
|
210
|
+
color: isActive ? colors.primary : colors.textSecondary,
|
|
211
|
+
cursor: 'pointer',
|
|
212
|
+
fontSize: '14px',
|
|
213
|
+
fontWeight: isActive ? 600 : 400,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
getButtonStyle(bgColor, disabled) {
|
|
217
|
+
return {
|
|
218
|
+
padding: '8px 16px',
|
|
219
|
+
backgroundColor: bgColor,
|
|
220
|
+
color: 'white',
|
|
221
|
+
border: 'none',
|
|
222
|
+
borderRadius: '4px',
|
|
223
|
+
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
224
|
+
fontSize: '13px',
|
|
225
|
+
opacity: disabled ? 0.5 : 1,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
renderStatusTab() {
|
|
229
|
+
const { status, connectionInfo, actionInProgress, colors } = this.state;
|
|
230
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
231
|
+
react_1.default.createElement("div", { style: { marginBottom: '24px' } },
|
|
232
|
+
react_1.default.createElement("h3", { style: {
|
|
233
|
+
fontSize: '14px',
|
|
234
|
+
fontWeight: 600,
|
|
235
|
+
marginBottom: '12px',
|
|
236
|
+
color: colors.textPrimary,
|
|
237
|
+
} }, "Server Status"),
|
|
238
|
+
react_1.default.createElement("div", { style: {
|
|
239
|
+
display: 'flex',
|
|
240
|
+
alignItems: 'center',
|
|
241
|
+
gap: '12px',
|
|
242
|
+
padding: '12px',
|
|
243
|
+
backgroundColor: colors.panelBgSecondary,
|
|
244
|
+
borderRadius: '6px',
|
|
245
|
+
} },
|
|
246
|
+
react_1.default.createElement("span", { style: {
|
|
247
|
+
width: '12px',
|
|
248
|
+
height: '12px',
|
|
249
|
+
borderRadius: '50%',
|
|
250
|
+
backgroundColor: this.getStatusColor(),
|
|
251
|
+
} }),
|
|
252
|
+
react_1.default.createElement("span", { style: { fontWeight: 500, color: colors.textPrimary } }, this.getStatusText()),
|
|
253
|
+
status?.running && (react_1.default.createElement(react_1.default.Fragment, null,
|
|
254
|
+
react_1.default.createElement("span", { style: { color: colors.textSecondary } }, "|"),
|
|
255
|
+
react_1.default.createElement("span", { style: { color: colors.textSecondary } },
|
|
256
|
+
"Port: ",
|
|
257
|
+
status.port),
|
|
258
|
+
react_1.default.createElement("span", { style: { color: colors.textSecondary } }, "|"),
|
|
259
|
+
react_1.default.createElement("span", { style: { color: colors.textSecondary } },
|
|
260
|
+
"Uptime: ",
|
|
261
|
+
this.formatUptime(status.uptime)))))),
|
|
262
|
+
react_1.default.createElement("div", { style: { marginBottom: '24px' } },
|
|
263
|
+
react_1.default.createElement("h3", { style: {
|
|
264
|
+
fontSize: '14px',
|
|
265
|
+
fontWeight: 600,
|
|
266
|
+
marginBottom: '12px',
|
|
267
|
+
color: colors.textPrimary,
|
|
268
|
+
} }, "Server Controls"),
|
|
269
|
+
react_1.default.createElement("div", { style: { display: 'flex', gap: '12px', flexWrap: 'wrap' } },
|
|
270
|
+
react_1.default.createElement("button", { onClick: this.handleStartStop, disabled: actionInProgress, style: this.getButtonStyle(status?.running ? colors.errorText : colors.successText, actionInProgress) }, status?.running ? 'Stop Server' : 'Start Server'),
|
|
271
|
+
react_1.default.createElement("button", { onClick: this.handleRestart, disabled: actionInProgress || !status?.running, style: this.getButtonStyle('#6c757d', actionInProgress || !status?.running) }, "Restart Server"),
|
|
272
|
+
react_1.default.createElement("button", { onClick: this.handleTestConnection, disabled: !status?.running, style: this.getButtonStyle(status?.running ? '#17a2b8' : colors.textMuted, !status?.running) }, "Test Connection"))),
|
|
273
|
+
connectionInfo && (react_1.default.createElement("div", { style: { marginBottom: '24px' } },
|
|
274
|
+
react_1.default.createElement("h3", { style: {
|
|
275
|
+
fontSize: '14px',
|
|
276
|
+
fontWeight: 600,
|
|
277
|
+
marginBottom: '12px',
|
|
278
|
+
color: colors.textPrimary,
|
|
279
|
+
} }, "Connection Info"),
|
|
280
|
+
react_1.default.createElement("div", { style: {
|
|
281
|
+
padding: '12px',
|
|
282
|
+
backgroundColor: colors.panelBgSecondary,
|
|
283
|
+
borderRadius: '6px',
|
|
284
|
+
fontFamily: 'monospace',
|
|
285
|
+
fontSize: '12px',
|
|
286
|
+
color: colors.textPrimary,
|
|
287
|
+
} },
|
|
288
|
+
react_1.default.createElement("div", { style: { marginBottom: '8px' } },
|
|
289
|
+
react_1.default.createElement("strong", null, "URL:"),
|
|
290
|
+
" ",
|
|
291
|
+
connectionInfo.url),
|
|
292
|
+
react_1.default.createElement("div", { style: { marginBottom: '8px' } },
|
|
293
|
+
react_1.default.createElement("strong", null, "stdio script:"),
|
|
294
|
+
" bin/mcp-stdio.js"),
|
|
295
|
+
react_1.default.createElement("div", { style: { marginBottom: '8px' } },
|
|
296
|
+
react_1.default.createElement("strong", null, "Version:"),
|
|
297
|
+
" ",
|
|
298
|
+
connectionInfo.version),
|
|
299
|
+
react_1.default.createElement("div", null,
|
|
300
|
+
react_1.default.createElement("strong", null, "Tools:"),
|
|
301
|
+
" ",
|
|
302
|
+
connectionInfo.tools.join(', '))))),
|
|
303
|
+
react_1.default.createElement("div", { style: { marginBottom: '24px' } },
|
|
304
|
+
react_1.default.createElement("h3", { style: {
|
|
305
|
+
fontSize: '14px',
|
|
306
|
+
fontWeight: 600,
|
|
307
|
+
marginBottom: '12px',
|
|
308
|
+
color: colors.textPrimary,
|
|
309
|
+
} }, "Security"),
|
|
310
|
+
react_1.default.createElement("div", { style: { display: 'flex', gap: '12px', flexWrap: 'wrap' } },
|
|
311
|
+
react_1.default.createElement("button", { onClick: this.handleRegenerateToken, disabled: actionInProgress || !status?.running, style: {
|
|
312
|
+
padding: '8px 16px',
|
|
313
|
+
backgroundColor: '#ffc107',
|
|
314
|
+
color: '#212529',
|
|
315
|
+
border: 'none',
|
|
316
|
+
borderRadius: '4px',
|
|
317
|
+
cursor: actionInProgress || !status?.running ? 'not-allowed' : 'pointer',
|
|
318
|
+
fontSize: '13px',
|
|
319
|
+
opacity: actionInProgress || !status?.running ? 0.5 : 1,
|
|
320
|
+
} }, "Regenerate Token")),
|
|
321
|
+
react_1.default.createElement("p", { style: { fontSize: '12px', color: colors.textSecondary, marginTop: '8px' } }, "Regenerating the token will require you to update your AI tool configuration."))));
|
|
322
|
+
}
|
|
323
|
+
renderSetupTab() {
|
|
324
|
+
const { connectionInfo, copied, colors } = this.state;
|
|
325
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
326
|
+
react_1.default.createElement("div", { style: { marginBottom: '24px' } },
|
|
327
|
+
react_1.default.createElement("h3", { style: {
|
|
328
|
+
fontSize: '14px',
|
|
329
|
+
fontWeight: 600,
|
|
330
|
+
marginBottom: '12px',
|
|
331
|
+
color: colors.textPrimary,
|
|
332
|
+
} }, "Claude Code (Recommended)"),
|
|
333
|
+
react_1.default.createElement("div", { style: {
|
|
334
|
+
padding: '16px',
|
|
335
|
+
backgroundColor: colors.panelBgSecondary,
|
|
336
|
+
borderRadius: '6px',
|
|
337
|
+
} },
|
|
338
|
+
react_1.default.createElement("p", { style: { margin: '0 0 12px 0', fontSize: '13px', color: colors.textPrimary } },
|
|
339
|
+
"Add the following to your",
|
|
340
|
+
' ',
|
|
341
|
+
react_1.default.createElement("code", { style: {
|
|
342
|
+
backgroundColor: colors.panelBgCode,
|
|
343
|
+
padding: '2px 4px',
|
|
344
|
+
borderRadius: '3px',
|
|
345
|
+
color: '#f8f8f2',
|
|
346
|
+
} }, "~/.claude.json"),
|
|
347
|
+
' ',
|
|
348
|
+
"file:"),
|
|
349
|
+
react_1.default.createElement("pre", { style: {
|
|
350
|
+
backgroundColor: colors.panelBgCode,
|
|
351
|
+
color: '#f8f8f2',
|
|
352
|
+
padding: '12px',
|
|
353
|
+
borderRadius: '4px',
|
|
354
|
+
fontSize: '11px',
|
|
355
|
+
overflow: 'auto',
|
|
356
|
+
margin: '0 0 12px 0',
|
|
357
|
+
} }, `{
|
|
358
|
+
"mcpServers": {
|
|
359
|
+
"local": {
|
|
360
|
+
"type": "stdio",
|
|
361
|
+
"command": "node",
|
|
362
|
+
"args": ["/path/to/local-addon-mcp-server/bin/mcp-stdio.js"]
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}`),
|
|
366
|
+
react_1.default.createElement("button", { onClick: this.handleCopyStdioConfig, style: this.getButtonStyle(colors.primary) }, copied ? 'Copied!' : 'Copy Config'))),
|
|
367
|
+
react_1.default.createElement("div", { style: { marginBottom: '24px' } },
|
|
368
|
+
react_1.default.createElement("h3", { style: {
|
|
369
|
+
fontSize: '14px',
|
|
370
|
+
fontWeight: 600,
|
|
371
|
+
marginBottom: '12px',
|
|
372
|
+
color: colors.textPrimary,
|
|
373
|
+
} }, "Claude.ai / ChatGPT / Other AI Tools"),
|
|
374
|
+
react_1.default.createElement("div", { style: {
|
|
375
|
+
padding: '16px',
|
|
376
|
+
backgroundColor: colors.panelBgSecondary,
|
|
377
|
+
borderRadius: '6px',
|
|
378
|
+
} },
|
|
379
|
+
react_1.default.createElement("p", { style: { margin: '0 0 12px 0', fontSize: '13px', color: colors.textPrimary } }, "For tools that support SSE transport, use this configuration:"),
|
|
380
|
+
react_1.default.createElement("pre", { style: {
|
|
381
|
+
backgroundColor: colors.panelBgCode,
|
|
382
|
+
color: '#f8f8f2',
|
|
383
|
+
padding: '12px',
|
|
384
|
+
borderRadius: '4px',
|
|
385
|
+
fontSize: '11px',
|
|
386
|
+
overflow: 'auto',
|
|
387
|
+
margin: '0 0 12px 0',
|
|
388
|
+
} }, connectionInfo
|
|
389
|
+
? `{
|
|
390
|
+
"mcpServers": {
|
|
391
|
+
"local": {
|
|
392
|
+
"url": "${connectionInfo.url}/mcp/sse",
|
|
393
|
+
"transport": "sse",
|
|
394
|
+
"headers": {
|
|
395
|
+
"Authorization": "Bearer ${connectionInfo.authToken.substring(0, 20)}..."
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}`
|
|
400
|
+
: 'Server not running'),
|
|
401
|
+
react_1.default.createElement("button", { onClick: this.handleCopySseConfig, disabled: !connectionInfo, style: this.getButtonStyle(connectionInfo ? colors.primary : colors.textMuted, !connectionInfo) }, copied ? 'Copied!' : 'Copy SSE Config'))),
|
|
402
|
+
react_1.default.createElement("div", { style: { marginBottom: '24px' } },
|
|
403
|
+
react_1.default.createElement("h3", { style: {
|
|
404
|
+
fontSize: '14px',
|
|
405
|
+
fontWeight: 600,
|
|
406
|
+
marginBottom: '12px',
|
|
407
|
+
color: colors.textPrimary,
|
|
408
|
+
} }, "Example Commands"),
|
|
409
|
+
react_1.default.createElement("div", { style: {
|
|
410
|
+
padding: '16px',
|
|
411
|
+
backgroundColor: colors.infoBg,
|
|
412
|
+
borderRadius: '6px',
|
|
413
|
+
border: `1px solid ${colors.infoBorder}`,
|
|
414
|
+
} },
|
|
415
|
+
react_1.default.createElement("p", { style: {
|
|
416
|
+
margin: '0 0 8px 0',
|
|
417
|
+
fontSize: '13px',
|
|
418
|
+
fontWeight: 500,
|
|
419
|
+
color: colors.infoText,
|
|
420
|
+
} }, "Try saying to your AI assistant:"),
|
|
421
|
+
react_1.default.createElement("ul", { style: { margin: 0, paddingLeft: '20px', fontSize: '13px', color: colors.infoText } },
|
|
422
|
+
react_1.default.createElement("li", null, "\"List my Local sites\""),
|
|
423
|
+
react_1.default.createElement("li", null, "\"Start the blog site\""),
|
|
424
|
+
react_1.default.createElement("li", null, "\"Create a new site called test-project\""),
|
|
425
|
+
react_1.default.createElement("li", null, "\"Run wp plugin list on my-site\""),
|
|
426
|
+
react_1.default.createElement("li", null, "\"Stop all running sites\""),
|
|
427
|
+
react_1.default.createElement("li", null, "\"What plugins are installed on my-site?\""))))));
|
|
428
|
+
}
|
|
429
|
+
render() {
|
|
430
|
+
const { activeTab, colors } = this.state;
|
|
431
|
+
return (react_1.default.createElement("div", { style: { padding: '20px', color: colors.textPrimary } },
|
|
432
|
+
react_1.default.createElement("h2", { style: {
|
|
433
|
+
marginBottom: '20px',
|
|
434
|
+
fontSize: '18px',
|
|
435
|
+
fontWeight: 600,
|
|
436
|
+
color: colors.textPrimary,
|
|
437
|
+
} }, "MCP Server"),
|
|
438
|
+
react_1.default.createElement("p", { style: { color: colors.textSecondary, marginBottom: '24px' } }, "The MCP (Model Context Protocol) server enables AI tools like Claude Code to control your Local sites."),
|
|
439
|
+
react_1.default.createElement("div", { style: { borderBottom: `1px solid ${colors.border}`, marginBottom: '24px' } },
|
|
440
|
+
react_1.default.createElement("button", { style: this.getTabStyle(activeTab === 'status'), onClick: () => this.setState({ activeTab: 'status' }) }, "Status & Controls"),
|
|
441
|
+
react_1.default.createElement("button", { style: this.getTabStyle(activeTab === 'setup'), onClick: () => this.setState({ activeTab: 'setup' }) }, "AI Tool Setup")),
|
|
442
|
+
activeTab === 'status' && this.renderStatusTab(),
|
|
443
|
+
activeTab === 'setup' && this.renderSetupTab()));
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
// Export as a constructor function that Local can instantiate
|
|
447
|
+
module.exports = function McpServerRenderer(context) {
|
|
448
|
+
// CLI-only mode - preferences panel disabled
|
|
449
|
+
// To enable MCP preferences UI, uncomment the following:
|
|
450
|
+
/*
|
|
451
|
+
const { hooks, electron } = context as {
|
|
452
|
+
hooks: { addFilter: (name: string, callback: (items: unknown[]) => unknown[]) => void };
|
|
453
|
+
electron: McpPreferencesPanelProps['electron'];
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
console.log('[MCP Server] Renderer loading...');
|
|
457
|
+
|
|
458
|
+
// Add MCP Server to preferences menu
|
|
459
|
+
hooks.addFilter('preferencesMenuItems', (menuItems: unknown[]) => {
|
|
460
|
+
console.log('[MCP Server] Adding MCP Server to preferences');
|
|
461
|
+
|
|
462
|
+
(menuItems as Array<Record<string, unknown>>).push({
|
|
463
|
+
path: 'mcp-server',
|
|
464
|
+
displayName: 'MCP Server',
|
|
465
|
+
sections: () => <McpPreferencesPanel electron={electron} />,
|
|
466
|
+
onApply: () => {
|
|
467
|
+
// No apply action needed for read-only display
|
|
468
|
+
},
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
return menuItems;
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
console.log('[MCP Server] Renderer setup complete');
|
|
475
|
+
*/
|
|
476
|
+
// Silence unused variable warnings
|
|
477
|
+
void context;
|
|
478
|
+
};
|
|
479
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVuZGVyZXIvaW5kZXgudHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7R0FLRzs7Ozs7QUFFSCxrREFBMEI7QUFDMUIsMkNBQTZFO0FBb0M3RSx3RUFBd0U7QUFDeEUsTUFBTSxtQkFBb0IsU0FBUSxlQUFLLENBQUMsU0FHdkM7SUFIRDs7UUFPRSxVQUFLLEdBQTZCO1lBQ2hDLE1BQU0sRUFBRSxJQUFJO1lBQ1osY0FBYyxFQUFFLElBQUk7WUFDcEIsT0FBTyxFQUFFLElBQUk7WUFDYixNQUFNLEVBQUUsS0FBSztZQUNiLGdCQUFnQixFQUFFLEtBQUs7WUFDdkIsU0FBUyxFQUFFLFFBQVE7WUFDbkIsTUFBTSxFQUFFLElBQUEsc0JBQWMsR0FBRTtTQUN6QixDQUFDO1FBd0JNLGdCQUFXLEdBQUcsS0FBSyxJQUFtQixFQUFFO1lBQzlDLElBQUksQ0FBQztnQkFDSCxNQUFNLE1BQU0sR0FBRyxDQUFDLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsV0FBVyxFQUFFLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FFbEUsQ0FBQztnQkFDZCxJQUFJLE1BQU0sRUFBRSxDQUFDO29CQUNYLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztnQkFDcEMsQ0FBQztZQUNILENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMsNkJBQTZCLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDdEQsQ0FBQztRQUNILENBQUMsQ0FBQztRQUVNLHdCQUFtQixHQUFHLEtBQUssSUFBbUIsRUFBRTtZQUN0RCxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxNQUFNLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLFdBQVcsRUFBRSxNQUFNLENBQUMsdUJBQXVC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LGlCQUdFO1lBRUwscUNBQUcsS0FBSyxFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxhQUFhLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSw2R0FHM0Q7WUFHSix1Q0FBSyxLQUFLLEVBQUUsRUFBRSxZQUFZLEVBQUUsYUFBYSxNQUFNLENBQUMsTUFBTSxFQUFFLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRTtnQkFDOUUsMENBQ0UsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxLQUFLLFFBQVEsQ0FBQyxFQUMvQyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsQ0FBQyx3QkFHOUM7Z0JBQ1QsMENBQ0UsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxLQUFLLE9BQU8sQ0FBQyxFQUM5QyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxvQkFHN0MsQ0FDTDtZQUVMLFNBQVMsS0FBSyxRQUFRLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRTtZQUNoRCxTQUFTLEtBQUssT0FBTyxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FDM0MsQ0FDUCxDQUFDO0lBQ0osQ0FBQztDQUNGO0FBRUQsOERBQThEO0FBQzlELE1BQU0sQ0FBQyxPQUFPLEdBQUcsU0FBUyxpQkFBaUIsQ0FBQyxPQUE4QztJQUN4Riw2Q0FBNkM7SUFDN0MseURBQXlEO0lBQ3pEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O01BeUJFO0lBRUYsbUNBQW1DO0lBQ25DLEtBQUssT0FBTyxDQUFDO0FBQ2YsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNQ1AgU2VydmVyIEFkZG9uIC0gUmVuZGVyZXIgRW50cnkgUG9pbnRcbiAqIEFkZHMgTUNQIFNlcnZlciBwcmVmZXJlbmNlcyBwYW5lbCB0byBMb2NhbFxuICpcbiAqIFVzZXMgY2xhc3MgY29tcG9uZW50cyBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIExvY2FsJ3MgRWxlY3Ryb24gZW52aXJvbm1lbnQuXG4gKi9cblxuaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IGdldFRoZW1lQ29sb3JzLCBvblRoZW1lQ2hhbmdlLCBUaGVtZUNvbG9ycyB9IGZyb20gJy4uL2NvbW1vbi90aGVtZSc7XG5cbi8vIFR5cGUgZGVmaW5pdGlvbnNcbmludGVyZmFjZSBNY3BTdGF0dXMge1xuICBydW5uaW5nOiBib29sZWFuO1xuICBwb3J0OiBudW1iZXI7XG4gIHVwdGltZTogbnVtYmVyO1xuICBlcnJvcj86IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIENvbm5lY3Rpb25JbmZvIHtcbiAgdXJsOiBzdHJpbmc7XG4gIGF1dGhUb2tlbjogc3RyaW5nO1xuICBwb3J0OiBudW1iZXI7XG4gIHZlcnNpb246IHN0cmluZztcbiAgdG9vbHM6IHN0cmluZ1tdO1xufVxuXG5pbnRlcmZhY2UgTWNwUHJlZmVyZW5jZXNQYW5lbFByb3BzIHtcbiAgZWxlY3Ryb246IHtcbiAgICBpcGNSZW5kZXJlcj86IHtcbiAgICAgIGludm9rZTogKGNoYW5uZWw6IHN0cmluZywgLi4uYXJnczogdW5rbm93bltdKSA9PiBQcm9taXNlPHVua25vd24+O1xuICAgIH07XG4gIH07XG59XG5cbmludGVyZmFjZSBNY3BQcmVmZXJlbmNlc1BhbmVsU3RhdGUge1xuICBzdGF0dXM6IE1jcFN0YXR1cyB8IG51bGw7XG4gIGNvbm5lY3Rpb25JbmZvOiBDb25uZWN0aW9uSW5mbyB8IG51bGw7XG4gIGxvYWRpbmc6IGJvb2xlYW47XG4gIGNvcGllZDogYm9vbGVhbjtcbiAgYWN0aW9uSW5Qcm9ncmVzczogYm9vbGVhbjtcbiAgYWN0aXZlVGFiOiAnc3RhdHVzJyB8ICdzZXR1cCc7XG4gIGNvbG9yczogVGhlbWVDb2xvcnM7XG59XG5cbi8vIE1DUCBQcmVmZXJlbmNlcyBQYW5lbCBDb21wb25lbnQgKENsYXNzLWJhc2VkIGZvciBMb2NhbCBjb21wYXRpYmlsaXR5KVxuY2xhc3MgTWNwUHJlZmVyZW5jZXNQYW5lbCBleHRlbmRzIFJlYWN0LkNvbXBvbmVudDxcbiAgTWNwUHJlZmVyZW5jZXNQYW5lbFByb3BzLFxuICBNY3BQcmVmZXJlbmNlc1BhbmVsU3RhdGVcbj4ge1xuICBwcml2YXRlIHN0YXR1c0ludGVydmFsPzogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0SW50ZXJ2YWw+O1xuICBwcml2YXRlIHRoZW1lQ2xlYW51cD86ICgpID0+IHZvaWQ7XG5cbiAgc3RhdGU6IE1jcFByZWZlcmVuY2VzUGFuZWxTdGF0ZSA9IHtcbiAgICBzdGF0dXM6IG51bGwsXG4gICAgY29ubmVjdGlvbkluZm86IG51bGwsXG4gICAgbG9hZGluZzogdHJ1ZSxcbiAgICBjb3BpZWQ6IGZhbHNlLFxuICAgIGFjdGlvbkluUHJvZ3Jlc3M6IGZhbHNlLFxuICAgIGFjdGl2ZVRhYjogJ3N0YXR1cycsXG4gICAgY29sb3JzOiBnZXRUaGVtZUNvbG9ycygpLFxuICB9O1xuXG4gIGNvbXBvbmVudERpZE1vdW50KCk6IHZvaWQge1xuICAgIHRoaXMuaW5pdCgpO1xuICAgIHRoaXMuc3RhdHVzSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB0aGlzLmZldGNoU3RhdHVzKCksIDUwMDApO1xuICAgIHRoaXMudGhlbWVDbGVhbnVwID0gb25UaGVtZUNoYW5nZSgoKSA9PiB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgY29sb3JzOiBnZXRUaGVtZUNvbG9ycygpIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgY29tcG9uZW50V2lsbFVubW91bnQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc3RhdHVzSW50ZXJ2YWwpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5zdGF0dXNJbnRlcnZhbCk7XG4gICAgfVxuICAgIGlmICh0aGlzLnRoZW1lQ2xlYW51cCkge1xuICAgICAgdGhpcy50aGVtZUNsZWFudXAoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGluaXQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoW3RoaXMuZmV0Y2hTdGF0dXMoKSwgdGhpcy5mZXRjaENvbm5lY3Rpb25JbmZvKCldKTtcbiAgICB0aGlzLnNldFN0YXRlKHsgbG9hZGluZzogZmFsc2UgfSk7XG4gIH1cblxuICBwcml2YXRlIGZldGNoU3RhdHVzID0gYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN1bHQgPSAoYXdhaXQgdGhpcy5wcm9wcy5lbGVjdHJvbj8uaXBjUmVuZGVyZXI/Lmludm9rZSgnbWNwOmdldFN0YXR1cycpKSBhc1xuICAgICAgICB8IE1jcFN0YXR1c1xuICAgICAgICB8IHVuZGVmaW5lZDtcbiAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHN0YXR1czogcmVzdWx0IH0pO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gZmV0Y2ggTUNQIHN0YXR1czonLCBlcnJvcik7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgZmV0Y2hDb25uZWN0aW9uSW5mbyA9IGFzeW5jICgpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gKGF3YWl0IHRoaXMucHJvcHMuZWxlY3Ryb24/LmlwY1JlbmRlcmVyPy5pbnZva2UoJ21jcDpnZXRDb25uZWN0aW9uSW5mbycpKSBhc1xuICAgICAgICB8IENvbm5lY3Rpb25JbmZvXG4gICAgICAgIHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgY29ubmVjdGlvbkluZm86IHJlc3VsdCB9KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIGZldGNoIGNvbm5lY3Rpb24gaW5mbzonLCBlcnJvcik7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlQ29weVN0ZGlvQ29uZmlnID0gKCk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIG1jcFNlcnZlcnM6IHtcbiAgICAgICAgbG9jYWw6IHtcbiAgICAgICAgICB0eXBlOiAnc3RkaW8nLFxuICAgICAgICAgIGNvbW1hbmQ6ICdub2RlJyxcbiAgICAgICAgICBhcmdzOiBbJy9wYXRoL3RvL2xvY2FsLWFkZG9uLW1jcC1zZXJ2ZXIvYmluL21jcC1zdGRpby5qcyddLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICAgIG5hdmlnYXRvci5jbGlwYm9hcmQud3JpdGVUZXh0KEpTT04uc3RyaW5naWZ5KGNvbmZpZywgbnVsbCwgMikpO1xuICAgIHRoaXMuc2V0U3RhdGUoeyBjb3BpZWQ6IHRydWUgfSk7XG4gICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnNldFN0YXRlKHsgY29waWVkOiBmYWxzZSB9KSwgMjAwMCk7XG4gIH07XG5cbiAgcHJpdmF0ZSBoYW5kbGVDb3B5U3NlQ29uZmlnID0gKCk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IHsgY29ubmVjdGlvbkluZm8gfSA9IHRoaXMuc3RhdGU7XG4gICAgaWYgKGNvbm5lY3Rpb25JbmZvKSB7XG4gICAgICBjb25zdCBjb25maWcgPSB7XG4gICAgICAgIG1jcFNlcnZlcnM6IHtcbiAgICAgICAgICBsb2NhbDoge1xuICAgICAgICAgICAgdXJsOiBgJHtjb25uZWN0aW9uSW5mby51cmx9L21jcC9zc2VgLFxuICAgICAgICAgICAgdHJhbnNwb3J0OiAnc3NlJyxcbiAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgQXV0aG9yaXphdGlvbjogYEJlYXJlciAke2Nvbm5lY3Rpb25JbmZvLmF1dGhUb2tlbn1gLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIG5hdmlnYXRvci5jbGlwYm9hcmQud3JpdGVUZXh0KEpTT04uc3RyaW5naWZ5KGNvbmZpZywgbnVsbCwgMikpO1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGNvcGllZDogdHJ1ZSB9KTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zZXRTdGF0ZSh7IGNvcGllZDogZmFsc2UgfSksIDIwMDApO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZVRlc3RDb25uZWN0aW9uID0gYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGNvbnN0IHsgY29ubmVjdGlvbkluZm8gfSA9IHRoaXMuc3RhdGU7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goYGh0dHA6Ly8xMjcuMC4wLjE6JHtjb25uZWN0aW9uSW5mbz8ucG9ydH0vaGVhbHRoYCk7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgaWYgKGRhdGEuc3RhdHVzID09PSAnb2snKSB7XG4gICAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIHN1Y2Nlc3NmdWwhIE1DUCBzZXJ2ZXIgaXMgaGVhbHRoeS4nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFsZXJ0KCdDb25uZWN0aW9uIGZhaWxlZDogU2VydmVyIHJldHVybmVkIHVuZXhwZWN0ZWQgcmVzcG9uc2UnKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogJ1Vua25vd24gZXJyb3InO1xuICAgICAgYWxlcnQoYENvbm5lY3Rpb24gZmFpbGVkOiAke21lc3NhZ2V9YCk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlU3RhcnRTdG9wID0gYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGNvbnN0IHsgc3RhdHVzIH0gPSB0aGlzLnN0YXRlO1xuICAgIHRoaXMuc2V0U3RhdGUoeyBhY3Rpb25JblByb2dyZXNzOiB0cnVlIH0pO1xuICAgIHRyeSB7XG4gICAgICBpZiAoc3RhdHVzPy5ydW5uaW5nKSB7XG4gICAgICAgIGF3YWl0IHRoaXMucHJvcHMuZWxlY3Ryb24/LmlwY1JlbmRlcmVyPy5pbnZva2UoJ21jcDpzdG9wJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhd2FpdCB0aGlzLnByb3BzLmVsZWN0cm9uPy5pcGNSZW5kZXJlcj8uaW52b2tlKCdtY3A6c3RhcnQnKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHRoaXMuZmV0Y2hTdGF0dXMoKTtcbiAgICAgIGF3YWl0IHRoaXMuZmV0Y2hDb25uZWN0aW9uSW5mbygpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiAnVW5rbm93biBlcnJvcic7XG4gICAgICBhbGVydChgQWN0aW9uIGZhaWxlZDogJHttZXNzYWdlfWApO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgYWN0aW9uSW5Qcm9ncmVzczogZmFsc2UgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgaGFuZGxlUmVzdGFydCA9IGFzeW5jICgpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICB0aGlzLnNldFN0YXRlKHsgYWN0aW9uSW5Qcm9ncmVzczogdHJ1ZSB9KTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5wcm9wcy5lbGVjdHJvbj8uaXBjUmVuZGVyZXI/Lmludm9rZSgnbWNwOnJlc3RhcnQnKTtcbiAgICAgIGF3YWl0IHRoaXMuZmV0Y2hTdGF0dXMoKTtcbiAgICAgIGF3YWl0IHRoaXMuZmV0Y2hDb25uZWN0aW9uSW5mbygpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiAnVW5rbm93biBlcnJvcic7XG4gICAgICBhbGVydChgUmVzdGFydCBmYWlsZWQ6ICR7bWVzc2FnZX1gKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGFjdGlvbkluUHJvZ3Jlc3M6IGZhbHNlIH0pO1xuICAgIH1cbiAgfTtcblxuICBwcml2YXRlIGhhbmRsZVJlZ2VuZXJhdGVUb2tlbiA9IGFzeW5jICgpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICBpZiAoXG4gICAgICAhY29uZmlybShcbiAgICAgICAgJ1JlZ2VuZXJhdGUgYXV0aGVudGljYXRpb24gdG9rZW4/IFlvdSB3aWxsIG5lZWQgdG8gdXBkYXRlIHlvdXIgQUkgdG9vbCBjb25maWd1cmF0aW9uLidcbiAgICAgIClcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5zZXRTdGF0ZSh7IGFjdGlvbkluUHJvZ3Jlc3M6IHRydWUgfSk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IChhd2FpdCB0aGlzLnByb3BzLmVsZWN0cm9uPy5pcGNSZW5kZXJlcj8uaW52b2tlKCdtY3A6cmVnZW5lcmF0ZVRva2VuJykpIGFzIHtcbiAgICAgICAgc3VjY2Vzcz86IGJvb2xlYW47XG4gICAgICAgIGVycm9yPzogc3RyaW5nO1xuICAgICAgfTtcbiAgICAgIGlmIChyZXN1bHQ/LnN1Y2Nlc3MpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5mZXRjaENvbm5lY3Rpb25JbmZvKCk7XG4gICAgICAgIGFsZXJ0KCdUb2tlbiByZWdlbmVyYXRlZCBzdWNjZXNzZnVsbHkuIFBsZWFzZSB1cGRhdGUgeW91ciBBSSB0b29sIGNvbmZpZ3VyYXRpb24uJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhbGVydChgRmFpbGVkIHRvIHJlZ2VuZXJhdGUgdG9rZW46ICR7cmVzdWx0Py5lcnJvcn1gKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogJ1Vua25vd24gZXJyb3InO1xuICAgICAgYWxlcnQoYEZhaWxlZCB0byByZWdlbmVyYXRlIHRva2VuOiAke21lc3NhZ2V9YCk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoeyBhY3Rpb25JblByb2dyZXNzOiBmYWxzZSB9KTtcbiAgICB9XG4gIH07XG5cbiAgcHJpdmF0ZSBnZXRTdGF0dXNDb2xvcigpOiBzdHJpbmcge1xuICAgIGNvbnN0IHsgc3RhdHVzLCBjb2xvcnMgfSA9IHRoaXMuc3RhdGU7XG4gICAgaWYgKCFzdGF0dXMpIHJldHVybiBjb2xvcnMudGV4dE11dGVkO1xuICAgIGlmIChzdGF0dXMucnVubmluZykgcmV0dXJuIGNvbG9ycy5zdWNjZXNzVGV4dDtcbiAgICByZXR1cm4gY29sb3JzLmVycm9yVGV4dDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U3RhdHVzVGV4dCgpOiBzdHJpbmcge1xuICAgIGNvbnN0IHsgbG9hZGluZywgc3RhdHVzIH0gPSB0aGlzLnN0YXRlO1xuICAgIGlmIChsb2FkaW5nKSByZXR1cm4gJ0xvYWRpbmcuLi4nO1xuICAgIGlmICghc3RhdHVzKSByZXR1cm4gJ1Vua25vd24nO1xuICAgIGlmIChzdGF0dXMucnVubmluZykgcmV0dXJuICdSdW5uaW5nJztcbiAgICByZXR1cm4gJ1N0b3BwZWQnO1xuICB9XG5cbiAgcHJpdmF0ZSBmb3JtYXRVcHRpbWUoc2Vjb25kczogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBpZiAoc2Vjb25kcyA8IDYwKSByZXR1cm4gYCR7TWF0aC5mbG9vcihzZWNvbmRzKX1zYDtcbiAgICBpZiAoc2Vjb25kcyA8IDM2MDApIHJldHVybiBgJHtNYXRoLmZsb29yKHNlY29uZHMgLyA2MCl9bWA7XG4gICAgcmV0dXJuIGAke01hdGguZmxvb3Ioc2Vjb25kcyAvIDM2MDApfWggJHtNYXRoLmZsb29yKChzZWNvbmRzICUgMzYwMCkgLyA2MCl9bWA7XG4gIH1cblxuICBwcml2YXRlIGdldFRhYlN0eWxlKGlzQWN0aXZlOiBib29sZWFuKTogUmVhY3QuQ1NTUHJvcGVydGllcyB7XG4gICAgY29uc3QgeyBjb2xvcnMgfSA9IHRoaXMuc3RhdGU7XG4gICAgcmV0dXJuIHtcbiAgICAgIHBhZGRpbmc6ICc4cHggMTZweCcsXG4gICAgICBib3JkZXI6ICdub25lJyxcbiAgICAgIGJvcmRlckJvdHRvbTogaXNBY3RpdmUgPyBgMnB4IHNvbGlkICR7Y29sb3JzLnByaW1hcnl9YCA6ICcycHggc29saWQgdHJhbnNwYXJlbnQnLFxuICAgICAgYmFja2dyb3VuZENvbG9yOiAndHJhbnNwYXJlbnQnLFxuICAgICAgY29sb3I6IGlzQWN0aXZlID8gY29sb3JzLnByaW1hcnkgOiBjb2xvcnMudGV4dFNlY29uZGFyeSxcbiAgICAgIGN1cnNvcjogJ3BvaW50ZXInLFxuICAgICAgZm9udFNpemU6ICcxNHB4JyxcbiAgICAgIGZvbnRXZWlnaHQ6IGlzQWN0aXZlID8gNjAwIDogNDAwLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGdldEJ1dHRvblN0eWxlKGJnQ29sb3I6IHN0cmluZywgZGlzYWJsZWQ/OiBib29sZWFuKTogUmVhY3QuQ1NTUHJvcGVydGllcyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHBhZGRpbmc6ICc4cHggMTZweCcsXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6IGJnQ29sb3IsXG4gICAgICBjb2xvcjogJ3doaXRlJyxcbiAgICAgIGJvcmRlcjogJ25vbmUnLFxuICAgICAgYm9yZGVyUmFkaXVzOiAnNHB4JyxcbiAgICAgIGN1cnNvcjogZGlzYWJsZWQgPyAnbm90LWFsbG93ZWQnIDogJ3BvaW50ZXInLFxuICAgICAgZm9udFNpemU6ICcxM3B4JyxcbiAgICAgIG9wYWNpdHk6IGRpc2FibGVkID8gMC41IDogMSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJTdGF0dXNUYWIoKTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgICBjb25zdCB7IHN0YXR1cywgY29ubmVjdGlvbkluZm8sIGFjdGlvbkluUHJvZ3Jlc3MsIGNvbG9ycyB9ID0gdGhpcy5zdGF0ZTtcblxuICAgIHJldHVybiAoXG4gICAgICA8PlxuICAgICAgICB7LyogU3RhdHVzIFNlY3Rpb24gKi99XG4gICAgICAgIDxkaXYgc3R5bGU9e3sgbWFyZ2luQm90dG9tOiAnMjRweCcgfX0+XG4gICAgICAgICAgPGgzXG4gICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICBmb250U2l6ZTogJzE0cHgnLFxuICAgICAgICAgICAgICBmb250V2VpZ2h0OiA2MDAsXG4gICAgICAgICAgICAgIG1hcmdpbkJvdHRvbTogJzEycHgnLFxuICAgICAgICAgICAgICBjb2xvcjogY29sb3JzLnRleHRQcmltYXJ5LFxuICAgICAgICAgICAgfX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICBTZXJ2ZXIgU3RhdHVzXG4gICAgICAgICAgPC9oMz5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICBkaXNwbGF5OiAnZmxleCcsXG4gICAgICAgICAgICAgIGFsaWduSXRlbXM6ICdjZW50ZXInLFxuICAgICAgICAgICAgICBnYXA6ICcxMnB4JyxcbiAgICAgICAgICAgICAgcGFkZGluZzogJzEycHgnLFxuICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGNvbG9ycy5wYW5lbEJnU2Vjb25kYXJ5LFxuICAgICAgICAgICAgICBib3JkZXJSYWRpdXM6ICc2cHgnLFxuICAgICAgICAgICAgfX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICAgIHdpZHRoOiAnMTJweCcsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiAnMTJweCcsXG4gICAgICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAnNTAlJyxcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMuZ2V0U3RhdHVzQ29sb3IoKSxcbiAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8c3BhbiBzdHlsZT17eyBmb250V2VpZ2h0OiA1MDAsIGNvbG9yOiBjb2xvcnMudGV4dFByaW1hcnkgfX0+XG4gICAgICAgICAgICAgIHt0aGlzLmdldFN0YXR1c1RleHQoKX1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIHtzdGF0dXM/LnJ1bm5pbmcgJiYgKFxuICAgICAgICAgICAgICA8PlxuICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPXt7IGNvbG9yOiBjb2xvcnMudGV4dFNlY29uZGFyeSB9fT58PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPXt7IGNvbG9yOiBjb2xvcnMudGV4dFNlY29uZGFyeSB9fT5Qb3J0OiB7c3RhdHVzLnBvcnR9PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPXt7IGNvbG9yOiBjb2xvcnMudGV4dFNlY29uZGFyeSB9fT58PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPXt7IGNvbG9yOiBjb2xvcnMudGV4dFNlY29uZGFyeSB9fT5cbiAgICAgICAgICAgICAgICAgIFVwdGltZToge3RoaXMuZm9ybWF0VXB0aW1lKHN0YXR1cy51cHRpbWUpfVxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgPC8+XG4gICAgICAgICAgICApfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICB7LyogU2VydmVyIENvbnRyb2xzICovfVxuICAgICAgICA8ZGl2IHN0eWxlPXt7IG1hcmdpbkJvdHRvbTogJzI0cHgnIH19PlxuICAgICAgICAgIDxoM1xuICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgZm9udFNpemU6ICcxNHB4JyxcbiAgICAgICAgICAgICAgZm9udFdlaWdodDogNjAwLFxuICAgICAgICAgICAgICBtYXJnaW5Cb3R0b206ICcxMnB4JyxcbiAgICAgICAgICAgICAgY29sb3I6IGNvbG9ycy50ZXh0UHJpbWFyeSxcbiAgICAgICAgICAgIH19XG4gICAgICAgICAgPlxuICAgICAgICAgICAgU2VydmVyIENvbnRyb2xzXG4gICAgICAgICAgPC9oMz5cbiAgICAgICAgICA8ZGl2IHN0eWxlPXt7IGRpc3BsYXk6ICdmbGV4JywgZ2FwOiAnMTJweCcsIGZsZXhXcmFwOiAnd3JhcCcgfX0+XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIG9uQ2xpY2s9e3RoaXMuaGFuZGxlU3RhcnRTdG9wfVxuICAgICAgICAgICAgICBkaXNhYmxlZD17YWN0aW9uSW5Qcm9ncmVzc31cbiAgICAgICAgICAgICAgc3R5bGU9e3RoaXMuZ2V0QnV0dG9uU3R5bGUoXG4gICAgICAgICAgICAgICAgc3RhdHVzPy5ydW5uaW5nID8gY29sb3JzLmVycm9yVGV4dCA6IGNvbG9ycy5zdWNjZXNzVGV4dCxcbiAgICAgICAgICAgICAgICBhY3Rpb25JblByb2dyZXNzXG4gICAgICAgICAgICAgICl9XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIHtzdGF0dXM/LnJ1bm5pbmcgPyAnU3RvcCBTZXJ2ZXInIDogJ1N0YXJ0IFNlcnZlcid9XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5oYW5kbGVSZXN0YXJ0fVxuICAgICAgICAgICAgICBkaXNhYmxlZD17YWN0aW9uSW5Qcm9ncmVzcyB8fCAhc3RhdHVzPy5ydW5uaW5nfVxuICAgICAgICAgICAgICBzdHlsZT17dGhpcy5nZXRCdXR0b25TdHlsZSgnIzZjNzU3ZCcsIGFjdGlvbkluUHJvZ3Jlc3MgfHwgIXN0YXR1cz8ucnVubmluZyl9XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIFJlc3RhcnQgU2VydmVyXG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5oYW5kbGVUZXN0Q29ubmVjdGlvbn1cbiAgICAgICAgICAgICAgZGlzYWJsZWQ9eyFzdGF0dXM/LnJ1bm5pbmd9XG4gICAgICAgICAgICAgIHN0eWxlPXt0aGlzLmdldEJ1dHRvblN0eWxlKFxuICAgICAgICAgICAgICAgIHN0YXR1cz8ucnVubmluZyA/ICcjMTdhMmI4JyA6IGNvbG9ycy50ZXh0TXV0ZWQsXG4gICAgICAgICAgICAgICAgIXN0YXR1cz8ucnVubmluZ1xuICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICBUZXN0IENvbm5lY3Rpb25cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICB7LyogQ29ubmVjdGlvbiBJbmZvIFNlY3Rpb24gKi99XG4gICAgICAgIHtjb25uZWN0aW9uSW5mbyAmJiAoXG4gICAgICAgICAgPGRpdiBzdHlsZT17eyBtYXJnaW5Cb3R0b206ICcyNHB4JyB9fT5cbiAgICAgICAgICAgIDxoM1xuICAgICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICAgIGZvbnRTaXplOiAnMTRweCcsXG4gICAgICAgICAgICAgICAgZm9udFdlaWdodDogNjAwLFxuICAgICAgICAgICAgICAgIG1hcmdpbkJvdHRvbTogJzEycHgnLFxuICAgICAgICAgICAgICAgIGNvbG9yOiBjb2xvcnMudGV4dFByaW1hcnksXG4gICAgICAgICAgICAgIH19XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIENvbm5lY3Rpb24gSW5mb1xuICAgICAgICAgICAgPC9oMz5cbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgICBwYWRkaW5nOiAnMTJweCcsXG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBjb2xvcnMucGFuZWxCZ1NlY29uZGFyeSxcbiAgICAgICAgICAgICAgICBib3JkZXJSYWRpdXM6ICc2cHgnLFxuICAgICAgICAgICAgICAgIGZvbnRGYW1pbHk6ICdtb25vc3BhY2UnLFxuICAgICAgICAgICAgICAgIGZvbnRTaXplOiAnMTJweCcsXG4gICAgICAgICAgICAgICAgY29sb3I6IGNvbG9ycy50ZXh0UHJpbWFyeSxcbiAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPGRpdiBzdHlsZT17eyBtYXJnaW5Cb3R0b206ICc4cHgnIH19PlxuICAgICAgICAgICAgICAgIDxzdHJvbmc+VVJMOjwvc3Ryb25nPiB7Y29ubmVjdGlvbkluZm8udXJsfVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBzdHlsZT17eyBtYXJnaW5Cb3R0b206ICc4cHgnIH19PlxuICAgICAgICAgICAgICAgIDxzdHJvbmc+c3RkaW8gc2NyaXB0Ojwvc3Ryb25nPiBiaW4vbWNwLXN0ZGlvLmpzXG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IHN0eWxlPXt7IG1hcmdpbkJvdHRvbTogJzhweCcgfX0+XG4gICAgICAgICAgICAgICAgPHN0cm9uZz5WZXJzaW9uOjwvc3Ryb25nPiB7Y29ubmVjdGlvbkluZm8udmVyc2lvbn1cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPHN0cm9uZz5Ub29sczo8L3N0cm9uZz4ge2Nvbm5lY3Rpb25JbmZvLnRvb2xzLmpvaW4oJywgJyl9XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICl9XG5cbiAgICAgICAgey8qIFNlY3VyaXR5IFNlY3Rpb24gKi99XG4gICAgICAgIDxkaXYgc3R5bGU9e3sgbWFyZ2luQm90dG9tOiAnMjRweCcgfX0+XG4gICAgICAgICAgPGgzXG4gICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICBmb250U2l6ZTogJzE0cHgnLFxuICAgICAgICAgICAgICBmb250V2VpZ2h0OiA2MDAsXG4gICAgICAgICAgICAgIG1hcmdpbkJvdHRvbTogJzEycHgnLFxuICAgICAgICAgICAgICBjb2xvcjogY29sb3JzLnRleHRQcmltYXJ5LFxuICAgICAgICAgICAgfX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICBTZWN1cml0eVxuICAgICAgICAgIDwvaDM+XG4gICAgICAgICAgPGRpdiBzdHlsZT17eyBkaXNwbGF5OiAnZmxleCcsIGdhcDogJzEycHgnLCBmbGV4V3JhcDogJ3dyYXAnIH19PlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICBvbkNsaWNrPXt0aGlzLmhhbmRsZVJlZ2VuZXJhdGVUb2tlbn1cbiAgICAgICAgICAgICAgZGlzYWJsZWQ9e2FjdGlvbkluUHJvZ3Jlc3MgfHwgIXN0YXR1cz8ucnVubmluZ31cbiAgICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgICBwYWRkaW5nOiAnOHB4IDE2cHgnLFxuICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogJyNmZmMxMDcnLFxuICAgICAgICAgICAgICAgIGNvbG9yOiAnIzIxMjUyOScsXG4gICAgICAgICAgICAgICAgYm9yZGVyOiAnbm9uZScsXG4gICAgICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAnNHB4JyxcbiAgICAgICAgICAgICAgICBjdXJzb3I6IGFjdGlvbkluUHJvZ3Jlc3MgfHwgIXN0YXR1cz8ucnVubmluZyA/ICdub3QtYWxsb3dlZCcgOiAncG9pbnRlcicsXG4gICAgICAgICAgICAgICAgZm9udFNpemU6ICcxM3B4JyxcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiBhY3Rpb25JblByb2dyZXNzIHx8ICFzdGF0dXM/LnJ1bm5pbmcgPyAwLjUgOiAxLFxuICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICBSZWdlbmVyYXRlIFRva2VuXG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8cCBzdHlsZT17eyBmb250U2l6ZTogJzEycHgnLCBjb2xvcjogY29sb3JzLnRleHRTZWNvbmRhcnksIG1hcmdpblRvcDogJzhweCcgfX0+XG4gICAgICAgICAgICBSZWdlbmVyYXRpbmcgdGhlIHRva2VuIHdpbGwgcmVxdWlyZSB5b3UgdG8gdXBkYXRlIHlvdXIgQUkgdG9vbCBjb25maWd1cmF0aW9uLlxuICAgICAgICAgIDwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8Lz5cbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJTZXR1cFRhYigpOiBSZWFjdC5SZWFjdE5vZGUge1xuICAgIGNvbnN0IHsgY29ubmVjdGlvbkluZm8sIGNvcGllZCwgY29sb3JzIH0gPSB0aGlzLnN0YXRlO1xuXG4gICAgcmV0dXJuIChcbiAgICAgIDw+XG4gICAgICAgIHsvKiBDbGF1ZGUgQ29kZSBTZXR1cCAqL31cbiAgICAgICAgPGRpdiBzdHlsZT17eyBtYXJnaW5Cb3R0b206ICcyNHB4JyB9fT5cbiAgICAgICAgICA8aDNcbiAgICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICAgIGZvbnRTaXplOiAnMTRweCcsXG4gICAgICAgICAgICAgIGZvbnRXZWlnaHQ6IDYwMCxcbiAgICAgICAgICAgICAgbWFyZ2luQm90dG9tOiAnMTJweCcsXG4gICAgICAgICAgICAgIGNvbG9yOiBjb2xvcnMudGV4dFByaW1hcnksXG4gICAgICAgICAgICB9fVxuICAgICAgICAgID5cbiAgICAgICAgICAgIENsYXVkZSBDb2RlIChSZWNvbW1lbmRlZClcbiAgICAgICAgICA8L2gzPlxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICAgIHBhZGRpbmc6ICcxNnB4JyxcbiAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBjb2xvcnMucGFuZWxCZ1NlY29uZGFyeSxcbiAgICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAnNnB4JyxcbiAgICAgICAgICAgIH19XG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHAgc3R5bGU9e3sgbWFyZ2luOiAnMCAwIDEycHggMCcsIGZvbnRTaXplOiAnMTNweCcsIGNvbG9yOiBjb2xvcnMudGV4dFByaW1hcnkgfX0+XG4gICAgICAgICAgICAgIEFkZCB0aGUgZm9sbG93aW5nIHRvIHlvdXJ7JyAnfVxuICAgICAgICAgICAgICA8Y29kZVxuICAgICAgICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGNvbG9ycy5wYW5lbEJnQ29kZSxcbiAgICAgICAgICAgICAgICAgIHBhZGRpbmc6ICcycHggNHB4JyxcbiAgICAgICAgICAgICAgICAgIGJvcmRlclJhZGl1czogJzNweCcsXG4gICAgICAgICAgICAgICAgICBjb2xvcjogJyNmOGY4ZjInLFxuICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICB+Ly5jbGF1ZGUuanNvblxuICAgICAgICAgICAgICA8L2NvZGU+eycgJ31cbiAgICAgICAgICAgICAgZmlsZTpcbiAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgIDxwcmVcbiAgICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGNvbG9ycy5wYW5lbEJnQ29kZSxcbiAgICAgICAgICAgICAgICBjb2xvcjogJyNmOGY4ZjInLFxuICAgICAgICAgICAgICAgIHBhZGRpbmc6ICcxMnB4JyxcbiAgICAgICAgICAgICAgICBib3JkZXJSYWRpdXM6ICc0cHgnLFxuICAgICAgICAgICAgICAgIGZvbnRTaXplOiAnMTFweCcsXG4gICAgICAgICAgICAgICAgb3ZlcmZsb3c6ICdhdXRvJyxcbiAgICAgICAgICAgICAgICBtYXJnaW46ICcwIDAgMTJweCAwJyxcbiAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAge2B7XG4gIFwibWNwU2VydmVyc1wiOiB7XG4gICAgXCJsb2NhbFwiOiB7XG4gICAgICBcInR5cGVcIjogXCJzdGRpb1wiLFxuICAgICAgXCJjb21tYW5kXCI6IFwibm9kZVwiLFxuICAgICAgXCJhcmdzXCI6IFtcIi9wYXRoL3RvL2xvY2FsLWFkZG9uLW1jcC1zZXJ2ZXIvYmluL21jcC1zdGRpby5qc1wiXVxuICAgIH1cbiAgfVxufWB9XG4gICAgICAgICAgICA8L3ByZT5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5oYW5kbGVDb3B5U3RkaW9Db25maWd9XG4gICAgICAgICAgICAgIHN0eWxlPXt0aGlzLmdldEJ1dHRvblN0eWxlKGNvbG9ycy5wcmltYXJ5KX1cbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAge2NvcGllZCA/ICdDb3BpZWQhJyA6ICdDb3B5IENvbmZpZyd9XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgey8qIENsYXVkZS5haSAvIENoYXRHUFQgU2V0dXAgKi99XG4gICAgICAgIDxkaXYgc3R5bGU9e3sgbWFyZ2luQm90dG9tOiAnMjRweCcgfX0+XG4gICAgICAgICAgPGgzXG4gICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICBmb250U2l6ZTogJzE0cHgnLFxuICAgICAgICAgICAgICBmb250V2VpZ2h0OiA2MDAsXG4gICAgICAgICAgICAgIG1hcmdpbkJvdHRvbTogJzEycHgnLFxuICAgICAgICAgICAgICBjb2xvcjogY29sb3JzLnRleHRQcmltYXJ5LFxuICAgICAgICAgICAgfX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICBDbGF1ZGUuYWkgLyBDaGF0R1BUIC8gT3RoZXIgQUkgVG9vbHNcbiAgICAgICAgICA8L2gzPlxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICAgIHBhZGRpbmc6ICcxNnB4JyxcbiAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBjb2xvcnMucGFuZWxCZ1NlY29uZGFyeSxcbiAgICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAnNnB4JyxcbiAgICAgICAgICAgIH19XG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHAgc3R5bGU9e3sgbWFyZ2luOiAnMCAwIDEycHggMCcsIGZvbnRTaXplOiAnMTNweCcsIGNvbG9yOiBjb2xvcnMudGV4dFByaW1hcnkgfX0+XG4gICAgICAgICAgICAgIEZvciB0b29scyB0aGF0IHN1cHBvcnQgU1NFIHRyYW5zcG9ydCwgdXNlIHRoaXMgY29uZmlndXJhdGlvbjpcbiAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgIDxwcmVcbiAgICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGNvbG9ycy5wYW5lbEJnQ29kZSxcbiAgICAgICAgICAgICAgICBjb2xvcjogJyNmOGY4ZjInLFxuICAgICAgICAgICAgICAgIHBhZGRpbmc6ICcxMnB4JyxcbiAgICAgICAgICAgICAgICBib3JkZXJSYWRpdXM6ICc0cHgnLFxuICAgICAgICAgICAgICAgIGZvbnRTaXplOiAnMTFweCcsXG4gICAgICAgICAgICAgICAgb3ZlcmZsb3c6ICdhdXRvJyxcbiAgICAgICAgICAgICAgICBtYXJnaW46ICcwIDAgMTJweCAwJyxcbiAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAge2Nvbm5lY3Rpb25JbmZvXG4gICAgICAgICAgICAgICAgPyBge1xuICBcIm1jcFNlcnZlcnNcIjoge1xuICAgIFwibG9jYWxcIjoge1xuICAgICAgXCJ1cmxcIjogXCIke2Nvbm5lY3Rpb25JbmZvLnVybH0vbWNwL3NzZVwiLFxuICAgICAgXCJ0cmFuc3BvcnRcIjogXCJzc2VcIixcbiAgICAgIFwiaGVhZGVyc1wiOiB7XG4gICAgICAgIFwiQXV0aG9yaXphdGlvblwiOiBcIkJlYXJlciAke2Nvbm5lY3Rpb25JbmZvLmF1dGhUb2tlbi5zdWJzdHJpbmcoMCwgMjApfS4uLlwiXG4gICAgICB9XG4gICAgfVxuICB9XG59YFxuICAgICAgICAgICAgICAgIDogJ1NlcnZlciBub3QgcnVubmluZyd9XG4gICAgICAgICAgICA8L3ByZT5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5oYW5kbGVDb3B5U3NlQ29uZmlnfVxuICAgICAgICAgICAgICBkaXNhYmxlZD17IWNvbm5lY3Rpb25JbmZvfVxuICAgICAgICAgICAgICBzdHlsZT17dGhpcy5nZXRCdXR0b25TdHlsZShcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uSW5mbyA/IGNvbG9ycy5wcmltYXJ5IDogY29sb3JzLnRleHRNdXRlZCxcbiAgICAgICAgICAgICAgICAhY29ubmVjdGlvbkluZm9cbiAgICAgICAgICAgICAgKX1cbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAge2NvcGllZCA/ICdDb3BpZWQhJyA6ICdDb3B5IFNTRSBDb25maWcnfVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIHsvKiBBdmFpbGFibGUgQ29tbWFuZHMgKi99XG4gICAgICAgIDxkaXYgc3R5bGU9e3sgbWFyZ2luQm90dG9tOiAnMjRweCcgfX0+XG4gICAgICAgICAgPGgzXG4gICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICBmb250U2l6ZTogJzE0cHgnLFxuICAgICAgICAgICAgICBmb250V2VpZ2h0OiA2MDAsXG4gICAgICAgICAgICAgIG1hcmdpbkJvdHRvbTogJzEycHgnLFxuICAgICAgICAgICAgICBjb2xvcjogY29sb3JzLnRleHRQcmltYXJ5LFxuICAgICAgICAgICAgfX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICBFeGFtcGxlIENvbW1hbmRzXG4gICAgICAgICAgPC9oMz5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICBwYWRkaW5nOiAnMTZweCcsXG4gICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogY29sb3JzLmluZm9CZyxcbiAgICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAnNnB4JyxcbiAgICAgICAgICAgICAgYm9yZGVyOiBgMXB4IHNvbGlkICR7Y29sb3JzLmluZm9Cb3JkZXJ9YCxcbiAgICAgICAgICAgIH19XG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHBcbiAgICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgICBtYXJnaW46ICcwIDAgOHB4IDAnLFxuICAgICAgICAgICAgICAgIGZvbnRTaXplOiAnMTNweCcsXG4gICAgICAgICAgICAgICAgZm9udFdlaWdodDogNTAwLFxuICAgICAgICAgICAgICAgIGNvbG9yOiBjb2xvcnMuaW5mb1RleHQsXG4gICAgICAgICAgICAgIH19XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIFRyeSBzYXlpbmcgdG8geW91ciBBSSBhc3Npc3RhbnQ6XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICA8dWxcbiAgICAgICAgICAgICAgc3R5bGU9e3sgbWFyZ2luOiAwLCBwYWRkaW5nTGVmdDogJzIwcHgnLCBmb250U2l6ZTogJzEzcHgnLCBjb2xvcjogY29sb3JzLmluZm9UZXh0IH19XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxsaT4mcXVvdDtMaXN0IG15IExvY2FsIHNpdGVzJnF1b3Q7PC9saT5cbiAgICAgICAgICAgICAgPGxpPiZxdW90O1N0YXJ0IHRoZSBibG9nIHNpdGUmcXVvdDs8L2xpPlxuICAgICAgICAgICAgICA8bGk+JnF1b3Q7Q3JlYXRlIGEgbmV3IHNpdGUgY2FsbGVkIHRlc3QtcHJvamVjdCZxdW90OzwvbGk+XG4gICAgICAgICAgICAgIDxsaT4mcXVvdDtSdW4gd3AgcGx1Z2luIGxpc3Qgb24gbXktc2l0ZSZxdW90OzwvbGk+XG4gICAgICAgICAgICAgIDxsaT4mcXVvdDtTdG9wIGFsbCBydW5uaW5nIHNpdGVzJnF1b3Q7PC9saT5cbiAgICAgICAgICAgICAgPGxpPiZxdW90O1doYXQgcGx1Z2lucyBhcmUgaW5zdGFsbGVkIG9uIG15LXNpdGU/JnF1b3Q7PC9saT5cbiAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC8+XG4gICAgKTtcbiAgfVxuXG4gIHJlbmRlcigpOiBSZWFjdC5SZWFjdE5vZGUge1xuICAgIGNvbnN0IHsgYWN0aXZlVGFiLCBjb2xvcnMgfSA9IHRoaXMuc3RhdGU7XG5cbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBzdHlsZT17eyBwYWRkaW5nOiAnMjBweCcsIGNvbG9yOiBjb2xvcnMudGV4dFByaW1hcnkgfX0+XG4gICAgICAgIDxoMlxuICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICBtYXJnaW5Cb3R0b206ICcyMHB4JyxcbiAgICAgICAgICAgIGZvbnRTaXplOiAnMThweCcsXG4gICAgICAgICAgICBmb250V2VpZ2h0OiA2MDAsXG4gICAgICAgICAgICBjb2xvcjogY29sb3JzLnRleHRQcmltYXJ5LFxuICAgICAgICAgIH19XG4gICAgICAgID5cbiAgICAgICAgICBNQ1AgU2VydmVyXG4gICAgICAgIDwvaDI+XG5cbiAgICAgICAgPHAgc3R5bGU9e3sgY29sb3I6IGNvbG9ycy50ZXh0U2Vjb25kYXJ5LCBtYXJnaW5Cb3R0b206ICcyNHB4JyB9fT5cbiAgICAgICAgICBUaGUgTUNQIChNb2RlbCBDb250ZXh0IFByb3RvY29sKSBzZXJ2ZXIgZW5hYmxlcyBBSSB0b29scyBsaWtlIENsYXVkZSBDb2RlIHRvIGNvbnRyb2wgeW91clxuICAgICAgICAgIExvY2FsIHNpdGVzLlxuICAgICAgICA8L3A+XG5cbiAgICAgICAgey8qIFRhYiBOYXZpZ2F0aW9uICovfVxuICAgICAgICA8ZGl2IHN0eWxlPXt7IGJvcmRlckJvdHRvbTogYDFweCBzb2xpZCAke2NvbG9ycy5ib3JkZXJ9YCwgbWFyZ2luQm90dG9tOiAnMjRweCcgfX0+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgc3R5bGU9e3RoaXMuZ2V0VGFiU3R5bGUoYWN0aXZlVGFiID09PSAnc3RhdHVzJyl9XG4gICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiB0aGlzLnNldFN0YXRlKHsgYWN0aXZlVGFiOiAnc3RhdHVzJyB9KX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICBTdGF0dXMgJmFtcDsgQ29udHJvbHNcbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBzdHlsZT17dGhpcy5nZXRUYWJTdHlsZShhY3RpdmVUYWIgPT09ICdzZXR1cCcpfVxuICAgICAgICAgICAgb25DbGljaz17KCkgPT4gdGhpcy5zZXRTdGF0ZSh7IGFjdGl2ZVRhYjogJ3NldHVwJyB9KX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICBBSSBUb29sIFNldHVwXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIHthY3RpdmVUYWIgPT09ICdzdGF0dXMnICYmIHRoaXMucmVuZGVyU3RhdHVzVGFiKCl9XG4gICAgICAgIHthY3RpdmVUYWIgPT09ICdzZXR1cCcgJiYgdGhpcy5yZW5kZXJTZXR1cFRhYigpfVxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufVxuXG4vLyBFeHBvcnQgYXMgYSBjb25zdHJ1Y3RvciBmdW5jdGlvbiB0aGF0IExvY2FsIGNhbiBpbnN0YW50aWF0ZVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBNY3BTZXJ2ZXJSZW5kZXJlcihjb250ZXh0OiB7IGhvb2tzOiB1bmtub3duOyBlbGVjdHJvbjogdW5rbm93biB9KTogdm9pZCB7XG4gIC8vIENMSS1vbmx5IG1vZGUgLSBwcmVmZXJlbmNlcyBwYW5lbCBkaXNhYmxlZFxuICAvLyBUbyBlbmFibGUgTUNQIHByZWZlcmVuY2VzIFVJLCB1bmNvbW1lbnQgdGhlIGZvbGxvd2luZzpcbiAgLypcbiAgY29uc3QgeyBob29rcywgZWxlY3Ryb24gfSA9IGNvbnRleHQgYXMge1xuICAgIGhvb2tzOiB7IGFkZEZpbHRlcjogKG5hbWU6IHN0cmluZywgY2FsbGJhY2s6IChpdGVtczogdW5rbm93bltdKSA9PiB1bmtub3duW10pID0+IHZvaWQgfTtcbiAgICBlbGVjdHJvbjogTWNwUHJlZmVyZW5jZXNQYW5lbFByb3BzWydlbGVjdHJvbiddO1xuICB9O1xuXG4gIGNvbnNvbGUubG9nKCdbTUNQIFNlcnZlcl0gUmVuZGVyZXIgbG9hZGluZy4uLicpO1xuXG4gIC8vIEFkZCBNQ1AgU2VydmVyIHRvIHByZWZlcmVuY2VzIG1lbnVcbiAgaG9va3MuYWRkRmlsdGVyKCdwcmVmZXJlbmNlc01lbnVJdGVtcycsIChtZW51SXRlbXM6IHVua25vd25bXSkgPT4ge1xuICAgIGNvbnNvbGUubG9nKCdbTUNQIFNlcnZlcl0gQWRkaW5nIE1DUCBTZXJ2ZXIgdG8gcHJlZmVyZW5jZXMnKTtcblxuICAgIChtZW51SXRlbXMgYXMgQXJyYXk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+KS5wdXNoKHtcbiAgICAgIHBhdGg6ICdtY3Atc2VydmVyJyxcbiAgICAgIGRpc3BsYXlOYW1lOiAnTUNQIFNlcnZlcicsXG4gICAgICBzZWN0aW9uczogKCkgPT4gPE1jcFByZWZlcmVuY2VzUGFuZWwgZWxlY3Ryb249e2VsZWN0cm9ufSAvPixcbiAgICAgIG9uQXBwbHk6ICgpID0+IHtcbiAgICAgICAgLy8gTm8gYXBwbHkgYWN0aW9uIG5lZWRlZCBmb3IgcmVhZC1vbmx5IGRpc3BsYXlcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICByZXR1cm4gbWVudUl0ZW1zO1xuICB9KTtcblxuICBjb25zb2xlLmxvZygnW01DUCBTZXJ2ZXJdIFJlbmRlcmVyIHNldHVwIGNvbXBsZXRlJyk7XG4gICovXG5cbiAgLy8gU2lsZW5jZSB1bnVzZWQgdmFyaWFibGUgd2FybmluZ3NcbiAgdm9pZCBjb250ZXh0O1xufTtcbiJdfQ==
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@local-labs-jpollock/local-addon-cli",
|
|
3
|
+
"productName": "Local CLI",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"description": "Command-line interface for Local WordPress development",
|
|
6
|
+
"main": "lib/main/index.js",
|
|
7
|
+
"renderer": "lib/renderer/index.js",
|
|
8
|
+
"bin": {
|
|
9
|
+
"local-mcp": "./bin/mcp-stdio.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "npm run clean && tsc",
|
|
13
|
+
"watch": "tsc --watch",
|
|
14
|
+
"clean": "rm -rf lib coverage",
|
|
15
|
+
"lint": "eslint src --ext .ts,.tsx --max-warnings=0",
|
|
16
|
+
"lint:fix": "eslint src --ext .ts,.tsx --fix",
|
|
17
|
+
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
|
|
18
|
+
"format:check": "prettier --check \"src/**/*.{ts,tsx}\"",
|
|
19
|
+
"typecheck": "tsc --noEmit",
|
|
20
|
+
"test": "jest",
|
|
21
|
+
"test:watch": "jest --watch",
|
|
22
|
+
"test:coverage": "jest --coverage"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"local",
|
|
26
|
+
"addon",
|
|
27
|
+
"cli",
|
|
28
|
+
"wordpress",
|
|
29
|
+
"development"
|
|
30
|
+
],
|
|
31
|
+
"author": "Jeremy Pollock <jpollock911@gmail.com>",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://github.com/jpollock/local-addon-cli.git",
|
|
36
|
+
"directory": "packages/addon"
|
|
37
|
+
},
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18.0.0"
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"lib/",
|
|
43
|
+
"bin/",
|
|
44
|
+
"README.md",
|
|
45
|
+
"LICENSE"
|
|
46
|
+
],
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@getflywheel/local": "^9.0.0",
|
|
49
|
+
"@types/fs-extra": "^11.0.4",
|
|
50
|
+
"@types/jest": "^29.5.12",
|
|
51
|
+
"@types/node": "^20.0.0",
|
|
52
|
+
"@types/react": "^19.2.10",
|
|
53
|
+
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
|
54
|
+
"@typescript-eslint/parser": "^7.0.0",
|
|
55
|
+
"eslint": "^8.57.0",
|
|
56
|
+
"eslint-config-prettier": "^9.1.0",
|
|
57
|
+
"eslint-plugin-react": "^7.34.0",
|
|
58
|
+
"eslint-plugin-react-hooks": "^4.6.0",
|
|
59
|
+
"graphql-tag": "^2.12.6",
|
|
60
|
+
"jest": "^29.7.0",
|
|
61
|
+
"prettier": "^3.2.5",
|
|
62
|
+
"ts-jest": "^29.1.2",
|
|
63
|
+
"typescript": "^5.0.0"
|
|
64
|
+
},
|
|
65
|
+
"localAddon": {
|
|
66
|
+
"minimumLocalVersion": "9.0.0",
|
|
67
|
+
"type": "addon",
|
|
68
|
+
"category": "developer-tools"
|
|
69
|
+
},
|
|
70
|
+
"dependencies": {
|
|
71
|
+
"node-stream-zip": "^1.15.0"
|
|
72
|
+
}
|
|
73
|
+
}
|