@picked/vite-plugin-picked 0.0.50-next.2 → 0.0.50-next.4
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/cjs/index.js +9 -9
- package/dist/esm/index.js +213 -1055
- package/package.json +8 -8
package/dist/esm/index.js
CHANGED
|
@@ -1,1065 +1,223 @@
|
|
|
1
|
-
import { createClientHeaders as
|
|
2
|
-
|
|
3
|
-
function
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { createClientHeaders as e, fetchProject as t } from "@picked/client/plugins/dynamic-experiences";
|
|
2
|
+
//#region \0@oxc-project+runtime@0.120.0/helpers/taggedTemplateLiteral.js
|
|
3
|
+
function n(e, t) {
|
|
4
|
+
return t ||= e.slice(0), Object.freeze(Object.defineProperties(e, { raw: { value: Object.freeze(t) } }));
|
|
5
|
+
}
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/launcher.ts
|
|
8
|
+
var r;
|
|
9
|
+
function i(e) {
|
|
10
|
+
let t = JSON.stringify(e), i = e.length > 0 ? e.map((e) => `
|
|
6
11
|
<div class="feature-row">
|
|
7
12
|
<label>
|
|
8
|
-
<input type="checkbox" data-feature-id="${
|
|
9
|
-
<span class="feature-name">${
|
|
10
|
-
<span class="feature-id">${
|
|
13
|
+
<input type="checkbox" data-feature-id="${o(e.id)}" checked>
|
|
14
|
+
<span class="feature-name">${a(e.name)}</span>
|
|
15
|
+
<span class="feature-id">${a(e.id)}</span>
|
|
11
16
|
</label>
|
|
12
|
-
<select data-value-for="${
|
|
17
|
+
<select data-value-for="${o(e.id)}">
|
|
13
18
|
<option value="true" selected>true</option>
|
|
14
19
|
<option value="false">false</option>
|
|
15
20
|
</select>
|
|
16
|
-
</div>`
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
<
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
<meta name
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
.preview-input {
|
|
75
|
-
padding: 0.5rem;
|
|
76
|
-
border: 1px solid #4A4A4A;
|
|
77
|
-
border-radius: 0;
|
|
78
|
-
font-family: monospace;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
.preview-button {
|
|
82
|
-
padding: 0.5rem;
|
|
83
|
-
background: #4A4A4A;
|
|
84
|
-
color: white;
|
|
85
|
-
border: none;
|
|
86
|
-
border-radius: 0;
|
|
87
|
-
cursor: pointer;
|
|
88
|
-
font-family: monospace;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
.preview-button:hover {
|
|
92
|
-
opacity: 0.9;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
.buttons {
|
|
96
|
-
display: grid;
|
|
97
|
-
gap: 0.5em;
|
|
98
|
-
grid-template-columns: 1fr 1fr;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
#copy-status {
|
|
102
|
-
font-size: 1em;
|
|
103
|
-
text-align: right;
|
|
104
|
-
margin-top: 0.5em;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
.features-section {
|
|
108
|
-
margin-top: 1.5rem;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
.features-label {
|
|
112
|
-
font-weight: 700;
|
|
113
|
-
font-size: .875rem;
|
|
114
|
-
margin-bottom: 0.5rem;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
.feature-row {
|
|
118
|
-
display: flex;
|
|
119
|
-
align-items: center;
|
|
120
|
-
justify-content: space-between;
|
|
121
|
-
gap: 0.5rem;
|
|
122
|
-
padding: 0.25rem 0;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
.feature-row label {
|
|
126
|
-
display: flex;
|
|
127
|
-
align-items: center;
|
|
128
|
-
gap: 0.5rem;
|
|
129
|
-
cursor: pointer;
|
|
130
|
-
min-width: 0;
|
|
131
|
-
flex: 1;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
.feature-name {
|
|
135
|
-
font-size: .875rem;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
.feature-id {
|
|
139
|
-
font-size: .75rem;
|
|
140
|
-
color: #888;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
.feature-row select {
|
|
144
|
-
font-family: monospace;
|
|
145
|
-
font-size: .75rem;
|
|
146
|
-
padding: 0.125rem 0.25rem;
|
|
147
|
-
border: 1px solid #4A4A4A;
|
|
148
|
-
border-radius: 0;
|
|
149
|
-
background: white;
|
|
150
|
-
flex-shrink: 0;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
.no-features {
|
|
154
|
-
color: #888;
|
|
155
|
-
font-style: italic;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
.url-history {
|
|
159
|
-
margin-top: 0.5rem;
|
|
160
|
-
font-size: .75rem;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
.url-history-item {
|
|
164
|
-
display: flex;
|
|
165
|
-
align-items: center;
|
|
166
|
-
gap: 0.25rem;
|
|
167
|
-
padding: 0.125rem 0;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
.url-history-item button {
|
|
171
|
-
background: none;
|
|
172
|
-
border: none;
|
|
173
|
-
cursor: pointer;
|
|
174
|
-
font-family: monospace;
|
|
175
|
-
font-size: .75rem;
|
|
176
|
-
color: #888;
|
|
177
|
-
padding: 0;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
.url-history-item button.url-link {
|
|
181
|
-
color: #4A4A4A;
|
|
182
|
-
text-decoration: none;
|
|
183
|
-
text-align: left;
|
|
184
|
-
overflow: hidden;
|
|
185
|
-
text-overflow: ellipsis;
|
|
186
|
-
white-space: nowrap;
|
|
187
|
-
flex: 1;
|
|
188
|
-
min-width: 0;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
.url-history-item button.url-link:hover {
|
|
192
|
-
text-decoration: underline;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
.url-history-item button.url-delete:hover {
|
|
196
|
-
color: #b71c1c;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
@media (min-width: 640px) {
|
|
200
|
-
.title {
|
|
201
|
-
font-size: 1.25rem
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
.text {
|
|
205
|
-
font-size: 1rem
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
</style>
|
|
209
|
-
</head>
|
|
210
|
-
<body>
|
|
211
|
-
|
|
212
|
-
<main>
|
|
213
|
-
<div class="wrap">
|
|
214
|
-
<p class="title">Picked</p>
|
|
215
|
-
<p class="text">
|
|
216
|
-
Learn more at
|
|
217
|
-
<a href="https://picked.app">
|
|
218
|
-
https://picked.app
|
|
219
|
-
</a>
|
|
220
|
-
</p>
|
|
221
|
-
<div class="preview-form">
|
|
222
|
-
<input type="text" id="url-input" pattern="^(https?://)?.+" placeholder="Enter preview URL" required
|
|
223
|
-
class="preview-input">
|
|
224
|
-
<div id="url-history" class="url-history"></div>
|
|
225
|
-
<div class="features-section">
|
|
226
|
-
<p class="features-label">Features</p>
|
|
227
|
-
`, `
|
|
228
|
-
</div>
|
|
229
|
-
<div class="buttons">
|
|
230
|
-
<button type="button" class="preview-button" id="copy-btn">Copy</button>
|
|
231
|
-
<button type="button" class="preview-button" id="preview-btn">Preview</button>
|
|
232
|
-
</div>
|
|
233
|
-
<p class="text" id="copy-status" aria-live="polite" style="visibility:hidden;">
|
|
234
|
-
|
|
235
|
-
</p>
|
|
236
|
-
</div>
|
|
237
|
-
</div>
|
|
238
|
-
|
|
239
|
-
<script>
|
|
240
|
-
var FEATURES = `, `;
|
|
241
|
-
var STORAGE_KEY_URL = 'picked-launcher-url';
|
|
242
|
-
var STORAGE_KEY_HISTORY = 'picked-launcher-history';
|
|
243
|
-
var STORAGE_KEY_SELECTIONS = 'picked-launcher-selections';
|
|
244
|
-
|
|
245
|
-
function getUrlInput() {
|
|
246
|
-
return document.getElementById('url-input');
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// URL history
|
|
250
|
-
function getHistory() {
|
|
251
|
-
try {
|
|
252
|
-
var raw = localStorage.getItem(STORAGE_KEY_HISTORY);
|
|
253
|
-
if (!raw) return [];
|
|
254
|
-
var parsed = JSON.parse(raw);
|
|
255
|
-
return Array.isArray(parsed) ? parsed : [];
|
|
256
|
-
} catch (e) {
|
|
257
|
-
return [];
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
function saveHistory(history) {
|
|
262
|
-
localStorage.setItem(STORAGE_KEY_HISTORY, JSON.stringify(history));
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
function addToHistory(url) {
|
|
266
|
-
var history = getHistory().filter(function(h) { return h !== url; });
|
|
267
|
-
history.unshift(url);
|
|
268
|
-
if (history.length > 10) history = history.slice(0, 10);
|
|
269
|
-
saveHistory(history);
|
|
270
|
-
renderHistory();
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
function removeFromHistory(url) {
|
|
274
|
-
var history = getHistory().filter(function(h) { return h !== url; });
|
|
275
|
-
saveHistory(history);
|
|
276
|
-
renderHistory();
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
function renderHistory() {
|
|
280
|
-
var container = document.getElementById('url-history');
|
|
281
|
-
if (!container) return;
|
|
282
|
-
var history = getHistory();
|
|
283
|
-
if (history.length === 0) {
|
|
284
|
-
container.innerHTML = '';
|
|
285
|
-
return;
|
|
286
|
-
}
|
|
287
|
-
container.innerHTML = history.map(function(url) {
|
|
288
|
-
return '<div class="url-history-item">' +
|
|
289
|
-
'<button type="button" class="url-link" data-history-url="' + escapeAttr(url) + '">' + escapeHtml(url) + '</button>' +
|
|
290
|
-
'<button type="button" class="url-delete" data-history-delete="' + escapeAttr(url) + '">x</button>' +
|
|
291
|
-
'</div>';
|
|
292
|
-
}).join('');
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
// Feature selection persistence
|
|
296
|
-
function getSelections() {
|
|
297
|
-
try {
|
|
298
|
-
var raw = localStorage.getItem(STORAGE_KEY_SELECTIONS);
|
|
299
|
-
if (!raw) return {};
|
|
300
|
-
var parsed = JSON.parse(raw);
|
|
301
|
-
return typeof parsed === 'object' && parsed !== null ? parsed : {};
|
|
302
|
-
} catch (e) {
|
|
303
|
-
return {};
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
function saveSelections() {
|
|
308
|
-
var selections = {};
|
|
309
|
-
FEATURES.forEach(function(f) {
|
|
310
|
-
var checkbox = document.querySelector('input[data-feature-id="' + f.id + '"]');
|
|
311
|
-
var select = document.querySelector('select[data-value-for="' + f.id + '"]');
|
|
312
|
-
if (checkbox && select) {
|
|
313
|
-
selections[f.id] = { checked: checkbox.checked, value: select.value };
|
|
314
|
-
}
|
|
315
|
-
});
|
|
316
|
-
localStorage.setItem(STORAGE_KEY_SELECTIONS, JSON.stringify(selections));
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
function restoreSelections() {
|
|
320
|
-
var selections = getSelections();
|
|
321
|
-
FEATURES.forEach(function(f) {
|
|
322
|
-
var saved = selections[f.id];
|
|
323
|
-
if (!saved) return;
|
|
324
|
-
var checkbox = document.querySelector('input[data-feature-id="' + f.id + '"]');
|
|
325
|
-
var select = document.querySelector('select[data-value-for="' + f.id + '"]');
|
|
326
|
-
if (checkbox) checkbox.checked = saved.checked;
|
|
327
|
-
if (select) select.value = saved.value;
|
|
328
|
-
});
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
function escapeHtml(str) {
|
|
332
|
-
var div = document.createElement('div');
|
|
333
|
-
div.textContent = str;
|
|
334
|
-
return div.innerHTML;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
function escapeAttr(str) {
|
|
338
|
-
return str.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>');
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
function buildTargetUrl(inputValue) {
|
|
342
|
-
var value = inputValue;
|
|
343
|
-
if (!value.startsWith('http://') && !value.startsWith('https://')) {
|
|
344
|
-
value = 'https://' + value;
|
|
345
|
-
}
|
|
346
|
-
var hostname = window.location.hostname;
|
|
347
|
-
var subdomain = hostname.split('.').length > 2 ? hostname.split('.')[0] : '';
|
|
348
|
-
var target = value;
|
|
349
|
-
var sep = target.includes('?') ? '&' : '?';
|
|
350
|
-
if (subdomain) {
|
|
351
|
-
target = target + sep + 'cvly_env=' + encodeURIComponent(subdomain);
|
|
352
|
-
sep = '&';
|
|
353
|
-
}
|
|
354
|
-
FEATURES.forEach(function(f) {
|
|
355
|
-
var checkbox = document.querySelector('input[data-feature-id="' + f.id + '"]');
|
|
356
|
-
var select = document.querySelector('select[data-value-for="' + f.id + '"]');
|
|
357
|
-
if (checkbox && checkbox.checked && select) {
|
|
358
|
-
target = target + sep + 'picked-feature=' + encodeURIComponent(f.id + ':' + select.value);
|
|
359
|
-
sep = '&';
|
|
360
|
-
}
|
|
361
|
-
});
|
|
362
|
-
return target;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
function showCopyStatus(message, success) {
|
|
366
|
-
var el = document.getElementById('copy-status');
|
|
367
|
-
if (!el) return;
|
|
368
|
-
el.textContent = message;
|
|
369
|
-
el.style.visibility = 'visible';
|
|
370
|
-
el.style.color = success ? '#2e7d32' : '#b71c1c';
|
|
371
|
-
setTimeout(function() {
|
|
372
|
-
el.style.visibility = 'hidden';
|
|
373
|
-
}, 2000);
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
// Init
|
|
377
|
-
window.addEventListener('load', function() {
|
|
378
|
-
var input = getUrlInput();
|
|
379
|
-
var savedUrl = localStorage.getItem(STORAGE_KEY_URL);
|
|
380
|
-
if (savedUrl && input) {
|
|
381
|
-
input.value = savedUrl;
|
|
382
|
-
}
|
|
383
|
-
renderHistory();
|
|
384
|
-
restoreSelections();
|
|
385
|
-
});
|
|
386
|
-
|
|
387
|
-
// Delegate click events
|
|
388
|
-
document.addEventListener('click', function(e) {
|
|
389
|
-
var target = e.target;
|
|
390
|
-
|
|
391
|
-
// History URL click
|
|
392
|
-
var historyUrl = target.getAttribute('data-history-url');
|
|
393
|
-
if (historyUrl) {
|
|
394
|
-
var input = getUrlInput();
|
|
395
|
-
if (input) input.value = historyUrl;
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
// History delete click
|
|
400
|
-
var deleteUrl = target.getAttribute('data-history-delete');
|
|
401
|
-
if (deleteUrl) {
|
|
402
|
-
removeFromHistory(deleteUrl);
|
|
403
|
-
return;
|
|
404
|
-
}
|
|
405
|
-
});
|
|
406
|
-
|
|
407
|
-
// Feature change persistence
|
|
408
|
-
document.addEventListener('change', function(e) {
|
|
409
|
-
var target = e.target;
|
|
410
|
-
if (target.getAttribute('data-feature-id') || target.getAttribute('data-value-for')) {
|
|
411
|
-
saveSelections();
|
|
412
|
-
}
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
// Copy button
|
|
416
|
-
document.getElementById('copy-btn').addEventListener('click', function() {
|
|
417
|
-
var input = getUrlInput();
|
|
418
|
-
if (!input || !input.value) return;
|
|
419
|
-
localStorage.setItem(STORAGE_KEY_URL, input.value);
|
|
420
|
-
addToHistory(input.value);
|
|
421
|
-
saveSelections();
|
|
422
|
-
var target = buildTargetUrl(input.value);
|
|
423
|
-
navigator.clipboard.writeText(target).then(function() {
|
|
424
|
-
showCopyStatus('Preview URL copied to clipboard', true);
|
|
425
|
-
});
|
|
426
|
-
});
|
|
427
|
-
|
|
428
|
-
// Preview button
|
|
429
|
-
document.getElementById('preview-btn').addEventListener('click', function() {
|
|
430
|
-
var input = getUrlInput();
|
|
431
|
-
if (!input || !input.value) return;
|
|
432
|
-
localStorage.setItem(STORAGE_KEY_URL, input.value);
|
|
433
|
-
addToHistory(input.value);
|
|
434
|
-
saveSelections();
|
|
435
|
-
var target = buildTargetUrl(input.value);
|
|
436
|
-
window.location.href = target;
|
|
437
|
-
});
|
|
438
|
-
<\/script>
|
|
439
|
-
</main>
|
|
440
|
-
</body>
|
|
441
|
-
</html>`], [`<!DOCTYPE html>
|
|
442
|
-
<html lang="en">
|
|
443
|
-
<head>
|
|
444
|
-
<meta charset="UTF-8">
|
|
445
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
446
|
-
<meta name="robots" content="noindex, nofollow">
|
|
447
|
-
<title>Picked</title>
|
|
448
|
-
<style>
|
|
449
|
-
main {
|
|
450
|
-
position: fixed;
|
|
451
|
-
top: 0;
|
|
452
|
-
right: 0;
|
|
453
|
-
bottom: 0;
|
|
454
|
-
left: 0;
|
|
455
|
-
display: grid;
|
|
456
|
-
align-items: center;
|
|
457
|
-
justify-content: center;
|
|
458
|
-
font-family: monospace;
|
|
459
|
-
color: #4A4A4A
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
.wrap {
|
|
463
|
-
padding-left: 1.5rem;
|
|
464
|
-
padding-right: 1.5rem;
|
|
465
|
-
max-width: 480px;
|
|
466
|
-
width: 100%;
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
.title {
|
|
470
|
-
font-size: 1.125rem;
|
|
471
|
-
font-weight: 700;
|
|
472
|
-
margin-bottom: 0;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
.text {
|
|
476
|
-
margin-top: .5rem;
|
|
477
|
-
font-size: .875rem
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
.text a {
|
|
481
|
-
color: #4A4A4A;
|
|
482
|
-
text-decoration: none;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
.text a:hover {
|
|
486
|
-
cursor: pointer;
|
|
487
|
-
text-decoration: underline
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
.preview-form {
|
|
491
|
-
margin-top: 2rem;
|
|
492
|
-
display: flex;
|
|
493
|
-
flex-direction: column;
|
|
494
|
-
gap: 0.5rem;
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
.preview-input {
|
|
498
|
-
padding: 0.5rem;
|
|
499
|
-
border: 1px solid #4A4A4A;
|
|
500
|
-
border-radius: 0;
|
|
501
|
-
font-family: monospace;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
.preview-button {
|
|
505
|
-
padding: 0.5rem;
|
|
506
|
-
background: #4A4A4A;
|
|
507
|
-
color: white;
|
|
508
|
-
border: none;
|
|
509
|
-
border-radius: 0;
|
|
510
|
-
cursor: pointer;
|
|
511
|
-
font-family: monospace;
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
.preview-button:hover {
|
|
515
|
-
opacity: 0.9;
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
.buttons {
|
|
519
|
-
display: grid;
|
|
520
|
-
gap: 0.5em;
|
|
521
|
-
grid-template-columns: 1fr 1fr;
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
#copy-status {
|
|
525
|
-
font-size: 1em;
|
|
526
|
-
text-align: right;
|
|
527
|
-
margin-top: 0.5em;
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
.features-section {
|
|
531
|
-
margin-top: 1.5rem;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
.features-label {
|
|
535
|
-
font-weight: 700;
|
|
536
|
-
font-size: .875rem;
|
|
537
|
-
margin-bottom: 0.5rem;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
.feature-row {
|
|
541
|
-
display: flex;
|
|
542
|
-
align-items: center;
|
|
543
|
-
justify-content: space-between;
|
|
544
|
-
gap: 0.5rem;
|
|
545
|
-
padding: 0.25rem 0;
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
.feature-row label {
|
|
549
|
-
display: flex;
|
|
550
|
-
align-items: center;
|
|
551
|
-
gap: 0.5rem;
|
|
552
|
-
cursor: pointer;
|
|
553
|
-
min-width: 0;
|
|
554
|
-
flex: 1;
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
.feature-name {
|
|
558
|
-
font-size: .875rem;
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
.feature-id {
|
|
562
|
-
font-size: .75rem;
|
|
563
|
-
color: #888;
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
.feature-row select {
|
|
567
|
-
font-family: monospace;
|
|
568
|
-
font-size: .75rem;
|
|
569
|
-
padding: 0.125rem 0.25rem;
|
|
570
|
-
border: 1px solid #4A4A4A;
|
|
571
|
-
border-radius: 0;
|
|
572
|
-
background: white;
|
|
573
|
-
flex-shrink: 0;
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
.no-features {
|
|
577
|
-
color: #888;
|
|
578
|
-
font-style: italic;
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
.url-history {
|
|
582
|
-
margin-top: 0.5rem;
|
|
583
|
-
font-size: .75rem;
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
.url-history-item {
|
|
587
|
-
display: flex;
|
|
588
|
-
align-items: center;
|
|
589
|
-
gap: 0.25rem;
|
|
590
|
-
padding: 0.125rem 0;
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
.url-history-item button {
|
|
594
|
-
background: none;
|
|
595
|
-
border: none;
|
|
596
|
-
cursor: pointer;
|
|
597
|
-
font-family: monospace;
|
|
598
|
-
font-size: .75rem;
|
|
599
|
-
color: #888;
|
|
600
|
-
padding: 0;
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
.url-history-item button.url-link {
|
|
604
|
-
color: #4A4A4A;
|
|
605
|
-
text-decoration: none;
|
|
606
|
-
text-align: left;
|
|
607
|
-
overflow: hidden;
|
|
608
|
-
text-overflow: ellipsis;
|
|
609
|
-
white-space: nowrap;
|
|
610
|
-
flex: 1;
|
|
611
|
-
min-width: 0;
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
.url-history-item button.url-link:hover {
|
|
615
|
-
text-decoration: underline;
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
.url-history-item button.url-delete:hover {
|
|
619
|
-
color: #b71c1c;
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
@media (min-width: 640px) {
|
|
623
|
-
.title {
|
|
624
|
-
font-size: 1.25rem
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
.text {
|
|
628
|
-
font-size: 1rem
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
</style>
|
|
632
|
-
</head>
|
|
633
|
-
<body>
|
|
634
|
-
|
|
635
|
-
<main>
|
|
636
|
-
<div class="wrap">
|
|
637
|
-
<p class="title">Picked</p>
|
|
638
|
-
<p class="text">
|
|
639
|
-
Learn more at
|
|
640
|
-
<a href="https://picked.app">
|
|
641
|
-
https://picked.app
|
|
642
|
-
</a>
|
|
643
|
-
</p>
|
|
644
|
-
<div class="preview-form">
|
|
645
|
-
<input type="text" id="url-input" pattern="^(https?:\\/\\/)?.+" placeholder="Enter preview URL" required
|
|
646
|
-
class="preview-input">
|
|
647
|
-
<div id="url-history" class="url-history"></div>
|
|
648
|
-
<div class="features-section">
|
|
649
|
-
<p class="features-label">Features</p>
|
|
650
|
-
`, `
|
|
651
|
-
</div>
|
|
652
|
-
<div class="buttons">
|
|
653
|
-
<button type="button" class="preview-button" id="copy-btn">Copy</button>
|
|
654
|
-
<button type="button" class="preview-button" id="preview-btn">Preview</button>
|
|
655
|
-
</div>
|
|
656
|
-
<p class="text" id="copy-status" aria-live="polite" style="visibility:hidden;">
|
|
657
|
-
|
|
658
|
-
</p>
|
|
659
|
-
</div>
|
|
660
|
-
</div>
|
|
661
|
-
|
|
662
|
-
<script>
|
|
663
|
-
var FEATURES = `, `;
|
|
664
|
-
var STORAGE_KEY_URL = 'picked-launcher-url';
|
|
665
|
-
var STORAGE_KEY_HISTORY = 'picked-launcher-history';
|
|
666
|
-
var STORAGE_KEY_SELECTIONS = 'picked-launcher-selections';
|
|
667
|
-
|
|
668
|
-
function getUrlInput() {
|
|
669
|
-
return document.getElementById('url-input');
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
// URL history
|
|
673
|
-
function getHistory() {
|
|
674
|
-
try {
|
|
675
|
-
var raw = localStorage.getItem(STORAGE_KEY_HISTORY);
|
|
676
|
-
if (!raw) return [];
|
|
677
|
-
var parsed = JSON.parse(raw);
|
|
678
|
-
return Array.isArray(parsed) ? parsed : [];
|
|
679
|
-
} catch (e) {
|
|
680
|
-
return [];
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
function saveHistory(history) {
|
|
685
|
-
localStorage.setItem(STORAGE_KEY_HISTORY, JSON.stringify(history));
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
function addToHistory(url) {
|
|
689
|
-
var history = getHistory().filter(function(h) { return h !== url; });
|
|
690
|
-
history.unshift(url);
|
|
691
|
-
if (history.length > 10) history = history.slice(0, 10);
|
|
692
|
-
saveHistory(history);
|
|
693
|
-
renderHistory();
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
function removeFromHistory(url) {
|
|
697
|
-
var history = getHistory().filter(function(h) { return h !== url; });
|
|
698
|
-
saveHistory(history);
|
|
699
|
-
renderHistory();
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
function renderHistory() {
|
|
703
|
-
var container = document.getElementById('url-history');
|
|
704
|
-
if (!container) return;
|
|
705
|
-
var history = getHistory();
|
|
706
|
-
if (history.length === 0) {
|
|
707
|
-
container.innerHTML = '';
|
|
708
|
-
return;
|
|
709
|
-
}
|
|
710
|
-
container.innerHTML = history.map(function(url) {
|
|
711
|
-
return '<div class="url-history-item">' +
|
|
712
|
-
'<button type="button" class="url-link" data-history-url="' + escapeAttr(url) + '">' + escapeHtml(url) + '</button>' +
|
|
713
|
-
'<button type="button" class="url-delete" data-history-delete="' + escapeAttr(url) + '">x</button>' +
|
|
714
|
-
'</div>';
|
|
715
|
-
}).join('');
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
// Feature selection persistence
|
|
719
|
-
function getSelections() {
|
|
720
|
-
try {
|
|
721
|
-
var raw = localStorage.getItem(STORAGE_KEY_SELECTIONS);
|
|
722
|
-
if (!raw) return {};
|
|
723
|
-
var parsed = JSON.parse(raw);
|
|
724
|
-
return typeof parsed === 'object' && parsed !== null ? parsed : {};
|
|
725
|
-
} catch (e) {
|
|
726
|
-
return {};
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
function saveSelections() {
|
|
731
|
-
var selections = {};
|
|
732
|
-
FEATURES.forEach(function(f) {
|
|
733
|
-
var checkbox = document.querySelector('input[data-feature-id="' + f.id + '"]');
|
|
734
|
-
var select = document.querySelector('select[data-value-for="' + f.id + '"]');
|
|
735
|
-
if (checkbox && select) {
|
|
736
|
-
selections[f.id] = { checked: checkbox.checked, value: select.value };
|
|
737
|
-
}
|
|
738
|
-
});
|
|
739
|
-
localStorage.setItem(STORAGE_KEY_SELECTIONS, JSON.stringify(selections));
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
function restoreSelections() {
|
|
743
|
-
var selections = getSelections();
|
|
744
|
-
FEATURES.forEach(function(f) {
|
|
745
|
-
var saved = selections[f.id];
|
|
746
|
-
if (!saved) return;
|
|
747
|
-
var checkbox = document.querySelector('input[data-feature-id="' + f.id + '"]');
|
|
748
|
-
var select = document.querySelector('select[data-value-for="' + f.id + '"]');
|
|
749
|
-
if (checkbox) checkbox.checked = saved.checked;
|
|
750
|
-
if (select) select.value = saved.value;
|
|
751
|
-
});
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
function escapeHtml(str) {
|
|
755
|
-
var div = document.createElement('div');
|
|
756
|
-
div.textContent = str;
|
|
757
|
-
return div.innerHTML;
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
function escapeAttr(str) {
|
|
761
|
-
return str.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>');
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
function buildTargetUrl(inputValue) {
|
|
765
|
-
var value = inputValue;
|
|
766
|
-
if (!value.startsWith('http://') && !value.startsWith('https://')) {
|
|
767
|
-
value = 'https://' + value;
|
|
768
|
-
}
|
|
769
|
-
var hostname = window.location.hostname;
|
|
770
|
-
var subdomain = hostname.split('.').length > 2 ? hostname.split('.')[0] : '';
|
|
771
|
-
var target = value;
|
|
772
|
-
var sep = target.includes('?') ? '&' : '?';
|
|
773
|
-
if (subdomain) {
|
|
774
|
-
target = target + sep + 'cvly_env=' + encodeURIComponent(subdomain);
|
|
775
|
-
sep = '&';
|
|
776
|
-
}
|
|
777
|
-
FEATURES.forEach(function(f) {
|
|
778
|
-
var checkbox = document.querySelector('input[data-feature-id="' + f.id + '"]');
|
|
779
|
-
var select = document.querySelector('select[data-value-for="' + f.id + '"]');
|
|
780
|
-
if (checkbox && checkbox.checked && select) {
|
|
781
|
-
target = target + sep + 'picked-feature=' + encodeURIComponent(f.id + ':' + select.value);
|
|
782
|
-
sep = '&';
|
|
783
|
-
}
|
|
784
|
-
});
|
|
785
|
-
return target;
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
function showCopyStatus(message, success) {
|
|
789
|
-
var el = document.getElementById('copy-status');
|
|
790
|
-
if (!el) return;
|
|
791
|
-
el.textContent = message;
|
|
792
|
-
el.style.visibility = 'visible';
|
|
793
|
-
el.style.color = success ? '#2e7d32' : '#b71c1c';
|
|
794
|
-
setTimeout(function() {
|
|
795
|
-
el.style.visibility = 'hidden';
|
|
796
|
-
}, 2000);
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
// Init
|
|
800
|
-
window.addEventListener('load', function() {
|
|
801
|
-
var input = getUrlInput();
|
|
802
|
-
var savedUrl = localStorage.getItem(STORAGE_KEY_URL);
|
|
803
|
-
if (savedUrl && input) {
|
|
804
|
-
input.value = savedUrl;
|
|
805
|
-
}
|
|
806
|
-
renderHistory();
|
|
807
|
-
restoreSelections();
|
|
808
|
-
});
|
|
809
|
-
|
|
810
|
-
// Delegate click events
|
|
811
|
-
document.addEventListener('click', function(e) {
|
|
812
|
-
var target = e.target;
|
|
813
|
-
|
|
814
|
-
// History URL click
|
|
815
|
-
var historyUrl = target.getAttribute('data-history-url');
|
|
816
|
-
if (historyUrl) {
|
|
817
|
-
var input = getUrlInput();
|
|
818
|
-
if (input) input.value = historyUrl;
|
|
819
|
-
return;
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
// History delete click
|
|
823
|
-
var deleteUrl = target.getAttribute('data-history-delete');
|
|
824
|
-
if (deleteUrl) {
|
|
825
|
-
removeFromHistory(deleteUrl);
|
|
826
|
-
return;
|
|
827
|
-
}
|
|
828
|
-
});
|
|
829
|
-
|
|
830
|
-
// Feature change persistence
|
|
831
|
-
document.addEventListener('change', function(e) {
|
|
832
|
-
var target = e.target;
|
|
833
|
-
if (target.getAttribute('data-feature-id') || target.getAttribute('data-value-for')) {
|
|
834
|
-
saveSelections();
|
|
835
|
-
}
|
|
836
|
-
});
|
|
837
|
-
|
|
838
|
-
// Copy button
|
|
839
|
-
document.getElementById('copy-btn').addEventListener('click', function() {
|
|
840
|
-
var input = getUrlInput();
|
|
841
|
-
if (!input || !input.value) return;
|
|
842
|
-
localStorage.setItem(STORAGE_KEY_URL, input.value);
|
|
843
|
-
addToHistory(input.value);
|
|
844
|
-
saveSelections();
|
|
845
|
-
var target = buildTargetUrl(input.value);
|
|
846
|
-
navigator.clipboard.writeText(target).then(function() {
|
|
847
|
-
showCopyStatus('Preview URL copied to clipboard', true);
|
|
848
|
-
});
|
|
849
|
-
});
|
|
850
|
-
|
|
851
|
-
// Preview button
|
|
852
|
-
document.getElementById('preview-btn').addEventListener('click', function() {
|
|
853
|
-
var input = getUrlInput();
|
|
854
|
-
if (!input || !input.value) return;
|
|
855
|
-
localStorage.setItem(STORAGE_KEY_URL, input.value);
|
|
856
|
-
addToHistory(input.value);
|
|
857
|
-
saveSelections();
|
|
858
|
-
var target = buildTargetUrl(input.value);
|
|
859
|
-
window.location.href = target;
|
|
860
|
-
});
|
|
861
|
-
<\/script>
|
|
862
|
-
</main>
|
|
863
|
-
</body>
|
|
864
|
-
</html>`])), r, t);
|
|
865
|
-
}
|
|
866
|
-
function w(e) {
|
|
867
|
-
return e.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """);
|
|
868
|
-
}
|
|
869
|
-
function S(e) {
|
|
870
|
-
return e.replaceAll("&", "&").replaceAll('"', """).replaceAll("<", "<").replaceAll(">", ">");
|
|
871
|
-
}
|
|
872
|
-
const E = "picked", H = "\x1B[0m";
|
|
873
|
-
function O() {
|
|
874
|
-
const e = process.env.NO_COLOR;
|
|
875
|
-
return e === "1" || e === "true";
|
|
876
|
-
}
|
|
877
|
-
function c(e) {
|
|
878
|
-
return (t) => O() ? t : `${e}${t}${H}`;
|
|
879
|
-
}
|
|
880
|
-
const x = ["debug", "info", "warn", "error", "silent"], m = {
|
|
881
|
-
debug: {
|
|
882
|
-
color: c("\x1B[2m"),
|
|
883
|
-
log: console.debug,
|
|
884
|
-
enabled: !1
|
|
885
|
-
},
|
|
886
|
-
info: {
|
|
887
|
-
color: c("\x1B[36m"),
|
|
888
|
-
log: console.log,
|
|
889
|
-
enabled: !0
|
|
890
|
-
},
|
|
891
|
-
warn: {
|
|
892
|
-
color: c("\x1B[33m"),
|
|
893
|
-
log: console.warn,
|
|
894
|
-
enabled: !0
|
|
895
|
-
},
|
|
896
|
-
error: {
|
|
897
|
-
color: c("\x1B[31m"),
|
|
898
|
-
log: console.error,
|
|
899
|
-
enabled: !0
|
|
900
|
-
},
|
|
901
|
-
silent: {
|
|
902
|
-
log: () => {
|
|
903
|
-
},
|
|
904
|
-
enabled: !1
|
|
905
|
-
}
|
|
21
|
+
</div>`).join("") : "<p class=\"text no-features\">No features configured for this project.</p>";
|
|
22
|
+
return String.raw(r ||= n([
|
|
23
|
+
"<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <meta name=\"robots\" content=\"noindex, nofollow\">\n <title>Picked</title>\n <style>\n main {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n display: grid;\n align-items: center;\n justify-content: center;\n font-family: monospace;\n color: #4A4A4A\n }\n\n .wrap {\n padding-left: 1.5rem;\n padding-right: 1.5rem;\n max-width: 480px;\n width: 100%;\n }\n\n .title {\n font-size: 1.125rem;\n font-weight: 700;\n margin-bottom: 0;\n }\n\n .text {\n margin-top: .5rem;\n font-size: .875rem\n }\n\n .text a {\n color: #4A4A4A;\n text-decoration: none;\n }\n\n .text a:hover {\n cursor: pointer;\n text-decoration: underline\n }\n\n .preview-form {\n margin-top: 2rem;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n }\n\n .preview-input {\n padding: 0.5rem;\n border: 1px solid #4A4A4A;\n border-radius: 0;\n font-family: monospace;\n }\n\n .preview-button {\n padding: 0.5rem;\n background: #4A4A4A;\n color: white;\n border: none;\n border-radius: 0;\n cursor: pointer;\n font-family: monospace;\n }\n\n .preview-button:hover {\n opacity: 0.9;\n }\n\n .buttons {\n display: grid;\n gap: 0.5em;\n grid-template-columns: 1fr 1fr;\n }\n\n #copy-status {\n font-size: 1em;\n text-align: right;\n margin-top: 0.5em;\n }\n\n .features-section {\n margin-top: 1.5rem;\n }\n\n .features-label {\n font-weight: 700;\n font-size: .875rem;\n margin-bottom: 0.5rem;\n }\n\n .feature-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.5rem;\n padding: 0.25rem 0;\n }\n\n .feature-row label {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n min-width: 0;\n flex: 1;\n }\n\n .feature-name {\n font-size: .875rem;\n }\n\n .feature-id {\n font-size: .75rem;\n color: #888;\n }\n\n .feature-row select {\n font-family: monospace;\n font-size: .75rem;\n padding: 0.125rem 0.25rem;\n border: 1px solid #4A4A4A;\n border-radius: 0;\n background: white;\n flex-shrink: 0;\n }\n\n .no-features {\n color: #888;\n font-style: italic;\n }\n\n .url-history {\n margin-top: 0.5rem;\n font-size: .75rem;\n }\n\n .url-history-item {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0.125rem 0;\n }\n\n .url-history-item button {\n background: none;\n border: none;\n cursor: pointer;\n font-family: monospace;\n font-size: .75rem;\n color: #888;\n padding: 0;\n }\n\n .url-history-item button.url-link {\n color: #4A4A4A;\n text-decoration: none;\n text-align: left;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n min-width: 0;\n }\n\n .url-history-item button.url-link:hover {\n text-decoration: underline;\n }\n\n .url-history-item button.url-delete:hover {\n color: #b71c1c;\n }\n\n @media (min-width: 640px) {\n .title {\n font-size: 1.25rem\n }\n\n .text {\n font-size: 1rem\n }\n }\n </style>\n</head>\n<body>\n\n<main>\n <div class=\"wrap\">\n <p class=\"title\">Picked</p>\n <p class=\"text\">\n Learn more at\n <a href=\"https://picked.app\">\n https://picked.app\n </a>\n </p>\n <div class=\"preview-form\">\n <input type=\"text\" id=\"url-input\" pattern=\"^(https?://)?.+\" placeholder=\"Enter preview URL\" required\n class=\"preview-input\">\n <div id=\"url-history\" class=\"url-history\"></div>\n <div class=\"features-section\">\n <p class=\"features-label\">Features</p>\n ",
|
|
24
|
+
"\n </div>\n <div class=\"buttons\">\n <button type=\"button\" class=\"preview-button\" id=\"copy-btn\">Copy</button>\n <button type=\"button\" class=\"preview-button\" id=\"preview-btn\">Preview</button>\n </div>\n <p class=\"text\" id=\"copy-status\" aria-live=\"polite\" style=\"visibility:hidden;\">\n \n </p>\n </div>\n </div>\n\n <script>\n var FEATURES = ",
|
|
25
|
+
";\n var STORAGE_KEY_URL = 'picked-launcher-url';\n var STORAGE_KEY_HISTORY = 'picked-launcher-history';\n var STORAGE_KEY_SELECTIONS = 'picked-launcher-selections';\n\n function getUrlInput() {\n return document.getElementById('url-input');\n }\n\n // URL history\n function getHistory() {\n try {\n var raw = localStorage.getItem(STORAGE_KEY_HISTORY);\n if (!raw) return [];\n var parsed = JSON.parse(raw);\n return Array.isArray(parsed) ? parsed : [];\n } catch (e) {\n return [];\n }\n }\n\n function saveHistory(history) {\n localStorage.setItem(STORAGE_KEY_HISTORY, JSON.stringify(history));\n }\n\n function addToHistory(url) {\n var history = getHistory().filter(function(h) { return h !== url; });\n history.unshift(url);\n if (history.length > 10) history = history.slice(0, 10);\n saveHistory(history);\n renderHistory();\n }\n\n function removeFromHistory(url) {\n var history = getHistory().filter(function(h) { return h !== url; });\n saveHistory(history);\n renderHistory();\n }\n\n function renderHistory() {\n var container = document.getElementById('url-history');\n if (!container) return;\n var history = getHistory();\n if (history.length === 0) {\n container.innerHTML = '';\n return;\n }\n container.innerHTML = history.map(function(url) {\n return '<div class=\"url-history-item\">' +\n '<button type=\"button\" class=\"url-link\" data-history-url=\"' + escapeAttr(url) + '\">' + escapeHtml(url) + '</button>' +\n '<button type=\"button\" class=\"url-delete\" data-history-delete=\"' + escapeAttr(url) + '\">x</button>' +\n '</div>';\n }).join('');\n }\n\n // Feature selection persistence\n function getSelections() {\n try {\n var raw = localStorage.getItem(STORAGE_KEY_SELECTIONS);\n if (!raw) return {};\n var parsed = JSON.parse(raw);\n return typeof parsed === 'object' && parsed !== null ? parsed : {};\n } catch (e) {\n return {};\n }\n }\n\n function saveSelections() {\n var selections = {};\n FEATURES.forEach(function(f) {\n var checkbox = document.querySelector('input[data-feature-id=\"' + f.id + '\"]');\n var select = document.querySelector('select[data-value-for=\"' + f.id + '\"]');\n if (checkbox && select) {\n selections[f.id] = { checked: checkbox.checked, value: select.value };\n }\n });\n localStorage.setItem(STORAGE_KEY_SELECTIONS, JSON.stringify(selections));\n }\n\n function restoreSelections() {\n var selections = getSelections();\n FEATURES.forEach(function(f) {\n var saved = selections[f.id];\n if (!saved) return;\n var checkbox = document.querySelector('input[data-feature-id=\"' + f.id + '\"]');\n var select = document.querySelector('select[data-value-for=\"' + f.id + '\"]');\n if (checkbox) checkbox.checked = saved.checked;\n if (select) select.value = saved.value;\n });\n }\n\n function escapeHtml(str) {\n var div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n }\n\n function escapeAttr(str) {\n return str.replace(/&/g, '&').replace(/\"/g, '"').replace(/</g, '<').replace(/>/g, '>');\n }\n\n function buildTargetUrl(inputValue) {\n var value = inputValue;\n if (!value.startsWith('http://') && !value.startsWith('https://')) {\n value = 'https://' + value;\n }\n var hostname = window.location.hostname;\n var subdomain = hostname.split('.').length > 2 ? hostname.split('.')[0] : '';\n var target = value;\n var sep = target.includes('?') ? '&' : '?';\n if (subdomain) {\n target = target + sep + 'cvly_env=' + encodeURIComponent(subdomain);\n sep = '&';\n }\n FEATURES.forEach(function(f) {\n var checkbox = document.querySelector('input[data-feature-id=\"' + f.id + '\"]');\n var select = document.querySelector('select[data-value-for=\"' + f.id + '\"]');\n if (checkbox && checkbox.checked && select) {\n target = target + sep + 'picked-feature=' + encodeURIComponent(f.id + ':' + select.value);\n sep = '&';\n }\n });\n return target;\n }\n\n function showCopyStatus(message, success) {\n var el = document.getElementById('copy-status');\n if (!el) return;\n el.textContent = message;\n el.style.visibility = 'visible';\n el.style.color = success ? '#2e7d32' : '#b71c1c';\n setTimeout(function() {\n el.style.visibility = 'hidden';\n }, 2000);\n }\n\n // Init\n window.addEventListener('load', function() {\n var input = getUrlInput();\n var savedUrl = localStorage.getItem(STORAGE_KEY_URL);\n if (savedUrl && input) {\n input.value = savedUrl;\n }\n renderHistory();\n restoreSelections();\n });\n\n // Delegate click events\n document.addEventListener('click', function(e) {\n var target = e.target;\n\n // History URL click\n var historyUrl = target.getAttribute('data-history-url');\n if (historyUrl) {\n var input = getUrlInput();\n if (input) input.value = historyUrl;\n return;\n }\n\n // History delete click\n var deleteUrl = target.getAttribute('data-history-delete');\n if (deleteUrl) {\n removeFromHistory(deleteUrl);\n return;\n }\n });\n\n // Feature change persistence\n document.addEventListener('change', function(e) {\n var target = e.target;\n if (target.getAttribute('data-feature-id') || target.getAttribute('data-value-for')) {\n saveSelections();\n }\n });\n\n // Copy button\n document.getElementById('copy-btn').addEventListener('click', function() {\n var input = getUrlInput();\n if (!input || !input.value) return;\n localStorage.setItem(STORAGE_KEY_URL, input.value);\n addToHistory(input.value);\n saveSelections();\n var target = buildTargetUrl(input.value);\n navigator.clipboard.writeText(target).then(function() {\n showCopyStatus('Preview URL copied to clipboard', true);\n });\n });\n\n // Preview button\n document.getElementById('preview-btn').addEventListener('click', function() {\n var input = getUrlInput();\n if (!input || !input.value) return;\n localStorage.setItem(STORAGE_KEY_URL, input.value);\n addToHistory(input.value);\n saveSelections();\n var target = buildTargetUrl(input.value);\n window.location.href = target;\n });\n <\/script>\n</main>\n</body>\n</html>"
|
|
26
|
+
], [
|
|
27
|
+
"<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <meta name=\"robots\" content=\"noindex, nofollow\">\n <title>Picked</title>\n <style>\n main {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n display: grid;\n align-items: center;\n justify-content: center;\n font-family: monospace;\n color: #4A4A4A\n }\n\n .wrap {\n padding-left: 1.5rem;\n padding-right: 1.5rem;\n max-width: 480px;\n width: 100%;\n }\n\n .title {\n font-size: 1.125rem;\n font-weight: 700;\n margin-bottom: 0;\n }\n\n .text {\n margin-top: .5rem;\n font-size: .875rem\n }\n\n .text a {\n color: #4A4A4A;\n text-decoration: none;\n }\n\n .text a:hover {\n cursor: pointer;\n text-decoration: underline\n }\n\n .preview-form {\n margin-top: 2rem;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n }\n\n .preview-input {\n padding: 0.5rem;\n border: 1px solid #4A4A4A;\n border-radius: 0;\n font-family: monospace;\n }\n\n .preview-button {\n padding: 0.5rem;\n background: #4A4A4A;\n color: white;\n border: none;\n border-radius: 0;\n cursor: pointer;\n font-family: monospace;\n }\n\n .preview-button:hover {\n opacity: 0.9;\n }\n\n .buttons {\n display: grid;\n gap: 0.5em;\n grid-template-columns: 1fr 1fr;\n }\n\n #copy-status {\n font-size: 1em;\n text-align: right;\n margin-top: 0.5em;\n }\n\n .features-section {\n margin-top: 1.5rem;\n }\n\n .features-label {\n font-weight: 700;\n font-size: .875rem;\n margin-bottom: 0.5rem;\n }\n\n .feature-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.5rem;\n padding: 0.25rem 0;\n }\n\n .feature-row label {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n min-width: 0;\n flex: 1;\n }\n\n .feature-name {\n font-size: .875rem;\n }\n\n .feature-id {\n font-size: .75rem;\n color: #888;\n }\n\n .feature-row select {\n font-family: monospace;\n font-size: .75rem;\n padding: 0.125rem 0.25rem;\n border: 1px solid #4A4A4A;\n border-radius: 0;\n background: white;\n flex-shrink: 0;\n }\n\n .no-features {\n color: #888;\n font-style: italic;\n }\n\n .url-history {\n margin-top: 0.5rem;\n font-size: .75rem;\n }\n\n .url-history-item {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0.125rem 0;\n }\n\n .url-history-item button {\n background: none;\n border: none;\n cursor: pointer;\n font-family: monospace;\n font-size: .75rem;\n color: #888;\n padding: 0;\n }\n\n .url-history-item button.url-link {\n color: #4A4A4A;\n text-decoration: none;\n text-align: left;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n min-width: 0;\n }\n\n .url-history-item button.url-link:hover {\n text-decoration: underline;\n }\n\n .url-history-item button.url-delete:hover {\n color: #b71c1c;\n }\n\n @media (min-width: 640px) {\n .title {\n font-size: 1.25rem\n }\n\n .text {\n font-size: 1rem\n }\n }\n </style>\n</head>\n<body>\n\n<main>\n <div class=\"wrap\">\n <p class=\"title\">Picked</p>\n <p class=\"text\">\n Learn more at\n <a href=\"https://picked.app\">\n https://picked.app\n </a>\n </p>\n <div class=\"preview-form\">\n <input type=\"text\" id=\"url-input\" pattern=\"^(https?:\\/\\/)?.+\" placeholder=\"Enter preview URL\" required\n class=\"preview-input\">\n <div id=\"url-history\" class=\"url-history\"></div>\n <div class=\"features-section\">\n <p class=\"features-label\">Features</p>\n ",
|
|
28
|
+
"\n </div>\n <div class=\"buttons\">\n <button type=\"button\" class=\"preview-button\" id=\"copy-btn\">Copy</button>\n <button type=\"button\" class=\"preview-button\" id=\"preview-btn\">Preview</button>\n </div>\n <p class=\"text\" id=\"copy-status\" aria-live=\"polite\" style=\"visibility:hidden;\">\n \n </p>\n </div>\n </div>\n\n <script>\n var FEATURES = ",
|
|
29
|
+
";\n var STORAGE_KEY_URL = 'picked-launcher-url';\n var STORAGE_KEY_HISTORY = 'picked-launcher-history';\n var STORAGE_KEY_SELECTIONS = 'picked-launcher-selections';\n\n function getUrlInput() {\n return document.getElementById('url-input');\n }\n\n // URL history\n function getHistory() {\n try {\n var raw = localStorage.getItem(STORAGE_KEY_HISTORY);\n if (!raw) return [];\n var parsed = JSON.parse(raw);\n return Array.isArray(parsed) ? parsed : [];\n } catch (e) {\n return [];\n }\n }\n\n function saveHistory(history) {\n localStorage.setItem(STORAGE_KEY_HISTORY, JSON.stringify(history));\n }\n\n function addToHistory(url) {\n var history = getHistory().filter(function(h) { return h !== url; });\n history.unshift(url);\n if (history.length > 10) history = history.slice(0, 10);\n saveHistory(history);\n renderHistory();\n }\n\n function removeFromHistory(url) {\n var history = getHistory().filter(function(h) { return h !== url; });\n saveHistory(history);\n renderHistory();\n }\n\n function renderHistory() {\n var container = document.getElementById('url-history');\n if (!container) return;\n var history = getHistory();\n if (history.length === 0) {\n container.innerHTML = '';\n return;\n }\n container.innerHTML = history.map(function(url) {\n return '<div class=\"url-history-item\">' +\n '<button type=\"button\" class=\"url-link\" data-history-url=\"' + escapeAttr(url) + '\">' + escapeHtml(url) + '</button>' +\n '<button type=\"button\" class=\"url-delete\" data-history-delete=\"' + escapeAttr(url) + '\">x</button>' +\n '</div>';\n }).join('');\n }\n\n // Feature selection persistence\n function getSelections() {\n try {\n var raw = localStorage.getItem(STORAGE_KEY_SELECTIONS);\n if (!raw) return {};\n var parsed = JSON.parse(raw);\n return typeof parsed === 'object' && parsed !== null ? parsed : {};\n } catch (e) {\n return {};\n }\n }\n\n function saveSelections() {\n var selections = {};\n FEATURES.forEach(function(f) {\n var checkbox = document.querySelector('input[data-feature-id=\"' + f.id + '\"]');\n var select = document.querySelector('select[data-value-for=\"' + f.id + '\"]');\n if (checkbox && select) {\n selections[f.id] = { checked: checkbox.checked, value: select.value };\n }\n });\n localStorage.setItem(STORAGE_KEY_SELECTIONS, JSON.stringify(selections));\n }\n\n function restoreSelections() {\n var selections = getSelections();\n FEATURES.forEach(function(f) {\n var saved = selections[f.id];\n if (!saved) return;\n var checkbox = document.querySelector('input[data-feature-id=\"' + f.id + '\"]');\n var select = document.querySelector('select[data-value-for=\"' + f.id + '\"]');\n if (checkbox) checkbox.checked = saved.checked;\n if (select) select.value = saved.value;\n });\n }\n\n function escapeHtml(str) {\n var div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n }\n\n function escapeAttr(str) {\n return str.replace(/&/g, '&').replace(/\"/g, '"').replace(/</g, '<').replace(/>/g, '>');\n }\n\n function buildTargetUrl(inputValue) {\n var value = inputValue;\n if (!value.startsWith('http://') && !value.startsWith('https://')) {\n value = 'https://' + value;\n }\n var hostname = window.location.hostname;\n var subdomain = hostname.split('.').length > 2 ? hostname.split('.')[0] : '';\n var target = value;\n var sep = target.includes('?') ? '&' : '?';\n if (subdomain) {\n target = target + sep + 'cvly_env=' + encodeURIComponent(subdomain);\n sep = '&';\n }\n FEATURES.forEach(function(f) {\n var checkbox = document.querySelector('input[data-feature-id=\"' + f.id + '\"]');\n var select = document.querySelector('select[data-value-for=\"' + f.id + '\"]');\n if (checkbox && checkbox.checked && select) {\n target = target + sep + 'picked-feature=' + encodeURIComponent(f.id + ':' + select.value);\n sep = '&';\n }\n });\n return target;\n }\n\n function showCopyStatus(message, success) {\n var el = document.getElementById('copy-status');\n if (!el) return;\n el.textContent = message;\n el.style.visibility = 'visible';\n el.style.color = success ? '#2e7d32' : '#b71c1c';\n setTimeout(function() {\n el.style.visibility = 'hidden';\n }, 2000);\n }\n\n // Init\n window.addEventListener('load', function() {\n var input = getUrlInput();\n var savedUrl = localStorage.getItem(STORAGE_KEY_URL);\n if (savedUrl && input) {\n input.value = savedUrl;\n }\n renderHistory();\n restoreSelections();\n });\n\n // Delegate click events\n document.addEventListener('click', function(e) {\n var target = e.target;\n\n // History URL click\n var historyUrl = target.getAttribute('data-history-url');\n if (historyUrl) {\n var input = getUrlInput();\n if (input) input.value = historyUrl;\n return;\n }\n\n // History delete click\n var deleteUrl = target.getAttribute('data-history-delete');\n if (deleteUrl) {\n removeFromHistory(deleteUrl);\n return;\n }\n });\n\n // Feature change persistence\n document.addEventListener('change', function(e) {\n var target = e.target;\n if (target.getAttribute('data-feature-id') || target.getAttribute('data-value-for')) {\n saveSelections();\n }\n });\n\n // Copy button\n document.getElementById('copy-btn').addEventListener('click', function() {\n var input = getUrlInput();\n if (!input || !input.value) return;\n localStorage.setItem(STORAGE_KEY_URL, input.value);\n addToHistory(input.value);\n saveSelections();\n var target = buildTargetUrl(input.value);\n navigator.clipboard.writeText(target).then(function() {\n showCopyStatus('Preview URL copied to clipboard', true);\n });\n });\n\n // Preview button\n document.getElementById('preview-btn').addEventListener('click', function() {\n var input = getUrlInput();\n if (!input || !input.value) return;\n localStorage.setItem(STORAGE_KEY_URL, input.value);\n addToHistory(input.value);\n saveSelections();\n var target = buildTargetUrl(input.value);\n window.location.href = target;\n });\n <\/script>\n</main>\n</body>\n</html>"
|
|
30
|
+
]), i, t);
|
|
31
|
+
}
|
|
32
|
+
function a(e) {
|
|
33
|
+
return e.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """);
|
|
34
|
+
}
|
|
35
|
+
function o(e) {
|
|
36
|
+
return e.replaceAll("&", "&").replaceAll("\"", """).replaceAll("<", "<").replaceAll(">", ">");
|
|
37
|
+
}
|
|
38
|
+
//#endregion
|
|
39
|
+
//#region src/log.ts
|
|
40
|
+
var s = "picked", c = "\x1B[0m";
|
|
41
|
+
function l() {
|
|
42
|
+
let e = process.env.NO_COLOR;
|
|
43
|
+
return e === "1" || e === "true";
|
|
44
|
+
}
|
|
45
|
+
function u(e) {
|
|
46
|
+
return (t) => l() ? t : `${e}${t}${c}`;
|
|
47
|
+
}
|
|
48
|
+
var d = [
|
|
49
|
+
"debug",
|
|
50
|
+
"info",
|
|
51
|
+
"warn",
|
|
52
|
+
"error",
|
|
53
|
+
"silent"
|
|
54
|
+
], f = {
|
|
55
|
+
debug: {
|
|
56
|
+
color: u("\x1B[2m"),
|
|
57
|
+
log: console.debug,
|
|
58
|
+
enabled: !1
|
|
59
|
+
},
|
|
60
|
+
info: {
|
|
61
|
+
color: u("\x1B[36m"),
|
|
62
|
+
log: console.log,
|
|
63
|
+
enabled: !0
|
|
64
|
+
},
|
|
65
|
+
warn: {
|
|
66
|
+
color: u("\x1B[33m"),
|
|
67
|
+
log: console.warn,
|
|
68
|
+
enabled: !0
|
|
69
|
+
},
|
|
70
|
+
error: {
|
|
71
|
+
color: u("\x1B[31m"),
|
|
72
|
+
log: console.error,
|
|
73
|
+
enabled: !0
|
|
74
|
+
},
|
|
75
|
+
silent: {
|
|
76
|
+
log: () => {},
|
|
77
|
+
enabled: !1
|
|
78
|
+
}
|
|
906
79
|
};
|
|
907
|
-
function
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
console.log(e.join(`
|
|
950
|
-
`));
|
|
951
|
-
}
|
|
952
|
-
const l = {
|
|
953
|
-
banner: Y,
|
|
954
|
-
debug: p("debug"),
|
|
955
|
-
info: p("info"),
|
|
956
|
-
warn: p("warn"),
|
|
957
|
-
error: p("error"),
|
|
958
|
-
setLevel: C
|
|
80
|
+
function p(e, t) {
|
|
81
|
+
return `${(/* @__PURE__ */ new Date()).toLocaleTimeString()} [${t ? `${s}:${t}` : s}] ${e}`;
|
|
82
|
+
}
|
|
83
|
+
function m(e, t, n, r) {
|
|
84
|
+
if (!e.enabled) return;
|
|
85
|
+
let i = p(t, r);
|
|
86
|
+
e.log(e.color ? e.color(i) : i), n !== void 0 && e.log(n);
|
|
87
|
+
}
|
|
88
|
+
function h(e) {
|
|
89
|
+
let t = f[e], n = /* @__PURE__ */ new Set();
|
|
90
|
+
return Object.assign((e, n, r) => {
|
|
91
|
+
m(t, e, n, r);
|
|
92
|
+
}, { once(e, r, i) {
|
|
93
|
+
!t.enabled || n.has(e) || (n.add(e), m(t, e, r, i));
|
|
94
|
+
} });
|
|
95
|
+
}
|
|
96
|
+
function g(e) {
|
|
97
|
+
let t = d.indexOf(e);
|
|
98
|
+
if (t === -1) {
|
|
99
|
+
m(f.error, `invalid log level: ${e}`);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
for (let [e, n] of d.entries()) f[n].enabled = e >= t;
|
|
103
|
+
}
|
|
104
|
+
var _ = u("\x1B[34m"), v = u("\x1B[36m");
|
|
105
|
+
function y() {
|
|
106
|
+
let e = [
|
|
107
|
+
` ${_("_")} ${v("_")} _ _ _`,
|
|
108
|
+
`${_("(_)")} ${v("(_)")} _ __(_)__| |_____ __| |`,
|
|
109
|
+
` ${_("_")} ${_("_")} | '_ \\ / _| / / -_) _\` |`,
|
|
110
|
+
`${_("(_)")} ${_("(_)")} | .__/_\\__|_\\_\\___\\__,_|`,
|
|
111
|
+
" |_|\n "
|
|
112
|
+
];
|
|
113
|
+
console.log(e.join("\n"));
|
|
114
|
+
}
|
|
115
|
+
var b = {
|
|
116
|
+
banner: y,
|
|
117
|
+
debug: h("debug"),
|
|
118
|
+
info: h("info"),
|
|
119
|
+
warn: h("warn"),
|
|
120
|
+
error: h("error"),
|
|
121
|
+
setLevel: g
|
|
959
122
|
};
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
})
|
|
982
|
-
|
|
983
|
-
`))
|
|
984
|
-
}
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
return new Promise((t) => {
|
|
995
|
-
setTimeout(t, e);
|
|
996
|
-
});
|
|
997
|
-
}
|
|
998
|
-
async function N(e, t, r) {
|
|
999
|
-
const n = await g(e, t, { headers: r });
|
|
1000
|
-
if (n || !z(e))
|
|
1001
|
-
return n;
|
|
1002
|
-
for (let o = 1; o <= T; o++) {
|
|
1003
|
-
l.info(
|
|
1004
|
-
`local API not ready, retrying in ${(k / 1e3).toString()}s (${o.toString()}/${T.toString()})`
|
|
1005
|
-
), await P(k);
|
|
1006
|
-
const i = await g(e, t, { headers: r });
|
|
1007
|
-
if (i)
|
|
1008
|
-
return i;
|
|
1009
|
-
}
|
|
1010
|
-
return null;
|
|
1011
|
-
}
|
|
1012
|
-
function G() {
|
|
1013
|
-
return "0.0.50-next.2";
|
|
123
|
+
//#endregion
|
|
124
|
+
//#region src/middleware.ts
|
|
125
|
+
function x(e) {
|
|
126
|
+
return (t, n, r) => {
|
|
127
|
+
if (t.method !== "GET") {
|
|
128
|
+
r();
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
let i = (t.url ?? "").split("?")[0];
|
|
132
|
+
if (i !== "/" && i !== "/index.html") {
|
|
133
|
+
r();
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
let a = e();
|
|
137
|
+
n.setHeader("Content-Type", "text/html"), n.statusCode = 200, n.end(a);
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
//#endregion
|
|
141
|
+
//#region src/index.ts
|
|
142
|
+
function S(e) {
|
|
143
|
+
if (e.length === 0) return;
|
|
144
|
+
let t = Math.max(4, ...e.map((e) => e.name.length)), n = Math.max(2, ...e.map((e) => e.id.length)), r = ` ${"Name".padEnd(t)} ${"ID".padEnd(n)} Status Weight Ver`, i = ` ${"─".repeat(t)} ${"─".repeat(n)} ──────── ────── ───`, a = e.map((e) => {
|
|
145
|
+
let r = e.enabled ? "\x1B[32m enabled\x1B[0m" : "\x1B[2mdisabled\x1B[0m", i = `${e.weight.toString()}%`.padStart(6), a = `v${e.version.toString()}`;
|
|
146
|
+
return ` ${e.name.padEnd(t)} ${e.id.padEnd(n)} ${r} ${i} ${a}`;
|
|
147
|
+
});
|
|
148
|
+
console.log([
|
|
149
|
+
"",
|
|
150
|
+
" Features:",
|
|
151
|
+
"",
|
|
152
|
+
r,
|
|
153
|
+
i,
|
|
154
|
+
...a,
|
|
155
|
+
""
|
|
156
|
+
].join("\n"));
|
|
1014
157
|
}
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
l.banner(), l.info(`fetching project config for "${e.projectId}"`), t !== A && l.warn(`using custom API URL: ${t}`);
|
|
1023
|
-
const n = R("vite-plugin", G()), o = performance.now(), i = await N(t, e.projectId, n), a = (performance.now() - o).toFixed(0);
|
|
1024
|
-
if (!i) {
|
|
1025
|
-
l.warn(`failed to fetch project config for "${e.projectId}" (${a}ms)`);
|
|
1026
|
-
return;
|
|
1027
|
-
}
|
|
1028
|
-
r = i.features;
|
|
1029
|
-
const d = i.features.length, u = i.features.filter((U) => U.enabled).length, f = JSON.stringify(i).length;
|
|
1030
|
-
return l.info(
|
|
1031
|
-
`fetched ${d.toString()} features (${u.toString()} enabled) for "${e.projectId}" in ${a}ms`
|
|
1032
|
-
), F(i.features), l.debug(`config size: ${f.toString()} bytes`), {
|
|
1033
|
-
define: {
|
|
1034
|
-
[K]: JSON.stringify(i)
|
|
1035
|
-
}
|
|
1036
|
-
};
|
|
1037
|
-
},
|
|
1038
|
-
configureServer(n) {
|
|
1039
|
-
if (e.disableLauncher) return;
|
|
1040
|
-
n.middlewares.use(B(() => b(r)));
|
|
1041
|
-
const o = n.printUrls.bind(n);
|
|
1042
|
-
n.printUrls = () => {
|
|
1043
|
-
const i = n.resolvedUrls?.local[0];
|
|
1044
|
-
if (i) {
|
|
1045
|
-
const a = i.replace(
|
|
1046
|
-
/:(?<port>\d+)\//,
|
|
1047
|
-
(d, u) => `:\x1B[1m${u}\x1B[22m/`
|
|
1048
|
-
);
|
|
1049
|
-
console.log(` \x1B[32m➜\x1B[0m \x1B[1mPicked\x1B[22m: \x1B[36m${a}\x1B[0m`);
|
|
1050
|
-
}
|
|
1051
|
-
o();
|
|
1052
|
-
};
|
|
1053
|
-
},
|
|
1054
|
-
generateBundle() {
|
|
1055
|
-
e.disableLauncher || this.emitFile({
|
|
1056
|
-
type: "asset",
|
|
1057
|
-
fileName: "index.html",
|
|
1058
|
-
source: b(r)
|
|
1059
|
-
});
|
|
1060
|
-
}
|
|
1061
|
-
};
|
|
158
|
+
function C(e) {
|
|
159
|
+
try {
|
|
160
|
+
let t = new URL(e).hostname;
|
|
161
|
+
return t === "localhost" || t === "127.0.0.1" || t === "::1";
|
|
162
|
+
} catch {
|
|
163
|
+
return !1;
|
|
164
|
+
}
|
|
1062
165
|
}
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
166
|
+
function w(e) {
|
|
167
|
+
return new Promise((t) => {
|
|
168
|
+
setTimeout(t, e);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
async function T(e, n, r) {
|
|
172
|
+
let i = await t(e, n, { headers: r });
|
|
173
|
+
if (i || !C(e)) return i;
|
|
174
|
+
for (let i = 1; i <= k; i++) {
|
|
175
|
+
b.info(`local API not ready, retrying in ${(A / 1e3).toString()}s (${i.toString()}/${k.toString()})`), await w(A);
|
|
176
|
+
let a = await t(e, n, { headers: r });
|
|
177
|
+
if (a) return a;
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
function E() {
|
|
182
|
+
return "0.0.50-next.4";
|
|
183
|
+
}
|
|
184
|
+
var D = "https://api.picked.app", O = "__PICKED_PROJECT_CONFIG__", k = 5, A = 2e3;
|
|
185
|
+
function j(t) {
|
|
186
|
+
let n = t.apiUrl ?? D, r = [];
|
|
187
|
+
return {
|
|
188
|
+
name: "picked",
|
|
189
|
+
config: async () => {
|
|
190
|
+
b.banner(), b.info(`fetching project config for "${t.projectId}"`), n !== D && b.warn(`using custom API URL: ${n}`);
|
|
191
|
+
let i = e("vite-plugin", E()), a = performance.now(), o = await T(n, t.projectId, i), s = (performance.now() - a).toFixed(0);
|
|
192
|
+
if (!o) {
|
|
193
|
+
b.warn(`failed to fetch project config for "${t.projectId}" (${s}ms)`);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
r = o.features;
|
|
197
|
+
let c = o.features.length, l = o.features.filter((e) => e.enabled).length, u = JSON.stringify(o).length;
|
|
198
|
+
return b.info(`fetched ${c.toString()} features (${l.toString()} enabled) for "${t.projectId}" in ${s}ms`), S(o.features), b.debug(`config size: ${u.toString()} bytes`), { define: { [O]: JSON.stringify(o) } };
|
|
199
|
+
},
|
|
200
|
+
configureServer(e) {
|
|
201
|
+
if (t.disableLauncher) return;
|
|
202
|
+
e.middlewares.use(x(() => i(r)));
|
|
203
|
+
let n = e.printUrls.bind(e);
|
|
204
|
+
e.printUrls = () => {
|
|
205
|
+
let t = e.resolvedUrls?.local[0];
|
|
206
|
+
if (t) {
|
|
207
|
+
let e = t.replace(/:(?<port>\d+)\//, (e, t) => `:\x1b[1m${t}\x1b[22m/`);
|
|
208
|
+
console.log(` \x1b[32m➜\x1b[0m \x1b[1mPicked\x1b[22m: \x1b[36m${e}\x1b[0m`);
|
|
209
|
+
}
|
|
210
|
+
n();
|
|
211
|
+
};
|
|
212
|
+
},
|
|
213
|
+
generateBundle() {
|
|
214
|
+
t.disableLauncher || this.emitFile({
|
|
215
|
+
type: "asset",
|
|
216
|
+
fileName: "index.html",
|
|
217
|
+
source: i(r)
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
//#endregion
|
|
223
|
+
export { j as picked };
|