@hydra-acp/browser 0.1.1 → 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 +58 -8
- 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; }
|
|
@@ -1073,6 +1073,26 @@ pre code { background: transparent; padding: 0; }
|
|
|
1073
1073
|
function shortSessionId(sessionId) {
|
|
1074
1074
|
return sessionId.replace(/^hydra_session_/, "");
|
|
1075
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`;
|
|
1095
|
+
}
|
|
1076
1096
|
function fmtTokens(n) {
|
|
1077
1097
|
if (!Number.isFinite(n)) return "?";
|
|
1078
1098
|
if (n < 1e3) return String(n);
|
|
@@ -1185,7 +1205,7 @@ pre code { background: transparent; padding: 0; }
|
|
|
1185
1205
|
groupNode.appendChild(el("h2", null, g.label));
|
|
1186
1206
|
}
|
|
1187
1207
|
for (const s of g.sessions) {
|
|
1188
|
-
groupNode.appendChild(renderSessionCard(s));
|
|
1208
|
+
groupNode.appendChild(renderSessionCard(s, g.label === null));
|
|
1189
1209
|
}
|
|
1190
1210
|
list.appendChild(groupNode);
|
|
1191
1211
|
}
|
|
@@ -1211,15 +1231,22 @@ pre code { background: transparent; padding: 0; }
|
|
|
1211
1231
|
}
|
|
1212
1232
|
const out = [];
|
|
1213
1233
|
for (const [cwd, items] of [...map.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {
|
|
1214
|
-
const last = cwd.split("/").filter(Boolean).pop() || cwd;
|
|
1215
1234
|
items.sort(compareSessions);
|
|
1216
|
-
out.push({ label:
|
|
1235
|
+
out.push({ label: cwd, sessions: items });
|
|
1217
1236
|
}
|
|
1218
1237
|
return out;
|
|
1219
1238
|
}
|
|
1220
|
-
function renderSessionCard(s) {
|
|
1239
|
+
function renderSessionCard(s, showCwd) {
|
|
1221
1240
|
const title = s.title || fallbackTitle(s.sessionId);
|
|
1222
|
-
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 ");
|
|
1223
1250
|
return el(
|
|
1224
1251
|
"div",
|
|
1225
1252
|
{
|
|
@@ -1284,11 +1311,12 @@ pre code { background: transparent; padding: 0; }
|
|
|
1284
1311
|
}
|
|
1285
1312
|
}
|
|
1286
1313
|
function openSessionModal() {
|
|
1314
|
+
const hasDefault = state.defaultAgent && state.agents.some((a) => a.id === state.defaultAgent);
|
|
1287
1315
|
setState({
|
|
1288
1316
|
modal: {
|
|
1289
1317
|
kind: "session",
|
|
1290
|
-
cwd: "",
|
|
1291
|
-
agentId: state.agents[0]?.id ?? "",
|
|
1318
|
+
cwd: state.defaultCwd ?? "",
|
|
1319
|
+
agentId: hasDefault ? state.defaultAgent : state.agents[0]?.id ?? "",
|
|
1292
1320
|
name: "",
|
|
1293
1321
|
prompt: "",
|
|
1294
1322
|
err: null,
|
|
@@ -1315,6 +1343,7 @@ pre code { background: transparent; padding: 0; }
|
|
|
1315
1343
|
el("label", { for: "f-cwd" }, "cwd"),
|
|
1316
1344
|
el("input", {
|
|
1317
1345
|
id: "f-cwd",
|
|
1346
|
+
"data-focus-key": "session-modal-cwd",
|
|
1318
1347
|
value: m.cwd,
|
|
1319
1348
|
placeholder: "/home/you/dev/project",
|
|
1320
1349
|
oninput: (e) => {
|
|
@@ -1334,6 +1363,7 @@ pre code { background: transparent; padding: 0; }
|
|
|
1334
1363
|
el("label", { for: "f-name" }, "name (optional)"),
|
|
1335
1364
|
el("input", {
|
|
1336
1365
|
id: "f-name",
|
|
1366
|
+
"data-focus-key": "session-modal-name",
|
|
1337
1367
|
value: m.name,
|
|
1338
1368
|
placeholder: "feature-x",
|
|
1339
1369
|
oninput: (e) => {
|
|
@@ -1349,6 +1379,7 @@ pre code { background: transparent; padding: 0; }
|
|
|
1349
1379
|
"textarea",
|
|
1350
1380
|
{
|
|
1351
1381
|
id: "f-prompt",
|
|
1382
|
+
"data-focus-key": "session-modal-prompt",
|
|
1352
1383
|
rows: "4",
|
|
1353
1384
|
placeholder: "What should the agent do first?",
|
|
1354
1385
|
oninput: (e) => {
|
|
@@ -1375,6 +1406,7 @@ pre code { background: transparent; padding: 0; }
|
|
|
1375
1406
|
function renderAgentSelect(m) {
|
|
1376
1407
|
const sel = el("select", {
|
|
1377
1408
|
id: "f-agent",
|
|
1409
|
+
"data-focus-key": "session-modal-agent",
|
|
1378
1410
|
onchange: (e) => {
|
|
1379
1411
|
m.agentId = e.target.value;
|
|
1380
1412
|
}
|
|
@@ -2027,6 +2059,8 @@ ${recent}`;
|
|
|
2027
2059
|
view: "list",
|
|
2028
2060
|
sessions: [],
|
|
2029
2061
|
agents: [],
|
|
2062
|
+
defaultAgent: null,
|
|
2063
|
+
defaultCwd: null,
|
|
2030
2064
|
groupBy: "project",
|
|
2031
2065
|
// Hide cold (disk-only) sessions by default. The "show cold"
|
|
2032
2066
|
// toggle in the topbar reveals them; clicking one attaches over
|
|
@@ -2098,6 +2132,9 @@ ${recent}`;
|
|
|
2098
2132
|
if (!hadBanner && hasActiveSelection()) {
|
|
2099
2133
|
return;
|
|
2100
2134
|
}
|
|
2135
|
+
if (!hadBanner && state.modal) {
|
|
2136
|
+
return;
|
|
2137
|
+
}
|
|
2101
2138
|
if (state.view === "list" || hadBanner) {
|
|
2102
2139
|
render();
|
|
2103
2140
|
} else if (state.view === "chat" && state.current) {
|
|
@@ -2133,11 +2170,24 @@ ${recent}`;
|
|
|
2133
2170
|
});
|
|
2134
2171
|
}
|
|
2135
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
|
+
}
|
|
2136
2185
|
|
|
2137
2186
|
// src/ui/main.ts
|
|
2138
2187
|
window.addEventListener("DOMContentLoaded", () => {
|
|
2139
2188
|
startPolling();
|
|
2140
2189
|
void loadAgents();
|
|
2190
|
+
void loadConfig();
|
|
2141
2191
|
applyHashRoute();
|
|
2142
2192
|
render();
|
|
2143
2193
|
});
|