@ocelescope/ocelot 0.0.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/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # react-components-starter
2
+
3
+ A starter for creating a React component library.
4
+
5
+ ## Development
6
+
7
+ - Install dependencies:
8
+
9
+ ```bash
10
+ npm install
11
+ ```
12
+
13
+ - Run the playground:
14
+
15
+ ```bash
16
+ npm run play
17
+ ```
18
+
19
+ - Run the unit tests:
20
+
21
+ ```bash
22
+ npm run test
23
+ ```
24
+
25
+ - Build the library:
26
+
27
+ ```bash
28
+ npm run build
29
+ ```
package/dist/index.css ADDED
@@ -0,0 +1 @@
1
+ ._79UKFW_test{color:#00f;background-color:red}
@@ -0,0 +1,6 @@
1
+ import * as _ocelescope_core0 from "@ocelescope/core";
2
+
3
+ //#region src/config.d.ts
4
+ declare const _default: _ocelescope_core0.ModuleDefinition;
5
+ //#endregion
6
+ export { _default as default };
package/dist/index.js ADDED
@@ -0,0 +1,1003 @@
1
+ import { defineModule, defineModuleRoute, useCurrentOcel } from "@ocelescope/core";
2
+ import { ActionIcon, Box, Button, Divider, Flex, Group, Input, LoadingOverlay, ScrollArea, SegmentedControl, SimpleGrid, Stack, Table, Tabs, Text } from "@mantine/core";
3
+ import { useE2o, useEventAttributes, useEventCounts, useO2o, useObjectAttributes, useObjectCounts, useOcelotPaginatedEvents, useOcelotPaginatedObjects } from "@ocelescope/api-base";
4
+ import { keepPreviousData } from "@tanstack/react-query";
5
+ import { memo, useCallback, useEffect, useMemo, useState } from "react";
6
+ import { DataTable } from "mantine-datatable";
7
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
+ import { useDebouncedState, useScrollIntoView } from "@mantine/hooks";
9
+ import { ChevronLeftIcon, ChevronRightIcon, DownloadIcon, SearchIcon } from "lucide-react";
10
+ import { BaseEdge, Controls, EdgeLabelRenderer, Handle, MarkerType, Position, ReactFlow, ReactFlowProvider, applyNodeChanges, getSmoothStepPath, getStraightPath, useEdgesState, useInternalNode, useReactFlow } from "@xyflow/react";
11
+ import { saveAs } from "file-saver";
12
+ import { toPng } from "html-to-image";
13
+ import dagre from "@dagrejs/dagre";
14
+ import ELK from "elkjs/lib/elk.bundled.js";
15
+
16
+ //#region src/components/EntityTable.tsx
17
+ const EntityTable = ({ entities, withTimestamp, attributes = [], relations = [], onPageChange, onPageSizeChange, sortStatus, onStartStatusChange }) => {
18
+ const columns = useMemo(() => [
19
+ {
20
+ accessor: "id",
21
+ title: "#",
22
+ sortable: true
23
+ },
24
+ ...withTimestamp ? [{
25
+ accessor: "timestamp",
26
+ title: "date",
27
+ sortable: true
28
+ }] : [],
29
+ ...attributes.map(({ attribute }) => ({
30
+ accessor: attribute,
31
+ sortable: true
32
+ })),
33
+ ...relations.map(({ qualifier, target }) => ({
34
+ accessor: `${qualifier}::${target}`,
35
+ title: `${qualifier} (${target})`
36
+ }))
37
+ ], [
38
+ withTimestamp,
39
+ attributes,
40
+ relations
41
+ ]);
42
+ const records = useMemo(() => entities.items.map((entity) => ({
43
+ ...entity,
44
+ ...entity.attributes,
45
+ ...Object.assign({}, ...Object.entries(entity.relations).map(([qualifierName, entityIds]) => ({ [qualifierName]: entityIds.join(", ") })))
46
+ })), [entities]);
47
+ return /* @__PURE__ */ jsx(DataTable, {
48
+ page: entities.page,
49
+ totalRecords: entities.total_items,
50
+ recordsPerPage: entities.page_size,
51
+ onPageChange,
52
+ withColumnBorders: true,
53
+ columns,
54
+ records,
55
+ recordsPerPageOptions: [
56
+ 20,
57
+ 40,
58
+ 50
59
+ ],
60
+ onRecordsPerPageChange: onPageSizeChange,
61
+ sortStatus: sortStatus ?? {
62
+ columnAccessor: "id",
63
+ direction: "asc"
64
+ },
65
+ onSortStatusChange: onStartStatusChange
66
+ });
67
+ };
68
+ var EntityTable_default = EntityTable;
69
+
70
+ //#endregion
71
+ //#region src/components/SingleLineTabs/SingleLineTabs.tsx
72
+ const SingleLineTabs = ({ setCurrentTab, currentTab, tabs }) => {
73
+ const currentTabIndex = useMemo(() => tabs.findIndex((tab) => tab.value === currentTab), [currentTab, tabs]);
74
+ const { targetRef, scrollableRef, scrollIntoView } = useScrollIntoView({
75
+ axis: "x",
76
+ duration: 0
77
+ });
78
+ const onChangeCurrentTab = useCallback((newTab) => {
79
+ setCurrentTab(newTab);
80
+ scrollIntoView({ alignment: "center" });
81
+ }, [scrollIntoView, setCurrentTab]);
82
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Flex, {
83
+ align: "center",
84
+ justify: "center",
85
+ children: [
86
+ /* @__PURE__ */ jsx(Button, {
87
+ variant: "subtle",
88
+ onClick: () => {
89
+ onChangeCurrentTab(tabs[Math.max(0, currentTabIndex - 1)].value);
90
+ },
91
+ disabled: currentTabIndex === 0,
92
+ children: /* @__PURE__ */ jsx(ChevronLeftIcon, {})
93
+ }),
94
+ /* @__PURE__ */ jsx(ScrollArea, {
95
+ w: "100%",
96
+ scrollbars: false,
97
+ viewportRef: scrollableRef,
98
+ children: /* @__PURE__ */ jsx(Tabs, {
99
+ variant: "default",
100
+ value: currentTab,
101
+ onChange: (newTab) => {
102
+ if (newTab) onChangeCurrentTab(newTab);
103
+ },
104
+ children: /* @__PURE__ */ jsx(Tabs.List, {
105
+ style: {
106
+ flexWrap: "unset",
107
+ minWidth: "max-content"
108
+ },
109
+ grow: true,
110
+ justify: "space-between",
111
+ children: tabs.map((tab) => /* @__PURE__ */ jsx(Tabs.Tab, {
112
+ value: tab.value,
113
+ ref: currentTab === tab.value ? targetRef : void 0,
114
+ children: tab.label
115
+ }, tab.value))
116
+ })
117
+ })
118
+ }),
119
+ /* @__PURE__ */ jsx(Button, {
120
+ variant: "subtle",
121
+ onClick: () => {
122
+ onChangeCurrentTab(tabs[Math.min(tabs.length - 1, currentTabIndex + 1)].value);
123
+ },
124
+ disabled: currentTabIndex === tabs.length - 1,
125
+ children: /* @__PURE__ */ jsx(ChevronRightIcon, {})
126
+ })
127
+ ]
128
+ }) });
129
+ };
130
+ var SingleLineTabs_default = SingleLineTabs;
131
+
132
+ //#endregion
133
+ //#region src/components/EntityPage.tsx
134
+ const EntityPage = ({ type }) => {
135
+ const { id } = useCurrentOcel();
136
+ const areEntitiesEvents = type === "events";
137
+ const { data: entityCounts } = (areEntitiesEvents ? useEventCounts : useObjectCounts)({ ocel_id: id });
138
+ const { data: attributes } = (areEntitiesEvents ? useEventAttributes : useObjectAttributes)({ ocel_id: id });
139
+ const [currentTab, setCurrentTab] = useState("");
140
+ const [page, setPage] = useState(1);
141
+ const [sort, setSort] = useState(void 0);
142
+ const [pageSize, setPageSize] = useState(20);
143
+ const entityNames = useMemo(() => Object.keys(entityCounts ?? {}), [entityCounts]);
144
+ const { data: unfilteredRelations = [] } = (areEntitiesEvents ? useE2o : useO2o)({ ocel_id: id });
145
+ const relations = useMemo(() => {
146
+ return unfilteredRelations.filter(({ source }) => source === currentTab);
147
+ }, [unfilteredRelations, currentTab]);
148
+ const { data: entities } = (areEntitiesEvents ? useOcelotPaginatedEvents : useOcelotPaginatedObjects)({
149
+ ocel_id: id,
150
+ type: currentTab,
151
+ page_size: pageSize,
152
+ page,
153
+ ...sort && {
154
+ sort_by: sort.columnAccessor,
155
+ ascending: sort.direction === "asc"
156
+ }
157
+ }, { query: {
158
+ placeholderData: keepPreviousData,
159
+ staleTime: 5e3
160
+ } });
161
+ useEffect(() => {
162
+ if (!currentTab && entityNames.length > 0) setCurrentTab(entityNames[0]);
163
+ }, [currentTab, entityNames]);
164
+ if (entityNames.length === 0) return null;
165
+ return /* @__PURE__ */ jsxs(Flex, {
166
+ direction: "column",
167
+ h: "100%",
168
+ children: [/* @__PURE__ */ jsx(SingleLineTabs_default, {
169
+ tabs: Object.entries(entityCounts ?? {}).map(([entityName, count]) => ({
170
+ value: entityName,
171
+ label: `${entityName} (${count})`
172
+ })),
173
+ setCurrentTab: (newTab) => {
174
+ setCurrentTab(newTab);
175
+ setPage(1);
176
+ setSort(void 0);
177
+ },
178
+ currentTab: currentTab ?? entityNames[0]
179
+ }), entities && /* @__PURE__ */ jsx(EntityTable_default, {
180
+ entities,
181
+ attributes: attributes?.[currentTab ?? entityNames[0]],
182
+ withTimestamp: type === "events",
183
+ onPageChange: (newPage) => setPage(newPage),
184
+ onPageSizeChange: (newPageSize) => setPageSize(newPageSize),
185
+ relations,
186
+ sortStatus: sort,
187
+ onStartStatusChange: (sortStatus) => setSort(sortStatus)
188
+ })]
189
+ });
190
+ };
191
+ var EntityPage_default = EntityPage;
192
+
193
+ //#endregion
194
+ //#region src/routes/events.tsx
195
+ const EventPage = () => /* @__PURE__ */ jsx(EntityPage_default, { type: "events" });
196
+ var events_default = defineModuleRoute({
197
+ component: EventPage,
198
+ label: "Events",
199
+ name: "events",
200
+ requiresOcel: true
201
+ });
202
+
203
+ //#endregion
204
+ //#region src/routes/objects.tsx
205
+ const ObjectPage = () => /* @__PURE__ */ jsx(EntityPage_default, { type: "objects" });
206
+ var objects_default = defineModuleRoute({
207
+ component: ObjectPage,
208
+ label: "Objects",
209
+ name: "objects",
210
+ requiresOcel: true
211
+ });
212
+
213
+ //#endregion
214
+ //#region src/components/EntityCard.tsx
215
+ const EntityCard = ({ name, count, attributeSummaries = [], relationSummaries = [] }) => {
216
+ return /* @__PURE__ */ jsxs(Flex, {
217
+ w: "100%",
218
+ bd: "1px solid black",
219
+ bg: "white",
220
+ miw: 200,
221
+ mih: 100,
222
+ direction: "column",
223
+ children: [
224
+ /* @__PURE__ */ jsx(Text, {
225
+ fw: 700,
226
+ size: "sm",
227
+ ta: "center",
228
+ py: "4",
229
+ children: `${name} (${count})`
230
+ }),
231
+ /* @__PURE__ */ jsx(Divider, {
232
+ c: "black",
233
+ size: "md"
234
+ }),
235
+ attributeSummaries.length !== 0 && /* @__PURE__ */ jsxs(Table, {
236
+ withRowBorders: false,
237
+ captionSide: "top",
238
+ style: {
239
+ overflow: "hidden",
240
+ textOverflow: "ellipsis"
241
+ },
242
+ children: [/* @__PURE__ */ jsx(Table.Caption, {
243
+ mb: 0,
244
+ children: "Attributes"
245
+ }), /* @__PURE__ */ jsx(Table.Tbody, { children: attributeSummaries.map((attribute) => /* @__PURE__ */ jsxs(Table.Tr, { children: [/* @__PURE__ */ jsxs(Table.Td, { children: [" ", attribute.attribute] }), /* @__PURE__ */ jsx(Table.Td, {
246
+ ta: "end",
247
+ children: attribute.type
248
+ })] }, attribute.attribute)) })]
249
+ }),
250
+ relationSummaries.length !== 0 && /* @__PURE__ */ jsxs(Table, {
251
+ withRowBorders: false,
252
+ captionSide: "top",
253
+ style: {
254
+ overflow: "hidden",
255
+ textOverflow: "ellipsis"
256
+ },
257
+ children: [/* @__PURE__ */ jsx(Table.Caption, {
258
+ mb: 0,
259
+ children: "Relations"
260
+ }), /* @__PURE__ */ jsx(Table.Tbody, { children: relationSummaries.map(({ target, qualifier, min_count, max_count }) => /* @__PURE__ */ jsxs(Table.Tr, { children: [
261
+ /* @__PURE__ */ jsx(Table.Td, { children: target }),
262
+ /* @__PURE__ */ jsx(Table.Td, { children: qualifier ?? "None" }),
263
+ /* @__PURE__ */ jsx(Table.Td, { children: min_count < max_count ? `${min_count}-${max_count}` : min_count })
264
+ ] }, `${target}-${qualifier}`)) })]
265
+ })
266
+ ]
267
+ });
268
+ };
269
+ var EntityCard_default = EntityCard;
270
+
271
+ //#endregion
272
+ //#region src/components/EntityOverview.tsx
273
+ const EntityOverview = ({ attributes, relations, entityCounts, search = "" }) => {
274
+ const relationMap = useMemo(() => {
275
+ return relations.reduce((relationMap$1, currentRelation) => {
276
+ if (currentRelation.source in relationMap$1) relationMap$1[currentRelation.source]?.push(currentRelation);
277
+ else relationMap$1[currentRelation.source] = [currentRelation];
278
+ return relationMap$1;
279
+ }, {});
280
+ }, [relations]);
281
+ return /* @__PURE__ */ jsx(SimpleGrid, {
282
+ cols: {
283
+ base: 1,
284
+ sm: 2,
285
+ md: 4,
286
+ lg: 5
287
+ },
288
+ children: useMemo(() => {
289
+ const toSearch = search.toLowerCase();
290
+ return Object.entries(entityCounts).filter(([event, _]) => event.toLowerCase().includes(search.toLowerCase()) || relationMap[event]?.some(({ target, qualifier }) => target.toLowerCase().includes(toSearch) || qualifier.toLowerCase().includes(toSearch)) || attributes[event]?.some(({ attribute }) => attribute.toLowerCase().includes(toSearch)));
291
+ }, [
292
+ search,
293
+ relationMap,
294
+ entityCounts,
295
+ attributes
296
+ ]).map(([name, count]) => {
297
+ return /* @__PURE__ */ jsx(EntityCard_default, {
298
+ count,
299
+ name,
300
+ attributeSummaries: attributes[name] ?? [],
301
+ relationSummaries: relationMap[name] ?? []
302
+ }, name);
303
+ })
304
+ });
305
+ };
306
+ var EntityOverview_default = EntityOverview;
307
+
308
+ //#endregion
309
+ //#region src/routes/eventOverview.tsx
310
+ const EventOverview = () => {
311
+ const { id } = useCurrentOcel();
312
+ const { data: eventsAttributes = {} } = useEventAttributes({ ocel_id: id });
313
+ const { data: e2o = [] } = useE2o({ ocel_id: id });
314
+ const { data: eventCounts, isLoading: isEventCountsLoading } = useEventCounts({ ocel_id: id });
315
+ const [searchValue, setSearchValue] = useDebouncedState("", 200);
316
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(LoadingOverlay, { visible: isEventCountsLoading }), /* @__PURE__ */ jsxs(Stack, { children: [/* @__PURE__ */ jsx(Input, {
317
+ leftSection: /* @__PURE__ */ jsx(SearchIcon, {}),
318
+ defaultValue: searchValue,
319
+ onChange: (newSearch) => setSearchValue(newSearch.target.value)
320
+ }), eventCounts && /* @__PURE__ */ jsx(EntityOverview_default, {
321
+ relations: e2o,
322
+ entityCounts: eventCounts,
323
+ attributes: eventsAttributes,
324
+ search: searchValue
325
+ })] })] });
326
+ };
327
+ var eventOverview_default = defineModuleRoute({
328
+ component: EventOverview,
329
+ label: "Event Overview",
330
+ name: "eventOverview",
331
+ requiresOcel: true
332
+ });
333
+
334
+ //#endregion
335
+ //#region src/components/Graph/util/getEdgeParams.tsx
336
+ const getRectangleIntersection = (targetNode, sourceNode) => {
337
+ const { width = 0, height = 0 } = sourceNode.measured;
338
+ const sourcePos = sourceNode.internals.positionAbsolute;
339
+ const targetPos = targetNode.internals.positionAbsolute;
340
+ const w = width / 2;
341
+ const h = height / 2;
342
+ const x2 = sourcePos.x + w;
343
+ const y2 = sourcePos.y + h;
344
+ const x1 = targetPos.x + (targetNode.measured.width ?? 0) / 2;
345
+ const y1 = targetPos.y + (targetNode.measured.height ?? 0) / 2;
346
+ const xx1 = (x1 - x2) / (2 * w) - (y1 - y2) / (2 * h);
347
+ const yy1 = (x1 - x2) / (2 * w) + (y1 - y2) / (2 * h);
348
+ const a = 1 / (Math.abs(xx1) + Math.abs(yy1));
349
+ const xx3 = a * xx1;
350
+ const yy3 = a * yy1;
351
+ return {
352
+ x: w * (xx3 + yy3) + x2,
353
+ y: h * (-xx3 + yy3) + y2
354
+ };
355
+ };
356
+ const getCircleIntersection = (source, target) => {
357
+ const sourceX = source.internals.positionAbsolute.x;
358
+ const sourceY = source.internals.positionAbsolute.y;
359
+ const targetX = target.internals.positionAbsolute.x;
360
+ const targetY = target.internals.positionAbsolute.y;
361
+ const radius = (target.measured.width ?? 0) / 2;
362
+ const sourceCenterX = sourceX + (source.measured.width ?? 0) / 2;
363
+ const sourceCenterY = sourceY + (source.measured.height ?? 0) / 2;
364
+ const targetCenterX = targetX + radius;
365
+ const targetCenterY = targetY + radius;
366
+ const dx = targetCenterX - sourceCenterX;
367
+ const dy = targetCenterY - sourceCenterY;
368
+ const angle = Math.atan2(dy, dx);
369
+ return {
370
+ x: targetCenterX - Math.cos(angle) * radius,
371
+ y: targetCenterY - Math.sin(angle) * radius
372
+ };
373
+ };
374
+ function getIntersectionPoint(source, target) {
375
+ if (target.type === "circle") return getCircleIntersection(source, target);
376
+ return getRectangleIntersection(source, target);
377
+ }
378
+ const getEdgePosition = (node, point) => {
379
+ const n = {
380
+ ...node.internals.positionAbsolute,
381
+ ...node
382
+ };
383
+ const nx = Math.round(n.x);
384
+ const ny = Math.round(n.y);
385
+ const px = Math.round(point.x);
386
+ const py = Math.round(point.y);
387
+ if (px <= nx + 1) return Position.Left;
388
+ if (px >= nx + (node.measured.width ?? 0) - 1) return Position.Right;
389
+ if (py <= ny + 1) return Position.Top;
390
+ if (py >= ny + (node.measured.height ?? 0) - 1) return Position.Bottom;
391
+ return Position.Top;
392
+ };
393
+ function getEdgeParams(source, target) {
394
+ const sourceIntersectionPoint = getIntersectionPoint(target, source);
395
+ const targetIntersectionPoint = getIntersectionPoint(source, target);
396
+ const sourcePos = getEdgePosition(source, sourceIntersectionPoint);
397
+ const targetPos = getEdgePosition(target, targetIntersectionPoint);
398
+ return {
399
+ sx: sourceIntersectionPoint.x,
400
+ sy: sourceIntersectionPoint.y,
401
+ tx: targetIntersectionPoint.x,
402
+ ty: targetIntersectionPoint.y,
403
+ sourcePos,
404
+ targetPos
405
+ };
406
+ }
407
+
408
+ //#endregion
409
+ //#region src/components/Graph/edges/BaseEdge.tsx
410
+ const EdgeLabel = ({ transform, label }) => {
411
+ return /* @__PURE__ */ jsx("div", {
412
+ style: {
413
+ position: "absolute",
414
+ fontSize: 10,
415
+ fontWeight: 600,
416
+ padding: "0 2px",
417
+ transform,
418
+ transformOrigin: "center",
419
+ background: "white"
420
+ },
421
+ className: "nodrag nopan",
422
+ children: label
423
+ });
424
+ };
425
+ const customMarkes = ["url('#double-rect')", "url('#rect')"];
426
+ const BaseEdge$1 = ({ labels = [], markerEnd, path, ...rest }) => {
427
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
428
+ /* @__PURE__ */ jsx("svg", {
429
+ style: {
430
+ position: "absolute",
431
+ top: 0,
432
+ left: 0
433
+ },
434
+ children: /* @__PURE__ */ jsxs("defs", { children: [
435
+ /* @__PURE__ */ jsx("marker", {
436
+ id: "rect-end",
437
+ markerWidth: "8",
438
+ markerHeight: "8",
439
+ refX: "8",
440
+ refY: "5",
441
+ orient: "auto",
442
+ children: /* @__PURE__ */ jsx("rect", {
443
+ x: "2",
444
+ y: "2",
445
+ width: "6",
446
+ height: "6",
447
+ fill: "black"
448
+ })
449
+ }),
450
+ /* @__PURE__ */ jsxs("marker", {
451
+ id: "double-rect-end",
452
+ markerWidth: "14",
453
+ markerHeight: "10",
454
+ refX: "12",
455
+ refY: "5",
456
+ orient: "auto",
457
+ children: [/* @__PURE__ */ jsx("rect", {
458
+ x: "2",
459
+ y: "2",
460
+ width: "4",
461
+ height: "6",
462
+ fill: "black"
463
+ }), /* @__PURE__ */ jsx("rect", {
464
+ x: "8",
465
+ y: "2",
466
+ width: "4",
467
+ height: "6",
468
+ fill: "black"
469
+ })]
470
+ }),
471
+ /* @__PURE__ */ jsx("marker", {
472
+ id: "rect",
473
+ markerWidth: "8",
474
+ markerHeight: "8",
475
+ refX: "3",
476
+ refY: "5",
477
+ orient: "auto",
478
+ children: /* @__PURE__ */ jsx("rect", {
479
+ x: "2",
480
+ y: "2",
481
+ width: "6",
482
+ height: "6",
483
+ fill: "black"
484
+ })
485
+ }),
486
+ /* @__PURE__ */ jsxs("marker", {
487
+ id: "double-rect",
488
+ markerWidth: "14",
489
+ markerHeight: "10",
490
+ refX: "2",
491
+ refY: "5",
492
+ orient: "auto",
493
+ children: [/* @__PURE__ */ jsx("rect", {
494
+ x: "2",
495
+ y: "2",
496
+ width: "4",
497
+ height: "6",
498
+ fill: "black"
499
+ }), /* @__PURE__ */ jsx("rect", {
500
+ x: "8",
501
+ y: "2",
502
+ width: "4",
503
+ height: "6",
504
+ fill: "black"
505
+ })]
506
+ }),
507
+ /* @__PURE__ */ jsx("marker", {
508
+ id: "circle",
509
+ markerWidth: "8",
510
+ markerHeight: "8",
511
+ refX: "5",
512
+ refY: "5",
513
+ children: /* @__PURE__ */ jsx("circle", {
514
+ cx: "5",
515
+ cy: "5",
516
+ r: "3",
517
+ fill: "black"
518
+ })
519
+ })
520
+ ] })
521
+ }),
522
+ /* @__PURE__ */ jsx(BaseEdge, {
523
+ path,
524
+ markerEnd: customMarkes.includes(markerEnd ?? "") ? markerEnd?.replace("rect", "rect-end") : markerEnd,
525
+ ...rest
526
+ }),
527
+ /* @__PURE__ */ jsx(EdgeLabelRenderer, { children: labels.map((props, index) => /* @__PURE__ */ jsx(EdgeLabel, { ...props }, index)) })
528
+ ] });
529
+ };
530
+ var BaseEdge_default = BaseEdge$1;
531
+
532
+ //#endregion
533
+ //#region src/components/Graph/edges/FloatingEdge.tsx
534
+ const FloatingEdge = ({ data, source, target, ...props }) => {
535
+ const sourceNode = useInternalNode(source);
536
+ const targetNode = useInternalNode(target);
537
+ if (!sourceNode || !targetNode) return null;
538
+ const { sx, sy, tx, ty } = getEdgeParams(sourceNode, targetNode);
539
+ const [edgePath, labelX, labelY, offsetX, offsetY] = getStraightPath(data?.position ?? {
540
+ sourceX: sx,
541
+ sourceY: sy,
542
+ targetX: tx,
543
+ targetY: ty
544
+ });
545
+ const angle = Math.atan2((sy > ty ? -1 : 1) * offsetY, offsetX) * (180 / Math.PI);
546
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(BaseEdge_default, {
547
+ path: edgePath,
548
+ ...props,
549
+ labels: data?.mid ? [{
550
+ transform: `translate(-50% , -50%) translate(${labelX}px, ${labelY}px) rotate(${angle}deg)`,
551
+ label: data.mid
552
+ }] : []
553
+ }) });
554
+ };
555
+ var FloatingEdge_default = FloatingEdge;
556
+
557
+ //#endregion
558
+ //#region src/components/Graph/edges/LoopEdge.tsx
559
+ const LoopingEdge = ({ data, source, ...props }) => {
560
+ const { position, measured } = useInternalNode(source) ?? {
561
+ position: {
562
+ x: 0,
563
+ y: 0
564
+ },
565
+ measured: { width: 0 }
566
+ };
567
+ const [edgePath, labelX, labelY] = getSmoothStepPath({
568
+ sourceX: position.x,
569
+ sourceY: position.y,
570
+ targetX: position.x + (measured.width ?? 0),
571
+ targetY: position.y,
572
+ sourcePosition: Position.Top,
573
+ targetPosition: Position.Top,
574
+ offset: (data?.offset ?? 0) * 15
575
+ });
576
+ return /* @__PURE__ */ jsx(BaseEdge_default, {
577
+ path: edgePath,
578
+ ...props,
579
+ labels: data?.mid ? [{
580
+ label: data.mid,
581
+ transform: `translate(-50% , -50%) translate(${labelX}px, ${labelY - 10}px)`
582
+ }] : []
583
+ });
584
+ };
585
+ var LoopEdge_default = LoopingEdge;
586
+
587
+ //#endregion
588
+ //#region src/components/Graph/layout/dagre.ts
589
+ const useDagreLayout = () => {
590
+ const { getNodes, setNodes, getEdges, fitView } = useReactFlow();
591
+ return { layout: useCallback(async (options) => {
592
+ const dagreGraph = new dagre.graphlib.Graph();
593
+ dagreGraph.setDefaultEdgeLabel(() => ({}));
594
+ dagreGraph.setGraph(options ?? { rankdir: "TB" });
595
+ const nodes = getNodes();
596
+ for (const node of nodes) dagreGraph.setNode(node.id, {
597
+ width: node.measured?.width,
598
+ height: node.measured?.height
599
+ });
600
+ for (const edge of getEdges()) dagreGraph.setEdge(edge.source, edge.target);
601
+ dagre.layout(dagreGraph);
602
+ setNodes(nodes.map((node) => {
603
+ const { x, y } = dagreGraph.node(node.id);
604
+ return {
605
+ ...node,
606
+ position: {
607
+ x,
608
+ y
609
+ }
610
+ };
611
+ }));
612
+ await fitView();
613
+ }, [
614
+ getNodes,
615
+ getEdges,
616
+ setNodes,
617
+ fitView
618
+ ]) };
619
+ };
620
+
621
+ //#endregion
622
+ //#region src/components/Graph/layout/elk.ts
623
+ const elk = new ELK();
624
+ const useElkLayout = () => {
625
+ const { getNodes, setNodes, setEdges, getEdges, fitView } = useReactFlow();
626
+ const defaultOptions = {
627
+ "elk.algorithm": "layered",
628
+ "elk.direction": "RIGHT",
629
+ "elk.spacing.nodeNode": "100",
630
+ "elk.spacing.edgeNode": "50",
631
+ "elk.spacing.edgeEdge": "40",
632
+ "elk.spacing.componentComponent": "100",
633
+ "elk.layered.spacing.baseValue": "50",
634
+ "elk.layered.spacing.nodeNodeBetweenLayers": "150",
635
+ "elk.edgeRouting": "ORTHOGONAL",
636
+ "elk.layered.nodePlacement.strategy": "NETWORK_SIMPLEX"
637
+ };
638
+ return { layout: useCallback(async (options) => {
639
+ const nodes = getNodes();
640
+ const edges = getEdges();
641
+ const graph = {
642
+ id: "root",
643
+ layoutOptions: defaultOptions,
644
+ children: nodes.map((node) => {
645
+ return {
646
+ id: node.id,
647
+ width: node.measured?.width,
648
+ height: node.measured?.height,
649
+ properties: {},
650
+ layoutOptions: {}
651
+ };
652
+ }),
653
+ edges: getEdges().map((edge) => ({
654
+ id: edge.id,
655
+ sources: [edge.source],
656
+ targets: [edge.target],
657
+ layoutOptions: edge?.data?.["mid"] ? { "elk.edge.minimalLength": edge.data["mid"].toString() } : void 0
658
+ }))
659
+ };
660
+ try {
661
+ const layoutedGraph = await elk.layout(graph);
662
+ setNodes(nodes.map((node) => {
663
+ const elkNode = layoutedGraph.children?.find(({ id }) => id === node.id);
664
+ return {
665
+ ...node,
666
+ position: {
667
+ x: elkNode?.x ?? 0,
668
+ y: elkNode?.y ?? 0
669
+ }
670
+ };
671
+ }));
672
+ setEdges(edges.map((edge) => {
673
+ const elkEdge = layoutedGraph.edges?.find(({ id }) => id === edge.id)?.sections?.[0];
674
+ return {
675
+ ...edge,
676
+ data: {
677
+ ...edge.data,
678
+ ...elkEdge && { position: {
679
+ sourceX: elkEdge.startPoint.x,
680
+ sourceY: elkEdge.startPoint.y,
681
+ targetX: elkEdge.endPoint.x,
682
+ targetY: elkEdge.endPoint.y
683
+ } }
684
+ }
685
+ };
686
+ }));
687
+ fitView();
688
+ } catch (error) {}
689
+ }, [
690
+ setEdges,
691
+ setNodes,
692
+ getNodes,
693
+ getEdges,
694
+ fitView
695
+ ]) };
696
+ };
697
+
698
+ //#endregion
699
+ //#region src/components/Graph/nodes/CircleNode.tsx
700
+ const CircleNode = memo(({ data: { color, label, inner, diameter = 50 } }) => {
701
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
702
+ /* @__PURE__ */ jsx(Handle, {
703
+ type: "source",
704
+ position: Position.Bottom
705
+ }),
706
+ /* @__PURE__ */ jsxs(Box, {
707
+ w: diameter,
708
+ h: diameter,
709
+ style: { position: "relative" },
710
+ children: [/* @__PURE__ */ jsx(Box, {
711
+ w: diameter,
712
+ h: diameter,
713
+ style: {
714
+ borderRadius: "50%",
715
+ backgroundColor: color,
716
+ display: "flex",
717
+ alignItems: "center",
718
+ justifyContent: "center"
719
+ },
720
+ children: inner
721
+ }), /* @__PURE__ */ jsx(Box, {
722
+ size: "xs",
723
+ style: {
724
+ position: "absolute",
725
+ top: "100%",
726
+ left: "50%",
727
+ transform: "translateX(-50%)",
728
+ marginTop: 4,
729
+ whiteSpace: "nowrap"
730
+ },
731
+ children: label
732
+ })]
733
+ }),
734
+ /* @__PURE__ */ jsx(Handle, {
735
+ type: "target",
736
+ position: Position.Top
737
+ })
738
+ ] });
739
+ });
740
+ var CircleNode_default = CircleNode;
741
+
742
+ //#endregion
743
+ //#region src/components/Graph/nodes/RectangleNode.tsx
744
+ var RectangleNode_default = memo(({ data: { color, label, inner } }) => {
745
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
746
+ /* @__PURE__ */ jsx(Handle, {
747
+ type: "source",
748
+ position: Position.Bottom
749
+ }),
750
+ /* @__PURE__ */ jsxs(Box, {
751
+ style: {
752
+ position: "relative",
753
+ display: "inline-block"
754
+ },
755
+ children: [/* @__PURE__ */ jsx(Box, {
756
+ style: {
757
+ backgroundColor: color,
758
+ display: "inline-flex",
759
+ alignItems: "center",
760
+ justifyContent: "center",
761
+ width: "auto",
762
+ height: "auto"
763
+ },
764
+ children: inner
765
+ }), /* @__PURE__ */ jsx(Box, {
766
+ style: {
767
+ position: "absolute",
768
+ top: "100%",
769
+ left: "50%",
770
+ transform: "translateX(-50%)",
771
+ marginTop: 4,
772
+ whiteSpace: "nowrap"
773
+ },
774
+ children: label
775
+ })]
776
+ }),
777
+ /* @__PURE__ */ jsx(Handle, {
778
+ type: "target",
779
+ position: Position.Top
780
+ })
781
+ ] });
782
+ });
783
+
784
+ //#endregion
785
+ //#region src/components/Graph/Graph.module.css?css_module
786
+ const classes = { "test": "_79UKFW_test" };
787
+ var Graph_module_default = classes;
788
+ const _test0 = classes["test"];
789
+
790
+ //#endregion
791
+ //#region src/components/Graph/index.tsx
792
+ const edgeTypes = {
793
+ floating: FloatingEdge_default,
794
+ looping: LoopEdge_default
795
+ };
796
+ const nodeTypes = {
797
+ circle: CircleNode_default,
798
+ rectangle: RectangleNode_default
799
+ };
800
+ const layoutToHook = {
801
+ elk: useElkLayout,
802
+ dagre: useDagreLayout
803
+ };
804
+ const handleDownload = async (fileName) => {
805
+ const flow = document.querySelector(".react-flow__viewport");
806
+ if (!flow) return;
807
+ saveAs(await toPng(flow, { backgroundColor: "white" }), `${fileName}.png`);
808
+ };
809
+ const InnerFlow = ({ initialNodes, initialEdges, layoutOptions = { type: "dagre" } }) => {
810
+ const [nodes, setNodes] = useState(initialNodes.map((node) => ({
811
+ ...node,
812
+ type: node.data.type,
813
+ position: {
814
+ x: 0,
815
+ y: 0
816
+ }
817
+ })));
818
+ const seenLoops = {};
819
+ const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges.map((edge, index) => {
820
+ const type = edge.source === edge.target ? "looping" : "floating";
821
+ if (type === "looping") seenLoops[edge.source] = (seenLoops[edge.source] ?? 0) + 1;
822
+ return {
823
+ ...edge,
824
+ id: `edge_${index}`,
825
+ type,
826
+ ...type === "looping" && { data: {
827
+ ...edge.data,
828
+ offset: seenLoops[edge.source]
829
+ } }
830
+ };
831
+ }));
832
+ const onNodesChange = useCallback((changes) => {
833
+ const positionChange = changes.filter((change) => change.type === "position");
834
+ if (positionChange.length > 0) {
835
+ const movedNodes = positionChange.map((change) => change.id);
836
+ setEdges((edges$1) => edges$1.map((edge) => ({
837
+ ...edge,
838
+ data: {
839
+ ...edge.data,
840
+ position: movedNodes.includes(edge.target) || movedNodes.includes(edge.source) ? void 0 : edge.data?.["position"]
841
+ }
842
+ })));
843
+ }
844
+ setNodes((nds) => applyNodeChanges(changes, nds));
845
+ }, [setEdges]);
846
+ const { layout } = layoutToHook[layoutOptions.type]();
847
+ const hasMeasuredNodes = nodes.some(({ measured }) => !!measured);
848
+ useEffect(() => {
849
+ if (hasMeasuredNodes) layout(layoutOptions?.options);
850
+ }, [
851
+ layout,
852
+ layoutOptions,
853
+ hasMeasuredNodes
854
+ ]);
855
+ return /* @__PURE__ */ jsx(ReactFlow, {
856
+ className: Graph_module_default["test"],
857
+ style: { height: "100%" },
858
+ nodes,
859
+ edges,
860
+ onNodesChange,
861
+ onEdgesChange,
862
+ fitView: true,
863
+ edgeTypes,
864
+ nodeTypes,
865
+ minZoom: .1,
866
+ nodesDraggable: false,
867
+ proOptions: { hideAttribution: true },
868
+ children: /* @__PURE__ */ jsx(Controls, {
869
+ showInteractive: false,
870
+ children: /* @__PURE__ */ jsx(ActionIcon, {
871
+ variant: "transparent",
872
+ onClick: () => handleDownload("ocelot"),
873
+ className: "test",
874
+ children: /* @__PURE__ */ jsx(DownloadIcon, {
875
+ className: "test",
876
+ size: 18
877
+ })
878
+ })
879
+ })
880
+ });
881
+ };
882
+ const Graph = (props) => /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsx(InnerFlow, { ...props }) });
883
+ var Graph_default = Graph;
884
+
885
+ //#endregion
886
+ //#region src/routes/objectOverview.tsx
887
+ const ObjectGraph = () => {
888
+ const { id: ocelId } = useCurrentOcel();
889
+ const { data: o2o } = useO2o({ ocel_id: ocelId });
890
+ const { data: objectAttributes } = useObjectAttributes({ ocel_id: ocelId });
891
+ const { data: objectCounts } = useObjectCounts({ ocel_id: ocelId });
892
+ const [searchValue, setSearchValue] = useDebouncedState("", 200);
893
+ const [vizualization, setVizualization] = useState("graph");
894
+ const nodes = useMemo(() => {
895
+ if (!objectCounts || !objectAttributes) return [];
896
+ return Object.entries(objectCounts).map(([objectName, count]) => ({
897
+ id: objectName,
898
+ data: {
899
+ type: "rectangle",
900
+ inner: /* @__PURE__ */ jsx(EntityCard_default, {
901
+ count,
902
+ name: objectName,
903
+ attributeSummaries: objectAttributes[objectName]
904
+ }, objectName)
905
+ }
906
+ }));
907
+ }, [objectCounts, objectAttributes]);
908
+ return /* @__PURE__ */ jsxs(Stack, {
909
+ w: "100%",
910
+ h: "100%",
911
+ children: [
912
+ /* @__PURE__ */ jsxs(Group, {
913
+ justify: "end",
914
+ children: [vizualization === "cards" && /* @__PURE__ */ jsx(Input, {
915
+ leftSection: /* @__PURE__ */ jsx(SearchIcon, {}),
916
+ defaultValue: searchValue,
917
+ onChange: (newSearch) => setSearchValue(newSearch.target.value)
918
+ }), /* @__PURE__ */ jsx(SegmentedControl, {
919
+ onChange: (newViz) => setVizualization(newViz),
920
+ value: vizualization,
921
+ data: [{
922
+ label: "Graph",
923
+ value: "graph"
924
+ }, {
925
+ label: "Cards",
926
+ value: "cards"
927
+ }]
928
+ })]
929
+ }),
930
+ vizualization === "graph" && o2o && objectAttributes && /* @__PURE__ */ jsx(Graph_default, {
931
+ initialNodes: nodes,
932
+ initialEdges: o2o.map(({ source, target, sum, qualifier }) => ({
933
+ source,
934
+ target,
935
+ markerEnd: { type: MarkerType.ArrowClosed },
936
+ style: { strokeWidth: "2px" },
937
+ data: { mid: `${qualifier} (${sum})` }
938
+ })),
939
+ layoutOptions: {
940
+ type: "elk",
941
+ options: {
942
+ "elk.algorithm": "layered",
943
+ "elk.direction": "RIGHT",
944
+ "elk.spacing.nodeNode": 50,
945
+ "elk.layered.spacing.nodeNodeBetweenLayers": 100
946
+ }
947
+ }
948
+ }, ocelId),
949
+ vizualization === "cards" && objectCounts && /* @__PURE__ */ jsx(EntityOverview_default, {
950
+ entityCounts: objectCounts,
951
+ attributes: objectAttributes ?? {},
952
+ relations: o2o ?? [],
953
+ search: searchValue
954
+ })
955
+ ]
956
+ });
957
+ };
958
+ var objectOverview_default = defineModuleRoute({
959
+ component: ObjectGraph,
960
+ label: "Object Overview",
961
+ name: "objectOverview",
962
+ requiresOcel: true
963
+ });
964
+
965
+ //#endregion
966
+ //#region src/components/OcelotIcon.tsx
967
+ const OcelotIcon = (props) => /* @__PURE__ */ jsxs("svg", {
968
+ xmlns: "http://www.w3.org/2000/svg",
969
+ width: 128,
970
+ height: 128,
971
+ viewBox: "0 0 96 96",
972
+ ...props,
973
+ fill: "currentColor",
974
+ children: [
975
+ /* @__PURE__ */ jsx("title", { children: "Ocelot" }),
976
+ /* @__PURE__ */ jsx("path", { d: "M2.5 8.2c-2.2 5.6-2.3 18-.2 23 .9 2.1 2.7 5.3 4.1 7.1C8.2 40.6 8.6 42 8 43c-2 3.2-1.1 9.1 2.4 14.8 1.9 3.2 4 8.4 4.6 11.7 1.6 8 2.9 9.9 9.4 12.8 3 1.4 7.1 4.2 9.1 6.1l3.6 3.6h21.8l3.6-3.6c2-1.9 6-4.7 8.9-6 3-1.4 5.9-3.1 6.6-3.9.6-.8 2-4.9 3.1-9.1 1.1-4.3 3.3-9.9 4.9-12.4 3.1-4.8 4-10.9 2-14-.6-1-.2-2.4 1.6-4.7 1.4-1.8 3.2-5 4.1-7.1 2.1-5 2-17.4-.2-23C91.8 4.1 91.7 4 87 4c-5.6 0-12 2.1-17.3 5.6-3.9 2.5-3.9 2.5-7.5.7-2.9-1.4-6-1.8-14.2-1.8s-11.3.4-14.2 1.8c-3.6 1.8-3.6 1.8-7.5-.7C21 6.1 14.6 4 9 4c-4.7 0-4.8.1-6.5 4.2zM19 11.1c2.5 1.1 6.1 3.3 8.2 4.9 3.2 2.6 3.8 2.8 4.9 1.4 2.9-3.5 7.3-4.8 15.9-4.8 6.9 0 9.3.4 12.8 2.2 2.3 1.2 4.2 2.7 4.2 3.3 0 .5 1.7-.4 3.8-2 4.3-3.5 11.1-6.7 16.3-7.6 3.6-.7 3.7-.6 4.9 3.1 3 8.9.5 19.7-5.9 25.8l-2.9 2.8 1.9 3.2c2.5 4.2 2.4 6.5-.6 10.7-1.4 1.9-3.3 5.8-4.1 8.6-.9 2.9-1.8 5.3-2.1 5.3-.9 0 .6-8.1 2.8-14.6 1.9-5.6 1.9-6.3.5-9.7-1.6-4-2.7-4.5-4.6-2.2-1 1.2-1 1.8 0 3 1.3 1.6 1.1 3.8-1.5 12.5-.9 3.3-1.4 8.3-1.3 12.5l.3 7-4.9 2.8c-2.7 1.5-5.1 2.5-5.4 2.2-.2-.2.7-1.8 2.2-3.5 2.2-2.7 2.6-4.1 2.6-9.5 0-7.6-.9-10.1-5.5-16.2-4.5-5.8-4.6-8.1-.5-7.5 1.9.3 4.3-.4 6.6-1.7 2-1.2 3.9-1.9 4.2-1.7.5.6 3.1-2.4 3.2-3.5 0-1.1-7.9-3.9-11.1-3.9-7.1 0-11.8 5.6-10.5 12.5.4 1.9 2.3 5.6 4.3 8.2 5.5 7.2 6.6 17.9 2.2 21.9-1.4 1.3-2.6 1.4-5.6.7-3.5-.8-3.8-1.1-4.1-4.8-.3-3.7 0-4.1 2.8-5.2 2.3-.9 3-1.7 3-3.9 0-2.5-.1-2.6-1.7-1.2-2.2 1.8-10.4 1.8-12.6-.1-1.5-1.2-1.7-1-1.7 1.4 0 2.1.7 2.9 3 3.8 2.8 1.1 3.1 1.5 2.8 5.2-.3 3.7-.6 4-4.1 4.8-3.3.8-4.2.6-5.9-1.1-1.7-1.7-2.1-3.2-2-8.8.1-4.3.7-7.4 1.7-8.8 5.1-6.9 7.5-11.3 7.5-13.7C43 38.5 38.5 34 32.1 34 28.9 34 21 36.8 21 37.9c.1 1.1 2.7 4.1 3.2 3.5.3-.2 2.2.5 4.2 1.7 2.3 1.3 4.7 2 6.6 1.7 4.1-.6 4 1.7-.5 7.5-4.6 6.1-5.5 8.6-5.5 16.2 0 5.4.4 6.8 2.6 9.5 1.5 1.7 2.4 3.3 2.2 3.5-.3.3-2.7-.7-5.4-2.2l-4.9-2.8.3-7.7c.2-5.6-.2-9.2-1.8-13.7-2.3-6.9-2.5-9.2-.8-10.9.8-.8.8-1.5-.2-2.7-1.9-2.3-3-1.8-4.6 2.2-1.4 3.4-1.4 4.1.5 9.7 2.2 6.5 3.7 14.6 2.8 14.6-.3 0-1.2-2.4-2.1-5.3-.8-2.8-2.7-6.7-4.1-8.6-3-4.2-3.1-6.5-.6-10.7l1.9-3.2-2.9-2.8C5.5 31.3 3 20.5 6 11.6c1.2-3.7 1.3-3.8 4.9-3.1 2 .4 5.6 1.5 8.1 2.6zm39.2 72.8C60.6 86.3 56.3 88 48 88c-12.3 0-15-4.2-4.2-6.5 5.1-1.1 12.2 0 14.4 2.4z" }),
977
+ /* @__PURE__ */ jsx("path", { d: "M8.6 15.1c-1.3 6.8.1 13.2 4 17.9l2.6 3 2.7-4.2c1.5-2.4 4.3-5.8 6.1-7.7 3.3-3.2 3.3-3.4 1.4-4.8-2.5-1.9-13.6-7.3-15-7.3-.6 0-1.4 1.4-1.8 3.1zm8.9 4.1c3.1 1.4 3.1 2.5.2 6.2-2.8 3.4-4.4 2.9-5.3-1.9-1-5.3.4-6.5 5.1-4.3zM78.5 14.9c-3.3 1.6-6.9 3.6-7.9 4.4-1.9 1.4-1.9 1.6 1.4 4.8 1.8 1.9 4.6 5.3 6.1 7.7l2.7 4.2 2.6-3c2.5-3.1 4.6-8.7 4.6-12.6 0-4-1.2-8.4-2.4-8.4-.6 0-3.8 1.3-7.1 2.9zm5.2 7.2c-.8 6.1-2.3 7-5.3 3.4-1.3-1.7-2.4-3.5-2.4-4.1 0-1.3 3.7-3.2 6.4-3.3 1.6-.1 1.8.4 1.3 4z" })
978
+ ]
979
+ });
980
+ var OcelotIcon_default = OcelotIcon;
981
+
982
+ //#endregion
983
+ //#region src/config.ts
984
+ var config_default = defineModule({
985
+ name: "ocelot",
986
+ description: "A tool for exploring object-centric event logs, allowing yout to search events and objects and visualize their relationships and attributes.",
987
+ label: "Ocelot",
988
+ authors: [{ name: "Öztürk, Görkem-Emre" }],
989
+ routes: [
990
+ events_default,
991
+ objects_default,
992
+ eventOverview_default,
993
+ objectOverview_default
994
+ ],
995
+ icon: OcelotIcon_default
996
+ });
997
+
998
+ //#endregion
999
+ //#region src/index.ts
1000
+ var src_default = config_default;
1001
+
1002
+ //#endregion
1003
+ export { src_default as default };
@@ -0,0 +1 @@
1
+ .test{color:red;background-color:red}.floating-edges{width:100%;height:100vh;margin:1rem}.react-flow__handle{opacity:0}
@@ -0,0 +1 @@
1
+ import "@xyflow/react/dist/style.css";
@@ -0,0 +1 @@
1
+ import "@xyflow/react/dist/style.css";
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@ocelescope/ocelot",
3
+ "type": "module",
4
+ "version": "0.0.0",
5
+ "description": "A module for inspections of OCELs",
6
+ "author": "Görkem-Emre Öztürk <goerkem.oeztuerk@rwth-aachen.de>",
7
+ "license": "MIT",
8
+ "homepage": "https://www.ocelescope.org",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/promi4s/ocelescope.git"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/promi4s/ocelescope/issues"
15
+ },
16
+ "exports": {
17
+ ".": "./dist/index.js",
18
+ "./package.json": "./package.json",
19
+ "./styles": "./dist/styles/styles.js"
20
+ },
21
+ "main": "./dist/index.js",
22
+ "module": "./dist/index.js",
23
+ "types": "./dist/index.d.ts",
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "peerDependencies": {
31
+ "@dagrejs/dagre": "^2.0.4",
32
+ "@mantine/core": "^8.3.14",
33
+ "@mantine/hooks": "^8.3.14",
34
+ "@tanstack/react-query": "^5.90.21",
35
+ "@xyflow/react": "^12.10.1",
36
+ "file-saver": "^2.0.5",
37
+ "html-to-image": "^1.11.13",
38
+ "lucide-react": "^0.563.0",
39
+ "mantine-datatable": "^8.3.13",
40
+ "react": "^19.2.0",
41
+ "react-dom": "^19.2.0",
42
+ "@ocelescope/core": "0.0.0",
43
+ "@ocelescope/api-base": "0.0.0"
44
+ },
45
+ "devDependencies": {
46
+ "@tsconfig/strictest": "^2.0.8",
47
+ "@types/file-saver": "^2.0.7",
48
+ "@types/node": "^25.0.3",
49
+ "@types/react": "^19.2.7",
50
+ "@types/react-dom": "^19.2.3",
51
+ "tsdown": "^0.18.1",
52
+ "typescript": "^5.9.3"
53
+ },
54
+ "dependencies": {
55
+ "elkjs": "^0.11.0"
56
+ },
57
+ "scripts": {
58
+ "build": "tsdown",
59
+ "dev": "tsdown --watch",
60
+ "typecheck": "tsc --noEmit"
61
+ }
62
+ }