@gunjo/ui 0.0.1-alpha.0 → 0.0.1-alpha.2

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.
Files changed (224) hide show
  1. package/LICENSE +21 -0
  2. package/README.ja.md +90 -0
  3. package/README.md +52 -91
  4. package/package.json +47 -6
  5. package/src/components/display/Accordion.tsx +185 -0
  6. package/src/components/display/AccordionGroup.tsx +155 -0
  7. package/src/components/display/ActionDataTable.tsx +413 -0
  8. package/src/components/display/ActivityTimelineCard.tsx +483 -0
  9. package/src/components/display/AnalyticsCard.tsx +167 -0
  10. package/src/components/display/AssetCard.tsx +242 -0
  11. package/src/components/display/AssetGrid.tsx +164 -0
  12. package/src/components/display/Avatar.tsx +127 -0
  13. package/src/components/display/AvatarGroup.tsx +131 -0
  14. package/src/components/{atoms → display}/Badge.tsx +3 -3
  15. package/src/components/display/BarChart.tsx +247 -0
  16. package/src/components/{molecules → display}/Card.tsx +1 -1
  17. package/src/components/display/Carousel.tsx +593 -0
  18. package/src/components/display/ChartLegend.tsx +124 -0
  19. package/src/components/display/ChatMessage.tsx +382 -0
  20. package/src/components/display/ChoroplethMap.tsx +613 -0
  21. package/src/components/display/Code.tsx +42 -0
  22. package/src/components/display/CodeBlock.tsx +338 -0
  23. package/src/components/display/ColorSwatch.tsx +71 -0
  24. package/src/components/display/ConcentricProgressCard.tsx +545 -0
  25. package/src/components/display/DataTable.tsx +522 -0
  26. package/src/components/display/DistributionBar.tsx +102 -0
  27. package/src/components/display/DocNote.tsx +36 -0
  28. package/src/components/display/DonutChart.tsx +257 -0
  29. package/src/components/display/EmptyState.tsx +44 -0
  30. package/src/components/display/FileTree.tsx +180 -0
  31. package/src/components/display/GaugeChart.tsx +219 -0
  32. package/src/components/display/HeatmapChart.tsx +266 -0
  33. package/src/components/display/Icon.tsx +66 -0
  34. package/src/components/display/ImagePreview.tsx +140 -0
  35. package/src/components/{atoms → display}/Img.tsx +46 -12
  36. package/src/components/display/LabeledDonutCard.tsx +475 -0
  37. package/src/components/display/LineChart.tsx +464 -0
  38. package/src/components/{molecules → display}/List.tsx +20 -13
  39. package/src/components/display/MarkdownRenderer.tsx +157 -0
  40. package/src/components/display/MetadataList.tsx +81 -0
  41. package/src/components/display/MiniDistributionBarCard.tsx +314 -0
  42. package/src/components/display/PieChart.tsx +234 -0
  43. package/src/components/display/QuadrantMatrix.tsx +330 -0
  44. package/src/components/display/RadarChart.tsx +335 -0
  45. package/src/components/display/RadialBarChart.tsx +264 -0
  46. package/src/components/display/RetentionCohortCard.tsx +350 -0
  47. package/src/components/display/RibbonChart.tsx +618 -0
  48. package/src/components/display/SearchableAccordion.tsx +270 -0
  49. package/src/components/display/SegmentTimelineCard.tsx +452 -0
  50. package/src/components/display/SegmentedGaugeCard.tsx +607 -0
  51. package/src/components/display/Spacer.tsx +51 -0
  52. package/src/components/display/SparklineChart.tsx +394 -0
  53. package/src/components/display/StackedBarChart.tsx +393 -0
  54. package/src/components/display/Statistic.tsx +70 -0
  55. package/src/components/{molecules → display}/Table.tsx +22 -7
  56. package/src/components/display/Tag.tsx +80 -0
  57. package/src/components/display/TagEditor.tsx +141 -0
  58. package/src/components/display/Timeline.tsx +121 -0
  59. package/src/components/{atoms → display}/ToolPill.tsx +42 -18
  60. package/src/components/display/TreeView.tsx +226 -0
  61. package/src/components/display/chart-tooltip.tsx +423 -0
  62. package/src/components/display/chart-utils.ts +71 -0
  63. package/src/components/display/circular-chart-utils.ts +147 -0
  64. package/src/components/display/generated/default-variant-keys.ts +90 -0
  65. package/src/components/display/generated/variant-keys.ts +169 -0
  66. package/src/components/{atoms → feedback}/Alert.tsx +12 -5
  67. package/src/components/feedback/Banner.tsx +90 -0
  68. package/src/components/{molecules → feedback}/NotificationCenter.tsx +64 -31
  69. package/src/components/feedback/ProgressWidget.tsx +44 -0
  70. package/src/components/{atoms → feedback}/Spinner.tsx +2 -2
  71. package/src/components/{molecules → feedback}/StatusBar.tsx +4 -4
  72. package/src/components/feedback/StatusScreen.tsx +148 -0
  73. package/src/components/{molecules → feedback}/Stepper.tsx +10 -5
  74. package/src/components/feedback/Toast.tsx +108 -0
  75. package/src/components/feedback/ToastProvider.tsx +78 -0
  76. package/src/components/feedback/generated/default-variant-keys.ts +16 -0
  77. package/src/components/feedback/generated/variant-keys.ts +21 -0
  78. package/src/components/generated/component-manifest.ts +1568 -454
  79. package/src/components/generated/component-style-hints.ts +1958 -718
  80. package/src/components/{atoms → inputs}/ButtonVariants.ts +13 -3
  81. package/src/components/inputs/Calendar.tsx +212 -0
  82. package/src/components/inputs/ChatComposer.tsx +75 -0
  83. package/src/components/inputs/ChatInput.tsx +528 -0
  84. package/src/components/{atoms → inputs}/Checkbox.tsx +2 -2
  85. package/src/components/inputs/Combobox.tsx +175 -0
  86. package/src/components/inputs/CopyButton.tsx +187 -0
  87. package/src/components/inputs/DatePicker.tsx +519 -0
  88. package/src/components/inputs/DateRangePicker.tsx +878 -0
  89. package/src/components/inputs/EditableField.tsx +182 -0
  90. package/src/components/{organisms → inputs}/FileUploader.tsx +24 -9
  91. package/src/components/inputs/FilterButton.tsx +163 -0
  92. package/src/components/{molecules → inputs}/Form.tsx +20 -3
  93. package/src/components/{atoms → inputs}/Input.tsx +2 -0
  94. package/src/components/inputs/InputOTP.tsx +75 -0
  95. package/src/components/inputs/Mention.tsx +279 -0
  96. package/src/components/inputs/NumberInput.tsx +109 -0
  97. package/src/components/inputs/PasswordGroup.tsx +138 -0
  98. package/src/components/inputs/PasswordInput.tsx +74 -0
  99. package/src/components/inputs/PasswordRequirementList.tsx +96 -0
  100. package/src/components/inputs/PasswordStrengthMeter.tsx +93 -0
  101. package/src/components/inputs/PhoneInput.tsx +99 -0
  102. package/src/components/inputs/PostalCodeInput.tsx +98 -0
  103. package/src/components/inputs/RangeSlider.tsx +129 -0
  104. package/src/components/inputs/SearchInput.tsx +76 -0
  105. package/src/components/inputs/Select.tsx +39 -0
  106. package/src/components/{atoms → inputs}/Slider.tsx +18 -5
  107. package/src/components/{molecules → inputs}/SortButton.tsx +5 -2
  108. package/src/components/{atoms → inputs}/Switch.tsx +15 -4
  109. package/src/components/inputs/TagInput.tsx +114 -0
  110. package/src/components/{atoms → inputs}/Textarea.tsx +1 -0
  111. package/src/components/inputs/TimePicker.tsx +150 -0
  112. package/src/components/inputs/Toggle.tsx +48 -0
  113. package/src/components/{atoms → inputs}/ToggleGroup.tsx +2 -2
  114. package/src/components/inputs/TooltipButton.tsx +148 -0
  115. package/src/components/inputs/VoiceInputButton.tsx +317 -0
  116. package/src/components/inputs/calendar-holidays.ts +56 -0
  117. package/src/components/inputs/generated/default-variant-keys.ts +32 -0
  118. package/src/components/{atoms → inputs}/generated/variant-keys.ts +19 -27
  119. package/src/components/layout/AspectRatio.tsx +12 -0
  120. package/src/components/layout/AssetInspectorPanel.tsx +416 -0
  121. package/src/components/layout/Cluster.tsx +56 -0
  122. package/src/components/layout/CollapsiblePanelToggle.tsx +94 -0
  123. package/src/components/layout/Container.tsx +43 -0
  124. package/src/components/layout/DeviceFrame.tsx +227 -0
  125. package/src/components/layout/Grid.tsx +65 -0
  126. package/src/components/layout/HStack.tsx +73 -0
  127. package/src/components/{organisms → layout}/InspectorPanel.tsx +6 -5
  128. package/src/components/layout/MarqueeFrame.tsx +158 -0
  129. package/src/components/layout/Resizable.tsx +94 -0
  130. package/src/components/layout/ScrollArea.tsx +71 -0
  131. package/src/components/{organisms → layout}/SpatialCanvas.tsx +12 -7
  132. package/src/components/layout/VStack.tsx +69 -0
  133. package/src/components/layout/generated/default-variant-keys.ts +16 -0
  134. package/src/components/layout/generated/variant-keys.ts +21 -0
  135. package/src/components/{molecules → navigation}/Breadcrumb.tsx +5 -4
  136. package/src/components/navigation/Command.tsx +266 -0
  137. package/src/components/navigation/CommandPalette.tsx +83 -0
  138. package/src/components/navigation/DocumentPager.tsx +171 -0
  139. package/src/components/navigation/Footer.tsx +88 -0
  140. package/src/components/navigation/Header.tsx +80 -0
  141. package/src/components/{molecules → navigation}/Menubar.tsx +45 -12
  142. package/src/components/navigation/NavigationMenu.tsx +128 -0
  143. package/src/components/navigation/PageAside.tsx +84 -0
  144. package/src/components/{molecules → navigation}/Pagination.tsx +60 -7
  145. package/src/components/{organisms → navigation}/RightRail.tsx +1 -1
  146. package/src/components/navigation/Sidebar.tsx +223 -0
  147. package/src/components/navigation/SidebarItem.tsx +160 -0
  148. package/src/components/{molecules → navigation}/Tabs.tsx +2 -2
  149. package/src/components/navigation/TextLink.tsx +71 -0
  150. package/src/components/navigation/generated/default-variant-keys.ts +12 -0
  151. package/src/components/navigation/generated/variant-keys.ts +13 -0
  152. package/src/components/overlay/AIChatInput.tsx +5 -0
  153. package/src/components/overlay/AIChatMessage.tsx +6 -0
  154. package/src/components/overlay/AlertDialog.tsx +145 -0
  155. package/src/components/overlay/ChatPanel.tsx +180 -0
  156. package/src/components/{molecules → overlay}/ContextMenu.tsx +65 -29
  157. package/src/components/{molecules → overlay}/Dialog.tsx +21 -13
  158. package/src/components/overlay/Drawer.tsx +131 -0
  159. package/src/components/{molecules → overlay}/DropdownMenu.tsx +52 -17
  160. package/src/components/overlay/FloatingPanel.tsx +90 -0
  161. package/src/components/overlay/HoverCard.tsx +36 -0
  162. package/src/components/overlay/MediaLightbox.tsx +403 -0
  163. package/src/components/overlay/MediaPickerDialog.tsx +198 -0
  164. package/src/components/overlay/Modal.tsx +103 -0
  165. package/src/components/overlay/OnboardingFlow.tsx +172 -0
  166. package/src/components/overlay/Popover.tsx +36 -0
  167. package/src/components/overlay/ShareModal.tsx +324 -0
  168. package/src/components/{molecules → overlay}/Sheet.tsx +76 -19
  169. package/src/components/overlay/Tooltip.tsx +130 -0
  170. package/src/components/overlay/generated/default-variant-keys.ts +14 -0
  171. package/src/components/overlay/generated/variant-keys.ts +17 -0
  172. package/src/components/patterns/BlogTemplate.tsx +46 -0
  173. package/src/components/{templates → patterns}/DashboardTemplate.tsx +2 -2
  174. package/src/components/patterns/DocsTemplate.tsx +41 -0
  175. package/src/components/{templates → patterns}/MediaLibraryTemplate.tsx +1 -1
  176. package/src/components/patterns/OnboardingTemplate.tsx +32 -0
  177. package/src/components/patterns/PricingTemplate.tsx +106 -0
  178. package/src/globals.css +173 -22
  179. package/src/index.ts +177 -76
  180. package/tailwind-theme-extend.cjs +48 -3
  181. package/design/atoms-metadata.json +0 -82
  182. package/design/molecules-metadata.json +0 -130
  183. package/design/organisms-metadata.json +0 -38
  184. package/design/templates-metadata.json +0 -38
  185. package/src/components/atoms/Avatar.tsx +0 -57
  186. package/src/components/atoms/Select.tsx +0 -28
  187. package/src/components/atoms/generated/default-variant-keys.ts +0 -36
  188. package/src/components/molecules/AIChatInput.tsx +0 -140
  189. package/src/components/molecules/AIChatMessage.tsx +0 -109
  190. package/src/components/molecules/Accordion.tsx +0 -99
  191. package/src/components/molecules/Calendar.tsx +0 -60
  192. package/src/components/molecules/Carousel.tsx +0 -261
  193. package/src/components/molecules/Command.tsx +0 -152
  194. package/src/components/molecules/FilterButton.tsx +0 -133
  195. package/src/components/molecules/HoverCard.tsx +0 -29
  196. package/src/components/molecules/Modal.tsx +0 -66
  197. package/src/components/molecules/Popover.tsx +0 -31
  198. package/src/components/molecules/ProgressWidget.tsx +0 -40
  199. package/src/components/molecules/Resizable.tsx +0 -47
  200. package/src/components/molecules/ScrollArea.tsx +0 -48
  201. package/src/components/molecules/SidebarItem.tsx +0 -134
  202. package/src/components/molecules/Toast.tsx +0 -57
  203. package/src/components/molecules/Tooltip.tsx +0 -30
  204. package/src/components/molecules/generated/default-variant-keys.ts +0 -22
  205. package/src/components/molecules/generated/variant-keys.ts +0 -33
  206. package/src/components/organisms/CommandPalette.tsx +0 -58
  207. package/src/components/organisms/FloatingPanel.tsx +0 -46
  208. package/src/components/organisms/ShareModal.tsx +0 -182
  209. package/src/components/organisms/ToastProvider.tsx +0 -49
  210. /package/src/components/{atoms → display}/Kbd.tsx +0 -0
  211. /package/src/components/{atoms → display}/Separator.tsx +0 -0
  212. /package/src/components/{atoms → display}/Skeleton.tsx +0 -0
  213. /package/src/components/{atoms → feedback}/Progress.tsx +0 -0
  214. /package/src/components/{atoms → inputs}/Button.tsx +0 -0
  215. /package/src/components/{atoms → inputs}/Label.tsx +0 -0
  216. /package/src/components/{atoms → inputs}/RadioGroup.tsx +0 -0
  217. /package/src/components/{organisms → navigation}/AppRail.tsx +0 -0
  218. /package/src/components/{templates → patterns}/AuthTemplate.tsx +0 -0
  219. /package/src/components/{templates → patterns}/BannalyzeTemplate.tsx +0 -0
  220. /package/src/components/{templates → patterns}/ChatTemplate.tsx +0 -0
  221. /package/src/components/{templates → patterns}/EditorTemplate.tsx +0 -0
  222. /package/src/components/{templates → patterns}/KanbanTemplate.tsx +0 -0
  223. /package/src/components/{templates → patterns}/LandingTemplate.tsx +0 -0
  224. /package/src/components/{templates → patterns}/SettingsTemplate.tsx +0 -0
