@zenky/storefront-vue 0.11.0 → 0.12.0

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.
package/dist/seo/index.js CHANGED
@@ -1,12 +1,7 @@
1
- import { resolveVariantPrice } from '../chunk-KK645XNR.js';
2
- import { getSocialLinks } from '../chunk-RURXGVWW.js';
3
- import '../chunk-XUGXLJZB.js';
4
- import '../chunk-5QCUH3FF.js';
5
- import '../chunk-4JCJHAL3.js';
1
+ import { getEmailLink, getSocialLinks } from '../chunk-JY3UJRMF.js';
6
2
  import { minorToMajorString } from '../chunk-2Y6QTHXI.js';
7
- import '../chunk-TXR76IDL.js';
8
- import '../chunk-IOYYCA75.js';
9
- import { ContactType } from '@zenky/storefront-api';
3
+ import { getRequiredModifiersMinCost, resolveVariantPrice, getProductWeight } from '../chunk-6HOKVW4M.js';
4
+ import { UnitType } from '@zenky/storefront-api';
10
5
 
11
6
  // src/seo/utils.ts
12
7
  function resolveMediaUrl(media) {
@@ -26,6 +21,40 @@ function resolveStoreLogoUrl(store) {
26
21
  function stripHtml(html) {
27
22
  return html.replace(/<[^>]*>/g, "").trim();
28
23
  }
24
+ var INVISIBLE_CHARACTERS = /[\u00ad\u200b-\u200d\u2060\ufeff]/g;
25
+ var BLOCK_TAG = /<\/?(?:p|div|br|li|ul|ol|h[1-6]|tr|td|th|table|blockquote|section|article|header|footer)\b[^>]*>/gi;
26
+ var ANY_TAG = /<[^>]*>/g;
27
+ var HTML_ENTITY = /&(#x[0-9a-f]+|#\d+|[a-z]+);/gi;
28
+ var NAMED_ENTITIES = {
29
+ amp: "&",
30
+ lt: "<",
31
+ gt: ">",
32
+ quot: '"',
33
+ apos: "'",
34
+ nbsp: " ",
35
+ laquo: "\xAB",
36
+ raquo: "\xBB",
37
+ ndash: "\u2013",
38
+ mdash: "\u2014",
39
+ hellip: "\u2026"
40
+ };
41
+ function decodeEntity(entity, body) {
42
+ const lower = body.toLowerCase();
43
+ if (lower.startsWith("#")) {
44
+ const code = lower.startsWith("#x") ? Number.parseInt(lower.slice(2), 16) : Number.parseInt(lower.slice(1), 10);
45
+ return Number.isInteger(code) && code > 0 && code <= 1114111 ? String.fromCodePoint(code) : entity;
46
+ }
47
+ return NAMED_ENTITIES[lower] ?? entity;
48
+ }
49
+ function normalizeSchemaText(value) {
50
+ if (!value) return "";
51
+ return value.replace(INVISIBLE_CHARACTERS, "").replace(/\s+/g, " ").trim();
52
+ }
53
+ function htmlToPlainText(html) {
54
+ if (!html) return "";
55
+ const text = html.replace(BLOCK_TAG, " ").replace(ANY_TAG, "").replace(HTML_ENTITY, (entity, body) => decodeEntity(entity, body));
56
+ return normalizeSchemaText(text);
57
+ }
29
58
  function prepareOgDescription(text, maxLength = 160) {
30
59
  if (!text) return null;
31
60
  const plain = stripHtml(text);
@@ -43,56 +72,147 @@ function resolveSiteOrigin(storeDomain, fallbackOrigin) {
43
72
  return fallbackOrigin;
44
73
  }
45
74
 
46
- // src/seo/productSchema.ts
47
- function isProductInStock(variants) {
48
- if (!variants.length) return false;
49
- return variants.some((variant) => {
50
- const remainders = variant.remainders;
51
- if (!remainders?.length) return true;
52
- return remainders.some((remainder) => remainder.quantity > 0);
53
- });
75
+ // src/seo/ids.ts
76
+ function organizationSchemaId(origin) {
77
+ return `${origin}/#organization`;
54
78
  }
55
- function buildProductSchema(product, currency) {
56
- const variants = product.variants ?? [];
57
- const firstVariant = variants[0];
58
- let offerBlock;
59
- if (firstVariant) {
60
- const resolved = resolveVariantPrice(firstVariant);
61
- offerBlock = {
62
- "@type": "Offer",
63
- price: minorToMajorString(resolved.price, currency),
79
+ function webSiteSchemaId(origin) {
80
+ return `${origin}/#website`;
81
+ }
82
+ function locationAnchorId(stockId) {
83
+ return `location-${stockId}`;
84
+ }
85
+ function locationSchemaId(origin, stockId) {
86
+ return `${origin}/#${locationAnchorId(stockId)}`;
87
+ }
88
+ function productSchemaId(productUrl) {
89
+ return `${productUrl}#product`;
90
+ }
91
+
92
+ // src/seo/businessType.ts
93
+ var BUSINESS_TYPES = [
94
+ "Restaurant",
95
+ "CafeOrCoffeeShop",
96
+ "FastFoodRestaurant",
97
+ "Bakery",
98
+ "BarOrPub",
99
+ "GroceryStore",
100
+ "ConvenienceStore",
101
+ "Florist",
102
+ "Pharmacy",
103
+ "PetStore",
104
+ "ClothingStore",
105
+ "Store",
106
+ "LocalBusiness"
107
+ ];
108
+ var FOOD_VENUE = /(?:^|[^\p{L}])(?:ресторан\p{L}*|кафе|кофейн\p{L}*|бистро|пиццери\p{L}*|бар(?:а|у|ом|е|ы|ов)?|паб(?:а|у|ом|е|ы|ов)?|restaurants?|caf[eé]s?|coffee|bistro|pizzeria|bars?|pubs?)(?!\p{L})/iu;
109
+ var PICKUP_POINT = /самовывоз|выдач|pick-?up/iu;
110
+ function isBusinessType(value) {
111
+ return typeof value === "string" && BUSINESS_TYPES.includes(value);
112
+ }
113
+ function resolveLocationType(stock, businessType) {
114
+ const name = normalizeSchemaText(stock.name);
115
+ const isFoodVenue = FOOD_VENUE.test(name);
116
+ if (!businessType) return isFoodVenue ? "Restaurant" : "LocalBusiness";
117
+ if (!isFoodVenue && PICKUP_POINT.test(name)) return "LocalBusiness";
118
+ return businessType;
119
+ }
120
+ var IN_STOCK = "https://schema.org/InStock";
121
+ var WEIGHT_UNIT_CODES = {
122
+ [UnitType.Piece]: "GRM",
123
+ [UnitType.Gram]: "GRM",
124
+ [UnitType.Kilogram]: "KGM"
125
+ };
126
+ function buildWeight(product) {
127
+ const weight = getProductWeight(product);
128
+ const unitCode = WEIGHT_UNIT_CODES[product.unit_type];
129
+ if (!weight || weight < 0 || !unitCode) return null;
130
+ return { "@type": "QuantitativeValue", value: weight, unitCode };
131
+ }
132
+ function buildProductOffer(product, currency, stockId) {
133
+ const requiredModifiersCost = getRequiredModifiersMinCost(product);
134
+ const priced = (product.variants ?? []).map((variant) => ({
135
+ variant,
136
+ price: resolveVariantPrice(variant, stockId).price + requiredModifiersCost
137
+ })).filter(({ price }) => price > 0);
138
+ const [first] = priced;
139
+ if (!first) return null;
140
+ if (priced.length > 1) {
141
+ const prices = priced.map(({ price }) => price);
142
+ return {
143
+ "@type": "AggregateOffer",
144
+ lowPrice: minorToMajorString(Math.min(...prices), currency),
145
+ highPrice: minorToMajorString(Math.max(...prices), currency),
146
+ offerCount: priced.length,
64
147
  priceCurrency: currency,
65
- availability: isProductInStock(variants) ? "https://schema.org/InStock" : "https://schema.org/OutOfStock",
66
- ...firstVariant.sku ? { sku: firstVariant.sku } : {}
148
+ availability: IN_STOCK
67
149
  };
68
150
  }
69
- const images = (product.images ?? []).map(resolveMediaUrl).filter((url) => !!url);
151
+ const sku = first.variant.sku;
152
+ return {
153
+ "@type": "Offer",
154
+ price: minorToMajorString(first.price, currency),
155
+ priceCurrency: currency,
156
+ availability: IN_STOCK,
157
+ ...sku ? { sku } : {}
158
+ };
159
+ }
160
+ function buildProductSchema(product, currency, options = {}) {
70
161
  const schema = {
71
162
  "@context": "https://schema.org",
72
- "@type": "Product",
73
- name: product.name
163
+ "@type": "Product"
74
164
  };
75
- if (product.description) schema.description = product.description;
165
+ if (options.url) {
166
+ schema["@id"] = productSchemaId(options.url);
167
+ schema.url = options.url;
168
+ }
169
+ schema.name = normalizeSchemaText(product.name);
170
+ const description = htmlToPlainText(product.description);
171
+ if (description) schema.description = description;
172
+ const images = (product.images ?? []).map(resolveMediaUrl).filter((url) => !!url);
76
173
  if (images.length) schema.image = images;
77
- if (offerBlock) schema.offers = offerBlock;
174
+ const variants = product.variants ?? [];
175
+ const sku = variants.length === 1 ? variants[0]?.sku : null;
176
+ if (sku) schema.sku = sku;
177
+ const category = normalizeSchemaText(product.categories?.[0]?.name);
178
+ if (category) schema.category = category;
179
+ const weight = buildWeight(product);
180
+ if (weight) schema.weight = weight;
181
+ const offer = buildProductOffer(product, currency, options.stockId);
182
+ if (offer) {
183
+ schema.offers = {
184
+ ...offer,
185
+ ...options.url ? { url: options.url } : {},
186
+ ...options.seller ? { seller: options.seller } : {}
187
+ };
188
+ }
78
189
  return [schema];
79
190
  }
80
191
 
81
- // src/seo/listingSchema.ts
82
- function buildListingSchemas(name, products, breadcrumbs, origin) {
83
- const schemas = [];
84
- if (breadcrumbs.length) {
85
- schemas.push({
192
+ // src/seo/breadcrumbSchema.ts
193
+ function toAbsoluteUrl(path, origin) {
194
+ return /^https?:\/\//i.test(path) ? path : `${origin}${path}`;
195
+ }
196
+ function buildBreadcrumbListSchema(items, origin) {
197
+ const crumbs = items.map((item) => ({ name: normalizeSchemaText(item.label), to: item.to })).filter((crumb) => crumb.name);
198
+ if (!crumbs.length) return [];
199
+ return [
200
+ {
86
201
  "@context": "https://schema.org",
87
202
  "@type": "BreadcrumbList",
88
- itemListElement: breadcrumbs.map((crumb, index) => ({
203
+ itemListElement: crumbs.map((crumb, index) => ({
89
204
  "@type": "ListItem",
90
205
  position: index + 1,
91
- name: crumb.label,
92
- ...crumb.to ? { item: `${origin}${crumb.to}` } : {}
206
+ name: crumb.name,
207
+ ...crumb.to ? { item: toAbsoluteUrl(crumb.to, origin) } : {}
93
208
  }))
94
- });
95
- }
209
+ }
210
+ ];
211
+ }
212
+
213
+ // src/seo/listingSchema.ts
214
+ function buildListingSchemas(name, products, breadcrumbs, origin) {
215
+ const schemas = buildBreadcrumbListSchema(breadcrumbs, origin);
96
216
  const items = products.slice(0, 10);
97
217
  if (items.length) {
98
218
  schemas.push({
@@ -108,7 +228,7 @@ function buildListingSchemas(name, products, breadcrumbs, origin) {
108
228
  "@type": "ListItem",
109
229
  position: index + 1,
110
230
  url,
111
- name: product.name
231
+ name: normalizeSchemaText(product.name)
112
232
  };
113
233
  if (image) item.image = image;
114
234
  return item;
@@ -168,72 +288,186 @@ function buildBlogPostSchema(article, storeName, origin) {
168
288
  }
169
289
  return [schema];
170
290
  }
171
- var SCHEMA_DAY = {
172
- monday: "Monday",
173
- tuesday: "Tuesday",
174
- wednesday: "Wednesday",
175
- thursday: "Thursday",
176
- friday: "Friday",
177
- saturday: "Saturday",
178
- sunday: "Sunday"
179
- };
180
- function buildOpeningHours(schedule) {
181
- if (!schedule) return [];
182
- const result = [];
183
- for (const key of Object.keys(SCHEMA_DAY)) {
184
- const day = schedule.days[key];
185
- const match = day?.hours?.match(/(\d{1,2}:\d{2}).*?(\d{1,2}:\d{2})/);
186
- if (!match) continue;
187
- result.push({
188
- "@type": "OpeningHoursSpecification",
189
- dayOfWeek: SCHEMA_DAY[key],
190
- opens: match[1],
191
- closes: match[2]
192
- });
291
+
292
+ // src/seo/openingHours.ts
293
+ var SCHEMA_DAYS = [
294
+ ["monday", "Monday"],
295
+ ["tuesday", "Tuesday"],
296
+ ["wednesday", "Wednesday"],
297
+ ["thursday", "Thursday"],
298
+ ["friday", "Friday"],
299
+ ["saturday", "Saturday"],
300
+ ["sunday", "Sunday"]
301
+ ];
302
+ var ROUND_THE_CLOCK = /^\s*0?0:00\s*[-–—]\s*0?0:00\s*$|круглосуточно|24\s*\/\s*7|24\s*час/iu;
303
+ var SHIFT = /(\d{1,2}):(\d{2})\D+?(\d{1,2}):(\d{2})/g;
304
+ function formatTime(hours, minutes) {
305
+ const hour = Number(hours);
306
+ const minute = Number(minutes);
307
+ if (hour > 24 || minute > 59 || hour === 24 && minute > 0) return null;
308
+ if (hour === 24) return "23:59";
309
+ return `${String(hour).padStart(2, "0")}:${minutes}`;
310
+ }
311
+ function parseShifts(hours) {
312
+ if (ROUND_THE_CLOCK.test(hours)) return [["00:00", "23:59"]];
313
+ const shifts = [];
314
+ for (const [, openHour, openMinute, closeHour, closeMinute] of hours.matchAll(SHIFT)) {
315
+ const opens = formatTime(openHour ?? "", openMinute ?? "");
316
+ const closes = formatTime(closeHour ?? "", closeMinute ?? "");
317
+ if (opens && closes) shifts.push([opens, closes]);
193
318
  }
194
- return result;
195
- }
196
- function buildOrganizationSchema(store, origin) {
197
- const logoUrl = store.square_logo?.medium?.url || store.square_logo?.large?.url || store.logo?.medium?.url || store.logo?.large?.url || null;
198
- const phones = (store.phones ?? []).map((p) => p.number).filter((n) => !!n);
199
- const email = store.links?.find((c) => c.type === ContactType.Email)?.value ?? null;
200
- const socialLinks = getSocialLinks(store.links ?? []).map((l) => l.url);
201
- const city = (store.cities ?? []).find((c) => c.is_default) ?? store.cities?.[0] ?? null;
202
- const stock = city?.stocks?.find((st) => st.address) ?? city?.stocks?.[0] ?? null;
203
- const streetAddress = stock?.address ?? null;
204
- const geo = stock?.coordinates ?? city?.coordinates ?? null;
205
- const openingHours = buildOpeningHours(stock?.schedule ?? city?.schedule);
206
- const isLocalBusiness = Boolean(streetAddress || geo || openingHours.length);
207
- const schema = {
208
- "@context": "https://schema.org",
209
- "@type": isLocalBusiness ? "LocalBusiness" : "Organization",
210
- name: store.name,
211
- url: origin
319
+ return shifts;
320
+ }
321
+ function buildOpeningHoursSpecification(schedule) {
322
+ if (!schedule?.days) return [];
323
+ const groups = [];
324
+ for (const [key, dayOfWeek] of SCHEMA_DAYS) {
325
+ const hours = schedule.days[key]?.hours;
326
+ if (!hours) continue;
327
+ for (const [opens, closes] of parseShifts(hours)) {
328
+ const group = groups.find((item) => item.opens === opens && item.closes === closes);
329
+ if (group) group.days.push(dayOfWeek);
330
+ else groups.push({ opens, closes, days: [dayOfWeek] });
331
+ }
332
+ }
333
+ return groups.map(({ opens, closes, days }) => ({
334
+ "@type": "OpeningHoursSpecification",
335
+ dayOfWeek: days,
336
+ opens,
337
+ closes
338
+ }));
339
+ }
340
+
341
+ // src/seo/locationSchema.ts
342
+ function escapeRegExp(value) {
343
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
344
+ }
345
+ function normalizeStreetAddress(address, cityName) {
346
+ const street = normalizeSchemaText(address);
347
+ if (!street || !cityName) return street;
348
+ const city = `(?:\u0433\\.?|\u0433\u043E\u0440\u043E\u0434)?\\s*${escapeRegExp(cityName)}`;
349
+ const cityPrefix = new RegExp(`^${city}\\s*,\\s*`, "iu");
350
+ const citySuffix = new RegExp(`\\s*,\\s*${city}$`, "iu");
351
+ return street.replace(cityPrefix, "").replace(citySuffix, "") || street;
352
+ }
353
+ function hasCoordinates(coordinates) {
354
+ if (!coordinates) return false;
355
+ const { latitude, longitude } = coordinates;
356
+ if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) return false;
357
+ return latitude !== 0 || longitude !== 0;
358
+ }
359
+ function buildLocationNode(stock, city, store, origin, options) {
360
+ const cityName = normalizeSchemaText(city.name);
361
+ const streetAddress = normalizeStreetAddress(stock.address, cityName);
362
+ if (!streetAddress) return null;
363
+ const node = {
364
+ "@type": resolveLocationType(stock, options.businessType),
365
+ "@id": locationSchemaId(origin, stock.id),
366
+ name: normalizeSchemaText(stock.name) || normalizeSchemaText(store.name)
367
+ };
368
+ const description = htmlToPlainText(stock.description);
369
+ if (description) node.description = description;
370
+ const url = options.locationUrl?.(stock);
371
+ if (url) node.url = url;
372
+ const image = resolveStoreLogoUrl(store);
373
+ if (image) node.image = image;
374
+ const telephone = stock.phones?.[0]?.number || city.phones?.[0]?.number || store.phones?.[0]?.number;
375
+ if (telephone) node.telephone = telephone;
376
+ node.address = {
377
+ "@type": "PostalAddress",
378
+ streetAddress,
379
+ ...cityName ? { addressLocality: cityName } : {},
380
+ addressCountry: store.settings?.country || "RU"
212
381
  };
213
- if (logoUrl) {
214
- schema.logo = logoUrl;
215
- schema.image = logoUrl;
382
+ if (hasCoordinates(stock.coordinates)) {
383
+ const { latitude, longitude } = stock.coordinates;
384
+ node.geo = { "@type": "GeoCoordinates", latitude, longitude };
385
+ node.hasMap = `https://yandex.ru/maps/?pt=${longitude},${latitude}&z=17&l=map`;
216
386
  }
217
- if (phones.length) schema.telephone = phones.length === 1 ? phones[0] : phones;
218
- if (email) schema.email = email;
219
- if (socialLinks.length) schema.sameAs = socialLinks;
220
- if (streetAddress || city?.name) {
221
- schema.address = {
222
- "@type": "PostalAddress",
223
- ...streetAddress ? { streetAddress } : {},
224
- ...city?.name ? { addressLocality: city.name } : {},
225
- addressCountry: "RU"
226
- };
387
+ const openingHours = buildOpeningHoursSpecification(stock.schedule);
388
+ if (openingHours.length) node.openingHoursSpecification = openingHours;
389
+ node.parentOrganization = { "@id": organizationSchemaId(origin) };
390
+ return node;
391
+ }
392
+ function buildLocationNodes(store, origin, options = {}) {
393
+ const seen = /* @__PURE__ */ new Set();
394
+ const nodes = [];
395
+ for (const city of store.cities ?? []) {
396
+ for (const stock of city.stocks ?? []) {
397
+ if (seen.has(stock.id)) continue;
398
+ const node = buildLocationNode(stock, city, store, origin, options);
399
+ if (!node) continue;
400
+ seen.add(stock.id);
401
+ nodes.push(node);
402
+ }
227
403
  }
228
- if (geo) {
229
- schema.geo = {
230
- "@type": "GeoCoordinates",
231
- latitude: geo.latitude,
232
- longitude: geo.longitude
404
+ return nodes;
405
+ }
406
+
407
+ // src/seo/organizationSchema.ts
408
+ function unique(values) {
409
+ return [...new Set(values.filter(Boolean))];
410
+ }
411
+ function buildOrganizationReference(store, origin) {
412
+ return {
413
+ "@type": "Organization",
414
+ "@id": organizationSchemaId(origin),
415
+ name: normalizeSchemaText(store.name),
416
+ url: `${origin}/`
417
+ };
418
+ }
419
+ function buildOrganizationNode(store, origin) {
420
+ const node = buildOrganizationReference(store, origin);
421
+ const logo = resolveStoreLogoUrl(store);
422
+ if (logo) node.logo = logo;
423
+ const phones = unique((store.phones ?? []).map((phone) => phone.number));
424
+ if (phones.length) node.telephone = phones.length === 1 ? phones[0] : phones;
425
+ const email = getEmailLink(store.links ?? []);
426
+ if (email) node.email = email;
427
+ const sameAs = unique(getSocialLinks(store.links ?? []).map((link) => link.url));
428
+ if (sameAs.length) node.sameAs = sameAs;
429
+ const cities = store.cities ?? [];
430
+ const cityName = cities.length === 1 ? normalizeSchemaText(cities[0]?.name) : "";
431
+ if (cityName) {
432
+ node.address = {
433
+ "@type": "PostalAddress",
434
+ addressLocality: cityName,
435
+ addressCountry: store.settings?.country || "RU"
233
436
  };
234
437
  }
235
- if (openingHours.length) schema.openingHoursSpecification = openingHours;
236
- return [schema];
438
+ return node;
439
+ }
440
+ function buildWebSiteNode(store, origin, inLanguage) {
441
+ return {
442
+ "@type": "WebSite",
443
+ "@id": webSiteSchemaId(origin),
444
+ url: `${origin}/`,
445
+ name: normalizeSchemaText(store.name),
446
+ ...inLanguage ? { inLanguage } : {},
447
+ publisher: { "@id": organizationSchemaId(origin) }
448
+ };
449
+ }
450
+ function buildOrganizationSchema(store, origin, options = {}) {
451
+ return [
452
+ {
453
+ "@context": "https://schema.org",
454
+ "@graph": [
455
+ buildOrganizationNode(store, origin),
456
+ buildWebSiteNode(store, origin, options.inLanguage),
457
+ ...buildLocationNodes(store, origin, options)
458
+ ]
459
+ }
460
+ ];
461
+ }
462
+ function buildLocationsSchema(store, origin, options = {}) {
463
+ const locations = buildLocationNodes(store, origin, options);
464
+ if (!locations.length) return [];
465
+ return [
466
+ {
467
+ "@context": "https://schema.org",
468
+ "@graph": [buildOrganizationNode(store, origin), ...locations]
469
+ }
470
+ ];
237
471
  }
238
472
 
239
473
  // src/seo/ogTags.ts
@@ -282,6 +516,6 @@ function buildEntitySeoMeta(seo) {
282
516
  return tags;
283
517
  }
284
518
 
285
- export { buildBlogPostSchema, buildCategorySchemas, buildCollectionSchemas, buildEntitySeoMeta, buildOfferArticleSchema, buildOgTags, buildOrganizationSchema, buildProductSchema, mapSeoMetaTags, prepareOgDescription, resolveMediaUrl, resolveSiteOrigin, resolveStoreLogoUrl, stripHtml };
519
+ export { BUSINESS_TYPES, buildBlogPostSchema, buildBreadcrumbListSchema, buildCategorySchemas, buildCollectionSchemas, buildEntitySeoMeta, buildLocationsSchema, buildOfferArticleSchema, buildOgTags, buildOrganizationReference, buildOrganizationSchema, buildProductOffer, buildProductSchema, htmlToPlainText, isBusinessType, locationAnchorId, locationSchemaId, mapSeoMetaTags, normalizeSchemaText, organizationSchemaId, prepareOgDescription, productSchemaId, resolveMediaUrl, resolveSiteOrigin, resolveStoreLogoUrl, stripHtml, webSiteSchemaId };
286
520
  //# sourceMappingURL=index.js.map
287
521
  //# sourceMappingURL=index.js.map