@monster-orange/den 0.4.17 → 0.4.18
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/CHANGELOG.md +43 -0
- package/README.md +7 -7
- package/docs/distributions.md +39 -1
- package/package.json +1 -1
- package/src/ui/cli/agent-ops.ts +43 -0
- package/src/ui/server/agent-routes.ts +9 -0
- package/src/ui/server/public/agents-page.js +23 -0
- package/src/ui/server/public/agents.html +13 -0
- package/src/ui/server/public/graph.css +22 -0
- package/src/ui/server/public/graph.js +25 -1
- package/src/ui/server/public/header.js +7 -0
- package/src/ui/server/public/i18n/es.js +35 -0
- package/src/ui/server/public/i18n/ja.js +35 -0
- package/src/ui/server/public/local-dev.html +11 -2
- package/src/ui/server/public/log-source.js +26 -0
- package/src/ui/server/public/logs.html +7 -20
- package/src/ui/server/public/services.html +18 -3
- package/src/ui/server/public/shell.js +208 -25
- package/src/ui/server/public/svc-panel.js +672 -0
- package/src/ui/server/ui-assets.ts +4 -0
|
@@ -211,6 +211,20 @@
|
|
|
211
211
|
font-weight: 600;
|
|
212
212
|
color: var(--text);
|
|
213
213
|
}
|
|
214
|
+
/* 0.4.18: the name opens the service panel (svc-panel.js). */
|
|
215
|
+
.svc-name-btn {
|
|
216
|
+
background: none;
|
|
217
|
+
border: 0;
|
|
218
|
+
padding: 0;
|
|
219
|
+
font: inherit;
|
|
220
|
+
color: inherit;
|
|
221
|
+
cursor: pointer;
|
|
222
|
+
text-align: left;
|
|
223
|
+
}
|
|
224
|
+
.svc-name-btn:hover,
|
|
225
|
+
.svc-name-btn[aria-expanded="true"] {
|
|
226
|
+
text-decoration: underline;
|
|
227
|
+
}
|
|
214
228
|
.service-repo .owners {
|
|
215
229
|
color: var(--accent-text);
|
|
216
230
|
}
|
|
@@ -335,6 +349,7 @@
|
|
|
335
349
|
envReady,
|
|
336
350
|
sudoRun,
|
|
337
351
|
} from "/header.js";
|
|
352
|
+
import { logStreamUrl } from "/log-source.js";
|
|
338
353
|
import { ownersLabel } from "/workspace-picker.js";
|
|
339
354
|
|
|
340
355
|
let es = null;
|
|
@@ -656,7 +671,7 @@
|
|
|
656
671
|
<div class="service-card-header">
|
|
657
672
|
<span class="dot" id="dot-${s.repo}-${s.service}"></span>
|
|
658
673
|
<div class="service-card-title">
|
|
659
|
-
<div class="service-name">${addr}</div>
|
|
674
|
+
<div class="service-name"><button type="button" class="svc-name-btn" data-svpanel-open="${esc(isSub ? addr : s.repo)}" aria-haspopup="dialog" aria-expanded="false" title="${esc(window.denShell?.t?.("svp.more", { s: isSub ? addr : s.repo }) ?? addr)}">${esc(addr)}</button></div>
|
|
660
675
|
<div class="service-repo">${s.repo}${
|
|
661
676
|
ownersLabel(s.inWorkspaces)
|
|
662
677
|
? `<span class="owners" title="Shared: listed once for every workspace in view that defines it">${esc(ownersLabel(s.inWorkspaces))}</span>`
|
|
@@ -821,8 +836,8 @@
|
|
|
821
836
|
);
|
|
822
837
|
appendLine(`\n▶ ${repo}/${service} logs · ${env}\n`, "cmd");
|
|
823
838
|
|
|
824
|
-
|
|
825
|
-
es = new EventSource(
|
|
839
|
+
// The Logs page's source (log-source.js): taillog for local.
|
|
840
|
+
es = new EventSource(logStreamUrl(repo, service, env));
|
|
826
841
|
handleSSE(es, repo, service, { stream: true });
|
|
827
842
|
}
|
|
828
843
|
|
|
@@ -169,6 +169,41 @@
|
|
|
169
169
|
"act.unpinX": "Unpin {s}",
|
|
170
170
|
"toast.pinned": "Pinned {s}",
|
|
171
171
|
"toast.unpinned": "Unpinned {s}",
|
|
172
|
+
// 0.4.18: the service panel (svc-panel.js) and Start's Folder.
|
|
173
|
+
"svp.label": "{s}: quick panel",
|
|
174
|
+
"svp.more": "Quick panel for {s}",
|
|
175
|
+
"svp.notRunning": "Not running",
|
|
176
|
+
"svp.up": "up {d}",
|
|
177
|
+
"svp.upNow": "up",
|
|
178
|
+
"svp.down": "down: {c}",
|
|
179
|
+
"svp.downNone": "down",
|
|
180
|
+
"svp.starting": "starting…",
|
|
181
|
+
"svp.stopped": "stopped",
|
|
182
|
+
"svp.noUrl": "No URL",
|
|
183
|
+
"svp.start": "Start",
|
|
184
|
+
"svp.stop": "Stop",
|
|
185
|
+
"svp.restart": "Restart",
|
|
186
|
+
"svp.logs": "Logs",
|
|
187
|
+
"svp.stopping": "Stopping {s}",
|
|
188
|
+
"svp.tests": "Last test run",
|
|
189
|
+
"svp.testsOk": "✓ {t}",
|
|
190
|
+
"svp.testsBad": "✗ failed {t}",
|
|
191
|
+
"svp.testsRun": "running…",
|
|
192
|
+
"svp.testsNone": "—",
|
|
193
|
+
"svp.runTests": "Run tests",
|
|
194
|
+
"svp.testsDone": "Tests passed: {s}",
|
|
195
|
+
"svp.testsFailed": "Tests failed: {s}",
|
|
196
|
+
"svp.agents": "Agents",
|
|
197
|
+
"svp.noAgents": "No agents in this repo.",
|
|
198
|
+
"svp.open": "Open",
|
|
199
|
+
"svp.openAg": "Open {s}",
|
|
200
|
+
"svp.startHere": "Start agent here",
|
|
201
|
+
"svp.openSvc": "Open in Services",
|
|
202
|
+
"svp.openGraph": "Open in Graph",
|
|
203
|
+
"svp.close": "Close",
|
|
204
|
+
"ag.new.folder": "Folder (optional)",
|
|
205
|
+
"ag.new.folderHelp":
|
|
206
|
+
"Inside the workspace's folder. Empty: the workspace's own.",
|
|
172
207
|
collapse: "Collapse",
|
|
173
208
|
expand: "Expand",
|
|
174
209
|
menu: "Menu",
|
|
@@ -1214,6 +1249,12 @@
|
|
|
1214
1249
|
// SEC-2a: who this browser is (GET /api/session `identity`): local,
|
|
1215
1250
|
// a signed-in device, or a GitHub login. Null until known.
|
|
1216
1251
|
identity: null,
|
|
1252
|
+
// 0.4.18: each pin's URL (svc-panel.js, from the health feed) for its
|
|
1253
|
+
// Visit ↗, whether that Visit is off (down or starting: the panel's own
|
|
1254
|
+
// live state), and the pin whose service panel is open.
|
|
1255
|
+
pinUrls: {},
|
|
1256
|
+
pinOff: {},
|
|
1257
|
+
svpOpen: null,
|
|
1217
1258
|
};
|
|
1218
1259
|
try {
|
|
1219
1260
|
var cached = JSON.parse(localStorage.getItem(LS) || "{}");
|
|
@@ -1441,6 +1482,31 @@
|
|
|
1441
1482
|
var r = anchor.getBoundingClientRect();
|
|
1442
1483
|
var gap = opts.gap != null ? opts.gap : 4;
|
|
1443
1484
|
el.style.maxHeight = "";
|
|
1485
|
+
// 0.4.18: a bottom sheet is placed by its CSS (bottom: 0), not here.
|
|
1486
|
+
if (opts.sheet) {
|
|
1487
|
+
el.style.removeProperty("top");
|
|
1488
|
+
el.style.removeProperty("left");
|
|
1489
|
+
return;
|
|
1490
|
+
}
|
|
1491
|
+
// 0.4.18: beside the anchor (the rail), level with a row in it.
|
|
1492
|
+
if (opts.side === "right") {
|
|
1493
|
+
var row = typeof opts.row === "function" ? opts.row() : null;
|
|
1494
|
+
var rr = row ? row.getBoundingClientRect() : r;
|
|
1495
|
+
var bw = el.offsetWidth;
|
|
1496
|
+
var bh = el.offsetHeight;
|
|
1497
|
+
var bl = Math.min(r.right + gap, window.innerWidth - bw - TOP_MARGIN);
|
|
1498
|
+
var bt = Math.min(
|
|
1499
|
+
rr.top + (opts.dy || 0),
|
|
1500
|
+
window.innerHeight - bh - TOP_MARGIN,
|
|
1501
|
+
);
|
|
1502
|
+
el.style.setProperty("top", Math.max(TOP_MARGIN, bt) + "px", "important");
|
|
1503
|
+
el.style.setProperty(
|
|
1504
|
+
"left",
|
|
1505
|
+
Math.max(TOP_MARGIN, bl) + "px",
|
|
1506
|
+
"important",
|
|
1507
|
+
);
|
|
1508
|
+
return;
|
|
1509
|
+
}
|
|
1444
1510
|
var w = el.offsetWidth;
|
|
1445
1511
|
var h = el.offsetHeight;
|
|
1446
1512
|
var vw = window.innerWidth;
|
|
@@ -2123,6 +2189,47 @@
|
|
|
2123
2189
|
: " off";
|
|
2124
2190
|
return '<span class="den-dot' + cls + '" aria-hidden="true"></span>';
|
|
2125
2191
|
}
|
|
2192
|
+
/**
|
|
2193
|
+
* 0.4.18: a pin's Visit ↗: none without a URL, greyed out while it is
|
|
2194
|
+
* down. Down is the service panel's live state (pinOff), the same as its
|
|
2195
|
+
* dot, so it holds for a pin outside the View too; the rail's rollup
|
|
2196
|
+
* only without it.
|
|
2197
|
+
*/
|
|
2198
|
+
function pinVisit(id) {
|
|
2199
|
+
var url = state.pinUrls && state.pinUrls[id];
|
|
2200
|
+
if (!url) return "";
|
|
2201
|
+
var off = state.pinOff || {};
|
|
2202
|
+
var down = Object.prototype.hasOwnProperty.call(off, id)
|
|
2203
|
+
? !!off[id]
|
|
2204
|
+
: state.health[id] === "down";
|
|
2205
|
+
return (
|
|
2206
|
+
'<button type="button" class="den-pvisit" tabindex="-1" data-visit="' +
|
|
2207
|
+
esc(id) +
|
|
2208
|
+
'" data-url="' +
|
|
2209
|
+
esc(url) +
|
|
2210
|
+
'" aria-label="' +
|
|
2211
|
+
esc(t("act.visitX", { s: id })) +
|
|
2212
|
+
'" title="' +
|
|
2213
|
+
esc(down ? t("svp.notRunning") : url) +
|
|
2214
|
+
'"' +
|
|
2215
|
+
(down ? ' aria-disabled="true"' : "") +
|
|
2216
|
+
'><span aria-hidden="true">↗</span></button>'
|
|
2217
|
+
);
|
|
2218
|
+
}
|
|
2219
|
+
function visitPin(b) {
|
|
2220
|
+
if (b.getAttribute("aria-disabled") === "true") {
|
|
2221
|
+
toast(t("svp.notRunning"));
|
|
2222
|
+
return;
|
|
2223
|
+
}
|
|
2224
|
+
var url = b.getAttribute("data-url");
|
|
2225
|
+
if (url && /^https?:\/\//i.test(url))
|
|
2226
|
+
window.open(url, "_blank", "noopener");
|
|
2227
|
+
}
|
|
2228
|
+
// 0.4.18: the service panel (svc-panel.js registers it).
|
|
2229
|
+
var servicePanel = null;
|
|
2230
|
+
function setServicePanel(p) {
|
|
2231
|
+
servicePanel = p && typeof p.open === "function" ? p : null;
|
|
2232
|
+
}
|
|
2126
2233
|
function pinHref(id) {
|
|
2127
2234
|
var repo = id.split("/")[0];
|
|
2128
2235
|
return "/services#repo-" + encodeURIComponent(repo);
|
|
@@ -2191,9 +2298,12 @@
|
|
|
2191
2298
|
null,
|
|
2192
2299
|
state.pins
|
|
2193
2300
|
.map(function (p) {
|
|
2194
|
-
//
|
|
2195
|
-
//
|
|
2196
|
-
//
|
|
2301
|
+
// 0.4.18: the row (named by the id alone) opens the service's
|
|
2302
|
+
// panel in place (svc-panel.js); it is still the link to
|
|
2303
|
+
// Services, so ⌘-click and middle-click open that in a new
|
|
2304
|
+
// tab. Delete unpins it. Visit ↗ beside it opens the service's
|
|
2305
|
+
// URL, out of the tab order: the panel's first button is the
|
|
2306
|
+
// keyboard's Visit. Unpin is in the panel's footer.
|
|
2197
2307
|
return (
|
|
2198
2308
|
'<div class="den-pin-row">' +
|
|
2199
2309
|
item(
|
|
@@ -2205,17 +2315,17 @@
|
|
|
2205
2315
|
mono: true,
|
|
2206
2316
|
},
|
|
2207
2317
|
false,
|
|
2208
|
-
|
|
2209
|
-
'
|
|
2210
|
-
|
|
2318
|
+
"",
|
|
2319
|
+
' data-pin="' +
|
|
2320
|
+
esc(p) +
|
|
2321
|
+
'" data-svpanel="' +
|
|
2322
|
+
esc(p) +
|
|
2323
|
+
'" aria-haspopup="dialog" aria-expanded="' +
|
|
2324
|
+
(state.svpOpen === p ? "true" : "false") +
|
|
2325
|
+
'" aria-keyshortcuts="Delete"',
|
|
2211
2326
|
) +
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
'" aria-label="' +
|
|
2215
|
-
esc(t("act.unpinX", { s: p })) +
|
|
2216
|
-
'" title="' +
|
|
2217
|
-
esc(t("act.unpin")) +
|
|
2218
|
-
'"><span aria-hidden="true">×</span></button></div>'
|
|
2327
|
+
pinVisit(p) +
|
|
2328
|
+
"</div>"
|
|
2219
2329
|
);
|
|
2220
2330
|
})
|
|
2221
2331
|
.join(""),
|
|
@@ -2423,10 +2533,28 @@
|
|
|
2423
2533
|
});
|
|
2424
2534
|
nav.addEventListener("click", function (e) {
|
|
2425
2535
|
var tgt = e.target;
|
|
2426
|
-
var
|
|
2427
|
-
if (
|
|
2536
|
+
var v = tgt && tgt.closest ? tgt.closest("[data-visit]") : null;
|
|
2537
|
+
if (v) {
|
|
2428
2538
|
e.preventDefault();
|
|
2429
|
-
|
|
2539
|
+
visitPin(v);
|
|
2540
|
+
return;
|
|
2541
|
+
}
|
|
2542
|
+
// 0.4.18: a plain click (or Enter) on a pinned row opens its panel;
|
|
2543
|
+
// ⌘/Ctrl-, Shift- and middle-click keep the link (Services).
|
|
2544
|
+
var sp = tgt && tgt.closest ? tgt.closest("[data-svpanel]") : null;
|
|
2545
|
+
if (
|
|
2546
|
+
sp &&
|
|
2547
|
+
servicePanel &&
|
|
2548
|
+
e.button === 0 &&
|
|
2549
|
+
!e.metaKey &&
|
|
2550
|
+
!e.ctrlKey &&
|
|
2551
|
+
!e.shiftKey &&
|
|
2552
|
+
!e.altKey
|
|
2553
|
+
) {
|
|
2554
|
+
e.preventDefault();
|
|
2555
|
+
servicePanel.open(sp.getAttribute("data-svpanel"), sp, {
|
|
2556
|
+
fromRail: true,
|
|
2557
|
+
});
|
|
2430
2558
|
return;
|
|
2431
2559
|
}
|
|
2432
2560
|
var c = tgt && tgt.closest ? tgt.closest('[data-act="collapse"]') : null;
|
|
@@ -4523,6 +4651,14 @@
|
|
|
4523
4651
|
* anchor; hide(el). The page hiding it (display: none) closes it too.
|
|
4524
4652
|
*/
|
|
4525
4653
|
topLayer: { show: topShow, hide: topHide },
|
|
4654
|
+
/**
|
|
4655
|
+
* 0.4.18: the service panel. svc-panel.js registers { open, close,
|
|
4656
|
+
* visit }; openServicePanel(id, opener) opens it beside opener.
|
|
4657
|
+
*/
|
|
4658
|
+
setServicePanel: setServicePanel,
|
|
4659
|
+
openServicePanel: function (id, opener) {
|
|
4660
|
+
if (servicePanel) servicePanel.open(id, opener);
|
|
4661
|
+
},
|
|
4526
4662
|
closeMenu: function () {
|
|
4527
4663
|
closeMenu(false);
|
|
4528
4664
|
},
|
|
@@ -4865,18 +5001,65 @@
|
|
|
4865
5001
|
" display: inline-block; margin: 0 5px; }",
|
|
4866
5002
|
".den-dot.bad { background: var(--bad); } .den-dot.warn { background: var(--warn); }",
|
|
4867
5003
|
".den-dot.off { background: var(--faint); }",
|
|
4868
|
-
|
|
4869
|
-
".den-pin-
|
|
4870
|
-
".den-pin-
|
|
4871
|
-
"
|
|
4872
|
-
"
|
|
4873
|
-
"
|
|
4874
|
-
"
|
|
5004
|
+
// 0.4.18: a pinned row is its name (opens the service panel) and Visit ↗.
|
|
5005
|
+
".den-pin-row { display: flex; align-items: center; gap: 2px; min-width: 0; }",
|
|
5006
|
+
".den-pin-row .den-ni { flex: 1; min-width: 0; }",
|
|
5007
|
+
".den-pin-row .den-ni[aria-expanded='true'] { background: var(--sunken); color: var(--text); }",
|
|
5008
|
+
".den-pvisit { flex: none; width: 26px; height: 26px; padding: 0; display: grid; place-items: center;",
|
|
5009
|
+
" background: none; border: 1px solid transparent; border-radius: var(--radius-button);",
|
|
5010
|
+
" color: var(--muted); cursor: pointer; font: 13px/1 var(--sans); }",
|
|
5011
|
+
".den-pvisit:hover { background: var(--sunken); color: var(--accent-text); border-color: var(--border); }",
|
|
5012
|
+
".den-pvisit[aria-disabled='true'], .den-svp .den-btn[aria-disabled='true'] { opacity: .45; cursor: not-allowed; }",
|
|
5013
|
+
".den-pvisit[aria-disabled='true']:hover { background: none; color: var(--muted); border-color: transparent; }",
|
|
5014
|
+
"body.den-rail-collapsed .den-rail .den-pvisit { display: none; }",
|
|
5015
|
+
"@media (max-width: 720px) { .den-pvisit { width: 32px; height: 32px; }",
|
|
5016
|
+
" body.den-rail-collapsed .den-rail .den-pvisit { display: grid; } }",
|
|
5017
|
+
// The service panel (svc-panel.js): beside its row, a bottom sheet at phone width.
|
|
5018
|
+
".den-pop.den-svp { width: 340px; max-width: calc(100vw - 16px); box-sizing: border-box; padding: 0;",
|
|
5019
|
+
" max-height: calc(100dvh - 16px); overflow-y: auto; min-width: 0; }",
|
|
5020
|
+
".den-svp-h { display: grid; gap: 4px; padding: 12px 12px 10px; border-bottom: 1px solid var(--border); }",
|
|
5021
|
+
".den-svp-t { display: flex; align-items: center; gap: 8px; min-width: 0; }",
|
|
5022
|
+
".den-svp-t .den-dot, .den-svp-ag .den-dot, .den-svp-line .den-dot { margin: 0; }",
|
|
5023
|
+
// Line heights pinned to the mock's (its mono font's normal), whatever the theme's font.
|
|
5024
|
+
".den-svp-t b { flex: 1; min-width: 0; font: 600 14px/21px var(--mono); overflow: hidden;",
|
|
5025
|
+
" text-overflow: ellipsis; white-space: nowrap; }",
|
|
5026
|
+
".den-svp-x { padding: 2px 6px; margin: -4px -6px -4px 0; }",
|
|
5027
|
+
".den-svp-meta { display: flex; align-items: center; gap: 4px 8px; flex-wrap: wrap; font-size: 12.5px; color: var(--muted); }",
|
|
5028
|
+
".den-wsp { font: 11px/16px var(--mono); border-radius: 999px; padding: 0 7px; white-space: nowrap;",
|
|
5029
|
+
" border: 1px solid var(--border); color: var(--muted); }",
|
|
5030
|
+
".den-svp-st { color: var(--ok); } .den-svp-st.bad { color: var(--bad); }",
|
|
5031
|
+
".den-svp-st.off { color: var(--faint); } .den-svp-st.run { color: var(--accent-text); }",
|
|
5032
|
+
".den-svp-ms { font: 11.5px var(--mono); color: var(--faint); }",
|
|
5033
|
+
".den-svp-url { font: 12px/17px var(--mono); color: var(--faint); overflow-wrap: anywhere; }",
|
|
5034
|
+
".den-svp-acts { display: flex; gap: 6px; flex-wrap: wrap; padding: 10px 12px; }",
|
|
5035
|
+
".den-svp-sec { display: grid; gap: 6px; padding: 8px 12px 10px; border-top: 1px solid var(--border); }",
|
|
5036
|
+
".den-svp-k { font: 11px/16px var(--mono); color: var(--faint); text-transform: uppercase; letter-spacing: .07em; }",
|
|
5037
|
+
".den-svp-line { display: flex; align-items: center; gap: 8px; font-size: 13px; }",
|
|
5038
|
+
".den-svp-line .den-svp-sp { margin-left: auto; }",
|
|
5039
|
+
".den-svp-ok { color: var(--ok); } .den-svp-bad { color: var(--bad); } .den-svp-none { color: var(--faint); }",
|
|
5040
|
+
".den-svp-ag { display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; gap: 0 8px;",
|
|
5041
|
+
" align-items: center; font-size: 13px; }",
|
|
5042
|
+
".den-svp-nm { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }",
|
|
5043
|
+
".den-svp-as { font: 11px var(--mono); color: var(--faint); white-space: nowrap; }",
|
|
5044
|
+
".den-wbdg { font: 10.5px var(--mono); color: var(--warn); border: 1px solid color-mix(in srgb, var(--warn) 45%, transparent);",
|
|
5045
|
+
" border-radius: 999px; padding: 0 6px; }",
|
|
5046
|
+
".den-svp-help { font-size: 12px; color: var(--faint); line-height: 1.4; }",
|
|
5047
|
+
".den-svp-foot { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; padding: 8px 12px 10px;",
|
|
5048
|
+
" border-top: 1px solid var(--border); }",
|
|
5049
|
+
".den-svp-grow { margin-left: auto; }",
|
|
5050
|
+
".den-lnk { color: var(--accent-text); cursor: pointer; font: inherit; font-size: 12.5px; text-decoration: underline;",
|
|
5051
|
+
" background: none; border: 0; padding: 0; }",
|
|
5052
|
+
".den-scrim.den-svp-scrim { z-index: 43; }",
|
|
5053
|
+
".den-pop.den-svp.den-sheet.den-toplayer { top: auto !important; left: 0 !important; right: 0 !important;",
|
|
5054
|
+
" bottom: 0 !important; width: auto; max-width: none; border-bottom: 0; border-radius: 14px 14px 0 0;",
|
|
5055
|
+
" max-height: 85dvh; padding-bottom: env(safe-area-inset-bottom, 0px); }",
|
|
5056
|
+
".den-pop.den-svp.den-sheet::before { content: ''; display: block; width: 36px; height: 4px; border-radius: 2px;",
|
|
5057
|
+
" background: var(--border-strong); margin: 8px auto 0; }",
|
|
5058
|
+
".den-pop.den-svp.den-sheet .den-svp-acts .den-btn { flex: 1 1 auto; padding: 9px 12px; }",
|
|
4875
5059
|
// Collapsed: icons only. The prototype hides headings and labels; they
|
|
4876
5060
|
// stay here for screen readers (visually hidden, no space taken).
|
|
4877
5061
|
"body.den-rail-collapsed .den-rail .den-lbl, body.den-rail-collapsed .den-rail .den-gh,",
|
|
4878
|
-
"body.den-rail-collapsed .den-rail .den-bdg
|
|
4879
|
-
"body.den-rail-collapsed .den-rail .den-pin-sp {",
|
|
5062
|
+
"body.den-rail-collapsed .den-rail .den-bdg {",
|
|
4880
5063
|
" position: absolute; width: 1px; height: 1px; padding: 0; overflow: hidden;",
|
|
4881
5064
|
" clip: rect(0 0 0 0); white-space: nowrap; border: 0; }",
|
|
4882
5065
|
// Toast (.toast)
|