-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpack.html
More file actions
64 lines (64 loc) · 4.28 KB
/
Copy pathpack.html
File metadata and controls
64 lines (64 loc) · 4.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Hacky file</title>
<meta name="description" content="Inspect and download a Hacky v0.1 file.">
<style>
:root { --bg:#0b0d12; --panel:#11151e; --line:#283244; --text:#f3f5f8; --muted:#9aa6b8; --accent:#8b7bff; --mint:#67e8c2; --mono:ui-monospace,SFMono-Regular,Menlo,monospace; --sans:-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; }
* { box-sizing:border-box; } body { min-height:100vh; margin:0; display:grid; place-items:center; padding:24px; color:var(--text); background:var(--bg); font:15px/1.6 var(--sans); }
.card { width:min(760px,100%); padding:30px; border:1px solid var(--line); border-radius:16px; background:var(--panel); }
.top { display:flex; justify-content:space-between; align-items:center; gap:15px; margin-bottom:32px; } a { color:#b5aaff; text-decoration:none; }
.brand { color:var(--text); font:700 1rem var(--mono); } .mark { color:var(--mint); margin-right:7px; } .back { color:var(--muted); font-size:.85rem; }
h1 { margin:0; font-size:clamp(2rem,6vw,3.5rem); letter-spacing:-.06em; line-height:1; } .meta { margin:12px 0 26px; color:var(--mint); font:.8rem var(--mono); }
.instructions { max-height:390px; overflow:auto; padding:18px; border:1px solid var(--line); border-radius:10px; color:#dce5f4; background:#0b1018; white-space:pre-wrap; word-break:break-word; font:.78rem/1.7 var(--mono); }
.actions { display:flex; flex-wrap:wrap; gap:10px; margin-top:20px; } button, .button { display:inline-flex; padding:10px 14px; border:1px solid var(--line); border-radius:8px; color:var(--text); background:#171d29; font:700 .85rem var(--sans); cursor:pointer; text-decoration:none; }
.primary { border-color:var(--accent); background:var(--accent); } .note { color:var(--muted); font-size:.86rem; }
.error { color:#fb7185; } @media(max-width:500px) { .card { padding:22px; } .top { margin-bottom:24px; } }
</style>
</head>
<body>
<main class="card">
<div class="top"><a class="brand" href="index.html"><span class="mark">✦</span>Hacky</a><a class="back" href="generator.html">Create another →</a></div>
<div id="content"><p class="note">Loading Hacky file…</p></div>
</main>
<script src="hacky-pdf.js"></script>
<script>
function decodeBase64(value) {
var binary = atob(value.replace(/-/g, '+').replace(/_/g, '/'))
var bytes = new Uint8Array(binary.length)
for (var index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index)
return new TextDecoder('utf-8', { fatal:true }).decode(bytes)
}
function escapeHtml(value) {
return value.replace(/[&<>"']/g, function (character) { return ({ '&':'&', '<':'<', '>':'>', '"':'"', "'":''' })[character] })
}
function save() {
var blob = hackyPdfBlob(window.hackyPackValue)
var link = document.createElement('a')
link.href = URL.createObjectURL(blob)
link.download = hackyPdfFilename(window.hackyPackValue.name)
link.click()
URL.revokeObjectURL(link.href)
}
function copy() { navigator.clipboard.writeText(hackyStringify(window.hackyPackValue)) }
function render() {
var encoded = new URLSearchParams(location.search).get('data') || new URLSearchParams(location.search).get('pack')
if (!encoded) throw new Error('No Hacky data was supplied')
var pack = hackyLoad(decodeBase64(encoded))
window.hackyPackValue = pack
document.title = pack.name + ' - Hacky'
document.getElementById('content').innerHTML =
'<h1>' + escapeHtml(pack.name) + '</h1>' +
'<div class="meta">Hacky v0.1 · ' + pack.turns + ' replies</div>' +
'<div class="instructions">' + escapeHtml(pack.instructions) + '</div>' +
'<p class="note">This file is valid canonical Hacky JSON. The effect is finite and the host AI remains in control.</p>' +
'<div class="actions"><button class="primary" id="save">Download .hacky.pdf</button><button id="copy">Copy canonical JSON</button><a class="button" href="index.html">Back to Hacky</a></div>'
document.getElementById('save').addEventListener('click', save)
document.getElementById('copy').addEventListener('click', copy)
}
try { render() } catch (error) { document.getElementById('content').innerHTML = '<p class="error">' + escapeHtml(error.message) + '</p><p class="note">Use the generator to create a fresh file.</p>' }
</script>
</body>
</html>