@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.cjs CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var compliance = require('@scalemule/compliance');
3
4
  var react = require('react');
4
5
  var jsxRuntime = require('react/jsx-runtime');
5
6
 
@@ -782,26 +783,9 @@ async function syncPublication(input) {
782
783
  ageMs
783
784
  };
784
785
  }
785
-
786
- // src/cookies.ts
787
- var COOKIE_CONSENT_KEY = "sm_cookie_consent_v1";
788
- var COOKIE_CONSENT_BACKUP_KEY = "napsite_cookie_consent_v1";
789
- var COOKIE_CONSENT_EVENT = "scalemule-cookie-consent-change";
790
- var COOKIE_CONSENT_MAX_AGE_SECONDS = 365 * 24 * 60 * 60;
791
- var DEFAULT_CONSENT_HUB_URL = "https://bayareachronicle.com/consent-bridge.html";
792
- var NETWORK_CONSENT_STORAGE_KEY = "sm_network_consent_status";
793
- var DEFAULT_PREFERENCES_REJECTED = {
794
- essential: true,
795
- performance: false,
796
- functional: false,
797
- advertising: false
798
- };
799
- var DEFAULT_PREFERENCES_ACCEPTED = {
800
- essential: true,
801
- performance: true,
802
- functional: true,
803
- advertising: true
804
- };
786
+ async function recordConsentToCompliance(record, options) {
787
+ return compliance.recordConsentToCompliance(record, options);
788
+ }
805
789
  var COOKIE_CATEGORIES = [
806
790
  {
807
791
  id: "essential",
@@ -910,383 +894,6 @@ var COOKIE_CATEGORIES = [
910
894
  ]
911
895
  }
912
896
  ];
