@hydra-acp/browser 0.1.0 → 0.1.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/hydra/client.js +13 -8
- package/dist/hydra/client.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/server/routes-config.js +14 -0
- package/dist/server/routes-config.js.map +1 -0
- package/dist/server/routes-sessions.js +12 -3
- package/dist/server/routes-sessions.js.map +1 -1
- package/dist/ui/index.html +59 -10
- package/package.json +1 -1
package/dist/hydra/client.js
CHANGED
|
@@ -8,14 +8,16 @@ export class HydraRestClient {
|
|
|
8
8
|
this.token = token;
|
|
9
9
|
}
|
|
10
10
|
async json(method, path, body) {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
headers: {
|
|
14
|
-
Authorization: `Bearer ${this.token}`,
|
|
15
|
-
"Content-Type": "application/json",
|
|
16
|
-
},
|
|
11
|
+
const headers = {
|
|
12
|
+
Authorization: `Bearer ${this.token}`,
|
|
17
13
|
};
|
|
14
|
+
const init = { method, headers };
|
|
15
|
+
// Only set Content-Type when there's a body. Fastify v5 rejects
|
|
16
|
+
// POST with Content-Type: application/json and an empty body
|
|
17
|
+
// (FST_ERR_CTP_EMPTY_JSON_BODY), which broke bodyless POSTs like
|
|
18
|
+
// /v1/sessions/:id/kill.
|
|
18
19
|
if (body !== undefined) {
|
|
20
|
+
headers["Content-Type"] = "application/json";
|
|
19
21
|
init.body = JSON.stringify(body);
|
|
20
22
|
}
|
|
21
23
|
const r = await fetch(`${this.baseUrl}${path}`, init);
|
|
@@ -43,12 +45,15 @@ export class HydraRestClient {
|
|
|
43
45
|
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
44
46
|
return this.json("GET", `/v1/sessions${suffix}`);
|
|
45
47
|
}
|
|
46
|
-
async
|
|
47
|
-
await this.json("
|
|
48
|
+
async killSession(sessionId) {
|
|
49
|
+
await this.json("POST", `/v1/sessions/${encodeURIComponent(sessionId)}/kill`);
|
|
48
50
|
}
|
|
49
51
|
async listAgents() {
|
|
50
52
|
return this.json("GET", "/v1/agents");
|
|
51
53
|
}
|
|
54
|
+
async getConfig() {
|
|
55
|
+
return this.json("GET", "/v1/config");
|
|
56
|
+
}
|
|
52
57
|
}
|
|
53
58
|
export class HydraRestError extends Error {
|
|
54
59
|
status;
|
package/dist/hydra/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/hydra/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;AAqBjC,MAAM,OAAO,eAAe;IAEP;IACA;IAFnB,YACmB,OAAe,EACf,KAAa;QADb,YAAO,GAAP,OAAO,CAAQ;QACf,UAAK,GAAL,KAAK,CAAQ;IAC7B,CAAC;IAEI,KAAK,CAAC,IAAI,CAChB,MAAc,EACd,IAAY,EACZ,IAAc;QAEd,MAAM,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/hydra/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import { registerSessionRoutes } from "./server/routes-sessions.js";
|
|
|
9
9
|
import { registerAgentRoutes } from "./server/routes-agents.js";
|
|
10
10
|
import { registerFileRoutes } from "./server/routes-files.js";
|
|
11
11
|
import { registerRootRoutes } from "./server/routes-root.js";
|
|
12
|
+
import { registerConfigRoutes } from "./server/routes-config.js";
|
|
12
13
|
import { attachWsBridge } from "./server/ws-bridge.js";
|
|
13
14
|
import { logger, setDebug } from "./util/log.js";
|
|
14
15
|
const log = logger("main");
|
|
@@ -40,6 +41,7 @@ async function main(argv) {
|
|
|
40
41
|
registerSessionRoutes(app, ctx);
|
|
41
42
|
registerAgentRoutes(app, ctx);
|
|
42
43
|
registerFileRoutes(app, ctx);
|
|
44
|
+
registerConfigRoutes(app, ctx);
|
|
43
45
|
await app.listen({ host: config.browserHost, port: config.browserPort });
|
|
44
46
|
attachWsBridge(app.server, ctx);
|
|
45
47
|
const scheme = config.tls ? "https" : "http";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;AAE3B,SAAS,mBAAmB,CAAC,IAAY,EAAE,MAAe;IACxD,MAAM,UAAU,GACd,IAAI,KAAK,WAAW;QACpB,IAAI,KAAK,KAAK;QACd,IAAI,KAAK,WAAW;QACpB,IAAI,KAAK,OAAO,CAAC;IACnB,IAAI,CAAC,UAAU,IAAI,CAAC,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,yCAAyC,IAAI,iGAAiG,CAC/I,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI,CAAC,IAAc;IAChC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,SAAS,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAEjD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEvB,mBAAmB,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAEtD,MAAM,OAAO,GAAG,MAAM;QACpB,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC;QACnC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAEtC,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IAC3E,MAAM,GAAG,GAAG,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAE9B,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC7B,qBAAqB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAChC,mBAAmB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC9B,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { HydraRestError } from "../hydra/client.js";
|
|
2
|
+
export function registerConfigRoutes(app, ctx) {
|
|
3
|
+
app.get("/api/config", async (_request, reply) => {
|
|
4
|
+
try {
|
|
5
|
+
const result = await ctx.rest.getConfig();
|
|
6
|
+
reply.send(result);
|
|
7
|
+
}
|
|
8
|
+
catch (err) {
|
|
9
|
+
const status = err instanceof HydraRestError ? err.status : 502;
|
|
10
|
+
reply.code(status).send({ error: err.message });
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=routes-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes-config.js","sourceRoot":"","sources":["../../src/server/routes-config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGpD,MAAM,UAAU,oBAAoB,CAClC,GAAoB,EACpB,GAAkB;IAElB,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;QAC/C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAC1C,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,GAAG,YAAY,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;YAChE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
1
2
|
import { HydraRestError } from "../hydra/client.js";
|
|
2
3
|
import { UpstreamConnection, runInitialize } from "../hydra/ws.js";
|
|
3
4
|
import { logger } from "../util/log.js";
|
|
5
|
+
function expandHome(p) {
|
|
6
|
+
if (p === "~")
|
|
7
|
+
return homedir();
|
|
8
|
+
if (p.startsWith("~/"))
|
|
9
|
+
return homedir() + p.slice(1);
|
|
10
|
+
return p;
|
|
11
|
+
}
|
|
4
12
|
const log = logger("routes-sessions");
|
|
5
13
|
export function registerSessionRoutes(app, ctx) {
|
|
6
14
|
app.get("/api/health", { config: { skipAuth: true } }, async (_request, reply) => {
|
|
@@ -33,7 +41,7 @@ export function registerSessionRoutes(app, ctx) {
|
|
|
33
41
|
return;
|
|
34
42
|
}
|
|
35
43
|
try {
|
|
36
|
-
await ctx.rest.
|
|
44
|
+
await ctx.rest.killSession(body.sessionId);
|
|
37
45
|
reply.code(204).send();
|
|
38
46
|
}
|
|
39
47
|
catch (err) {
|
|
@@ -72,10 +80,11 @@ async function createSession(ctx, body) {
|
|
|
72
80
|
});
|
|
73
81
|
conn.start();
|
|
74
82
|
await opened;
|
|
83
|
+
const cwd = expandHome(body.cwd);
|
|
75
84
|
try {
|
|
76
85
|
await runInitialize(conn);
|
|
77
86
|
const newParams = {
|
|
78
|
-
cwd
|
|
87
|
+
cwd,
|
|
79
88
|
mcpServers: [],
|
|
80
89
|
};
|
|
81
90
|
if (body.agentId) {
|
|
@@ -94,7 +103,7 @@ async function createSession(ctx, body) {
|
|
|
94
103
|
return {
|
|
95
104
|
sessionId: newResult.sessionId,
|
|
96
105
|
agentId: body.agentId,
|
|
97
|
-
cwd
|
|
106
|
+
cwd,
|
|
98
107
|
};
|
|
99
108
|
}
|
|
100
109
|
finally {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes-sessions.js","sourceRoot":"","sources":["../../src/server/routes-sessions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"routes-sessions.js","sourceRoot":"","sources":["../../src/server/routes-sessions.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/index.html
CHANGED
|
@@ -62,7 +62,7 @@ pre code { background: transparent; padding: 0; }
|
|
|
62
62
|
/* Session list */
|
|
63
63
|
.list { flex: 1; overflow-y: auto; padding: 1rem; }
|
|
64
64
|
.list .group { margin-bottom: 1.25rem; }
|
|
65
|
-
.list .group h2 { font-size: 0.85rem;
|
|
65
|
+
.list .group h2 { font-size: 0.85rem; color: var(--muted); margin: 0 0 0.5rem; }
|
|
66
66
|
.card { background: var(--panel); border: 1px solid var(--border); border-radius: 8px; padding: 0.75rem 1rem; margin-bottom: 0.5rem; display: flex; align-items: center; gap: 0.75rem; cursor: pointer; }
|
|
67
67
|
.card:hover { background: var(--panel-2); }
|
|
68
68
|
.card .meta { flex: 1; min-width: 0; }
|
|
@@ -1071,8 +1071,27 @@ pre code { background: transparent; padding: 0; }
|
|
|
1071
1071
|
return "untitled";
|
|
1072
1072
|
}
|
|
1073
1073
|
function shortSessionId(sessionId) {
|
|
1074
|
-
|
|
1075
|
-
|
|
1074
|
+
return sessionId.replace(/^hydra_session_/, "");
|
|
1075
|
+
}
|
|
1076
|
+
function formatRelativeAge(iso, now = Date.now()) {
|
|
1077
|
+
if (!iso) return "?";
|
|
1078
|
+
const t = Date.parse(iso);
|
|
1079
|
+
if (Number.isNaN(t)) return "?";
|
|
1080
|
+
const diff = Math.max(0, now - t);
|
|
1081
|
+
const sec = Math.floor(diff / 1e3);
|
|
1082
|
+
if (sec < 60) return "<1m";
|
|
1083
|
+
const min = Math.floor(sec / 60);
|
|
1084
|
+
if (min < 60) return `${min}m`;
|
|
1085
|
+
const hr = Math.floor(min / 60);
|
|
1086
|
+
if (hr < 24) return `${hr}h`;
|
|
1087
|
+
const day = Math.floor(hr / 24);
|
|
1088
|
+
if (day < 14) return `${day}d`;
|
|
1089
|
+
const week = Math.floor(day / 7);
|
|
1090
|
+
if (week < 9) return `${week}w`;
|
|
1091
|
+
const month = Math.floor(day / 30);
|
|
1092
|
+
if (month < 12) return `${month}mo`;
|
|
1093
|
+
const year = Math.floor(day / 365);
|
|
1094
|
+
return `${year}y`;
|
|
1076
1095
|
}
|
|
1077
1096
|
function fmtTokens(n) {
|
|
1078
1097
|
if (!Number.isFinite(n)) return "?";
|
|
@@ -1186,7 +1205,7 @@ pre code { background: transparent; padding: 0; }
|
|
|
1186
1205
|
groupNode.appendChild(el("h2", null, g.label));
|
|
1187
1206
|
}
|
|
1188
1207
|
for (const s of g.sessions) {
|
|
1189
|
-
groupNode.appendChild(renderSessionCard(s));
|
|
1208
|
+
groupNode.appendChild(renderSessionCard(s, g.label === null));
|
|
1190
1209
|
}
|
|
1191
1210
|
list.appendChild(groupNode);
|
|
1192
1211
|
}
|
|
@@ -1212,15 +1231,22 @@ pre code { background: transparent; padding: 0; }
|
|
|
1212
1231
|
}
|
|
1213
1232
|
const out = [];
|
|
1214
1233
|
for (const [cwd, items] of [...map.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {
|
|
1215
|
-
const last = cwd.split("/").filter(Boolean).pop() || cwd;
|
|
1216
1234
|
items.sort(compareSessions);
|
|
1217
|
-
out.push({ label:
|
|
1235
|
+
out.push({ label: cwd, sessions: items });
|
|
1218
1236
|
}
|
|
1219
1237
|
return out;
|
|
1220
1238
|
}
|
|
1221
|
-
function renderSessionCard(s) {
|
|
1239
|
+
function renderSessionCard(s, showCwd) {
|
|
1222
1240
|
const title = s.title || fallbackTitle(s.sessionId);
|
|
1223
|
-
const
|
|
1241
|
+
const parts = [
|
|
1242
|
+
shortSessionId(s.sessionId),
|
|
1243
|
+
s.agentId || "?",
|
|
1244
|
+
`age ${formatRelativeAge(s.updatedAt)}`
|
|
1245
|
+
];
|
|
1246
|
+
if (showCwd) {
|
|
1247
|
+
parts.push(s.cwd || "?");
|
|
1248
|
+
}
|
|
1249
|
+
const subtitle = parts.join(" \xB7 ");
|
|
1224
1250
|
return el(
|
|
1225
1251
|
"div",
|
|
1226
1252
|
{
|
|
@@ -1285,11 +1311,12 @@ pre code { background: transparent; padding: 0; }
|
|
|
1285
1311
|
}
|
|
1286
1312
|
}
|
|
1287
1313
|
function openSessionModal() {
|
|
1314
|
+
const hasDefault = state.defaultAgent && state.agents.some((a) => a.id === state.defaultAgent);
|
|
1288
1315
|
setState({
|
|
1289
1316
|
modal: {
|
|
1290
1317
|
kind: "session",
|
|
1291
|
-
cwd: "",
|
|
1292
|
-
agentId: state.agents[0]?.id ?? "",
|
|
1318
|
+
cwd: state.defaultCwd ?? "",
|
|
1319
|
+
agentId: hasDefault ? state.defaultAgent : state.agents[0]?.id ?? "",
|
|
1293
1320
|
name: "",
|
|
1294
1321
|
prompt: "",
|
|
1295
1322
|
err: null,
|
|
@@ -1316,6 +1343,7 @@ pre code { background: transparent; padding: 0; }
|
|
|
1316
1343
|
el("label", { for: "f-cwd" }, "cwd"),
|
|
1317
1344
|
el("input", {
|
|
1318
1345
|
id: "f-cwd",
|
|
1346
|
+
"data-focus-key": "session-modal-cwd",
|
|
1319
1347
|
value: m.cwd,
|
|
1320
1348
|
placeholder: "/home/you/dev/project",
|
|
1321
1349
|
oninput: (e) => {
|
|
@@ -1335,6 +1363,7 @@ pre code { background: transparent; padding: 0; }
|
|
|
1335
1363
|
el("label", { for: "f-name" }, "name (optional)"),
|
|
1336
1364
|
el("input", {
|
|
1337
1365
|
id: "f-name",
|
|
1366
|
+
"data-focus-key": "session-modal-name",
|
|
1338
1367
|
value: m.name,
|
|
1339
1368
|
placeholder: "feature-x",
|
|
1340
1369
|
oninput: (e) => {
|
|
@@ -1350,6 +1379,7 @@ pre code { background: transparent; padding: 0; }
|
|
|
1350
1379
|
"textarea",
|
|
1351
1380
|
{
|
|
1352
1381
|
id: "f-prompt",
|
|
1382
|
+
"data-focus-key": "session-modal-prompt",
|
|
1353
1383
|
rows: "4",
|
|
1354
1384
|
placeholder: "What should the agent do first?",
|
|
1355
1385
|
oninput: (e) => {
|
|
@@ -1376,6 +1406,7 @@ pre code { background: transparent; padding: 0; }
|
|
|
1376
1406
|
function renderAgentSelect(m) {
|
|
1377
1407
|
const sel = el("select", {
|
|
1378
1408
|
id: "f-agent",
|
|
1409
|
+
"data-focus-key": "session-modal-agent",
|
|
1379
1410
|
onchange: (e) => {
|
|
1380
1411
|
m.agentId = e.target.value;
|
|
1381
1412
|
}
|
|
@@ -2028,6 +2059,8 @@ ${recent}`;
|
|
|
2028
2059
|
view: "list",
|
|
2029
2060
|
sessions: [],
|
|
2030
2061
|
agents: [],
|
|
2062
|
+
defaultAgent: null,
|
|
2063
|
+
defaultCwd: null,
|
|
2031
2064
|
groupBy: "project",
|
|
2032
2065
|
// Hide cold (disk-only) sessions by default. The "show cold"
|
|
2033
2066
|
// toggle in the topbar reveals them; clicking one attaches over
|
|
@@ -2099,6 +2132,9 @@ ${recent}`;
|
|
|
2099
2132
|
if (!hadBanner && hasActiveSelection()) {
|
|
2100
2133
|
return;
|
|
2101
2134
|
}
|
|
2135
|
+
if (!hadBanner && state.modal) {
|
|
2136
|
+
return;
|
|
2137
|
+
}
|
|
2102
2138
|
if (state.view === "list" || hadBanner) {
|
|
2103
2139
|
render();
|
|
2104
2140
|
} else if (state.view === "chat" && state.current) {
|
|
@@ -2134,11 +2170,24 @@ ${recent}`;
|
|
|
2134
2170
|
});
|
|
2135
2171
|
}
|
|
2136
2172
|
}
|
|
2173
|
+
async function loadConfig() {
|
|
2174
|
+
try {
|
|
2175
|
+
const data = await api(
|
|
2176
|
+
"/api/config"
|
|
2177
|
+
);
|
|
2178
|
+
setState({
|
|
2179
|
+
defaultAgent: data.defaultAgent ?? null,
|
|
2180
|
+
defaultCwd: data.defaultCwd ?? null
|
|
2181
|
+
});
|
|
2182
|
+
} catch {
|
|
2183
|
+
}
|
|
2184
|
+
}
|
|
2137
2185
|
|
|
2138
2186
|
// src/ui/main.ts
|
|
2139
2187
|
window.addEventListener("DOMContentLoaded", () => {
|
|
2140
2188
|
startPolling();
|
|
2141
2189
|
void loadAgents();
|
|
2190
|
+
void loadConfig();
|
|
2142
2191
|
applyHashRoute();
|
|
2143
2192
|
render();
|
|
2144
2193
|
});
|