PageSourceSearch

https://picbloom.ai/js/script.js?v=12

js picbloom.ai collected 2026-10-05 12:25:30 UTC 3,173 bytes, 110 lines download raw bytes

1(function () {
2  const body = document.body;
3  const burger = document.querySelector('[data-burger]');
4  const nav = document.querySelector('[data-nav]');
5  const toast = document.querySelector('[data-toast]');
6  const uploadLinks = document.querySelectorAll('[data-upload-link]');
7  const revealItems = document.querySelectorAll('.reveal');
8
9  function closeMenu() {
10    body.classList.remove('nav-open');
11    if (burger) burger.setAttribute('aria-expanded', 'false');
12  }
13
14  function showToast(message) {
15    if (!toast) return;
16    toast.textContent = message;
17    toast.classList.add('is-visible');
18    window.clearTimeout(showToast.timer);
19    showToast.timer = window.setTimeout(() => {
20      toast.classList.remove('is-visible');
21    }, 3200);
22  }
23
24  if (burger) {
25    burger.addEventListener('click', () => {
26      const isOpen = body.classList.toggle('nav-open');
27      burger.setAttribute('aria-expanded', String(isOpen));
28    });
29  }
30
31  if (nav) {
32    nav.addEventListener('click', (event) => {
33      if (event.target.closest('a')) closeMenu();
34    });
35  }
36
37  const cards = document.querySelectorAll('.template-card');
38
39  if (cards.length > 0) {
40    cards.forEach(card => {
41      card.addEventListener('click', () => {
42        window.location.href = '/app';
43      });
44    });
45  }
46
47  document.addEventListener('click', (event) => {
48    const shot = event.target.closest('.shot');
49
50    if (!shot) return;
51
52    window.location.href = '/app';
53  });
54
55  const accordion = document.querySelector('[data-accordion]');
56  if (accordion) {
57    accordion.addEventListener('click', (event) => {
58      const button = event.target.closest('button');
59      if (!button) return;
60
61      const item = button.closest('.faq-item');
62      const body = item ? item.querySelector('.faq-item__body') : null;
63      const isOpen = button.getAttribute('aria-expanded') === 'true';
64
65      button.setAttribute('aria-expanded', String(!isOpen));
66      if (body) body.hidden = isOpen;
67    });
68  }
69
70  if ('IntersectionObserver' in window) {
71    const observer = new IntersectionObserver((entries) => {
72      entries.forEach((entry) => {
73        if (entry.isIntersecting) {
74          entry.target.classList.add('is-visible');
75          observer.unobserve(entry.target);
76        }
77      });
78    }, { threshold: 0.12 });
79
80    revealItems.forEach((item) => observer.observe(item));
81  } else {
82    revealItems.forEach((item) => item.classList.add('is-visible'));
83  }
84
85  document.addEventListener('keydown', (event) => {
86    if (event.key === 'Escape') closeMenu();
87  });
88}());
89
90(() => {
91  const timers = new WeakMap();
92
93  window.PicBloomToast = (message, type = 'info', timeout = 3200) => {
94    const toast = document.querySelector('[data-app-toast], [data-history-toast], [data-toast]');
95    if (!toast) return;
96
97    toast.textContent = String(message || '');
98    toast.dataset.type = type;
99    toast.classList.add('is-visible');
100
101    const previous = timers.get(toast);
102    if (previous) window.clearTimeout(previous);
103
104    const timer = window.setTimeout(() => {
105      toast.classList.remove('is-visible');
106      delete toast.dataset.type;
107    }, timeout);
108    timers.set(toast, timer);
109  };
110})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.