@scalemule/news-publication 0.0.48 → 0.0.49

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.
Files changed (72) hide show
  1. package/README.md +28 -0
  2. package/dist/{chunk-GB36YM56.js → chunk-2MEYHM7M.js} +11 -1
  3. package/dist/chunk-4JRWZXAP.js +62 -0
  4. package/dist/chunk-MBBPEFDA.js +124 -0
  5. package/dist/chunk-TTLM7YOH.js +444 -0
  6. package/dist/chunk-ZXH3O537.js +251 -0
  7. package/dist/community-maps-view.d.cts +3 -3
  8. package/dist/community-maps-view.d.ts +3 -3
  9. package/dist/cookie-consent-banner.d.cts +2 -2
  10. package/dist/cookie-consent-banner.d.ts +2 -2
  11. package/dist/cookie-settings-view.d.cts +2 -2
  12. package/dist/cookie-settings-view.d.ts +2 -2
  13. package/dist/index.cjs +29 -1
  14. package/dist/index.d.cts +4 -3
  15. package/dist/index.d.ts +4 -3
  16. package/dist/index.js +4 -3
  17. package/dist/marketplace-forms.d.cts +3 -3
  18. package/dist/marketplace-forms.d.ts +3 -3
  19. package/dist/marketplace-view.d.cts +5 -5
  20. package/dist/marketplace-view.d.ts +5 -5
  21. package/dist/{meet-RWmfj3I3.d.cts → meet-BWpxY20X.d.ts} +5 -0
  22. package/dist/{meet-RWmfj3I3.d.ts → meet-CO9Unz5M.d.cts} +5 -0
  23. package/dist/meet-forms.d.cts +7 -6
  24. package/dist/meet-forms.d.ts +7 -6
  25. package/dist/meet-forms.js +2 -1
  26. package/dist/meet-view.cjs +22 -2
  27. package/dist/meet-view.d.cts +7 -5
  28. package/dist/meet-view.d.ts +7 -5
  29. package/dist/meet-view.js +21 -4
  30. package/dist/network-bar.d.cts +2 -2
  31. package/dist/network-bar.d.ts +2 -2
  32. package/dist/network-copyright.d.cts +2 -2
  33. package/dist/network-copyright.d.ts +2 -2
  34. package/dist/pets-auth-server.cjs +212 -0
  35. package/dist/pets-auth-server.d.cts +17 -0
  36. package/dist/pets-auth-server.d.ts +17 -0
  37. package/dist/pets-auth-server.js +155 -0
  38. package/dist/pets-forms.cjs +762 -0
  39. package/dist/pets-forms.d.cts +26 -0
  40. package/dist/pets-forms.d.ts +26 -0
  41. package/dist/pets-forms.js +712 -0
  42. package/dist/pets-interactions.cjs +332 -0
  43. package/dist/pets-interactions.d.cts +20 -0
  44. package/dist/pets-interactions.d.ts +20 -0
  45. package/dist/pets-interactions.js +319 -0
  46. package/dist/pets-publication.cjs +818 -0
  47. package/dist/pets-publication.d.cts +36 -0
  48. package/dist/pets-publication.d.ts +36 -0
  49. package/dist/pets-publication.js +177 -0
  50. package/dist/pets-server.cjs +289 -0
  51. package/dist/pets-server.d.cts +42 -0
  52. package/dist/pets-server.d.ts +42 -0
  53. package/dist/pets-server.js +2 -0
  54. package/dist/pets-view.cjs +541 -0
  55. package/dist/pets-view.d.cts +56 -0
  56. package/dist/pets-view.d.ts +56 -0
  57. package/dist/pets-view.js +4 -0
  58. package/dist/pets.cjs +138 -0
  59. package/dist/pets.d.cts +127 -0
  60. package/dist/pets.d.ts +127 -0
  61. package/dist/pets.js +1 -0
  62. package/dist/sponsorship-view.d.cts +2 -2
  63. package/dist/sponsorship-view.d.ts +2 -2
  64. package/dist/sponsorship-view.js +2 -62
  65. package/dist/story-review.d.cts +6 -6
  66. package/dist/story-review.d.ts +6 -6
  67. package/dist/theme-toggle.d.cts +2 -2
  68. package/dist/theme-toggle.d.ts +2 -2
  69. package/dist/verified-card.d.cts +3 -3
  70. package/dist/verified-card.d.ts +3 -3
  71. package/package.json +40 -3
  72. package/pets.css +538 -0
