mirror of
https://github.com/olehomelchenko/astrolabe-nvc.git
synced 2025-12-21 21:22:23 +00:00
544 lines
32 KiB
HTML
544 lines
32 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Astrolabe - Vega-Lite Snippet Manager</title>
|
||
<link rel="stylesheet" href="src/styles.css">
|
||
|
||
<!-- Monaco Editor -->
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.47.0/min/vs/loader.js"></script>
|
||
</head>
|
||
|
||
<body>
|
||
<!-- Header -->
|
||
<div class="header">
|
||
<div class="header-left">
|
||
<span class="header-icon">🔭</span>
|
||
<span class="header-title">Astrolabe</span>
|
||
</div>
|
||
<div class="header-links">
|
||
<span class="header-link" id="import-link" title="Import snippets from JSON file">Import</span>
|
||
<span class="header-link" id="export-link" title="Export all snippets to JSON file">Export</span>
|
||
<span class="header-link" id="datasets-link" title="Open dataset manager (Cmd/Ctrl+K)">Datasets</span>
|
||
<span class="header-link" id="help-link" title="View keyboard shortcuts and help">Help</span>
|
||
<span class="header-link" id="donate-link" title="Support Astrolabe creators">Donate 🇺🇦</span>
|
||
<input type="file" id="import-file-input" accept=".json" style="display: none;" />
|
||
</div>
|
||
</div>
|
||
|
||
<div class="app-container">
|
||
<!-- Toggle Button Strip -->
|
||
<div class="toggle-strip">
|
||
<button class="btn btn-icon xlarge active" id="toggle-snippet-panel" title="Toggle Snippets Panel">
|
||
📄
|
||
</button>
|
||
<button class="btn btn-icon xlarge active" id="toggle-editor-panel" title="Toggle Editor Panel">
|
||
✏️
|
||
</button>
|
||
<button class="btn btn-icon xlarge active" id="toggle-preview-panel" title="Toggle Preview Panel">
|
||
👁️
|
||
</button>
|
||
<button class="btn btn-icon xlarge" id="toggle-datasets" title="Datasets">
|
||
📁
|
||
</button>
|
||
</div>
|
||
|
||
<div class="main-panels">
|
||
<!-- Snippet Library Panel -->
|
||
<div class="panel snippet-panel" id="snippet-panel">
|
||
<div class="panel-header">
|
||
Snippets
|
||
</div>
|
||
<div class="sort-controls">
|
||
<span class="sort-label">Sort by:</span>
|
||
<button class="sort-btn active" data-sort="modified" title="Sort by last modified date">
|
||
<span class="sort-text">Modified</span>
|
||
<span class="sort-arrow">⬇</span>
|
||
</button>
|
||
<button class="sort-btn" data-sort="created" title="Sort by creation date">
|
||
<span class="sort-text">Created</span>
|
||
<span class="sort-arrow">⬇</span>
|
||
</button>
|
||
<button class="sort-btn" data-sort="name" title="Sort alphabetically by name">
|
||
<span class="sort-text">Name</span>
|
||
<span class="sort-arrow">⬇</span>
|
||
</button>
|
||
</div>
|
||
<div class="search-controls">
|
||
<input type="text" id="snippet-search" placeholder="Search snippets..." />
|
||
<button class="btn btn-icon" id="search-clear" title="Clear search">×</button>
|
||
</div>
|
||
<div class="panel-content">
|
||
<ul class="snippet-list">
|
||
<!-- Dynamically populated by renderSnippetList() -->
|
||
</ul>
|
||
<div class="placeholder">
|
||
Click to select a snippet
|
||
</div>
|
||
<div class="snippet-meta" id="snippet-meta" style="display: none;">
|
||
<div class="meta-header">Name</div>
|
||
<input type="text" id="snippet-name" class="input small" placeholder="Snippet name..." />
|
||
|
||
<div class="meta-header">Comment</div>
|
||
<textarea id="snippet-comment" class="input textarea medium" placeholder="Add a comment..." rows="3"></textarea>
|
||
|
||
<div class="meta-info">
|
||
<div class="meta-info-item">
|
||
<span class="meta-info-label">Created:</span>
|
||
<span id="snippet-created"></span>
|
||
</div>
|
||
<div class="meta-info-item">
|
||
<span class="meta-info-label">Modified:</span>
|
||
<span id="snippet-modified"></span>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="snippet-datasets-section" style="display: none;">
|
||
<div class="meta-header">Linked Datasets</div>
|
||
<div class="meta-info" id="snippet-datasets">
|
||
<!-- Dynamically populated by updateLinkedDatasets() -->
|
||
</div>
|
||
</div>
|
||
|
||
<div class="meta-actions">
|
||
<button class="btn btn-standard flex" id="duplicate-btn" title="Create a copy of this snippet">Duplicate</button>
|
||
<button class="btn btn-standard flex danger" id="delete-btn" title="Delete this snippet permanently">Delete</button>
|
||
</div>
|
||
</div>
|
||
<div class="storage-monitor" id="storage-monitor">
|
||
<div class="storage-info">
|
||
<span class="storage-label">Storage:</span>
|
||
<span class="storage-text" id="storage-text">0 KB / 5 MB</span>
|
||
</div>
|
||
<div class="storage-bar">
|
||
<div class="storage-fill" id="storage-fill"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Resize Handle 1 -->
|
||
<div class="resize-handle" id="resize-handle-1"></div>
|
||
|
||
<!-- Editor Panel -->
|
||
<div class="panel editor-panel" id="editor-panel">
|
||
<div class="panel-header">
|
||
<span>Editor</span>
|
||
<div class="editor-controls">
|
||
<button class="btn btn-action" id="extract-btn" style="display: none; background: #87CEEB;" title="Extract inline data to a reusable dataset">Extract to Dataset</button>
|
||
<button class="btn btn-action publish" id="publish-btn" title="Publish draft changes (Cmd/Ctrl+S)">Publish</button>
|
||
<button class="btn btn-action revert" id="revert-btn" title="Discard draft and revert to published version">Revert</button>
|
||
<span class="view-label">View:</span>
|
||
<div class="view-toggle-group">
|
||
<button class="btn btn-toggle active" id="view-draft" title="View and edit draft version">Draft</button>
|
||
<button class="btn btn-toggle" id="view-published" title="View published version (read-only if draft exists)">Published</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="panel-content">
|
||
<div id="monaco-editor" style="height: 100%; width: 100%;"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Resize Handle 2 -->
|
||
<div class="resize-handle" id="resize-handle-2"></div>
|
||
|
||
<!-- Preview Panel -->
|
||
<div class="panel preview-panel" id="preview-panel">
|
||
<div class="panel-header">
|
||
Preview
|
||
</div>
|
||
<div class="panel-content">
|
||
<div id="vega-preview" style="height: 100%; width: 100%; overflow: auto;"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Dataset Manager Modal -->
|
||
<div id="dataset-modal" class="modal" style="display: none;">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<span class="modal-title">Dataset Manager</span>
|
||
<button class="btn btn-icon" id="dataset-modal-close" title="Close dataset manager (Escape)">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<!-- List View (default) -->
|
||
<div id="dataset-list-view" class="dataset-view">
|
||
<div class="dataset-list-header">
|
||
<button class="btn btn-modal primary" id="new-dataset-btn" title="Create a new dataset">New Dataset</button>
|
||
<button class="btn btn-modal" id="import-dataset-btn" title="Import dataset from file">Import</button>
|
||
<input type="file" id="import-dataset-file" accept=".json,.csv,.tsv,.txt" style="display: none;" />
|
||
</div>
|
||
<div class="dataset-container">
|
||
<div class="dataset-list" id="dataset-list">
|
||
<!-- Dynamically populated by renderDatasetList() -->
|
||
</div>
|
||
<div class="dataset-details" id="dataset-details" style="display: none;">
|
||
<div class="dataset-detail-section">
|
||
<div class="dataset-actions">
|
||
<button class="btn btn-modal primary" id="new-snippet-btn" title="Create a new snippet using this dataset">New Snippet</button>
|
||
<button class="btn btn-modal" id="export-dataset-btn" title="Export this dataset to file">Export</button>
|
||
<button class="btn btn-modal" id="copy-reference-btn" title="Copy dataset reference to clipboard">Copy Reference</button>
|
||
<button class="btn btn-modal danger" id="delete-dataset-btn" title="Delete this dataset permanently">Delete</button>
|
||
</div>
|
||
|
||
<div class="dataset-detail-header">Name</div>
|
||
<input type="text" id="dataset-detail-name" class="input" placeholder="Dataset name..." />
|
||
|
||
<div class="dataset-detail-header">Comment</div>
|
||
<textarea id="dataset-detail-comment" class="input textarea" placeholder="Add a comment..." rows="3"></textarea>
|
||
|
||
<div class="dataset-detail-header-row">
|
||
<span class="dataset-detail-header">Statistics</span>
|
||
<button class="btn btn-icon large" id="refresh-metadata-btn" style="display: none;" title="Refresh metadata from URL">🔄</button>
|
||
</div>
|
||
<div class="stats-box">
|
||
<div class="stat-item">
|
||
<span class="stat-label">Rows:</span>
|
||
<span id="dataset-detail-rows">0</span>
|
||
</div>
|
||
<div class="stat-item">
|
||
<span class="stat-label">Columns:</span>
|
||
<span id="dataset-detail-columns">0</span>
|
||
</div>
|
||
<div class="stat-item">
|
||
<span class="stat-label">Size:</span>
|
||
<span id="dataset-detail-size">0 B</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="dataset-detail-header">Timestamps</div>
|
||
<div class="stats-box">
|
||
<div class="stat-item">
|
||
<span class="stat-label">Created:</span>
|
||
<span id="dataset-detail-created">-</span>
|
||
</div>
|
||
<div class="stat-item">
|
||
<span class="stat-label">Modified:</span>
|
||
<span id="dataset-detail-modified">-</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="dataset-detail-header-row">
|
||
<span class="dataset-detail-header">Preview</span>
|
||
<div class="preview-toggle-group" id="preview-toggle-group" style="display: none;">
|
||
<button class="btn btn-toggle small active" id="preview-raw-btn" title="Show raw data preview">Raw</button>
|
||
<button class="btn btn-toggle small" id="preview-table-btn" title="Show data in table format with type detection">Table</button>
|
||
</div>
|
||
</div>
|
||
<pre id="dataset-preview" class="preview-box large"></pre>
|
||
<div id="dataset-preview-table" class="preview-table-container" style="display: none;"></div>
|
||
|
||
<div id="dataset-snippets-section" style="display: none;">
|
||
<div class="dataset-detail-header">Linked Snippets</div>
|
||
<div class="stats-box" id="dataset-snippets">
|
||
<!-- Dynamically populated by updateLinkedSnippets() -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Form View (for creating new datasets) -->
|
||
<div id="dataset-form-view" class="dataset-view" style="display: none;">
|
||
<div class="dataset-form">
|
||
<div class="dataset-form-header">Create New Dataset</div>
|
||
|
||
<div class="dataset-form-group">
|
||
<label class="dataset-form-label">Name *</label>
|
||
<input type="text" id="dataset-form-name" class="input" placeholder="Enter dataset name..." />
|
||
</div>
|
||
|
||
<div class="dataset-form-group">
|
||
<label class="dataset-form-label">Data or URL *</label>
|
||
<div class="dataset-format-hint">
|
||
Paste your data (JSON, CSV, or TSV) or a URL. Format will be detected automatically.
|
||
</div>
|
||
<textarea id="dataset-form-input" class="input textarea" placeholder="Paste data or URL here..." rows="12"></textarea>
|
||
</div>
|
||
|
||
<!-- Detection Confirmation UI -->
|
||
<div id="dataset-detection-confirm" class="dataset-detection-confirm" style="display: none;">
|
||
<div class="detection-header">
|
||
<span class="detection-title">Detected:</span>
|
||
<div class="detection-badges">
|
||
<span class="detection-badge" id="detected-format">JSON</span>
|
||
<span class="detection-badge" id="detected-source">Inline</span>
|
||
<span class="detected-confidence high" id="detected-confidence">high confidence</span>
|
||
</div>
|
||
</div>
|
||
<div class="detection-preview-label">Preview:</div>
|
||
<pre id="detected-preview" class="preview-box medium"></pre>
|
||
</div>
|
||
|
||
<div class="dataset-form-group">
|
||
<label class="dataset-form-label">Comment</label>
|
||
<textarea id="dataset-form-comment" class="input textarea" placeholder="Optional description..." rows="3"></textarea>
|
||
</div>
|
||
|
||
<div class="dataset-form-error" id="dataset-form-error"></div>
|
||
|
||
<div class="dataset-form-actions">
|
||
<button class="btn btn-modal primary" id="save-dataset-btn" title="Save this dataset">Save Dataset</button>
|
||
<button class="btn btn-modal" id="cancel-dataset-btn" title="Cancel and return to dataset list">Cancel</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Extract to Dataset Modal -->
|
||
<div id="extract-modal" class="modal" style="display: none;">
|
||
<div class="modal-content" style="max-width: 600px; height: auto; max-height: 80vh;">
|
||
<div class="modal-header">
|
||
<span class="modal-title">Extract to Dataset</span>
|
||
<button class="btn btn-icon" id="extract-modal-close" title="Close modal (Escape)">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div style="padding: 16px;">
|
||
<div class="dataset-form-group">
|
||
<label class="dataset-form-label">Dataset Name *</label>
|
||
<input type="text" id="extract-dataset-name" class="input" placeholder="Enter dataset name..." />
|
||
</div>
|
||
|
||
<div class="dataset-form-group">
|
||
<label class="dataset-form-label">Data Preview</label>
|
||
<pre id="extract-data-preview" class="preview-box large" style="max-height: 250px;"></pre>
|
||
</div>
|
||
|
||
<div class="dataset-form-error" id="extract-form-error"></div>
|
||
|
||
<div class="dataset-form-actions">
|
||
<button class="btn btn-modal primary" id="extract-create-btn" title="Create dataset and update snippet reference">Create Dataset</button>
|
||
<button class="btn btn-modal" id="extract-cancel-btn" title="Cancel extraction">Cancel</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Help Modal -->
|
||
<div id="help-modal" class="modal" style="display: none;">
|
||
<div class="modal-content" style="max-width: 700px; height: auto; max-height: 85vh;">
|
||
<div class="modal-header">
|
||
<span class="modal-title">Help</span>
|
||
<button class="btn btn-icon" id="help-modal-close" title="Close help (Escape)">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="help-content">
|
||
<!-- About -->
|
||
<section class="help-section">
|
||
<h3 class="help-heading">About Astrolabe</h3>
|
||
<p class="help-text">
|
||
Astrolabe is a lightweight, browser-based snippet manager for Vega-Lite visualizations.
|
||
It's designed to help you quickly create, organize, and iterate on visualization specs without
|
||
the overhead of a full development environment.
|
||
</p>
|
||
<p class="help-text">
|
||
Everything runs locally in your browser—no server, no signup, no data leaving your machine.
|
||
Your snippets and datasets are stored using browser storage, so they persist across sessions.
|
||
</p>
|
||
</section>
|
||
|
||
<!-- Key Features -->
|
||
<section class="help-section">
|
||
<h3 class="help-heading">Key Features</h3>
|
||
<ul class="help-list">
|
||
<li><strong>Three-panel workspace</strong> — Snippet library, Monaco code editor with Vega-Lite schema validation, and live preview</li>
|
||
<li><strong>Draft/published workflow</strong> — Experiment safely without losing your working version</li>
|
||
<li><strong>Dataset library</strong> — Store and reuse datasets across multiple visualizations (supports JSON, CSV, TSV, TopoJSON)</li>
|
||
<li><strong>Import/export</strong> — Back up your work or move it between browsers</li>
|
||
<li><strong>Inline data extraction</strong> — Convert hardcoded data into reusable datasets</li>
|
||
<li><strong>Search and sorting</strong> — Find snippets by name, comment, or spec content</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<!-- Quick Start -->
|
||
<section class="help-section">
|
||
<h3 class="help-heading">Getting Started</h3>
|
||
<div class="help-workflow">
|
||
<div class="help-step">
|
||
<strong>1. Create a snippet</strong>
|
||
<p>Click the "Create New Snippet" ghost card at the top of the snippet list. A sample Vega-Lite spec loads automatically.</p>
|
||
</div>
|
||
<div class="help-step">
|
||
<strong>2. Edit in the Draft view</strong>
|
||
<p>Changes auto-save as you type. The preview updates automatically. Your published version stays safe until you're ready.</p>
|
||
</div>
|
||
<div class="help-step">
|
||
<strong>3. Publish when ready</strong>
|
||
<p>Click "Publish" (or Cmd/Ctrl+S) to save your draft as the official version. Use "Revert" if you want to discard changes.</p>
|
||
</div>
|
||
<div class="help-step">
|
||
<strong>4. Organize with datasets</strong>
|
||
<p>Open the Dataset Manager to create reusable datasets. Reference them in your specs using <code>{"data": {"name": "dataset-name"}}</code>.</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Keyboard Shortcuts -->
|
||
<section class="help-section">
|
||
<h3 class="help-heading">Keyboard Shortcuts</h3>
|
||
<table class="help-shortcuts-table">
|
||
<tbody>
|
||
<tr>
|
||
<td class="shortcut-key">Cmd/Ctrl+Shift+N</td>
|
||
<td class="shortcut-desc">Create new snippet</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="shortcut-key">Cmd/Ctrl+K</td>
|
||
<td class="shortcut-desc">Toggle dataset manager</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="shortcut-key">Cmd/Ctrl+S</td>
|
||
<td class="shortcut-desc">Publish draft (save)</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="shortcut-key">Escape</td>
|
||
<td class="shortcut-desc">Close any open modal</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
|
||
<!-- Storage & Limits -->
|
||
<section class="help-section">
|
||
<h3 class="help-heading">Storage & Limits</h3>
|
||
|
||
<div class="help-warning">
|
||
<strong>⚠️ Important:</strong> All data is stored in your browser's local storage. If you clear your browser cache or site data,
|
||
your snippets and datasets will be permanently deleted. Regular exports are recommended as backups.
|
||
</div>
|
||
|
||
<ul class="help-list">
|
||
<li><strong>Snippets</strong> — Stored in localStorage with a 5 MB limit (shared across all snippets). The storage monitor shows current usage.</li>
|
||
<li><strong>Datasets</strong> — Stored in IndexedDB with effectively unlimited space (browser-dependent, typically 50 MB+).</li>
|
||
<li><strong>Backup</strong> — Use Import/Export to save your work as JSON files. Datasets can be exported individually from the Dataset Manager.</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<!-- Tips & Tricks -->
|
||
<section class="help-section">
|
||
<h3 class="help-heading">Tips & Tricks</h3>
|
||
<ul class="help-list">
|
||
<li><strong>Extract inline data</strong> — When editing a spec with inline data, click "Extract to Dataset" to create a reusable dataset automatically.</li>
|
||
<li><strong>Dataset references</strong> — Astrolabe resolves dataset references at render time, so you can freely switch between inline and referenced data.</li>
|
||
<li><strong>Search across specs</strong> — The search box looks inside snippet names, comments, and the spec content itself.</li>
|
||
<li><strong>Linked datasets</strong> — The metadata panel shows which datasets a snippet uses, and the Dataset Manager shows which snippets reference each dataset.</li>
|
||
<li><strong>URL datasets</strong> — Reference remote data by URL. Astrolabe fetches and caches it for preview, but the URL is what gets stored.</li>
|
||
</ul>
|
||
</section>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Donate Modal -->
|
||
<div id="donate-modal" class="modal" style="display: none;">
|
||
<div class="modal-content" style="height: auto;">
|
||
<div class="modal-header">
|
||
<span class="modal-title"></span>
|
||
<button class="btn btn-icon" id="donate-modal-close" title="Close (Escape)">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="help-content">
|
||
<section class="help-section">
|
||
<h3 class="help-heading">Why Donate?</h3>
|
||
<p class="help-text">
|
||
Astrolabe is a free open-source project built by a Ukrainian in Kyiv, Ukraine.
|
||
If you're thinking of donating, I should be transparent about where that money actually goes - it doesn't go to me or the project.
|
||
It goes to something I care about much more. Right now, while I've been building this passion project, there are people I know - my relatives, friends, colleagues - who took arms and joined Ukraine's Armed Forces. They're defending their country against Russian invasion.
|
||
Most of them were civilians before this. They're still civilians, really, just doing something they had to do.
|
||
I feel deep gratitude to them. So my goal is to support these brave people however I can.
|
||
</p>
|
||
<p class="help-text">
|
||
You might wonder if the military really needs donations.
|
||
The honest answer: yes. The government and Ministry of Defense cover basics, but when you're on the frontlines, every small thing matters.
|
||
Better equipment, better protection, better conditions - these things can make a difference between life and death.
|
||
</p>
|
||
<p class="help-text">
|
||
If you have concerns about donating to the military: I get it. Not everyone is comfortable with that for various reasons, and I respect that.
|
||
The good news is that many of the organizations below also run humanitarian projects for civilians affected by the war. So you have options.
|
||
</p>
|
||
</section>
|
||
<div class="donate-two-column">
|
||
<section class="help-section">
|
||
<h3 class="help-heading">Where to Donate</h3>
|
||
<p class="help-text">
|
||
<ul class="help-list">
|
||
<li>
|
||
|
||
<strong><a href="https://bank.gov.ua/en/news/all/natsionalniy-bank-vidkriv-spetsrahunok-dlya-zboru-koshtiv-na-potrebi-armiyi">
|
||
National Bank of Ukraine's special account for Ukraine's Armed Forces
|
||
</a> - Direct government channel</strong>
|
||
</li>
|
||
<li>
|
||
<strong><a href="https://savelife.in.ua/en/donate-en/#donate-army-card-once">
|
||
Come Back Alive Foundation</a></strong> - One of the biggest and most trusted. They've been around since 2014 and share <a href="https://savelife.in.ua/en/reporting-en/">detailed reports</a> of where money goes.
|
||
</li>
|
||
<li>
|
||
<strong><a href="https://macpaw.foundation/">
|
||
MacPaw Foundation</a></strong> - Founded by MacPaw (where I work). Started in 2016, shifted focus in 2022 to support the Defence Forces.
|
||
</li>
|
||
<li>
|
||
<strong><a href="https://foundation.kse.ua/en/humanitarian-projects/">
|
||
KSE Foundation</a></strong>. Kyiv School of Economics (where I teach). Focuses on both education and humanitarian support for people and defenders
|
||
</li>
|
||
<li>
|
||
<strong><a href="https://standforukraine.com/">
|
||
Stand for Ukraine</a></strong> - Not a foundation, but an aggregator of reliable organizations.
|
||
The list of fundraisers goes beyond military and covers recovery of veterans & victims of war, shelter for the refugees and many more.
|
||
</li>
|
||
</ul>
|
||
</p>
|
||
</section>
|
||
|
||
<section class="help-section">
|
||
<h3 class="help-heading">Other Ways to Support</h3>
|
||
<p class="help-text">
|
||
Not able to donate? You can still help by:
|
||
</p>
|
||
<ul class="help-list">
|
||
<li>Sharing Astrolabe with colleagues and friends</li>
|
||
<li>Reporting bugs and suggesting improvements</li>
|
||
<li>Contributing code or documentation</li>
|
||
<li>Writing about your experience using Astrolabe</li>
|
||
</ul>
|
||
</section>
|
||
</div>
|
||
|
||
<section class="help-section">
|
||
<p class="help-text" style="text-align: center; font-style: italic; color: var(--win-gray-darker);">
|
||
Thank you for considering this.
|
||
</p>
|
||
<p class="help-text" style="text-align: center; font-style: italic; color: var(--win-gray-darker);">
|
||
Oleh Omelchenko
|
||
</p>
|
||
</section>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Toast Notification Container -->
|
||
<div id="toast-container"></div>
|
||
|
||
<script src="src/js/config.js"></script>
|
||
<script src="src/js/snippet-manager.js"></script>
|
||
<script src="src/js/dataset-manager.js"></script>
|
||
<script src="src/js/panel-manager.js"></script>
|
||
<script src="src/js/editor.js"></script>
|
||
<script src="src/js/app.js"></script>
|
||
|
||
<!-- GoatCounter Analytics -->
|
||
<script data-goatcounter="https://astrolabe.goatcounter.com/count"
|
||
data-goatcounter-settings='{"allow_local": true}'
|
||
async src="//gc.zgo.at/count.js"></script>
|
||
</body>
|
||
|
||
</html> |