Files
bal-electrum-plugin/docs/inheritance-options.html
donkey-ai dc166d04ff feat(bal): Group A (timestamps + statuses + anticipate docs) and Group B (auto-sign) v0.3.4
Bump plugin version to 0.3.4 (manifest, __init__, plugin_base, VERSION).

GROUP A
- A1: remove block-height locktimes; the plugin now uses UNIX timestamps
  only. The NLOCKTIME_BLOCKHEIGHT_MAX guard is kept on purpose (it forces
  every locktime to be a timestamp). chk_locktime is now 2-arg; int_locktime
  and anticipate_locktime no longer accept blocks; RAW input only accepts d/y.
  Two now-dormant configs (LOCKTIME_BLOCKS, LOCKTIMEDELTA_BLOCKS) are kept with
  comments to avoid touching persisted keys.
- A2: rename PENDING -> MEMPOOL everywhere (label 'Mempool', yellow #ffce30);
  add new UPDATED status; ANTICIPATED & UPDATED keep VALID; documented
  set_status rules; backward-compat migration (old PENDING -> MEMPOOL).
- A3: clarify that anticipating to a future date only rebuilds (never
  invalidates), while only a past locktime invalidates (WillExpired). Code was
  already correct; only the comment and docs were fixed.

Colour follow-up: UPDATED lightened from #800080 to #b266b2 (more readable),
updated in theme.py, docs and the theme test.

GROUP B
- B1: verified the 'Create your will' button already opens the guided wizard
  (no code change needed).
- B2: new persisted AUTO_SIGN setting (default ON) with an 'Auto-sign on Check'
  checkbox in the settings dialog. When enabled, Check signs and broadcasts
  automatically; the wallet password is requested only for encrypted wallets.

B2 follow-up (fixes reported after testing):
- Remove the duplicate sign/broadcast cycle in lists.check(); build_will_task()
  already signs and broadcasts.
- Suppress the manual 'press Sign/Broadcast' hint and its popup when AUTO_SIGN
  is ON (kept when OFF).
- Make broadcast one-shot: removed the retry flag and the Exception('retry');
  failed will-executors stay PUSH_FAIL and are skipped (no endless retry).
  PUSHED transactions are already excluded from re-collection.

Docs: inheritance-options.md/.html and inheritance-flow.svg updated to v0.3.4.
Tests: 206 passing (new test_anticipate_manual_locktime, test_anticipate_past_locktime,
test_group_b_auto_sign; updated core/util, core/will_extra, gui/theme, gui/widgets).
CHANGELOG.md added with one numbered entry per task.
2026-06-28 23:00:23 -04:00

295 lines
20 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>BAL — Inheritance Options Guide</title>
<style>
:root{
--bg:#0d1117; --panel:#161b22; --text:#e6edf3; --muted:#9da7b3;
--border:#30363d; --accent:#2bc8ed; --red:#e83845; --green:#2ea043;
--blue:#2bc8ed; --grey:#8b949e; --amber:#cfa808;
}
*{box-sizing:border-box}
body{
margin:0; background:var(--bg); color:var(--text);
font:16px/1.65 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
}
.wrap{max-width:980px;margin:0 auto;padding:32px 20px 80px}
h1{font-size:2rem;margin:.2em 0 .1em;border-bottom:2px solid var(--accent);padding-bottom:.3em}
h2{font-size:1.4rem;margin:2em 0 .4em;border-bottom:1px solid var(--border);padding-bottom:.25em}
h3{font-size:1.12rem;margin:1.6em 0 .3em;color:#cdd9e5}
p,li{color:var(--text)}
blockquote{
margin:1em 0;padding:.6em 1em;border-left:4px solid var(--accent);
background:var(--panel);border-radius:0 8px 8px 0;color:var(--muted)
}
blockquote strong{color:var(--text)}
code{background:#1f2630;padding:.12em .4em;border-radius:5px;font-size:.9em}
table{border-collapse:collapse;width:100%;margin:1em 0;font-size:.93rem;display:block;overflow-x:auto}
th,td{border:1px solid var(--border);padding:8px 10px;text-align:left;vertical-align:top}
th{background:var(--panel)}
tr:nth-child(even) td{background:#11161d}
.yes{color:var(--green);font-weight:700}
.no{color:var(--grey);font-weight:700}
.fee{color:var(--red);font-weight:700}
.pill{display:inline-block;padding:.05em .55em;border-radius:999px;font-size:.78em;font-weight:700;color:#0d1117}
.pill.red{background:var(--red);color:#fff}
.pill.blue{background:var(--blue)}
.pill.green{background:var(--green);color:#fff}
.pill.grey{background:var(--grey);color:#fff}
/* Status colours matching gui/qt/theme.py exactly. */
.pill.orange{background:#f87838;color:#0d1117}
.pill.pink{background:#ff97e9;color:#0d1117}
.pill.violet{background:#b266b2;color:#fff}
.pill.yellow{background:#ffce30;color:#0d1117}
.pill.teal{background:#73f3c8;color:#0d1117}
.mermaid{background:var(--panel);border:1px solid var(--border);border-radius:10px;padding:18px;margin:1.2em 0;overflow-x:auto}
.lead{color:var(--muted);font-size:1.05rem}
footer{margin-top:3em;color:var(--muted);font-size:.85rem;border-top:1px solid var(--border);padding-top:1em}
a{color:var(--accent)}
</style>
</head>
<body>
<div class="wrap">
<h1>BAL — Inheritance Options Guide</h1>
<p class="lead">How the <strong>Bitcoin After Life</strong> Electrum plugin reacts to every change you can make to
your will: changing the date (earlier / later), adding or removing an heir, changing percentages, fees or
will‑executors — and what happens to the transactions held by the will‑executor servers.</p>
<blockquote>This page reflects the <strong>actual behaviour of the code</strong>
(<code>core/will.py</code> → <code>is_will_valid</code> / <code>check_willexecutors_and_heirs</code> and
<code>gui/qt/window.py</code> → <code>build_inheritance_transaction</code>). It is meant for end users and
for anyone wanting to understand the on‑chain consequences of each action.</blockquote>
<h2>1. The mental model in one paragraph</h2>
<p>Your will is a <strong>tree of pre‑signed Bitcoin transactions</strong>. Each leaf transaction sends your
coins to your heirs and is <strong>time‑locked</strong> (<code>nLockTime</code>) so it can only be broadcast
<strong>after</strong> a future date/block. A copy of each signed transaction is handed to one or more
<strong>will‑executor servers</strong>. While you are alive you periodically prove you are alive (the
<em>Check‑Alive threshold</em>). When you change anything, BAL chooses between three outcomes:</p>
<ol>
<li><strong>Do nothing</strong> — the will is still coherent.</li>
<li><strong>Rebuild</strong> (re‑prepare + re‑sign, <em>no on‑chain cost</em>) — the will changed but
nothing dangerous is committed yet.</li>
<li><strong>Invalidate on‑chain first</strong> (costs a real Bitcoin fee) — a previously
<strong>signed/sent</strong> transaction must be neutralised by spending its inputs <em>before</em> a
new will can safely replace it.</li>
</ol>
<blockquote>The whole point of rule 3 is safety: <strong>a will‑executor must never be able to broadcast an old
transaction that would execute your inheritance too early.</strong></blockquote>
<h2>2. Transaction states (status flags)</h2>
<table>
<thead><tr><th>Status</th><th>Meaning</th><th>Set when</th></tr></thead>
<tbody>
<tr><td><code>VALID</code></td><td>The current, usable plan</td><td>default; cleared by INVALIDATED/REPLACED/CONFIRMED/MEMPOOL</td></tr>
<tr><td><code>COMPLETE</code> (<em>Signed</em>)</td><td>The transaction has been <strong>signed</strong></td><td>after <strong>Sign</strong></td></tr>
<tr><td><code>PUSHED</code></td><td>Signed tx <strong>sent to executor(s)</strong></td><td>after <strong>Broadcast</strong> to executors</td></tr>
<tr><td><code>CHECKED</code></td><td>Executor <strong>confirmed</strong> it holds the tx</td><td>after a successful server <strong>Check</strong> (implies PUSHED)</td></tr>
<tr><td><code>CHECK_FAIL</code></td><td>Server <strong>check failed</strong></td><td>a queried executor did not return the tx</td></tr>
<tr><td><code>PUSH_FAIL</code></td><td>Sending to the executor failed</td><td>cleared when PUSHED becomes true</td></tr>
<tr><td><code>CONFIRMED</code></td><td>Tx <strong>mined on‑chain</strong></td><td>seen on‑chain, height &gt; 0</td></tr>
<tr><td><code>MEMPOOL</code></td><td>Tx <strong>in the Electrum mempool</strong></td><td>seen on‑chain, height 0 (named <code>PENDING</code> before v0.3.4)</td></tr>
<tr><td><code>INVALIDATED</code></td><td>Inputs spent → can never confirm</td><td>invalidation tx / inputs gone</td></tr>
<tr><td><code>REPLACED</code></td><td>Superseded by an <strong>earlier</strong>‑locktime child</td><td>a replacing child found</td></tr>
<tr><td><code>ANTICIPATED</code></td><td>Locktime anticipated by 1 day vs a pre‑existing tx with the same heirs</td><td><code>set_anticipate</code> (tx <strong>stays</strong> VALID)</td></tr>
<tr><td><code>UPDATED</code></td><td>Replaced by a new tx keeping the <strong>same</strong> locktime + same heirs</td><td>same‑locktime replacement (tx <strong>stays</strong> VALID)</td></tr>
<tr><td><code>EXPIRED</code></td><td>Locktime already in the past vs the check date</td><td><code>check_will_expired</code></td></tr>
</tbody>
</table>
<h3>Safety rules baked into <code>set_status</code></h3>
<ul>
<li>Setting <code>INVALIDATED</code> / <code>REPLACED</code> / <code>CONFIRMED</code> / <code>MEMPOOL</code> → clears <code>VALID</code>.</li>
<li>Setting <code>ANTICIPATED</code> → <strong>keeps</strong> <code>VALID</code> (only moves the locktime 1 day earlier).</li>
<li>Setting <code>UPDATED</code> → <strong>keeps</strong> <code>VALID</code> (same locktime + same heirs).</li>
<li>Setting <code>CONFIRMED</code> / <code>MEMPOOL</code> → clears <code>INVALIDATED</code>.</li>
<li>Setting <code>PUSHED</code> → clears <code>PUSH_FAIL</code> <strong>and</strong> <code>CHECK_FAIL</code>.</li>
<li>Setting <code>CHECKED</code> → implies <code>PUSHED</code>.</li>
</ul>
<h3>How states map to row colour</h3>
<table>
<thead><tr><th>Priority</th><th>State</th><th>Colour</th><th>Hex</th></tr></thead>
<tbody>
<tr><td>1</td><td><code>INVALIDATED</code></td><td><span class="pill orange">orange</span></td><td><code>#f87838</code></td></tr>
<tr><td>2</td><td><code>REPLACED</code></td><td><span class="pill pink">pink</span></td><td><code>#ff97e9</code></td></tr>
<tr><td>3</td><td><code>UPDATED</code></td><td><span class="pill violet">light violet</span></td><td><code>#b266b2</code></td></tr>
<tr><td>4</td><td><code>CONFIRMED</code></td><td><span class="pill grey">grey</span></td><td><code>#bfbfbf</code></td></tr>
<tr><td>5</td><td><code>MEMPOOL</code></td><td><span class="pill yellow">yellow</span></td><td><code>#ffce30</code></td></tr>
<tr><td>6</td><td><code>CHECK_FAIL</code> (and not <code>CHECKED</code>)</td><td><span class="pill red">red</span></td><td><code>#e83845</code></td></tr>
<tr><td>7</td><td><code>CHECKED</code></td><td><span class="pill green">green</span></td><td><code>#8afa6c</code></td></tr>
<tr><td>8</td><td><code>PUSH_FAIL</code></td><td><span class="pill red">red</span></td><td><code>#e83845</code></td></tr>
<tr><td>9</td><td><code>PUSHED</code></td><td><span class="pill teal">teal</span></td><td><code>#73f3c8</code></td></tr>
<tr><td>10</td><td><code>COMPLETE</code> (signed, not pushed)</td><td><span class="pill blue">blue</span></td><td><code>#2bc8ed</code></td></tr>
<tr><td>—</td><td>none of the above (plain <code>VALID</code>)</td><td>default white</td><td><code>#ffffff</code></td></tr>
</tbody>
</table>
<blockquote><strong>v0.3.3 fix:</strong> a will that is <em>signed but not yet broadcast</em>
(<code>COMPLETE</code> and <strong>not</strong> <code>PUSHED</code>) is <strong>not</strong> queried on the
server, so it stays <strong>blue</strong> instead of turning red. Only <code>PUSHED</code> wills are checked.</blockquote>
<h2>3. The decision flow</h2>
<p>On <strong>Prepare</strong> (or the periodic <strong>Check</strong>, or on Electrum close) BAL runs
<code>is_will_valid</code>, raises a specific exception, and each maps to one action:</p>
<pre class="mermaid">
flowchart TD
A([You change something &amp; press Prepare / Check]) --> B{Heirs defined?}
B -- No --> Z1[/Show: Heirs are not defined — stop/]
B -- Yes --> C{Check-Alive threshold in the future?}
C -- "No, it's in the past" --> INV1[[Invalidate on-chain<br/>CheckAliveError]]
C -- Yes --> D{New delivery date already in the PAST?}
D -- "Yes date is now expired" --> INV2[[Invalidate on-chain FIRST<br/>WillExpired]]
D -- "No date still in the future" --> AN{Did you move the date EARLIER anticipate?}
AN -- "Yes anticipate — signed or not" --> R1[[Rebuild only<br/>no on-chain cost<br/>NEVER invalidates]]
AN -- No --> F{Will-executor / fee / heirs unchanged?}
F -- "Fee changed" --> R2[[Rebuild<br/>TxFeesChanged]]
F -- "Will-executor changed/absent" --> R3[[Rebuild<br/>WillExecutorNotPresent / Change]]
F -- "Heir added/removed, % or address changed" --> G{POSTPONE of an already signed/sent tx?}
G -- "Yes date later + signed/sent" --> INV3[[Invalidate on-chain FIRST then rebuild<br/>WillPostponed]]
G -- "No never signed, or pure heir/% change" --> R4[[Rebuild only<br/>HeirNotFound / HeirChange]]
F -- "Nothing changed" --> OK([Will still coherent — do nothing])
R1 --> SIGN
R2 --> SIGN
R3 --> SIGN
R4 --> SIGN
SIGN([Re-sign the new transactions]) --> PUSH([Broadcast to will-executors])
INV1 --> SB
INV2 --> SB
INV3 --> SB
SB([Sign &amp; broadcast the INVALIDATION tx on-chain]) --> WAIT{Invalidation confirmed?}
WAIT -- Yes --> REBUILD([Press Prepare again → build the new will])
REBUILD --> SIGN
</pre>
<h2>4. Every option, explained</h2>
<h3>4.1 Changing the Check‑Alive date / heir locktime</h3>
<p>BAL compares the <strong>requested</strong> locktime against the locktime <strong>frozen inside the
already‑signed transaction</strong> (<code>w.tx.locktime</code>) — exactly what the will‑executors hold.</p>
<table>
<thead><tr><th>You do…</th><th>Tx already signed/sent?</th><th>Result</th><th>On‑chain fee?</th></tr></thead>
<tbody>
<tr><td>Move date <strong>LATER</strong> (postpone)</td><td>No (never signed)</td><td>Plain <strong>rebuild</strong></td><td class="no">No</td></tr>
<tr><td>Move date <strong>LATER</strong> (postpone)</td><td>Yes</td><td><strong>Invalidate first</strong>, then rebuild (WillPostponed)</td><td class="fee">Yes</td></tr>
<tr><td>Move date <strong>EARLIER, still in the future</strong> (anticipate)</td><td><strong>any</strong> (signed or not)</td><td>Plain <strong>rebuild</strong> with the new earlier locktime — <strong>never</strong> invalidates</td><td class="no">No</td></tr>
<tr><td>Move date <strong>EARLIER into the past</strong> (new date already passed)</td><td>—</td><td>Will is genuinely <strong>expired</strong> → invalidate (WillExpired)</td><td class="fee">Yes</td></tr>
<tr><td>Check‑Alive threshold already passed</td><td>—</td><td><strong>Invalidate</strong> (CheckAliveError)</td><td class="fee">Yes</td></tr>
</tbody>
</table>
<blockquote><strong>Why postpone needs on‑chain invalidation:</strong> the executor still holds the <em>old</em>
transaction with the <em>earlier</em> locktime. Spending its inputs on‑chain makes it un‑minable, so it can
never execute the inheritance early. The plugin tells you this and offers to build the invalidation tx.</blockquote>
<blockquote><strong>Why anticipate (move earlier, still future) is NOT on‑chain:</strong> moving the delivery
date <em>earlier</em> only makes the inheritance available <em>sooner</em>; there is no early‑execution risk,
so the plugin simply <strong>rebuilds</strong> the transactions with the new earlier locktime — <strong>no
on‑chain invalidation and no Bitcoin fee</strong>. This holds <strong>even if the will was already
signed/sent</strong>: anticipating never invalidates. Only a date that lands in the <em>past</em> is treated
as expired and invalidated (<code>WillExpired</code>).</blockquote>
<h3>4.2 Adding an heir</h3>
<p>An heir present in your set but not yet in the will raises <code>HeirNotFoundException</code>.</p>
<ul><li><strong>Result:</strong> rebuild.</li>
<li><strong>On‑chain fee:</strong> <span class="no">No</span> — unless the changed will was already signed/sent
and the change also moves a locktime later (then 4.1 applies).</li></ul>
<h3>4.3 Removing an heir</h3>
<p>The will still carries an heir no longer in your set → <code>HeirNotFoundException</code> (removed‑heir branch).</p>
<ul><li><strong>Result:</strong> rebuild, so the removed heir disappears.</li>
<li><strong>On‑chain fee:</strong> <span class="no">No</span> for a prepared‑only will; if it was signed/sent,
invalidate on‑chain first, then rebuild.</li></ul>
<blockquote><strong>v0.3.2 fix:</strong> removing an heir is now detected on <strong>Check</strong> and on
Electrum <strong>close</strong>, not only on Prepare.</blockquote>
<h3>4.4 Changing an heir's percentage or address</h3>
<p>A changed <code>[address, amount]</code> is treated like an heir change (<code>HeirChange</code> / <code>HeirNotFound</code>).</p>
<ul><li><strong>Result:</strong> rebuild with new amounts.</li>
<li><strong>On‑chain fee:</strong> <span class="no">No</span> (unless signed/sent → invalidate first).</li></ul>
<blockquote>The wallet is always <strong>fully emptied</strong> by the inheritance; amounts must add up, or an
<code>AmountException</code> warns you to adjust.</blockquote>
<h3>4.5 Changing the transaction fee (sat/byte)</h3>
<p>A different rate raises <code>TxFeesChangedException</code>.</p>
<ul><li><strong>Result:</strong> rebuild at the new fee rate.</li>
<li><strong>On‑chain fee:</strong> <span class="no">No</span> to rebuild (you pay only when broadcasting on‑chain).</li></ul>
<h3>4.6 Changing or removing a will‑executor</h3>
<ul>
<li>Selected executor not referenced → <code>WillExecutorNotPresent</code>.</li>
<li>Executor details changed → <code>WillexecutorChangeException</code>.</li>
<li>“No executor” mode without a backup tx → <code>NoWillExecutorNotPresent</code>.</li>
</ul>
<ul><li><strong>Result:</strong> rebuild &amp; redistribute to the new executor set.</li>
<li><strong>On‑chain fee:</strong> <span class="no">No</span> to rebuild.</li></ul>
<h3>4.7 Nothing changed</h3>
<p>If heirs, percentages, fees, executors and locktimes all still match the signed transactions,
<code>is_will_valid</code> returns <code>True</code> and <strong>nothing happens</strong>.</p>
<h2>5. What happens on the will‑executor servers</h2>
<table>
<thead><tr><th>Your action</th><th>Effect on the servers</th></tr></thead>
<tbody>
<tr><td><strong>Prepare</strong> (rebuild)</td><td>Nothing yet — new txs are local until Sign + Broadcast.</td></tr>
<tr><td><strong>Sign</strong></td><td>Still local; tx becomes <code>COMPLETE</code> (<span class="pill blue">blue</span>).</td></tr>
<tr><td><strong>Broadcast to executors</strong></td><td>Signed txs uploaded; items become <code>PUSHED</code>.</td></tr>
<tr><td><strong>Check</strong></td><td>Each <code>PUSHED</code> will is queried; success → <code>CHECKED</code> (<span class="pill green">green</span>), failure → <code>CHECK_FAIL</code> (<span class="pill red">red</span>).</td></tr>
<tr><td><strong>Invalidate (on‑chain)</strong></td><td>You spend the committed inputs on the network. Once confirmed, the executor's stored tx can no longer be mined and is dropped on the next check.</td></tr>
<tr><td><strong>Re‑broadcast a new will</strong></td><td>Executors replace the obsolete copy with the new signed tx.</td></tr>
</tbody>
</table>
<blockquote>A row turning <span class="pill red">red</span> (<code>CHECK_FAIL</code>) after a Check means an
executor that <em>should</em> hold your tx did not return it — re‑Broadcast or rebuild. A merely
<span class="pill blue">blue</span> row is signed‑but‑not‑yet‑sent and perfectly normal.</blockquote>
<h2>6. Quick reference — does it cost a Bitcoin fee?</h2>
<table>
<thead><tr><th>Change</th><th>Rebuild?</th><th>On‑chain invalidation (real fee)?</th></tr></thead>
<tbody>
<tr><td>Add heir (only prepared)</td><td class="yes">Yes</td><td class="no">No</td></tr>
<tr><td>Remove heir (only prepared)</td><td class="yes">Yes</td><td class="no">No</td></tr>
<tr><td>Change % / address (only prepared)</td><td class="yes">Yes</td><td class="no">No</td></tr>
<tr><td>Change fee rate</td><td class="yes">Yes</td><td class="no">No</td></tr>
<tr><td>Change / remove will‑executor</td><td class="yes">Yes</td><td class="no">No</td></tr>
<tr><td>Move date <strong>earlier, still in the future</strong> (anticipate) — signed <strong>or</strong> not</td><td class="yes">Yes</td><td class="no">No</td></tr>
<tr><td>Move date <strong>earlier into the past</strong> (new date already passed)</td><td class="yes">Yes after</td><td class="fee">Yes</td></tr>
<tr><td>Move date <strong>later</strong> — will <strong>signed/sent</strong></td><td class="yes">Yes after</td><td class="fee">Yes</td></tr>
<tr><td>Move date <strong>later</strong> — will <strong>only prepared</strong></td><td class="yes">Yes</td><td class="no">No</td></tr>
<tr><td>Check‑Alive threshold already passed</td><td class="yes">Yes after</td><td class="fee">Yes</td></tr>
<tr><td>Any change to an <strong>already signed/sent</strong> will <strong>that postpones it or expires it</strong></td><td class="yes">Yes after</td><td class="fee">Yes</td></tr>
<tr><td>Nothing changed</td><td class="no">No</td><td class="no">No</td></tr>
</tbody>
</table>
<h2>7. Golden rules</h2>
<ol>
<li><strong>Before it's signed</strong>, changing anything is free — just <strong>Prepare</strong> again.</li>
<li><strong>After it's signed/sent</strong>, only <strong>postponing</strong> the date (moving it <em>later</em>),
or letting it <strong>expire</strong> (a date now in the past), requires an <strong>on‑chain invalidation
first</strong> (a small Bitcoin fee) so an old transaction can never execute early.
<strong>Anticipating</strong> (moving the date <em>earlier</em>, still in the future) never invalidates —
it is just a free <strong>rebuild</strong>.</li>
<li>Always finish with <strong>Sign → Broadcast → Check</strong> so executors hold the current plan (green).</li>
<li>The wallet is always <strong>fully emptied</strong> by the inheritance, so heir amounts must add up.</li>
</ol>
<footer>This document reflects BAL plugin v0.3.4. Behaviour is derived directly from
<code>core/will.py</code> and <code>gui/qt/window.py</code>.</footer>
</div>
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true, theme: 'dark', securityLevel: 'loose' });
</script>
</body>
</html>