@@ -1,182 +0,0 @@
1
- "use client"
2
- import React, { useState, useEffect } from 'react';
3
- import { createPortal } from 'react-dom';
4
- import { X, Copy, Globe, Lock, Check, ExternalLink } from 'lucide-react';
5
- import { cn } from '../../lib/utils';
6
-
7
- export interface ShareData {
8
- isPublic: boolean;
9
- token?: string;
10
- accessCount?: number;
11
- createdAt?: string;
12
- }
13
-
14
- export interface ShareableItem {
15
- id: string;
16
- share?: ShareData;
17
- [key: string]: any;
18
- }
19
-
20
- interface ShareModalProps {
21
- isOpen: boolean;
22
- onClose: () => void;
23
- item: ShareableItem;
24
- onUpdate: (id: string, updates: Partial<ShareableItem>) => void;
25
- apiEndpoint?: string; // Allow customizing API endpoint
26
- }
27
-
28
- export const ShareModal = ({ isOpen, onClose, item, onUpdate, apiEndpoint = '/api/share' }: ShareModalProps) => {
29
- const [isPublic, setIsPublic] = useState(item.share?.isPublic || false);
30
- const [isLoading, setIsLoading] = useState(false);
31
- const [copied, setCopied] = useState(false);
32
- const [shareData, setShareData] = useState<ShareData | undefined>(item.share);
33
- const [mounted, setMounted] = useState(false);
34
-
35
- useEffect(() => {
36
- setMounted(true);
37
- }, []);
38
-
39
- useEffect(() => {
40
- setIsPublic(item.share?.isPublic || false);
41
- setShareData(item.share);
42
- }, [item.id, item.share]);
43
-
44
- if (!isOpen || !mounted) return null;
45
-
46
- const handleToggleShare = async () => {
47
- setIsLoading(true);
48
- try {
49
- const res = await fetch(apiEndpoint, {
50
- method: 'POST',
51
- headers: { 'Content-Type': 'application/json' },
52
- body: JSON.stringify({
53
- id: item.id,
54
- enable: !isPublic
55
- })
56
- });
57
-
58
- if (res.ok) {
59
- const json = await res.json();
60
- setIsPublic(!isPublic);
61
- setShareData(json.share);
62
- // Optimistic update for parent
63
- onUpdate(item.id, { share: json.share });
64
- }
65
- } catch (error) {
66
- console.error('Failed to toggle share', error);
67
- } finally {
68
- setIsLoading(false);
69
- }
70
- };
71
-
72
- const shareUrl = shareData?.token
73
- ? `${window.location.origin}/share/${shareData.token}`
74
- : '';
75
-
76
- const handleCopy = () => {
77
- if (shareUrl) {
78
- navigator.clipboard.writeText(shareUrl);
79
- setCopied(true);
80
- setTimeout(() => setCopied(false), 2000);
81
- }
82
- };
83
-
84
- return createPortal(
85
- <div className="fixed inset-0 z-50 flex items-center justify-center bg-overlay/50 backdrop-blur-sm animate-in fade-in duration-200" onClick={(e) => { e.stopPropagation(); onClose(); }}>
86
- <div className="bg-background border border-border rounded-xl shadow-2xl w-[448px] w-full max-w-md overflow-hidden animate-in zoom-in-95 duration-200" onClick={e => e.stopPropagation()}>
87
- {/* Header */}
88
- <div className="flex items-center justify-between px-4 py-3 border-b border-border bg-muted/50">
89
- <h3 className="text-sm font-semibold text-foreground flex items-center gap-2">
90
- <Globe size={16} className="text-primary" />
91
- Share Image
92
- </h3>
93
- <button onClick={onClose} className="text-muted-foreground hover:text-foreground transition-colors">
94
- <X size={18} />
95
- </button>
96
- </div>
97
-
98
- {/* Content */}
99
- <div className="p-6 space-y-6">
100
-
101
- {/* Toggle Switch */}
102
- <div className="flex items-center justify-between">
103
- <div className="space-y-1">
104
- <div className="text-sm font-medium text-foreground">Public Link</div>
105
- <div className="text-xs text-muted-foreground">
106
- {isPublic
107
- ? "Anyone with the link can view this image."
108
- : "Only you can view this image."}
109
- </div>
110
- </div>
111
-
112
- <button
113
- onClick={handleToggleShare}
114
- disabled={isLoading}
115
- className={cn(
116
- "relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background",
117
- isPublic ? "bg-primary" : "bg-muted",
118
- isLoading && "opacity-50 cursor-not-allowed"
119
- )}
120
- >
121
- <span
122
- className={cn(
123
- "inline-block h-4 w-4 transform rounded-full bg-background transition-transform",
124
- isPublic ? "translate-x-6" : "translate-x-1"
125
- )}
126
- />
127
- </button>
128
- </div>
129
-
130
- {/* URL Display */}
131
- {isPublic && shareData && (
132
- <div className="space-y-2 animate-in slide-in-from-top-2 duration-200">
133
- <label className="text-xs font-medium text-muted-foreground">Public URL</label>
134
- <div className="flex items-center gap-2">
135
- <div className="flex-1 bg-muted border border-border rounded-md px-3 py-2 text-xs text-muted-foreground font-mono truncate select-all">
136
- {shareUrl}
137
- </div>
138
- <button
139
- onClick={handleCopy}
140
- className="p-2 bg-background hover:bg-muted text-muted-foreground rounded-md transition-colors border border-border"
141
- title="Copy to clipboard"
142
- >
143
- {copied ? <Check size={16} className="text-primary" /> : <Copy size={16} />}
144
- </button>
145
- <a
146
- href={shareUrl}
147
- target="_blank"
148
- rel="noopener noreferrer"
149
- className="p-2 bg-background hover:bg-muted text-muted-foreground rounded-md transition-colors border border-border"
150
- title="Open in new tab"
151
- >
152
- <ExternalLink size={16} />
153
- </a>
154
- </div>
155
-
156
- {/* Stats */}
157
- <div className="flex items-center gap-4 pt-2">
158
- <div className="flex items-center gap-1.5 text-xs text-muted-foreground">
159
- <Globe size={12} />
160
- <span>Access Count: <span className="text-foreground font-mono">{shareData.accessCount || 0}</span></span>
161
- </div>
162
- <div className="flex items-center gap-1.5 text-xs text-muted-foreground">
163
- <Lock size={12} />
164
- <span>Token: <span className="text-foreground font-mono">{shareData.token?.slice(0, 8)}...</span></span>
165
- </div>
166
- </div>
167
- </div>
168
- )}
169
-
170
- {!isPublic && (
171
- <div className="flex flex-col items-center justify-center py-4 text-muted-foreground space-y-2 border-2 border-dashed border-border rounded-lg bg-muted/50">
172
- <Lock size={24} />
173
- <span className="text-xs">Sharing is disabled</span>
174
- </div>
175
- )}
176
-
177
- </div>
178
- </div>
179
- </div>,
180
- document.body
181
- );
182
- };
@@ -1,49 +0,0 @@
1
- "use client"
2
- import React, { createContext, useContext, useState, useCallback } from 'react';
3
- import { Toast, ToastType } from '../molecules/Toast';
4
-
5
- interface ToastContextType {
6
- showToast: (message: string, type: ToastType, duration?: number) => void;
7
- }
8
-
9
- const ToastContext = createContext<ToastContextType | undefined>(undefined);
10
-
11
- export const ToastProvider = ({ children }: { children: React.ReactNode }) => {
12
- const [toasts, setToasts] = useState<{ id: number, message: string, type: ToastType, duration: number, isVisible: boolean }[]>([]);
13
-
14
- const showToast = useCallback((message: string, type: ToastType, duration = 3000) => {
15
- const id = Date.now();
16
- setToasts(prev => [...prev, { id, message, type, duration, isVisible: true }]);
17
- }, []);
18
-
19
- const closeToast = useCallback((id: number) => {
20
- setToasts(prev => prev.map(t => t.id === id ? { ...t, isVisible: false } : t));
21
- setTimeout(() => {
22
- setToasts(prev => prev.filter(t => t.id !== id));
23
- }, 300);
24
- }, []);
25
-
26
- return (
27
- <ToastContext.Provider value={{ showToast }}>
28
- {children}
29
- <div className="fixed top-6 right-6 z-[100] flex flex-col items-center w-[320px] gap-2 pointer-events-none">
30
- {toasts.map(toast => (
31
- <Toast
32
- key={toast.id}
33
- message={toast.message}
34
- type={toast.type}
35
- isVisible={toast.isVisible}
36
- onClose={() => closeToast(toast.id)}
37
- duration={toast.duration}
38
- />
39
- ))}
40
- </div>
41
- </ToastContext.Provider>
42
- );
43
- };
44
-
45
- export const useToast = () => {
46
- const context = useContext(ToastContext);
47
- if (!context) throw new Error('useToast must be used within a ToastProvider');
48
- return context;
49
- };
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes