6const { useState, useRef, useEffect } = React;
7
8function compressImage(file, maxWidth = 800, maxHeight = 800, quality = 0.7) {
9 return new Promise((resolve, reject) => {
10 const reader = new FileReader();
11 reader.readAsDataURL(file);
12 reader.onload = (event) => {
13 const img = new Image();
14 img.src = event.target.result as string;
15 img.onload = () => {
35
36 const ctx = canvas.getContext('2d');
37 ctx.drawImage(img, 0, 0, width, height);
38
39 // Convert to base64 with compression
40 const compressedImage = canvas.toDataURL('image/jpeg', quality);
41 resolve(compressedImage);
42 };
43 img.onerror = reject;
54 if (file) {
55 try {
56 const compressedImage = await compressImage(file);
57 onPhotoUpload(compressedImage);
58 } catch (error) {
59 console.error("Photo upload failed", error);
68 ref={fileInputRef}
69 onChange={handleFileChange}
70 accept="image/*"
71 style={{ display: 'none' }}
72 />
24 const price = $(el).find('.woocommerce-Price-amount').text().trim();
25 const link = $(el).find('h4 a').attr('href');
26 const images = $(el).find('img').map((i, img) => $(img).attr('src')).get();
27
28 return {
30 price,
31 link,
32 images: images.slice(0, 2), // Capture first two images (visible and hidden)
33 categories: $(el).attr('class')
34 .split(' ')
60๐ Link: ${product.link}
61๐ Categories: ${product.categories.join(', ')}
62๐ผ๏ธ Images: ${product.images.length} found
63${stockEmoji} Stock Status: ${product.inStock ? 'Available' : 'Out of Stock'}
64---`.trim();
24 const price = $(el).find('.woocommerce-Price-amount').text().trim();
25 const link = $(el).find('h4 a').attr('href');
26 const images = $(el).find('img').map((i, img) => $(img).attr('src')).get();
27
28 return {
30 price,
31 link,
32 images: images.slice(0, 2), // Capture first two images (visible and hidden)
33 categories: $(el).attr('class')
34 .split(' ')
60๐ Link: ${product.link}
61๐ Categories: ${product.categories.join(', ')}
62๐ผ๏ธ Images: ${product.images.length} found
63${stockEmoji} Stock Status: ${product.inStock ? 'Available' : 'Out of Stock'}
64---`.trim();
3This is a lightweight Blob Admin interface to view and debug your Blob data.
4
5
6
7## Installation
498 <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
499 <meta name="description" content="Expoline 2025 Participant Registration Form">
500 <link rel="icon" type="image/png" href="https://maxm-imggenurl.web.val.run/Expoline-favicon">
501 <style>${css}</style>
502 </head>
36 </div>
37 <div class="illustration">
38 <img src="https://wsrv.nl/?output=webp&url=https%3A%2F%2Fmaxm-imggenurl.web.val.run%2Fa%20dark%20minimalist%20landscape%20with%20a%20floating%20island%2C%20cat-like%20character%20with%20a%20magnifying%20glass%2C%20soft%20purple%20and%20teal%20colors%2C%20night%20scene%20with%20glowing%20orb" alt="Repo Search Illustration" class="scene-image">
39 </div>
40 </div>
150}
151
152.scene-image {
153 width: 100%;
154 height: auto;
200app.get('/styles.css', serve(css, 'text/css'));
201app.get('/main.js', serve(js, 'text/javascript'));
202app.get('/favicon.svg', serve(favicon, 'image/svg+xml'));
203
204export default app.fetch;
10* Create a [Val Town API token](https://www.val.town/settings/api), open the browser preview of this val, and use the API token as the password to log in.
11
12<img width=500 src="https://imagedelivery.net/iHX6Ovru0O7AjmyT5yZRoA/7077d1b5-1fa7-4a9b-4b93-f8d01d3e4f00/public"/>
10 savePDFIsVisible,
11 isOceanTheme,
12 ogImageUrl,
13 customTitle
14}) {
41 const name = resumeDetails?.basics?.name || 'Resume';
42 const title = customTitle || `${name}'s Resume`;
43 const ogImage = ogImageUrl ? `<meta property="og:image" content="${ogImageUrl}">` : '';
44
45 return `
52 <meta property="og:title" content="${title}">
53 <meta property="og:type" content="website">
54 ${ogImage}
55 <link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text y='50%' font-size='24' text-anchor='middle' x='50%' dy='.3em'>๐</text></svg>">
56 <style>
57 ${theme.styles}
318 right: 0;
319 bottom: 0;
320 background-image: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ffffff' fill-opacity='0.05'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
321 opacity: 0.1;
322 pointer-events: none;
119
120 // Capture current video frame
121 context.drawImage(video, 0, 0, canvas.width, canvas.height);
122
123 // Add timestamp
137
138 // Convert canvas to data URL with reduced quality
139 const photoDataUrl = canvas.toDataURL('image/jpeg', 0.5);
140 setPhotoData(photoDataUrl);
141 setErrorMessage('Photo captured successfully!');