@moontra/moonui-pro 2.0.22 → 2.0.23

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 (96) hide show
  1. package/package.json +2 -1
  2. package/src/__tests__/use-intersection-observer.test.tsx +216 -0
  3. package/src/__tests__/use-local-storage.test.tsx +174 -0
  4. package/src/__tests__/use-pro-access.test.tsx +183 -0
  5. package/src/components/advanced-chart/advanced-chart.test.tsx +281 -0
  6. package/src/components/advanced-chart/index.tsx +412 -0
  7. package/src/components/advanced-forms/index.tsx +431 -0
  8. package/src/components/animated-button/index.tsx +202 -0
  9. package/src/components/calendar/event-dialog.tsx +372 -0
  10. package/src/components/calendar/index.tsx +531 -0
  11. package/src/components/color-picker/index.tsx +434 -0
  12. package/src/components/dashboard/index.tsx +334 -0
  13. package/src/components/data-table/data-table.test.tsx +187 -0
  14. package/src/components/data-table/index.tsx +368 -0
  15. package/src/components/draggable-list/index.tsx +100 -0
  16. package/src/components/enhanced/button.tsx +360 -0
  17. package/src/components/enhanced/card.tsx +272 -0
  18. package/src/components/enhanced/dialog.tsx +248 -0
  19. package/src/components/enhanced/index.ts +3 -0
  20. package/src/components/error-boundary/index.tsx +111 -0
  21. package/src/components/file-upload/file-upload.test.tsx +242 -0
  22. package/src/components/file-upload/index.tsx +362 -0
  23. package/src/components/floating-action-button/index.tsx +209 -0
  24. package/src/components/github-stars/index.tsx +414 -0
  25. package/src/components/health-check/index.tsx +441 -0
  26. package/src/components/hover-card-3d/index.tsx +170 -0
  27. package/src/components/index.ts +76 -0
  28. package/src/components/kanban/index.tsx +436 -0
  29. package/src/components/lazy-component/index.tsx +342 -0
  30. package/src/components/magnetic-button/index.tsx +170 -0
  31. package/src/components/memory-efficient-data/index.tsx +352 -0
  32. package/src/components/optimized-image/index.tsx +427 -0
  33. package/src/components/performance-debugger/index.tsx +591 -0
  34. package/src/components/performance-monitor/index.tsx +775 -0
  35. package/src/components/pinch-zoom/index.tsx +172 -0
  36. package/src/components/rich-text-editor/index-old-backup.tsx +443 -0
  37. package/src/components/rich-text-editor/index.tsx +1537 -0
  38. package/src/components/rich-text-editor/slash-commands-extension.ts +220 -0
  39. package/src/components/rich-text-editor/slash-commands.css +35 -0
  40. package/src/components/rich-text-editor/table-styles.css +65 -0
  41. package/src/components/spotlight-card/index.tsx +194 -0
  42. package/src/components/swipeable-card/index.tsx +100 -0
  43. package/src/components/timeline/index.tsx +333 -0
  44. package/src/components/ui/animated-button.tsx +185 -0
  45. package/src/components/ui/avatar.tsx +135 -0
  46. package/src/components/ui/badge.tsx +225 -0
  47. package/src/components/ui/button.tsx +221 -0
  48. package/src/components/ui/card.tsx +141 -0
  49. package/src/components/ui/checkbox.tsx +256 -0
  50. package/src/components/ui/color-picker.tsx +95 -0
  51. package/src/components/ui/dialog.tsx +332 -0
  52. package/src/components/ui/dropdown-menu.tsx +200 -0
  53. package/src/components/ui/hover-card-3d.tsx +103 -0
  54. package/src/components/ui/index.ts +33 -0
  55. package/src/components/ui/input.tsx +219 -0
  56. package/src/components/ui/label.tsx +26 -0
  57. package/src/components/ui/magnetic-button.tsx +129 -0
  58. package/src/components/ui/popover.tsx +183 -0
  59. package/src/components/ui/select.tsx +273 -0
  60. package/src/components/ui/separator.tsx +140 -0
  61. package/src/components/ui/slider.tsx +351 -0
  62. package/src/components/ui/spotlight-card.tsx +119 -0
  63. package/src/components/ui/switch.tsx +83 -0
  64. package/src/components/ui/tabs.tsx +195 -0
  65. package/src/components/ui/textarea.tsx +25 -0
  66. package/src/components/ui/toast.tsx +313 -0
  67. package/src/components/ui/tooltip.tsx +152 -0
  68. package/src/components/virtual-list/index.tsx +369 -0
  69. package/src/hooks/use-chart.ts +205 -0
  70. package/src/hooks/use-data-table.ts +182 -0
  71. package/src/hooks/use-docs-pro-access.ts +13 -0
  72. package/src/hooks/use-license-check.ts +65 -0
  73. package/src/hooks/use-subscription.ts +19 -0
  74. package/src/index.ts +11 -0
  75. package/src/lib/micro-interactions.ts +255 -0
  76. package/src/lib/utils.ts +6 -0
  77. package/src/patterns/login-form/index.tsx +276 -0
  78. package/src/patterns/login-form/types.ts +67 -0
  79. package/src/setupTests.ts +41 -0
  80. package/src/styles/design-system.css +365 -0
  81. package/src/styles/index.css +4 -0
  82. package/src/styles/tailwind.css +6 -0
  83. package/src/styles/tokens.css +453 -0
  84. package/src/types/moonui.d.ts +22 -0
  85. package/src/use-intersection-observer.tsx +154 -0
  86. package/src/use-local-storage.tsx +71 -0
  87. package/src/use-paddle.ts +138 -0
  88. package/src/use-performance-optimizer.ts +379 -0
  89. package/src/use-pro-access.ts +141 -0
  90. package/src/use-scroll-animation.ts +221 -0
  91. package/src/use-subscription.ts +37 -0
  92. package/src/use-toast.ts +32 -0
  93. package/src/utils/chart-helpers.ts +257 -0
  94. package/src/utils/cn.ts +69 -0
  95. package/src/utils/data-processing.ts +151 -0
  96. package/src/utils/license-validator.tsx +183 -0
