@scalemule/news-publication 0.0.59 → 0.0.61

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.
@@ -232,6 +232,17 @@ var NETWORK_PARENT = {
232
232
  principles: EDITORIAL_PRINCIPLES
233
233
  };
234
234
  var localPublications = [
235
+ {
236
+ slug: "lazytensor",
237
+ name: "Lazy Tensor",
238
+ url: "https://lazytensor.com",
239
+ area: "Silicon Valley \xB7 AI & Technology",
240
+ focus: "AI & Technology",
241
+ kind: "topical",
242
+ slogan: "Technology, Intelligence & Everything in Between.",
243
+ description: "The network's technology publication: artificial intelligence, computing, science, startups and what technology means for the people and communities of Silicon Valley and the Bay Area.",
244
+ aboutIntro: "Lazy Tensor is the Bay Area News Network's dedicated technology publication. We report on artificial intelligence, computing, science and the companies, researchers and founders of Silicon Valley, and we explain what those developments mean for readers' lives, work and communities. Our principle is simple: understand the technology, question the hype, explain what matters. Lazy Tensor also gathers the technology reporting of the network's local newsrooms in one place, always with credit to the paper that reported the story first."
245
+ },
235
246
  {
236
247
  slug: "bayareachronicle",
237
248
  name: "Bay Area Chronicle",
@@ -337,7 +348,10 @@ var listedPublications = localPublications.filter(
337
348
  (publication) => !("listed" in publication) || publication.listed
338
349
  );
339
350
  var communityPublications = listedPublications.filter(
340
- (publication) => publication.slug !== "bayareachronicle"
351
+ (publication) => publication.slug !== "bayareachronicle" && publication.kind !== "topical"
352
+ );
353
+ var topicalPublications = listedPublications.filter(
354
+ (publication) => publication.kind === "topical"
341
355
  );
342
356
  function findPublicationBySlug(slug) {
343
357
  return localPublications.find((p) => p.slug === slug);
@@ -369,4 +383,4 @@ function isNetworkHostname(hostname) {
369
383
  return clean === "bayareanewsnetwork.com" || clean.endsWith(".bayareanewsnetwork.com") || NETWORK_HOSTNAMES.has(clean) || clean.endsWith(".bayareachronicle.com") || clean.endsWith(".napsite.com") || clean.endsWith(".site.scalemule.com");
370
384
  }
371
385
 
372
- export { COOKIE_CATEGORIES, EDITORIAL_PRINCIPLES, NETWORK_PARENT, communityPublications, findPublicationByHost, findPublicationBySlug, getNetworkPublicationUrl, isNetworkHostname, listedPublications, localPublications, recordConsentToCompliance, setupNetworkConsentDelegation };
386
+ export { COOKIE_CATEGORIES, EDITORIAL_PRINCIPLES, NETWORK_PARENT, communityPublications, findPublicationByHost, findPublicationBySlug, getNetworkPublicationUrl, isNetworkHostname, listedPublications, localPublications, recordConsentToCompliance, setupNetworkConsentDelegation, topicalPublications };
@@ -1,4 +1,4 @@
1
- import { NETWORK_PARENT } from './chunk-JV76ZEIA.js';
1
+ import { NETWORK_PARENT } from './chunk-6S5FARL3.js';
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
3
 
4
4
  function NetworkCopyrightNotice({
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { setupNetworkConsentDelegation, COOKIE_CONSENT_EVENT, listedPublications, decorateNetworkUrl } from './chunk-JV76ZEIA.js';
2
+ import { setupNetworkConsentDelegation, COOKIE_CONSENT_EVENT, listedPublications, decorateNetworkUrl } from './chunk-6S5FARL3.js';
3
3
  import { useState, useId, useRef, useEffect } from 'react';
4
4
  import { jsx, jsxs } from 'react/jsx-runtime';
5
5
 
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { getCookieConsent, DEFAULT_PREFERENCES_ACCEPTED, COOKIE_CATEGORIES, setCookieConsent, recordConsentToCompliance, DEFAULT_PREFERENCES_REJECTED } from './chunk-JV76ZEIA.js';
2
+ import { getCookieConsent, DEFAULT_PREFERENCES_ACCEPTED, COOKIE_CATEGORIES, setCookieConsent, recordConsentToCompliance, DEFAULT_PREFERENCES_REJECTED } from './chunk-6S5FARL3.js';
3
3
  import { useState, useEffect } from 'react';
4
4
  import { jsxs, jsx } from 'react/jsx-runtime';
5
5
 
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { hasConsented, rejectOptionalCookies, DEFAULT_CONSENT_HUB_URL, isGpcActive, COOKIE_CONSENT_EVENT, acceptAllCookies, recordConsentToCompliance } from './chunk-JV76ZEIA.js';
2
+ import { hasConsented, rejectOptionalCookies, DEFAULT_CONSENT_HUB_URL, isGpcActive, COOKIE_CONSENT_EVENT, acceptAllCookies, recordConsentToCompliance } from './chunk-6S5FARL3.js';
3
3
  import { useState, useEffect } from 'react';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
 
@@ -7,6 +7,17 @@ var jsxRuntime = require('react/jsx-runtime');
7
7
 
8
8
  // src/network.ts
9
9
  var localPublications = [
10
+ {
11
+ slug: "lazytensor",
12
+ name: "Lazy Tensor",
13
+ url: "https://lazytensor.com",
14
+ area: "Silicon Valley \xB7 AI & Technology",
15
+ focus: "AI & Technology",
16
+ kind: "topical",
17
+ slogan: "Technology, Intelligence & Everything in Between.",
18
+ description: "The network's technology publication: artificial intelligence, computing, science, startups and what technology means for the people and communities of Silicon Valley and the Bay Area.",
19
+ aboutIntro: "Lazy Tensor is the Bay Area News Network's dedicated technology publication. We report on artificial intelligence, computing, science and the companies, researchers and founders of Silicon Valley, and we explain what those developments mean for readers' lives, work and communities. Our principle is simple: understand the technology, question the hype, explain what matters. Lazy Tensor also gathers the technology reporting of the network's local newsrooms in one place, always with credit to the paper that reported the story first."
20
+ },
10
21
  {
11
22
  slug: "bayareachronicle",
12
23
  name: "Bay Area Chronicle",
@@ -112,7 +123,10 @@ var listedPublications = localPublications.filter(
112
123
  (publication) => !("listed" in publication) || publication.listed
113
124
  );
114
125
  listedPublications.filter(
115
- (publication) => publication.slug !== "bayareachronicle"
126
+ (publication) => publication.slug !== "bayareachronicle" && publication.kind !== "topical"
127
+ );
128
+ listedPublications.filter(
129
+ (publication) => publication.kind === "topical"
116
130
  );
117
131
  new Set(
118
132
  localPublications.map((p) => {
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- export { CookieConsentBanner } from './chunk-GOWOYMSG.js';
3
- import './chunk-JV76ZEIA.js';
2
+ export { CookieConsentBanner } from './chunk-XPOZGZTM.js';
3
+ import './chunk-6S5FARL3.js';
@@ -7,6 +7,17 @@ var jsxRuntime = require('react/jsx-runtime');
7
7
 
8
8
  // src/network.ts
9
9
  var localPublications = [
10
+ {
11
+ slug: "lazytensor",
12
+ name: "Lazy Tensor",
13
+ url: "https://lazytensor.com",
14
+ area: "Silicon Valley \xB7 AI & Technology",
15
+ focus: "AI & Technology",
16
+ kind: "topical",
17
+ slogan: "Technology, Intelligence & Everything in Between.",
18
+ description: "The network's technology publication: artificial intelligence, computing, science, startups and what technology means for the people and communities of Silicon Valley and the Bay Area.",
19
+ aboutIntro: "Lazy Tensor is the Bay Area News Network's dedicated technology publication. We report on artificial intelligence, computing, science and the companies, researchers and founders of Silicon Valley, and we explain what those developments mean for readers' lives, work and communities. Our principle is simple: understand the technology, question the hype, explain what matters. Lazy Tensor also gathers the technology reporting of the network's local newsrooms in one place, always with credit to the paper that reported the story first."
20
+ },
10
21
  {
11
22
  slug: "bayareachronicle",
12
23
  name: "Bay Area Chronicle",
@@ -112,7 +123,10 @@ var listedPublications = localPublications.filter(
112
123
  (publication) => !("listed" in publication) || publication.listed
113
124
  );
114
125
  listedPublications.filter(
115
- (publication) => publication.slug !== "bayareachronicle"
126
+ (publication) => publication.slug !== "bayareachronicle" && publication.kind !== "topical"
127
+ );
128
+ listedPublications.filter(
129
+ (publication) => publication.kind === "topical"
116
130
  );
117
131
  new Set(
118
132
  localPublications.map((p) => {
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- export { CookieSettingsView } from './chunk-UL2Q3N26.js';
3
- import './chunk-JV76ZEIA.js';
2
+ export { CookieSettingsView } from './chunk-GYYUJYI4.js';
3
+ import './chunk-6S5FARL3.js';
package/dist/index.cjs CHANGED
@@ -633,6 +633,156 @@ function defaultRevalidateTargets() {
633
633
  };
634
634
  }
635
635
 
636
+ // src/navigation.ts
637
+ var NAVIGATION_GROUPS = [
638
+ { id: "news-knowledge", label: "News & knowledge" },
639
+ { id: "local-life", label: "Local life" },
640
+ { id: "marketplace", label: "Marketplace" },
641
+ { id: "publication", label: "Publication" }
642
+ ];
643
+ function editorial(id, section, overrides = {}) {
644
+ return {
645
+ id,
646
+ section,
647
+ kind: "editorial",
648
+ label: sectionDefinition(section).label,
649
+ href: sectionPath(section),
650
+ order: 0,
651
+ priority: 0,
652
+ ...overrides
653
+ };
654
+ }
655
+ var NETWORK_NAVIGATION = [
656
+ // Primary editorial row. "News" is the Civic life desk; the section slug and story classifications are unchanged.
657
+ editorial("news", "Civic life", { label: "News", order: 10, priority: 100, primary: true }),
658
+ editorial("community", "Community", { order: 20, priority: 90, primary: true }),
659
+ editorial("food-drink", "Food & places", { order: 30, priority: 85, primary: true }),
660
+ editorial("things-to-do", "Events", { order: 40, priority: 80, primary: true }),
661
+ editorial("health", "Health", { order: 50, priority: 75, primary: true }),
662
+ editorial("real-estate", "Real Estate", { order: 60, priority: 70, primary: true }),
663
+ { id: "autos", label: "Autos", href: "/autos", kind: "marketplace", group: "marketplace", order: 65, priority: 65, primary: true, more: true, enabled: false },
664
+ editorial("business", "Local businesses", { order: 70, priority: 60, primary: true }),
665
+ { id: "meet", label: "Meet", href: "/meet", kind: "product", order: 80, priority: 50, primary: true, feature: "chat" },
666
+ { id: "jokes", label: "Jokes", href: "/smile", kind: "product", order: 90, priority: 40, primary: true, feature: "smile" },
667
+ // More — News & knowledge.
668
+ editorial("ai-technology", "AI & Technology", { label: "AI & technology", group: "news-knowledge", order: 10, more: true }),
669
+ editorial("schools", "Schools", { label: "Schools & education", group: "news-knowledge", order: 20, more: true }),
670
+ editorial("civic-life", "Civic life", { group: "news-knowledge", order: 30, more: true }),
671
+ editorial("environment", "Environment", { group: "news-knowledge", order: 40, more: true }),
672
+ editorial("transportation", "Transportation", { group: "news-knowledge", order: 50, more: true }),
673
+ // More — Local life.
674
+ { id: "pets", label: "Pets", href: "/pets", kind: "product", group: "local-life", order: 10, more: true },
675
+ { id: "celebrations", label: "Celebrations", href: "/sections/celebrations", kind: "product", group: "local-life", order: 20, more: true, enabled: false },
676
+ { id: "community-maps", label: "Community maps", href: "/community-maps", kind: "product", group: "local-life", order: 30, more: true },
677
+ { id: "town-chat", label: "Town chat", href: "/chat", kind: "product", group: "local-life", order: 40, more: true, feature: "chat" },
678
+ { id: "neighborhood-guides", label: "Neighborhood guides", href: "/guides", kind: "product", group: "local-life", order: 50, more: true, enabled: false },
679
+ { id: "poll", label: "Poll", href: "/polls", kind: "product", group: "local-life", order: 60, more: true, publications: ["walnutcreektimes"] },
680
+ // More — Marketplace.
681
+ { id: "jobs", label: "Jobs", href: "/jobs", kind: "marketplace", group: "marketplace", order: 10, more: true, feature: "jobs" },
682
+ { id: "classifieds", label: "Classifieds", href: "/classifieds", kind: "marketplace", group: "marketplace", order: 20, more: true, feature: "classifieds" },
683
+ { id: "local-services", label: "Local services", href: "/services", kind: "marketplace", group: "marketplace", order: 40, more: true, enabled: false },
684
+ // More — Publication.
685
+ { id: "latest", label: "Latest", href: "/news", kind: "publication", group: "publication", order: 10, more: true },
686
+ { id: "this-week", label: "This week", href: "/this-week", kind: "publication", group: "publication", order: 20, more: true },
687
+ { id: "newsletter", label: "Newsletter", href: "/newsletter", kind: "publication", group: "publication", order: 30, more: true },
688
+ { id: "about", label: "About", href: "/about", kind: "publication", group: "publication", order: 40, more: true },
689
+ { id: "advertise", label: "Advertise", href: "/advertise", kind: "publication", group: "publication", order: 50, more: true },
690
+ { id: "contact", label: "Contact", href: "/contact", kind: "publication", group: "publication", order: 60, more: true }
691
+ ];
692
+ var MAX_LABEL = 60;
693
+ function safeHref(href) {
694
+ if (typeof href !== "string") return null;
695
+ const value = href.trim();
696
+ if (!value.startsWith("/") || value.startsWith("//") || /[\s\\]/.test(value)) return null;
697
+ return value;
698
+ }
699
+ function safeLabel(label) {
700
+ if (typeof label !== "string") return null;
701
+ const value = label.trim();
702
+ return value && value.length <= MAX_LABEL ? value : null;
703
+ }
704
+ var GROUP_IDS = new Set(NAVIGATION_GROUPS.map((group) => group.id));
705
+ var KINDS = /* @__PURE__ */ new Set(["editorial", "product", "marketplace", "publication"]);
706
+ function applyNavigationConfig(defaults, config) {
707
+ const merged = new Map(defaults.map((destination) => [destination.id, { ...destination }]));
708
+ for (const override of config?.destinations ?? []) {
709
+ if (!override || typeof override.id !== "string" || !override.id) continue;
710
+ const current = merged.get(override.id);
711
+ const label = safeLabel(override.label);
712
+ const href = safeHref(override.href);
713
+ if (!current && !(label && href)) continue;
714
+ const next = current ? { ...current } : {
715
+ id: override.id,
716
+ label,
717
+ href,
718
+ kind: "product",
719
+ order: 1e3,
720
+ priority: 0
721
+ };
722
+ if (label) next.label = label;
723
+ if (href) next.href = href;
724
+ if (typeof override.order === "number" && Number.isFinite(override.order)) next.order = override.order;
725
+ if (typeof override.priority === "number" && Number.isFinite(override.priority)) next.priority = override.priority;
726
+ if (typeof override.enabled === "boolean") next.enabled = override.enabled;
727
+ if (typeof override.primary === "boolean") next.primary = override.primary;
728
+ if (typeof override.more === "boolean") next.more = override.more;
729
+ if (override.group && GROUP_IDS.has(override.group)) next.group = override.group;
730
+ if (override.kind && KINDS.has(override.kind)) next.kind = override.kind;
731
+ if (typeof override.section === "string") next.section = override.section;
732
+ if (typeof override.feature === "string") next.feature = override.feature;
733
+ if (Array.isArray(override.publications)) next.publications = override.publications.filter((slug) => typeof slug === "string");
734
+ merged.set(next.id, next);
735
+ }
736
+ return Array.from(merged.values());
737
+ }
738
+ function activeFeatured(config, now) {
739
+ if (config?.featured === null) return null;
740
+ const featured = config?.featured;
741
+ if (!featured) return void 0;
742
+ const label = safeLabel(featured.label);
743
+ const href = safeHref(featured.href);
744
+ if (!label || !href) return void 0;
745
+ const time = now.getTime();
746
+ if (featured.from && time < Date.parse(featured.from)) return void 0;
747
+ if (featured.until && time >= Date.parse(featured.until)) return void 0;
748
+ return { label, href };
749
+ }
750
+ function resolveNavigation(context) {
751
+ const now = context.now ?? /* @__PURE__ */ new Date();
752
+ const sections2 = /* @__PURE__ */ new Set([...context.sections ?? [], ...context.discovered ?? []]);
753
+ const featureEnabled2 = context.featureEnabled ?? (() => false);
754
+ const destinations = applyNavigationConfig(NETWORK_NAVIGATION, context.config);
755
+ const visible = destinations.filter((destination) => {
756
+ if (destination.enabled === false) return false;
757
+ if (destination.feature && !featureEnabled2(destination.feature)) return false;
758
+ if (destination.section && !sections2.has(destination.section)) return false;
759
+ if (destination.publications && !destination.publications.includes(context.publication)) return false;
760
+ return true;
761
+ });
762
+ const link = (destination) => ({
763
+ id: destination.id,
764
+ label: destination.label,
765
+ href: destination.href,
766
+ kind: destination.kind,
767
+ priority: destination.priority ?? 0
768
+ });
769
+ const byOrder = (left, right) => left.order - right.order || left.label.localeCompare(right.label);
770
+ const primary = visible.filter((destination) => destination.primary).sort(byOrder).map(link);
771
+ const covered = new Set(destinations.map((destination) => destination.section).filter(Boolean));
772
+ const stray = [...new Set(context.discovered ?? [])].filter((name) => name !== "Local news" && !covered.has(name)).sort((left, right) => left.localeCompare(right)).map((name) => {
773
+ const definition = sectionDefinition(name);
774
+ return { id: definition.id, label: definition.label, href: sectionPath(name), kind: "editorial", priority: 0 };
775
+ });
776
+ const groups = NAVIGATION_GROUPS.map((group) => ({
777
+ ...group,
778
+ links: [
779
+ ...visible.filter((destination) => destination.more && destination.group === group.id).sort(byOrder).map(link),
780
+ ...group.id === "news-knowledge" ? stray : []
781
+ ]
782
+ })).filter((group) => group.links.length > 0);
783
+ return { primary, groups, featured: activeFeatured(context.config, now) };
784
+ }
785
+
636
786
  // src/analytics.ts
637
787
  var ANALYTICS_VERSION = 1;
638
788
  var ANALYTICS_COOKIE = "napsite_analytics_v1";
@@ -1164,6 +1314,17 @@ var NETWORK_PARENT = {
1164
1314
  principles: EDITORIAL_PRINCIPLES
1165
1315
  };
1166
1316
  var localPublications = [
1317
+ {
1318
+ slug: "lazytensor",
1319
+ name: "Lazy Tensor",
1320
+ url: "https://lazytensor.com",
1321
+ area: "Silicon Valley \xB7 AI & Technology",
1322
+ focus: "AI & Technology",
1323
+ kind: "topical",
1324
+ slogan: "Technology, Intelligence & Everything in Between.",
1325
+ description: "The network's technology publication: artificial intelligence, computing, science, startups and what technology means for the people and communities of Silicon Valley and the Bay Area.",
1326
+ aboutIntro: "Lazy Tensor is the Bay Area News Network's dedicated technology publication. We report on artificial intelligence, computing, science and the companies, researchers and founders of Silicon Valley, and we explain what those developments mean for readers' lives, work and communities. Our principle is simple: understand the technology, question the hype, explain what matters. Lazy Tensor also gathers the technology reporting of the network's local newsrooms in one place, always with credit to the paper that reported the story first."
1327
+ },
1167
1328
  {
1168
1329
  slug: "bayareachronicle",
1169
1330
  name: "Bay Area Chronicle",
@@ -1269,7 +1430,10 @@ var listedPublications = localPublications.filter(
1269
1430
  (publication) => !("listed" in publication) || publication.listed
1270
1431
  );
1271
1432
  var communityPublications = listedPublications.filter(
1272
- (publication) => publication.slug !== "bayareachronicle"
1433
+ (publication) => publication.slug !== "bayareachronicle" && publication.kind !== "topical"
1434
+ );
1435
+ var topicalPublications = listedPublications.filter(
1436
+ (publication) => publication.kind === "topical"
1273
1437
  );
1274
1438
  function findPublicationBySlug(slug) {
1275
1439
  return localPublications.find((p) => p.slug === slug);
@@ -3464,6 +3628,8 @@ exports.LAYOUT_COOKIE = LAYOUT_COOKIE;
3464
3628
  exports.LOCAL_BRIEFING_POLICY_VERSION = LOCAL_BRIEFING_POLICY_VERSION;
3465
3629
  exports.LocalNetworkBar = LocalNetworkBar;
3466
3630
  exports.MEET_ACTIVITIES = MEET_ACTIVITIES;
3631
+ exports.NAVIGATION_GROUPS = NAVIGATION_GROUPS;
3632
+ exports.NETWORK_NAVIGATION = NETWORK_NAVIGATION;
3467
3633
  exports.NETWORK_PARENT = NETWORK_PARENT;
3468
3634
  exports.NEWS_CACHE = NEWS_CACHE;
3469
3635
  exports.NetworkCopyrightNotice = NetworkCopyrightNotice;
@@ -3484,6 +3650,7 @@ exports.acceptRemoteRecord = acceptRemoteRecord;
3484
3650
  exports.acceptSnapshot = acceptSnapshot;
3485
3651
  exports.activeNearby = activeNearby;
3486
3652
  exports.activityLabel = activityLabel;
3653
+ exports.applyNavigationConfig = applyNavigationConfig;
3487
3654
  exports.applyTheme = applyTheme;
3488
3655
  exports.articleCacheKey = articleCacheKey;
3489
3656
  exports.articleCacheOptions = articleCacheOptions;
@@ -3562,6 +3729,7 @@ exports.renderArticleBlocksToHtml = renderArticleBlocksToHtml;
3562
3729
  exports.resolveCoupon = resolveCoupon;
3563
3730
  exports.resolveEffectiveTheme = resolveEffectiveTheme;
3564
3731
  exports.resolveLayout = resolveLayout;
3732
+ exports.resolveNavigation = resolveNavigation;
3565
3733
  exports.resolveSection = resolveSection;
3566
3734
  exports.revalidateDecision = revalidateDecision;
3567
3735
  exports.safeSponsorUrl = safeSponsorUrl;
@@ -3581,6 +3749,7 @@ exports.storyTowns = storyTowns;
3581
3749
  exports.subscribeTheme = subscribeTheme;
3582
3750
  exports.syncPublication = syncPublication;
3583
3751
  exports.themeInitScript = themeInitScript;
3752
+ exports.topicalPublications = topicalPublications;
3584
3753
  exports.townSlug = townSlug;
3585
3754
  exports.validCalendarDate = validCalendarDate;
3586
3755
  exports.walnutCreekTimes = walnutCreekTimes;
package/dist/index.d.cts CHANGED
@@ -8,7 +8,7 @@ export { COOKIE_CONSENT_BACKUP_KEY, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, CO
8
8
  export { CookieConsentBanner, CookieConsentBannerProps } from './cookie-consent-banner.cjs';
9
9
  export { CookieSettingsView, CookieSettingsViewProps } from './cookie-settings-view.cjs';
10
10
  export { ThemeToggle, ThemeToggleProps } from './theme-toggle.cjs';
11
- export { EDITORIAL_PRINCIPLES, EditorialPrinciple, NETWORK_PARENT, NetworkParent, PublicationNetworkItem, communityPublications, findPublicationByHost, findPublicationBySlug, getNetworkPublicationUrl, listedPublications, localPublications } from './network.cjs';
11
+ export { EDITORIAL_PRINCIPLES, EditorialPrinciple, NETWORK_PARENT, NetworkParent, PublicationNetworkItem, communityPublications, findPublicationByHost, findPublicationBySlug, getNetworkPublicationUrl, listedPublications, localPublications, topicalPublications } from './network.cjs';
12
12
  export { LocalNetworkBar, LocalNetworkBarProps } from './network-bar.cjs';
13
13
  export { NetworkCopyrightNotice, NetworkCopyrightNoticeProps } from './network-copyright.cjs';
14
14
  import * as React from 'react';
@@ -274,6 +274,113 @@ declare function nearbyUpdates(items: NewsItem[], selection?: HomepageSelection,
274
274
  declare function shortDeck(value: string | null | undefined, limit?: number): string;
275
275
  declare function storyDate(value: string): string | null;
276
276
 
277
+ /**
278
+ * Shared network navigation.
279
+ *
280
+ * One configuration drives the primary row, the More menu and the hamburger
281
+ * directory on every Bay Area News Network paper. The defaults below ship in
282
+ * this package; day-to-day changes (labels, order, enabling Autos, a featured
283
+ * seasonal destination) are `NavigationConfig` overrides stored in each
284
+ * paper's site record and picked up at request time — no release required.
285
+ */
286
+ /** Editorial sections, community products and marketplaces stay distinct in config even where readers see one row. */
287
+ type NavigationKind = "editorial" | "product" | "marketplace" | "publication";
288
+ type NavigationGroup = "news-knowledge" | "local-life" | "marketplace" | "publication";
289
+ declare const NAVIGATION_GROUPS: {
290
+ id: NavigationGroup;
291
+ label: string;
292
+ }[];
293
+ type NavigationDestination = {
294
+ /** Stable identifier; overrides and additions merge by id. */
295
+ id: string;
296
+ label: string;
297
+ href: string;
298
+ kind: NavigationKind;
299
+ /** More-menu column; destinations without a group never render in More. */
300
+ group?: NavigationGroup;
301
+ /** Reading order inside the primary row and inside each More group. */
302
+ order: number;
303
+ /** Responsive weight: when the row runs out of width, lower priority collapses into More first. */
304
+ priority?: number;
305
+ /** Renders in the primary editorial row. */
306
+ primary?: boolean;
307
+ /** Renders in its group inside the More menu. */
308
+ more?: boolean;
309
+ /** Hidden everywhere until enabled (default true). */
310
+ enabled?: boolean;
311
+ /** Publication feature flag that must be on (e.g. "jobs", "chat", "smile", "classifieds"). */
312
+ feature?: string;
313
+ /** Canonical section name: shown only when the publication configures or publishes the section. */
314
+ section?: string;
315
+ /** Restricts the destination to the listed publication slugs. */
316
+ publications?: string[];
317
+ };
318
+ /** Record-stored delta applied over the shipped defaults. Unknown ids with a label and href are additions. */
319
+ type NavigationOverride = {
320
+ id: string;
321
+ } & Partial<Omit<NavigationDestination, "id">>;
322
+ type FeaturedDestination = {
323
+ label: string;
324
+ href: string;
325
+ /** ISO instants limiting when the promotion shows. */
326
+ from?: string;
327
+ until?: string;
328
+ };
329
+ /** Stored in the site record under `render.navigation`. Everything is optional: absent fields keep defaults. */
330
+ type NavigationConfig = {
331
+ version?: 1;
332
+ destinations?: NavigationOverride[];
333
+ /** Overrides the seasonal featured slot; `null` suppresses it entirely. */
334
+ featured?: FeaturedDestination | null;
335
+ };
336
+ /**
337
+ * The network-wide default navigation. Primary order and collapse priority
338
+ * follow the 2026 information architecture: editorial sections first, then
339
+ * the community products. "Front page" is the masthead's job, so it is not a
340
+ * destination. Autos ships disabled; enabling it is a record override.
341
+ */
342
+ declare const NETWORK_NAVIGATION: NavigationDestination[];
343
+ type NavigationLink = {
344
+ id: string;
345
+ label: string;
346
+ href: string;
347
+ kind: NavigationKind;
348
+ priority: number;
349
+ };
350
+ type NavigationGroupLinks = {
351
+ id: NavigationGroup;
352
+ label: string;
353
+ links: NavigationLink[];
354
+ };
355
+ type ResolvedNavigation = {
356
+ /** Editorial row in reading order; collapse into More by ascending priority. */
357
+ primary: NavigationLink[];
358
+ /** More-menu columns in canonical group order; empty groups are dropped. */
359
+ groups: NavigationGroupLinks[];
360
+ /** Active featured promotion from config, if any. `null` means "configured off". */
361
+ featured?: {
362
+ label: string;
363
+ href: string;
364
+ } | null;
365
+ };
366
+ type NavigationContext = {
367
+ /** This paper's slug. */
368
+ publication: string;
369
+ /** Sections the publication configures (profile taxonomy). */
370
+ sections?: string[];
371
+ /** Sections observed in the live feed; they satisfy a section gate too. */
372
+ discovered?: string[];
373
+ /** Publication feature flags. */
374
+ featureEnabled?: (feature: string) => boolean;
375
+ /** Record-stored overrides. Invalid entries are ignored, never fatal. */
376
+ config?: NavigationConfig | null;
377
+ now?: Date;
378
+ };
379
+ /** Apply record overrides defensively: the record is data, never trusted markup or routing. */
380
+ declare function applyNavigationConfig(defaults: NavigationDestination[], config: NavigationConfig | null | undefined): NavigationDestination[];
381
+ /** The one place that decides what every reader-facing menu shows. */
382
+ declare function resolveNavigation(context: NavigationContext): ResolvedNavigation;
383
+
277
384
  /** https URL with no userinfo. Anything else is dropped from public markup. */
278
385
  declare function publicHttps(value?: string | null): string | undefined;
279
386
  declare function articleUrl(canonical: string, slug: string): string;
@@ -514,4 +621,4 @@ interface SponsorshipReport {
514
621
  /** Shared by the newsroom print/export view and the repeatable PDF renderer. */
515
622
  declare function campaignReportHtml(report: SponsorshipReport): string;
516
623
 
517
- export { ANALYTICS_COOKIE, ANALYTICS_VERSION, ArticleProvenance, type Attribution, BROADSHEET_THEME, type BriefingCandidate, type BriefingPreferences, type BriefingReason, type BriefingSection, type BriefingSource, type BriefingVerification, COOKIE_CATEGORIES, CURATED_COMMUNITY_CARDS, CouponOffer, EDITORIAL_SECTION_ORDER, EVENTS, EditorialSection, type EffectiveTheme, FeatureName, HomepageSelection, LAYOUT_COOKIE, LOCAL_BRIEFING_POLICY_VERSION, type ListeningArticle, type LocalBriefing, type LocalBriefingItem, type LocalBriefingOptions, Measurement, NEWS_CACHE, NearbyUpdate, NewsArticle, NewsError, NewsItem, NewsPublication, PublicationInput, PublicationTheme, SESSION_IDLE_MS, type SponsorshipReport, THEME_COOKIE, THEME_EVENT, THEME_MAX_AGE_SECONDS, THEME_STORAGE_KEY, type ThemeMode, UTM_FIELDS, UUID, activeNearby, applyTheme, articleCacheKey, articleCacheOptions, articleMeta, articleUrl, attribution, briefSummary, campaignReportHtml, clearTheme, composeEdition, composeLocalBriefing, defaultRevalidateTargets, definePublication, displayHeadline, edgeCacheControl, editorialSections, featureEnabled, feedCacheKey, feedCacheOptions, filterNews, getStoredTheme, getSystemTheme, inventoryCacheOptions, llmsText, matchesStoryTag, measurementConsent, nearbyUpdates, newsArticleJsonLd, normalizedText, orderedSections, publicHttps, publicUrl, publicationJsonLd, publicationListeningCandidates, publicationListeningTrack, publicationMeta, readerSources, recordConsentToCompliance, referralCode, resolveCoupon, resolveEffectiveTheme, resolveLayout, resolveSection, revalidateDecision, secretsMatch, sectionDefinition, sectionId, sectionPath, setTheme, shortDeck, shortText, shouldServeLastKnown, storyDate, storyTowns, subscribeTheme, themeInitScript, townSlug, validCalendarDate, walnutCreekTimes, withLastKnown };
624
+ export { ANALYTICS_COOKIE, ANALYTICS_VERSION, ArticleProvenance, type Attribution, BROADSHEET_THEME, type BriefingCandidate, type BriefingPreferences, type BriefingReason, type BriefingSection, type BriefingSource, type BriefingVerification, COOKIE_CATEGORIES, CURATED_COMMUNITY_CARDS, CouponOffer, EDITORIAL_SECTION_ORDER, EVENTS, EditorialSection, type EffectiveTheme, FeatureName, type FeaturedDestination, HomepageSelection, LAYOUT_COOKIE, LOCAL_BRIEFING_POLICY_VERSION, type ListeningArticle, type LocalBriefing, type LocalBriefingItem, type LocalBriefingOptions, Measurement, NAVIGATION_GROUPS, NETWORK_NAVIGATION, NEWS_CACHE, type NavigationConfig, type NavigationContext, type NavigationDestination, type NavigationGroup, type NavigationGroupLinks, type NavigationKind, type NavigationLink, type NavigationOverride, NearbyUpdate, NewsArticle, NewsError, NewsItem, NewsPublication, PublicationInput, PublicationTheme, type ResolvedNavigation, SESSION_IDLE_MS, type SponsorshipReport, THEME_COOKIE, THEME_EVENT, THEME_MAX_AGE_SECONDS, THEME_STORAGE_KEY, type ThemeMode, UTM_FIELDS, UUID, activeNearby, applyNavigationConfig, applyTheme, articleCacheKey, articleCacheOptions, articleMeta, articleUrl, attribution, briefSummary, campaignReportHtml, clearTheme, composeEdition, composeLocalBriefing, defaultRevalidateTargets, definePublication, displayHeadline, edgeCacheControl, editorialSections, featureEnabled, feedCacheKey, feedCacheOptions, filterNews, getStoredTheme, getSystemTheme, inventoryCacheOptions, llmsText, matchesStoryTag, measurementConsent, nearbyUpdates, newsArticleJsonLd, normalizedText, orderedSections, publicHttps, publicUrl, publicationJsonLd, publicationListeningCandidates, publicationListeningTrack, publicationMeta, readerSources, recordConsentToCompliance, referralCode, resolveCoupon, resolveEffectiveTheme, resolveLayout, resolveNavigation, resolveSection, revalidateDecision, secretsMatch, sectionDefinition, sectionId, sectionPath, setTheme, shortDeck, shortText, shouldServeLastKnown, storyDate, storyTowns, subscribeTheme, themeInitScript, townSlug, validCalendarDate, walnutCreekTimes, withLastKnown };
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@ export { COOKIE_CONSENT_BACKUP_KEY, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, CO
8
8
  export { CookieConsentBanner, CookieConsentBannerProps } from './cookie-consent-banner.js';
9
9
  export { CookieSettingsView, CookieSettingsViewProps } from './cookie-settings-view.js';
10
10
  export { ThemeToggle, ThemeToggleProps } from './theme-toggle.js';
11
- export { EDITORIAL_PRINCIPLES, EditorialPrinciple, NETWORK_PARENT, NetworkParent, PublicationNetworkItem, communityPublications, findPublicationByHost, findPublicationBySlug, getNetworkPublicationUrl, listedPublications, localPublications } from './network.js';
11
+ export { EDITORIAL_PRINCIPLES, EditorialPrinciple, NETWORK_PARENT, NetworkParent, PublicationNetworkItem, communityPublications, findPublicationByHost, findPublicationBySlug, getNetworkPublicationUrl, listedPublications, localPublications, topicalPublications } from './network.js';
12
12
  export { LocalNetworkBar, LocalNetworkBarProps } from './network-bar.js';
13
13
  export { NetworkCopyrightNotice, NetworkCopyrightNoticeProps } from './network-copyright.js';
14
14
  import * as React from 'react';
@@ -274,6 +274,113 @@ declare function nearbyUpdates(items: NewsItem[], selection?: HomepageSelection,
274
274
  declare function shortDeck(value: string | null | undefined, limit?: number): string;
275
275
  declare function storyDate(value: string): string | null;
276
276
 
277
+ /**
278
+ * Shared network navigation.
279
+ *
280
+ * One configuration drives the primary row, the More menu and the hamburger
281
+ * directory on every Bay Area News Network paper. The defaults below ship in
282
+ * this package; day-to-day changes (labels, order, enabling Autos, a featured
283
+ * seasonal destination) are `NavigationConfig` overrides stored in each
284
+ * paper's site record and picked up at request time — no release required.
285
+ */
286
+ /** Editorial sections, community products and marketplaces stay distinct in config even where readers see one row. */
287
+ type NavigationKind = "editorial" | "product" | "marketplace" | "publication";
288
+ type NavigationGroup = "news-knowledge" | "local-life" | "marketplace" | "publication";
289
+ declare const NAVIGATION_GROUPS: {
290
+ id: NavigationGroup;
291
+ label: string;
292
+ }[];
293
+ type NavigationDestination = {
294
+ /** Stable identifier; overrides and additions merge by id. */
295
+ id: string;
296
+ label: string;
297
+ href: string;
298
+ kind: NavigationKind;
299
+ /** More-menu column; destinations without a group never render in More. */
300
+ group?: NavigationGroup;
301
+ /** Reading order inside the primary row and inside each More group. */
302
+ order: number;
303
+ /** Responsive weight: when the row runs out of width, lower priority collapses into More first. */
304
+ priority?: number;
305
+ /** Renders in the primary editorial row. */
306
+ primary?: boolean;
307
+ /** Renders in its group inside the More menu. */
308
+ more?: boolean;
309
+ /** Hidden everywhere until enabled (default true). */
310
+ enabled?: boolean;
311
+ /** Publication feature flag that must be on (e.g. "jobs", "chat", "smile", "classifieds"). */
312
+ feature?: string;
313
+ /** Canonical section name: shown only when the publication configures or publishes the section. */
314
+ section?: string;
315
+ /** Restricts the destination to the listed publication slugs. */
316
+ publications?: string[];
317
+ };
318
+ /** Record-stored delta applied over the shipped defaults. Unknown ids with a label and href are additions. */
319
+ type NavigationOverride = {
320
+ id: string;
321
+ } & Partial<Omit<NavigationDestination, "id">>;
322
+ type FeaturedDestination = {
323
+ label: string;
324
+ href: string;
325
+ /** ISO instants limiting when the promotion shows. */
326
+ from?: string;
327
+ until?: string;
328
+ };
329
+ /** Stored in the site record under `render.navigation`. Everything is optional: absent fields keep defaults. */
330
+ type NavigationConfig = {
331
+ version?: 1;
332
+ destinations?: NavigationOverride[];
333
+ /** Overrides the seasonal featured slot; `null` suppresses it entirely. */
334
+ featured?: FeaturedDestination | null;
335
+ };
336
+ /**
337
+ * The network-wide default navigation. Primary order and collapse priority
338
+ * follow the 2026 information architecture: editorial sections first, then
339
+ * the community products. "Front page" is the masthead's job, so it is not a
340
+ * destination. Autos ships disabled; enabling it is a record override.
341
+ */
342
+ declare const NETWORK_NAVIGATION: NavigationDestination[];
343
+ type NavigationLink = {
344
+ id: string;
345
+ label: string;
346
+ href: string;
347
+ kind: NavigationKind;
348
+ priority: number;
349
+ };
350
+ type NavigationGroupLinks = {
351
+ id: NavigationGroup;
352
+ label: string;
353
+ links: NavigationLink[];
354
+ };
355
+ type ResolvedNavigation = {
356
+ /** Editorial row in reading order; collapse into More by ascending priority. */
357
+ primary: NavigationLink[];
358
+ /** More-menu columns in canonical group order; empty groups are dropped. */
359
+ groups: NavigationGroupLinks[];
360
+ /** Active featured promotion from config, if any. `null` means "configured off". */
361
+ featured?: {
362
+ label: string;
363
+ href: string;
364
+ } | null;
365
+ };
366
+ type NavigationContext = {
367
+ /** This paper's slug. */
368
+ publication: string;
369
+ /** Sections the publication configures (profile taxonomy). */
370
+ sections?: string[];
371
+ /** Sections observed in the live feed; they satisfy a section gate too. */
372
+ discovered?: string[];
373
+ /** Publication feature flags. */
374
+ featureEnabled?: (feature: string) => boolean;
375
+ /** Record-stored overrides. Invalid entries are ignored, never fatal. */
376
+ config?: NavigationConfig | null;
377
+ now?: Date;
378
+ };
379
+ /** Apply record overrides defensively: the record is data, never trusted markup or routing. */
380
+ declare function applyNavigationConfig(defaults: NavigationDestination[], config: NavigationConfig | null | undefined): NavigationDestination[];
381
+ /** The one place that decides what every reader-facing menu shows. */
382
+ declare function resolveNavigation(context: NavigationContext): ResolvedNavigation;
383
+
277
384
  /** https URL with no userinfo. Anything else is dropped from public markup. */
278
385
  declare function publicHttps(value?: string | null): string | undefined;
279
386
  declare function articleUrl(canonical: string, slug: string): string;
@@ -514,4 +621,4 @@ interface SponsorshipReport {
514
621
  /** Shared by the newsroom print/export view and the repeatable PDF renderer. */
515
622
  declare function campaignReportHtml(report: SponsorshipReport): string;
516
623
 
517
- export { ANALYTICS_COOKIE, ANALYTICS_VERSION, ArticleProvenance, type Attribution, BROADSHEET_THEME, type BriefingCandidate, type BriefingPreferences, type BriefingReason, type BriefingSection, type BriefingSource, type BriefingVerification, COOKIE_CATEGORIES, CURATED_COMMUNITY_CARDS, CouponOffer, EDITORIAL_SECTION_ORDER, EVENTS, EditorialSection, type EffectiveTheme, FeatureName, HomepageSelection, LAYOUT_COOKIE, LOCAL_BRIEFING_POLICY_VERSION, type ListeningArticle, type LocalBriefing, type LocalBriefingItem, type LocalBriefingOptions, Measurement, NEWS_CACHE, NearbyUpdate, NewsArticle, NewsError, NewsItem, NewsPublication, PublicationInput, PublicationTheme, SESSION_IDLE_MS, type SponsorshipReport, THEME_COOKIE, THEME_EVENT, THEME_MAX_AGE_SECONDS, THEME_STORAGE_KEY, type ThemeMode, UTM_FIELDS, UUID, activeNearby, applyTheme, articleCacheKey, articleCacheOptions, articleMeta, articleUrl, attribution, briefSummary, campaignReportHtml, clearTheme, composeEdition, composeLocalBriefing, defaultRevalidateTargets, definePublication, displayHeadline, edgeCacheControl, editorialSections, featureEnabled, feedCacheKey, feedCacheOptions, filterNews, getStoredTheme, getSystemTheme, inventoryCacheOptions, llmsText, matchesStoryTag, measurementConsent, nearbyUpdates, newsArticleJsonLd, normalizedText, orderedSections, publicHttps, publicUrl, publicationJsonLd, publicationListeningCandidates, publicationListeningTrack, publicationMeta, readerSources, recordConsentToCompliance, referralCode, resolveCoupon, resolveEffectiveTheme, resolveLayout, resolveSection, revalidateDecision, secretsMatch, sectionDefinition, sectionId, sectionPath, setTheme, shortDeck, shortText, shouldServeLastKnown, storyDate, storyTowns, subscribeTheme, themeInitScript, townSlug, validCalendarDate, walnutCreekTimes, withLastKnown };
624
+ export { ANALYTICS_COOKIE, ANALYTICS_VERSION, ArticleProvenance, type Attribution, BROADSHEET_THEME, type BriefingCandidate, type BriefingPreferences, type BriefingReason, type BriefingSection, type BriefingSource, type BriefingVerification, COOKIE_CATEGORIES, CURATED_COMMUNITY_CARDS, CouponOffer, EDITORIAL_SECTION_ORDER, EVENTS, EditorialSection, type EffectiveTheme, FeatureName, type FeaturedDestination, HomepageSelection, LAYOUT_COOKIE, LOCAL_BRIEFING_POLICY_VERSION, type ListeningArticle, type LocalBriefing, type LocalBriefingItem, type LocalBriefingOptions, Measurement, NAVIGATION_GROUPS, NETWORK_NAVIGATION, NEWS_CACHE, type NavigationConfig, type NavigationContext, type NavigationDestination, type NavigationGroup, type NavigationGroupLinks, type NavigationKind, type NavigationLink, type NavigationOverride, NearbyUpdate, NewsArticle, NewsError, NewsItem, NewsPublication, PublicationInput, PublicationTheme, type ResolvedNavigation, SESSION_IDLE_MS, type SponsorshipReport, THEME_COOKIE, THEME_EVENT, THEME_MAX_AGE_SECONDS, THEME_STORAGE_KEY, type ThemeMode, UTM_FIELDS, UUID, activeNearby, applyNavigationConfig, applyTheme, articleCacheKey, articleCacheOptions, articleMeta, articleUrl, attribution, briefSummary, campaignReportHtml, clearTheme, composeEdition, composeLocalBriefing, defaultRevalidateTargets, definePublication, displayHeadline, edgeCacheControl, editorialSections, featureEnabled, feedCacheKey, feedCacheOptions, filterNews, getStoredTheme, getSystemTheme, inventoryCacheOptions, llmsText, matchesStoryTag, measurementConsent, nearbyUpdates, newsArticleJsonLd, normalizedText, orderedSections, publicHttps, publicUrl, publicationJsonLd, publicationListeningCandidates, publicationListeningTrack, publicationMeta, readerSources, recordConsentToCompliance, referralCode, resolveCoupon, resolveEffectiveTheme, resolveLayout, resolveNavigation, resolveSection, revalidateDecision, secretsMatch, sectionDefinition, sectionId, sectionPath, setTheme, shortDeck, shortText, shouldServeLastKnown, storyDate, storyTowns, subscribeTheme, themeInitScript, townSlug, validCalendarDate, walnutCreekTimes, withLastKnown };
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
- export { NetworkCopyrightNotice } from './chunk-WAC6ATNP.js';
1
+ export { NetworkCopyrightNotice } from './chunk-DM4KQNJH.js';
2
2
  export { CURATED_COMMUNITY_CARDS, VerifiedCardComponent, VerifiedCardSection, getArticleCards, isSafeActionUrl } from './chunk-FMCHQI7K.js';
3
3
  export { MEET_ACTIVITIES, activityLabel, canHostMeetup, isAdult, prepareMeetup, screenMessage } from './chunk-AMLVCZDP.js';
4
- export { CookieConsentBanner } from './chunk-GOWOYMSG.js';
5
- export { CookieSettingsView } from './chunk-UL2Q3N26.js';
4
+ export { CookieConsentBanner } from './chunk-XPOZGZTM.js';
5
+ export { CookieSettingsView } from './chunk-GYYUJYI4.js';
6
6
  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';
7
- export { LocalNetworkBar } from './chunk-2XSW7JZS.js';
8
- import { localPublications } from './chunk-JV76ZEIA.js';
9
- 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, EDITORIAL_PRINCIPLES, EU_EEA_UK_COUNTRIES, NETWORK_CONSENT_STORAGE_KEY, NETWORK_PARENT, acceptAllCookies, checkUrlConsentBridge, clearCookieConsent, communityPublications, decorateNetworkUrl, findPublicationByHost, findPublicationBySlug, getCookieConsent, getNetworkPublicationUrl, hasConsented, isCategoryAllowed, isGeoConsentRequired, listedPublications, localPublications, queryNetworkConsentHub, recordConsentToCompliance, rejectOptionalCookies, setCookieConsent, setNetworkConsentHub } from './chunk-JV76ZEIA.js';
7
+ export { LocalNetworkBar } from './chunk-F53CPZQO.js';
8
+ import { localPublications } from './chunk-6S5FARL3.js';
9
+ 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, EDITORIAL_PRINCIPLES, EU_EEA_UK_COUNTRIES, NETWORK_CONSENT_STORAGE_KEY, NETWORK_PARENT, acceptAllCookies, checkUrlConsentBridge, clearCookieConsent, communityPublications, decorateNetworkUrl, findPublicationByHost, findPublicationBySlug, getCookieConsent, getNetworkPublicationUrl, hasConsented, isCategoryAllowed, isGeoConsentRequired, listedPublications, localPublications, queryNetworkConsentHub, recordConsentToCompliance, rejectOptionalCookies, setCookieConsent, setNetworkConsentHub, topicalPublications } from './chunk-6S5FARL3.js';
10
10
  export { communityMapEmbeds } from './chunk-IMYBSG7J.js';
11
11
  export { formatArtworkCaption, parseDocumentBlocks, renderArticleBlocksToHtml, sanitizeInlineMarkdown } from './chunk-OISLCYER.js';
12
12
  import { definePublication } from './chunk-57YVL6BD.js';
@@ -576,6 +576,156 @@ function defaultRevalidateTargets() {
576
576
  };
577
577
  }
578
578
 
579
+ // src/navigation.ts
580
+ var NAVIGATION_GROUPS = [
581
+ { id: "news-knowledge", label: "News & knowledge" },
582
+ { id: "local-life", label: "Local life" },
583
+ { id: "marketplace", label: "Marketplace" },
584
+ { id: "publication", label: "Publication" }
585
+ ];
586
+ function editorial(id, section, overrides = {}) {
587
+ return {
588
+ id,
589
+ section,
590
+ kind: "editorial",
591
+ label: sectionDefinition(section).label,
592
+ href: sectionPath(section),
593
+ order: 0,
594
+ priority: 0,
595
+ ...overrides
596
+ };
597
+ }
598
+ var NETWORK_NAVIGATION = [
599
+ // Primary editorial row. "News" is the Civic life desk; the section slug and story classifications are unchanged.
600
+ editorial("news", "Civic life", { label: "News", order: 10, priority: 100, primary: true }),
601
+ editorial("community", "Community", { order: 20, priority: 90, primary: true }),
602
+ editorial("food-drink", "Food & places", { order: 30, priority: 85, primary: true }),
603
+ editorial("things-to-do", "Events", { order: 40, priority: 80, primary: true }),
604
+ editorial("health", "Health", { order: 50, priority: 75, primary: true }),
605
+ editorial("real-estate", "Real Estate", { order: 60, priority: 70, primary: true }),
606
+ { id: "autos", label: "Autos", href: "/autos", kind: "marketplace", group: "marketplace", order: 65, priority: 65, primary: true, more: true, enabled: false },
607
+ editorial("business", "Local businesses", { order: 70, priority: 60, primary: true }),
608
+ { id: "meet", label: "Meet", href: "/meet", kind: "product", order: 80, priority: 50, primary: true, feature: "chat" },
609
+ { id: "jokes", label: "Jokes", href: "/smile", kind: "product", order: 90, priority: 40, primary: true, feature: "smile" },
610
+ // More — News & knowledge.
611
+ editorial("ai-technology", "AI & Technology", { label: "AI & technology", group: "news-knowledge", order: 10, more: true }),
612
+ editorial("schools", "Schools", { label: "Schools & education", group: "news-knowledge", order: 20, more: true }),
613
+ editorial("civic-life", "Civic life", { group: "news-knowledge", order: 30, more: true }),
614
+ editorial("environment", "Environment", { group: "news-knowledge", order: 40, more: true }),
615
+ editorial("transportation", "Transportation", { group: "news-knowledge", order: 50, more: true }),
616
+ // More — Local life.
617
+ { id: "pets", label: "Pets", href: "/pets", kind: "product", group: "local-life", order: 10, more: true },
618
+ { id: "celebrations", label: "Celebrations", href: "/sections/celebrations", kind: "product", group: "local-life", order: 20, more: true, enabled: false },
619
+ { id: "community-maps", label: "Community maps", href: "/community-maps", kind: "product", group: "local-life", order: 30, more: true },
620
+ { id: "town-chat", label: "Town chat", href: "/chat", kind: "product", group: "local-life", order: 40, more: true, feature: "chat" },
621
+ { id: "neighborhood-guides", label: "Neighborhood guides", href: "/guides", kind: "product", group: "local-life", order: 50, more: true, enabled: false },
622
+ { id: "poll", label: "Poll", href: "/polls", kind: "product", group: "local-life", order: 60, more: true, publications: ["walnutcreektimes"] },
623
+ // More — Marketplace.
624
+ { id: "jobs", label: "Jobs", href: "/jobs", kind: "marketplace", group: "marketplace", order: 10, more: true, feature: "jobs" },
625
+ { id: "classifieds", label: "Classifieds", href: "/classifieds", kind: "marketplace", group: "marketplace", order: 20, more: true, feature: "classifieds" },
626
+ { id: "local-services", label: "Local services", href: "/services", kind: "marketplace", group: "marketplace", order: 40, more: true, enabled: false },
627
+ // More — Publication.
628
+ { id: "latest", label: "Latest", href: "/news", kind: "publication", group: "publication", order: 10, more: true },
629
+ { id: "this-week", label: "This week", href: "/this-week", kind: "publication", group: "publication", order: 20, more: true },
630
+ { id: "newsletter", label: "Newsletter", href: "/newsletter", kind: "publication", group: "publication", order: 30, more: true },
631
+ { id: "about", label: "About", href: "/about", kind: "publication", group: "publication", order: 40, more: true },
632
+ { id: "advertise", label: "Advertise", href: "/advertise", kind: "publication", group: "publication", order: 50, more: true },
633
+ { id: "contact", label: "Contact", href: "/contact", kind: "publication", group: "publication", order: 60, more: true }
634
+ ];
635
+ var MAX_LABEL = 60;
636
+ function safeHref(href) {
637
+ if (typeof href !== "string") return null;
638
+ const value = href.trim();
639
+ if (!value.startsWith("/") || value.startsWith("//") || /[\s\\]/.test(value)) return null;
640
+ return value;
641
+ }
642
+ function safeLabel(label) {
643
+ if (typeof label !== "string") return null;
644
+ const value = label.trim();
645
+ return value && value.length <= MAX_LABEL ? value : null;
646
+ }
647
+ var GROUP_IDS = new Set(NAVIGATION_GROUPS.map((group) => group.id));
648
+ var KINDS = /* @__PURE__ */ new Set(["editorial", "product", "marketplace", "publication"]);
649
+ function applyNavigationConfig(defaults, config) {
650
+ const merged = new Map(defaults.map((destination) => [destination.id, { ...destination }]));
651
+ for (const override of config?.destinations ?? []) {
652
+ if (!override || typeof override.id !== "string" || !override.id) continue;
653
+ const current = merged.get(override.id);
654
+ const label = safeLabel(override.label);
655
+ const href = safeHref(override.href);
656
+ if (!current && !(label && href)) continue;
657
+ const next = current ? { ...current } : {
658
+ id: override.id,
659
+ label,
660
+ href,
661
+ kind: "product",
662
+ order: 1e3,
663
+ priority: 0
664
+ };
665
+ if (label) next.label = label;
666
+ if (href) next.href = href;
667
+ if (typeof override.order === "number" && Number.isFinite(override.order)) next.order = override.order;
668
+ if (typeof override.priority === "number" && Number.isFinite(override.priority)) next.priority = override.priority;
669
+ if (typeof override.enabled === "boolean") next.enabled = override.enabled;
670
+ if (typeof override.primary === "boolean") next.primary = override.primary;
671
+ if (typeof override.more === "boolean") next.more = override.more;
672
+ if (override.group && GROUP_IDS.has(override.group)) next.group = override.group;
673
+ if (override.kind && KINDS.has(override.kind)) next.kind = override.kind;
674
+ if (typeof override.section === "string") next.section = override.section;
675
+ if (typeof override.feature === "string") next.feature = override.feature;
676
+ if (Array.isArray(override.publications)) next.publications = override.publications.filter((slug) => typeof slug === "string");
677
+ merged.set(next.id, next);
678
+ }
679
+ return Array.from(merged.values());
680
+ }
681
+ function activeFeatured(config, now) {
682
+ if (config?.featured === null) return null;
683
+ const featured = config?.featured;
684
+ if (!featured) return void 0;
685
+ const label = safeLabel(featured.label);
686
+ const href = safeHref(featured.href);
687
+ if (!label || !href) return void 0;
688
+ const time = now.getTime();
689
+ if (featured.from && time < Date.parse(featured.from)) return void 0;
690
+ if (featured.until && time >= Date.parse(featured.until)) return void 0;
691
+ return { label, href };
692
+ }
693
+ function resolveNavigation(context) {
694
+ const now = context.now ?? /* @__PURE__ */ new Date();
695
+ const sections2 = /* @__PURE__ */ new Set([...context.sections ?? [], ...context.discovered ?? []]);
696
+ const featureEnabled2 = context.featureEnabled ?? (() => false);
697
+ const destinations = applyNavigationConfig(NETWORK_NAVIGATION, context.config);
698
+ const visible = destinations.filter((destination) => {
699
+ if (destination.enabled === false) return false;
700
+ if (destination.feature && !featureEnabled2(destination.feature)) return false;
701
+ if (destination.section && !sections2.has(destination.section)) return false;
702
+ if (destination.publications && !destination.publications.includes(context.publication)) return false;
703
+ return true;
704
+ });
705
+ const link = (destination) => ({
706
+ id: destination.id,
707
+ label: destination.label,
708
+ href: destination.href,
709
+ kind: destination.kind,
710
+ priority: destination.priority ?? 0
711
+ });
712
+ const byOrder = (left, right) => left.order - right.order || left.label.localeCompare(right.label);
713
+ const primary = visible.filter((destination) => destination.primary).sort(byOrder).map(link);
714
+ const covered = new Set(destinations.map((destination) => destination.section).filter(Boolean));
715
+ const stray = [...new Set(context.discovered ?? [])].filter((name) => name !== "Local news" && !covered.has(name)).sort((left, right) => left.localeCompare(right)).map((name) => {
716
+ const definition = sectionDefinition(name);
717
+ return { id: definition.id, label: definition.label, href: sectionPath(name), kind: "editorial", priority: 0 };
718
+ });
719
+ const groups = NAVIGATION_GROUPS.map((group) => ({
720
+ ...group,
721
+ links: [
722
+ ...visible.filter((destination) => destination.more && destination.group === group.id).sort(byOrder).map(link),
723
+ ...group.id === "news-knowledge" ? stray : []
724
+ ]
725
+ })).filter((group) => group.links.length > 0);
726
+ return { primary, groups, featured: activeFeatured(context.config, now) };
727
+ }
728
+
579
729
  // src/analytics.ts
580
730
  var ANALYTICS_VERSION = 1;
581
731
  var ANALYTICS_COOKIE = "napsite_analytics_v1";
@@ -837,4 +987,4 @@ function campaignReportHtml(report) {
837
987
  <footer><p>${escape(report.reporting_note)}</p><p>${escape(report.editorial_independence)}</p><p>Campaign reference: ${escape(report.campaign_id)}</p></footer></body></html>`;
838
988
  }
839
989
 
840
- export { ANALYTICS_COOKIE, ANALYTICS_VERSION, ArticleProvenance, EDITORIAL_SECTION_ORDER, EVENTS, LOCAL_BRIEFING_POLICY_VERSION, NEWS_CACHE, NewsError, SESSION_IDLE_MS, UTM_FIELDS, UUID, activeNearby, articleCacheKey, articleCacheOptions, articleMeta, articleUrl, attribution, briefSummary, campaignReportHtml, composeEdition, composeLocalBriefing, defaultRevalidateTargets, displayHeadline, edgeCacheControl, editorialSections, feedCacheKey, feedCacheOptions, filterNews, inventoryCacheOptions, llmsText, matchesStoryTag, measurementConsent, nearbyUpdates, newsArticleJsonLd, normalizedText, orderedSections, publicHttps, publicUrl, publicationJsonLd, publicationListeningCandidates, publicationListeningTrack, publicationMeta, readerSources, referralCode, resolveCoupon, resolveSection, revalidateDecision, secretsMatch, sectionDefinition, sectionId, sectionPath, shortDeck, shortText, shouldServeLastKnown, storyDate, storyTowns, townSlug, validCalendarDate, walnutCreekTimes, withLastKnown };
990
+ export { ANALYTICS_COOKIE, ANALYTICS_VERSION, ArticleProvenance, EDITORIAL_SECTION_ORDER, EVENTS, LOCAL_BRIEFING_POLICY_VERSION, NAVIGATION_GROUPS, NETWORK_NAVIGATION, NEWS_CACHE, NewsError, SESSION_IDLE_MS, UTM_FIELDS, UUID, activeNearby, applyNavigationConfig, articleCacheKey, articleCacheOptions, articleMeta, articleUrl, attribution, briefSummary, campaignReportHtml, composeEdition, composeLocalBriefing, defaultRevalidateTargets, displayHeadline, edgeCacheControl, editorialSections, feedCacheKey, feedCacheOptions, filterNews, inventoryCacheOptions, llmsText, matchesStoryTag, measurementConsent, nearbyUpdates, newsArticleJsonLd, normalizedText, orderedSections, publicHttps, publicUrl, publicationJsonLd, publicationListeningCandidates, publicationListeningTrack, publicationMeta, readerSources, referralCode, resolveCoupon, resolveNavigation, resolveSection, revalidateDecision, secretsMatch, sectionDefinition, sectionId, sectionPath, shortDeck, shortText, shouldServeLastKnown, storyDate, storyTowns, townSlug, validCalendarDate, walnutCreekTimes, withLastKnown };
@@ -36,6 +36,17 @@ function setupNetworkConsentDelegation() {
36
36
 
37
37
  // src/network.ts
38
38
  var localPublications = [
39
+ {
40
+ slug: "lazytensor",
41
+ name: "Lazy Tensor",
42
+ url: "https://lazytensor.com",
43
+ area: "Silicon Valley \xB7 AI & Technology",
44
+ focus: "AI & Technology",
45
+ kind: "topical",
46
+ slogan: "Technology, Intelligence & Everything in Between.",
47
+ description: "The network's technology publication: artificial intelligence, computing, science, startups and what technology means for the people and communities of Silicon Valley and the Bay Area.",
48
+ aboutIntro: "Lazy Tensor is the Bay Area News Network's dedicated technology publication. We report on artificial intelligence, computing, science and the companies, researchers and founders of Silicon Valley, and we explain what those developments mean for readers' lives, work and communities. Our principle is simple: understand the technology, question the hype, explain what matters. Lazy Tensor also gathers the technology reporting of the network's local newsrooms in one place, always with credit to the paper that reported the story first."
49
+ },
39
50
  {
40
51
  slug: "bayareachronicle",
41
52
  name: "Bay Area Chronicle",
@@ -141,7 +152,10 @@ var listedPublications = localPublications.filter(
141
152
  (publication) => !("listed" in publication) || publication.listed
142
153
  );
143
154
  listedPublications.filter(
144
- (publication) => publication.slug !== "bayareachronicle"
155
+ (publication) => publication.slug !== "bayareachronicle" && publication.kind !== "topical"
156
+ );
157
+ listedPublications.filter(
158
+ (publication) => publication.kind === "topical"
145
159
  );
146
160
  var NETWORK_HOSTNAMES = new Set(
147
161
  localPublications.map((p) => {
@@ -1,2 +1,2 @@
1
- export { LocalNetworkBar } from './chunk-2XSW7JZS.js';
2
- import './chunk-JV76ZEIA.js';
1
+ export { LocalNetworkBar } from './chunk-F53CPZQO.js';
2
+ import './chunk-6S5FARL3.js';
@@ -9,6 +9,17 @@ var NETWORK_PARENT = {
9
9
  url: "https://bayareanewsnetwork.com",
10
10
  brandSlogan: "Bringing communities closer."};
11
11
  var localPublications = [
12
+ {
13
+ slug: "lazytensor",
14
+ name: "Lazy Tensor",
15
+ url: "https://lazytensor.com",
16
+ area: "Silicon Valley \xB7 AI & Technology",
17
+ focus: "AI & Technology",
18
+ kind: "topical",
19
+ slogan: "Technology, Intelligence & Everything in Between.",
20
+ description: "The network's technology publication: artificial intelligence, computing, science, startups and what technology means for the people and communities of Silicon Valley and the Bay Area.",
21
+ aboutIntro: "Lazy Tensor is the Bay Area News Network's dedicated technology publication. We report on artificial intelligence, computing, science and the companies, researchers and founders of Silicon Valley, and we explain what those developments mean for readers' lives, work and communities. Our principle is simple: understand the technology, question the hype, explain what matters. Lazy Tensor also gathers the technology reporting of the network's local newsrooms in one place, always with credit to the paper that reported the story first."
22
+ },
12
23
  {
13
24
  slug: "bayareachronicle",
14
25
  name: "Bay Area Chronicle",
@@ -114,7 +125,10 @@ var listedPublications = localPublications.filter(
114
125
  (publication) => !("listed" in publication) || publication.listed
115
126
  );
116
127
  listedPublications.filter(
117
- (publication) => publication.slug !== "bayareachronicle"
128
+ (publication) => publication.slug !== "bayareachronicle" && publication.kind !== "topical"
129
+ );
130
+ listedPublications.filter(
131
+ (publication) => publication.kind === "topical"
118
132
  );
119
133
  new Set(
120
134
  localPublications.map((p) => {
@@ -1,2 +1,2 @@
1
- export { NetworkCopyrightNotice } from './chunk-WAC6ATNP.js';
2
- import './chunk-JV76ZEIA.js';
1
+ export { NetworkCopyrightNotice } from './chunk-DM4KQNJH.js';
2
+ import './chunk-6S5FARL3.js';
package/dist/network.cjs CHANGED
@@ -109,6 +109,17 @@ var NETWORK_PARENT = {
109
109
  principles: EDITORIAL_PRINCIPLES
110
110
  };
111
111
  var localPublications = [
112
+ {
113
+ slug: "lazytensor",
114
+ name: "Lazy Tensor",
115
+ url: "https://lazytensor.com",
116
+ area: "Silicon Valley \xB7 AI & Technology",
117
+ focus: "AI & Technology",
118
+ kind: "topical",
119
+ slogan: "Technology, Intelligence & Everything in Between.",
120
+ description: "The network's technology publication: artificial intelligence, computing, science, startups and what technology means for the people and communities of Silicon Valley and the Bay Area.",
121
+ aboutIntro: "Lazy Tensor is the Bay Area News Network's dedicated technology publication. We report on artificial intelligence, computing, science and the companies, researchers and founders of Silicon Valley, and we explain what those developments mean for readers' lives, work and communities. Our principle is simple: understand the technology, question the hype, explain what matters. Lazy Tensor also gathers the technology reporting of the network's local newsrooms in one place, always with credit to the paper that reported the story first."
122
+ },
112
123
  {
113
124
  slug: "bayareachronicle",
114
125
  name: "Bay Area Chronicle",
@@ -214,7 +225,10 @@ var listedPublications = localPublications.filter(
214
225
  (publication) => !("listed" in publication) || publication.listed
215
226
  );
216
227
  var communityPublications = listedPublications.filter(
217
- (publication) => publication.slug !== "bayareachronicle"
228
+ (publication) => publication.slug !== "bayareachronicle" && publication.kind !== "topical"
229
+ );
230
+ var topicalPublications = listedPublications.filter(
231
+ (publication) => publication.kind === "topical"
218
232
  );
219
233
  function findPublicationBySlug(slug) {
220
234
  return localPublications.find((p) => p.slug === slug);
@@ -255,3 +269,4 @@ exports.getNetworkPublicationUrl = getNetworkPublicationUrl;
255
269
  exports.isNetworkHostname = isNetworkHostname;
256
270
  exports.listedPublications = listedPublications;
257
271
  exports.localPublications = localPublications;
272
+ exports.topicalPublications = topicalPublications;
@@ -34,6 +34,14 @@ interface PublicationNetworkItem {
34
34
  slogan?: string;
35
35
  aboutIntro?: string;
36
36
  listed?: boolean;
37
+ /**
38
+ * `local` (default) papers cover towns; a `topical` publication covers a
39
+ * subject for the whole network (Lazy Tensor: AI & technology). Topical
40
+ * titles sit in the network bar but not among the community papers.
41
+ */
42
+ kind?: "local" | "topical";
43
+ /** Short subject line shown beside the name in directories, e.g. "AI & Technology". */
44
+ focus?: string;
37
45
  }
38
46
  /**
39
47
  * Public directory of all ScaleMule local news publications in the Bay Area network.
@@ -42,6 +50,8 @@ interface PublicationNetworkItem {
42
50
  declare const localPublications: readonly PublicationNetworkItem[];
43
51
  declare const listedPublications: readonly PublicationNetworkItem[];
44
52
  declare const communityPublications: readonly PublicationNetworkItem[];
53
+ /** Subject publications that serve the whole network (currently Lazy Tensor). */
54
+ declare const topicalPublications: readonly PublicationNetworkItem[];
45
55
  /** Find a publication in the network by its slug. */
46
56
  declare function findPublicationBySlug(slug: string): PublicationNetworkItem | undefined;
47
57
  /** Find a publication in the network by its hostname or full origin URL. */
@@ -51,4 +61,4 @@ declare function getNetworkPublicationUrl(slug: string): string | null;
51
61
  /** Check whether a given hostname belongs to any publication in the ScaleMule news network. */
52
62
  declare function isNetworkHostname(hostname: string): boolean;
53
63
 
54
- export { EDITORIAL_PRINCIPLES, type EditorialPrinciple, NETWORK_PARENT, type NetworkParent, type PublicationNetworkItem, communityPublications, findPublicationByHost, findPublicationBySlug, getNetworkPublicationUrl, isNetworkHostname, listedPublications, localPublications };
64
+ export { EDITORIAL_PRINCIPLES, type EditorialPrinciple, NETWORK_PARENT, type NetworkParent, type PublicationNetworkItem, communityPublications, findPublicationByHost, findPublicationBySlug, getNetworkPublicationUrl, isNetworkHostname, listedPublications, localPublications, topicalPublications };
package/dist/network.d.ts CHANGED
@@ -34,6 +34,14 @@ interface PublicationNetworkItem {
34
34
  slogan?: string;
35
35
  aboutIntro?: string;
36
36
  listed?: boolean;
37
+ /**
38
+ * `local` (default) papers cover towns; a `topical` publication covers a
39
+ * subject for the whole network (Lazy Tensor: AI & technology). Topical
40
+ * titles sit in the network bar but not among the community papers.
41
+ */
42
+ kind?: "local" | "topical";
43
+ /** Short subject line shown beside the name in directories, e.g. "AI & Technology". */
44
+ focus?: string;
37
45
  }
38
46
  /**
39
47
  * Public directory of all ScaleMule local news publications in the Bay Area network.
@@ -42,6 +50,8 @@ interface PublicationNetworkItem {
42
50
  declare const localPublications: readonly PublicationNetworkItem[];
43
51
  declare const listedPublications: readonly PublicationNetworkItem[];
44
52
  declare const communityPublications: readonly PublicationNetworkItem[];
53
+ /** Subject publications that serve the whole network (currently Lazy Tensor). */
54
+ declare const topicalPublications: readonly PublicationNetworkItem[];
45
55
  /** Find a publication in the network by its slug. */
46
56
  declare function findPublicationBySlug(slug: string): PublicationNetworkItem | undefined;
47
57
  /** Find a publication in the network by its hostname or full origin URL. */
@@ -51,4 +61,4 @@ declare function getNetworkPublicationUrl(slug: string): string | null;
51
61
  /** Check whether a given hostname belongs to any publication in the ScaleMule news network. */
52
62
  declare function isNetworkHostname(hostname: string): boolean;
53
63
 
54
- export { EDITORIAL_PRINCIPLES, type EditorialPrinciple, NETWORK_PARENT, type NetworkParent, type PublicationNetworkItem, communityPublications, findPublicationByHost, findPublicationBySlug, getNetworkPublicationUrl, isNetworkHostname, listedPublications, localPublications };
64
+ export { EDITORIAL_PRINCIPLES, type EditorialPrinciple, NETWORK_PARENT, type NetworkParent, type PublicationNetworkItem, communityPublications, findPublicationByHost, findPublicationBySlug, getNetworkPublicationUrl, isNetworkHostname, listedPublications, localPublications, topicalPublications };
package/dist/network.js CHANGED
@@ -1 +1 @@
1
- export { EDITORIAL_PRINCIPLES, NETWORK_PARENT, communityPublications, findPublicationByHost, findPublicationBySlug, getNetworkPublicationUrl, isNetworkHostname, listedPublications, localPublications } from './chunk-JV76ZEIA.js';
1
+ export { EDITORIAL_PRINCIPLES, NETWORK_PARENT, communityPublications, findPublicationByHost, findPublicationBySlug, getNetworkPublicationUrl, isNetworkHostname, listedPublications, localPublications, topicalPublications } from './chunk-6S5FARL3.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scalemule/news-publication",
3
- "version": "0.0.59",
3
+ "version": "0.0.61",
4
4
  "description": "Shared server framework for ScaleMule local news publications. Walnut Creek Times is the broadsheet default; each paper supplies its own identity and feature flags.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",