punchout-simulator 0.6.1 → 0.7.1

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/README.md CHANGED
@@ -167,6 +167,12 @@ SetupRequest → catalog → cart → OrderRequest → OrderResponse. The **Sess
167
167
  - **inspect** — view a previously ordered item read-only (`operation="inspect"`),
168
168
  carrying that item (or the whole source cart) as `ItemOut`.
169
169
 
170
+ The built-in **mock supplier honours these on the receiving side too**: an
171
+ `edit` pre-fills the catalog quantities from the carried `ItemOut` (items it
172
+ doesn't list appear as extra "from cart" rows), and an `inspect` shows the
173
+ item(s) read-only and returns them unchanged — so the full round-trip is
174
+ exercisable end-to-end against the built-in mock.
175
+
170
176
  Connections/Buyers/Suppliers/Products/Profiles remain under **Configure** — you set
171
177
  them up there, then run them from **Sessions**.
172
178
 
@@ -94,13 +94,34 @@ var PROFILE_PRESETS = [
94
94
  shipToInSetup: false,
95
95
  contactInSetup: false
96
96
  },
97
+ // Jaggaer (formerly SciQuest) is observed sending TWO different UserAgent
98
+ // strings in the wild — the modern "JAGGAER" and the legacy "SciQuest" — so we
99
+ // ship both presets. They are identical except for name + userAgent, letting
100
+ // you faithfully reproduce whichever tenant you're testing against. DTD 1.2.011
101
+ // is confirmed on real OrderRequests for both; setup requests are assumed to
102
+ // use the same version (set as `default`, easily overridden per document type).
97
103
  {
98
104
  id: "jaggaer",
99
- name: "JAGGAER",
105
+ name: "Jaggaer",
100
106
  platform: "Jaggaer",
101
107
  builtin: true,
102
- dtdVersions: { default: "1.2.021" },
103
- userAgent: "JAGGAER Procurement",
108
+ dtdVersions: { default: "1.2.011" },
109
+ userAgent: "JAGGAER",
110
+ setupOperation: "create",
111
+ attachmentEncoding: "binary",
112
+ cartReturnTransport: "cxml-urlencoded",
113
+ extrinsics: [],
114
+ addressMode: "full",
115
+ shipToInSetup: false,
116
+ contactInSetup: false
117
+ },
118
+ {
119
+ id: "jaggaer-sciquest",
120
+ name: "Jaggaer (SciQuest)",
121
+ platform: "Jaggaer",
122
+ builtin: true,
123
+ dtdVersions: { default: "1.2.011" },
124
+ userAgent: "SciQuest",
104
125
  setupOperation: "create",
105
126
  attachmentEncoding: "binary",
106
127
  cartReturnTransport: "cxml-urlencoded",
@@ -553,6 +574,12 @@ function migrateProfiles(data) {
553
574
  p.shipToInSetup ??= preset?.shipToInSetup ?? false;
554
575
  p.contactInSetup ??= preset?.contactInSetup ?? false;
555
576
  }
577
+ const jaggaer = data.profiles.find((p) => p.id === "jaggaer" && p.builtin);
578
+ if (jaggaer && jaggaer.name === "JAGGAER" && jaggaer.userAgent === "JAGGAER Procurement") {
579
+ jaggaer.name = "Jaggaer";
580
+ jaggaer.userAgent = "JAGGAER";
581
+ if (jaggaer.dtdVersions?.default === "1.2.021") jaggaer.dtdVersions.default = "1.2.011";
582
+ }
556
583
  }
557
584
  function migrateClassifications(data) {
558
585
  for (const list of data.productLists) {
@@ -1620,31 +1647,39 @@ function collectCidReferences(doc) {
1620
1647
  });
1621
1648
  return refs;
1622
1649
  }
1650
+ function itemFromNode(it) {
1651
+ const detail = it?.ItemDetail;
1652
+ const up = money(detail?.UnitPrice);
1653
+ const classifications = asArray(detail?.Classification).filter((c) => c != null).map((c) => ({ domain: attr(c, "domain") ?? "", value: text(c) ?? "" }));
1654
+ const classFirst = classifications[0];
1655
+ return {
1656
+ quantity: Number(attr(it, "quantity") ?? "1") || 1,
1657
+ supplierPartId: text(it?.ItemID?.SupplierPartID),
1658
+ supplierPartAuxiliaryId: text(it?.ItemID?.SupplierPartAuxiliaryID),
1659
+ description: text(detail?.Description),
1660
+ uom: text(detail?.UnitOfMeasure),
1661
+ unitPriceAmount: up.amount,
1662
+ currency: up.currency,
1663
+ classifications: classifications.length > 0 ? classifications : void 0,
1664
+ classificationDomain: classFirst?.domain,
1665
+ classification: classFirst?.value,
1666
+ manufacturerPartId: text(detail?.ManufacturerPartID),
1667
+ manufacturerName: text(detail?.ManufacturerName)
1668
+ };
1669
+ }
1670
+ function parseSetupItems(doc) {
1671
+ const sr = root(doc)?.Request?.PunchOutSetupRequest;
1672
+ return {
1673
+ operation: attr(sr, "operation") ?? "create",
1674
+ items: asArray(sr?.ItemOut).map(itemFromNode)
1675
+ };
1676
+ }
1623
1677
  function parseCart(doc) {
1624
1678
  const pom = root(doc)?.Message?.PunchOutOrderMessage;
1625
1679
  const sessionId = text(pom?.BuyerCookie) ?? "";
1626
1680
  const headerNode = pom?.PunchOutOrderMessageHeader;
1627
1681
  const total = money(headerNode?.Total);
1628
- const items = asArray(pom?.ItemIn).map((it) => {
1629
- const detail = it?.ItemDetail;
1630
- const up = money(detail?.UnitPrice);
1631
- const classifications = asArray(detail?.Classification).filter((c) => c != null).map((c) => ({ domain: attr(c, "domain") ?? "", value: text(c) ?? "" }));
1632
- const classFirst = classifications[0];
1633
- return {
1634
- quantity: Number(attr(it, "quantity") ?? "1") || 1,
1635
- supplierPartId: text(it?.ItemID?.SupplierPartID),
1636
- supplierPartAuxiliaryId: text(it?.ItemID?.SupplierPartAuxiliaryID),
1637
- description: text(detail?.Description),
1638
- uom: text(detail?.UnitOfMeasure),
1639
- unitPriceAmount: up.amount,
1640
- currency: up.currency,
1641
- classifications: classifications.length > 0 ? classifications : void 0,
1642
- classificationDomain: classFirst?.domain,
1643
- classification: classFirst?.value,
1644
- manufacturerPartId: text(detail?.ManufacturerPartID),
1645
- manufacturerName: text(detail?.ManufacturerName)
1646
- };
1647
- });
1682
+ const items = asArray(pom?.ItemIn).map(itemFromNode);
1648
1683
  return {
1649
1684
  sessionId,
1650
1685
  operationAllowed: attr(headerNode, "operationAllowed"),
@@ -2522,6 +2557,20 @@ var catalogOf = (s) => {
2522
2557
  const items = catalogForSupplier(s);
2523
2558
  return items.length > 0 ? items : DEMO_CATALOG;
2524
2559
  };
2560
+ function setupContextFor(cookie) {
2561
+ if (!cookie) return { operation: "create", items: [] };
2562
+ const records = readSession(cookie);
2563
+ for (let i = records.length - 1; i >= 0; i--) {
2564
+ const r = records[i];
2565
+ if (r.direction === "in" && r.docType === "SetupRequest") {
2566
+ return parseSetupItems(parseXml(r.body));
2567
+ }
2568
+ }
2569
+ return { operation: "create", items: [] };
2570
+ }
2571
+ function sameProduct(a, b) {
2572
+ return !!a.supplierPartId && a.supplierPartId === b.supplierPartId && (a.supplierPartAuxiliaryId ?? "") === (b.supplierPartAuxiliaryId ?? "");
2573
+ }
2525
2574
  function safeHttpUrl(u) {
2526
2575
  if (!u) return "";
2527
2576
  try {
@@ -2590,26 +2639,46 @@ simRoute.post("/:id/punchout", async (c) => {
2590
2639
  c.header("Content-Type", "text/xml; charset=UTF-8");
2591
2640
  return c.body(respXml);
2592
2641
  });
2593
- simRoute.get("/:id/catalog", (c) => {
2594
- const supplier = getSupplier(c.req.param("id"));
2595
- if (!supplier) return c.text("supplier not found", 404);
2596
- const cookie = c.req.query("cookie") ?? "";
2597
- const formpost = safeHttpUrl(c.req.query("formpost") ?? "");
2598
- const bd = c.req.query("bd") ?? "";
2599
- const bi = c.req.query("bi") ?? "";
2600
- const items = catalogOf(supplier);
2601
- const rows = items.map((it, i) => {
2602
- const partId = escapeXml(it.supplierPartId) + (it.supplierPartAuxiliaryId ? ` / ${escapeXml(it.supplierPartAuxiliaryId)}` : "");
2603
- const cls = (it.classifications ?? []).map((c2) => `${escapeXml(c2.domain)} ${escapeXml(c2.value)}`).join(" \xB7 ");
2604
- return `<tr>
2605
- <td><strong>${escapeXml(it.description)}</strong><br><small>${partId} \xB7 ${escapeXml(it.uom)}${cls ? ` \xB7 ${cls}` : ""}</small></td>
2606
- <td class="price">${escapeXml(it.currency)} ${it.unitPrice.toFixed(2)}</td>
2607
- <td><input type="number" name="q_${i}" value="0" min="0" step="${it.allowFractional ? "any" : "1"}" inputmode="${it.allowFractional ? "decimal" : "numeric"}"></td>
2642
+ var catalogView = (it) => ({
2643
+ description: it.description,
2644
+ supplierPartId: it.supplierPartId,
2645
+ supplierPartAuxiliaryId: it.supplierPartAuxiliaryId,
2646
+ uom: it.uom,
2647
+ currency: it.currency,
2648
+ price: it.unitPrice,
2649
+ classifications: it.classifications
2650
+ });
2651
+ var cartView = (it) => ({
2652
+ description: it.description,
2653
+ supplierPartId: it.supplierPartId,
2654
+ supplierPartAuxiliaryId: it.supplierPartAuxiliaryId,
2655
+ uom: it.uom,
2656
+ currency: it.currency,
2657
+ price: it.unitPriceAmount,
2658
+ classifications: it.classifications
2659
+ });
2660
+ function rowLabelCells(v) {
2661
+ const partId = escapeXml(v.supplierPartId ?? "") + (v.supplierPartAuxiliaryId ? ` / ${escapeXml(v.supplierPartAuxiliaryId)}` : "");
2662
+ const cls = (v.classifications ?? []).map((c) => `${escapeXml(c.domain)} ${escapeXml(c.value)}`).join(" \xB7 ");
2663
+ return `<td><strong>${escapeXml(v.description ?? "")}</strong><br><small>${partId} \xB7 ${escapeXml(v.uom ?? "")}${cls ? ` \xB7 ${cls}` : ""}</small></td>
2664
+ <td class="price">${escapeXml(v.currency ?? "")} ${(v.price ?? 0).toFixed(2)}</td>`;
2665
+ }
2666
+ function qtyRow(v, name, value, fractional, tag) {
2667
+ return `<tr>
2668
+ ${rowLabelCells(v)}
2669
+ <td><input type="number" name="${name}" value="${escapeXml(value)}" min="0" step="${fractional ? "any" : "1"}" inputmode="${fractional ? "decimal" : "numeric"}">${tag ? ` <span class="tag">${tag}</span>` : ""}</td>
2608
2670
  </tr>`;
2609
- }).join("\n");
2610
- return c.html(`<!doctype html><html lang="en"><head><meta charset="utf-8">
2671
+ }
2672
+ function readonlyRow(v, qty) {
2673
+ return `<tr>
2674
+ ${rowLabelCells(v)}
2675
+ <td class="ro">${escapeXml(qty)}</td>
2676
+ </tr>`;
2677
+ }
2678
+ function catalogPage(o) {
2679
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8">
2611
2680
  <meta name="viewport" content="width=device-width, initial-scale=1">
2612
- <title>${escapeXml(supplier.name)} \u2014 mock catalog</title>
2681
+ <title>${escapeXml(o.supplier.name)} \u2014 mock catalog</title>
2613
2682
  <script>
2614
2683
  // Match the main app's theme. The app appends ?theme= to the catalog link
2615
2684
  // (works even when the SPA is on a different origin, e.g. the Vite dev server);
@@ -2627,31 +2696,61 @@ simRoute.get("/:id/catalog", (c) => {
2627
2696
  })();
2628
2697
  </script>
2629
2698
  <style>
2630
- :root{--bg:#0f172a;--text:#e2e8f0;--muted:#94a3b8;--panel:#1e293b;--th:#0b1220;--border:#334155;--field:#0b1220;--price:#fbbf24;--accent:#6366f1;--accent-hover:#4f46e5}
2631
- :root[data-theme="light"]{--bg:#f5f7fb;--text:#1e293b;--muted:#4b5a73;--panel:#ffffff;--th:#eef1f7;--border:#d4dae8;--field:#ffffff;--price:#b45309;--accent:#6366f1;--accent-hover:#4f46e5}
2699
+ :root{--bg:#0f172a;--text:#e2e8f0;--muted:#94a3b8;--panel:#1e293b;--th:#0b1220;--border:#334155;--field:#0b1220;--price:#fbbf24;--accent:#6366f1;--accent-hover:#4f46e5;--banner:#1e293b}
2700
+ :root[data-theme="light"]{--bg:#f5f7fb;--text:#1e293b;--muted:#4b5a73;--panel:#ffffff;--th:#eef1f7;--border:#d4dae8;--field:#ffffff;--price:#b45309;--accent:#6366f1;--accent-hover:#4f46e5;--banner:#eef1f7}
2632
2701
  body{font-family:system-ui,sans-serif;background:var(--bg);color:var(--text);margin:0;padding:2rem}
2633
2702
  .wrap{max-width:720px;margin:0 auto}
2634
2703
  h1{font-size:1.4rem}.sub{color:var(--muted);margin-bottom:1.5rem}
2704
+ .banner{background:var(--banner);border:1px solid var(--border);border-left:4px solid var(--accent);border-radius:8px;padding:.7rem 1rem;margin-bottom:1.25rem;font-size:.95rem}
2705
+ .banner.inspect{border-left-color:var(--price)}
2635
2706
  table{width:100%;border-collapse:collapse;background:var(--panel);border-radius:12px;overflow:hidden}
2636
2707
  th,td{padding:.75rem 1rem;text-align:left;border-bottom:1px solid var(--border)}
2637
2708
  th{background:var(--th);font-size:.8rem;text-transform:uppercase;letter-spacing:.05em;color:var(--muted)}
2638
2709
  .price{white-space:nowrap;color:var(--price)}
2710
+ .ro{color:var(--muted)}
2711
+ .tag{font-size:.7rem;color:var(--muted);text-transform:uppercase;letter-spacing:.04em;margin-left:.4rem}
2639
2712
  input[type=number]{width:5rem;background:var(--field);border:1px solid var(--border);color:var(--text);border-radius:6px;padding:.35rem .5rem}
2640
2713
  button{margin-top:1.5rem;background:var(--accent);color:#fff;border:0;border-radius:8px;padding:.7rem 1.4rem;font-size:1rem;cursor:pointer}
2641
2714
  button:hover{background:var(--accent-hover)}
2642
2715
  </style></head><body><div class="wrap">
2643
- <h1>${escapeXml(supplier.name)} <small>(virtual supplier)</small></h1>
2716
+ <h1>${escapeXml(o.supplier.name)} <small>(virtual supplier)</small></h1>
2644
2717
  <div class="sub">Mock catalog served by punchout-simulator. Set quantities and return the cart.</div>
2645
- <form method="post" action="${getPublicUrl()}/sim/${supplier.id}/checkout">
2646
- <input type="hidden" name="cookie" value="${escapeXml(cookie)}">
2647
- <input type="hidden" name="formpost" value="${escapeXml(formpost)}">
2648
- <input type="hidden" name="bd" value="${escapeXml(bd)}">
2649
- <input type="hidden" name="bi" value="${escapeXml(bi)}">
2718
+ ${o.banner}
2719
+ <form method="post" action="${getPublicUrl()}/sim/${o.supplier.id}/checkout">
2720
+ <input type="hidden" name="cookie" value="${escapeXml(o.cookie)}">
2721
+ <input type="hidden" name="formpost" value="${escapeXml(o.formpost)}">
2722
+ <input type="hidden" name="bd" value="${escapeXml(o.bd)}">
2723
+ <input type="hidden" name="bi" value="${escapeXml(o.bi)}">
2650
2724
  <table><thead><tr><th>Item</th><th>Price</th><th>Qty</th></tr></thead>
2651
- <tbody>${rows}</tbody></table>
2652
- <button type="submit">Return cart to buyer \u2192</button>
2725
+ <tbody>${o.rows}</tbody></table>
2726
+ <button type="submit">${escapeXml(o.submitLabel)}</button>
2653
2727
  </form>
2654
- </div></body></html>`);
2728
+ </div></body></html>`;
2729
+ }
2730
+ simRoute.get("/:id/catalog", (c) => {
2731
+ const supplier = getSupplier(c.req.param("id"));
2732
+ if (!supplier) return c.text("supplier not found", 404);
2733
+ const cookie = c.req.query("cookie") ?? "";
2734
+ const formpost = safeHttpUrl(c.req.query("formpost") ?? "");
2735
+ const bd = c.req.query("bd") ?? "";
2736
+ const bi = c.req.query("bi") ?? "";
2737
+ const items = catalogOf(supplier);
2738
+ const ctx = setupContextFor(cookie);
2739
+ const page = (banner2, rows2, submitLabel) => c.html(catalogPage({ supplier, banner: banner2, rows: rows2, submitLabel, cookie, formpost, bd, bi }));
2740
+ if (ctx.operation === "inspect" && ctx.items.length > 0) {
2741
+ const rows2 = ctx.items.map((it) => readonlyRow(cartView(it), it.quantity)).join("\n");
2742
+ const banner2 = `<div class="banner inspect">Inspect \u2014 ${ctx.items.length} item(s), read-only. Returning the cart unchanged to the buyer.</div>`;
2743
+ return page(banner2, rows2, "Return to buyer \u2192");
2744
+ }
2745
+ const isEdit = ctx.operation === "edit";
2746
+ const prefill = (it) => isEdit ? ctx.items.find((p) => sameProduct(p, it))?.quantity ?? 0 : 0;
2747
+ const catalogRows = items.map((it, i) => qtyRow(catalogView(it), `q_${i}`, prefill(it), !!it.allowFractional)).join("\n");
2748
+ const extras = isEdit ? ctx.items.filter((p) => !items.some((it) => sameProduct(p, it))) : [];
2749
+ const extraRows = extras.map((p, j) => qtyRow(cartView(p), `qx_${j}`, p.quantity, true, "from cart")).join("\n");
2750
+ const banner = isEdit ? `<div class="banner edit">Edit \u2014 ${ctx.items.length} item(s) pre-loaded from the buyer's cart. Adjust quantities and return.</div>` : "";
2751
+ const rows = extraRows ? `${catalogRows}
2752
+ ${extraRows}` : catalogRows;
2753
+ return page(banner, rows, "Return cart to buyer \u2192");
2655
2754
  });
2656
2755
  simRoute.post("/:id/checkout", async (c) => {
2657
2756
  const supplier = getSupplier(c.req.param("id"));
@@ -2664,29 +2763,41 @@ simRoute.post("/:id/checkout", async (c) => {
2664
2763
  const formpost = safeHttpUrl(String(form.formpost ?? ""));
2665
2764
  const buyerCred = { domain: String(form.bd ?? ""), identity: String(form.bi ?? "") };
2666
2765
  const catalog = catalogOf(supplier);
2667
- const items = [];
2668
- catalog.forEach((it, i) => {
2669
- let qty = Number(form[`q_${i}`] ?? 0);
2670
- if (!it.allowFractional) qty = Math.floor(qty);
2671
- if (qty > 0) {
2672
- items.push({
2673
- quantity: qty,
2674
- supplierPartId: it.supplierPartId,
2675
- supplierPartAuxiliaryId: it.supplierPartAuxiliaryId,
2676
- description: it.description,
2677
- uom: it.uom,
2678
- unitPriceAmount: it.unitPrice,
2679
- currency: it.currency,
2680
- classifications: it.classifications,
2681
- // Keep the legacy single fields populated from the first classification
2682
- // for back-compat display (CartView) and any single-domain consumer.
2683
- classificationDomain: it.classifications[0]?.domain,
2684
- classification: it.classifications[0]?.value,
2685
- manufacturerPartId: it.manufacturerPartId,
2686
- manufacturerName: it.manufacturerName
2766
+ const ctx = setupContextFor(cookie);
2767
+ let items = [];
2768
+ if (ctx.operation === "inspect" && ctx.items.length > 0) {
2769
+ items = ctx.items;
2770
+ } else {
2771
+ catalog.forEach((it, i) => {
2772
+ let qty = Number(form[`q_${i}`] ?? 0);
2773
+ if (!it.allowFractional) qty = Math.floor(qty);
2774
+ if (qty > 0) {
2775
+ items.push({
2776
+ quantity: qty,
2777
+ supplierPartId: it.supplierPartId,
2778
+ supplierPartAuxiliaryId: it.supplierPartAuxiliaryId,
2779
+ description: it.description,
2780
+ uom: it.uom,
2781
+ unitPriceAmount: it.unitPrice,
2782
+ currency: it.currency,
2783
+ classifications: it.classifications,
2784
+ // Keep the legacy single fields populated from the first classification
2785
+ // for back-compat display (CartView) and any single-domain consumer.
2786
+ classificationDomain: it.classifications[0]?.domain,
2787
+ classification: it.classifications[0]?.value,
2788
+ manufacturerPartId: it.manufacturerPartId,
2789
+ manufacturerName: it.manufacturerName
2790
+ });
2791
+ }
2792
+ });
2793
+ if (ctx.operation === "edit") {
2794
+ const extras = ctx.items.filter((p) => !catalog.some((it) => sameProduct(p, it)));
2795
+ extras.forEach((p, j) => {
2796
+ const qty = Number(form[`qx_${j}`] ?? p.quantity);
2797
+ if (qty > 0) items.push({ ...p, quantity: qty });
2687
2798
  });
2688
2799
  }
2689
- });
2800
+ }
2690
2801
  const currency = items[0]?.currency ?? "USD";
2691
2802
  const eff = effFor(supplier.id, buyerCred);
2692
2803
  const xml = buildPunchOutOrderMessage({
@@ -1,4 +1,4 @@
1
- import{m as et}from"./index-ByIxIbJu.js";/*!-----------------------------------------------------------------------------
1
+ import{m as et}from"./index-Dr4reAcK.js";/*!-----------------------------------------------------------------------------
2
2
  * Copyright (c) Microsoft Corporation. All rights reserved.
3
3
  * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1)
4
4
  * Released under the MIT license
@@ -1,4 +1,4 @@
1
- import{m as f}from"./index-ByIxIbJu.js";/*!-----------------------------------------------------------------------------
1
+ import{m as f}from"./index-Dr4reAcK.js";/*!-----------------------------------------------------------------------------
2
2
  * Copyright (c) Microsoft Corporation. All rights reserved.
3
3
  * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1)
4
4
  * Released under the MIT license
@@ -1,4 +1,4 @@
1
- import{m as l}from"./index-ByIxIbJu.js";/*!-----------------------------------------------------------------------------
1
+ import{m as l}from"./index-Dr4reAcK.js";/*!-----------------------------------------------------------------------------
2
2
  * Copyright (c) Microsoft Corporation. All rights reserved.
3
3
  * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1)
4
4
  * Released under the MIT license
@@ -1,4 +1,4 @@
1
- import{m as s}from"./index-ByIxIbJu.js";/*!-----------------------------------------------------------------------------
1
+ import{m as s}from"./index-Dr4reAcK.js";/*!-----------------------------------------------------------------------------
2
2
  * Copyright (c) Microsoft Corporation. All rights reserved.
3
3
  * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1)
4
4
  * Released under the MIT license
@@ -1,4 +1,4 @@
1
- import{m as lt}from"./index-ByIxIbJu.js";/*!-----------------------------------------------------------------------------
1
+ import{m as lt}from"./index-Dr4reAcK.js";/*!-----------------------------------------------------------------------------
2
2
  * Copyright (c) Microsoft Corporation. All rights reserved.
3
3
  * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1)
4
4
  * Released under the MIT license