@scalemule/news-publication 0.0.40 → 0.0.42

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.
@@ -75,12 +75,15 @@ function createPublicationCommunityMapsHandler(options) {
75
75
  const featureId = params.get("feature_id") || void 0;
76
76
  if (discussion && featureId && !UUID.test(featureId))
77
77
  return json({ error: { message: "Invalid place" } }, 400);
78
- const read = method === "GET" && (discussion || voting || rest.length === 0 || rest[0] === "features" && (rest.length === 1 || rest.length === 2 && UUID.test(rest[1])) || rest[0] === "media" && rest.length === 2 && UUID.test(rest[1]));
78
+ const ownList = rest.length === 1 && rest[0] === "submissions";
79
+ const ownUpdate = method === "POST" && rest.length === 2 && rest[0] === "submissions" && UUID.test(rest[1]);
80
+ const ownMedia = rest.length === 4 && rest[0] === "submissions" && UUID.test(rest[1]) && rest[2] === "media" && UUID.test(rest[3]);
81
+ const read = method === "GET" && (ownList || ownMedia || discussion || voting || rest.length === 0 || rest[0] === "features" && (rest.length === 1 || rest.length === 2 && UUID.test(rest[1])) || rest[0] === "media" && rest.length === 2 && UUID.test(rest[1]));
79
82
  const upload = method === "POST" && rest.length === 3 && rest[0] === "submissions" && UUID.test(rest[1]) && rest[2] === "media";
80
83
  const submission = method === "POST" && rest.length === 1 && rest[0] === "submissions";
81
84
  const action = method === "POST" && rest.length === 3 && rest[0] === "features" && UUID.test(rest[1]) && ["reactions", "reports"].includes(rest[2]);
82
85
  const engagementWrite = method === "POST" && (discussion || voting);
83
- if (!read && !upload && !submission && !action && !engagementWrite)
86
+ if (!read && !upload && !submission && !ownUpdate && !action && !engagementWrite)
84
87
  return json({ error: { message: "Route not found" } }, 404);
85
88
  const scope = await options.resolve(request);
86
89
  if (method !== "GET" && request.headers.get("origin") !== new URL(scope.origin).origin)
@@ -104,9 +107,9 @@ function createPublicationCommunityMapsHandler(options) {
104
107
  headers: scope.accessToken ? { authorization: `Bearer ${scope.accessToken}` } : {}
105
108
  };
106
109
  let response;
107
- if (read && rest[0] === "media") {
110
+ if (read && (rest[0] === "media" || ownMedia)) {
108
111
  const upstream = await fetch(
109
- `${gateway.origin}${ROOT}/collections/${slug}/media/${rest[1]}`,
112
+ `${gateway.origin}${ROOT}/collections/${slug}/${ownMedia ? `submissions/${rest[1]}/media/${rest[3]}` : `media/${rest[1]}`}`,
110
113
  {
111
114
  headers: {
112
115
  ...sdk.buildClientContextHeaders(clientContext),
@@ -157,7 +160,16 @@ function createPublicationCommunityMapsHandler(options) {
157
160
  } else {
158
161
  let result;
159
162
  if (read) {
160
- if (discussion)
163
+ if (ownList) {
164
+ const after = params.get("after") || void 0;
165
+ if (after && !UUID.test(after))
166
+ throw new ProxyProblem(400, "Invalid submission cursor.");
167
+ result = await sdk$1.communityMaps.listOwnSubmissions(
168
+ slug,
169
+ after,
170
+ callOptions
171
+ );
172
+ } else if (discussion)
161
173
  result = await sdk$1.communityMaps.listComments(
162
174
  slug,
163
175
  {
@@ -231,7 +243,8 @@ function createPublicationCommunityMapsHandler(options) {
231
243
  caption: String(form.get("caption") || ""),
232
244
  attribution: String(form.get("attribution") || ""),
233
245
  rights_confirmed: form.get("rights_confirmed") === "true",
234
- consent_version: String(form.get("consent_version") || "")
246
+ consent_version: String(form.get("consent_version") || ""),
247
+ ...form.has("idempotency_key") ? { idempotency_key: String(form.get("idempotency_key")) } : {}
235
248
  },
236
249
  callOptions
237
250
  );
@@ -263,6 +276,13 @@ function createPublicationCommunityMapsHandler(options) {
263
276
  body.value,
264
277
  callOptions
265
278
  );
279
+ else if (ownUpdate)
280
+ result = await sdk$1.communityMaps.updateOwnSubmission(
281
+ slug,
282
+ rest[1],
283
+ body,
284
+ callOptions
285
+ );
266
286
  else if (submission)
267
287
  result = await sdk$1.communityMaps.createSubmission(
268
288
  slug,
@@ -73,12 +73,15 @@ function createPublicationCommunityMapsHandler(options) {
73
73
  const featureId = params.get("feature_id") || void 0;
74
74
  if (discussion && featureId && !UUID.test(featureId))
75
75
  return json({ error: { message: "Invalid place" } }, 400);
76
- const read = method === "GET" && (discussion || voting || rest.length === 0 || rest[0] === "features" && (rest.length === 1 || rest.length === 2 && UUID.test(rest[1])) || rest[0] === "media" && rest.length === 2 && UUID.test(rest[1]));
76
+ const ownList = rest.length === 1 && rest[0] === "submissions";
77
+ const ownUpdate = method === "POST" && rest.length === 2 && rest[0] === "submissions" && UUID.test(rest[1]);
78
+ const ownMedia = rest.length === 4 && rest[0] === "submissions" && UUID.test(rest[1]) && rest[2] === "media" && UUID.test(rest[3]);
79
+ const read = method === "GET" && (ownList || ownMedia || discussion || voting || rest.length === 0 || rest[0] === "features" && (rest.length === 1 || rest.length === 2 && UUID.test(rest[1])) || rest[0] === "media" && rest.length === 2 && UUID.test(rest[1]));
77
80
  const upload = method === "POST" && rest.length === 3 && rest[0] === "submissions" && UUID.test(rest[1]) && rest[2] === "media";
78
81
  const submission = method === "POST" && rest.length === 1 && rest[0] === "submissions";
79
82
  const action = method === "POST" && rest.length === 3 && rest[0] === "features" && UUID.test(rest[1]) && ["reactions", "reports"].includes(rest[2]);
80
83
  const engagementWrite = method === "POST" && (discussion || voting);
81
- if (!read && !upload && !submission && !action && !engagementWrite)
84
+ if (!read && !upload && !submission && !ownUpdate && !action && !engagementWrite)
82
85
  return json({ error: { message: "Route not found" } }, 404);
83
86
  const scope = await options.resolve(request);
84
87
  if (method !== "GET" && request.headers.get("origin") !== new URL(scope.origin).origin)
@@ -102,9 +105,9 @@ function createPublicationCommunityMapsHandler(options) {
102
105
  headers: scope.accessToken ? { authorization: `Bearer ${scope.accessToken}` } : {}
103
106
  };
104
107
  let response;
105
- if (read && rest[0] === "media") {
108
+ if (read && (rest[0] === "media" || ownMedia)) {
106
109
  const upstream = await fetch(
107
- `${gateway.origin}${ROOT}/collections/${slug}/media/${rest[1]}`,
110
+ `${gateway.origin}${ROOT}/collections/${slug}/${ownMedia ? `submissions/${rest[1]}/media/${rest[3]}` : `media/${rest[1]}`}`,
108
111
  {
109
112
  headers: {
110
113
  ...buildClientContextHeaders(clientContext),
@@ -155,7 +158,16 @@ function createPublicationCommunityMapsHandler(options) {
155
158
  } else {
156
159
  let result;
157
160
  if (read) {
158
- if (discussion)
161
+ if (ownList) {
162
+ const after = params.get("after") || void 0;
163
+ if (after && !UUID.test(after))
164
+ throw new ProxyProblem(400, "Invalid submission cursor.");
165
+ result = await sdk.communityMaps.listOwnSubmissions(
166
+ slug,
167
+ after,
168
+ callOptions
169
+ );
170
+ } else if (discussion)
159
171
  result = await sdk.communityMaps.listComments(
160
172
  slug,
161
173
  {
@@ -229,7 +241,8 @@ function createPublicationCommunityMapsHandler(options) {
229
241
  caption: String(form.get("caption") || ""),
230
242
  attribution: String(form.get("attribution") || ""),
231
243
  rights_confirmed: form.get("rights_confirmed") === "true",
232
- consent_version: String(form.get("consent_version") || "")
244
+ consent_version: String(form.get("consent_version") || ""),
245
+ ...form.has("idempotency_key") ? { idempotency_key: String(form.get("idempotency_key")) } : {}
233
246
  },
234
247
  callOptions
235
248
  );
@@ -261,6 +274,13 @@ function createPublicationCommunityMapsHandler(options) {
261
274
  body.value,
262
275
  callOptions
263
276
  );
277
+ else if (ownUpdate)
278
+ result = await sdk.communityMaps.updateOwnSubmission(
279
+ slug,
280
+ rest[1],
281
+ body,
282
+ callOptions
283
+ );
264
284
  else if (submission)
265
285
  result = await sdk.communityMaps.createSubmission(
266
286
  slug,
@@ -42,64 +42,90 @@ function PublicationCommunityMapPage({
42
42
  );
43
43
  const signInHref = (f) => `/account?next=${encodeURIComponent(`${basePath}/places/${f.id}`)}`;
44
44
  const featureHref = (f) => `${basePath}/places/${f.id}`;
45
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "smcm", children: [
46
- mode !== "guide" && /* @__PURE__ */ jsxRuntime.jsx("p", { children: /* @__PURE__ */ jsxRuntime.jsxs("a", { href: basePath, children: [
47
- "\u2190 ",
48
- collection.config.title
49
- ] }) }),
50
- mode === "submit" ? /* @__PURE__ */ jsxRuntime.jsx(
51
- communityMaps.CommunitySubmissionForm,
52
- {
53
- client,
54
- collection,
55
- initialAreaId: areaId,
56
- correctionFor,
57
- guidelinesHref: "/editorial-standards",
58
- termsHref: "/terms"
59
- }
60
- ) : mode === "feature" && feature ? /* @__PURE__ */ jsxRuntime.jsx(
61
- communityMaps.CommunityFeatureDetail,
62
- {
63
- client,
64
- collection,
65
- feature,
66
- signInHref: signInHref(feature),
67
- correctionHref: `${basePath}/submit?correction=${feature.id}&area=${feature.area_id}`
68
- }
69
- ) : atlas ? /* @__PURE__ */ jsxRuntime.jsx(
70
- communityMaps.CommunityCityGuide,
71
- {
72
- client,
73
- collection,
74
- atlas,
75
- featureHref,
76
- signInHref,
77
- communityHref: (id) => `${basePath}?area=${id}`,
78
- submitHref: `${basePath}/submit?area=${collection.areas.find((a) => a.slug === atlas.areaSlug)?.id || ""}`
79
- }
80
- ) : /* @__PURE__ */ jsxRuntime.jsx(
81
- communityMaps.CommunityGuide,
82
- {
83
- client,
84
- collection,
85
- featureHref,
86
- signInHref,
87
- communityHref: (a) => `${basePath}/map?area=${a.id}`,
88
- submitHref: `${basePath}/submit${areaId ? `?area=${areaId}` : ""}`,
89
- initialAreaId: areaId,
90
- showMap: mode === "map"
91
- }
92
- ),
93
- (mode === "guide" || mode === "map") && /* @__PURE__ */ jsxRuntime.jsx(
94
- communityMaps.CommunityDiscussion,
95
- {
96
- client,
97
- collection,
98
- guidelinesHref: "/editorial-standards",
99
- termsHref: "/terms"
100
- }
101
- )
102
- ] });
45
+ return /* @__PURE__ */ jsxRuntime.jsxs(
46
+ "div",
47
+ {
48
+ className: `smcm${atlas ? " smcm-illustrated-publication" : ""}`,
49
+ style: {
50
+ "--smcm-paper": "var(--pub-paper, Canvas)",
51
+ "--smcm-ink": "var(--pub-ink, CanvasText)",
52
+ "--smcm-border": "var(--pub-rule, currentColor)"
53
+ },
54
+ children: [
55
+ mode !== "guide" && /* @__PURE__ */ jsxRuntime.jsx("p", { children: /* @__PURE__ */ jsxRuntime.jsxs("a", { href: basePath, children: [
56
+ "\u2190 ",
57
+ collection.config.title
58
+ ] }) }),
59
+ mode === "submit" ? correctionFor ? /* @__PURE__ */ jsxRuntime.jsx(
60
+ communityMaps.CommunitySubmissionForm,
61
+ {
62
+ client,
63
+ collection,
64
+ initialAreaId: areaId || collection.areas.find((a) => a.slug === atlas?.areaSlug)?.id,
65
+ correctionFor,
66
+ guidelinesHref: "/editorial-standards",
67
+ termsHref: "/terms"
68
+ }
69
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
70
+ communityMaps.CommunityStreetCapture,
71
+ {
72
+ client,
73
+ collection,
74
+ initialAreaId: areaId || collection.areas.find((a) => a.slug === atlas?.areaSlug)?.id,
75
+ featureHref: (id) => `${basePath}/places/${id}`,
76
+ guidelinesHref: "/editorial-standards",
77
+ termsHref: "/terms"
78
+ }
79
+ ) : mode === "feature" && feature ? /* @__PURE__ */ jsxRuntime.jsx(
80
+ communityMaps.CommunityFeatureDetail,
81
+ {
82
+ client,
83
+ collection,
84
+ feature,
85
+ signInHref: signInHref(feature),
86
+ correctionHref: `${basePath}/submit?correction=${feature.id}&area=${feature.area_id}`
87
+ }
88
+ ) : atlas ? /* @__PURE__ */ jsxRuntime.jsx(
89
+ communityMaps.CommunityCityGuide,
90
+ {
91
+ client,
92
+ collection,
93
+ atlas,
94
+ featureHref,
95
+ signInHref,
96
+ communityHref: (id) => `${basePath}?area=${id}`,
97
+ submitHref: `${basePath}/submit?area=${collection.areas.find((a) => a.slug === atlas.areaSlug)?.id || ""}`
98
+ }
99
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
100
+ communityMaps.CommunityGuide,
101
+ {
102
+ client,
103
+ collection,
104
+ featureHref,
105
+ signInHref,
106
+ communityHref: (a) => `${basePath}/map?area=${a.id}`,
107
+ submitHref: `${basePath}/submit${areaId ? `?area=${areaId}` : ""}`,
108
+ initialAreaId: areaId,
109
+ showMap: mode === "map"
110
+ }
111
+ ),
112
+ (mode === "guide" || mode === "map") && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "smcm-contribute-links", children: [
113
+ "Already shared a place?",
114
+ " ",
115
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: `${basePath}/submit#my-submissions`, children: "My submissions" })
116
+ ] }),
117
+ (mode === "guide" || mode === "map") && /* @__PURE__ */ jsxRuntime.jsx(
118
+ communityMaps.CommunityDiscussion,
119
+ {
120
+ client,
121
+ collection,
122
+ guidelinesHref: "/editorial-standards",
123
+ termsHref: "/terms"
124
+ }
125
+ )
126
+ ]
127
+ }
128
+ );
103
129
  }
104
130
  function CommunityMapArticleEmbeds({
105
131
  metadata,
@@ -2,7 +2,7 @@
2
2
  import { communityMapEmbeds } from './chunk-IMYBSG7J.js';
3
3
  export { communityMapEmbeds } from './chunk-IMYBSG7J.js';
4
4
  import { useMemo, useState, useEffect } from 'react';
5
- import { createCommunityMapsBrowserClient, CommunitySubmissionForm, CommunityFeatureDetail, CommunityCityGuide, CommunityGuide, CommunityDiscussion, CommunityCards, CommunityMap, CommunityFeatureCard } from '@scalemule/react/community-maps';
5
+ import { createCommunityMapsBrowserClient, CommunitySubmissionForm, CommunityStreetCapture, CommunityFeatureDetail, CommunityCityGuide, CommunityGuide, CommunityDiscussion, CommunityCards, CommunityMap, CommunityFeatureCard } from '@scalemule/react/community-maps';
6
6
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
7
7
 
8
8
  function PublicationCommunityMapPage({
@@ -21,64 +21,90 @@ function PublicationCommunityMapPage({
21
21
  );
22
22
  const signInHref = (f) => `/account?next=${encodeURIComponent(`${basePath}/places/${f.id}`)}`;
23
23
  const featureHref = (f) => `${basePath}/places/${f.id}`;
24
- return /* @__PURE__ */ jsxs("div", { className: "smcm", children: [
25
- mode !== "guide" && /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsxs("a", { href: basePath, children: [
26
- "\u2190 ",
27
- collection.config.title
28
- ] }) }),
29
- mode === "submit" ? /* @__PURE__ */ jsx(
30
- CommunitySubmissionForm,
31
- {
32
- client,
33
- collection,
34
- initialAreaId: areaId,
35
- correctionFor,
36
- guidelinesHref: "/editorial-standards",
37
- termsHref: "/terms"
38
- }
39
- ) : mode === "feature" && feature ? /* @__PURE__ */ jsx(
40
- CommunityFeatureDetail,
41
- {
42
- client,
43
- collection,
44
- feature,
45
- signInHref: signInHref(feature),
46
- correctionHref: `${basePath}/submit?correction=${feature.id}&area=${feature.area_id}`
47
- }
48
- ) : atlas ? /* @__PURE__ */ jsx(
49
- CommunityCityGuide,
50
- {
51
- client,
52
- collection,
53
- atlas,
54
- featureHref,
55
- signInHref,
56
- communityHref: (id) => `${basePath}?area=${id}`,
57
- submitHref: `${basePath}/submit?area=${collection.areas.find((a) => a.slug === atlas.areaSlug)?.id || ""}`
58
- }
59
- ) : /* @__PURE__ */ jsx(
60
- CommunityGuide,
61
- {
62
- client,
63
- collection,
64
- featureHref,
65
- signInHref,
66
- communityHref: (a) => `${basePath}/map?area=${a.id}`,
67
- submitHref: `${basePath}/submit${areaId ? `?area=${areaId}` : ""}`,
68
- initialAreaId: areaId,
69
- showMap: mode === "map"
70
- }
71
- ),
72
- (mode === "guide" || mode === "map") && /* @__PURE__ */ jsx(
73
- CommunityDiscussion,
74
- {
75
- client,
76
- collection,
77
- guidelinesHref: "/editorial-standards",
78
- termsHref: "/terms"
79
- }
80
- )
81
- ] });
24
+ return /* @__PURE__ */ jsxs(
25
+ "div",
26
+ {
27
+ className: `smcm${atlas ? " smcm-illustrated-publication" : ""}`,
28
+ style: {
29
+ "--smcm-paper": "var(--pub-paper, Canvas)",
30
+ "--smcm-ink": "var(--pub-ink, CanvasText)",
31
+ "--smcm-border": "var(--pub-rule, currentColor)"
32
+ },
33
+ children: [
34
+ mode !== "guide" && /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsxs("a", { href: basePath, children: [
35
+ "\u2190 ",
36
+ collection.config.title
37
+ ] }) }),
38
+ mode === "submit" ? correctionFor ? /* @__PURE__ */ jsx(
39
+ CommunitySubmissionForm,
40
+ {
41
+ client,
42
+ collection,
43
+ initialAreaId: areaId || collection.areas.find((a) => a.slug === atlas?.areaSlug)?.id,
44
+ correctionFor,
45
+ guidelinesHref: "/editorial-standards",
46
+ termsHref: "/terms"
47
+ }
48
+ ) : /* @__PURE__ */ jsx(
49
+ CommunityStreetCapture,
50
+ {
51
+ client,
52
+ collection,
53
+ initialAreaId: areaId || collection.areas.find((a) => a.slug === atlas?.areaSlug)?.id,
54
+ featureHref: (id) => `${basePath}/places/${id}`,
55
+ guidelinesHref: "/editorial-standards",
56
+ termsHref: "/terms"
57
+ }
58
+ ) : mode === "feature" && feature ? /* @__PURE__ */ jsx(
59
+ CommunityFeatureDetail,
60
+ {
61
+ client,
62
+ collection,
63
+ feature,
64
+ signInHref: signInHref(feature),
65
+ correctionHref: `${basePath}/submit?correction=${feature.id}&area=${feature.area_id}`
66
+ }
67
+ ) : atlas ? /* @__PURE__ */ jsx(
68
+ CommunityCityGuide,
69
+ {
70
+ client,
71
+ collection,
72
+ atlas,
73
+ featureHref,
74
+ signInHref,
75
+ communityHref: (id) => `${basePath}?area=${id}`,
76
+ submitHref: `${basePath}/submit?area=${collection.areas.find((a) => a.slug === atlas.areaSlug)?.id || ""}`
77
+ }
78
+ ) : /* @__PURE__ */ jsx(
79
+ CommunityGuide,
80
+ {
81
+ client,
82
+ collection,
83
+ featureHref,
84
+ signInHref,
85
+ communityHref: (a) => `${basePath}/map?area=${a.id}`,
86
+ submitHref: `${basePath}/submit${areaId ? `?area=${areaId}` : ""}`,
87
+ initialAreaId: areaId,
88
+ showMap: mode === "map"
89
+ }
90
+ ),
91
+ (mode === "guide" || mode === "map") && /* @__PURE__ */ jsxs("p", { className: "smcm-contribute-links", children: [
92
+ "Already shared a place?",
93
+ " ",
94
+ /* @__PURE__ */ jsx("a", { href: `${basePath}/submit#my-submissions`, children: "My submissions" })
95
+ ] }),
96
+ (mode === "guide" || mode === "map") && /* @__PURE__ */ jsx(
97
+ CommunityDiscussion,
98
+ {
99
+ client,
100
+ collection,
101
+ guidelinesHref: "/editorial-standards",
102
+ termsHref: "/terms"
103
+ }
104
+ )
105
+ ]
106
+ }
107
+ );
82
108
  }
83
109
  function CommunityMapArticleEmbeds({
84
110
  metadata,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scalemule/news-publication",
3
- "version": "0.0.40",
3
+ "version": "0.0.42",
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",
@@ -109,8 +109,8 @@
109
109
  "story-review.css"
110
110
  ],
111
111
  "peerDependencies": {
112
- "react": ">=18.0.0",
113
- "@scalemule/react": "0.0.16"
112
+ "@scalemule/react": "0.0.19",
113
+ "react": ">=18.0.0"
114
114
  },
115
115
  "peerDependenciesMeta": {
116
116
  "react": {
@@ -129,6 +129,7 @@
129
129
  "prepublishOnly": "node -e \"const v=require('./package.json').version; if(!/^0\\.(0|1)\\.\\d+$/.test(v)){console.error('ERR: SDK '+v+' violates patch-only policy (0.0.x or 0.1.x only). See CONTRIBUTING.md SDK versioning section.');process.exit(1)}\" && npm run lint && npm test && npm run build"
130
130
  },
131
131
  "devDependencies": {
132
+ "@scalemule/react": "0.0.19",
132
133
  "@testing-library/react": "^16.3.3",
133
134
  "@types/node": "^22.15.0",
134
135
  "@types/react": "^19.1.0",
@@ -138,8 +139,7 @@
138
139
  "react-dom": "^19.3.0",
139
140
  "tsup": "^8.5.0",
140
141
  "typescript": "^5.8.3",
141
- "vitest": "^3.2.4",
142
- "@scalemule/react": "0.0.16"
142
+ "vitest": "^3.2.4"
143
143
  },
144
144
  "keywords": [
145
145
  "scalemule",
@@ -162,7 +162,7 @@
162
162
  },
163
163
  "dependencies": {
164
164
  "@scalemule/compliance": "^0.0.5",
165
- "@scalemule/sdk": "0.0.74",
166
- "@scalemule/react": "0.0.16"
165
+ "@scalemule/react": "0.0.19",
166
+ "@scalemule/sdk": "0.0.75"
167
167
  }
168
168
  }