@@ -0,0 +1,818 @@
1
+ 'use strict';
2
+
3
+ var sdk = require('@scalemule/sdk');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var react = require('react');
6
+
7
+ // src/pets-server.ts
8
+
9
+ // src/pets.ts
10
+ var PET_KINDS = [
11
+ "profile",
12
+ "spotlight",
13
+ "photo",
14
+ "celebration",
15
+ "lost",
16
+ "found",
17
+ "adoption",
18
+ "event"
19
+ ];
20
+ var PET_SAFETY = {
21
+ recovery: "Bay Area Paw does not independently verify pet ownership. A report is a contributor\u2019s account. Never send money or verification codes to someone claiming to have found a pet. Keep microchip numbers and ownership evidence private.",
22
+ adoption: "Contact the named shelter or rescue for current availability, eligibility and adoption arrangements. Bay Area Paw is not the adoption agency and does not collect adoption payments."};
23
+ var PET_UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
24
+ var PET_SLUG = /^[a-z0-9][a-z0-9-]{0,190}$/;
25
+ function petReferences(metadata) {
26
+ const entries = metadata && typeof metadata === "object" ? metadata.pet_resources : null;
27
+ if (!Array.isArray(entries)) return [];
28
+ return entries.slice(0, 12).flatMap((v) => {
29
+ if (!v || typeof v !== "object") return [];
30
+ const r = v;
31
+ return typeof r.collection_slug === "string" && PET_SLUG.test(r.collection_slug) && typeof r.id === "string" && PET_UUID.test(r.id) && PET_KINDS.includes(r.kind) ? [
32
+ {
33
+ collection_slug: r.collection_slug,
34
+ id: r.id,
35
+ kind: r.kind
36
+ }
37
+ ] : [];
38
+ });
39
+ }
40
+ function resolvePetCommunity(areas, selected, preference, publicationDefault) {
41
+ if (selected === "") return void 0;
42
+ for (const candidate of [selected, preference, publicationDefault]) {
43
+ const found = areas.find(
44
+ (area) => area.id === candidate || area.slug === candidate
45
+ );
46
+ if (found) return found;
47
+ }
48
+ return void 0;
49
+ }
50
+ function safePetLink(raw) {
51
+ if (raw.startsWith("/") && !raw.startsWith("//") && !/[\\\r\n]/.test(raw))
52
+ return raw;
53
+ try {
54
+ const url = new URL(raw);
55
+ return url.protocol === "https:" && !url.username && !url.password ? url.href : void 0;
56
+ } catch {
57
+ return void 0;
58
+ }
59
+ }
60
+ function adoptionAvailability(source, now = Date.now()) {
61
+ const at = source?.verified_at ? Date.parse(source.verified_at) : NaN;
62
+ return source?.availability_confirmed && Number.isFinite(at) && at <= now && now - at <= 864e5 ? "confirmed" : "check_with_organization";
63
+ }
64
+
65
+ // src/pets-server.ts
66
+ var PetRequestError = class extends Error {
67
+ constructor(status, message) {
68
+ super(message);
69
+ this.status = status;
70
+ }
71
+ status;
72
+ };
73
+ function config(scope) {
74
+ const url = new URL(scope.gatewayUrl);
75
+ if (!scope.apiKey || !PET_SLUG.test(scope.collectionSlug) || url.username || url.password || url.protocol !== "https:" && !(url.protocol === "http:" && ["localhost", "127.0.0.1"].includes(url.hostname)))
76
+ throw new PetRequestError(503, "The pet community is not available yet.");
77
+ return url.origin;
78
+ }
79
+ async function petRequest(scope, path, init = {}, fetcher = fetch) {
80
+ const gateway = config(scope);
81
+ if (!path.startsWith("/v1/") || path.includes("..") || /[\\\r\n]/.test(path))
82
+ throw new Error("Invalid platform path");
83
+ const response = await fetcher(gateway + path, {
84
+ method: init.method || "GET",
85
+ headers: {
86
+ ...sdk.buildClientContextHeaders(scope.clientContext),
87
+ "x-api-key": scope.apiKey,
88
+ "content-type": "application/json",
89
+ ...scope.accessToken ? { authorization: `Bearer ${scope.accessToken}` } : {}
90
+ },
91
+ body: init.body === void 0 ? void 0 : JSON.stringify(init.body),
92
+ cache: "no-store",
93
+ redirect: "error",
94
+ signal: AbortSignal.timeout(15e3)
95
+ });
96
+ if (!response.ok)
97
+ throw new PetRequestError(
98
+ response.status,
99
+ response.status === 401 ? "Please sign in to continue." : response.status === 404 ? "This pet resource is not available." : response.status === 409 ? "This contribution changed. Reload before saving." : response.status === 429 ? "Please wait before trying again." : "We couldn\u2019t complete that request. Please try again."
100
+ );
101
+ const json = await response.json();
102
+ return json?.data ?? json;
103
+ }
104
+ async function resolvePetReferences(scope, metadata, fetcher = fetch) {
105
+ const references = petReferences(metadata).filter(
106
+ (ref) => ref.collection_slug === scope.collectionSlug
107
+ );
108
+ const results = await Promise.all(
109
+ references.map(async (ref) => {
110
+ try {
111
+ const resource = await petRequest(
112
+ { ...scope, accessToken: void 0 },
113
+ `/v1/knowledge/community-maps/collections/${ref.collection_slug}/pets/${ref.id}`,
114
+ {},
115
+ fetcher
116
+ );
117
+ return resource.kind === ref.kind ? resource : null;
118
+ } catch (error) {
119
+ if (error instanceof PetRequestError && [403, 404].includes(error.status))
120
+ return null;
121
+ throw error;
122
+ }
123
+ })
124
+ );
125
+ return results.filter(
126
+ (resource) => resource !== null
127
+ );
128
+ }
129
+ async function petAcknowledgments(scope, community, productPath = "/pets", fetcher = fetch) {
130
+ if (!scope.publicationId || !PET_UUID.test(scope.publicationId)) return [];
131
+ try {
132
+ const groups = await Promise.all(
133
+ ["community_partner", "community_guide"].map(
134
+ async (placement) => {
135
+ const query = new URLSearchParams({
136
+ placement_type: placement,
137
+ product_path: productPath
138
+ });
139
+ if (community) query.set("community", community);
140
+ const response = await petRequest(
141
+ { ...scope, accessToken: void 0 },
142
+ `/v1/blog/publications/${scope.publicationId}/sponsorships/delivery?${query}`,
143
+ {},
144
+ fetcher
145
+ );
146
+ return response.items.filter(
147
+ (item) => item.publication_id === scope.publicationId && item.placement_type === placement
148
+ );
149
+ }
150
+ )
151
+ );
152
+ return groups.flat().slice(0, 2);
153
+ } catch {
154
+ console.warn("paw.sponsorship_delivery_unavailable");
155
+ return [];
156
+ }
157
+ }
158
+
159
+ // src/sponsorships.ts
160
+ function safeSponsorUrl(value) {
161
+ if (typeof value !== "string" || value.length > 2048) return void 0;
162
+ try {
163
+ const url = new URL(value);
164
+ if (url.protocol !== "https:" || url.username || url.password)
165
+ return void 0;
166
+ return url.toString();
167
+ } catch {
168
+ return void 0;
169
+ }
170
+ }
171
+ function SponsorAcknowledgment({
172
+ creative,
173
+ label = "Community Partner",
174
+ preview = false,
175
+ acknowledgment
176
+ }) {
177
+ const logo = safeSponsorUrl(creative.logo_url);
178
+ const destination = safeSponsorUrl(creative.destination_url);
179
+ return /* @__PURE__ */ jsxRuntime.jsxs(
180
+ "aside",
181
+ {
182
+ className: "sm-sponsorship",
183
+ "aria-label": `${label}: ${creative.name}`,
184
+ "data-sponsorship": preview ? void 0 : acknowledgment?.campaign_id,
185
+ "data-placement-id": preview ? void 0 : acknowledgment?.placement_id,
186
+ "data-publication-id": preview ? void 0 : acknowledgment?.publication_id,
187
+ "data-sponsor-id": preview ? void 0 : acknowledgment?.sponsor_id,
188
+ children: [
189
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sm-sponsorship-copy", children: [
190
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "sm-sponsorship-label", children: [
191
+ label,
192
+ preview ? " \xB7 Illustrative preview" : ""
193
+ ] }),
194
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "sm-sponsorship-name", children: creative.name }),
195
+ creative.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "sm-sponsorship-description", children: creative.description }),
196
+ destination && /* @__PURE__ */ jsxRuntime.jsxs(
197
+ "a",
198
+ {
199
+ href: destination,
200
+ rel: "sponsored noopener noreferrer",
201
+ referrerPolicy: "no-referrer",
202
+ "data-analytics-skip": "true",
203
+ children: [
204
+ creative.link_label || "Learn more",
205
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sm-sponsorship-sr", children: [
206
+ " about ",
207
+ creative.name
208
+ ] })
209
+ ]
210
+ }
211
+ )
212
+ ] }),
213
+ logo && /* @__PURE__ */ jsxRuntime.jsx(
214
+ "img",
215
+ {
216
+ src: logo,
217
+ alt: `${creative.name} logo`,
218
+ loading: "lazy",
219
+ decoding: "async",
220
+ referrerPolicy: "no-referrer",
221
+ className: "sm-sponsorship-logo"
222
+ }
223
+ )
224
+ ]
225
+ }
226
+ );
227
+ }
228
+ function PawMark({ size = 36 }) {
229
+ return /* @__PURE__ */ jsxRuntime.jsxs(
230
+ "svg",
231
+ {
232
+ width: size,
233
+ height: size,
234
+ viewBox: "0 0 48 48",
235
+ fill: "currentColor",
236
+ "aria-hidden": "true",
237
+ children: [
238
+ /* @__PURE__ */ jsxRuntime.jsx(
239
+ "ellipse",
240
+ {
241
+ cx: "10",
242
+ cy: "19",
243
+ rx: "5.1",
244
+ ry: "6.5",
245
+ transform: "rotate(-25 10 19)"
246
+ }
247
+ ),
248
+ /* @__PURE__ */ jsxRuntime.jsx("ellipse", { cx: "20", cy: "10", rx: "5", ry: "6.5", transform: "rotate(-8 20 10)" }),
249
+ /* @__PURE__ */ jsxRuntime.jsx("ellipse", { cx: "32", cy: "12", rx: "5", ry: "6.5", transform: "rotate(14 32 12)" }),
250
+ /* @__PURE__ */ jsxRuntime.jsx("ellipse", { cx: "40", cy: "23", rx: "4.7", ry: "6.2", transform: "rotate(30 40 23)" }),
251
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M11 35c0-5 7-16 13-16s14 11 14 16c0 6-6 9-11 6-2-1-4-1-6 0-5 3-10 0-10-6Z" })
252
+ ]
253
+ }
254
+ );
255
+ }
256
+ function Photo({
257
+ resource,
258
+ mediaUrl,
259
+ large = false
260
+ }) {
261
+ const photo = resource.media.find((m) => m.status === "PUBLISHED");
262
+ const src = photo && safePetLink(mediaUrl(resource.id, photo.id));
263
+ if (!src)
264
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "paw-photo-empty", children: [
265
+ /* @__PURE__ */ jsxRuntime.jsx(PawMark, { size: 64 }),
266
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "A story from your community" })
267
+ ] });
268
+ const separator = src.includes("?") ? "&" : "?";
269
+ return /* @__PURE__ */ jsxRuntime.jsxs("figure", { className: "paw-photo", children: [
270
+ /* @__PURE__ */ jsxRuntime.jsxs("picture", { children: [
271
+ /* @__PURE__ */ jsxRuntime.jsx(
272
+ "source",
273
+ {
274
+ type: "image/webp",
275
+ srcSet: `${src}${separator}width=640&format=webp 640w, ${src}${separator}width=1280&format=webp 1280w`,
276
+ sizes: large ? "(max-width: 700px) 100vw, 65vw" : "(max-width: 700px) 100vw, 33vw"
277
+ }
278
+ ),
279
+ /* @__PURE__ */ jsxRuntime.jsx(
280
+ "img",
281
+ {
282
+ src: `${src}${separator}width=1280&format=jpeg`,
283
+ srcSet: `${src}${separator}width=640&format=jpeg 640w, ${src}${separator}width=1280&format=jpeg 1280w`,
284
+ sizes: large ? "(max-width: 700px) 100vw, 65vw" : "(max-width: 700px) 100vw, 33vw",
285
+ alt: photo.caption || resource.content.name,
286
+ width: large ? 1200 : 640,
287
+ height: large ? 900 : 480,
288
+ loading: large ? "eager" : "lazy"
289
+ }
290
+ )
291
+ ] }),
292
+ photo.attribution && /* @__PURE__ */ jsxRuntime.jsxs("figcaption", { children: [
293
+ "Photograph: ",
294
+ photo.attribution
295
+ ] })
296
+ ] });
297
+ }
298
+ function ResourceCard(props) {
299
+ const href = safePetLink(props.href);
300
+ return /* @__PURE__ */ jsxRuntime.jsxs("article", { className: `paw-resource${props.memorial ? " paw-memorial" : ""}`, children: [
301
+ /* @__PURE__ */ jsxRuntime.jsx(Photo, { ...props }),
302
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "paw-resource-copy", children: [
303
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "paw-context", children: [
304
+ props.label,
305
+ " \xB7 ",
306
+ props.community
307
+ ] }),
308
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { children: href ? /* @__PURE__ */ jsxRuntime.jsx("a", { href, children: props.resource.content.name }) : props.resource.content.name }),
309
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: props.resource.content.story }),
310
+ props.resource.content.attribution && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "paw-credit", children: [
311
+ "Shared by ",
312
+ props.resource.content.attribution
313
+ ] })
314
+ ] })
315
+ ] });
316
+ }
317
+ function PetProfileCard(props) {
318
+ return /* @__PURE__ */ jsxRuntime.jsx(ResourceCard, { ...props, label: "Meet a neighbor" });
319
+ }
320
+ function PetCelebrationCard(props) {
321
+ return /* @__PURE__ */ jsxRuntime.jsx(
322
+ ResourceCard,
323
+ {
324
+ ...props,
325
+ memorial: props.resource.content.category === "memorial",
326
+ label: props.resource.content.category === "memorial" ? "In loving memory" : "A little joy worth sharing"
327
+ }
328
+ );
329
+ }
330
+ function LostPetNotice(props) {
331
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "paw-notice", children: [
332
+ /* @__PURE__ */ jsxRuntime.jsx(
333
+ ResourceCard,
334
+ {
335
+ ...props,
336
+ label: props.resource.reunited_at ? "Reported reunited" : props.resource.kind === "found" ? "Found pet" : "Lost pet"
337
+ }
338
+ ),
339
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "paw-safety", children: PET_SAFETY.recovery })
340
+ ] });
341
+ }
342
+ function AdoptionListingCard(props) {
343
+ const source = props.resource.content.source;
344
+ const url = source && safePetLink(source.official_url);
345
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
346
+ /* @__PURE__ */ jsxRuntime.jsx(ResourceCard, { ...props, label: "Adoption discovery" }),
347
+ source && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "paw-source", children: [
348
+ adoptionAvailability(source) === "confirmed" ? "Availability recently confirmed." : "Check current availability with the organization.",
349
+ " ",
350
+ url && /* @__PURE__ */ jsxRuntime.jsxs("a", { href: url, rel: "noopener noreferrer", children: [
351
+ "Visit ",
352
+ source.organization
353
+ ] }),
354
+ source.verified_at && /* @__PURE__ */ jsxRuntime.jsxs("small", { children: [
355
+ "Source checked",
356
+ " ",
357
+ new Date(source.verified_at).toLocaleDateString("en-US", {
358
+ timeZone: "America/Los_Angeles"
359
+ })
360
+ ] })
361
+ ] })
362
+ ] });
363
+ }
364
+ function PetEventCard(props) {
365
+ const event = props.resource.content.event, source = props.resource.content.source;
366
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
367
+ /* @__PURE__ */ jsxRuntime.jsx(ResourceCard, { ...props, label: "Pet community event" }),
368
+ event && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "paw-source", children: [
369
+ /* @__PURE__ */ jsxRuntime.jsx("time", { dateTime: event.starts_at, children: new Date(event.starts_at).toLocaleString("en-US", {
370
+ timeZone: "America/Los_Angeles",
371
+ dateStyle: "medium",
372
+ timeStyle: "short"
373
+ }) }),
374
+ " ",
375
+ "\xB7 Pacific time",
376
+ /* @__PURE__ */ jsxRuntime.jsx("br", {}),
377
+ event.cost_verified && event.cost === "free" ? "Verified free event" : event.cost_verified && event.cost === "paid" ? "Paid event \u2014 check official pricing" : "Check the official organization for cost"
378
+ ] }),
379
+ source && /* @__PURE__ */ jsxRuntime.jsx("p", { children: /* @__PURE__ */ jsxRuntime.jsxs("a", { href: safePetLink(source.official_url), rel: "noopener noreferrer", children: [
380
+ "Official details from ",
381
+ source.organization
382
+ ] }) })
383
+ ] });
384
+ }
385
+ function PawOfTheWeekCard(props) {
386
+ const href = safePetLink(props.href);
387
+ return /* @__PURE__ */ jsxRuntime.jsxs("article", { className: "paw-spotlight", children: [
388
+ /* @__PURE__ */ jsxRuntime.jsx(Photo, { ...props, large: true }),
389
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "paw-spotlight-copy", children: [
390
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "paw-context", children: [
391
+ props.community,
392
+ "\u2019s Paw of the Week"
393
+ ] }),
394
+ /* @__PURE__ */ jsxRuntime.jsxs("h2", { children: [
395
+ "Meet ",
396
+ props.resource.content.name,
397
+ "."
398
+ ] }),
399
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: props.resource.content.story }),
400
+ href && /* @__PURE__ */ jsxRuntime.jsx("a", { className: "paw-button", href, children: "Read the story" }),
401
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "paw-credit", children: "Chosen by our editors. Always free to submit." })
402
+ ] })
403
+ ] });
404
+ }
405
+ function SponsorAcknowledgment2({
406
+ acknowledgment,
407
+ now = Date.now()
408
+ }) {
409
+ const start = Date.parse(acknowledgment.starts_at), end = Date.parse(acknowledgment.ends_at);
410
+ if (!(start <= now && now < end)) return null;
411
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "paw-sponsor", children: [
412
+ /* @__PURE__ */ jsxRuntime.jsx(
413
+ SponsorAcknowledgment,
414
+ {
415
+ creative: acknowledgment.creative,
416
+ acknowledgment,
417
+ label: "Sponsored"
418
+ }
419
+ ),
420
+ /* @__PURE__ */ jsxRuntime.jsx("small", { children: "Paid community sponsorship. Sponsorship does not influence editorial selections and is not an endorsement." })
421
+ ] });
422
+ }
423
+ function PetsSection({
424
+ name = "Bay Area Paw",
425
+ tagline = "Happier pets. Closer communities.",
426
+ community,
427
+ communities,
428
+ resources,
429
+ spotlight,
430
+ acknowledgments = [],
431
+ basePath = "/pets",
432
+ mediaUrl,
433
+ contributeUrl,
434
+ placesUrl,
435
+ walksUrl,
436
+ nextUrl,
437
+ unavailable,
438
+ regionLabel,
439
+ resourceBasePath,
440
+ browseBasePath = "/browse",
441
+ eventsUrl,
442
+ accountUrl
443
+ }) {
444
+ const location = community?.name || regionLabel || "the Bay Area";
445
+ const link = (id) => `${resourceBasePath || basePath}/${encodeURIComponent(id)}`;
446
+ const local = (id) => communities.find((c) => c.id === id)?.name || "Our community";
447
+ const communityQuery = community ? "?community=" + encodeURIComponent(community.slug) : "";
448
+ const photoBoard = resources.filter(
449
+ (r) => r.kind === "photo" || r.kind === "profile"
450
+ );
451
+ const celebrations = resources.filter((r) => r.kind === "celebration");
452
+ const notices = resources.filter((r) => ["lost", "found"].includes(r.kind));
453
+ const adoptions = resources.filter((r) => r.kind === "adoption");
454
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "paw", children: [
455
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "paw-masthead", children: [
456
+ /* @__PURE__ */ jsxRuntime.jsxs("a", { href: basePath || "/", className: "paw-brand", children: [
457
+ /* @__PURE__ */ jsxRuntime.jsx(PawMark, {}),
458
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: name })
459
+ ] }),
460
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: tagline }),
461
+ accountUrl && /* @__PURE__ */ jsxRuntime.jsx("a", { href: safePetLink(accountUrl), children: "My pets" }),
462
+ contributeUrl && /* @__PURE__ */ jsxRuntime.jsx("a", { className: "paw-button", href: safePetLink(contributeUrl), children: "Share your pet" })
463
+ ] }),
464
+ /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: "paw-nav", "aria-label": "Pet community", children: [
465
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: "#neighbors", children: "Our pets" }),
466
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: "#lost-found", children: "Lost & found" }),
467
+ walksUrl && /* @__PURE__ */ jsxRuntime.jsx("a", { href: safePetLink(walksUrl), children: "Paw Walks" }),
468
+ placesUrl && /* @__PURE__ */ jsxRuntime.jsx("a", { href: safePetLink(placesUrl), children: "Paw Places" }),
469
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: "#adoption", children: "Adoption" }),
470
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: "#celebrations", children: "Celebrations" }),
471
+ eventsUrl && /* @__PURE__ */ jsxRuntime.jsx("a", { href: safePetLink(eventsUrl), children: "Events" })
472
+ ] }),
473
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "paw-community", children: [
474
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
475
+ "A little closer to ",
476
+ location,
477
+ "."
478
+ ] }),
479
+ /* @__PURE__ */ jsxRuntime.jsxs("form", { action: basePath || "/", method: "get", children: [
480
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "paw-community", children: "Your community" }),
481
+ /* @__PURE__ */ jsxRuntime.jsxs(
482
+ "select",
483
+ {
484
+ id: "paw-community",
485
+ name: "community",
486
+ defaultValue: community?.slug || "",
487
+ children: [
488
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "All communities" }),
489
+ communities.map((c) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: c.slug, children: c.name }, c.id))
490
+ ]
491
+ }
492
+ ),
493
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "submit", children: "Explore" })
494
+ ] })
495
+ ] }),
496
+ unavailable ? /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "status", className: "paw-empty", children: [
497
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { children: "Your community is on its way." }),
498
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "We can\u2019t load the pet community right now. Please try again shortly." })
499
+ ] }) : spotlight ? /* @__PURE__ */ jsxRuntime.jsx(
500
+ PawOfTheWeekCard,
501
+ {
502
+ resource: spotlight,
503
+ community: local(spotlight.area_id),
504
+ href: link(spotlight.id),
505
+ mediaUrl
506
+ }
507
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "paw-welcome", children: [
508
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
509
+ /* @__PURE__ */ jsxRuntime.jsxs("h1", { children: [
510
+ "Every pet has a story.",
511
+ /* @__PURE__ */ jsxRuntime.jsx("br", {}),
512
+ "Let\u2019s meet yours."
513
+ ] }),
514
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "A place for familiar faces, happy reunions and the everyday joy of life with pets." }),
515
+ contributeUrl && /* @__PURE__ */ jsxRuntime.jsx("a", { className: "paw-button", href: safePetLink(contributeUrl), children: "Submit for Paw of the Week" }),
516
+ /* @__PURE__ */ jsxRuntime.jsx("small", { children: "Free to enter. Thoughtfully selected by local editors." })
517
+ ] }),
518
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "paw-emblem", children: [
519
+ /* @__PURE__ */ jsxRuntime.jsx(PawMark, { size: 180 }),
520
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
521
+ "Good neighbors.",
522
+ /* @__PURE__ */ jsxRuntime.jsx("br", {}),
523
+ "Great companions."
524
+ ] })
525
+ ] })
526
+ ] }),
527
+ !unavailable && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
528
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { id: "neighbors", className: "paw-section", children: [
529
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "paw-section-heading", children: [
530
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { children: "Friends around the corner" }),
531
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Small moments. Very good company." })
532
+ ] }),
533
+ photoBoard.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "paw-gallery", children: photoBoard.map((r) => /* @__PURE__ */ jsxRuntime.jsx(
534
+ PetProfileCard,
535
+ {
536
+ resource: r,
537
+ community: local(r.area_id),
538
+ href: link(r.id),
539
+ mediaUrl
540
+ },
541
+ r.id
542
+ )) }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "paw-empty", children: "The photo board is ready for its first neighbors. Share a photograph and a few words about your pet." }),
543
+ /* @__PURE__ */ jsxRuntime.jsx(
544
+ "a",
545
+ {
546
+ href: safePetLink(browseBasePath + "/neighbors" + communityQuery),
547
+ children: "Browse all community pets"
548
+ }
549
+ )
550
+ ] }),
551
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { id: "lost-found", className: "paw-section paw-recovery", children: [
552
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "paw-section-heading", children: [
553
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { children: "Let\u2019s help them get home." }),
554
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Lost & found is always free." })
555
+ ] }),
556
+ notices.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "paw-gallery", children: notices.map((r) => /* @__PURE__ */ jsxRuntime.jsx(
557
+ LostPetNotice,
558
+ {
559
+ resource: r,
560
+ community: local(r.area_id),
561
+ href: link(r.id),
562
+ mediaUrl
563
+ },
564
+ r.id
565
+ )) }) : /* @__PURE__ */ jsxRuntime.jsx("p", { children: "No current, reviewed notices in this community." }),
566
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "paw-safety", children: PET_SAFETY.recovery }),
567
+ /* @__PURE__ */ jsxRuntime.jsx(
568
+ "a",
569
+ {
570
+ href: safePetLink(
571
+ browseBasePath + "/lost_found" + communityQuery
572
+ ),
573
+ children: "Open the lost & found board"
574
+ }
575
+ )
576
+ ] }),
577
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { id: "celebrations", className: "paw-section", children: [
578
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "paw-section-heading", children: [
579
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { children: "A life full of little milestones" }),
580
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Birthdays, adoption days, new beginnings and fond memories." })
581
+ ] }),
582
+ celebrations.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "paw-gallery", children: celebrations.map((r) => /* @__PURE__ */ jsxRuntime.jsx(
583
+ PetCelebrationCard,
584
+ {
585
+ resource: r,
586
+ community: local(r.area_id),
587
+ href: link(r.id),
588
+ mediaUrl
589
+ },
590
+ r.id
591
+ )) }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "paw-empty", children: "Celebrate someone who makes your days brighter. Every story is reviewed with care." }),
592
+ /* @__PURE__ */ jsxRuntime.jsx(
593
+ "a",
594
+ {
595
+ href: safePetLink(
596
+ browseBasePath + "/celebration" + communityQuery
597
+ ),
598
+ children: "More pet celebrations"
599
+ }
600
+ )
601
+ ] }),
602
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { id: "adoption", className: "paw-section", children: [
603
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "paw-section-heading", children: [
604
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { children: "A new chapter starts with hello." }),
605
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Discover animals through local shelters and rescue organizations." })
606
+ ] }),
607
+ adoptions.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "paw-gallery", children: adoptions.map((r) => /* @__PURE__ */ jsxRuntime.jsx(
608
+ AdoptionListingCard,
609
+ {
610
+ resource: r,
611
+ community: local(r.area_id),
612
+ href: link(r.id),
613
+ mediaUrl
614
+ },
615
+ r.id
616
+ )) }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "paw-empty", children: "Our editors are gathering official shelter and rescue listings. Check directly with your local organization for current availability." }),
617
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "paw-safety", children: PET_SAFETY.adoption }),
618
+ /* @__PURE__ */ jsxRuntime.jsx(
619
+ "a",
620
+ {
621
+ href: safePetLink(browseBasePath + "/adoption" + communityQuery),
622
+ children: "Explore adoption listings"
623
+ }
624
+ )
625
+ ] }),
626
+ nextUrl && /* @__PURE__ */ jsxRuntime.jsx("a", { className: "paw-button", href: safePetLink(nextUrl), children: "More community pets" })
627
+ ] }),
628
+ acknowledgments.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("section", { "aria-label": "Community support", children: [
629
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Bay Area Paw is made possible with support from our community partners." }),
630
+ acknowledgments.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
631
+ SponsorAcknowledgment2,
632
+ {
633
+ acknowledgment: item
634
+ },
635
+ item.campaign_id + item.placement_id
636
+ ))
637
+ ] }),
638
+ /* @__PURE__ */ jsxRuntime.jsxs("footer", { className: "paw-footer", children: [
639
+ /* @__PURE__ */ jsxRuntime.jsx(PawMark, { size: 24 }),
640
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
641
+ "A community project from Bay Area News Network.",
642
+ /* @__PURE__ */ jsxRuntime.jsx("br", {}),
643
+ tagline
644
+ ] })
645
+ ] })
646
+ ] });
647
+ }
648
+ async function PublicationPetsSection({
649
+ scope,
650
+ query,
651
+ region,
652
+ canonicalOrigin,
653
+ defaultCommunity,
654
+ walksUrl,
655
+ cleanCaption = (v) => v
656
+ }) {
657
+ const root = `/v1/knowledge/community-maps/collections/${scope.collectionSlug}`;
658
+ const mediaUrl = (id, photo) => `/api/pets/${id}/media/${photo}`;
659
+ try {
660
+ const collection = await petRequest(scope, root);
661
+ const home = defaultCommunity || collection.areas.find(
662
+ (area) => area.name.toLocaleLowerCase() === region.toLocaleLowerCase()
663
+ )?.id;
664
+ const chosen = resolvePetCommunity(
665
+ collection.areas,
666
+ query.community,
667
+ void 0,
668
+ home
669
+ );
670
+ const filter = new URLSearchParams();
671
+ if (chosen) filter.set("area_id", chosen.id);
672
+ if (query.after) filter.set("after", query.after);
673
+ const date = new Intl.DateTimeFormat("en-CA", {
674
+ timeZone: "America/Los_Angeles",
675
+ year: "numeric",
676
+ month: "2-digit",
677
+ day: "2-digit"
678
+ }).format(/* @__PURE__ */ new Date());
679
+ const monday = /* @__PURE__ */ new Date(date + "T12:00:00Z");
680
+ monday.setUTCDate(monday.getUTCDate() - (monday.getUTCDay() + 6) % 7);
681
+ const weekly = new URLSearchParams({
682
+ kind: "spotlight",
683
+ week: monday.toISOString().split("T")[0]
684
+ });
685
+ if (chosen) weekly.set("area_id", chosen.id);
686
+ const [feeds, spotlights] = await Promise.all([
687
+ Promise.all(
688
+ ["neighbors", "lost_found", "celebration", "adoption"].map((kind) => {
689
+ const q = new URLSearchParams(filter);
690
+ q.set("kind", kind);
691
+ q.set("limit", "6");
692
+ return petRequest(
693
+ scope,
694
+ root + "/pets?" + q
695
+ );
696
+ })
697
+ ),
698
+ petRequest(scope, root + "/pets?" + weekly)
699
+ ]);
700
+ const clean = (r) => ({
701
+ ...r,
702
+ media: r.media.map((m) => ({
703
+ ...m,
704
+ caption: cleanCaption(m.caption),
705
+ attribution: cleanCaption(m.attribution)
706
+ }))
707
+ });
708
+ const local = chosen ? "?community=" + encodeURIComponent(chosen.slug) : "";
709
+ return /* @__PURE__ */ jsxRuntime.jsx(
710
+ PetsSection,
711
+ {
712
+ basePath: "/pets",
713
+ regionLabel: region,
714
+ resourceBasePath: canonicalOrigin + "/pets",
715
+ communities: collection.areas,
716
+ community: chosen,
717
+ acknowledgments: await petAcknowledgments(scope, chosen?.slug),
718
+ resources: feeds.flatMap((feed) => feed.items).map(clean),
719
+ spotlight: spotlights.items[0] && clean(spotlights.items[0]),
720
+ mediaUrl,
721
+ contributeUrl: canonicalOrigin + "/submit" + local,
722
+ placesUrl: canonicalOrigin + "/places" + local,
723
+ walksUrl,
724
+ browseBasePath: canonicalOrigin + "/browse",
725
+ eventsUrl: canonicalOrigin + "/events"
726
+ }
727
+ );
728
+ } catch {
729
+ return /* @__PURE__ */ jsxRuntime.jsx(
730
+ PetsSection,
731
+ {
732
+ communities: [],
733
+ resources: [],
734
+ mediaUrl,
735
+ regionLabel: region,
736
+ unavailable: true
737
+ }
738
+ );
739
+ }
740
+ }
741
+ async function PublicationPetReferences({
742
+ scope,
743
+ metadata,
744
+ canonicalOrigin,
745
+ communities,
746
+ cleanCaption = (v) => v
747
+ }) {
748
+ let resources;
749
+ try {
750
+ resources = await resolvePetReferences(scope, metadata);
751
+ } catch {
752
+ return /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Linked pet resources are temporarily unavailable." });
753
+ }
754
+ if (!resources.length) return null;
755
+ return /* @__PURE__ */ jsxRuntime.jsx("section", { className: "paw", "aria-label": "Related community pet resources", children: resources.map((resource) => {
756
+ const props = {
757
+ resource: {
758
+ ...resource,
759
+ media: resource.media.map((m) => ({
760
+ ...m,
761
+ caption: cleanCaption(m.caption),
762
+ attribution: cleanCaption(m.attribution)
763
+ }))
764
+ },
765
+ community: communities?.find((c) => c.id === resource.area_id)?.name || "Our community",
766
+ href: `${canonicalOrigin}/pets/${resource.id}`,
767
+ mediaUrl: (id, photo) => `/api/pets/${id}/media/${photo}`
768
+ };
769
+ const Card = resource.kind === "spotlight" ? PawOfTheWeekCard : resource.kind === "adoption" ? AdoptionListingCard : resource.kind === "event" ? PetEventCard : resource.kind === "celebration" ? PetCelebrationCard : ["lost", "found"].includes(resource.kind) ? LostPetNotice : PetProfileCard;
770
+ return /* @__PURE__ */ react.createElement(Card, { ...props, key: resource.id });
771
+ }) });
772
+ }
773
+ async function PublicationPetEvents({
774
+ scope,
775
+ canonicalOrigin,
776
+ cleanCaption = (value) => value
777
+ }) {
778
+ try {
779
+ const query = new URLSearchParams({
780
+ kind: "event",
781
+ limit: "6",
782
+ starts_after: (/* @__PURE__ */ new Date()).toISOString(),
783
+ starts_before: new Date(Date.now() + 7 * 864e5).toISOString()
784
+ });
785
+ const { items } = await petRequest(
786
+ scope,
787
+ `/v1/knowledge/community-maps/collections/${scope.collectionSlug}/pets?${query}`
788
+ );
789
+ if (!items.length) return null;
790
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "paw paw-section", "aria-label": "Pet events this week", children: [
791
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { children: "This week for pets and their people" }),
792
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "paw-gallery", children: items.map((resource) => /* @__PURE__ */ jsxRuntime.jsx(
793
+ PetEventCard,
794
+ {
795
+ resource: {
796
+ ...resource,
797
+ media: resource.media.map((photo) => ({
798
+ ...photo,
799
+ caption: cleanCaption(photo.caption),
800
+ attribution: cleanCaption(photo.attribution)
801
+ }))
802
+ },
803
+ community: "Our community",
804
+ href: `${canonicalOrigin}/pets/${resource.id}`,
805
+ mediaUrl: (id, media) => `/api/pets/${id}/media/${media}`
806
+ },
807
+ resource.id
808
+ )) }),
809
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: canonicalOrigin + "/events", children: "Browse the pet community calendar" })
810
+ ] });
811
+ } catch {
812
+ return /* @__PURE__ */ jsxRuntime.jsx("p", { role: "status", children: "Pet event listings are temporarily unavailable." });
813
+ }
814
+ }
815
+
816
+ exports.PublicationPetEvents = PublicationPetEvents;
817
+ exports.PublicationPetReferences = PublicationPetReferences;
818
+ exports.PublicationPetsSection = PublicationPetsSection;