@scalemule/news-publication 0.0.13 → 0.0.15

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 (41) hide show
  1. package/dist/chunk-5W4EMBFY.js +106 -0
  2. package/dist/{chunk-5MHPE77S.js → chunk-5YQYJ2L2.js} +1 -1
  3. package/dist/chunk-7TBML5Q7.js +57 -0
  4. package/dist/chunk-QWK6G2UF.js +117 -0
  5. package/dist/{chunk-FUUL2PSF.js → chunk-WZ3NQRQO.js} +1 -1
  6. package/dist/compliance.cjs +19 -0
  7. package/dist/compliance.d.cts +2 -0
  8. package/dist/compliance.d.ts +2 -0
  9. package/dist/compliance.js +2 -0
  10. package/dist/cookie-consent-banner.cjs +25 -369
  11. package/dist/cookie-consent-banner.js +2 -2
  12. package/dist/cookie-settings-view.cjs +21 -193
  13. package/dist/cookie-settings-view.js +2 -2
  14. package/dist/index.cjs +287 -448
  15. package/dist/index.d.cts +16 -113
  16. package/dist/index.d.ts +16 -113
  17. package/dist/index.js +5 -3
  18. package/dist/{marketplace-CpGWPbFk.d.ts → marketplace-29i5w4LS.d.cts} +1 -1
  19. package/dist/{marketplace-CpGWPbFk.d.cts → marketplace-29i5w4LS.d.ts} +1 -1
  20. package/dist/marketplace-view.d.cts +1 -1
  21. package/dist/marketplace-view.d.ts +1 -1
  22. package/dist/{meet-5Ym5bxfh.d.cts → meet-RWmfj3I3.d.cts} +1 -1
  23. package/dist/{meet-5Ym5bxfh.d.ts → meet-RWmfj3I3.d.ts} +1 -1
  24. package/dist/meet-forms.d.cts +1 -1
  25. package/dist/meet-forms.d.ts +1 -1
  26. package/dist/meet-view.d.cts +1 -1
  27. package/dist/meet-view.d.ts +1 -1
  28. package/dist/network-bar.cjs +145 -0
  29. package/dist/network-bar.d.cts +15 -0
  30. package/dist/network-bar.d.ts +15 -0
  31. package/dist/network-bar.js +3 -0
  32. package/dist/network.cjs +115 -0
  33. package/dist/network.d.cts +23 -0
  34. package/dist/network.d.ts +23 -0
  35. package/dist/network.js +2 -0
  36. package/dist/snapshot-file.d.cts +1 -1
  37. package/dist/snapshot-file.d.ts +1 -1
  38. package/dist/{snapshot-BS4hn1dk.d.ts → snapshot-sHgQHuAF.d.cts} +1 -1
  39. package/dist/{snapshot-BS4hn1dk.d.cts → snapshot-sHgQHuAF.d.ts} +1 -1
  40. package/package.json +22 -2
  41. package/dist/chunk-L5OE6DND.js +0 -506
package/dist/index.d.cts CHANGED
@@ -1,10 +1,14 @@
1
- import { P as PublicationTheme, a as PublicationInput, N as NewsPublication, F as FeatureName, H as HomepageSelection, b as NearbyUpdate, c as NewsItem, E as EditorialSection, d as NewsArticle, C as CouponOffer } from './snapshot-BS4hn1dk.cjs';
2
- export { A as ArticleCitation, e as CategoryRef, f as CouponSettings, g as CoverImageMetadata, h as FEATURE_NAMES, i as FeatureFlags, j as NewsFeed, k as NewsLayoutId, l as PublicationModules, m as PublicationRecord, n as PublicationSnapshot, R as ReferralSettings, S as SnapshotHooks, o as StoryDisplay, p as SyncSource, q as SyncedPublication, T as TagRef, r as acceptRemoteRecord, s as acceptSnapshot, t as parseSnapshot, u as publicationFromSnapshot, v as publicationRecord, w as snapshotFromRecord, x as syncPublication } from './snapshot-BS4hn1dk.cjs';
3
- export { M as MEET_ACTIVITIES, a as MeetActivity, b as MeetupInput, P as PreparedMeetup, c as PublicPlace, d as activityLabel, e as canHostMeetup, i as isAdult, p as prepareMeetup, s as screenMessage } from './meet-5Ym5bxfh.cjs';
4
- export { C as CLASSIFIED_CATEGORIES, a as ClassifiedCategory, b as ClassifiedListing, E as EmploymentType, J as JOB_EMPLOYMENT_TYPES, P as PreparedClassified, c as PreparedJob, d as PublicDeal, e as PublicDealOffer, f as PublicJob, g as categoryLabel, h as classifiedPath, i as classifiedSearchPath, j as clipChars, k as dealDollars, l as dealGoPath, m as dealsFeedPath, n as employmentLabel, o as isClassifiedCategory, p as isEmploymentType, q as jobEmployerBody, r as jobOpeningBody, s as jobPostingBody, t as prepareClassified, u as prepareJobPost, v as publicJobPath, w as publicJobsPath } from './marketplace-CpGWPbFk.cjs';
1
+ import { b as PublicationTheme, c as PublicationInput, N as NewsPublication, F as FeatureName, H as HomepageSelection, d as NearbyUpdate, e as NewsItem, E as EditorialSection, f as NewsArticle, C as CouponOffer } from './snapshot-sHgQHuAF.cjs';
2
+ export { A as ArticleCitation, g as CategoryRef, h as CouponSettings, i as CoverImageMetadata, j as FEATURE_NAMES, k as FeatureFlags, l as NewsFeed, m as NewsLayoutId, n as PublicationModules, o as PublicationRecord, P as PublicationSnapshot, R as ReferralSettings, S as SnapshotHooks, p as StoryDisplay, q as SyncSource, a as SyncedPublication, T as TagRef, r as acceptRemoteRecord, s as acceptSnapshot, t as parseSnapshot, u as publicationFromSnapshot, v as publicationRecord, w as snapshotFromRecord, x as syncPublication } from './snapshot-sHgQHuAF.cjs';
3
+ export { M as MEET_ACTIVITIES, b as MeetActivity, c as MeetupInput, a as PreparedMeetup, P as PublicPlace, d as activityLabel, e as canHostMeetup, i as isAdult, p as prepareMeetup, s as screenMessage } from './meet-RWmfj3I3.cjs';
4
+ export { b as CLASSIFIED_CATEGORIES, c as ClassifiedCategory, C as ClassifiedListing, E as EmploymentType, J as JOB_EMPLOYMENT_TYPES, d as PreparedClassified, e as PreparedJob, P as PublicDeal, f as PublicDealOffer, a as PublicJob, g as categoryLabel, h as classifiedPath, i as classifiedSearchPath, j as clipChars, k as dealDollars, l as dealGoPath, m as dealsFeedPath, n as employmentLabel, o as isClassifiedCategory, p as isEmploymentType, q as jobEmployerBody, r as jobOpeningBody, s as jobPostingBody, t as prepareClassified, u as prepareJobPost, v as publicJobPath, w as publicJobsPath } from './marketplace-29i5w4LS.cjs';
5
+ import { CookieCategoryDefinition, CookieConsentRecord } from '@scalemule/compliance';
6
+ export { COOKIE_CONSENT_BACKUP_KEY, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, COOKIE_CONSENT_MAX_AGE_SECONDS, CookieCategory, CookieCategoryDefinition, CookieConsentRecord, CookieDisclosure, CookiePreferences, DEFAULT_CONSENT_HUB_URL, DEFAULT_PREFERENCES_ACCEPTED, DEFAULT_PREFERENCES_REJECTED, EU_EEA_UK_COUNTRIES, NETWORK_CONSENT_STORAGE_KEY, acceptAllCookies, checkUrlConsentBridge, clearCookieConsent, decorateNetworkUrl, getCookieConsent, hasConsented, isCategoryAllowed, isGeoConsentRequired, queryNetworkConsentHub, rejectOptionalCookies, setCookieConsent, setNetworkConsentHub } from '@scalemule/compliance';
5
7
  export { CookieConsentBanner, CookieConsentBannerProps } from './cookie-consent-banner.cjs';