913
- var memoryConsent = null;
914
- function readCookie(name) {
915
- if (typeof document === "undefined") return null;
916
- const match = document.cookie.match(new RegExp("(?:^|; )" + name.replace(/([.$?*|{}()[\]\\/+^])/g, "\\$1") + "=([^;]*)"));
917
- return match ? decodeURIComponent(match[1]) : null;
918
- }
919
- function writeCookie(name, value, maxAgeSeconds) {
920
- if (typeof document === "undefined") return;
921
- const secure = typeof location !== "undefined" && location.protocol === "https:" ? "; Secure" : "";
922
- document.cookie = `${name}=${encodeURIComponent(value)}; Path=/; Max-Age=${maxAgeSeconds}; SameSite=Lax${secure}`;
923
- }
924
- function getCookieConsent() {
925
- if (typeof window === "undefined") return memoryConsent;
926
- try {
927
- const raw = readCookie(COOKIE_CONSENT_KEY) || readCookie(COOKIE_CONSENT_BACKUP_KEY);
928
- if (raw) {
929
- const parsed = JSON.parse(raw);
930
- if (parsed && parsed.version === 1 && parsed.preferences) {
931
- memoryConsent = parsed;
932
- return parsed;
933
- }
934
- }
935
- const stored = window.localStorage?.getItem(COOKIE_CONSENT_KEY);
936
- if (stored) {
937
- const parsed = JSON.parse(stored);
938
- if (parsed && parsed.version === 1 && parsed.preferences) {
939
- memoryConsent = parsed;
940
- return parsed;
941
- }
942
- }
943
- } catch {
944
- }
945
- return memoryConsent;
946
- }
947
- var EU_EEA_UK_COUNTRIES = /* @__PURE__ */ new Set([
948
- "AT",
949
- "BE",
950
- "BG",
951
- "HR",
952
- "CY",
953
- "CZ",
954
- "DK",
955
- "EE",
956
- "FI",
957
- "FR",
958
- "DE",
959
- "GR",
960
- "HU",
961
- "IE",
962
- "IT",
963
- "LV",
964
- "LT",
965
- "LU",
966
- "MT",
967
- "NL",
968
- "PL",
969
- "PT",
970
- "RO",
971
- "SK",
972
- "SI",
973
- "ES",
974
- "SE",
975
- "IS",
976
- "LI",
977
- "NO",
978
- "GB",
979
- "CH"
980
- ]);
981
- function isGeoConsentRequired(countryCode) {
982
- if (countryCode && typeof countryCode === "string") {
983
- const code = countryCode.trim().toUpperCase();
984
- if (code.length === 2) {
985
- return EU_EEA_UK_COUNTRIES.has(code);
986
- }
987
- }
988
- if (typeof window !== "undefined") {
989
- try {
990
- const cached = readCookie("sm_geo_country") || window.localStorage?.getItem("sm_geo_country");
991
- if (cached && typeof cached === "string" && cached.length === 2) {
992
- return EU_EEA_UK_COUNTRIES.has(cached.toUpperCase());
993
- }
994
- const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
995
- if (tz) {
996
- if (/^(America|US|Canada|Pacific)\//i.test(tz)) {
997
- return false;
998
- }
999
- if (/^(Europe|Atlantic\/Reykjavik|Atlantic\/Canary|Atlantic\/Faeroe|Atlantic\/Madeira|Atlantic\/Azores|WET|CET|EET|GMT)/i.test(tz)) {
1000
- return true;
1001
- }
1002
- }
1003
- } catch {
1004
- }
1005
- }
1006
- return false;
1007
- }
1008
- function checkUrlConsentBridge() {
1009
- if (typeof window === "undefined") return false;
1010
- try {
1011
- const url = new URL(window.location.href);
1012
- const param = url.searchParams.get("sm_consent");
1013
- if (!param) return false;
1014
- if (param === "accepted" || param === "1" || param === "all") {
1015
- acceptAllCookies();
1016
- } else if (param === "rejected" || param === "0" || param === "essential") {
1017
- rejectOptionalCookies();
1018
- } else {
1019
- return false;
1020
- }
1021
- url.searchParams.delete("sm_consent");
1022
- const newSearch = url.searchParams.toString() ? `?${url.searchParams.toString()}` : "";
1023
- window.history.replaceState(null, "", `${url.pathname}${newSearch}${url.hash}`);
1024
- return true;
1025
- } catch {
1026
- return false;
1027
- }
1028
- }
1029
- function decorateNetworkUrl(targetUrl) {
1030
- const consent = getCookieConsent();
1031
- if (!consent) return targetUrl;
1032
- try {
1033
- const base = typeof window !== "undefined" ? window.location.origin : "https://localhost";
1034
- const url = new URL(targetUrl, base);
1035
- const value = consent.preferences.performance || consent.preferences.advertising ? "1" : "0";
1036
- url.searchParams.set("sm_consent", value);
1037
- return url.toString();
1038
- } catch {
1039
- return targetUrl;
1040
- }
1041
- }
1042
- function queryNetworkConsentHub(hubUrl = DEFAULT_CONSENT_HUB_URL, timeoutMs = 1e3) {
1043
- if (typeof window === "undefined") return Promise.resolve(null);
1044
- try {
1045
- const hubOrigin = new URL(hubUrl).origin;
1046
- if (window.location.origin === hubOrigin) {
1047
- try {
1048
- const direct = window.localStorage?.getItem(NETWORK_CONSENT_STORAGE_KEY);
1049
- if (direct === "accepted" || direct === "rejected") {
1050
- return Promise.resolve(direct);
1051
- }
1052
- } catch {
1053
- }
1054
- return Promise.resolve(null);
1055
- }
1056
- return new Promise((resolve) => {
1057
- let settled = false;
1058
- let iframe = null;
1059
- let timer = null;
1060
- const finish = (result) => {
1061
- if (settled) return;
1062
- settled = true;
1063
- if (timer !== null) window.clearTimeout(timer);
1064
- window.removeEventListener("message", onMessage);
1065
- if (iframe && iframe.parentNode) {
1066
- try {
1067
- iframe.parentNode.removeChild(iframe);
1068
- } catch {
1069
- }
1070
- }
1071
- resolve(result);
1072
- };
1073
- const sendGet = () => {
1074
- try {
1075
- iframe?.contentWindow?.postMessage({ type: "SM_CONSENT_GET" }, hubOrigin);
1076
- } catch {
1077
- }
1078
- };
1079
- const onMessage = (event) => {
1080
- if (event.origin !== hubOrigin) return;
1081
- const data = event.data;
1082
- if (!data || typeof data !== "object") return;
1083
- if (data.type === "SM_CONSENT_STATUS") {
1084
- const status = data.status === "accepted" || data.status === "rejected" ? data.status : null;
1085
- finish(status);
1086
- } else if (data.type === "SM_CONSENT_BRIDGE_READY") {
1087
- sendGet();
1088
- }
1089
- };
1090
- window.addEventListener("message", onMessage);
1091
- timer = window.setTimeout(() => {
1092
- finish(null);
1093
- }, timeoutMs);
1094
- try {
1095
- iframe = document.createElement("iframe");
1096
- iframe.src = hubUrl;
1097
- iframe.style.position = "absolute";
1098
- iframe.style.width = "0";
1099
- iframe.style.height = "0";
1100
- iframe.style.border = "0";
1101
- iframe.style.display = "none";
1102
- iframe.style.visibility = "hidden";
1103
- iframe.setAttribute("aria-hidden", "true");
1104
- iframe.setAttribute("tabindex", "-1");
1105
- iframe.onload = () => {
1106
- sendGet();
1107
- };
1108
- iframe.onerror = () => {
1109
- finish(null);
1110
- };
1111
- const target = document.body || document.documentElement;
1112
- target.appendChild(iframe);
1113
- } catch {
1114
- finish(null);
1115
- }
1116
- });
1117
- } catch {
1118
- return Promise.resolve(null);
1119
- }
1120
- }
1121
- function setNetworkConsentHub(status, hubUrl = DEFAULT_CONSENT_HUB_URL) {
1122
- if (typeof window === "undefined") return;
1123
- try {
1124
- const hubOrigin = new URL(hubUrl).origin;
1125
- if (window.location.origin === hubOrigin) {
1126
- try {
1127
- if (status) {
1128
- window.localStorage?.setItem(NETWORK_CONSENT_STORAGE_KEY, status);
1129
- } else {
1130
- window.localStorage?.removeItem(NETWORK_CONSENT_STORAGE_KEY);
1131
- }
1132
- } catch {
1133
- }
1134
- return;
1135
- }
1136
- let iframe = null;
1137
- let timer = null;
1138
- const cleanup = () => {
1139
- if (timer !== null) window.clearTimeout(timer);
1140
- window.removeEventListener("message", onMessage);
1141
- if (iframe && iframe.parentNode) {
1142
- try {
1143
- iframe.parentNode.removeChild(iframe);
1144
- } catch {
1145
- }
1146
- }
1147
- };
1148
- const sendSet = () => {
1149
- try {
1150
- iframe?.contentWindow?.postMessage({ type: "SM_CONSENT_SET", status }, hubOrigin);
1151
- } catch {
1152
- }
1153
- };
1154
- const onMessage = (event) => {
1155
- if (event.origin !== hubOrigin) return;
1156
- const data = event.data;
1157
- if (!data || typeof data !== "object") return;
1158
- if (data.type === "SM_CONSENT_SAVED") {
1159
- cleanup();
1160
- } else if (data.type === "SM_CONSENT_BRIDGE_READY") {
1161
- sendSet();
1162
- }
1163
- };
1164
- window.addEventListener("message", onMessage);
1165
- timer = window.setTimeout(cleanup, 2500);
1166
- try {
1167
- iframe = document.createElement("iframe");
1168
- iframe.src = hubUrl;
1169
- iframe.style.position = "absolute";
1170
- iframe.style.width = "0";
1171
- iframe.style.height = "0";
1172
- iframe.style.border = "0";
1173
- iframe.style.display = "none";
1174
- iframe.style.visibility = "hidden";
1175
- iframe.setAttribute("aria-hidden", "true");
1176
- iframe.setAttribute("tabindex", "-1");
1177
- iframe.onload = () => {
1178
- sendSet();
1179
- };
1180
- iframe.onerror = cleanup;
1181
- const target = document.body || document.documentElement;
1182
- target.appendChild(iframe);
1183
- } catch {
1184
- cleanup();
1185
- }
1186
- } catch {
1187
- }
1188
- }
1189
- function hasConsented() {
1190
- return getCookieConsent() !== null;
1191
- }
1192
- function isCategoryAllowed(category) {
1193
- if (category === "essential") return true;
1194
- const consent = getCookieConsent();
1195
- if (!consent) {
1196
- if (typeof navigator !== "undefined") {
1197
- const nav = navigator;
1198
- if (nav.globalPrivacyControl || nav.doNotTrack === "1") {
1199
- return false;
1200
- }
1201
- }
1202
- return false;
1203
- }
1204
- return Boolean(consent.preferences[category]);
1205
- }
1206
- function setCookieConsent(preferences, source = "settings_save") {
1207
- const mergedPreferences = {
1208
- essential: true,
1209
- performance: Boolean(preferences.performance),
1210
- functional: Boolean(preferences.functional),
1211
- advertising: Boolean(preferences.advertising)
1212
- };
1213
- let anonymous_id;
1214
- if (typeof window !== "undefined") {
1215
- try {
1216
- anonymous_id = window.localStorage?.getItem("napsite_visitor_v1") || void 0;
1217
- } catch {
1218
- }
1219
- }
1220
- const record = {
1221
- version: 1,
1222
- preferences: mergedPreferences,
1223
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1224
- anonymous_id,
1225
- source
1226
- };
1227
- memoryConsent = record;
1228
- const serialized = JSON.stringify(record);
1229
- writeCookie(COOKIE_CONSENT_KEY, serialized, COOKIE_CONSENT_MAX_AGE_SECONDS);
1230
- writeCookie(COOKIE_CONSENT_BACKUP_KEY, serialized, COOKIE_CONSENT_MAX_AGE_SECONDS);
1231
- if (typeof window !== "undefined") {
1232
- try {
1233
- window.localStorage?.setItem(COOKIE_CONSENT_KEY, serialized);
1234
- } catch {
1235
- }
1236
- const networkStatus = mergedPreferences.performance || mergedPreferences.advertising ? "accepted" : "rejected";
1237
- setNetworkConsentHub(networkStatus);
1238
- window.dispatchEvent(new CustomEvent(COOKIE_CONSENT_EVENT, { detail: record }));
1239
- }
1240
- return record;
1241
- }
1242
- function acceptAllCookies() {
1243
- return setCookieConsent(DEFAULT_PREFERENCES_ACCEPTED, "banner_accept");
1244
- }
1245
- function rejectOptionalCookies() {
1246
- return setCookieConsent(DEFAULT_PREFERENCES_REJECTED, "banner_reject");
1247
- }
1248
- function clearCookieConsent() {
1249
- memoryConsent = null;
1250
- if (typeof document !== "undefined") {
1251
- document.cookie = `${COOKIE_CONSENT_KEY}=; Path=/; Max-Age=0; SameSite=Lax`;
1252
- document.cookie = `${COOKIE_CONSENT_BACKUP_KEY}=; Path=/; Max-Age=0; SameSite=Lax`;
1253
- }
1254
- if (typeof window !== "undefined") {
1255
- try {
1256
- window.localStorage?.removeItem(COOKIE_CONSENT_KEY);
1257
- } catch {
1258
- }
1259
- setNetworkConsentHub(null);
1260
- window.dispatchEvent(new CustomEvent(COOKIE_CONSENT_EVENT, { detail: null }));
1261
- }
1262
- }
1263
- async function recordConsentToCompliance(record, options) {
1264
- if (typeof window === "undefined") return;
1265
- const endpoint = options?.endpoint || "/api/compliance/consent";
1266
- try {
1267
- const payload = {
1268
- consent_type: "cookie_policy",
1269
- granted: record.preferences.performance || record.preferences.advertising,
1270
- preferences: record.preferences,
1271
- source: record.source,
1272
- anonymous_id: record.anonymous_id,
1273
- timestamp: record.timestamp,
1274
- url: window.location.href,
1275
- user_agent: window.navigator.userAgent
1276
- };
1277
- if (typeof navigator.sendBeacon === "function") {
1278
- navigator.sendBeacon(endpoint, new Blob([JSON.stringify(payload)], { type: "application/json" }));
1279
- } else {
1280
- await fetch(endpoint, {
1281
- method: "POST",
1282
- headers: { "content-type": "application/json" },
1283
- body: JSON.stringify(payload),
1284
- keepalive: true
1285
- });
1286
- }
1287
- } catch {
1288
- }
1289
- }
1290
897
  function CookieConsentBanner({
1291
898
  title = "Help Us Improve Our Website with Cookies",
1292
899
  text,
@@ -1296,39 +903,39 @@ function CookieConsentBanner({
1296
903
  complianceEndpoint = "/api/compliance/consent",
1297
904
  countryCode,
1298
905
  forceShow = false,
1299
- consentHubUrl = DEFAULT_CONSENT_HUB_URL
906
+ consentHubUrl = compliance.DEFAULT_CONSENT_HUB_URL
1300
907
  }) {
1301
908
  const [mounted, setMounted] = react.useState(false);
1302
909
  const [visible, setVisible] = react.useState(false);
1303
910
  react.useEffect(() => {
1304
911
  setMounted(true);
1305
- if (checkUrlConsentBridge()) {
912
+ if (compliance.checkUrlConsentBridge()) {
1306
913
  setVisible(false);
1307
914
  return;
1308
915
  }
1309
- if (hasConsented()) {
916
+ if (compliance.hasConsented()) {
1310
917
  setVisible(false);
1311
918
  return;
1312
919
  }
1313
- if (!forceShow && !isGeoConsentRequired(countryCode)) {
920
+ if (!forceShow && !compliance.isGeoConsentRequired(countryCode)) {
1314
921
  setVisible(false);
1315
- void queryNetworkConsentHub(consentHubUrl, 1200).then((networkStatus) => {
922
+ void compliance.queryNetworkConsentHub(consentHubUrl, 1200).then((networkStatus) => {
1316
923
  if (networkStatus === "accepted") {
1317
- acceptAllCookies();
924
+ compliance.acceptAllCookies();
1318
925
  } else if (networkStatus === "rejected") {
1319
- rejectOptionalCookies();
926
+ compliance.rejectOptionalCookies();
1320
927
  }
1321
928
  });
1322
929
  return;
1323
930
  }
1324
931
  let cancelled = false;
1325
- void queryNetworkConsentHub(consentHubUrl, 1e3).then((networkStatus) => {
932
+ void compliance.queryNetworkConsentHub(consentHubUrl, 1e3).then((networkStatus) => {
1326
933
  if (cancelled) return;
1327
934
  if (networkStatus === "accepted") {
1328
- acceptAllCookies();
935
+ compliance.acceptAllCookies();
1329
936
  setVisible(false);
1330
937
  } else if (networkStatus === "rejected") {
1331
- rejectOptionalCookies();
938
+ compliance.rejectOptionalCookies();
1332
939
  setVisible(false);
1333
940
  } else {
1334
941
  setVisible(true);
@@ -1340,27 +947,31 @@ function CookieConsentBanner({
1340
947
  }, [countryCode, forceShow, consentHubUrl]);
1341
948
  react.useEffect(() => {
1342
949
  const onConsentChange = () => {
1343
- if (hasConsented()) {
950
+ if (compliance.hasConsented()) {
1344
951
  setVisible(false);
1345
952
  }
1346
953
  };
1347
- window.addEventListener(COOKIE_CONSENT_EVENT, onConsentChange);
1348
- return () => window.removeEventListener(COOKIE_CONSENT_EVENT, onConsentChange);
954
+ window.addEventListener(compliance.COOKIE_CONSENT_EVENT, onConsentChange);
955
+ return () => window.removeEventListener(compliance.COOKIE_CONSENT_EVENT, onConsentChange);
1349
956
  }, []);
1350
957
  if (!mounted || !visible) return null;
1351
958
  const handleAccept = () => {
1352
- const record = acceptAllCookies();
959
+ const record = compliance.acceptAllCookies();
1353
960
  setVisible(false);
1354
961
  void recordConsentToCompliance(record, {
1355
- endpoint: complianceEndpoint});
1356
- setNetworkConsentHub("accepted", consentHubUrl);
962
+ endpoint: complianceEndpoint,
963
+ publicationSlug
964
+ });
965
+ compliance.setNetworkConsentHub("accepted", consentHubUrl);
1357
966
  };
1358
967
  const handleReject = () => {
1359
- const record = rejectOptionalCookies();
968
+ const record = compliance.rejectOptionalCookies();
1360
969
  setVisible(false);
1361
970
  void recordConsentToCompliance(record, {
1362
- endpoint: complianceEndpoint});
1363
- setNetworkConsentHub("rejected", consentHubUrl);
971
+ endpoint: complianceEndpoint,
972
+ publicationSlug
973
+ });
974
+ compliance.setNetworkConsentHub("rejected", consentHubUrl);
1364
975
  };
1365
976
  const defaultText = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1366
977
  "We use cookies and device data to analyze performance, support local sponsors, and remember your reading preferences across our news network. View",
@@ -1415,8 +1026,8 @@ function CookieSettingsView({
1415
1026
  publicationSlug
1416
1027
  }) {
1417
1028
  const [preferences, setPreferences] = react.useState(() => {
1418
- const existing = getCookieConsent();
1419
- return existing ? existing.preferences : { ...DEFAULT_PREFERENCES_ACCEPTED };
1029
+ const existing = compliance.getCookieConsent();
1030
+ return existing ? existing.preferences : { ...compliance.DEFAULT_PREFERENCES_ACCEPTED };
1420
1031
  });
1421
1032
  const [expandedCategories, setExpandedCategories] = react.useState({
1422
1033
  essential: false,
@@ -1427,7 +1038,7 @@ function CookieSettingsView({
1427
1038
  const [saveSuccess, setSaveSuccess] = react.useState(false);
1428
1039
  const [lastSavedTime, setLastSavedTime] = react.useState(null);
1429
1040
  react.useEffect(() => {
1430
- const existing = getCookieConsent();
1041
+ const existing = compliance.getCookieConsent();
1431
1042
  if (existing) {
1432
1043
  setPreferences(existing.preferences);
1433
1044
  setLastSavedTime(new Date(existing.timestamp).toLocaleTimeString([], { hour: "numeric", minute: "2-digit" }));
@@ -1448,29 +1059,35 @@ function CookieSettingsView({
1448
1059
  }));
1449
1060
  };
1450
1061
  const handleSave = () => {
1451
- const record = setCookieConsent(preferences, "settings_save");
1062
+ const record = compliance.setCookieConsent(preferences, "settings_save");
1452
1063
  setSaveSuccess(true);
1453
1064
  setLastSavedTime(new Date(record.timestamp).toLocaleTimeString([], { hour: "numeric", minute: "2-digit" }));
1454
1065
  void recordConsentToCompliance(record, {
1455
- endpoint: complianceEndpoint});
1066
+ endpoint: complianceEndpoint,
1067
+ publicationSlug
1068
+ });
1456
1069
  window.scrollTo({ top: 0, behavior: "smooth" });
1457
1070
  };
1458
1071
  const handleAcceptAll = () => {
1459
- setPreferences({ ...DEFAULT_PREFERENCES_ACCEPTED });
1460
- const record = setCookieConsent(DEFAULT_PREFERENCES_ACCEPTED, "settings_save");
1072
+ setPreferences({ ...compliance.DEFAULT_PREFERENCES_ACCEPTED });
1073
+ const record = compliance.setCookieConsent(compliance.DEFAULT_PREFERENCES_ACCEPTED, "settings_save");
1461
1074
  setSaveSuccess(true);
1462
1075
  setLastSavedTime(new Date(record.timestamp).toLocaleTimeString([], { hour: "numeric", minute: "2-digit" }));
1463
1076
  void recordConsentToCompliance(record, {
1464
- endpoint: complianceEndpoint});
1077
+ endpoint: complianceEndpoint,
1078
+ publicationSlug
1079
+ });
1465
1080
  window.scrollTo({ top: 0, behavior: "smooth" });
1466
1081
  };
1467
1082
  const handleRejectAll = () => {
1468
- setPreferences({ ...DEFAULT_PREFERENCES_REJECTED });
1469
- const record = setCookieConsent(DEFAULT_PREFERENCES_REJECTED, "settings_save");
1083
+ setPreferences({ ...compliance.DEFAULT_PREFERENCES_REJECTED });
1084
+ const record = compliance.setCookieConsent(compliance.DEFAULT_PREFERENCES_REJECTED, "settings_save");
1470
1085
  setSaveSuccess(true);
1471
1086
  setLastSavedTime(new Date(record.timestamp).toLocaleTimeString([], { hour: "numeric", minute: "2-digit" }));
1472
1087
  void recordConsentToCompliance(record, {
1473
- endpoint: complianceEndpoint});
1088
+ endpoint: complianceEndpoint,
1089
+ publicationSlug
1090
+ });
1474
1091
  window.scrollTo({ top: 0, behavior: "smooth" });
1475
1092
  };
1476
1093
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sm-cookie-settings-container", children: [
@@ -1934,27 +1551,255 @@ function ThemeToggle({
1934
1551
  ] });
1935
1552
  }
1936
1553
 
1554
+ // src/network.ts
1555
+ var localPublications = [
1556
+ {
1557
+ slug: "bayareachronicle",
1558
+ name: "Bay Area Chronicle",
1559
+ url: "https://bayareachronicle.com",
1560
+ area: "San Francisco Bay Area",
1561
+ description: "The parent home for our local community publications."
1562
+ },
1563
+ {
1564
+ slug: "concordchronicle",
1565
+ name: "Concord Chronicle",
1566
+ url: "https://concordchronicle.com",
1567
+ area: "Concord",
1568
+ description: "A new place for Concord\u2019s local stories, independent businesses and community voices."
1569
+ },
1570
+ {
1571
+ slug: "walnutcreektimes",
1572
+ name: "Walnut Creek Times",
1573
+ url: "https://walnutcreektimes.com",
1574
+ area: "Walnut Creek \xB7 Rossmoor \xB7 Saranap \xB7 Pleasant Hill",
1575
+ description: "A new place for Walnut Creek\u2019s local stories, independent businesses and community voices."
1576
+ },
1577
+ {
1578
+ slug: "lamorindapost",
1579
+ name: "Lamorinda Post",
1580
+ url: "https://lamorindapost.com",
1581
+ area: "Orinda \xB7 Lafayette \xB7 Moraga",
1582
+ description: "A new home for the neighbors, businesses and community stories of Lamorinda."
1583
+ },
1584
+ {
1585
+ slug: "alamoweekly",
1586
+ name: "Alamo Weekly",
1587
+ url: "https://alamoweekly.com",
1588
+ area: "Alamo",
1589
+ description: "A new place for Alamo\u2019s local stories, independent businesses and community voices."
1590
+ },
1591
+ {
1592
+ slug: "danvilletimes",
1593
+ name: "Danville Times",
1594
+ url: "https://danvilletimes.com",
1595
+ area: "Danville",
1596
+ description: "A new place for Danville\u2019s local stories, independent businesses and community voices."
1597
+ },
1598
+ {
1599
+ slug: "sanramontimes",
1600
+ name: "San Ramon Times",
1601
+ url: "https://sanramontimes.com",
1602
+ area: "San Ramon",
1603
+ description: "A new place for San Ramon\u2019s local stories, independent businesses and community voices."
1604
+ },
1605
+ {
1606
+ slug: "diablovalleynews",
1607
+ name: "Diablo Valley News",
1608
+ url: "https://diablovalleynews.com",
1609
+ area: "Concord \xB7 Walnut Creek \xB7 Pleasant Hill \xB7 Alamo \xB7 Danville \xB7 San Ramon",
1610
+ description: "Local stories about the people, businesses and community life of the Diablo Valley."
1611
+ },
1612
+ {
1613
+ slug: "trivalleyweekly",
1614
+ name: "Tri-Valley Weekly",
1615
+ url: "https://trivalleyweekly.com",
1616
+ area: "Alamo \xB7 Danville \xB7 San Ramon \xB7 Dublin \xB7 Pleasanton \xB7 Livermore",
1617
+ description: "Local stories about the businesses, people and community life of the Tri-Valley."
1618
+ },
1619
+ {
1620
+ slug: "eastbaypost",
1621
+ name: "East Bay Post",
1622
+ url: "https://eastbaypost.com",
1623
+ area: "The East Bay",
1624
+ description: "A new publication connecting the people and neighborhoods of the East Bay."
1625
+ },
1626
+ {
1627
+ slug: "napagate",
1628
+ name: "Napa Gate",
1629
+ url: "https://napagate.com",
1630
+ area: "Napa Valley",
1631
+ description: "A new local publication for the people, places and everyday life of Napa Valley.",
1632
+ listed: false
1633
+ }
1634
+ ];
1635
+ var listedPublications = localPublications.filter(
1636
+ (publication) => !("listed" in publication) || publication.listed
1637
+ );
1638
+ var communityPublications = listedPublications.filter(
1639
+ (publication) => publication.slug !== "bayareachronicle"
1640
+ );
1641
+ function findPublicationBySlug(slug) {
1642
+ return localPublications.find((p) => p.slug === slug);
1643
+ }
1644
+ function findPublicationByHost(host) {
1645
+ const cleanHost = host.replace(/^https?:\/\//, "").replace(/\/.*$/, "").toLowerCase();
1646
+ return localPublications.find((p) => {
1647
+ const pubHost = p.url.replace(/^https?:\/\//, "").replace(/\/.*$/, "").toLowerCase();
1648
+ return pubHost === cleanHost || cleanHost.startsWith(`${p.slug}.`);
1649
+ });
1650
+ }
1651
+ function getNetworkPublicationUrl(slug) {
1652
+ const pub = findPublicationBySlug(slug);
1653
+ if (!pub) return null;
1654
+ return compliance.decorateNetworkUrl(pub.url + "/");
1655
+ }
1656
+ function LocalNetworkBar({ currentSlug, className = "", style }) {
1657
+ const [open, setOpen] = react.useState(false);
1658
+ const id = react.useId();
1659
+ const button = react.useRef(null);
1660
+ return /* @__PURE__ */ jsxRuntime.jsx(
1661
+ "nav",
1662
+ {
1663
+ className: `sm-network-bar ${className}`.trim(),
1664
+ style,
1665
+ "aria-label": "Local publication network",
1666
+ onKeyDown: (e) => {
1667
+ if (e.key === "Escape" && open) {
1668
+ setOpen(false);
1669
+ button.current?.focus();
1670
+ }
1671
+ },
1672
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sm-network-inner", children: [
1673
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sm-network-label", children: "Our local sites" }),
1674
+ /* @__PURE__ */ jsxRuntime.jsxs(
1675
+ "button",
1676
+ {
1677
+ className: "sm-network-selector",
1678
+ ref: button,
1679
+ "aria-expanded": open,
1680
+ "aria-controls": id,
1681
+ onClick: () => setOpen(!open),
1682
+ type: "button",
1683
+ children: [
1684
+ "Our local sites ",
1685
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: open ? "\u2212" : "+" })
1686
+ ]
1687
+ }
1688
+ ),
1689
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { id, className: `sm-network-sites ${open ? "sm-network-expanded" : ""}`, "aria-label": "All local publications", children: listedPublications.map((publication) => {
1690
+ const isCurrent = publication.slug === currentSlug;
1691
+ const targetUrl = isCurrent ? publication.url + "/" : compliance.decorateNetworkUrl(publication.url + "/");
1692
+ return /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
1693
+ "a",
1694
+ {
1695
+ href: targetUrl,
1696
+ "aria-current": isCurrent ? "true" : void 0,
1697
+ children: publication.name
1698
+ }
1699
+ ) }, publication.slug);
1700
+ }) })
1701
+ ] })
1702
+ }
1703
+ );
1704
+ }
1705
+
1706
+ Object.defineProperty(exports, "COOKIE_CONSENT_BACKUP_KEY", {
1707
+ enumerable: true,
1708
+ get: function () { return compliance.COOKIE_CONSENT_BACKUP_KEY; }
1709
+ });
1710
+ Object.defineProperty(exports, "COOKIE_CONSENT_EVENT", {
1711
+ enumerable: true,
1712
+ get: function () { return compliance.COOKIE_CONSENT_EVENT; }
1713
+ });
1714
+ Object.defineProperty(exports, "COOKIE_CONSENT_KEY", {
1715
+ enumerable: true,
1716
+ get: function () { return compliance.COOKIE_CONSENT_KEY; }
1717
+ });
1718
+ Object.defineProperty(exports, "COOKIE_CONSENT_MAX_AGE_SECONDS", {
1719
+ enumerable: true,
1720
+ get: function () { return compliance.COOKIE_CONSENT_MAX_AGE_SECONDS; }
1721
+ });
1722
+ Object.defineProperty(exports, "DEFAULT_CONSENT_HUB_URL", {
1723
+ enumerable: true,
1724
+ get: function () { return compliance.DEFAULT_CONSENT_HUB_URL; }
1725
+ });
1726
+ Object.defineProperty(exports, "DEFAULT_PREFERENCES_ACCEPTED", {
1727
+ enumerable: true,
1728
+ get: function () { return compliance.DEFAULT_PREFERENCES_ACCEPTED; }
1729
+ });
1730
+ Object.defineProperty(exports, "DEFAULT_PREFERENCES_REJECTED", {
1731
+ enumerable: true,
1732
+ get: function () { return compliance.DEFAULT_PREFERENCES_REJECTED; }
1733
+ });
1734
+ Object.defineProperty(exports, "EU_EEA_UK_COUNTRIES", {
1735
+ enumerable: true,
1736
+ get: function () { return compliance.EU_EEA_UK_COUNTRIES; }
1737
+ });
1738
+ Object.defineProperty(exports, "NETWORK_CONSENT_STORAGE_KEY", {
1739
+ enumerable: true,
1740
+ get: function () { return compliance.NETWORK_CONSENT_STORAGE_KEY; }
1741
+ });
1742
+ Object.defineProperty(exports, "acceptAllCookies", {
1743
+ enumerable: true,
1744
+ get: function () { return compliance.acceptAllCookies; }
1745
+ });
1746
+ Object.defineProperty(exports, "checkUrlConsentBridge", {
1747
+ enumerable: true,
1748
+ get: function () { return compliance.checkUrlConsentBridge; }
1749
+ });
1750
+ Object.defineProperty(exports, "clearCookieConsent", {
1751
+ enumerable: true,
1752
+ get: function () { return compliance.clearCookieConsent; }
1753
+ });
1754
+ Object.defineProperty(exports, "decorateNetworkUrl", {
1755
+ enumerable: true,
1756
+ get: function () { return compliance.decorateNetworkUrl; }
1757
+ });
1758
+ Object.defineProperty(exports, "getCookieConsent", {
1759
+ enumerable: true,
1760
+ get: function () { return compliance.getCookieConsent; }
1761
+ });
1762
+ Object.defineProperty(exports, "hasConsented", {
1763
+ enumerable: true,
1764
+ get: function () { return compliance.hasConsented; }
1765
+ });
1766
+ Object.defineProperty(exports, "isCategoryAllowed", {
1767
+ enumerable: true,
1768
+ get: function () { return compliance.isCategoryAllowed; }
1769
+ });
1770
+ Object.defineProperty(exports, "isGeoConsentRequired", {
1771
+ enumerable: true,
1772
+ get: function () { return compliance.isGeoConsentRequired; }
1773
+ });
1774
+ Object.defineProperty(exports, "queryNetworkConsentHub", {
1775
+ enumerable: true,
1776
+ get: function () { return compliance.queryNetworkConsentHub; }
1777
+ });
1778
+ Object.defineProperty(exports, "rejectOptionalCookies", {
1779
+ enumerable: true,
1780
+ get: function () { return compliance.rejectOptionalCookies; }
1781
+ });
1782
+ Object.defineProperty(exports, "setCookieConsent", {
1783
+ enumerable: true,
1784
+ get: function () { return compliance.setCookieConsent; }
1785
+ });
1786
+ Object.defineProperty(exports, "setNetworkConsentHub", {
1787
+ enumerable: true,
1788
+ get: function () { return compliance.setNetworkConsentHub; }
1789
+ });
1937
1790
  exports.ANALYTICS_COOKIE = ANALYTICS_COOKIE;
1938
1791
  exports.ANALYTICS_VERSION = ANALYTICS_VERSION;
1939
1792
  exports.BROADSHEET_THEME = BROADSHEET_THEME;
1940
1793
  exports.CLASSIFIED_CATEGORIES = CLASSIFIED_CATEGORIES;
1941
1794
  exports.COOKIE_CATEGORIES = COOKIE_CATEGORIES;
1942
- exports.COOKIE_CONSENT_BACKUP_KEY = COOKIE_CONSENT_BACKUP_KEY;
1943
- exports.COOKIE_CONSENT_EVENT = COOKIE_CONSENT_EVENT;
1944
- exports.COOKIE_CONSENT_KEY = COOKIE_CONSENT_KEY;
1945
- exports.COOKIE_CONSENT_MAX_AGE_SECONDS = COOKIE_CONSENT_MAX_AGE_SECONDS;
1946
1795
  exports.CookieConsentBanner = CookieConsentBanner;
1947
1796
  exports.CookieSettingsView = CookieSettingsView;
1948
- exports.DEFAULT_CONSENT_HUB_URL = DEFAULT_CONSENT_HUB_URL;
1949
- exports.DEFAULT_PREFERENCES_ACCEPTED = DEFAULT_PREFERENCES_ACCEPTED;
1950
- exports.DEFAULT_PREFERENCES_REJECTED = DEFAULT_PREFERENCES_REJECTED;
1951
- exports.EU_EEA_UK_COUNTRIES = EU_EEA_UK_COUNTRIES;
1952
1797
  exports.EVENTS = EVENTS;
1953
1798
  exports.FEATURE_NAMES = FEATURE_NAMES;
1954
1799
  exports.JOB_EMPLOYMENT_TYPES = JOB_EMPLOYMENT_TYPES;
1955
1800
  exports.LAYOUT_COOKIE = LAYOUT_COOKIE;
1801
+ exports.LocalNetworkBar = LocalNetworkBar;
1956
1802
  exports.MEET_ACTIVITIES = MEET_ACTIVITIES;
1957
- exports.NETWORK_CONSENT_STORAGE_KEY = NETWORK_CONSENT_STORAGE_KEY;
1958
1803
  exports.NEWS_CACHE = NEWS_CACHE;
1959
1804
  exports.NewsError = NewsError;
1960
1805
  exports.SESSION_IDLE_MS = SESSION_IDLE_MS;
@@ -1965,7 +1810,6 @@ exports.THEME_STORAGE_KEY = THEME_STORAGE_KEY;
1965
1810
  exports.ThemeToggle = ThemeToggle;
1966
1811
  exports.UTM_FIELDS = UTM_FIELDS;
1967
1812
  exports.UUID = UUID;
1968
- exports.acceptAllCookies = acceptAllCookies;
1969
1813
  exports.acceptRemoteRecord = acceptRemoteRecord;
1970
1814
  exports.acceptSnapshot = acceptSnapshot;
1971
1815
  exports.activeNearby = activeNearby;
@@ -1979,17 +1823,15 @@ exports.attribution = attribution;
1979
1823
  exports.briefSummary = briefSummary;
1980
1824
  exports.canHostMeetup = canHostMeetup;
1981
1825
  exports.categoryLabel = categoryLabel;
1982
- exports.checkUrlConsentBridge = checkUrlConsentBridge;
1983
1826
  exports.classifiedPath = classifiedPath;
1984
1827
  exports.classifiedSearchPath = classifiedSearchPath;
1985
- exports.clearCookieConsent = clearCookieConsent;
1986
1828
  exports.clearTheme = clearTheme;
1987
1829
  exports.clipChars = clipChars;
1830
+ exports.communityPublications = communityPublications;
1988
1831
  exports.composeEdition = composeEdition;
1989
1832
  exports.dealDollars = dealDollars;
1990
1833
  exports.dealGoPath = dealGoPath;
1991
1834
  exports.dealsFeedPath = dealsFeedPath;
1992
- exports.decorateNetworkUrl = decorateNetworkUrl;
1993
1835
  exports.defaultRevalidateTargets = defaultRevalidateTargets;
1994
1836
  exports.definePublication = definePublication;
1995
1837
  exports.displayHeadline = displayHeadline;
@@ -2000,20 +1842,21 @@ exports.featureEnabled = featureEnabled;
2000
1842
  exports.feedCacheKey = feedCacheKey;
2001
1843
  exports.feedCacheOptions = feedCacheOptions;
2002
1844
  exports.filterNews = filterNews;
2003
- exports.getCookieConsent = getCookieConsent;
1845
+ exports.findPublicationByHost = findPublicationByHost;
1846
+ exports.findPublicationBySlug = findPublicationBySlug;
1847
+ exports.getNetworkPublicationUrl = getNetworkPublicationUrl;
2004
1848
  exports.getStoredTheme = getStoredTheme;
2005
1849
  exports.getSystemTheme = getSystemTheme;
2006
- exports.hasConsented = hasConsented;
2007
1850
  exports.inventoryCacheOptions = inventoryCacheOptions;
2008
1851
  exports.isAdult = isAdult;
2009
- exports.isCategoryAllowed = isCategoryAllowed;
2010
1852
  exports.isClassifiedCategory = isClassifiedCategory;
2011
1853
  exports.isEmploymentType = isEmploymentType;
2012
- exports.isGeoConsentRequired = isGeoConsentRequired;
2013
1854
  exports.jobEmployerBody = jobEmployerBody;
2014
1855
  exports.jobOpeningBody = jobOpeningBody;
2015
1856
  exports.jobPostingBody = jobPostingBody;
1857
+ exports.listedPublications = listedPublications;
2016
1858
  exports.llmsText = llmsText;
1859
+ exports.localPublications = localPublications;
2017
1860
  exports.matchesStoryTag = matchesStoryTag;
2018
1861
  exports.nearbyUpdates = nearbyUpdates;
2019
1862
  exports.newsArticleJsonLd = newsArticleJsonLd;
@@ -2030,10 +1873,8 @@ exports.publicationFromSnapshot = publicationFromSnapshot;
2030
1873
  exports.publicationJsonLd = publicationJsonLd;
2031
1874
  exports.publicationMeta = publicationMeta;
2032
1875
  exports.publicationRecord = publicationRecord;
2033
- exports.queryNetworkConsentHub = queryNetworkConsentHub;
2034
1876
  exports.recordConsentToCompliance = recordConsentToCompliance;
2035
1877
  exports.referralCode = referralCode;
2036
- exports.rejectOptionalCookies = rejectOptionalCookies;
2037
1878
  exports.resolveCoupon = resolveCoupon;
2038
1879
  exports.resolveEffectiveTheme = resolveEffectiveTheme;
2039
1880
  exports.resolveLayout = resolveLayout;
@@ -2043,8 +1884,6 @@ exports.secretsMatch = secretsMatch;
2043
1884
  exports.sectionDefinition = sectionDefinition;
2044
1885
  exports.sectionId = sectionId;
2045
1886
  exports.sectionPath = sectionPath;
2046
- exports.setCookieConsent = setCookieConsent;
2047
- exports.setNetworkConsentHub = setNetworkConsentHub;
2048
1887
  exports.setTheme = setTheme;
2049
1888
  exports.shortDeck = shortDeck;
2050
1889
  exports.shortText = shortText;