PageSourceSearch

https://mesca-submittal.onrender.com/resources/js/pages/ProductCategories.tsx

js mesca-submittal.onrender.com collected 2026-10-03 11:41:46 UTC 85,155 bytes, 643 lines download raw bytes

1import __vite__cjsImport0_react from "/node_modules/.vite/deps/react.js?v=47cb5776"; const React = __vite__cjsImport0_react.__esModule ? __vite__cjsImport0_react.default : __vite__cjsImport0_react; const useState = __vite__cjsImport0_react["useState"]; const useEffect = __vite__cjsImport0_react["useEffect"];
2import axios from "/node_modules/.vite/deps/axios.js?v=a22cc16d";
3import {
4  DndContext,
5  DragOverlay,
6  PointerSensor,
7  useSensor,
8  useSensors,
9  closestCenter
10} from "/node_modules/.vite/deps/@dnd-kit_core.js?v=639d9591";
11import { SortableContext, verticalListSortingStrategy, useSortable } from "/node_modules/.vite/deps/@dnd-kit_sortable.js?v=7bbfd44e";
12import { CSS } from "/node_modules/.vite/deps/@dnd-kit_utilities.js?v=e5ec5f33";
13const CategoryItem = ({
14  category,
15  onEdit,
16  onDelete,
17  isReorderMode,
18  flatCategories,
19  setFlatCategories
20}) => {
21  const {
22    attributes,
23    listeners,
24    setNodeRef,
25    transform,
26    transition,
27    isDragging: isSortableDragging
28  } = useSortable({
29    id: category.id,
30    disabled: !isReorderMode,
31    data: {
32      type: "category",
33      category
34    }
35  });
36  const style = {
37    transform: CSS.Transform.toString(transform),
38    transition,
39    opacity: isSortableDragging ? 0.5 : 1
40  };
41  const indentLevel = category.level * 50;
42  const moveCategory = async (categoryId, direction) => {
43    const categoryIndex = flatCategories.findIndex((cat) => cat.id === categoryId);
44    if (categoryIndex === -1) return;
45    const swapIndex = direction === "up" ? categoryIndex - 1 : categoryIndex + 1;
46    if (swapIndex < 0 || swapIndex >= flatCategories.length) return;
47    const updatedCategories = [...flatCategories];
48    const temp = updatedCategories[categoryIndex];
49    updatedCategories[categoryIndex] = updatedCategories[swapIndex];
50    updatedCategories[swapIndex] = temp;
51    updatedCategories[categoryIndex].order = categoryIndex + 1;
52    updatedCategories[swapIndex].order = swapIndex + 1;
53    setFlatCategories(updatedCategories);
54    try {
55      await axios.put(`/api/product-categories/${updatedCategories[categoryIndex].id}`, {
56        order: updatedCategories[categoryIndex].order
57      });
58      await axios.put(`/api/product-categories/${updatedCategories[swapIndex].id}`, {
59        order: updatedCategories[swapIndex].order
60      });
61    } catch (err) {
62      console.error("Error updating category order:", err);
63    }
64  };
65  return /* @__PURE__ */ React.createElement(
66    "div",
67    {
68      ref: setNodeRef,
69      style,
70      className: `
71        bg-white border border-gray-200 rounded-lg p-4 mb-2 shadow-sm transition-all
72        ${isSortableDragging ? "shadow-lg ring-2 ring-blue-500" : ""}
73        ${category.isDropTarget ? "ring-2 ring-green-400 bg-green-50" : ""}
74        ${isReorderMode ? "cursor-grab active:cursor-grabbing" : ""}
75      `,
76      ...attributes,
77      ...listeners
78    },
79    /* @__PURE__ */ React.createElement(
80      "div",
81      {
82        className: "flex flex-col lg:flex-row lg:items-center lg:justify-between space-y-3 lg:space-y-0",
83        style: { marginLeft: indentLevel }
84      },
85      /* @__PURE__ */ React.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-2" }, /* @__PURE__ */ React.createElement("h3", { className: "text-lg font-medium text-gray-900" }, category.name), category.hasChildren && /* @__PURE__ */ React.createElement("span", { className: "inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800" }, category.children?.length || 0, " children")), category.description && /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-gray-600" }, category.description), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-xs text-gray-500" }, "Order: ", category.order, " | Created: ", new Date(category.createdAt).toLocaleDateString())),
86      /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2 lg:space-x-2 lg:gap-0" }, /* @__PURE__ */ React.createElement(
87        "button",
88        {
89          onClick: () => onEdit(category),
90          className: "text-blue-500 hover:text-gray-700 text-sm font-medium"
91        },
92        "Edit"
93      ), /* @__PURE__ */ React.createElement(
94        "button",
95        {
96          onClick: () => onDelete(category.id),
97          className: "text-red-500 hover:text-gray-700 text-sm font-medium"
98        },
99        "Delete"
100      ), /* @__PURE__ */ React.createElement(
101        "button",
102        {
103          onClick: () => moveCategory(category.id, "up"),
104          className: "px-2 py-1 text-sm bg-gray-300 text-black rounded hover:bg-gray-400 transition-colors"
105        },
106        "↑"
107      ), /* @__PURE__ */ React.createElement(
108        "button",
109        {
110          onClick: () => moveCategory(category.id, "down"),
111          className: "px-2 py-1 text-sm bg-gray-300 text-black rounded hover:bg-gray-400 transition-colors"
112        },
113        "↓"
114      ))
115    )
116  );
117};
118const ProductCategories = () => {
119  const [categories, setCategories] = useState([]);
120  const [flatCategories, setFlatCategories] = useState([]);
121  const [loading, setLoading] = useState(true);
122  const [error, setError] = useState(null);
123  const [showNewCategoryModal, setShowNewCategoryModal] = useState(false);
124  const [newCategoryName, setNewCategoryName] = useState("");
125  const [newCategoryDescription, setNewCategoryDescription] = useState("");
126  const [newCategoryParent, setNewCategoryParent] = useState(null);
127  const [showEditCategoryModal, setShowEditCategoryModal] = useState(false);
128  const [editCategoryId, setEditCategoryId] = useState(null);
129  const [editCategoryName, setEditCategoryName] = useState("");
130  const [editCategoryDescription, setEditCategoryDescription] = useState("");
131  const [editCategoryParent, setEditCategoryParent] = useState(null);
132  const [deleteConfirmId, setDeleteConfirmId] = useState(null);
133  const [isReorderMode, setIsReorderMode] = useState(false);
134  const [activeId, setActiveId] = useState(null);
135  const [pendingUpdates, setPendingUpdates] = useState([]);
136  const [overId, setOverId] = useState(null);
137  const [originalCategories, _setOriginalCategories] = useState([]);
138  const [originalFlatCategories, _setOriginalFlatCategories] = useState([]);
139  const sensors = useSensors(
140    useSensor(PointerSensor, {
141      activationConstraint: {
142        distance: 8
143      }
144    })
145  );
146  useEffect(() => {
147    fetchCategories();
148  }, []);
149  useEffect(() => {
150    if (categories.length > 0) {
151      setFlatCategories(flattenCategories(categories));
152    }
153  }, [categories, overId]);
154  const flattenCategories = (cats, level = 0) => {
155    const result = [];
156    cats.forEach((cat) => {
157      result.push({
158        ...cat,
159        level,
160        hasChildren: Boolean(cat.children && cat.children.length > 0),
161        isDropTarget: overId === cat.id
162      });
163      if (cat.children && cat.children.length > 0) {
164        result.push(...flattenCategories(cat.children, level + 1));
165      }
166    });
167    return result;
168  };
169  const fetchCategories = async () => {
170    try {
171      setLoading(true);
172      const response = await axios.get("/api/product-categories");
173      setCategories(response.data?.categories || []);
174      setError(null);
175    } catch (err) {
176      console.error("Error fetching categories:", err);
177      setError(err.response?.data?.error || "Failed to fetch categories");
178      setCategories([]);
179    } finally {
180      setLoading(false);
181    }
182  };
183  const handleCreateCategory = async () => {
184    if (!newCategoryName.trim()) {
185      setError("Category name is required");
186      return;
187    }
188    try {
189      await axios.post("/api/product-categories", {
190        name: newCategoryName.trim(),
191        description: newCategoryDescription.trim() || null,
192        parentId: newCategoryParent
193      });
194      setNewCategoryName("");
195      setNewCategoryDescription("");
196      setNewCategoryParent(null);
197      setShowNewCategoryModal(false);
198      await fetchCategories();
199    } catch (err) {
200      console.error("Error creating category:", err);
201      setError(err.response?.data?.error || "Failed to create category");
202    }
203  };
204  const handleEditClick = (category) => {
205    setEditCategoryId(category.id);
206    setEditCategoryName(category.name);
207    setEditCategoryDescription(category.description || "");
208    setEditCategoryParent(category.parentId);
209    setShowEditCategoryModal(true);
210  };
211  const handleUpdateCategory = async () => {
212    if (!editCategoryName.trim()) {
213      setError("Category name is required");
214      return;
215    }
216    try {
217      await axios.put(`/api/product-categories/${editCategoryId}`, {
218        name: editCategoryName.trim(),
219        description: editCategoryDescription.trim() || null,
220        parentId: editCategoryParent
221      });
222      setShowEditCategoryModal(false);
223      await fetchCategories();
224    } catch (err) {
225      console.error("Error updating category:", err);
226      setError(err.response?.data?.error || "Failed to update category");
227    }
228  };
229  const handleDeleteCategory = async (id) => {
230    try {
231      await axios.delete(`/api/product-categories/${id}`);
232      await fetchCategories();
233      setDeleteConfirmId(null);
234    } catch (err) {
235      console.error("Error deleting category:", err);
236      setError(err.response?.data?.error || "Failed to delete category");
237    }
238  };
239  const handleDragStart = (event) => {
240    setActiveId(event.active.id);
241  };
242  const handleDragOver = (event) => {
243    const { active, over } = event;
244    if (!over || !active) {
245      setOverId(null);
246      return;
247    }
248    const activeId2 = active.id;
249    const overId2 = over.id;
250    if (activeId2 === overId2) {
251      setOverId(null);
252      return;
253    }
254    const activeCategory2 = flatCategories.find((cat) => cat.id === activeId2);
255    if (activeCategory2 && isDescendantOf(overId2, activeId2)) {
256      setOverId(null);
257      return;
258    }
259    setOverId(overId2);
260  };
261  const isDescendantOf = (categoryId, ancestorId) => {
262    const category = flatCategories.find((cat) => cat.id === categoryId);
263    if (!category || !category.parentId) return false;
264    if (category.parentId === ancestorId) return true;
265    return isDescendantOf(category.parentId, ancestorId);
266  };
267  const handleDragEnd = async (event) => {
268    const { active, over } = event;
269    setActiveId(null);
270    setOverId(null);
271    if (!over || active.id === over.id) {
272      return;
273    }
274    const activeId2 = active.id;
275    const overId2 = over.id;
276    const activeCategory2 = flatCategories.find((cat) => cat.id === activeId2);
277    const overCategory = flatCategories.find((cat) => cat.id === overId2);
278    if (!activeCategory2 || !overCategory) {
279      return;
280    }
281    if (isDescendantOf(overId2, activeId2)) {
282      return;
283    }
284    let newParentId;
285    let newOrder;
286    const shouldBecomeChild = event.delta.x > 20;
287    if (shouldBecomeChild) {
288      newParentId = overId2;
289      const childrenCount = flatCategories.filter((cat) => cat.parentId === overId2).length;
290      newOrder = childrenCount;
291    } else {
292      newParentId = overCategory.parentId;
293      const siblings = flatCategories.filter((cat) => cat.parentId === newParentId);
294      const overIndex = siblings.findIndex((cat) => cat.id === overId2);
295      newOrder = overIndex + 1;
296    }
297    const updatedCategories = updateCategoryHierarchy(activeId2, newParentId, newOrder);
298    const newTree = buildCategoryTree(updatedCategories);
299    setCategories(newTree);
300    setFlatCategories(flattenCategories(newTree));
301    const update = {
302      id: activeId2,
303      parentId: newParentId,
304      order: newOrder
305    };
306    setPendingUpdates((prev) => {
307      const filtered = prev.filter((u) => u.id !== activeId2);
308      return [...filtered, update];
309    });
310  };
311  const updateCategoryHierarchy = (categoryId, newParentId, newOrder) => {
312    return flatCategories.map((cat) => {
313      if (cat.id === categoryId) {
314        return { ...cat, parentId: newParentId, order: newOrder };
315      } else if (cat.parentId === newParentId) {
316        if (cat.order >= newOrder) {
317          return { ...cat, order: cat.order + 1 };
318        }
319      }
320      return cat;
321    });
322  };
323  const buildCategoryTree = (flatCats) => {
324    const categoryMap = /* @__PURE__ */ new Map();
325    const rootCategories = [];
326    flatCats.forEach((cat) => {
327      categoryMap.set(cat.id, {
328        id: cat.id,
329        name: cat.name,
330        description: cat.description,
331        parentId: cat.parentId,
332        order: cat.order,
333        createdAt: cat.createdAt,
334        updatedAt: cat.updatedAt,
335        children: []
336      });
337    });
338    flatCats.forEach((cat) => {
339      const category = categoryMap.get(cat.id);
340      if (cat.parentId === null) {
341        rootCategories.push(category);
342      } else {
343        const parent = categoryMap.get(cat.parentId);
344        if (parent) {
345          parent.children = parent.children || [];
346          parent.children.push(category);
347        }
348      }
349    });
350    const sortByOrder = (cats) => {
351      cats.sort((a, b) => (a.order || 0) - (b.order || 0));
352      cats.forEach((cat) => {
353        if (cat.children && cat.children.length > 0) {
354          sortByOrder(cat.children);
355        }
356      });
357    };
358    sortByOrder(rootCategories);
359    return rootCategories;
360  };
361  const handleSaveReorder = async () => {
362    try {
363      setLoading(true);
364      for (const update of pendingUpdates) {
365        await axios.put(`/api/product-categories/${update.id}`, {
366          parentId: update.parentId,
367          order: update.order
368        });
369      }
370      setPendingUpdates([]);
371      setIsReorderMode(false);
372      await fetchCategories();
373    } catch (err) {
374      console.error("Error saving reorder:", err);
375      setError(err.response?.data?.error || "Failed to save new order");
376      await fetchCategories();
377    } finally {
378      setLoading(false);
379    }
380  };
381  const handleCancelReorder = () => {
382    setIsReorderMode(false);
383    setPendingUpdates([]);
384    setCategories(originalCategories);
385    setFlatCategories(originalFlatCategories);
386  };
387  const getAllCategoriesFlat = (cats) => {
388    const result = [];
389    const traverse = (categories2) => {
390      categories2.forEach((cat) => {
391        result.push(cat);
392        if (cat.children && cat.children.length > 0) {
393          traverse(cat.children);
394        }
395      });
396    };
397    traverse(cats);
398    return result;
399  };
400  const activeCategory = activeId ? flatCategories.find((cat) => cat.id === activeId) : null;
401  if (loading && categories.length === 0) {
402    return /* @__PURE__ */ React.createElement("div", { className: "container mx-auto px-4 py-8" }, /* @__PURE__ */ React.createElement("div", { className: "text-center py-10" }, /* @__PURE__ */ React.createElement("div", { className: "animate-spin h-10 w-10 text-blue-500 mx-auto mb-4" }, /* @__PURE__ */ React.createElement("svg", { className: "w-full h-full", fill: "none", viewBox: "0 0 24 24" }, /* @__PURE__ */ React.createElement(
403      "circle",
404      {
405        className: "opacity-25",
406        cx: "12",
407        cy: "12",
408        r: "10",
409        stroke: "currentColor",
410        strokeWidth: "4"
411      }
412    ), /* @__PURE__ */ React.createElement(
413      "path",
414      {
415        className: "opacity-75",
416        fill: "currentColor",
417        d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
418      }
419    ))), /* @__PURE__ */ React.createElement("p", { className: "text-gray-600" }, "Loading categories...")));
420  }
421  return /* @__PURE__ */ React.createElement("div", { className: "container mx-auto px-4 py-8" }, /* @__PURE__ */ React.createElement("div", { className: "mb-6 flex justify-between items-center" }, /* @__PURE__ */ React.createElement("h1", { className: "text-2xl font-bold text-gray-800" }, "Product Categories"), /* @__PURE__ */ React.createElement("div", { className: "flex space-x-3" }, !isReorderMode ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
422    "button",
423    {
424      onClick: () => setShowNewCategoryModal(true),
425      className: "px-4 py-2  bg-gray-300 border border-gray-300 rounded hover:bg-gray-50"
426    },
427    "Add New Category"
428  )) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
429    "button",
430    {
431      onClick: handleCancelReorder,
432      className: "px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600 transition-colors"
433    },
434    "Cancel"
435  ), /* @__PURE__ */ React.createElement(
436    "button",
437    {
438      onClick: handleSaveReorder,
439      className: "px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600 transition-colors",
440      disabled: pendingUpdates.length === 0
441    },
442    "Save Order (",
443    pendingUpdates.length,
444    " changes)"
445  )))), error && /* @__PURE__ */ React.createElement("div", { className: "mb-6 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded" }, /* @__PURE__ */ React.createElement("p", null, error), /* @__PURE__ */ React.createElement("button", { onClick: () => setError(null), className: "mt-2 text-sm underline" }, "Dismiss")), isReorderMode && /* @__PURE__ */ React.createElement("div", { className: "mb-6 bg-yellow-50 border border-yellow-200 text-yellow-800 px-4 py-3 rounded" }, /* @__PURE__ */ React.createElement("p", { className: "font-medium" }, "Reorder Mode Active"), /* @__PURE__ */ React.createElement("p", { className: "text-sm mt-1" }, "Drag categories to reorder them or change their parent:"), /* @__PURE__ */ React.createElement("ul", { className: "text-xs mt-1 list-disc list-inside" }, /* @__PURE__ */ React.createElement("li", null, "Drag slightly right to make a category a child of another"), /* @__PURE__ */ React.createElement("li", null, "Normal drag to make it a sibling"), /* @__PURE__ */ React.createElement("li", null, "Green highlight shows valid drop targets"))), /* @__PURE__ */ React.createElement(
446    DndContext,
447    {
448      sensors,
449      collisionDetection: closestCenter,
450      onDragStart: handleDragStart,
451      onDragOver: handleDragOver,
452      onDragEnd: handleDragEnd
453    },
454    /* @__PURE__ */ React.createElement(
455      SortableContext,
456      {
457        items: flatCategories.map((cat) => cat.id),
458        strategy: verticalListSortingStrategy
459      },
460      /* @__PURE__ */ React.createElement("div", { className: "space-y-2" }, flatCategories.map((category) => /* @__PURE__ */ React.createElement(
461        CategoryItem,
462        {
463          key: category.id,
464          category,
465          onEdit: handleEditClick,
466          onDelete: setDeleteConfirmId,
467          isReorderMode,
468          flatCategories,
469          setFlatCategories
470        }
471      )))
472    ),
473    /* @__PURE__ */ React.createElement(DragOverlay, null, activeCategory ? /* @__PURE__ */ React.createElement(
474      CategoryItem,
475      {
476        category: activeCategory,
477        onEdit: () => {
478        },
479        onDelete: () => {
480        },
481        isReorderMode,
482        isDragging: true,
483        flatCategories,
484        setFlatCategories
485      }
486    ) : null)
487  ), flatCategories.length === 0 && !loading && /* @__PURE__ */ React.createElement("div", { className: "text-center py-10 bg-gray-50 rounded-lg" }, /* @__PURE__ */ React.createElement("p", { className: "text-gray-500" }, "No categories found"), /* @__PURE__ */ React.createElement(
488    "button",
489    {
490      onClick: () => setShowNewCategoryModal(true),
491      className: "px-4 py-2  bg-gray-300 border border-gray-300 rounded hover:bg-gray-50"
492    },
493    "Create your first category"
494  )), showNewCategoryModal && /* @__PURE__ */ React.createElement("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50" }, /* @__PURE__ */ React.createElement("div", { className: "bg-white rounded-lg p-6 w-full max-w-md" }, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold mb-4" }, "Add New Category"), /* @__PURE__ */ React.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
495    "label",
496    {
497      htmlFor: "newCategoryName",
498      className: "block text-sm font-medium text-gray-700"
499    },
500    "Name *"
501  ), /* @__PURE__ */ React.createElement(
502    "input",
503    {
504      type: "text",
505      id: "newCategoryName",
506      value: newCategoryName,
507      onChange: (e) => setNewCategoryName(e.target.value),
508      className: "mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
509    }
510  )), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
511    "label",
512    {
513      htmlFor: "newCategoryDescription",
514      className: "block text-sm font-medium text-gray-700"
515    },
516    "Description"
517  ), /* @__PURE__ */ React.createElement(
518    "textarea",
519    {
520      id: "newCategoryDescription",
521      value: newCategoryDescription,
522      onChange: (e) => setNewCategoryDescription(e.target.value),
523      rows: 3,
524      className: "mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
525    }
526  )), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
527    "label",
528    {
529      htmlFor: "newCategoryParent",
530      className: "block text-sm font-medium text-gray-700"
531    },
532    "Parent Category"
533  ), /* @__PURE__ */ React.createElement(
534    "select",
535    {
536      id: "newCategoryParent",
537      value: newCategoryParent || "",
538      onChange: (e) => setNewCategoryParent(e.target.value ? parseInt(e.target.value) : null),
539      className: "mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
540    },
541    /* @__PURE__ */ React.createElement("option", { value: "" }, "No parent (top level)"),
542    getAllCategoriesFlat(categories).map((cat) => /* @__PURE__ */ React.createElement("option", { key: cat.id, value: cat.id }, cat.name))
543  ))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 flex justify-end space-x-3" }, /* @__PURE__ */ React.createElement(
544    "button",
545    {
546      onClick: () => {
547        setShowNewCategoryModal(false);
548        setNewCategoryName("");
549        setNewCategoryDescription("");
550        setNewCategoryParent(null);
551      },
552      className: "px-4 py-2 text-gray-700 border border-gray-300 rounded hover:bg-gray-50"
553    },
554    "Cancel"
555  ), /* @__PURE__ */ React.createElement(
556    "button",
557    {
558      onClick: handleCreateCategory,
559      className: "px-4 py-2  bg-gray-300 border border-gray-300 rounded hover:bg-gray-50"
560    },
561    "Create Category"
562  )))), showEditCategoryModal && /* @__PURE__ */ React.createElement("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50" }, /* @__PURE__ */ React.createElement("div", { className: "bg-white rounded-lg p-6 w-full max-w-md" }, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold mb-4" }, "Edit Category"), /* @__PURE__ */ React.createElement("div", { className: "space-y-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
563    "label",
564    {
565      htmlFor: "editCategoryName",
566      className: "block text-sm font-medium text-gray-700"
567    },
568    "Name *"
569  ), /* @__PURE__ */ React.createElement(
570    "input",
571    {
572      type: "text",
573      id: "editCategoryName",
574      value: editCategoryName,
575      onChange: (e) => setEditCategoryName(e.target.value),
576      className: "mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
577    }
578  )), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
579    "label",
580    {
581      htmlFor: "editCategoryDescription",
582      className: "block text-sm font-medium text-gray-700"
583    },
584    "Description"
585  ), /* @__PURE__ */ React.createElement(
586    "textarea",
587    {
588      id: "editCategoryDescription",
589      value: editCategoryDescription,
590      onChange: (e) => setEditCategoryDescription(e.target.value),
591      rows: 3,
592      className: "mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
593    }
594  )), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
595    "label",
596    {
597      htmlFor: "editCategoryParent",
598      className: "block text-sm font-medium text-gray-700"
599    },
600    "Parent Category"
601  ), /* @__PURE__ */ React.createElement(
602    "select",
603    {
604      id: "editCategoryParent",
605      value: editCategoryParent || "",
606      onChange: (e) => setEditCategoryParent(e.target.value ? parseInt(e.target.value) : null),
607      className: "mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
608    },
609    /* @__PURE__ */ React.createElement("option", { value: "" }, "No parent (top level)"),
610    getAllCategoriesFlat(categories).filter((cat) => cat.id !== editCategoryId).map((cat) => /* @__PURE__ */ React.createElement("option", { key: cat.id, value: cat.id }, cat.name))
611  ))), /* @__PURE__ */ React.createElement("div", { className: "mt-6 flex justify-end space-x-3" }, /* @__PURE__ */ React.createElement(
612    "button",
613    {
614      onClick: () => setShowEditCategoryModal(false),
615      className: "px-4 py-2 text-gray-700 border border-gray-300 rounded hover:bg-gray-50"
616    },
617    "Cancel"
618  ), /* @__PURE__ */ React.createElement(
619    "button",
620    {
621      onClick: handleUpdateCategory,
622      className: "px-4 py-2  bg-gray-300 border border-gray-300 rounded hover:bg-gray-50"
623    },
624    "Update Category"
625  )))), deleteConfirmId && /* @__PURE__ */ React.createElement("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50" }, /* @__PURE__ */ React.createElement("div", { className: "bg-white rounded-lg p-6 w-full max-w-md" }, /* @__PURE__ */ React.createElement("h2", { className: "text-xl font-semibold mb-4" }, "Delete Category"), /* @__PURE__ */ React.createElement("p", { className: "mb-6 text-gray-600" }, "Are you sure you want to delete this category? This action cannot be undone."), /* @__PURE__ */ React.createElement("div", { className: "flex justify-end space-x-3" }, /* @__PURE__ */ React.createElement(
626    "button",
627    {
628      onClick: () => setDeleteConfirmId(null),
629      className: "px-4 py-2  bg-gray-300 border border-gray-300 rounded hover:bg-gray-50"
630    },
631    "Cancel"
632  ), /* @__PURE__ */ React.createElement(
633    "button",
634    {
635      onClick: () => handleDeleteCategory(deleteConfirmId),
636      className: "px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600"
637    },
638    "Delete"
639  )))));
640};
641export default ProductCategories;
642
643//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIlByb2R1Y3RDYXRlZ29yaWVzLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUmVhY3QsIHsgdXNlU3RhdGUsIHVzZUVmZmVjdCB9IGZyb20gJ3JlYWN0J1xuaW1wb3J0IGF4aW9zIGZyb20gJ2F4aW9zJ1xuaW1wb3J0IHtcbiAgRG5kQ29udGV4dCxcbiAgRHJhZ0VuZEV2ZW50LFxuICBEcmFnT3ZlckV2ZW50LFxuICBEcmFnT3ZlcmxheSxcbiAgRHJhZ1N0YXJ0RXZlbnQsXG4gIFBvaW50ZXJTZW5zb3IsXG4gIHVzZVNlbnNvcixcbiAgdXNlU2Vuc29ycyxcbiAgY2xvc2VzdENlbnRlcixcbn0gZnJvbSAnQGRuZC1raXQvY29yZSdcbmltcG9ydCB7IFNvcnRhYmxlQ29udGV4dCwgdmVydGljYWxMaXN0U29ydGluZ1N0cmF0ZWd5LCB1c2VTb3J0YWJsZSB9IGZyb20gJ0BkbmQta2l0L3NvcnRhYmxlJ1xuaW1wb3J0IHsgQ1NTIH0gZnJvbSAnQGRuZC1raXQvdXRpbGl0aWVzJ1xuXG5pbnRlcmZhY2UgUHJvZHVjdENhdGVnb3J5IHtcbiAgaWQ6IG51bWJlclxuICBuYW1lOiBzdHJpbmdcbiAgZGVzY3JpcHRpb246IHN0cmluZyB8IG51bGxcbiAgcGFyZW50SWQ6IG51bWJlciB8IG51bGxcbiAgb3JkZXI6IG51bWJlclxuICBjcmVhdGVkQXQ6IHN0cmluZ1xuICB1cGRhdGVkQXQ6IHN0cmluZ1xuICBjaGlsZHJlbj86IFByb2R1Y3RDYXRlZ29yeVtdXG59XG5cbmludGVyZmFjZSBGbGF0Q2F0ZWdvcnkgZXh0ZW5kcyBQcm9kdWN0Q2F0ZWdvcnkge1xuICBsZXZlbDogbnVtYmVyXG4gIGhhc0NoaWxkcmVuOiBib29sZWFuXG4gIGlzRHJvcFRhcmdldD86IGJvb2xlYW5cbn1cblxuaW50ZXJmYWNlIENhdGVnb3J5SXRlbVByb3BzIHtcbiAgY2F0ZWdvcnk6IEZsYXRDYXRlZ29yeVxuICBvbkVkaXQ6IChjYXRlZ29yeTogUHJvZHVjdENhdGVnb3J5KSA9PiB2b2lkXG4gIG9uRGVsZXRlOiAoaWQ6IG51bWJlcikgPT4gdm9pZFxuICBpc1Jlb3JkZXJNb2RlOiBib29sZWFuXG4gIGlzRHJhZ2dpbmc/OiBib29sZWFuXG4gIGZsYXRDYXRlZ29yaWVzOiBGbGF0Q2F0ZWdvcnlbXVxuICBzZXRGbGF0Q2F0ZWdvcmllczogUmVhY3QuRGlzcGF0Y2g8UmVhY3QuU2V0U3RhdGVBY3Rpb248RmxhdENhdGVnb3J5W10+PlxufVxuXG5jb25zdCBDYXRlZ29yeUl0ZW06IFJlYWN0LkZDPENhdGVnb3J5SXRlbVByb3BzPiA9ICh7XG4gIGNhdGVnb3J5LFxuICBvbkVkaXQsXG4gIG9uRGVsZXRlLFxuICBpc1Jlb3JkZXJNb2RlLFxuXG4gIGZsYXRDYXRlZ29yaWVzLFxuICBzZXRGbGF0Q2F0ZWdvcmllcyxcbn0pID0+IHtcbiAgY29uc3Qge1xuICAgIGF0dHJpYnV0ZXMsXG4gICAgbGlzdGVuZXJzLFxuICAgIHNldE5vZGVSZWYsXG4gICAgdHJhbnNmb3JtLFxuICAgIHRyYW5zaXRpb24sXG4gICAgaXNEcmFnZ2luZzogaXNTb3J0YWJsZURyYWdnaW5nLFxuICB9ID0gdXNlU29ydGFibGUoe1xuICAgIGl
643kOiBjYXRlZ29yeS5pZCxcbiAgICBkaXNhYmxlZDogIWlzUmVvcmRlck1vZGUsXG4gICAgZGF0YToge1xuICAgICAgdHlwZTogJ2NhdGVnb3J5JyxcbiAgICAgIGNhdGVnb3J5LFxuICAgIH0sXG4gIH0pXG5cbiAgY29uc3Qgc3R5bGUgPSB7XG4gICAgdHJhbnNmb3JtOiBDU1MuVHJhbnNmb3JtLnRvU3RyaW5nKHRyYW5zZm9ybSksXG4gICAgdHJhbnNpdGlvbixcbiAgICBvcGFjaXR5OiBpc1NvcnRhYmxlRHJhZ2dpbmcgPyAwLjUgOiAxLFxuICB9XG5cbiAgY29uc3QgaW5kZW50TGV2ZWwgPSBjYXRlZ29yeS5sZXZlbCAqIDUwXG5cbiAgLy8gRnVuY3Rpb24gdG8gbW92ZSBhIGNhdGVnb3J5IHVwIG9yIGRvd25cbiAgY29uc3QgbW92ZUNhdGVnb3J5ID0gYXN5bmMgKGNhdGVnb3J5SWQ6IG51bWJlciwgZGlyZWN0aW9uOiAndXAnIHwgJ2Rvd24nKSA9PiB7XG4gICAgY29uc3QgY2F0ZWdvcnlJbmRleCA9IGZsYXRDYXRlZ29yaWVzLmZpbmRJbmRleCgoY2F0OiBGbGF0Q2F0ZWdvcnkpID0+IGNhdC5pZCA9PT0gY2F0ZWdvcnlJZClcbiAgICBpZiAoY2F0ZWdvcnlJbmRleCA9PT0gLTEpIHJldHVyblxuXG4gICAgY29uc3Qgc3dhcEluZGV4ID0gZGlyZWN0aW9uID09PSAndXAnID8gY2F0ZWdvcnlJbmRleCAtIDEgOiBjYXRlZ29yeUluZGV4ICsgMVxuICAgIGlmIChzd2FwSW5kZXggPCAwIHx8IHN3YXBJbmRleCA+PSBmbGF0Q2F0ZWdvcmllcy5sZW5ndGgpIHJldHVyblxuXG4gICAgY29uc3QgdXBkYXRlZENhdGVnb3JpZXMgPSBbLi4uZmxhdENhdGVnb3JpZXNdXG4gICAgY29uc3QgdGVtcCA9IHVwZGF0ZWRDYXRlZ29yaWVzW2NhdGVnb3J5SW5kZXhdXG4gICAgdXBkYXRlZENhdGVnb3JpZXNbY2F0ZWdvcnlJbmRleF0gPSB1cGRhdGVkQ2F0ZWdvcmllc1tzd2FwSW5kZXhdXG4gICAgdXBkYXRlZENhdGVnb3JpZXNbc3dhcEluZGV4XSA9IHRlbXBcblxuICAgIC8vIFVwZGF0ZSBvcmRlciB2YWx1ZXNcbiAgICB1cGRhdGVkQ2F0ZWdvcmllc1tjYXRlZ29yeUluZGV4XS5vcmRlciA9IGNhdGVnb3J5SW5kZXggKyAxXG4gICAgdXBkYXRlZENhdGVnb3JpZXNbc3dhcEluZGV4XS5vcmRlciA9IHN3YXBJbmRleCArIDFcblxuICAgI
643HNldEZsYXRDYXRlZ29yaWVzKHVwZGF0ZWRDYXRlZ29yaWVzKVxuXG4gICAgLy8gVXBkYXRlIGJhY2tlbmRcbiAgICB0cnkge1xuICAgICAgYXdhaXQgYXhpb3MucHV0KGAvYXBpL3Byb2R1Y3QtY2F0ZWdvcmllcy8ke3VwZGF0ZWRDYXRlZ29yaWVzW2NhdGVnb3J5SW5kZXhdLmlkfWAsIHtcbiAgICAgICAgb3JkZXI6IHVwZGF0ZWRDYXRlZ29yaWVzW2NhdGVnb3J5SW5kZXhdLm9yZGVyLFxuICAgICAgfSlcbiAgICAgIGF3YWl0IGF4aW9zLnB1dChgL2FwaS9wcm9kdWN0LWNhdGVnb3JpZXMvJHt1cGRhdGVkQ2F0ZWdvcmllc1tzd2FwSW5kZXhdLmlkfWAsIHtcbiAgICAgICAgb3JkZXI6IHVwZGF0ZWRDYXRlZ29yaWVzW3N3YXBJbmRleF0ub3JkZXIsXG4gICAgICB9KVxuICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdFcnJvciB1cGRhdGluZyBjYXRlZ29yeSBvcmRlcjonLCBlcnIpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIChcbiAgICA8ZGl2XG4gICAgICByZWY9e3NldE5vZGVSZWZ9XG4gICAgICBzdHlsZT17c3R5bGV9XG4gICAgICBjbGFzc05hbWU9e2BcbiAgICAgICAgYmctd2hpdGUgYm9yZGVyIGJvcmRlci1ncmF5LTIwMCByb3VuZGVkLWxnIHAtNCBtYi0yIHNoYWRvdy1zbSB0cmFuc2l0aW9uLWFsbFxuICAgICAgICAke2lzU29ydGFibGVEcmFnZ2luZyA/ICdzaGFkb3ctbGcgcmluZy0yIHJpbmctYmx1ZS01MDAnIDogJyd9XG4gICAgICAgICR7Y2F0ZWdvcnkuaXNEcm9wVGFyZ2V0ID8gJ3JpbmctMiByaW5nLWdyZWVuLTQwMCBiZy1ncmVlbi01MCcgOiAnJ31cbiAgICAgICAgJHtpc1Jlb3JkZXJNb2RlID8gJ2N1cnNvci1ncmFiIGFjdGl2ZTpjdXJzb3ItZ3JhYmJpbmcnIDogJyd9XG4gICAgICBgfVxuICAgICAgey4uLmF0dHJpYnV0ZXN9XG4gICAgICB7Li4ubGlzdGVuZXJzfVxuICAgID5cbiAgICAgIDxkaXZcbiAgICAgICAgY2xhc3NOYW1lPVwiZmxleCBmbGV4LWNvbCBsZzpmbGV4LXJvdyBsZzppdGVtcy1jZW50ZXIgbGc6anVzdGlmeS1iZXR3ZWVuIHNwYWNlLXktMyBsZzpzcGFjZS15LTBcIlxuICAgICAgICBzdHlsZT17eyBtYXJnaW5MZWZ0OiBpbmRlbnRMZXZlbCB9fVxuICAgICAgPlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImZsZXgtMVwiPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZmxleCBmbGV4LXdyYXAgaXRlbXMtY2VudGVyIGdhcC0yXCI+XG4gICAgICAgICAgICA8aDMgY2xhc3NOYW1lPVwidGV4dC1sZyBmb250LW1lZGl1bSB0ZXh0LWdyYXktOTAwXCI+e2NhdGVnb3J5Lm5hbWV9PC9oMz5cbiAgICAgICAgICAgIHtjYXRlZ29yeS5oYXNDaGlsZHJlbiAmJiAoXG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cImlubGluZS1mbGV4IGl0ZW1zLWNlbnRlciBweC0yLjUgcHktMC41IHJvdW5kZWQtZnVsbCB0ZXh0LXhzIGZvbnQtbWVkaXVtIGJnLWJsdWUtMTAwIHRleHQtYmx1ZS04MDBcIj5cbiAgICAgICAgICAgICAgICB7Y2F0ZWdvcnkuY2hpbGRyZW4/Lmxlbmd0aCB8fCAwfSBjaGlsZHJlblxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICApfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIHtjYXRlZ29yeS5kZXNjcmlwdGlvbiAmJiAoXG4gICAgICAgICAgICA8cCBjbGFzc05hbWU9XCJtdC0xIHRleHQtc20gdGV4dC1ncmF5LTYwMFwiPntjYXRlZ29yeS5kZXNjcmlwdGlvbn08L3A+XG4gICAgICAgICAgKX1cbiAgICAgICAgICA8cCBjbGFzc05hbWU9XCJtdC0xIHRleHQteHMgdGV4dC1ncmF5LTUwMFwiPlxuICAgICAgICAgICAgT3JkZXI6IHtjYXRlZ29yeS5vcmRlcn0gfCBDcmVhdGVkOiB7bmV3IERhdGUoY2F0ZWdvcnkuY3JlYXRlZEF0KS50b0xvY2FsZURhdGVTdHJpbmcoKX1cbiAgICAgICAgICA8L3A+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZmxleCBmbGV4LXdyYXAgZ2FwLTIgbGc6c3BhY2UteC0yIGxnOmdhcC0wXCI+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgb25DbGljaz17KCkgPT4gb25FZGl0KGNhdGVnb3J5KX1cbiAgICAgICAgICAgIGNsYXNzTmFtZT1cInRleHQtYmx1ZS01MDAgaG92ZXI6dGV4dC1ncmF5LTcwMCB0ZXh0LXNtIGZvbnQtbWVkaXVtXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICBFZGl0XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgb25DbGljaz17KCkgPT4gb25EZWxldGUoY2F0ZWdvcnkuaWQpfVxuICAgICAgICAgICAgY2xhc3NOYW1lPVwidGV4dC1yZWQtNTAwIGhvdmVyOnRleHQtZ3JheS03MDAgdGV4dC1zbSBmb250LW1lZGl1bVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgRGVsZXRlXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgb25DbGljaz17KCkgPT4gbW92ZUNhdGVnb3J5KGNhdGVnb3J5LmlkLCAndXAnKX1cbiAgICAgICAgICAgIGNsYXNzTmFtZT1cInB4LTIgcHktMSB0ZXh0LXNtIGJnLWdyYXktMzAwIHRleHQtYmxhY2sgcm91bmRlZCBob3ZlcjpiZy1ncmF5LTQwMCB0cmFuc2l0aW9uLWNvbG9yc1wiXG4gICAgICAgICAgPlxuICAgICAgICAgICAg4oaRXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgb25DbGljaz17KCkgPT4gbW92ZUNhdGVnb3J5KGNhdGVnb3J5LmlkLCAnZG93bicpfVxuICAgICAgICAgICAgY2xhc3NOYW1lPVwicHgtMiBweS0xIHRleHQtc20gYmctZ3JheS0zMDAgdGV4dC1ibGFjayByb3VuZGVkIGhvdmVyOmJnLWdyYXktNDAwIHRyYW5zaXRpb24tY29sb3JzXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICDihpNcbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgKVxufVxuXG5jb25zdCBQcm9kdWN0Q2F0ZWdvcmllczogUmVhY3QuRkMgPSAoKSA9PiB7XG4gIGNvbnN0IFtjYXRlZ29yaWVzLCBzZXRDYXRlZ29yaWVzXSA9IHVzZVN0YXRlPFByb2R1Y3RDYXRlZ29yeVtdPihbXSlcbiAgY29uc3QgW2ZsYXRDYXRlZ29yaWVzLCBzZXRGbGF0Q2F0ZWdvcmllc10gPSB1c2VTdGF0ZTxGbGF0Q2F0ZWdvcnlbXT4oW10pXG4gIGNvbnN0IFtsb2FkaW5nLCBzZXRMb2FkaW5nXSA9IHVzZVN0YXRlPGJvb2xlYW4+KHRydWUpXG4gIGNvbnN0IFtlcnJvciwgc2V0RXJyb3JdID0gdXNlU3RhdGU8c3RyaW5nIHwgbnVsbD4obnVsbClcbiAgY29uc3QgW3Nob3dOZXd
643DYXRlZ29yeU1vZGFsLCBzZXRTaG93TmV3Q2F0ZWdvcnlNb2RhbF0gPSB1c2VTdGF0ZTxib29sZWFuPihmYWxzZSlcbiAgY29uc3QgW25ld0NhdGVnb3J5TmFtZSwgc2V0TmV3Q2F0ZWdvcnlOYW1lXSA9IHVzZVN0YXRlPHN0cmluZz4oJycpXG4gIGNvbnN0IFtuZXdDYXRlZ29yeURlc2NyaXB0aW9uLCBzZXROZXdDYXRlZ29yeURlc2NyaXB0aW9uXSA9IHVzZVN0YXRlPHN0cmluZz4oJycpXG4gIGNvbnN0IFtuZXdDYXRlZ29yeVBhcmVudCwgc2V0TmV3Q2F0ZWdvcnlQYXJlbnRdID0gdXNlU3RhdGU8bnVtYmVyIHwgbnVsbD4obnVsbClcbiAgY29uc3QgW3Nob3dFZGl0Q2F0ZWdvcnlNb2RhbCwgc2V0U2hvd0VkaXRDYXRlZ29yeU1vZGFsXSA9IHVzZVN0YXRlPGJvb2xlYW4+KGZhbHNlKVxuICBjb25zdCBbZWRpdENhdGVnb3J5SWQsIHNldEVkaXRDYXRlZ29yeUlkXSA9IHVzZVN0YXRlPG51bWJlciB8IG51bGw+KG51bGwpXG4gIGNvbnN0IFtlZGl0Q2F0ZWdvcnlOYW1lLCBzZXRFZGl0Q2F0ZWdvcnlOYW1lXSA9IHVzZVN0YXRlPHN0cmluZz4oJycpXG4gIGNvbnN0IFtlZGl0Q2F0ZWdvcnlEZXNjcmlwdGlvbiwgc2V0RWRpdENhdGVnb3J5RGVzY3JpcHRpb25dID0gdXNlU3RhdGU8c3RyaW5nPignJylcbiAgY29uc3QgW2VkaXRDYXRlZ29yeVBhcmVudCwgc2V0RWRpdENhdGVnb3J5UGFyZW50XSA9IHVzZVN0YXRlPG51bWJlciB8IG51bGw+KG51bGwpXG4gIGNvbnN0IFtkZWxldGVDb25maXJtSWQsIHNldERlbGV0ZUNvbmZpcm1JZF0gPSB1c2VTdGF0ZTxudW1iZXIgfCBudWxsPihudWxsKVxuICBjb25zdCBbaXNSZW9yZGVyTW9kZSwgc2V0SXNSZW9yZGVyTW9kZV0gPSB1c2VTdGF0ZTxib29sZWFuPihmYWxzZSlcbiAgY29uc3QgW2FjdGl2ZUlkLCBzZXRBY3RpdmVJZF0gPSB1c2VTdGF0ZTxudW1iZXIgfCBudWxsPihudWxsKVxuICBjb25zdCBbcGVuZGluZ1VwZGF0ZXMsIHNldFBlbmRpbmdVcGRhdGVzXSA9IHVzZVN0YXRlPFxuICAgIHsgaWQ6IG51bWJlcjsgcGFyZW50SWQ6IG51bWJlciB8IG51bGw7IG9yZGVyOiBudW1iZXIgfVtdXG4gID4oW10pXG4gIGNvbnN0IFtvdmVySWQsIHNldE92ZXJJZF0gPSB1c2VTdGF0ZTxudW1iZXIgfCBudWxsPihudWxsKVxuICBjb25zdCBbb3JpZ2luYWxDYXRlZ29yaWVzLCBfc2V0T3JpZ2luYWxDYXRlZ29yaWVzXSA9IHVzZVN0YXRlPFByb2R1Y3RDYXRlZ29yeVtdPihbXSlcbiAgY29uc3QgW29yaWdpbmFsRmxhdENhdGVnb3JpZXMsIF9zZXRPcmlnaW5hbEZsYXRDYXRlZ29yaWVzXSA9IHVzZVN0YXRlPEZsYXRDYXRlZ29yeVtdPihbXSlcblxuICBjb25zdCBzZW5zb3JzID0gdXNlU2Vuc29ycyhcbiAgICB1c2VTZW5zb3IoUG9pbnRlclNlbnNvciwge1xuICAgICAgYWN0aXZhdGlvbkNvbnN0cmFpbnQ6IHtcbiAgICAgICAgZGlzdGFuY2U6IDgsXG4gICAgICB9LFxuICAgIH0pXG4gIClcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGZldGNoQ2F0ZWdvcmllcygpXG4gIH0sIFtdKVxuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKGNhdGVnb3JpZXMubGVuZ3RoID4gMCkge1xuICAgICAgc2V0RmxhdENhdGVnb3JpZXMoZmxhdHRlbkNhdGVnb3JpZXMoY2F0ZWdvcmllcykpXG4gICAgfVxuICB9LCBbY2F0ZWdvcmllcywgb3ZlcklkXSlcblxuICBjb25zdCBmbGF0dGVuQ2F0ZWdvcmllcyA9IChjYXRzOiBQcm9kdWN0Q2F0ZWdvcnlbXSwgbGV2ZWwgPSAwKTogRmxhdENhdGVnb3J5W10gPT4ge1xuICAgIGNvbnN0IHJlc3VsdDogRmxhdENhdGVnb3J5W10gPSBbXVxuXG4gICAgY2F0cy5mb3JFYWNoKChjYXQpID0+IHtcbiAgICAgIHJlc3VsdC5wdXNoKHtcbiAgICAgICAgLi4uY2F0LFxuICAgICAgICBsZXZlbCxcbiAgICAgICAgaGFzQ2hpbGRyZW46IEJvb2xlYW4oY2F0LmNoaWxkcmVuICYmIGNhdC5jaGlsZHJlbi5sZW5ndGggPiAwKSxcbiAgICAgICAgaXNEcm9wVGFyZ2V0OiBvdmVySWQgPT09IGNhdC5pZCxcbiAgICAgIH0pXG5cbiAgICAgIGlmIChjYXQuY2hpbGRyZW4gJiYgY2F0LmNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmVzdWx0LnB1c2goLi4uZmxhdHRlbkNhdGVnb3JpZXMoY2F0LmNoaWxkcmVuLCBsZXZlbCArIDEpKVxuICAgICAgfVxuICAgIH0pXG5cbiAgICByZXR1cm4gcmVzdWx0XG4gIH1cblxuICBjb25zdCBmZXRjaENhdGVnb3JpZXMgPSBhc3luYyAoKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIHNldExvYWRpbmcodHJ1ZSlcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgYXhpb3MuZ2V0KCcvYXBpL3Byb2R1Y3QtY2F0ZWdvcmllcycpXG4gICAgICBzZXRDYXRlZ29yaWVzKHJlc3BvbnNlLmRhdGE/LmNhdGVnb3JpZXMgfHwgW10pXG4gICAgICBzZXRFcnJvcihudWxsKVxuICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBmZXRjaGluZyBjYXRlZ29yaWVzOicsIGVycilcbiAgICAgIHNldEVycm9yKGVyci5yZXNwb25zZT8uZGF0YT8uZXJyb3IgfHwgJ0ZhaWxlZCB0byBmZXRjaCBjYXRlZ29yaWVzJylcbiAgICAgIHNldENhdGVnb3JpZXMoW10pXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHNldExvYWRpbmcoZmFsc2UpXG4gICAgfVxuICB9XG5cbiAgY29uc3QgaGFuZGxlQ3JlYXRlQ2F0ZWdvcnkgPSBhc3luYyAoKSA9PiB7XG4gICAgaWYgKCFuZXdDYXRlZ29yeU5hbWUudHJpbSgpKSB7XG4gICAgICBzZXRFcnJvcignQ2F0ZWdvcnkgbmFtZSBpcyByZXF1aXJlZCcpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgYXhpb3MucG9zdCgnL2FwaS9wcm9kdWN0LWNhdGVnb3JpZXMnLCB7XG4gICAgICAgIG5hbWU6IG5ld0NhdGVnb3J5TmFtZS50cmltKCksXG4gICAgICAgIGRlc2NyaXB0aW9uOiBuZXdDYXRlZ29yeURlc2NyaXB0aW9uLnRyaW0oKSB8fCBudWxsLFxuICAgICAgICBwYXJlbnRJZDogbmV3Q2F0ZWdvcnlQYXJlbnQsXG4gICAgICB9KVxuXG4gICAgICBzZXROZXdDYXRlZ29yeU5hbWUoJycpXG4gICAgICBzZXROZXdDYXRlZ29yeURlc2NyaXB0aW9uKCcnKVxuICAgICAgc2V0TmV3Q2F0ZWdvcnlQYXJlbnQobnVsbClcbiAgICAgIHNldFNob3dOZXd
643DYXRlZ29yeU1vZGFsKGZhbHNlKVxuICAgICAgYXdhaXQgZmV0Y2hDYXRlZ29yaWVzKClcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgY3JlYXRpbmcgY2F0ZWdvcnk6JywgZXJyKVxuICAgICAgc2V0RXJyb3IoZXJyLnJlc3BvbnNlPy5kYXRhPy5lcnJvciB8fCAnRmFpbGVkIHRvIGNyZWF0ZSBjYXRlZ29yeScpXG4gICAgfVxuICB9XG5cbiAgY29uc3QgaGFuZGxlRWRpdENsaWNrID0gKGNhdGVnb3J5OiBQcm9kdWN0Q2F0ZWdvcnkpID0+IHtcbiAgICBzZXRFZGl0Q2F0ZWdvcnlJZChjYXRlZ29yeS5pZClcbiAgICBzZXRFZGl0Q2F0ZWdvcnlOYW1lKGNhdGVnb3J5Lm5hbWUpXG4gICAgc2V0RWRpdENhdGVnb3J5RGVzY3JpcHRpb24oY2F0ZWdvcnkuZGVzY3JpcHRpb24gfHwgJycpXG4gICAgc2V0RWRpdENhdGVnb3J5UGFyZW50KGNhdGVnb3J5LnBhcmVudElkKVxuICAgIHNldFNob3dFZGl0Q2F0ZWdvcnlNb2RhbCh0cnVlKVxuICB9XG5cbiAgY29uc3QgaGFuZGxlVXBkYXRlQ2F0ZWdvcnkgPSBhc3luYyAoKSA9PiB7XG4gICAgaWYgKCFlZGl0Q2F0ZWdvcnlOYW1lLnRyaW0oKSkge1xuICAgICAgc2V0RXJyb3IoJ0NhdGVnb3J5IG5hbWUgaXMgcmVxdWlyZWQnKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGF4aW9zLnB1dChgL2FwaS9wcm9kdWN0LWNhdGVnb3JpZXMvJHtlZGl0Q2F0ZWdvcnlJZH1gLCB7XG4gICAgICAgIG5hbWU6IGVkaXRDYXRlZ29yeU5hbWUudHJpbSgpLFxuICAgICAgICBkZXNjcmlwdGlvbjogZWRpdENhdGVnb3J5RGVzY3JpcHRpb24udHJpbSgpIHx8IG51bGwsXG4gICAgICAgIHBhcmVudElkOiBlZGl0Q2F0ZWdvcnlQYXJlbnQsXG4gICAgICB9KVxuXG4gICAgICBzZXRTaG93RWRpdENhdGVnb3J5TW9kYWwoZmFsc2UpXG4gICAgICBhd2FpdCBmZXRjaENhdGVnb3JpZXMoKVxuICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdFcnJvciB1cGRhdGluZyBjYXRlZ29yeTonLCBlcnIpXG4gICAgICBzZXRFcnJvcihlcnIucmVzcG9uc2U/LmRhdGE/LmVycm9yIHx8ICdGYWlsZWQgdG8gdXBkYXRlIGNhdGVnb3J5JylcbiAgICB9XG4gIH1cblxuICBjb25zdCBoYW5kbGVEZWxldGVDYXRlZ29yeSA9IGFzeW5jIChpZDogbnVtYmVyKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGF4aW9zLmRlbGV0ZShgL2FwaS9wcm9kdWN0LWNhdGVnb3JpZXMvJHtpZH1gKVxuICAgICAgYXdhaXQgZmV0Y2hDYXRlZ29yaWVzKClcbiAgICAgIHNldERlbGV0ZUNvbmZpcm1JZChudWxsKVxuICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBkZWxldGluZyBjYXRlZ29yeTonLCBlcnIpXG4gICAgICBzZXRFcnJvcihlcnIucmVzcG9uc2U/LmRhdGE/LmVycm9yIHx8ICdGYWlsZWQgdG8gZGVsZXRlIGNhdGVnb3J5JylcbiAgICB9XG4gIH1cblxuICBjb25zdCBoYW5kbGVEcmFnU3RhcnQgPSAoZXZlbnQ6IERyYWdTdGFydEV2ZW50KSA9PiB7XG4gICAgc2V0QWN0aXZlSWQoZXZlbnQuYWN0aXZlLmlkIGFzIG51bWJlcilcbiAgfVxuXG4gIGNvbnN0IGhhbmRsZURyYWdPdmVyID0gKGV2ZW50OiBEcmFnT3ZlckV2ZW50KSA9PiB7XG4gICAgY29uc3QgeyBhY3RpdmUsIG92ZXIgfSA9IGV2ZW50XG5cbiAgICBpZiAoIW92ZXIgfHwgIWFjdGl2ZSkge1xuICAgICAgc2V0T3ZlcklkKG51bGwpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBhY3RpdmVJZCA9IGFjdGl2ZS5pZCBhcyBudW1iZXJcbiAgICBjb25zdCBvdmVySWQgPSBvdmVyLmlkIGFzIG51bWJlclxuXG4gICAgLy8gRG9uJ3QgYWxsb3cgZHJvcHBpbmcgb24gaXRzZWxmXG4gICAgaWYgKGFjdGl2ZUlkID09PSBvdmVySWQpIHtcbiAgICAgIHNldE92ZXJJZChudWxsKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gRG9uJ3QgYWxsb3cgZHJvcHBpbmcgb24gb3duIGNoaWxkcmVuICh3b3VsZCBjcmVhdGUgY2lyY3VsYXIgcmVmZXJlbmNlKVxuICAgIGNvbnN0IGFjdGl2ZUNhdGVnb3J5ID0gZmxhdENhdGVnb3JpZXMuZmluZCgoY2F0KSA9PiBjYXQuaWQgPT09IGFjdGl2ZUlkKVxuICAgIGlmIChhY3RpdmVDYXRlZ29yeSAmJiBpc0Rlc2NlbmRhbnRPZihvdmVySWQsIGFjdGl2ZUlkKSkge1xuICAgICAgc2V0T3ZlcklkKG51bGwpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBzZXRPdmVySWQob3ZlcklkKVxuICB9XG5cbiAgY29uc3QgaXNEZXNjZW5kYW50T2YgPSAoY2F0ZWdvcnlJZDogbnVtYmVyLCBhbmNlc3RvcklkOiBudW1iZXIpOiBib29sZWFuID0+IHtcbiAgICBjb25zdCBjYXRlZ29yeSA9IGZsYXRDYXRlZ29yaWVzLmZpbmQoKGNhdCkgPT4gY2F0LmlkID09PSBjYXRlZ29yeUlkKVxuICAgIGlmICghY2F0ZWdvcnkgfHwgIWNhdGVnb3J5LnBhcmVudElkKSByZXR1cm4gZmFsc2VcblxuICAgIGlmIChjYXRlZ29yeS5wYXJlbnRJZCA9PT0gYW5jZXN0b3JJZCkgcmV0dXJuIHRydWVcbiAgICByZXR1cm4gaXNEZXNjZW5kYW50T2YoY2F0ZWdvcnkucGFyZW50SWQsIGFuY2VzdG9ySWQpXG4gIH1cblxuICBjb25zdCBoYW5kbGVEcmFnRW5kID0gYXN5bmMgKGV2ZW50OiBEcmFnRW5kRXZlbnQpID0+IHtcbiAgICBjb25zdCB7IGFjdGl2ZSwgb3ZlciB9ID0gZXZlbnRcbiAgICBzZXRBY3RpdmVJZChudWxsKVxuICAgIHNldE92ZXJJZChudWxsKVxuXG4gICAgaWYgKCFvdmVyIHx8IGFjdGl2ZS5pZCA9PT0gb3Zlci5pZCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgYWN0aXZlSWQgPSBhY3RpdmUuaWQgYXMgbnVtYmVyXG4gICAgY29uc3Qgb3ZlcklkID0gb3Zlci5pZCBhcyBudW1iZXJcblxuICAgIGNvbnN0IGFjdGl2ZUNhdGVnb3J5ID0gZmxhdENhdGVnb3JpZXMuZmluZCgoY2F0KSA9PiBjYXQuaWQgPT09IGFjdGl2ZUlkKVxuICAgIGNvbnN0IG92ZXJDYXRlZ29yeSA9IGZsYXRDYXRlZ29yaWVzLmZpbmQoKGNhdCkgPT4gY2F0LmlkID09PSBvdmVySWQpXG5cbiAgICBpZiAoIWFjdGl2ZUNhdGVnb3J5IHx8ICFvdmVyQ2F0ZWdvcnkpIHtcbiAgICAgIHJldHVyblxuICAgI
643H1cblxuICAgIC8vIERvbid0IGFsbG93IGRyb3BwaW5nIG9uIG93biBjaGlsZHJlblxuICAgIGlmIChpc0Rlc2NlbmRhbnRPZihvdmVySWQsIGFjdGl2ZUlkKSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgbGV0IG5ld1BhcmVudElkOiBudW1iZXIgfCBudWxsXG4gICAgbGV0IG5ld09yZGVyOiBudW1iZXJcblxuICAgIC8vIERldGVybWluZSBpZiB3ZSdyZSBkcm9wcGluZyBhcyBhIGNoaWxkIG9yIHNpYmxpbmdcbiAgICBjb25zdCBzaG91bGRCZWNvbWVDaGlsZCA9IGV2ZW50LmRlbHRhLnggPiAyMCAvLyBEcmFnIHJpZ2h0IHRvIG1ha2UgY2hpbGRcblxuICAgIGlmIChzaG91bGRCZWNvbWVDaGlsZCkge1xuICAgICAgLy8gTWFrZSBpdCBhIGNoaWxkIG9mIHRoZSBvdmVyIGNhdGVnb3J5XG4gICAgICBuZXdQYXJlbnRJZCA9IG92ZXJJZFxuICAgICAgLy8gRmluZCBjaGlsZHJlbiBjb3VudCB0byBzZXQgb3JkZXJcbiAgICAgIGNvbnN0IGNoaWxkcmVuQ291bnQgPSBmbGF0Q2F0ZWdvcmllcy5maWx0ZXIoKGNhdCkgPT4gY2F0LnBhcmVudElkID09PSBvdmVySWQpLmxlbmd0aFxuICAgICAgbmV3T3JkZXIgPSBjaGlsZHJlbkNvdW50XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE1ha2UgaXQgYSBzaWJsaW5nIG9mIHRoZSBvdmVyIGNhdGVnb3J5XG4gICAgICBuZXdQYXJlbnRJZCA9IG92ZXJDYXRlZ29yeS5wYXJlbnRJZFxuICAgICAgLy8gRmluZCBwb3NpdGlvbiBhbW9uZyBzaWJsaW5nc1xuICAgICAgY29uc3Qgc2libGluZ3MgPSBmbGF0Q2F0ZWdvcmllcy5maWx0ZXIoKGNhdCkgPT4gY2F0LnBhcmVudElkID09PSBuZXdQYXJlbnRJZClcbiAgICAgIGNvbnN0IG92ZXJJbmRleCA9IHNpYmxpbmdzLmZpbmRJbmRleCgoY2F0KSA9PiBjYXQuaWQgPT09IG92ZXJJZClcbiAgICAgIG5ld09yZGVyID0gb3ZlckluZGV4ICsgMVxuICAgIH1cblxuICAgIC8vIFVwZGF0ZSBsb2NhbCBzdGF0ZSBpbW1lZGlhdGVseSBmb3IgdmlzdWFsIGZlZWRiYWNrXG4gICAgY29uc3QgdXBkYXRlZENhdGVnb3JpZXMgPSB1cGRhdGVDYXRlZ29yeUhpZXJhcmNoeShhY3RpdmVJZCwgbmV3UGFyZW50SWQsIG5ld09yZGVyKVxuICAgIGNvbnN0IG5ld1RyZWUgPSBidWlsZENhdGVnb3J5VHJlZSh1cGRhdGVkQ2F0ZWdvcmllcylcbiAgICBzZXRDYXRlZ29yaWVzKG5ld1RyZWUpXG4gICAgc2V0RmxhdENhdGVnb3JpZXMoZmxhdHRlbkNhdGVnb3JpZXMobmV3VHJlZSkpXG5cbiAgICAvLyBQcmVwYXJlIHVwZGF0ZSBmb3IgdGhlIGJhY2tlbmRcbiAgICBjb25zdCB1cGRhdGUgPSB7XG4gICAgICBpZDogYWN0aXZlSWQsXG4gICAgICBwYXJlbnRJZDogbmV3UGFyZW50SWQsXG4gICAgICBvcmRlcjogbmV3T3JkZXIsXG4gICAgfVxuXG4gICAgc2V0UGVuZGluZ1VwZGF0ZXMoKHByZXYpID0+IHtcbiAgICAgIGNvbnN0IGZpbHRlcmVkID0gcHJldi5maWx0ZXIoKHUpID0+IHUuaWQgIT09IGFjdGl2ZUlkKVxuICAgICAgcmV0dXJuIFsuLi5maWx0ZXJlZCwgdXBkYXRlXVxuICAgIH0pXG4gIH1cblxuICBjb25zdCB1cGRhdGVDYXRlZ29yeUhpZXJhcmNoeSA9IChcbiAgICBjYXRlZ29yeUlkOiBudW1iZXIsXG4gICAgbmV3UGFyZW50SWQ6IG51bWJlciB8IG51bGwsXG4gICAgbmV3T3JkZXI6IG51bWJlclxuICApOiBGbGF0Q2F0ZWdvcnlbXSA9PiB7XG4gICAgLy8gR2V0IGFsbCBjYXRlZ29yaWVzIHdpdGggdGhlIHNhbWUgcGFyZW50IGFzIHRoZSB0YXJnZXQgcG9zaXRpb25cblxuICAgIHJldHVybiBmbGF0Q2F0ZWdvcmllcy5tYXAoKGNhdCkgPT4ge1xuICAgICAgaWYgKGNhdC5pZCA9PT0gY2F0ZWdvcnlJZCkge1xuICAgICAgICAvLyBVcGRhdGUgdGhlIG1vdmVkIGNhdGVnb3J5XG4gICAgICAgIHJldHVybiB7IC4uLmNhdCwgcGFyZW50SWQ6IG5ld1BhcmVudElkLCBvcmRlcjogbmV3T3JkZXIgfVxuICAgICAgfSBlbHNlIGlmIChjYXQucGFyZW50SWQgPT09IG5ld1BhcmVudElkKSB7XG4gICAgICAgIC8vIFVwZGF0ZSBzaWJsaW5nIGNhdGVnb3JpZXMnIG9yZGVyIHZhbHVlc1xuICAgICAgICBpZiAoY2F0Lm9yZGVyID49IG5ld09yZGVyKSB7XG4gICAgICAgICAgcmV0dXJuIHsgLi4uY2F0LCBvcmRlcjogY2F0Lm9yZGVyICsgMSB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBjYXRcbiAgICB9KVxuICB9XG5cbiAgY29uc3QgYnVpbGRDYXRlZ29yeVRyZWUgPSAoZmxhdENhdHM6IEZsYXRDYXRlZ29yeVtdKTogUHJvZHVjdENhdGVnb3J5W10gPT4ge1xuICAgIGNvbnN0IGNhdGVnb3J5TWFwID0gbmV3IE1hcDxudW1iZXIsIFByb2R1Y3RDYXRlZ29yeT4oKVxuICAgIGNvbnN0IHJvb3RDYXRlZ29yaWVzOiBQcm9kdWN0Q2F0ZWdvcnlbXSA9IFtdXG5cbiAgICAvLyBGaXJzdCBwYXNzOiBjcmVhdGUgYWxsIGNhdGVnb3JpZXNcbiAgICBmbGF0Q2F0cy5mb3JFYWNoKChjYXQpID0+IHtcbiAgICAgIGNhdGVnb3J5TWFwLnNldChjYXQuaWQsIHtcbiAgICAgICAgaWQ6IGNhdC5pZCxcbiAgICAgICAgbmFtZTogY2F0Lm5hbWUsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBjYXQuZGVzY3JpcHRpb24sXG4gICAgICAgIHBhcmVudElkOiBjYXQucGFyZW50SWQsXG4gICAgICAgIG9yZGVyOiBjYXQub3JkZXIsXG4gICAgICAgIGNyZWF0ZWRBdDogY2F0LmNyZWF0ZWRBdCxcbiAgICAgICAgdXBkYXRlZEF0OiBjYXQudXBkYXRlZEF0LFxuICAgICAgICBjaGlsZHJlbjogW10sXG4gICAgICB9KVxuICAgIH0pXG5cbiAgICAvLyBTZWNvbmQgcGFzczogYnVpbGQgaGllcmFyY2h5XG4gICAgZmxhdENhdHMuZm9yRWFjaCgoY2F0KSA9PiB7XG4gICAgICBjb25zdCBjYXRlZ29yeSA9IGNhdGVnb3J5TWFwLmdldChjYXQuaWQpIVxuXG4gICAgICBpZiAoY2F0LnBhcmVudElkID09PSBudWxsKSB7XG4gICAgICAgIHJvb3RDYXRlZ29yaWVzLnB1c2goY2F0ZWdvcnkpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBwYXJlbnQgPSBjYXRlZ29yeU1hcC5nZXQoY2F0LnBhcmVudElkKVxuICAgICAgICBpZiAocGFyZW50KSB7XG4gICAgICAgICAgcGFyZW50LmNoaWxkcmVuID0gcGFyZW50LmNoaWxkcmVuIHx8IFtdXG4gICAgICAgICAgcGFyZW50LmNoaWxkcmVuLnB1c2goY2F0ZWdvcnkpXG4gICAgICAgI
643H1cbiAgICAgIH1cbiAgICB9KVxuXG4gICAgLy8gU29ydCBjaGlsZHJlbiBieSBvcmRlclxuICAgIGNvbnN0IHNvcnRCeU9yZGVyID0gKGNhdHM6IFByb2R1Y3RDYXRlZ29yeVtdKSA9PiB7XG4gICAgICBjYXRzLnNvcnQoKGEsIGIpID0+IChhLm9yZGVyIHx8IDApIC0gKGIub3JkZXIgfHwgMCkpXG4gICAgICBjYXRzLmZvckVhY2goKGNhdCkgPT4ge1xuICAgICAgICBpZiAoY2F0LmNoaWxkcmVuICYmIGNhdC5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgc29ydEJ5T3JkZXIoY2F0LmNoaWxkcmVuKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cblxuICAgIHNvcnRCeU9yZGVyKHJvb3RDYXRlZ29yaWVzKVxuICAgIHJldHVybiByb290Q2F0ZWdvcmllc1xuICB9XG5cbiAgY29uc3QgaGFuZGxlU2F2ZVJlb3JkZXIgPSBhc3luYyAoKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIHNldExvYWRpbmcodHJ1ZSlcblxuICAgICAgLy8gU2VuZCBhbGwgcGVuZGluZyB1cGRhdGVzIHRvIHRoZSBiYWNrZW5kXG4gICAgICBmb3IgKGNvbnN0IHVwZGF0ZSBvZiBwZW5kaW5nVXBkYXRlcykge1xuICAgICAgICBhd2FpdCBheGlvcy5wdXQoYC9hcGkvcHJvZHVjdC1jYXRlZ29yaWVzLyR7dXBkYXRlLmlkfWAsIHtcbiAgICAgICAgICBwYXJlbnRJZDogdXBkYXRlLnBhcmVudElkLFxuICAgICAgICAgIG9yZGVyOiB1cGRhdGUub3JkZXIsXG4gICAgICAgIH0pXG4gICAgICB9XG5cbiAgICAgIHNldFBlbmRpbmdVcGRhdGVzKFtdKVxuICAgICAgc2V0SXNSZW9yZGVyTW9kZShmYWxzZSlcbiAgICAgIGF3YWl0IGZldGNoQ2F0ZWdvcmllcygpXG4gICAgfSBjYXRjaCAoZXJyOiBhbnkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNhdmluZyByZW9yZGVyOicsIGVycilcbiAgICAgIHNldEVycm9yKGVyci5yZXNwb25zZT8uZGF0YT8uZXJyb3IgfHwgJ0ZhaWxlZCB0byBzYXZlIG5ldyBvcmRlcicpXG4gICAgICAvLyBSZXZlcnQgY2hhbmdlcyBvbiBlcnJvclxuICAgICAgYXdhaXQgZmV0Y2hDYXRlZ29yaWVzKClcbiAgICB9IGZpbmFsbHkge1xuICAgICAgc2V0TG9hZGluZyhmYWxzZSlcbiAgICB9XG4gIH1cblxuICBjb25zdCBoYW5kbGVDYW5jZWxSZW9yZGVyID0gKCkgPT4ge1xuICAgIHNldElzUmVvcmRlck1vZGUoZmFsc2UpXG4gICAgc2V0UGVuZGluZ1VwZGF0ZXMoW10pXG4gICAgc2V0Q2F0ZWdvcmllcyhvcmlnaW5hbENhdGVnb3JpZXMpXG4gICAgc2V0RmxhdENhdGVnb3JpZXMob3JpZ2luYWxGbGF0Q2F0ZWdvcmllcylcbiAgfVxuXG4gIGNvbnN0IGdldEFsbENhdGVnb3JpZXNGbGF0ID0gKGNhdHM6IFByb2R1Y3RDYXRlZ29yeVtdKTogUHJvZHVjdENhdGVnb3J5W10gPT4ge1xuICAgIGNvbnN0IHJlc3VsdDogUHJvZHVjdENhdGVnb3J5W10gPSBbXVxuXG4gICAgY29uc3QgdHJhdmVyc2UgPSAoY2F0ZWdvcmllczogUHJvZHVjdENhdGVnb3J5W10pID0+IHtcbiAgICAgIGNhdGVnb3JpZXMuZm9yRWFjaCgoY2F0KSA9PiB7XG4gICAgICAgIHJlc3VsdC5wdXNoKGNhdClcbiAgICAgICAgaWYgKGNhdC5jaGlsZHJlbiAmJiBjYXQuY2hpbGRyZW4ubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHRyYXZlcnNlKGNhdC5jaGlsZHJlbilcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9XG5cbiAgICB0cmF2ZXJzZShjYXRzKVxuICAgIHJldHVybiByZXN1bHRcbiAgfVxuXG4gIGNvbnN0IGFjdGl2ZUNhdGVnb3J5ID0gYWN0aXZlSWQgPyBmbGF0Q2F0ZWdvcmllcy5maW5kKChjYXQpID0+IGNhdC5pZCA9PT0gYWN0aXZlSWQpIDogbnVsbFxuXG4gIGlmIChsb2FkaW5nICYmIGNhdGVnb3JpZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiY29udGFpbmVyIG14LWF1dG8gcHgtNCBweS04XCI+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwidGV4dC1jZW50ZXIgcHktMTBcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImFuaW1hdGUtc3BpbiBoLTEwIHctMTAgdGV4dC1ibHVlLTUwMCBteC1hdXRvIG1iLTRcIj5cbiAgICAgICAgICAgIDxzdmcgY2xhc3NOYW1lPVwidy1mdWxsIGgtZnVsbFwiIGZpbGw9XCJub25lXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiPlxuICAgICAgICAgICAgICA8Y2lyY2xlXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwib3BhY2l0eS0yNVwiXG4gICAgICAgICAgICAgICAgY3g9XCIxMlwiXG4gICAgICAgICAgICAgICAgY3k9XCIxMlwiXG4gICAgICAgICAgICAgICAgcj1cIjEwXCJcbiAgICAgICAgICAgICAgICBzdHJva2U9XCJjdXJyZW50Q29sb3JcIlxuICAgICAgICAgICAgICAgIHN0cm9rZVdpZHRoPVwiNFwiXG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwib3BhY2l0eS03NVwiXG4gICAgICAgICAgICAgICAgZmlsbD1cImN1cnJlbnRDb2xvclwiXG4gICAgICAgICAgICAgICAgZD1cIk00IDEyYTggOCAwIDAxOC04VjBDNS4zNzMgMCAwIDUuMzczIDAgMTJoNHptMiA1LjI5MUE3Ljk2MiA3Ljk2MiAwIDAxNCAxMkgwYzAgMy4wNDIgMS4xMzUgNS44MjQgMyA3LjkzOGwzLTIuNjQ3elwiXG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8cCBjbGFzc05hbWU9XCJ0ZXh0LWdyYXktNjAwXCI+TG9hZGluZyBjYXRlZ29yaWVzLi4uPC9wPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIClcbiAgfVxuXG4gIHJldHVybiAoXG4gICAgPGRpdiBjbGFzc05hbWU9XCJjb250YWluZXIgbXgtYXV0byBweC00IHB5LThcIj5cbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwibWItNiBmbGV4IGp1c3RpZnktYmV0d2VlbiBpdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgPGgxIGNsYXNzTmFtZT1cInRleHQtMnhsIGZvbnQtYm9sZCB0ZXh0LWdyYXktODAwXCI+UHJvZHVjdCBDYXRlZ29yaWVzPC9oMT5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJmbGV4IHNwYWNlLXgtM1wiPlxuICAgICAgICAgIHshaXNSZW9yZGVyTW9kZSA/IChcbiAgICAgICAgICAgIDw+XG4gICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiBzZXRTaG93TmV3Q2F0ZWdvcnlNb2RhbCh0cnVlKX1cbiAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJweC00IHB5LTIgIGJnLWdyYXktMzAwIGJvcmRlciBib3JkZXItZ3JheS0zMDAgcm91bmRlZCBob3ZlcjpiZy1ncmF5LTUwXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIEFkZCBOZXcgQ2F0ZWdvcnlcbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8Lz5cbiAgICAgICAgICApIDogKFxuICAgICAgICAgICAgPD5cbiAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgIG9uQ2xpY2s9e2hhbmRsZUNhbmNlbFJlb3JkZXJ9XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwicHgtNCBweS0yIGJnLWdyYXktNTAwIHRleHQtd2hpdGUgcm91bmRlZCBob3ZlcjpiZy1ncmF5LTYwMCB0cmFuc2l0aW9uLWNvbG9yc1wiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICBDYW5jZWxcbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICBvbkNsaWNrPXtoYW5kbGVTYXZlUmVvcmRlcn1cbiAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJweC00IHB5LTIgYmctZ3JlZW4tNTAwIHRleHQtd2hpdGUgcm91bmRlZCBob3ZlcjpiZy1ncmVlbi02MDAgdHJhbnNpdGlvbi1jb2xvcnNcIlxuICAgICAgICAgICAgICAgIGRpc2FibGVkPXtwZW5kaW5nVXBkYXRlcy5sZW5ndGggPT09IDB9XG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICBTYXZlIE9yZGVyICh7cGVuZGluZ1VwZGF0ZXMubGVuZ3RofSBjaGFuZ2VzKVxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvPlxuICAgICAgICAgICl9XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIHtlcnJvciAmJiAoXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibWItNiBiZy1yZWQtMTAwIGJvcmRlciBib3JkZXItcmVkLTQwMCB0ZXh0LXJlZC03MDAgcHgtNCBweS0zIHJvdW5kZWRcIj5cbiAgICAgICAgICA8cD57ZXJyb3J9PC9wPlxuICAgICAgICAgIDxidXR0b24gb25DbGljaz17KCkgPT4gc2V0RXJyb3IobnVsbCl9IGNsYXNzTmFtZT1cIm10LTIgdGV4dC1zbSB1bmRlcmxpbmVcIj5cbiAgICAgICAgICAgIERpc21pc3NcbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICApfVxuXG4gICAgICB7aXNSZW9yZGVyTW9kZSAmJiAoXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibWItNiBiZy15ZWxsb3ctNTAgYm9yZGVyIGJvcmRlci15ZWxsb3ctMjAwIHRleHQteWVsbG93LTgwMCBweC00IHB5LTMgcm91bmRlZFwiPlxuICAgICAgICAgIDxwIGNsYXNzTmFtZT1cImZvbnQtbWVkaXVtXCI+UmVvcmRlciBNb2RlIEFjdGl2ZTwvcD5cbiAgICAgICAgICA8cCBjbGFzc05hbWU9XCJ0ZXh0LXNtIG10LTFcIj5EcmFnIGNhdGVnb3JpZXMgdG8gcmVvcmRlciB0aGVtIG9yIGNoYW5nZSB0aGVpciBwYXJlbnQ6PC9wPlxuICAgICAgICAgIDx1bCBjbGFzc05hbWU9XCJ0ZXh0LXhzIG10LTEgbGlzdC1kaXNjIGxpc3QtaW5zaWRlXCI+XG4gICAgICAgICAgICA8bGk+RHJhZyBzbGlnaHRseSByaWdodCB0byBtYWtlIGEgY2F0ZWdvcnkgYSBjaGlsZCBvZiBhbm90aGVyPC9saT5cbiAgICAgICAgICAgIDxsaT5Ob3JtYWwgZHJhZyB0byBtYWtlIGl0IGEgc2libGluZzwvbGk+XG4gICAgICAgICAgICA8bGk+R3JlZW4gaGlnaGxpZ2h0IHNob3dzIHZhbGlkIGRyb3AgdGFyZ2V0czwvbGk+XG4gICAgICAgICAgPC91bD5cbiAgICAgICAgPC9kaXY+XG4gICAgICApfVxuXG4gICAgICA8RG5kQ29udGV4dFxuICAgICAgICBzZW5zb3JzPXtzZW5zb3JzfVxuICAgICAgICBjb2xsaXNpb25EZXRlY3Rpb249e2Nsb3Nlc3RDZW50ZXJ9XG4gICAgICAgIG9uRHJhZ1N0YXJ0PXtoYW5kbGVEcmFnU3RhcnR9XG4gICAgICAgIG9uRHJhZ092ZXI9e2hhbmRsZURyYWdPdmVyfVxuICAgICAgICBvbkRyYWdFbmQ9e2hhbmRsZURyYWdFbmR9XG4gICAgICA+XG4gICAgICAgIDxTb3J0YWJsZUNvbnRleHRcbiAgICAgICAgICBpdGVtcz17ZmxhdENhdGVnb3JpZXMubWFwKChjYXQpID0+IGNhdC5pZCl9XG4gICAgICAgICAgc3RyYXRlZ3k9e3ZlcnRpY2FsTGlzdFNvcnRpbmdTdHJhdGVneX1cbiAgICAgICAgPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwic3BhY2UteS0yXCI+XG4gICAgICAgICAgICB7ZmxhdENhdGVnb3JpZXMubWFwKChjYXRlZ29yeSkgPT4gKFxuICAgICAgICAgICAgICA8Q2F0ZWdvcnlJdGVtXG4gICAgICAgICAgICAgICAga2V5PXtjYXRlZ29yeS5pZH1cbiAgICAgICAgICAgICAgICBjYXRlZ29yeT17Y2F0ZWdvcnl9XG4gICAgICAgICAgICAgICAgb25FZGl0PXtoYW5kbGVFZGl0Q2xpY2t9XG4gICAgICAgICAgICAgICAgb25EZWxldGU9e3NldERlbGV0ZUNvbmZpcm1JZH1cbiAgICAgICAgICAgICAgICBpc1Jlb3JkZXJNb2RlPXtpc1Jlb3JkZXJNb2RlfVxuICAgICAgICAgICAgICAgIGZsYXRDYXRlZ29yaWVzPXtmbGF0Q2F0ZWdvcmllc31cbiAgICAgICAgICAgICAgICBzZXRGbGF0Q2F0ZWdvcmllcz17c2V0RmxhdENhdGVnb3JpZXN9XG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICApKX1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9Tb3J0YWJsZUNvbnRleHQ+XG5cbiAgICAgICAgPERyYWdPdmVybGF5PlxuICAgICAgICAgI
643HthY3RpdmVDYXRlZ29yeSA/IChcbiAgICAgICAgICAgIDxDYXRlZ29yeUl0ZW1cbiAgICAgICAgICAgICAgY2F0ZWdvcnk9e2FjdGl2ZUNhdGVnb3J5fVxuICAgICAgICAgICAgICBvbkVkaXQ9eygpID0+IHt9fVxuICAgICAgICAgICAgICBvbkRlbGV0ZT17KCkgPT4ge319XG4gICAgICAgICAgICAgIGlzUmVvcmRlck1vZGU9e2lzUmVvcmRlck1vZGV9XG4gICAgICAgICAgICAgIGlzRHJhZ2dpbmc9e3RydWV9XG4gICAgICAgICAgICAgIGZsYXRDYXRlZ29yaWVzPXtmbGF0Q2F0ZWdvcmllc31cbiAgICAgICAgICAgICAgc2V0RmxhdENhdGVnb3JpZXM9e3NldEZsYXRDYXRlZ29yaWVzfVxuICAgICAgICAgICAgLz5cbiAgICAgICAgICApIDogbnVsbH1cbiAgICAgICAgPC9EcmFnT3ZlcmxheT5cbiAgICAgIDwvRG5kQ29udGV4dD5cblxuICAgICAge2ZsYXRDYXRlZ29yaWVzLmxlbmd0aCA9PT0gMCAmJiAhbG9hZGluZyAmJiAoXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwidGV4dC1jZW50ZXIgcHktMTAgYmctZ3JheS01MCByb3VuZGVkLWxnXCI+XG4gICAgICAgICAgPHAgY2xhc3NOYW1lPVwidGV4dC1ncmF5LTUwMFwiPk5vIGNhdGVnb3JpZXMgZm91bmQ8L3A+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgb25DbGljaz17KCkgPT4gc2V0U2hvd05ld0NhdGVnb3J5TW9kYWwodHJ1ZSl9XG4gICAgICAgICAgICBjbGFzc05hbWU9XCJweC00IHB5LTIgIGJnLWdyYXktMzAwIGJvcmRlciBib3JkZXItZ3JheS0zMDAgcm91bmRlZCBob3ZlcjpiZy1ncmF5LTUwXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICBDcmVhdGUgeW91ciBmaXJzdCBjYXRlZ29yeVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICl9XG5cbiAgICAgIHsvKiBOZXcgQ2F0ZWdvcnkgTW9kYWwgKi99XG4gICAgICB7c2hvd05ld0NhdGVnb3J5TW9kYWwgJiYgKFxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImZpeGVkIGluc2V0LTAgYmctYmxhY2sgYmctb3BhY2l0eS01MCBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciB6LTUwXCI+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJiZy13aGl0ZSByb3VuZGVkLWxnIHAtNiB3LWZ1bGwgbWF4LXctbWRcIj5cbiAgICAgICAgICAgIDxoMiBjbGFzc05hbWU9XCJ0ZXh0LXhsIGZvbnQtc2VtaWJvbGQgbWItNFwiPkFkZCBOZXcgQ2F0ZWdvcnk8L2gyPlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJzcGFjZS15LTRcIj5cbiAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8bGFiZWxcbiAgICAgICAgICAgICAgICAgIGh0bWxGb3I9XCJuZXdDYXRlZ29yeU5hbWVcIlxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwiYmxvY2sgdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktNzAwXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICBOYW1lICpcbiAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgICAgaWQ9XCJuZXd
643DYXRlZ29yeU5hbWVcIlxuICAgICAgICAgICAgICAgICAgdmFsdWU9e25ld0NhdGVnb3J5TmFtZX1cbiAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXsoZSkgPT4gc2V0TmV3Q2F0ZWdvcnlOYW1lKGUudGFyZ2V0LnZhbHVlKX1cbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIm10LTEgYmxvY2sgdy1mdWxsIHB4LTMgcHktMiBib3JkZXIgYm9yZGVyLWdyYXktMzAwIHJvdW5kZWQtbWQgZm9jdXM6b3V0bGluZS1ub25lIGZvY3VzOnJpbmctMiBmb2N1czpyaW5nLWJsdWUtNTAwXCJcbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8bGFiZWxcbiAgICAgICAgICAgICAgICAgIGh0bWxGb3I9XCJuZXdDYXRlZ29yeURlc2NyaXB0aW9uXCJcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cImJsb2NrIHRleHQtc20gZm9udC1tZWRpdW0gdGV4dC1ncmF5LTcwMFwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgRGVzY3JpcHRpb25cbiAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgIDx0ZXh0YXJlYVxuICAgICAgICAgICAgICAgICAgaWQ9XCJuZXdDYXRlZ29yeURlc2NyaXB0aW9uXCJcbiAgICAgICAgICAgICAgICAgIHZhbHVlPXtuZXdDYXRlZ29yeURlc2NyaXB0aW9ufVxuICAgICAgICAgICAgICAgICAgb25DaGFuZ2U9eyhlKSA9PiBzZXROZXdDYXRlZ29yeURlc2NyaXB0aW9uKGUudGFyZ2V0LnZhbHVlKX1cbiAgICAgICAgICAgICAgICAgIHJvd3M9ezN9XG4gICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJtdC0xIGJsb2NrIHctZnVsbCBweC0zIHB5LTIgYm9yZGVyIGJvcmRlci1ncmF5LTMwMCByb3VuZGVkLW1kIGZvY3VzOm91dGxpbmUtbm9uZSBmb2N1czpyaW5nLTIgZm9jdXM6cmluZy1ibHVlLTUwMFwiXG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPGxhYmVsXG4gICAgICAgICAgICAgICAgICBodG1sRm9yPVwibmV3Q2F0ZWdvcnlQYXJlbnRcIlxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwiYmxvY2sgdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWdyYXktNzAwXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICBQYXJlbnQgQ2F0ZWdvcnlcbiAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgIDxzZWxlY3RcbiAgICAgICAgICAgICAgICAgIGlkPVwibmV3Q2F0ZWdvcnlQYXJlbnRcIlxuICAgICAgICAgICAgICAgICAgdmFsdWU9e25ld0NhdGVnb3J5UGFyZW50IHx8ICcnfVxuICAgICAgICAgICAgICAgICAgb25DaGFuZ2U9eyhlKSA9PlxuICAgICAgICAgICAgICAgICAgICBzZXROZXdDYXRlZ29yeVBhcmVudChlLnRhcmdldC52YWx1ZSA/IHBhcnNlSW50KGUudGFyZ2V0LnZhbHVlKSA6IG51bGwpXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJtdC0xIGJsb2NrIHctZnVsbCBweC0zIHB5LTIgYm9yZGVyIGJvcmRlci1ncmF5LTMwMCByb3VuZGVkLW1kIGZvY3VzOm91dGxpbmUtbm9uZSBmb2N1czpyaW5nLTIgZm9jdXM6cmluZy1ibHVlLTUwMFwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPk5vIHBhcmVudCAodG9wIGxldmVsKTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAge2dldEFsbENhdGVnb3JpZXNGbGF0KGNhdGVnb3JpZXMpLm1hcCgoY2F0KSA9PiAoXG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24ga2V5PXtjYXQuaWR9IHZhbHVlPXtjYXQuaWR9PlxuICAgICAgICAgICAgICAgICAgICAgIHtjYXQubmFtZX1cbiAgICAgICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICApKX1cbiAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXQtNiBmbGV4IGp1c3RpZnktZW5kIHNwYWNlLXgtM1wiPlxuICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgb25DbGljaz17KCkgPT4ge1xuICAgICAgICAgICAgICAgICAgc2V0U2hvd05ld0NhdGVnb3J5TW9kYWwoZmFsc2UpXG4gICAgICAgICAgICAgICAgICBzZXROZXdDYXRlZ29yeU5hbWUoJycpXG4gICAgICAgICAgICAgICAgICBzZXROZXdDYXRlZ29yeURlc2NyaXB0aW9uKCcnKVxuICAgICAgICAgICAgICAgICAgc2V0TmV3Q2F0ZWdvcnlQYXJlbnQobnVsbClcbiAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cInB4LTQgcHktMiB0ZXh0LWdyYXktNzAwIGJvcmRlciBib3JkZXItZ3JheS0zMDAgcm91bmRlZCBob3ZlcjpiZy1ncmF5LTUwXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIENhbmNlbFxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgIG9uQ2xpY2s9e2hhbmRsZUNyZWF0ZUNhdGVnb3J5fVxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cInB4LTQgcHktMiAgYmctZ3JheS0zMDAgYm9yZGVyIGJvcmRlci1ncmF5LTMwMCByb3VuZGVkIGhvdmVyOmJnLWdyYXktNTBcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgQ3JlYXRlIENhdGVnb3J5XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgKX1cblxuICAgICAgey8qIEVkaXQgQ2F0ZWdvcnkgTW9kYWwgKi99XG4gICAgICB7c2hvd0VkaXRDYXRlZ29yeU1vZGFsICYmIChcbiAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJmaXhlZCBpbnNldC0wIGJnLWJsYWNrIGJnLW9wYWNpdHktNTAgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgei01MFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYmctd2h
643pdGUgcm91bmRlZC1sZyBwLTYgdy1mdWxsIG1heC13LW1kXCI+XG4gICAgICAgICAgICA8aDIgY2xhc3NOYW1lPVwidGV4dC14bCBmb250LXNlbWlib2xkIG1iLTRcIj5FZGl0IENhdGVnb3J5PC9oMj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwic3BhY2UteS00XCI+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPGxhYmVsXG4gICAgICAgICAgICAgICAgICBodG1sRm9yPVwiZWRpdENhdGVnb3J5TmFtZVwiXG4gICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJibG9jayB0ZXh0LXNtIGZvbnQtbWVkaXVtIHRleHQtZ3JheS03MDBcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIE5hbWUgKlxuICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICBpZD1cImVkaXRDYXRlZ29yeU5hbWVcIlxuICAgICAgICAgICAgICAgICAgdmFsdWU9e2VkaXRDYXRlZ29yeU5hbWV9XG4gICAgICAgICAgICAgICAgICBvbkNoYW5nZT17KGUpID0+IHNldEVkaXRDYXRlZ29yeU5hbWUoZS50YXJnZXQudmFsdWUpfVxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXQtMSBibG9jayB3LWZ1bGwgcHgtMyBweS0yIGJvcmRlciBib3JkZXItZ3JheS0zMDAgcm91bmRlZC1tZCBmb2N1czpvdXRsaW5lLW5vbmUgZm9jdXM6cmluZy0yIGZvY3VzOnJpbmctYmx1ZS01MDBcIlxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgIDxsYWJlbFxuICAgICAgICAgICAgICAgICAgaHRtbEZvcj1cImVkaXRDYXRlZ29yeURlc2NyaXB0aW9uXCJcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cImJsb2NrIHRleHQtc20gZm9udC1tZWRpdW0gdGV4dC1ncmF5LTcwMFwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgRGVzY3JpcHRpb25cbiAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgIDx0ZXh0YXJlYVxuICAgICAgICAgICAgICAgICAgaWQ9XCJlZGl0Q2F0ZWdvcnlEZXNjcmlwdGlvblwiXG4gICAgICAgICAgICAgICAgICB2YWx1ZT17ZWRpdENhdGVnb3J5RGVzY3JpcHRpb259XG4gICAgICAgICAgICAgICAgICBvbkNoYW5nZT17KGUpID0+IHNldEVkaXRDYXRlZ29yeURlc2NyaXB0aW9uKGUudGFyZ2V0LnZhbHVlKX1cbiAgICAgICAgICAgICAgICAgIHJvd3M9ezN9XG4gICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJtdC0xIGJsb2NrIHctZnVsbCBweC0zIHB5LTIgYm9yZGVyIGJvcmRlci1ncmF5LTMwMCByb3VuZGVkLW1kIGZvY3VzOm91dGxpbmUtbm9uZSBmb2N1czpyaW5nLTIgZm9jdXM6cmluZy1ibHVlLTUwMFwiXG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPGxhYmVsXG4gICAgICAgICAgICAgICAgICBodG1sRm9yPVwiZWRpdENhdGVnb3J5UGFyZW50XCJcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cImJsb2NrIHRleHQtc20gZm9udC1tZWRpdW0gdGV4dC1ncmF5LTcwMFwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgUGFyZW50IENhdGVnb3J5XG4gICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICA8c2VsZWN0XG4gICAgICAgICAgICAgICAgICBpZD1cImVkaXRDYXRlZ29yeVBhcmVudFwiXG4gICAgICAgICAgICAgICAgICB2YWx1ZT17ZWRpdENhdGVnb3J5UGFyZW50IHx8ICcnfVxuICAgICAgICAgICAgICAgICAgb25DaGFuZ2U9eyhlKSA9PlxuICAgICAgICAgICAgICAgICAgICBzZXRFZGl0Q2F0ZWdvcnlQYXJlbnQoZS50YXJnZXQudmFsdWUgPyBwYXJzZUludChlLnRhcmdldC52YWx1ZSkgOiBudWxsKVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXQtMSBibG9jayB3LWZ1bGwgcHgtMyBweS0yIGJvcmRlciBib3JkZXItZ3JheS0zMDAgcm91bmRlZC1tZCBmb2N1czpvdXRsaW5lLW5vbmUgZm9jdXM6cmluZy0yIGZvY3VzOnJpbmctYmx1ZS01MDBcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj5ObyBwYXJlbnQgKHRvcCBsZXZlbCk8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgIHtnZXRBbGxDYXRlZ29yaWVzRmxhdChjYXRlZ29yaWVzKVxuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKChjYXQpID0+IGNhdC5pZCAhPT0gZWRpdENhdGVnb3J5SWQpXG4gICAgICAgICAgICAgICAgICAgIC5tYXAoKGNhdCkgPT4gKFxuICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24ga2V5PXtjYXQuaWR9IHZhbHVlPXtjYXQuaWR9PlxuICAgICAgICAgICAgICAgICAgICAgICAge2NhdC5uYW1lfVxuICAgICAgICAgICAgICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICApKX1cbiAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXQtNiBmbGV4IGp1c3RpZnktZW5kIHNwYWNlLXgtM1wiPlxuICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgb25DbGljaz17KCkgPT4gc2V0U2hvd0VkaXRDYXRlZ29yeU1vZGFsKGZhbHNlKX1cbiAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJweC00IHB5LTIgdGV4dC1ncmF5LTcwMCBib3JkZXIgYm9yZGVyLWdyYXktMzAwIHJvdW5kZWQgaG92ZXI6YmctZ3JheS01MFwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICBDYW5jZWxcbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICBvbkNsaWNrPXtoYW5kbGVVcGRhdGVDYXRlZ29yeX1cbiAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJweC00IHB5LTIgIGJnLWdyYXktMzAwIGJvcmRlciBib3JkZXItZ3JheS0zMDAgcm91bmRlZCBob3ZlcjpiZy1ncmF5LTUwXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIFVwZGF0ZSBDYXRlZ29yeVxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICl9XG5cbiAgICAgIHsvKiBEZWxldGUgQ29uZmlybWF0aW9uIE1vZGFsICovfVxuICAgICAge2RlbGV0ZUNvbmZpcm1JZCAmJiAoXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZml4ZWQgaW5zZXQtMCBiZy1ibGFjayBiZy1vcGFjaXR5LTUwIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIHotNTBcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImJnLXdoaXRlIHJvdW5kZWQtbGcgcC02IHctZnVsbCBtYXgtdy1tZFwiPlxuICAgICAgICAgICAgPGgyIGNsYXNzTmFtZT1cInRleHQteGwgZm9udC1zZW1pYm9sZCBtYi00XCI+RGVsZXRlIENhdGVnb3J5PC9oMj5cbiAgICAgICAgICAgIDxwIGNsYXNzTmFtZT1cIm1iLTYgdGV4dC1ncmF5LTYwMFwiPlxuICAgICAgICAgICAgICB
643BcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlIHRoaXMgY2F0ZWdvcnk/IFRoaXMgYWN0aW9uIGNhbm5vdCBiZSB1bmRvbmUuXG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImZsZXgganVzdGlmeS1lbmQgc3BhY2UteC0zXCI+XG4gICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiBzZXREZWxldGVDb25maXJtSWQobnVsbCl9XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwicHgtNCBweS0yICBiZy1ncmF5LTMwMCBib3JkZXIgYm9yZGVyLWdyYXktMzAwIHJvdW5kZWQgaG92ZXI6YmctZ3JheS01MFwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICBDYW5jZWxcbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiBoYW5kbGVEZWxldGVDYXRlZ29yeShkZWxldGVDb25maXJtSWQpfVxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cInB4LTQgcHktMiBiZy1yZWQtNTAwIHRleHQtd2hpdGUgcm91bmRlZCBob3ZlcjpiZy1yZWQtNjAwXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIERlbGV0ZVxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICl9XG4gICAgPC9kaXY+XG4gIClcbn1cblxuZXhwb3J0IGRlZmF1bHQgUHJvZHVjdENhdGVnb3JpZXNcbiJdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxTQUFTLFVBQVUsaUJBQWlCO0FBQzNDLE9BQU8sV0FBVztBQUNsQjtBQUFBLEVBQ0U7QUFBQSxFQUdBO0FBQUEsRUFFQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtB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BQ1QsV0FBVTtBQUFBO0FBQUEsSUFDWDtBQUFBLEVBRUQsQ0FDRixDQUNGLENBQ0YsR0FJRCxtQk
643FDQyxvQ0FBQyxTQUFJLFdBQVUsZ0ZBQ2Isb0NBQUMsU0FBSSxXQUFVLDZDQUNiLG9DQUFDLFFBQUcsV0FBVSxnQ0FBNkIsaUJBQWUsR0FDMUQsb0NBQUMsT0FBRSxXQUFVLHdCQUFxQiw4RUFFbEMsR0FDQSxvQ0FBQyxTQUFJLFdBQVUsZ0NBQ2I7QUFBQSxJQUFDO0FBQUE7QUFBQSxNQUNDLFNBQVMsTUFBTSxtQkFBbUIsSUFBSTtBQUFBLE1BQ3RDLFdBQVU7QUFBQTtBQUFBLElBQ1g7QUFBQSxFQUVELEdBQ0E7QUFBQSxJQUFDO0FBQUE7QUFBQSxNQUNDLFNBQVMsTUFBTSxxQkFBcUIsZUFBZTtBQUFBLE1BQ25ELFdBQVU7QUFBQTtBQUFBLElBQ1g7QUFBQSxFQUVELENBQ0YsQ0FDRixDQUNGLENBRUo7QUFFSjtBQUVBLGVBQWU7IiwibmFtZXMiOlsiYWN0aXZlSWQiLCJvdmVySWQiLCJhY3RpdmVDYXRlZ29yeSIsImNhdGVnb3JpZXMiXX0=

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.