6
8
  export { CookieSettingsView, CookieSettingsViewProps } from './cookie-settings-view.cjs';
7
9
  export { ThemeToggle, ThemeToggleProps } from './theme-toggle.cjs';
10
+ export { PublicationNetworkItem, communityPublications, findPublicationByHost, findPublicationBySlug, getNetworkPublicationUrl, listedPublications, localPublications } from './network.cjs';
11
+ export { LocalNetworkBar, LocalNetworkBarProps } from './network-bar.cjs';
8
12
  import 'react';
9
13
 
10
14
  /** Walnut Creek Times broadsheet colors. A paper overrides only what it changes. */
@@ -235,119 +239,18 @@ declare function attribution(url: string, referrer?: string, publication?: Pick<
235
239
  declare function resolveCoupon(publication: NewsPublication, code: string | null | undefined): CouponOffer | null;
236
240
  declare function referralCode(publication: NewsPublication, url: string): string | null;
237
241
 
238
- type CookieCategory = "essential" | "performance" | "functional" | "advertising";
239
- interface CookiePreferences {
240
- /** Strictly necessary cookies required for core site operation and security. Always true. */
241
- essential: true;
242
- /** Analytics and performance measurement to improve community coverage and site speed. */
243
- performance: boolean;
244
- /** Personalization features such as narration audio speed, text sizing, and town filters. */
245
- functional: boolean;
246
- /** Local sponsorship delivery and partner campaign frequency capping. */
247
- advertising: boolean;
248
- }
249
- interface CookieConsentRecord {
250
- version: 1;
251
- preferences: CookiePreferences;
252
- timestamp: string;
253
- anonymous_id?: string;
254
- source: "banner_accept" | "banner_reject" | "settings_save";
255
- }
256
- interface CookieDisclosure {
257
- name: string;
258
- provider: string;
259
- purpose: string;
260
- duration: string;
261
- type: "HTTP Cookie" | "Local Storage" | "Session Storage";
262
- }
263
- interface CookieCategoryDefinition {
264
- id: CookieCategory;
265
- title: string;
266
- shortDescription: string;
267
- fullDescription: string;
268
- required: boolean;
269
- cookies: CookieDisclosure[];
270
- }
271
- declare const COOKIE_CONSENT_KEY = "sm_cookie_consent_v1";
272
- declare const COOKIE_CONSENT_BACKUP_KEY = "napsite_cookie_consent_v1";
273
- declare const COOKIE_CONSENT_EVENT = "scalemule-cookie-consent-change";
274
- declare const COOKIE_CONSENT_MAX_AGE_SECONDS: number;
275
- declare const DEFAULT_CONSENT_HUB_URL = "https://bayareachronicle.com/consent-bridge.html";
276
- declare const NETWORK_CONSENT_STORAGE_KEY = "sm_network_consent_status";
277
- declare const DEFAULT_PREFERENCES_REJECTED: CookiePreferences;
278
- declare const DEFAULT_PREFERENCES_ACCEPTED: CookiePreferences;
279
- declare const COOKIE_CATEGORIES: CookieCategoryDefinition[];
280
- /**
281
- * Retrieve the current cookie consent record.
282
- * Checks HTTP cookie first, then localStorage fallback, then in-memory state.
283
- */
284
- declare function getCookieConsent(): CookieConsentRecord | null;
285
- /**
286
- * ISO 3166-1 alpha-2 country codes for EU/EEA member states and the UK/Switzerland
287
- * subject to the GDPR and ePrivacy Directive prior-consent requirement.
288
- */
289
- declare const EU_EEA_UK_COUNTRIES: Set<string>;
290
- /**
291
- * Determine if cookie consent prior-opt-in banner is required based on visitor geography.
292
- * For US readers (including California CCPA/CPRA), opt-in banners are not required.
293
- * Returns true ONLY if the visitor is identified as being within an EU/EEA/UK jurisdiction.
294
- */
295
- declare function isGeoConsentRequired(countryCode?: string | null): boolean;
296
- /**
297
- * Checks for a cross-domain network consent signal in the URL query (?sm_consent=accepted|rejected|1|0).
298
- * If present, silently records the consent choice locally and removes the param from the address bar.
299
- * Returns true if a consent signal was processed.
300
- */
301
- declare function checkUrlConsentBridge(): boolean;
302
- /**
303
- * Appends the current consent decision to an outgoing URL within the newspaper network
304
- * so sister publications can adopt the user's choice without requiring a new banner prompt.
305
- */
306
- declare function decorateNetworkUrl(targetUrl: string): string;
307
- /**
308
- * Queries the central network iframe hub to retrieve the reader's cross-domain consent choice.
309
- * If running on the hub origin directly, reads from local storage without an iframe.
310
- */
311
- declare function queryNetworkConsentHub(hubUrl?: string, timeoutMs?: number): Promise<"accepted" | "rejected" | null>;
312
- /**
313
- * Propagates a consent decision to the central network iframe hub so all sister publications adopt it.
314
- */
315
- declare function setNetworkConsentHub(status: "accepted" | "rejected" | null, hubUrl?: string): void;
316
- /**
317
- * Check if the user has already provided an explicit consent decision.
318
- */
319
- declare function hasConsented(): boolean;
320
- /**
321
- * Check if a specific cookie category is currently permitted.
322
- * Essential is always permitted.
323
- */
324
- declare function isCategoryAllowed(category: CookieCategory): boolean;
325
- /**
326
- * Record cookie consent choices.
327
- * Updates both HTTP cookies, localStorage, and fires a window event.
328
- */
329
- declare function setCookieConsent(preferences: Partial<CookiePreferences>, source?: CookieConsentRecord["source"]): CookieConsentRecord;
330
- /**
331
- * Accepts all cookies (essential, performance, functional, advertising).
332
- */
333
- declare function acceptAllCookies(): CookieConsentRecord;
334
- /**
335
- * Rejects all optional cookies (preserves essential cookies only).
336
- */
337
- declare function rejectOptionalCookies(): CookieConsentRecord;
338
- /**
339
- * Clear consent record (used when resetting choices).
340
- */
341
- declare function clearCookieConsent(): void;
342
- /**
343
- * Forward the user consent choice to ScaleMule compliance service.
344
- * Respects customer security boundary: uses relative /api/compliance/consent proxy or client endpoint.
345
- */
346
242
  declare function recordConsentToCompliance(record: CookieConsentRecord, options?: {
347
243
  endpoint?: string;
244
+ applicationId?: string;
348
245
  publicationSlug?: string;
349
246
  }): Promise<void>;
350
247
 
248
+ /**
249
+ * News-publication specific cookie category disclosures.
250
+ * Defaults configured for ScaleMule community newsrooms and broadsheet publications.
251
+ */
252
+ declare const COOKIE_CATEGORIES: CookieCategoryDefinition[];
253
+
351
254
  type ThemeMode = "light" | "dark" | "system";
352
255
  type EffectiveTheme = "light" | "dark";
353
256
  declare const THEME_COOKIE = "news_publication_theme";
@@ -389,4 +292,4 @@ declare function subscribeTheme(listener: () => void): () => void;
389
292
  */
390
293
  declare function themeInitScript(): string;
391
294
 
392
- export { ANALYTICS_COOKIE, ANALYTICS_VERSION, type Attribution, BROADSHEET_THEME, COOKIE_CATEGORIES, COOKIE_CONSENT_BACKUP_KEY, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, COOKIE_CONSENT_MAX_AGE_SECONDS, type CookieCategory, type CookieCategoryDefinition, type CookieConsentRecord, type CookieDisclosure, type CookiePreferences, CouponOffer, DEFAULT_CONSENT_HUB_URL, DEFAULT_PREFERENCES_ACCEPTED, DEFAULT_PREFERENCES_REJECTED, EU_EEA_UK_COUNTRIES, EVENTS, EditorialSection, type EffectiveTheme, FeatureName, HomepageSelection, LAYOUT_COOKIE, NETWORK_CONSENT_STORAGE_KEY, NEWS_CACHE, NearbyUpdate, NewsArticle, NewsError, NewsItem, NewsPublication, PublicationInput, PublicationTheme, SESSION_IDLE_MS, THEME_COOKIE, THEME_EVENT, THEME_MAX_AGE_SECONDS, THEME_STORAGE_KEY, type ThemeMode, UTM_FIELDS, UUID, acceptAllCookies, activeNearby, applyTheme, articleCacheKey, articleCacheOptions, articleMeta, articleUrl, attribution, briefSummary, checkUrlConsentBridge, clearCookieConsent, clearTheme, composeEdition, decorateNetworkUrl, defaultRevalidateTargets, definePublication, displayHeadline, edgeCacheControl, editorialSections, featureEnabled, feedCacheKey, feedCacheOptions, filterNews, getCookieConsent, getStoredTheme, getSystemTheme, hasConsented, inventoryCacheOptions, isCategoryAllowed, isGeoConsentRequired, llmsText, matchesStoryTag, nearbyUpdates, newsArticleJsonLd, normalizedText, publicHttps, publicUrl, publicationJsonLd, publicationMeta, queryNetworkConsentHub, recordConsentToCompliance, referralCode, rejectOptionalCookies, resolveCoupon, resolveEffectiveTheme, resolveLayout, revalidateDecision, secretsMatch, sectionDefinition, sectionId, sectionPath, setCookieConsent, setNetworkConsentHub, setTheme, shortDeck, shortText, shouldServeLastKnown, storyDate, storyTowns, subscribeTheme, themeInitScript, townSlug, validCalendarDate, walnutCreekTimes, withLastKnown };
295
+ export { ANALYTICS_COOKIE, ANALYTICS_VERSION, type Attribution, BROADSHEET_THEME, COOKIE_CATEGORIES, CouponOffer, EVENTS, EditorialSection, type EffectiveTheme, FeatureName, HomepageSelection, LAYOUT_COOKIE, NEWS_CACHE, NearbyUpdate, NewsArticle, NewsError, NewsItem, NewsPublication, PublicationInput, PublicationTheme, SESSION_IDLE_MS, THEME_COOKIE, THEME_EVENT, THEME_MAX_AGE_SECONDS, THEME_STORAGE_KEY, type ThemeMode, UTM_FIELDS, UUID, activeNearby, applyTheme, articleCacheKey, articleCacheOptions, articleMeta, articleUrl, attribution, briefSummary, clearTheme, composeEdition, defaultRevalidateTargets, definePublication, displayHeadline, edgeCacheControl, editorialSections, featureEnabled, feedCacheKey, feedCacheOptions, filterNews, getStoredTheme, getSystemTheme, inventoryCacheOptions, llmsText, matchesStoryTag, nearbyUpdates, newsArticleJsonLd, normalizedText, publicHttps, publicUrl, publicationJsonLd, publicationMeta, recordConsentToCompliance, referralCode, resolveCoupon, resolveEffectiveTheme, resolveLayout, revalidateDecision, secretsMatch, sectionDefinition, sectionId, sectionPath, setTheme, shortDeck, shortText, shouldServeLastKnown, storyDate, storyTowns, subscribeTheme, themeInitScript, townSlug, validCalendarDate, walnutCreekTimes, withLastKnown };
package/dist/index.d.ts CHANGED
@@ -1,10 +1,14 @@
1
- import { P as PublicationTheme, a as PublicationInput, N as NewsPublication, F as FeatureName, H as HomepageSelection, b as NearbyUpdate, c as NewsItem, E as EditorialSection, d as NewsArticle, C as CouponOffer } from './snapshot-BS4hn1dk.js';
2
- export { A as ArticleCitation, e as CategoryRef, f as CouponSettings, g as CoverImageMetadata, h as FEATURE_NAMES, i as FeatureFlags, j as NewsFeed, k as NewsLayoutId, l as PublicationModules, m as PublicationRecord, n as PublicationSnapshot, R as ReferralSettings, S as SnapshotHooks, o as StoryDisplay, p as SyncSource, q as SyncedPublication, T as TagRef, r as acceptRemoteRecord, s as acceptSnapshot, t as parseSnapshot, u as publicationFromSnapshot, v as publicationRecord, w as snapshotFromRecord, x as syncPublication } from './snapshot-BS4hn1dk.js';
3
- export { M as MEET_ACTIVITIES, a as MeetActivity, b as MeetupInput, P as PreparedMeetup, c as PublicPlace, d as activityLabel, e as canHostMeetup, i as isAdult, p as prepareMeetup, s as screenMessage } from './meet-5Ym5bxfh.js';
4
- export { C as CLASSIFIED_CATEGORIES, a as ClassifiedCategory, b as ClassifiedListing, E as EmploymentType, J as JOB_EMPLOYMENT_TYPES, P as PreparedClassified, c as PreparedJob, d as PublicDeal, e as PublicDealOffer, f as PublicJob, g as categoryLabel, h as classifiedPath, i as classifiedSearchPath, j as clipChars, k as dealDollars, l as dealGoPath, m as dealsFeedPath, n as employmentLabel, o as isClassifiedCategory, p as isEmploymentType, q as jobEmployerBody, r as jobOpeningBody, s as jobPostingBody, t as prepareClassified, u as prepareJobPost, v as publicJobPath, w as publicJobsPath } from './marketplace-CpGWPbFk.js';
1
+ import { b as PublicationTheme, c as PublicationInput, N as NewsPublication, F as FeatureName, H as HomepageSelection, d as NearbyUpdate, e as NewsItem, E as EditorialSection, f as NewsArticle, C as CouponOffer } from './snapshot-sHgQHuAF.js';
2
+ export { A as ArticleCitation, g as CategoryRef, h as CouponSettings, i as CoverImageMetadata, j as FEATURE_NAMES, k as FeatureFlags, l as NewsFeed, m as NewsLayoutId, n as PublicationModules, o as PublicationRecord, P as PublicationSnapshot, R as ReferralSettings, S as SnapshotHooks, p as StoryDisplay, q as SyncSource, a as SyncedPublication, T as TagRef, r as acceptRemoteRecord, s as acceptSnapshot, t as parseSnapshot, u as publicationFromSnapshot, v as publicationRecord, w as snapshotFromRecord, x as syncPublication } from './snapshot-sHgQHuAF.js';
3
+ export { M as MEET_ACTIVITIES, b as MeetActivity, c as MeetupInput, a as PreparedMeetup, P as PublicPlace, d as activityLabel, e as canHostMeetup, i as isAdult, p as prepareMeetup, s as screenMessage } from './meet-RWmfj3I3.js';
4
+ export { b as CLASSIFIED_CATEGORIES, c as ClassifiedCategory, C as ClassifiedListing, E as EmploymentType, J as JOB_EMPLOYMENT_TYPES, d as PreparedClassified, e as PreparedJob, P as PublicDeal, f as PublicDealOffer, a as PublicJob, g as categoryLabel, h as classifiedPath, i as classifiedSearchPath, j as clipChars, k as dealDollars, l as dealGoPath, m as dealsFeedPath, n as employmentLabel, o as isClassifiedCategory, p as isEmploymentType, q as jobEmployerBody, r as jobOpeningBody, s as jobPostingBody, t as prepareClassified, u as prepareJobPost, v as publicJobPath, w as publicJobsPath } from './marketplace-29i5w4LS.js';
5
+ import { CookieCategoryDefinition, CookieConsentRecord } from '@scalemule/compliance';
6
+ export { COOKIE_CONSENT_BACKUP_KEY, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, COOKIE_CONSENT_MAX_AGE_SECONDS, CookieCategory, CookieCategoryDefinition, CookieConsentRecord, CookieDisclosure, CookiePreferences, DEFAULT_CONSENT_HUB_URL, DEFAULT_PREFERENCES_ACCEPTED, DEFAULT_PREFERENCES_REJECTED, EU_EEA_UK_COUNTRIES, NETWORK_CONSENT_STORAGE_KEY, acceptAllCookies, checkUrlConsentBridge, clearCookieConsent, decorateNetworkUrl, getCookieConsent, hasConsented, isCategoryAllowed, isGeoConsentRequired, queryNetworkConsentHub, rejectOptionalCookies, setCookieConsent, setNetworkConsentHub } from '@scalemule/compliance';
5
7
  export { CookieConsentBanner, CookieConsentBannerProps } from './cookie-consent-banner.js';
6
8
  export { CookieSettingsView, CookieSettingsViewProps } from './cookie-settings-view.js';
7
9
  export { ThemeToggle, ThemeToggleProps } from './theme-toggle.js';
10
+ export { PublicationNetworkItem, communityPublications, findPublicationByHost, findPublicationBySlug, getNetworkPublicationUrl, listedPublications, localPublications } from './network.js';
11
+ export { LocalNetworkBar, LocalNetworkBarProps } from './network-bar.js';
8
12
  import 'react';
9
13
 
10
14
  /** Walnut Creek Times broadsheet colors. A paper overrides only what it changes. */
@@ -235,119 +239,18 @@ declare function attribution(url: string, referrer?: string, publication?: Pick<
235
239
  declare function resolveCoupon(publication: NewsPublication, code: string | null | undefined): CouponOffer | null;
236
240
  declare function referralCode(publication: NewsPublication, url: string): string | null;
237
241
 
238
- type CookieCategory = "essential" | "performance" | "functional" | "advertising";
239
- interface CookiePreferences {
240
- /** Strictly necessary cookies required for core site operation and security. Always true. */
241
- essential: true;
242
- /** Analytics and performance measurement to improve community coverage and site speed. */
243
- performance: boolean;
244
- /** Personalization features such as narration audio speed, text sizing, and town filters. */
245
- functional: boolean;
246
- /** Local sponsorship delivery and partner campaign frequency capping. */
247
- advertising: boolean;
248
- }
249
- interface CookieConsentRecord {
250
- version: 1;
251
- preferences: CookiePreferences;
252
- timestamp: string;
253
- anonymous_id?: string;
254
- source: "banner_accept" | "banner_reject" | "settings_save";
255
- }
256
- interface CookieDisclosure {
257
- name: string;
258
- provider: string;
259
- purpose: string;
260
- duration: string;
261
- type: "HTTP Cookie" | "Local Storage" | "Session Storage";
262
- }
263
- interface CookieCategoryDefinition {
264
- id: CookieCategory;
265
- title: string;
266
- shortDescription: string;
267
- fullDescription: string;
268
- required: boolean;
269
- cookies: CookieDisclosure[];
270
- }
271
- declare const COOKIE_CONSENT_KEY = "sm_cookie_consent_v1";
272
- declare const COOKIE_CONSENT_BACKUP_KEY = "napsite_cookie_consent_v1";
273
- declare const COOKIE_CONSENT_EVENT = "scalemule-cookie-consent-change";
274
- declare const COOKIE_CONSENT_MAX_AGE_SECONDS: number;
275
- declare const DEFAULT_CONSENT_HUB_URL = "https://bayareachronicle.com/consent-bridge.html";
276
- declare const NETWORK_CONSENT_STORAGE_KEY = "sm_network_consent_status";
277
- declare const DEFAULT_PREFERENCES_REJECTED: CookiePreferences;
278
- declare const DEFAULT_PREFERENCES_ACCEPTED: CookiePreferences;
279
- declare const COOKIE_CATEGORIES: CookieCategoryDefinition[];
280
- /**
281
- * Retrieve the current cookie consent record.
282
- * Checks HTTP cookie first, then localStorage fallback, then in-memory state.
283
- */
284
- declare function getCookieConsent(): CookieConsentRecord | null;
285
- /**
286
- * ISO 3166-1 alpha-2 country codes for EU/EEA member states and the UK/Switzerland
287
- * subject to the GDPR and ePrivacy Directive prior-consent requirement.
288
- */
289
- declare const EU_EEA_UK_COUNTRIES: Set<string>;
290
- /**
291
- * Determine if cookie consent prior-opt-in banner is required based on visitor geography.
292
- * For US readers (including California CCPA/CPRA), opt-in banners are not required.
293
- * Returns true ONLY if the visitor is identified as being within an EU/EEA/UK jurisdiction.
294
- */
295
- declare function isGeoConsentRequired(countryCode?: string | null): boolean;
296
- /**
297
- * Checks for a cross-domain network consent signal in the URL query (?sm_consent=accepted|rejected|1|0).
298
- * If present, silently records the consent choice locally and removes the param from the address bar.
299
- * Returns true if a consent signal was processed.
300
- */
301
- declare function checkUrlConsentBridge(): boolean;
302
- /**
303
- * Appends the current consent decision to an outgoing URL within the newspaper network
304
- * so sister publications can adopt the user's choice without requiring a new banner prompt.
305
- */
306
- declare function decorateNetworkUrl(targetUrl: string): string;
307
- /**
308
- * Queries the central network iframe hub to retrieve the reader's cross-domain consent choice.
309
- * If running on the hub origin directly, reads from local storage without an iframe.
310
- */
311
- declare function queryNetworkConsentHub(hubUrl?: string, timeoutMs?: number): Promise<"accepted" | "rejected" | null>;
312
- /**
313
- * Propagates a consent decision to the central network iframe hub so all sister publications adopt it.
314
- */
315
- declare function setNetworkConsentHub(status: "accepted" | "rejected" | null, hubUrl?: string): void;
316
- /**
317
- * Check if the user has already provided an explicit consent decision.
318
- */
319
- declare function hasConsented(): boolean;
320
- /**
321
- * Check if a specific cookie category is currently permitted.
322
- * Essential is always permitted.
323
- */
324
- declare function isCategoryAllowed(category: CookieCategory): boolean;
325
- /**
326
- * Record cookie consent choices.
327
- * Updates both HTTP cookies, localStorage, and fires a window event.
328
- */
329
- declare function setCookieConsent(preferences: Partial<CookiePreferences>, source?: CookieConsentRecord["source"]): CookieConsentRecord;
330
- /**
331
- * Accepts all cookies (essential, performance, functional, advertising).
332
- */
333
- declare function acceptAllCookies(): CookieConsentRecord;
334
- /**
335
- * Rejects all optional cookies (preserves essential cookies only).
336
- */
337
- declare function rejectOptionalCookies(): CookieConsentRecord;
338
- /**
339
- * Clear consent record (used when resetting choices).
340
- */
341
- declare function clearCookieConsent(): void;
342
- /**
343
- * Forward the user consent choice to ScaleMule compliance service.
344
- * Respects customer security boundary: uses relative /api/compliance/consent proxy or client endpoint.
345
- */
346
242
  declare function recordConsentToCompliance(record: CookieConsentRecord, options?: {
347
243
  endpoint?: string;
244
+ applicationId?: string;
348
245
  publicationSlug?: string;
349
246
  }): Promise<void>;
350
247
 
248
+ /**
249
+ * News-publication specific cookie category disclosures.
250
+ * Defaults configured for ScaleMule community newsrooms and broadsheet publications.
251
+ */
252
+ declare const COOKIE_CATEGORIES: CookieCategoryDefinition[];
253
+
351
254
  type ThemeMode = "light" | "dark" | "system";
352
255
  type EffectiveTheme = "light" | "dark";
353
256
  declare const THEME_COOKIE = "news_publication_theme";
@@ -389,4 +292,4 @@ declare function subscribeTheme(listener: () => void): () => void;
389
292
  */
390
293
  declare function themeInitScript(): string;
391
294
 
392
- export { ANALYTICS_COOKIE, ANALYTICS_VERSION, type Attribution, BROADSHEET_THEME, COOKIE_CATEGORIES, COOKIE_CONSENT_BACKUP_KEY, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, COOKIE_CONSENT_MAX_AGE_SECONDS, type CookieCategory, type CookieCategoryDefinition, type CookieConsentRecord, type CookieDisclosure, type CookiePreferences, CouponOffer, DEFAULT_CONSENT_HUB_URL, DEFAULT_PREFERENCES_ACCEPTED, DEFAULT_PREFERENCES_REJECTED, EU_EEA_UK_COUNTRIES, EVENTS, EditorialSection, type EffectiveTheme, FeatureName, HomepageSelection, LAYOUT_COOKIE, NETWORK_CONSENT_STORAGE_KEY, NEWS_CACHE, NearbyUpdate, NewsArticle, NewsError, NewsItem, NewsPublication, PublicationInput, PublicationTheme, SESSION_IDLE_MS, THEME_COOKIE, THEME_EVENT, THEME_MAX_AGE_SECONDS, THEME_STORAGE_KEY, type ThemeMode, UTM_FIELDS, UUID, acceptAllCookies, activeNearby, applyTheme, articleCacheKey, articleCacheOptions, articleMeta, articleUrl, attribution, briefSummary, checkUrlConsentBridge, clearCookieConsent, clearTheme, composeEdition, decorateNetworkUrl, defaultRevalidateTargets, definePublication, displayHeadline, edgeCacheControl, editorialSections, featureEnabled, feedCacheKey, feedCacheOptions, filterNews, getCookieConsent, getStoredTheme, getSystemTheme, hasConsented, inventoryCacheOptions, isCategoryAllowed, isGeoConsentRequired, llmsText, matchesStoryTag, nearbyUpdates, newsArticleJsonLd, normalizedText, publicHttps, publicUrl, publicationJsonLd, publicationMeta, queryNetworkConsentHub, recordConsentToCompliance, referralCode, rejectOptionalCookies, resolveCoupon, resolveEffectiveTheme, resolveLayout, revalidateDecision, secretsMatch, sectionDefinition, sectionId, sectionPath, setCookieConsent, setNetworkConsentHub, setTheme, shortDeck, shortText, shouldServeLastKnown, storyDate, storyTowns, subscribeTheme, themeInitScript, townSlug, validCalendarDate, walnutCreekTimes, withLastKnown };
295
+ export { ANALYTICS_COOKIE, ANALYTICS_VERSION, type Attribution, BROADSHEET_THEME, COOKIE_CATEGORIES, CouponOffer, EVENTS, EditorialSection, type EffectiveTheme, FeatureName, HomepageSelection, LAYOUT_COOKIE, NEWS_CACHE, NearbyUpdate, NewsArticle, NewsError, NewsItem, NewsPublication, PublicationInput, PublicationTheme, SESSION_IDLE_MS, THEME_COOKIE, THEME_EVENT, THEME_MAX_AGE_SECONDS, THEME_STORAGE_KEY, type ThemeMode, UTM_FIELDS, UUID, activeNearby, applyTheme, articleCacheKey, articleCacheOptions, articleMeta, articleUrl, attribution, briefSummary, clearTheme, composeEdition, defaultRevalidateTargets, definePublication, displayHeadline, edgeCacheControl, editorialSections, featureEnabled, feedCacheKey, feedCacheOptions, filterNews, getStoredTheme, getSystemTheme, inventoryCacheOptions, llmsText, matchesStoryTag, nearbyUpdates, newsArticleJsonLd, normalizedText, publicHttps, publicUrl, publicationJsonLd, publicationMeta, recordConsentToCompliance, referralCode, resolveCoupon, resolveEffectiveTheme, resolveLayout, revalidateDecision, secretsMatch, sectionDefinition, sectionId, sectionPath, setTheme, shortDeck, shortText, shouldServeLastKnown, storyDate, storyTowns, subscribeTheme, themeInitScript, townSlug, validCalendarDate, walnutCreekTimes, withLastKnown };
package/dist/index.js CHANGED
@@ -1,11 +1,13 @@
1
1
  export { THEME_COOKIE, THEME_EVENT, THEME_MAX_AGE_SECONDS, THEME_STORAGE_KEY, ThemeToggle, applyTheme, clearTheme, getStoredTheme, getSystemTheme, resolveEffectiveTheme, setTheme, subscribeTheme, themeInitScript } from './chunk-NQD3M7ZY.js';
2
+ export { LocalNetworkBar } from './chunk-7TBML5Q7.js';
3
+ export { communityPublications, findPublicationByHost, findPublicationBySlug, getNetworkPublicationUrl, listedPublications, localPublications } from './chunk-5W4EMBFY.js';
2
4
  import { definePublication } from './chunk-C7JTEHTH.js';
3
5
  export { BROADSHEET_THEME, FEATURE_NAMES, LAYOUT_COOKIE, acceptRemoteRecord, acceptSnapshot, definePublication, featureEnabled, parseSnapshot, publicationFromSnapshot, publicationRecord, resolveLayout, snapshotFromRecord, syncPublication } from './chunk-C7JTEHTH.js';
4
6
  export { CLASSIFIED_CATEGORIES, JOB_EMPLOYMENT_TYPES, categoryLabel, classifiedPath, classifiedSearchPath, clipChars, dealDollars, dealGoPath, dealsFeedPath, employmentLabel, isClassifiedCategory, isEmploymentType, jobEmployerBody, jobOpeningBody, jobPostingBody, prepareClassified, prepareJobPost, publicJobPath, publicJobsPath } from './chunk-C7ZPLH2K.js';
5
7
  export { MEET_ACTIVITIES, activityLabel, canHostMeetup, isAdult, prepareMeetup, screenMessage } from './chunk-GB36YM56.js';
6
- export { CookieConsentBanner } from './chunk-5MHPE77S.js';
7
- export { CookieSettingsView } from './chunk-FUUL2PSF.js';
8
- export { COOKIE_CATEGORIES, COOKIE_CONSENT_BACKUP_KEY, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, COOKIE_CONSENT_MAX_AGE_SECONDS, DEFAULT_CONSENT_HUB_URL, DEFAULT_PREFERENCES_ACCEPTED, DEFAULT_PREFERENCES_REJECTED, EU_EEA_UK_COUNTRIES, NETWORK_CONSENT_STORAGE_KEY, acceptAllCookies, checkUrlConsentBridge, clearCookieConsent, decorateNetworkUrl, getCookieConsent, hasConsented, isCategoryAllowed, isGeoConsentRequired, queryNetworkConsentHub, recordConsentToCompliance, rejectOptionalCookies, setCookieConsent, setNetworkConsentHub } from './chunk-L5OE6DND.js';
8
+ export { CookieConsentBanner } from './chunk-5YQYJ2L2.js';
9
+ export { CookieSettingsView } from './chunk-WZ3NQRQO.js';
10
+ export { COOKIE_CATEGORIES, COOKIE_CONSENT_BACKUP_KEY, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, COOKIE_CONSENT_MAX_AGE_SECONDS, DEFAULT_CONSENT_HUB_URL, DEFAULT_PREFERENCES_ACCEPTED, DEFAULT_PREFERENCES_REJECTED, EU_EEA_UK_COUNTRIES, NETWORK_CONSENT_STORAGE_KEY, acceptAllCookies, checkUrlConsentBridge, clearCookieConsent, decorateNetworkUrl, getCookieConsent, hasConsented, isCategoryAllowed, isGeoConsentRequired, queryNetworkConsentHub, recordConsentToCompliance, rejectOptionalCookies, setCookieConsent, setNetworkConsentHub } from './chunk-QWK6G2UF.js';
9
11
 
10
12
  // src/preset.ts
11
13
  var walnutCreekTimes = definePublication({
@@ -139,4 +139,4 @@ declare function prepareClassified(input: {
139
139
  price?: unknown;
140
140
  }, towns: string[], region: string, now?: Date): PreparedClassified;
141
141
 
142
- export { CLASSIFIED_CATEGORIES as C, type EmploymentType as E, JOB_EMPLOYMENT_TYPES as J, type PreparedClassified as P, type ClassifiedCategory as a, type ClassifiedListing as b, type PreparedJob as c, type PublicDeal as d, type PublicDealOffer as e, type PublicJob as f, categoryLabel as g, classifiedPath as h, classifiedSearchPath as i, clipChars as j, dealDollars as k, dealGoPath as l, dealsFeedPath as m, employmentLabel as n, isClassifiedCategory as o, isEmploymentType as p, jobEmployerBody as q, jobOpeningBody as r, jobPostingBody as s, prepareClassified as t, prepareJobPost as u, publicJobPath as v, publicJobsPath as w };
142
+ export { type ClassifiedListing as C, type EmploymentType as E, JOB_EMPLOYMENT_TYPES as J, type PublicDeal as P, type PublicJob as a, CLASSIFIED_CATEGORIES as b, type ClassifiedCategory as c, type PreparedClassified as d, type PreparedJob as e, type PublicDealOffer as f, categoryLabel as g, classifiedPath as h, classifiedSearchPath as i, clipChars as j, dealDollars as k, dealGoPath as l, dealsFeedPath as m, employmentLabel as n, isClassifiedCategory as o, isEmploymentType as p, jobEmployerBody as q, jobOpeningBody as r, jobPostingBody as s, prepareClassified as t, prepareJobPost as u, publicJobPath as v, publicJobsPath as w };
@@ -139,4 +139,4 @@ declare function prepareClassified(input: {
139
139
  price?: unknown;
140
140
  }, towns: string[], region: string, now?: Date): PreparedClassified;
141
141
 
142
- export { CLASSIFIED_CATEGORIES as C, type EmploymentType as E, JOB_EMPLOYMENT_TYPES as J, type PreparedClassified as P, type ClassifiedCategory as a, type ClassifiedListing as b, type PreparedJob as c, type PublicDeal as d, type PublicDealOffer as e, type PublicJob as f, categoryLabel as g, classifiedPath as h, classifiedSearchPath as i, clipChars as j, dealDollars as k, dealGoPath as l, dealsFeedPath as m, employmentLabel as n, isClassifiedCategory as o, isEmploymentType as p, jobEmployerBody as q, jobOpeningBody as r, jobPostingBody as s, prepareClassified as t, prepareJobPost as u, publicJobPath as v, publicJobsPath as w };
142
+ export { type ClassifiedListing as C, type EmploymentType as E, JOB_EMPLOYMENT_TYPES as J, type PublicDeal as P, type PublicJob as a, CLASSIFIED_CATEGORIES as b, type ClassifiedCategory as c, type PreparedClassified as d, type PreparedJob as e, type PublicDealOffer as f, categoryLabel as g, classifiedPath as h, classifiedSearchPath as i, clipChars as j, dealDollars as k, dealGoPath as l, dealsFeedPath as m, employmentLabel as n, isClassifiedCategory as o, isEmploymentType as p, jobEmployerBody as q, jobOpeningBody as r, jobPostingBody as s, prepareClassified as t, prepareJobPost as u, publicJobPath as v, publicJobsPath as w };
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { b as ClassifiedListing, d as PublicDeal, f as PublicJob } from './marketplace-CpGWPbFk.cjs';
2
+ import { C as ClassifiedListing, P as PublicDeal, a as PublicJob } from './marketplace-29i5w4LS.cjs';
3
3
 
4
4
  declare function JobsBoard({ region, jobs, query }: {
5
5
  region: string;
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { b as ClassifiedListing, d as PublicDeal, f as PublicJob } from './marketplace-CpGWPbFk.js';
2
+ import { C as ClassifiedListing, P as PublicDeal, a as PublicJob } from './marketplace-29i5w4LS.js';
3
3
 
4
4
  declare function JobsBoard({ region, jobs, query }: {
5
5
  region: string;
@@ -76,4 +76,4 @@ declare function screenMessage(value: string): {
76
76
  declare function activityLabel(value: string, otherLabel?: string): string;
77
77
  declare function prepareMeetup(input: MeetupInput, places: PublicPlace[], now?: Date): PreparedMeetup;
78
78
 
79
- export { MEET_ACTIVITIES as M, type PreparedMeetup as P, type MeetActivity as a, type MeetupInput as b, type PublicPlace as c, activityLabel as d, canHostMeetup as e, isAdult as i, prepareMeetup as p, screenMessage as s };
79
+ export { MEET_ACTIVITIES as M, type PublicPlace as P, type PreparedMeetup as a, type MeetActivity as b, type MeetupInput as c, activityLabel as d, canHostMeetup as e, isAdult as i, prepareMeetup as p, screenMessage as s };
@@ -76,4 +76,4 @@ declare function screenMessage(value: string): {
76
76
  declare function activityLabel(value: string, otherLabel?: string): string;
77
77
  declare function prepareMeetup(input: MeetupInput, places: PublicPlace[], now?: Date): PreparedMeetup;
78
78
 
79
- export { MEET_ACTIVITIES as M, type PreparedMeetup as P, type MeetActivity as a, type MeetupInput as b, type PublicPlace as c, activityLabel as d, canHostMeetup as e, isAdult as i, prepareMeetup as p, screenMessage as s };
79
+ export { MEET_ACTIVITIES as M, type PublicPlace as P, type PreparedMeetup as a, type MeetActivity as b, type MeetupInput as c, activityLabel as d, canHostMeetup as e, isAdult as i, prepareMeetup as p, screenMessage as s };
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { c as PublicPlace } from './meet-5Ym5bxfh.cjs';
2
+ import { P as PublicPlace } from './meet-RWmfj3I3.cjs';
3
3
 
4
4
  declare function MeetHostForm({ places }: {
5
5
  places: PublicPlace[];
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { c as PublicPlace } from './meet-5Ym5bxfh.js';
2
+ import { P as PublicPlace } from './meet-RWmfj3I3.js';
3
3
 
4
4
  declare function MeetHostForm({ places }: {
5
5
  places: PublicPlace[];
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { P as PreparedMeetup } from './meet-5Ym5bxfh.cjs';
2
+ import { a as PreparedMeetup } from './meet-RWmfj3I3.cjs';
3
3
 
4
4
  type MeetupCard = PreparedMeetup & {
5
5
  id: string;
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { P as PreparedMeetup } from './meet-5Ym5bxfh.js';
2
+ import { a as PreparedMeetup } from './meet-RWmfj3I3.js';
3
3
 
4
4
  type MeetupCard = PreparedMeetup & {
5
5
  id: string;
@@ -0,0 +1,145 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var react = require('react');
5
+ var compliance = require('@scalemule/compliance');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ // src/network.ts
9
+ var localPublications = [
10
+ {
11
+ slug: "bayareachronicle",
12
+ name: "Bay Area Chronicle",
13
+ url: "https://bayareachronicle.com",
14
+ area: "San Francisco Bay Area",
15
+ description: "The parent home for our local community publications."
16
+ },
17
+ {
18
+ slug: "concordchronicle",
19
+ name: "Concord Chronicle",
20
+ url: "https://concordchronicle.com",
21
+ area: "Concord",
22
+ description: "A new place for Concord\u2019s local stories, independent businesses and community voices."
23
+ },
24
+ {
25
+ slug: "walnutcreektimes",
26
+ name: "Walnut Creek Times",
27
+ url: "https://walnutcreektimes.com",
28
+ area: "Walnut Creek \xB7 Rossmoor \xB7 Saranap \xB7 Pleasant Hill",
29
+ description: "A new place for Walnut Creek\u2019s local stories, independent businesses and community voices."
30
+ },
31
+ {
32
+ slug: "lamorindapost",
33
+ name: "Lamorinda Post",
34
+ url: "https://lamorindapost.com",
35
+ area: "Orinda \xB7 Lafayette \xB7 Moraga",
36
+ description: "A new home for the neighbors, businesses and community stories of Lamorinda."
37
+ },
38
+ {
39
+ slug: "alamoweekly",
40
+ name: "Alamo Weekly",
41
+ url: "https://alamoweekly.com",
42
+ area: "Alamo",
43
+ description: "A new place for Alamo\u2019s local stories, independent businesses and community voices."
44
+ },
45
+ {
46
+ slug: "danvilletimes",
47
+ name: "Danville Times",
48
+ url: "https://danvilletimes.com",
49
+ area: "Danville",
50
+ description: "A new place for Danville\u2019s local stories, independent businesses and community voices."
51
+ },
52
+ {
53
+ slug: "sanramontimes",
54
+ name: "San Ramon Times",
55
+ url: "https://sanramontimes.com",
56
+ area: "San Ramon",
57
+ description: "A new place for San Ramon\u2019s local stories, independent businesses and community voices."
58
+ },
59
+ {
60
+ slug: "diablovalleynews",
61
+ name: "Diablo Valley News",
62
+ url: "https://diablovalleynews.com",
63
+ area: "Concord \xB7 Walnut Creek \xB7 Pleasant Hill \xB7 Alamo \xB7 Danville \xB7 San Ramon",
64
+ description: "Local stories about the people, businesses and community life of the Diablo Valley."
65
+ },
66
+ {
67
+ slug: "trivalleyweekly",
68
+ name: "Tri-Valley Weekly",
69
+ url: "https://trivalleyweekly.com",
70
+ area: "Alamo \xB7 Danville \xB7 San Ramon \xB7 Dublin \xB7 Pleasanton \xB7 Livermore",
71
+ description: "Local stories about the businesses, people and community life of the Tri-Valley."
72
+ },
73
+ {
74
+ slug: "eastbaypost",
75
+ name: "East Bay Post",
76
+ url: "https://eastbaypost.com",
77
+ area: "The East Bay",
78
+ description: "A new publication connecting the people and neighborhoods of the East Bay."
79
+ },
80
+ {
81
+ slug: "napagate",
82
+ name: "Napa Gate",
83
+ url: "https://napagate.com",
84
+ area: "Napa Valley",
85
+ description: "A new local publication for the people, places and everyday life of Napa Valley.",
86
+ listed: false
87
+ }
88
+ ];
89
+ var listedPublications = localPublications.filter(
90
+ (publication) => !("listed" in publication) || publication.listed
91
+ );
92
+ listedPublications.filter(
93
+ (publication) => publication.slug !== "bayareachronicle"
94
+ );
95
+ function LocalNetworkBar({ currentSlug, className = "", style }) {
96
+ const [open, setOpen] = react.useState(false);
97
+ const id = react.useId();
98
+ const button = react.useRef(null);
99
+ return /* @__PURE__ */ jsxRuntime.jsx(
100
+ "nav",
101
+ {
102
+ className: `sm-network-bar ${className}`.trim(),
103
+ style,
104
+ "aria-label": "Local publication network",
105
+ onKeyDown: (e) => {
106
+ if (e.key === "Escape" && open) {
107
+ setOpen(false);
108
+ button.current?.focus();
109
+ }
110
+ },
111
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sm-network-inner", children: [
112
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sm-network-label", children: "Our local sites" }),
113
+ /* @__PURE__ */ jsxRuntime.jsxs(
114
+ "button",
115
+ {
116
+ className: "sm-network-selector",
117
+ ref: button,
118
+ "aria-expanded": open,
119
+ "aria-controls": id,
120
+ onClick: () => setOpen(!open),
121
+ type: "button",
122
+ children: [
123
+ "Our local sites ",
124
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: open ? "\u2212" : "+" })
125
+ ]
126
+ }
127
+ ),
128
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { id, className: `sm-network-sites ${open ? "sm-network-expanded" : ""}`, "aria-label": "All local publications", children: listedPublications.map((publication) => {
129
+ const isCurrent = publication.slug === currentSlug;
130
+ const targetUrl = isCurrent ? publication.url + "/" : compliance.decorateNetworkUrl(publication.url + "/");
131
+ return /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
132
+ "a",
133
+ {
134
+ href: targetUrl,
135
+ "aria-current": isCurrent ? "true" : void 0,
136
+ children: publication.name
137
+ }
138
+ ) }, publication.slug);
139
+ }) })
140
+ ] })
141
+ }
142
+ );
143
+ }
144
+
145
+ exports.LocalNetworkBar = LocalNetworkBar;
@@ -0,0 +1,15 @@
1
+ import * as react from 'react';
2
+ import { CSSProperties } from 'react';
3
+
4
+ interface LocalNetworkBarProps {
5
+ currentSlug: string;
6
+ className?: string;
7
+ style?: CSSProperties;
8
+ }
9
+ /**
10
+ * Global navigation bar for the Bay Area Local News network.
11
+ * Links across independent publication origins, transferring consent tokens automatically.
12
+ */
13
+ declare function LocalNetworkBar({ currentSlug, className, style }: LocalNetworkBarProps): react.JSX.Element;
14
+
15
+ export { LocalNetworkBar, type LocalNetworkBarProps };
@@ -0,0 +1,15 @@
1
+ import * as react from 'react';
2
+ import { CSSProperties } from 'react';
3
+
4
+ interface LocalNetworkBarProps {
5
+ currentSlug: string;
6
+ className?: string;
7
+ style?: CSSProperties;
8
+ }
9
+ /**
10
+ * Global navigation bar for the Bay Area Local News network.
11
+ * Links across independent publication origins, transferring consent tokens automatically.
12
+ */
13
+ declare function LocalNetworkBar({ currentSlug, className, style }: LocalNetworkBarProps): react.JSX.Element;
14
+
15
+ export { LocalNetworkBar, type LocalNetworkBarProps };
@@ -0,0 +1,3 @@
1
+ export { LocalNetworkBar } from './chunk-7TBML5Q7.js';
2
+ import './chunk-5W4EMBFY.js';
3
+ import './chunk-QWK6G2UF.js';