@@ -0,0 +1,182 @@
1
+ "use client"
2
+
3
+ import React from 'react'
4
+ import { ColumnDef } from '@tanstack/react-table'
5
+
6
+ export interface UseDataTableOptions<TData> {
7
+ data: TData[]
8
+ columns: ColumnDef<TData, any>[]
9
+ searchable?: boolean
10
+ filterable?: boolean
11
+ sortable?: boolean
12
+ pagination?: boolean
13
+ pageSize?: number
14
+ enableRowSelection?: boolean
15
+ enableMultiRowSelection?: boolean
16
+ }
17
+
18
+ export interface UseDataTableReturn<TData> {
19
+ // Table state
20
+ filteredData: TData[]
21
+ selectedRows: TData[]
22
+ searchQuery: string
23
+ currentPage: number
24
+ totalPages: number
25
+
26
+ // Actions
27
+ setSearchQuery: (query: string) => void
28
+ setCurrentPage: (page: number) => void
29
+ selectRow: (row: TData) => void
30
+ selectAllRows: () => void
31
+ clearSelection: () => void
32
+ exportData: (format?: 'csv' | 'json') => void
33
+
34
+ // Utilities
35
+ getRowCount: () => number
36
+ getSelectedCount: () => number
37
+ isRowSelected: (row: TData) => boolean
38
+ }
39
+
40
+ export function useDataTable<TData extends Record<string, any>>(
41
+ options: UseDataTableOptions<TData>
42
+ ): UseDataTableReturn<TData> {
43
+ const {
44
+ data,
45
+ searchable = true,
46
+ pageSize = 10,
47
+ enableRowSelection = false,
48
+ enableMultiRowSelection = true,
49
+ } = options
50
+
51
+ const [searchQuery, setSearchQuery] = React.useState('')
52
+ const [currentPage, setCurrentPage] = React.useState(1)
53
+ const [selectedRows, setSelectedRows] = React.useState<TData[]>([])
54
+
55
+ // Filter data based on search query
56
+ const filteredData = React.useMemo(() => {
57
+ if (!searchable || !searchQuery.trim()) {
58
+ return data
59
+ }
60
+
61
+ return data.filter((row) => {
62
+ return Object.values(row).some((value) => {
63
+ if (value == null) return false
64
+ return String(value).toLowerCase().includes(searchQuery.toLowerCase())
65
+ })
66
+ })
67
+ }, [data, searchQuery, searchable])
68
+
69
+ // Calculate pagination
70
+ const totalPages = Math.ceil(filteredData.length / pageSize)
71
+ const paginatedData = React.useMemo(() => {
72
+ const startIndex = (currentPage - 1) * pageSize
73
+ const endIndex = startIndex + pageSize
74
+ return filteredData.slice(startIndex, endIndex)
75
+ }, [filteredData, currentPage, pageSize])
76
+
77
+ // Row selection handlers
78
+ const selectRow = React.useCallback((row: TData) => {
79
+ if (!enableRowSelection) return
80
+
81
+ setSelectedRows((prev) => {
82
+ if (!enableMultiRowSelection) {
83
+ return [row]
84
+ }
85
+
86
+ const isSelected = prev.some((selectedRow) =>
87
+ JSON.stringify(selectedRow) === JSON.stringify(row)
88
+ )
89
+
90
+ if (isSelected) {
91
+ return prev.filter((selectedRow) =>
92
+ JSON.stringify(selectedRow) !== JSON.stringify(row)
93
+ )
94
+ } else {
95
+ return [...prev, row]
96
+ }
97
+ })
98
+ }, [enableRowSelection, enableMultiRowSelection])
99
+
100
+ const selectAllRows = React.useCallback(() => {
101
+ if (!enableRowSelection) return
102
+
103
+ setSelectedRows((prev) => {
104
+ if (prev.length === filteredData.length) {
105
+ return []
106
+ } else {
107
+ return [...filteredData]
108
+ }
109
+ })
110
+ }, [enableRowSelection, filteredData])
111
+
112
+ const clearSelection = React.useCallback(() => {
113
+ setSelectedRows([])
114
+ }, [])
115
+
116
+ const isRowSelected = React.useCallback((row: TData) => {
117
+ return selectedRows.some((selectedRow) =>
118
+ JSON.stringify(selectedRow) === JSON.stringify(row)
119
+ )
120
+ }, [selectedRows])
121
+
122
+ // Export functionality
123
+ const exportData = React.useCallback((format: 'csv' | 'json' = 'csv') => {
124
+ const dataToExport = selectedRows.length > 0 ? selectedRows : filteredData
125
+
126
+ if (format === 'csv') {
127
+ const headers = Object.keys(dataToExport[0] || {})
128
+ const csvContent = [
129
+ headers.join(','),
130
+ ...dataToExport.map(row =>
131
+ headers.map(header => {
132
+ const value = row[header]
133
+ // Escape commas and quotes in CSV
134
+ if (typeof value === 'string' && (value.includes(',') || value.includes('"'))) {
135
+ return `"${value.replace(/"/g, '""')}"`
136
+ }
137
+ return value
138
+ }).join(',')
139
+ )
140
+ ].join('\n')
141
+
142
+ const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })
143
+ const link = document.createElement('a')
144
+ link.href = URL.createObjectURL(blob)
145
+ link.download = 'data.csv'
146
+ link.click()
147
+ } else if (format === 'json') {
148
+ const jsonContent = JSON.stringify(dataToExport, null, 2)
149
+ const blob = new Blob([jsonContent], { type: 'application/json;charset=utf-8;' })
150
+ const link = document.createElement('a')
151
+ link.href = URL.createObjectURL(blob)
152
+ link.download = 'data.json'
153
+ link.click()
154
+ }
155
+ }, [selectedRows, filteredData])
156
+
157
+ // Utility functions
158
+ const getRowCount = React.useCallback(() => filteredData.length, [filteredData])
159
+ const getSelectedCount = React.useCallback(() => selectedRows.length, [selectedRows])
160
+
161
+ // Reset page when search changes
162
+ React.useEffect(() => {
163
+ setCurrentPage(1)
164
+ }, [searchQuery])
165
+
166
+ return {
167
+ filteredData: paginatedData,
168
+ selectedRows,
169
+ searchQuery,
170
+ currentPage,
171
+ totalPages,
172
+ setSearchQuery,
173
+ setCurrentPage,
174
+ selectRow,
175
+ selectAllRows,
176
+ clearSelection,
177
+ exportData,
178
+ getRowCount,
179
+ getSelectedCount,
180
+ isRowSelected,
181
+ }
182
+ }
@@ -0,0 +1,13 @@
1
+ // Mock docs pro access hook for standalone moonui-pro package
2
+ // Bu hook, moonui-pro'nun bağımsız çalışması için basit bir mock'tur
3
+
4
+ export function useDocsProAccess() {
5
+ // Production ortamında her zaman pro erişim verilir
6
+ // Gerçek uygulamada bu hook uygulamanın kendi auth sistemiyle değiştirilmelidir
7
+
8
+ return {
9
+ hasProAccess: true,
10
+ isLoading: false,
11
+ isDocsMode: false, // Standalone package'da docs mode yok
12
+ };
13
+ }
@@ -0,0 +1,65 @@
1
+ import { useEffect, useState } from 'react'
2
+
3
+ interface LicenseCheckResult {
4
+ isValid: boolean
5
+ isLoading: boolean
6
+ error?: string
7
+ }
8
+
9
+ // License kontrolü için hook
10
+ export function useLicenseCheck(): LicenseCheckResult {
11
+ const [isValid, setIsValid] = useState(false)
12
+ const [isLoading, setIsLoading] = useState(true)
13
+ const [error, setError] = useState<string>()
14
+
15
+ useEffect(() => {
16
+ async function checkLicense() {
17
+ try {
18
+ // Önce localStorage'dan kontrol et
19
+ const cachedLicense = localStorage.getItem('moonui_pro_license')
20
+ if (cachedLicense) {
21
+ const parsed = JSON.parse(cachedLicense)
22
+ if (parsed.expiresAt && new Date(parsed.expiresAt) > new Date()) {
23
+ setIsValid(true)
24
+ setIsLoading(false)
25
+ return
26
+ }
27
+ }
28
+
29
+ // API'den kontrol et
30
+ const response = await fetch('/api/license/verify', {
31
+ method: 'POST',
32
+ headers: { 'Content-Type': 'application/json' },
33
+ body: JSON.stringify({
34
+ key: process.env.NEXT_PUBLIC_MOONUI_LICENSE_KEY || localStorage.getItem('moonui_license_key')
35
+ })
36
+ })
37
+
38
+ if (response.ok) {
39
+ const data = await response.json()
40
+ if (data.valid) {
41
+ // Cache'e kaydet
42
+ localStorage.setItem('moonui_pro_license', JSON.stringify({
43
+ valid: true,
44
+ expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000) // 24 saat
45
+ }))
46
+ setIsValid(true)
47
+ } else {
48
+ setError('Invalid license key')
49
+ }
50
+ } else {
51
+ setError('License verification failed')
52
+ }
53
+ } catch (err) {
54
+ console.error('License check error:', err)
55
+ setError('License verification error')
56
+ } finally {
57
+ setIsLoading(false)
58
+ }
59
+ }
60
+
61
+ checkLicense()
62
+ }, [])
63
+
64
+ return { isValid, isLoading, error }
65
+ }
@@ -0,0 +1,19 @@
1
+ // Mock subscription hook for standalone moonui-pro package
2
+ // Bu hook, moonui-pro'nun bağımsız çalışması için basit bir mock'tur
3
+
4
+ export function useSubscription() {
5
+ // Production ortamında her zaman pro erişim verilir
6
+ // Gerçek uygulamada bu hook uygulamanın kendi auth sistemiyle değiştirilmelidir
7
+
8
+ return {
9
+ isLoading: false,
10
+ isAuthenticated: true,
11
+ isAdmin: false,
12
+ hasProAccess: true, // Pro package kullanıcıları varsayılan olarak pro erişime sahip
13
+ subscriptionPlan: "pro" as const,
14
+ subscription: {
15
+ status: "active" as const,
16
+ plan: "pro" as const,
17
+ },
18
+ };
19
+ }
package/src/index.ts ADDED
@@ -0,0 +1,11 @@
1
+ // Pro Components Export - Source of Truth: packages/moonui-pro
2
+ // Development environment imports from local packages
3
+
4
+ // Import CSS for auto-loading
5
+ import "./styles/index.css"
6
+
7
+ // Pro Components (Commercial License) - from packages/moonui-pro
8
+ export * from "./components"
9
+
10
+ // Enhanced Components - Premium animations and effects
11
+ export * as Enhanced from "./components/enhanced"
@@ -0,0 +1,255 @@
1
+ // MoonUI Micro-interactions System
2
+ // Provides consistent hover, focus, and active states across all components
3
+
4
+ import { cva, type VariantProps } from "class-variance-authority";
5
+
6
+ /**
7
+ * Micro-interaction variants for consistent component behavior
8
+ */
9
+ export const microInteractionVariants = cva("", {
10
+ variants: {
11
+ hover: {
12
+ lift: [
13
+ "transition-all duration-200 ease-out",
14
+ "hover:-translate-y-0.5",
15
+ "hover:shadow-md",
16
+ ],
17
+ glow: [
18
+ "transition-all duration-300 ease-out",
19
+ "hover:shadow-lg",
20
+ "hover:shadow-primary/20",
21
+ ],
22
+ scale: [
23
+ "transition-transform duration-200 ease-out",
24
+ "hover:scale-105",
25
+ "active:scale-95",
26
+ ],
27
+ brightness: [
28
+ "transition-all duration-200 ease-out",
29
+ "hover:brightness-110",
30
+ "active:brightness-95",
31
+ ],
32
+ border: [
33
+ "transition-all duration-200 ease-out",
34
+ "hover:border-primary/50",
35
+ ],
36
+ },
37
+ focus: {
38
+ ring: [
39
+ "focus:outline-none",
40
+ "focus-visible:ring-2",
41
+ "focus-visible:ring-primary/50",
42
+ "focus-visible:ring-offset-2",
43
+ ],
44
+ glow: [
45
+ "focus:outline-none",
46
+ "focus-visible:shadow-lg",
47
+ "focus-visible:shadow-primary/30",
48
+ ],
49
+ border: [
50
+ "focus:outline-none",
51
+ "focus-visible:border-primary",
52
+ "focus-visible:border-2",
53
+ ],
54
+ },
55
+ active: {
56
+ scale: [
57
+ "active:scale-95",
58
+ "transition-transform duration-100",
59
+ ],
60
+ darken: [
61
+ "active:brightness-90",
62
+ "transition-all duration-100",
63
+ ],
64
+ depress: [
65
+ "active:translate-y-0.5",
66
+ "active:shadow-sm",
67
+ "transition-all duration-100",
68
+ ],
69
+ },
70
+ cursor: {
71
+ pointer: "cursor-pointer",
72
+ grab: "cursor-grab active:cursor-grabbing",
73
+ text: "cursor-text",
74
+ wait: "cursor-wait",
75
+ help: "cursor-help",
76
+ notAllowed: "cursor-not-allowed",
77
+ },
78
+ },
79
+ defaultVariants: {
80
+ hover: "lift",
81
+ focus: "ring",
82
+ active: "scale",
83
+ cursor: "pointer",
84
+ },
85
+ });
86
+
87
+ /**
88
+ * Spring animation configurations
89
+ */
90
+ export const springAnimations = {
91
+ // Smooth spring for general use
92
+ smooth: {
93
+ type: "spring",
94
+ stiffness: 260,
95
+ damping: 20,
96
+ },
97
+ // Bouncy spring for playful interactions
98
+ bouncy: {
99
+ type: "spring",
100
+ stiffness: 300,
101
+ damping: 15,
102
+ },
103
+ // Stiff spring for quick responses
104
+ stiff: {
105
+ type: "spring",
106
+ stiffness: 400,
107
+ damping: 25,
108
+ },
109
+ // Gentle spring for subtle movements
110
+ gentle: {
111
+ type: "spring",
112
+ stiffness: 150,
113
+ damping: 15,
114
+ },
115
+ };
116
+
117
+ /**
118
+ * Hover animation presets
119
+ */
120
+ export const hoverAnimations = {
121
+ lift: {
122
+ y: -2,
123
+ transition: springAnimations.smooth,
124
+ },
125
+ scale: {
126
+ scale: 1.05,
127
+ transition: springAnimations.smooth,
128
+ },
129
+ glow: {
130
+ boxShadow: "0 0 20px rgba(var(--primary), 0.3)",
131
+ transition: springAnimations.smooth,
132
+ },
133
+ rotate: {
134
+ rotate: 2,
135
+ transition: springAnimations.bouncy,
136
+ },
137
+ };
138
+
139
+ /**
140
+ * Tap/Click animation presets
141
+ */
142
+ export const tapAnimations = {
143
+ scale: {
144
+ scale: 0.95,
145
+ transition: { duration: 0.1 },
146
+ },
147
+ depress: {
148
+ y: 1,
149
+ transition: { duration: 0.1 },
150
+ },
151
+ };
152
+
153
+ /**
154
+ * Focus animation presets
155
+ */
156
+ export const focusAnimations = {
157
+ ring: {
158
+ boxShadow: "0 0 0 2px var(--background), 0 0 0 4px var(--primary)",
159
+ transition: springAnimations.smooth,
160
+ },
161
+ glow: {
162
+ boxShadow: "0 0 0 3px rgba(var(--primary), 0.3)",
163
+ transition: springAnimations.smooth,
164
+ },
165
+ };
166
+
167
+ /**
168
+ * Stagger animation for lists
169
+ */
170
+ export const staggerAnimation = {
171
+ container: {
172
+ hidden: { opacity: 0 },
173
+ show: {
174
+ opacity: 1,
175
+ transition: {
176
+ staggerChildren: 0.05,
177
+ },
178
+ },
179
+ },
180
+ item: {
181
+ hidden: { opacity: 0, y: 20 },
182
+ show: {
183
+ opacity: 1,
184
+ y: 0,
185
+ transition: springAnimations.smooth,
186
+ },
187
+ },
188
+ };
189
+
190
+ /**
191
+ * Page transition animations
192
+ */
193
+ export const pageTransitions = {
194
+ fadeIn: {
195
+ initial: { opacity: 0 },
196
+ animate: { opacity: 1 },
197
+ exit: { opacity: 0 },
198
+ transition: { duration: 0.3 },
199
+ },
200
+ slideUp: {
201
+ initial: { opacity: 0, y: 20 },
202
+ animate: { opacity: 1, y: 0 },
203
+ exit: { opacity: 0, y: -20 },
204
+ transition: springAnimations.smooth,
205
+ },
206
+ slideRight: {
207
+ initial: { opacity: 0, x: -20 },
208
+ animate: { opacity: 1, x: 0 },
209
+ exit: { opacity: 0, x: 20 },
210
+ transition: springAnimations.smooth,
211
+ },
212
+ scale: {
213
+ initial: { opacity: 0, scale: 0.95 },
214
+ animate: { opacity: 1, scale: 1 },
215
+ exit: { opacity: 0, scale: 1.05 },
216
+ transition: springAnimations.smooth,
217
+ },
218
+ };
219
+
220
+ /**
221
+ * Skeleton loading animation
222
+ */
223
+ export const skeletonAnimation = {
224
+ initial: { opacity: 0.5 },
225
+ animate: {
226
+ opacity: [0.5, 0.8, 0.5],
227
+ transition: {
228
+ duration: 1.5,
229
+ repeat: Infinity,
230
+ ease: "easeInOut",
231
+ },
232
+ },
233
+ };
234
+
235
+ /**
236
+ * Tooltip animation
237
+ */
238
+ export const tooltipAnimation = {
239
+ initial: { opacity: 0, scale: 0.95 },
240
+ animate: { opacity: 1, scale: 1 },
241
+ exit: { opacity: 0, scale: 0.95 },
242
+ transition: { duration: 0.15 },
243
+ };
244
+
245
+ /**
246
+ * Notification animation
247
+ */
248
+ export const notificationAnimation = {
249
+ initial: { opacity: 0, y: -20, scale: 0.95 },
250
+ animate: { opacity: 1, y: 0, scale: 1 },
251
+ exit: { opacity: 0, scale: 0.95, transition: { duration: 0.15 } },
252
+ transition: springAnimations.bouncy,
253
+ };
254
+
255
+ export type MicroInteractionProps = VariantProps<typeof microInteractionVariants>;
@@ -0,0 +1,6 @@
1
+ import { type ClassValue, clsx } from "clsx"
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs))
6
+ }