tcmmichaelb139 commited on
Commit
f3f5382
·
1 Parent(s): 9b45e9e

fixed some issues + change color style.

Browse files
evolutiontransformer/.DS_Store DELETED
Binary file (6.15 kB)
 
frontend/src/App.jsx CHANGED
@@ -48,7 +48,7 @@ function App() {
48
  }, [fetchModels, checkTaskStatus]);
49
 
50
  return (
51
- <div className="h-screen bg-gradient-to-br from-primary-50 to-secondary-50 overflow-hidden">
52
  {/* GitHub Corner */}
53
  <a
54
  href="https://github.com/tcmmichaelb139/evolutiontransformer"
@@ -61,7 +61,7 @@ function App() {
61
  width="40"
62
  height="40"
63
  viewBox="0 0 250 250"
64
- className="fill-primary-500 text-white absolute top-0 right-0 border-0"
65
  aria-hidden="true"
66
  >
67
  <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z" />
 
48
  }, [fetchModels, checkTaskStatus]);
49
 
50
  return (
51
+ <div className="h-screen bg-secondary-50 overflow-hidden">
52
  {/* GitHub Corner */}
53
  <a
54
  href="https://github.com/tcmmichaelb139/evolutiontransformer"
 
61
  width="40"
62
  height="40"
63
  viewBox="0 0 250 250"
64
+ className="fill-primary-500 text-background absolute top-0 right-0 border-0"
65
  aria-hidden="true"
66
  >
67
  <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z" />
frontend/src/components/Dropdown.jsx CHANGED
@@ -43,24 +43,22 @@ const Dropdown = ({
43
  return (
44
  <div className={`relative ${className}`} ref={dropdownRef}>
45
  {label && (
46
- <label className="block text-sm font-medium text-secondary-700 mb-2">
47
  {label}
48
  </label>
49
  )}
50
  <button
51
  onClick={() => !disabled && setIsOpen(!isOpen)}
52
  disabled={disabled}
53
- className={`w-full p-4 rounded-xl text-left transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-primary-500 disabled:opacity-50 disabled:cursor-not-allowed bg-white border-2 border-secondary-300 hover:bg-primary-50 hover:shadow-lg ${className}`}
54
  >
55
  <div className="flex items-center justify-between">
56
  <div className="flex items-center space-x-3">
57
  {icon && <div className="text-lg">{icon}</div>}
58
  <span
59
  className={`${
60
- isSelected
61
- ? "text-secondary-800 font-medium"
62
- : "text-secondary-500"
63
- } ${loading ? "text-secondary-400" : ""}`}
64
  >
65
  {loading ? loadingMessage : displayValue}
66
  </span>
@@ -72,7 +70,7 @@ const Dropdown = ({
72
  <svg
73
  className={`w-5 h-5 text-primary-600 transition-transform duration-200 ${
74
  isOpen ? "rotate-180" : ""
75
- } ${disabled ? "text-secondary-400" : ""}`}
76
  fill="none"
77
  stroke="currentColor"
78
  viewBox="0 0 24 24"
@@ -89,13 +87,13 @@ const Dropdown = ({
89
  </button>
90
  {isOpen && !disabled && (
91
  <div
92
- className={`absolute z-50 w-full mt-2 rounded-xl max-h-60 overflow-hidden bg-white border-2 border-primary-200 shadow-lg ${dropdownClassName}`}
93
  >
94
  {showSearch && (
95
  <div className="p-3 border-b border-secondary-100">
96
  <div className="relative">
97
  <svg
98
- className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-secondary-400"
99
  fill="none"
100
  stroke="currentColor"
101
  viewBox="0 0 24 24"
@@ -120,12 +118,12 @@ const Dropdown = ({
120
  )}
121
  <div className="max-h-48 overflow-y-auto p-2">
122
  {loading ? (
123
- <div className="p-4 text-center text-secondary-500">
124
  <div className="animate-spin w-6 h-6 border-2 border-primary-500 border-t-transparent rounded-full mx-auto mb-2"></div>
125
  {loadingMessage}
126
  </div>
127
  ) : filteredOptions.length === 0 ? (
128
- <div className="p-4 text-center text-secondary-500">
129
  {emptyMessage}
130
  </div>
131
  ) : (
@@ -148,45 +146,23 @@ const Dropdown = ({
148
  className={`w-full p-3 text-left rounded-lg transition-all duration-200 hover:bg-blue-100 hover:text-blue-900 ${
149
  isOptionSelected
150
  ? "bg-gradient-to-r from-primary-200 to-accent-200 text-primary-800 font-medium"
151
- : "text-secondary-700 hover:bg-blue-50"
152
  } ${optionClassName}`}
153
  >
154
  <div className="flex items-center space-x-3">
155
  {optionIcon && (
156
  <div className="text-lg">{optionIcon}</div>
157
  )}
158
- <div
159
- className={`w-3 h-3 rounded-full transition-colors ${
160
- isOptionSelected
161
- ? "bg-primary-600"
162
- : "bg-secondary-300"
163
- }`}
164
- ></div>
165
  <div className="flex-1 min-w-0">
166
  <div className="truncate font-medium">
167
  {optionLabel}
168
  </div>
169
  {optionDescription && (
170
- <div className="text-xs text-secondary-500 truncate mt-1">
171
  {optionDescription}
172
  </div>
173
  )}
174
  </div>
175
- {isOptionSelected && (
176
- <svg
177
- className="w-4 h-4 text-primary-600"
178
- fill="none"
179
- stroke="currentColor"
180
- viewBox="0 0 24 24"
181
- >
182
- <path
183
- strokeLinecap="round"
184
- strokeLinejoin="round"
185
- strokeWidth="2"
186
- d="M5 13l4 4L19 7"
187
- />
188
- </svg>
189
- )}
190
  </div>
191
  </button>
192
  );
 
43
  return (
44
  <div className={`relative ${className}`} ref={dropdownRef}>
45
  {label && (
46
+ <label className="block text-sm font-medium text-foreground mb-2">
47
  {label}
48
  </label>
49
  )}
50
  <button
51
  onClick={() => !disabled && setIsOpen(!isOpen)}
52
  disabled={disabled}
53
+ className={`w-full p-4 rounded-xl text-left transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-primary-500 disabled:opacity-50 disabled:cursor-not-allowed bg-background border-2 border-secondary-300 hover:bg-primary-50 hover:shadow-lg ${className}`}
54
  >
55
  <div className="flex items-center justify-between">
56
  <div className="flex items-center space-x-3">
57
  {icon && <div className="text-lg">{icon}</div>}
58
  <span
59
  className={`${
60
+ isSelected ? "text-foreground font-medium" : "text-foreground"
61
+ } ${loading ? "text-foreground" : ""}`}
 
 
62
  >
63
  {loading ? loadingMessage : displayValue}
64
  </span>
 
70
  <svg
71
  className={`w-5 h-5 text-primary-600 transition-transform duration-200 ${
72
  isOpen ? "rotate-180" : ""
73
+ } ${disabled ? "text-foreground" : ""}`}
74
  fill="none"
75
  stroke="currentColor"
76
  viewBox="0 0 24 24"
 
87
  </button>
88
  {isOpen && !disabled && (
89
  <div
90
+ className={`absolute z-50 w-full mt-2 rounded-xl max-h-60 overflow-hidden bg-background border-2 border-primary-200 shadow-lg ${dropdownClassName}`}
91
  >
92
  {showSearch && (
93
  <div className="p-3 border-b border-secondary-100">
94
  <div className="relative">
95
  <svg
96
+ className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-foreground"
97
  fill="none"
98
  stroke="currentColor"
99
  viewBox="0 0 24 24"
 
118
  )}
119
  <div className="max-h-48 overflow-y-auto p-2">
120
  {loading ? (
121
+ <div className="p-4 text-center text-foreground">
122
  <div className="animate-spin w-6 h-6 border-2 border-primary-500 border-t-transparent rounded-full mx-auto mb-2"></div>
123
  {loadingMessage}
124
  </div>
125
  ) : filteredOptions.length === 0 ? (
126
+ <div className="p-4 text-center text-foreground">
127
  {emptyMessage}
128
  </div>
129
  ) : (
 
146
  className={`w-full p-3 text-left rounded-lg transition-all duration-200 hover:bg-blue-100 hover:text-blue-900 ${
147
  isOptionSelected
148
  ? "bg-gradient-to-r from-primary-200 to-accent-200 text-primary-800 font-medium"
149
+ : "text-foreground hover:bg-blue-50"
150
  } ${optionClassName}`}
151
  >
152
  <div className="flex items-center space-x-3">
153
  {optionIcon && (
154
  <div className="text-lg">{optionIcon}</div>
155
  )}
 
 
 
 
 
 
 
156
  <div className="flex-1 min-w-0">
157
  <div className="truncate font-medium">
158
  {optionLabel}
159
  </div>
160
  {optionDescription && (
161
+ <div className="text-xs text-foreground truncate mt-1">
162
  {optionDescription}
163
  </div>
164
  )}
165
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
  </div>
167
  </button>
168
  );
frontend/src/components/InferencePopup.jsx CHANGED
@@ -95,12 +95,12 @@ const InferencePopup = ({ isOpen, onClose, models }) => {
95
  WebkitBackdropFilter: "blur(8px)", // Safari support
96
  }}
97
  >
98
- <div className="bg-white rounded-2xl border-2 border-primary-200 shadow-2xl w-full max-w-2xl max-h-[90vh] overflow-hidden">
99
  {/* Header */}
100
- <div className="p-6 border-b border-secondary-200 bg-gradient-to-r from-primary-50 to-accent-50">
101
  <div className="flex items-center justify-between">
102
  <div className="flex items-center space-x-3">
103
- <div className="w-8 h-8 bg-gradient-to-br from-primary-500 to-accent-500 rounded-lg flex items-center justify-center text-white">
104
  <svg
105
  xmlns="http://www.w3.org/2000/svg"
106
  width="20"
@@ -115,13 +115,13 @@ const InferencePopup = ({ isOpen, onClose, models }) => {
115
  <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
116
  </svg>
117
  </div>
118
- <h2 className="text-xl font-bold text-secondary-800">
119
  Model Inference
120
  </h2>
121
  </div>
122
  <button
123
  onClick={handleClose}
124
- className="w-8 h-8 rounded-lg hover:bg-secondary-200 transition-colors duration-200 flex items-center justify-center text-secondary-600 hover:text-secondary-800"
125
  >
126
  <svg
127
  xmlns="http://www.w3.org/2000/svg"
@@ -152,7 +152,7 @@ const InferencePopup = ({ isOpen, onClose, models }) => {
152
  />
153
 
154
  <div>
155
- <label className="block text-sm font-medium text-secondary-700 mb-2">
156
  Prompt
157
  </label>
158
  <textarea
@@ -167,7 +167,7 @@ const InferencePopup = ({ isOpen, onClose, models }) => {
167
  {/* Configuration Section */}
168
  <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
169
  <div>
170
- <label className="block text-sm font-medium text-secondary-700 mb-2">
171
  Max New Tokens
172
  </label>
173
  <NumberInput
@@ -182,7 +182,7 @@ const InferencePopup = ({ isOpen, onClose, models }) => {
182
  </div>
183
 
184
  <div>
185
- <label className="block text-sm font-medium text-secondary-700 mb-2">
186
  Temperature
187
  </label>
188
  <NumberInput
@@ -202,11 +202,11 @@ const InferencePopup = ({ isOpen, onClose, models }) => {
202
  <button
203
  onClick={handleInference}
204
  disabled={isLoading || !selectedModel || !prompt.trim()}
205
- className="w-full py-3 px-4 bg-gradient-to-r from-primary-500 to-accent-500 text-white font-medium rounded-lg hover:from-primary-600 hover:to-accent-600 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center space-x-2"
206
  >
207
  {isLoading ? (
208
  <>
209
- <div className="animate-spin w-4 h-4 border-2 border-white border-t-transparent rounded-full"></div>
210
  <span>Generating...</span>
211
  </>
212
  ) : (
@@ -239,11 +239,11 @@ const InferencePopup = ({ isOpen, onClose, models }) => {
239
  {/* Response Display */}
240
  {response && (
241
  <div>
242
- <label className="block text-sm font-medium text-secondary-700 mb-2">
243
  Generated Response
244
  </label>
245
  <div className="p-4 bg-primary-50 border-2 border-primary-200 rounded-xl">
246
- <p className="text-secondary-800 whitespace-pre-wrap">
247
  {response}
248
  </p>
249
  </div>
 
95
  WebkitBackdropFilter: "blur(8px)", // Safari support
96
  }}
97
  >
98
+ <div className="bg-background rounded-2xl border-2 border-primary-200 shadow-2xl w-full max-w-2xl max-h-[90vh] overflow-hidden">
99
  {/* Header */}
100
+ <div className="p-6 border-b border-secondary-200 bg-secondary-50">
101
  <div className="flex items-center justify-between">
102
  <div className="flex items-center space-x-3">
103
+ <div className="w-8 h-8 bg-gradient-to-br from-primary-500 to-accent-500 rounded-lg flex items-center justify-center text-background">
104
  <svg
105
  xmlns="http://www.w3.org/2000/svg"
106
  width="20"
 
115
  <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
116
  </svg>
117
  </div>
118
+ <h2 className="text-xl font-bold text-foreground">
119
  Model Inference
120
  </h2>
121
  </div>
122
  <button
123
  onClick={handleClose}
124
+ className="w-8 h-8 rounded-lg hover:bg-secondary-200 transition-colors duration-200 flex items-center justify-center text-foreground hover:text-foreground"
125
  >
126
  <svg
127
  xmlns="http://www.w3.org/2000/svg"
 
152
  />
153
 
154
  <div>
155
+ <label className="block text-sm font-medium text-foreground mb-2">
156
  Prompt
157
  </label>
158
  <textarea
 
167
  {/* Configuration Section */}
168
  <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
169
  <div>
170
+ <label className="block text-sm font-medium text-foreground mb-2">
171
  Max New Tokens
172
  </label>
173
  <NumberInput
 
182
  </div>
183
 
184
  <div>
185
+ <label className="block text-sm font-medium text-foreground mb-2">
186
  Temperature
187
  </label>
188
  <NumberInput
 
202
  <button
203
  onClick={handleInference}
204
  disabled={isLoading || !selectedModel || !prompt.trim()}
205
+ className="w-full py-3 px-4 bg-gradient-to-r from-primary-500 to-accent-500 text-background font-medium rounded-lg hover:from-primary-600 hover:to-accent-600 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center space-x-2"
206
  >
207
  {isLoading ? (
208
  <>
209
+ <div className="animate-spin w-4 h-4 border-2 border-background border-t-transparent rounded-full"></div>
210
  <span>Generating...</span>
211
  </>
212
  ) : (
 
239
  {/* Response Display */}
240
  {response && (
241
  <div>
242
+ <label className="block text-sm font-medium text-foreground mb-2">
243
  Generated Response
244
  </label>
245
  <div className="p-4 bg-primary-50 border-2 border-primary-200 rounded-xl">
246
+ <p className="text-foreground backgroundspace-pre-wrap">
247
  {response}
248
  </p>
249
  </div>
frontend/src/components/NumberInput.jsx CHANGED
@@ -90,7 +90,7 @@ const NumberInput = ({
90
  <div className={className}>
91
  {label && (
92
  <label
93
- className={`block font-medium text-secondary-700 ${
94
  compact ? "text-xs mb-1" : "text-sm mb-2"
95
  }`}
96
  >
@@ -105,7 +105,7 @@ const NumberInput = ({
105
  onBlur={handleBlur}
106
  step={step}
107
  disabled={disabled}
108
- className={`w-full bg-white border-2 border-secondary-300 hover:bg-primary-50 hover:shadow-lg focus:outline-none focus:ring-2 focus:ring-primary-500 transition-all duration-200 text-secondary-800 font-medium disabled:opacity-50 disabled:cursor-not-allowed ${
109
  compact ? "p-2 rounded-lg text-sm" : "p-4 rounded-xl"
110
  }`}
111
  min={min}
@@ -117,7 +117,7 @@ const NumberInput = ({
117
  }`}
118
  >
119
  <div
120
- className={`text-secondary-500 bg-white px-1 py-0.5 rounded border border-secondary-200 ${
121
  compact ? "text-xs px-1" : "text-xs px-2 py-1"
122
  }`}
123
  >
 
90
  <div className={className}>
91
  {label && (
92
  <label
93
+ className={`block font-medium text-foreground ${
94
  compact ? "text-xs mb-1" : "text-sm mb-2"
95
  }`}
96
  >
 
105
  onBlur={handleBlur}
106
  step={step}
107
  disabled={disabled}
108
+ className={`w-full bg-background border-2 border-secondary-300 hover:bg-primary-50 hover:shadow-lg focus:outline-none focus:ring-2 focus:ring-primary-500 transition-all duration-200 text-foreground font-medium disabled:opacity-50 disabled:cursor-not-allowed ${
109
  compact ? "p-2 rounded-lg text-sm" : "p-4 rounded-xl"
110
  }`}
111
  min={min}
 
117
  }`}
118
  >
119
  <div
120
+ className={`text-foreground bg-background px-1 py-0.5 rounded border border-secondary-200 ${
121
  compact ? "text-xs px-1" : "text-xs px-2 py-1"
122
  }`}
123
  >
frontend/src/components/Options.jsx CHANGED
@@ -89,9 +89,9 @@ const Options = ({
89
 
90
  return (
91
  <div>
92
- <div className="p-6 border-2 border-primary-200 rounded-2xl bg-gradient-to-br from-white to-primary-50 shadow-xl fixed inset-y-4 left-4 w-[25rem] overflow-y-auto">
93
  <div className="flex items-center space-x-2 mb-6">
94
- <div className="w-8 h-8 bg-gradient-to-br from-primary-500 to-accent-500 rounded-lg flex items-center justify-center text-white">
95
  <svg
96
  xmlns="http://www.w3.org/2000/svg"
97
  width="24"
@@ -109,7 +109,7 @@ const Options = ({
109
  <circle cx="7" cy="7" r="3" />
110
  </svg>
111
  </div>
112
- <h2 className="text-xl font-bold text-secondary-800">
113
  Evolution Transformer Options
114
  </h2>
115
  </div>
@@ -151,7 +151,7 @@ const Options = ({
151
  />
152
 
153
  <div>
154
- <label className="block text-sm font-medium text-secondary-700 mb-1">
155
  Merged Model Name
156
  </label>
157
  <input
@@ -159,7 +159,7 @@ const Options = ({
159
  value={mergedName}
160
  onChange={(e) => setMergedName(e.target.value)}
161
  placeholder="Enter merged model name..."
162
- className="w-full px-3 py-2 border-2 border-secondary-200 rounded-lg focus:border-primary-500 focus:ring-2 focus:ring-primary-200 text-secondary-800 placeholder-secondary-400 transition-all duration-200"
163
  />
164
  </div>
165
 
@@ -182,9 +182,9 @@ const Options = ({
182
  </div>
183
 
184
  <div className="flex space-x-3">
185
- <div className="flex-1 p-4 rounded-xl border-2 border-accent-200 bg-gradient-to-br from-accent-50 to-primary-50">
186
  <div className="flex items-center space-x-2 mb-3">
187
- <div className="w-6 h-6 bg-gradient-to-br from-accent-500 to-secondary-500 rounded-lg flex items-center justify-center text-white">
188
  <svg
189
  xmlns="http://www.w3.org/2000/svg"
190
  width="16"
@@ -201,7 +201,7 @@ const Options = ({
201
  <path d="m20 22-5-5" />
202
  </svg>
203
  </div>
204
- <h3 className="text-sm font-semibold text-secondary-800">
205
  Merge Models
206
  </h3>
207
  </div>
@@ -215,11 +215,11 @@ const Options = ({
215
  layerRecipe.length === 0 ||
216
  !mergedName.trim()
217
  }
218
- className="w-full py-2.5 px-3 bg-gradient-to-r from-accent-500 to-primary-500 text-white font-medium rounded-lg hover:from-accent-600 hover:to-primary-600 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center space-x-2 text-sm"
219
  >
220
  {isLoading ? (
221
  <>
222
- <div className="animate-spin w-3.5 h-3.5 border-2 border-white border-t-transparent rounded-full"></div>
223
  <span>Merging...</span>
224
  </>
225
  ) : (
@@ -245,9 +245,9 @@ const Options = ({
245
  </button>
246
  </div>
247
 
248
- <div className="flex-1 p-4 rounded-xl border-2 border-primary-200 bg-gradient-to-br from-primary-50 to-accent-50">
249
  <div className="flex items-center space-x-2 mb-3">
250
- <div className="w-6 h-6 bg-gradient-to-br from-secondary-500 to-primary-500 rounded-lg flex items-center justify-center text-white">
251
  <svg
252
  xmlns="http://www.w3.org/2000/svg"
253
  width="16"
@@ -262,14 +262,14 @@ const Options = ({
262
  <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
263
  </svg>
264
  </div>
265
- <h3 className="text-sm font-semibold text-secondary-800">
266
  Test Inference
267
  </h3>
268
  </div>
269
 
270
  <button
271
  onClick={() => setIsInferenceOpen(true)}
272
- className="w-full py-2.5 px-3 bg-gradient-to-r from-secondary-500 to-primary-500 text-white font-medium rounded-lg hover:from-secondary-600 hover:to-primary-600 transition-all duration-200 flex items-center justify-center space-x-2 text-sm"
273
  >
274
  <svg
275
  xmlns="http://www.w3.org/2000/svg"
 
89
 
90
  return (
91
  <div>
92
+ <div className="p-6 border-2 border-primary-200 rounded-2xl bg-background shadow-xl fixed inset-y-4 left-4 w-[25rem] overflow-y-auto">
93
  <div className="flex items-center space-x-2 mb-6">
94
+ <div className="w-8 h-8 bg-gradient-to-br from-primary-500 to-accent-500 rounded-lg flex items-center justify-center text-background">
95
  <svg
96
  xmlns="http://www.w3.org/2000/svg"
97
  width="24"
 
109
  <circle cx="7" cy="7" r="3" />
110
  </svg>
111
  </div>
112
+ <h2 className="text-xl font-bold text-foreground">
113
  Evolution Transformer Options
114
  </h2>
115
  </div>
 
151
  />
152
 
153
  <div>
154
+ <label className="block text-sm font-medium text-foreground mb-1">
155
  Merged Model Name
156
  </label>
157
  <input
 
159
  value={mergedName}
160
  onChange={(e) => setMergedName(e.target.value)}
161
  placeholder="Enter merged model name..."
162
+ className="w-full px-3 py-2 border-2 border-secondary-200 rounded-lg focus:border-primary-500 focus:ring-2 focus:ring-primary-200 text-foreground placeholder-secondary-400 transition-all duration-200"
163
  />
164
  </div>
165
 
 
182
  </div>
183
 
184
  <div className="flex space-x-3">
185
+ <div className="flex-1 p-4 rounded-xl border-2 border-accent-200 bg-accent-50">
186
  <div className="flex items-center space-x-2 mb-3">
187
+ <div className="w-6 h-6 bg-gradient-to-br from-accent-500 to-secondary-500 rounded-lg flex items-center justify-center text-background">
188
  <svg
189
  xmlns="http://www.w3.org/2000/svg"
190
  width="16"
 
201
  <path d="m20 22-5-5" />
202
  </svg>
203
  </div>
204
+ <h3 className="text-sm font-semibold text-foreground">
205
  Merge Models
206
  </h3>
207
  </div>
 
215
  layerRecipe.length === 0 ||
216
  !mergedName.trim()
217
  }
218
+ className="w-full py-2.5 px-3 bg-gradient-to-r from-accent-500 to-primary-500 text-background font-medium rounded-lg hover:from-accent-600 hover:to-primary-600 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center space-x-2 text-sm"
219
  >
220
  {isLoading ? (
221
  <>
222
+ <div className="animate-spin w-3.5 h-3.5 border-2 border-background border-t-transparent rounded-full"></div>
223
  <span>Merging...</span>
224
  </>
225
  ) : (
 
245
  </button>
246
  </div>
247
 
248
+ <div className="flex-1 p-4 rounded-xl border-2 border-primary-200 bg-primary-50">
249
  <div className="flex items-center space-x-2 mb-3">
250
+ <div className="w-6 h-6 bg-gradient-to-br from-secondary-500 to-primary-500 rounded-lg flex items-center justify-center text-background">
251
  <svg
252
  xmlns="http://www.w3.org/2000/svg"
253
  width="16"
 
262
  <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
263
  </svg>
264
  </div>
265
+ <h3 className="text-sm font-semibold text-foreground">
266
  Test Inference
267
  </h3>
268
  </div>
269
 
270
  <button
271
  onClick={() => setIsInferenceOpen(true)}
272
+ className="w-full py-2.5 px-3 bg-gradient-to-r from-secondary-500 to-primary-500 text-background font-medium rounded-lg hover:from-secondary-600 hover:to-primary-600 transition-all duration-200 flex items-center justify-center space-x-2 text-sm"
273
  >
274
  <svg
275
  xmlns="http://www.w3.org/2000/svg"
frontend/src/components/Recipe.jsx CHANGED
@@ -108,7 +108,7 @@ const Recipe = ({
108
  };
109
 
110
  return (
111
- <div className="p-6 border-2 border-primary-200 rounded-2xl bg-gradient-to-br from-white to-primary-50 shadow-xl fixed top-4 right-4 bottom-4 left-[27rem] overflow-y-auto ">
112
  <div className="flex items-center space-x-2 mb-6">
113
  <div className="w-8 h-8 bg-gradient-to-br from-accent-500 to-primary-500 rounded-lg flex items-center justify-center">
114
  <svg
@@ -121,18 +121,18 @@ const Recipe = ({
121
  strokeWidth="2"
122
  strokeLinecap="round"
123
  strokeLinejoin="round"
124
- className="text-white"
125
  >
126
  <path d="M12 3v18m9-9H3" />
127
  </svg>
128
  </div>
129
- <h2 className="text-xl font-bold text-secondary-800">Layer Recipe</h2>
130
  </div>
131
 
132
  <div className="space-y-8">
133
  <div className="grid grid-cols-2 gap-6">
134
  <div className="space-y-4">
135
- <h3 className="text-lg font-semibold text-secondary-700">
136
  Embedding Layers
137
  </h3>
138
  <div className="space-y-3">
@@ -154,7 +154,7 @@ const Recipe = ({
154
  </div>
155
 
156
  <div className="space-y-4">
157
- <h3 className="text-lg font-semibold text-secondary-700">
158
  Linear Layers
159
  </h3>
160
  <div className="space-y-3">
@@ -178,10 +178,10 @@ const Recipe = ({
178
 
179
  <div className="space-y-4">
180
  <div className="flex items-center justify-between">
181
- <h3 className="text-lg font-semibold text-secondary-700">
182
  Transformer Layers
183
  </h3>
184
- <div className="text-xs text-secondary-500 space-x-4">
185
  <span>
186
  Model 1:{" "}
187
  {modelLayerCounts.model1 === "N/A"
@@ -200,14 +200,14 @@ const Recipe = ({
200
  {layerRecipe.map((layer, layerIndex) => (
201
  <div
202
  key={layerIndex}
203
- className="relative border-2 border-secondary-200 rounded-xl p-4 bg-white hover:border-primary-300 transition-all duration-200"
204
  >
205
  <div className="flex items-center justify-between mb-3">
206
  <div className="flex items-center space-x-3">
207
- <h4 className="font-medium text-secondary-700">
208
  Layer {layerIndex + 1}
209
  </h4>
210
- <div className="text-xs text-secondary-500 bg-secondary-100 px-2 py-1 rounded-md">
211
  Total:{" "}
212
  {Math.round(
213
  layer.reduce((sum, block) => sum + block[2], 0) * 100
@@ -217,7 +217,7 @@ const Recipe = ({
217
  </div>
218
  <button
219
  onClick={() => addBlockToLayer(layerIndex)}
220
- className="w-6 h-6 bg-primary-500 text-white rounded-md hover:bg-primary-600 transition-colors duration-200 flex items-center justify-center"
221
  title="Add block"
222
  >
223
  <svg
@@ -252,18 +252,16 @@ const Recipe = ({
252
  e.preventDefault();
253
  removeBlockFromLayer(layerIndex, blockIndex);
254
  }}
255
- className="px-3 py-2 bg-white border-2 border-secondary-300 rounded-lg hover:border-primary-300 hover:bg-primary-50 transition-all duration-200 text-sm font-medium text-secondary-700 flex items-center space-x-2"
256
  title="Left click to edit, Right click to delete"
257
  >
258
  <span className="text-primary-600">{modelName}</span>
259
- <span className="text-secondary-500">
260
- L{block[0]}
261
- </span>
262
  <span className="text-accent-600">
263
  {Math.round(block[2] * 100)}%
264
  </span>
265
  <svg
266
- className={`w-4 h-4 text-secondary-400 transition-transform duration-200 ${
267
  isExpanded ? "rotate-180" : ""
268
  }`}
269
  fill="none"
@@ -281,12 +279,12 @@ const Recipe = ({
281
 
282
  {isExpanded && (
283
  <div
284
- className="absolute top-full left-0 mt-1 p-3 bg-white border-2 border-primary-200 rounded-lg shadow-lg z-10 min-w-64"
285
  data-block-id={blockId}
286
  >
287
  <div className="space-y-3">
288
  <div>
289
- <label className="block text-xs font-medium text-secondary-600 mb-1">
290
  Model
291
  </label>
292
  <Dropdown
@@ -309,7 +307,7 @@ const Recipe = ({
309
 
310
  <div className="grid grid-cols-2 gap-3">
311
  <div>
312
- <label className="block text-xs font-medium text-secondary-600 mb-1">
313
  Layer
314
  </label>
315
  <NumberInput
@@ -337,7 +335,7 @@ const Recipe = ({
337
  </div>
338
 
339
  <div>
340
- <label className="block text-xs font-medium text-secondary-600 mb-1">
341
  Weight (%)
342
  </label>
343
  <NumberInput
@@ -366,7 +364,7 @@ const Recipe = ({
366
  );
367
  setExpandedBlock(null);
368
  }}
369
- className="w-full px-3 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors duration-200 text-sm font-medium"
370
  >
371
  Remove Block
372
  </button>
 
108
  };
109
 
110
  return (
111
+ <div className="p-6 border-2 border-primary-200 rounded-2xl bg-background shadow-xl fixed top-4 right-4 bottom-4 left-[27rem] overflow-y-auto ">
112
  <div className="flex items-center space-x-2 mb-6">
113
  <div className="w-8 h-8 bg-gradient-to-br from-accent-500 to-primary-500 rounded-lg flex items-center justify-center">
114
  <svg
 
121
  strokeWidth="2"
122
  strokeLinecap="round"
123
  strokeLinejoin="round"
124
+ className="text-background"
125
  >
126
  <path d="M12 3v18m9-9H3" />
127
  </svg>
128
  </div>
129
+ <h2 className="text-xl font-bold text-foreground">Layer Recipe</h2>
130
  </div>
131
 
132
  <div className="space-y-8">
133
  <div className="grid grid-cols-2 gap-6">
134
  <div className="space-y-4">
135
+ <h3 className="text-lg font-semibold text-foreground">
136
  Embedding Layers
137
  </h3>
138
  <div className="space-y-3">
 
154
  </div>
155
 
156
  <div className="space-y-4">
157
+ <h3 className="text-lg font-semibold text-foreground">
158
  Linear Layers
159
  </h3>
160
  <div className="space-y-3">
 
178
 
179
  <div className="space-y-4">
180
  <div className="flex items-center justify-between">
181
+ <h3 className="text-lg font-semibold text-foreground">
182
  Transformer Layers
183
  </h3>
184
+ <div className="text-xs text-foreground space-x-4">
185
  <span>
186
  Model 1:{" "}
187
  {modelLayerCounts.model1 === "N/A"
 
200
  {layerRecipe.map((layer, layerIndex) => (
201
  <div
202
  key={layerIndex}
203
+ className="relative border-2 border-secondary-200 rounded-xl p-4 bg-background hover:border-primary-300 transition-all duration-200"
204
  >
205
  <div className="flex items-center justify-between mb-3">
206
  <div className="flex items-center space-x-3">
207
+ <h4 className="font-medium text-foreground">
208
  Layer {layerIndex + 1}
209
  </h4>
210
+ <div className="text-xs text-foreground bg-secondary-100 px-2 py-1 rounded-md">
211
  Total:{" "}
212
  {Math.round(
213
  layer.reduce((sum, block) => sum + block[2], 0) * 100
 
217
  </div>
218
  <button
219
  onClick={() => addBlockToLayer(layerIndex)}
220
+ className="w-6 h-6 bg-primary-500 text-background rounded-md hover:bg-primary-600 transition-colors duration-200 flex items-center justify-center"
221
  title="Add block"
222
  >
223
  <svg
 
252
  e.preventDefault();
253
  removeBlockFromLayer(layerIndex, blockIndex);
254
  }}
255
+ className="px-3 py-2 bg-background border-2 border-secondary-300 rounded-lg hover:border-primary-300 hover:bg-primary-50 transition-all duration-200 text-sm font-medium text-foreground flex items-center space-x-2"
256
  title="Left click to edit, Right click to delete"
257
  >
258
  <span className="text-primary-600">{modelName}</span>
259
+ <span className="text-foreground">L{block[0]}</span>
 
 
260
  <span className="text-accent-600">
261
  {Math.round(block[2] * 100)}%
262
  </span>
263
  <svg
264
+ className={`w-4 h-4 text-foreground transition-transform duration-200 ${
265
  isExpanded ? "rotate-180" : ""
266
  }`}
267
  fill="none"
 
279
 
280
  {isExpanded && (
281
  <div
282
+ className="absolute top-full left-0 mt-1 p-3 bg-background border-2 border-primary-200 rounded-lg shadow-lg z-10 min-w-64"
283
  data-block-id={blockId}
284
  >
285
  <div className="space-y-3">
286
  <div>
287
+ <label className="block text-xs font-medium text-foreground mb-1">
288
  Model
289
  </label>
290
  <Dropdown
 
307
 
308
  <div className="grid grid-cols-2 gap-3">
309
  <div>
310
+ <label className="block text-xs font-medium text-foreground mb-1">
311
  Layer
312
  </label>
313
  <NumberInput
 
335
  </div>
336
 
337
  <div>
338
+ <label className="block text-xs font-medium text-foreground mb-1">
339
  Weight (%)
340
  </label>
341
  <NumberInput
 
364
  );
365
  setExpandedBlock(null);
366
  }}
367
+ className="w-full px-3 py-2 bg-red-800 text-background rounded-lg hover:bg-red-700 transition-colors duration-200 text-sm font-medium"
368
  >
369
  Remove Block
370
  </button>
frontend/src/index.css CHANGED
@@ -1,38 +1,249 @@
1
  @import "tailwindcss";
2
 
3
  @theme {
4
- --color-primary-50: #f0f9ff;
5
- --color-primary-100: #e0f2fe;
6
- --color-primary-200: #bae6fd;
7
- --color-primary-300: #7dd3fc;
8
- --color-primary-400: #38bdf8;
9
- --color-primary-500: #0ea5e9;
10
- --color-primary-600: #0284c7;
11
- --color-primary-700: #0369a1;
12
- --color-primary-800: #075985;
13
- --color-primary-900: #0c4a6e;
14
 
15
- --color-secondary-50: #f8fafc;
16
- --color-secondary-100: #f1f5f9;
17
- --color-secondary-200: #e2e8f0;
18
- --color-secondary-300: #cbd5e1;
19
- --color-secondary-400: #94a3b8;
20
- --color-secondary-500: #64748b;
21
- --color-secondary-600: #475569;
22
- --color-secondary-700: #334155;
23
- --color-secondary-800: #1e293b;
24
- --color-secondary-900: #0f172a;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
- --color-accent-50: #f0fdf4;
27
- --color-accent-100: #dcfce7;
28
- --color-accent-200: #bbf7d0;
29
- --color-accent-300: #86efac;
30
- --color-accent-400: #4ade80;
31
- --color-accent-500: #22c55e;
32
- --color-accent-600: #16a34a;
33
- --color-accent-700: #15803d;
34
- --color-accent-800: #166534;
35
- --color-accent-900: #14532d;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  }
37
 
38
  :root {
@@ -64,13 +275,13 @@ body {
64
  }
65
 
66
  ::-webkit-scrollbar-thumb {
67
- background: #0ea5e9;
68
  border-radius: 4px;
69
  transition: background 0.2s ease;
70
  }
71
 
72
  ::-webkit-scrollbar-thumb:hover {
73
- background: #0284c7;
74
  }
75
 
76
  ::-webkit-scrollbar-corner {
@@ -80,5 +291,5 @@ body {
80
  /* Firefox scrollbar styling */
81
  * {
82
  scrollbar-width: thin;
83
- scrollbar-color: #0ea5e9 transparent;
84
  }
 
1
  @import "tailwindcss";
2
 
3
  @theme {
4
+ /* Tokyo Night Light - Background and Foreground */
5
+ --color-background: #e6e7ed;
6
+ --color-foreground: #343b58;
 
 
 
 
 
 
 
7
 
8
+ /* Tokyo Night Light - Primary (8C4351 - HSL: 0.97, 0.35, 0.41) */
9
+ --color-primary-50: hsl(
10
+ calc(0.97 * 360),
11
+ calc(0.35 * 100%),
12
+ calc(0.41 * 100% + 45%)
13
+ );
14
+ --color-primary-100: hsl(
15
+ calc(0.97 * 360),
16
+ calc(0.35 * 100%),
17
+ calc(0.41 * 100% + 40%)
18
+ );
19
+ --color-primary-200: hsl(
20
+ calc(0.97 * 360),
21
+ calc(0.35 * 100%),
22
+ calc(0.41 * 100% + 30%)
23
+ );
24
+ --color-primary-300: hsl(
25
+ calc(0.97 * 360),
26
+ calc(0.35 * 100%),
27
+ calc(0.41 * 100% + 20%)
28
+ );
29
+ --color-primary-400: hsl(
30
+ calc(0.97 * 360),
31
+ calc(0.35 * 100%),
32
+ calc(0.41 * 100% + 10%)
33
+ );
34
+ --color-primary-500: #8c4351;
35
+ --color-primary-600: hsl(
36
+ calc(0.97 * 360),
37
+ calc(0.35 * 100%),
38
+ calc(0.41 * 100% - 5%)
39
+ );
40
+ --color-primary-700: hsl(
41
+ calc(0.97 * 360),
42
+ calc(0.35 * 100%),
43
+ calc(0.41 * 100% - 10%)
44
+ );
45
+ --color-primary-800: hsl(
46
+ calc(0.97 * 360),
47
+ calc(0.35 * 100%),
48
+ calc(0.41 * 100% - 15%)
49
+ );
50
+ --color-primary-900: hsl(
51
+ calc(0.97 * 360),
52
+ calc(0.35 * 100%),
53
+ calc(0.41 * 100% - 20%)
54
+ );
55
 
56
+ /* Tokyo Night Light - Secondary (343b58 - HSL: 0.63, 0.26, 0.29) */
57
+ --color-secondary-50: hsl(
58
+ calc(0.63 * 360),
59
+ calc(0.26 * 100%),
60
+ calc(0.29 * 100% + 55%)
61
+ );
62
+ --color-secondary-100: hsl(
63
+ calc(0.63 * 360),
64
+ calc(0.26 * 100%),
65
+ calc(0.29 * 100% + 45%)
66
+ );
67
+ --color-secondary-200: hsl(
68
+ calc(0.63 * 360),
69
+ calc(0.26 * 100%),
70
+ calc(0.29 * 100% + 35%)
71
+ );
72
+ --color-secondary-300: hsl(
73
+ calc(0.63 * 360),
74
+ calc(0.26 * 100%),
75
+ calc(0.29 * 100% + 25%)
76
+ );
77
+ --color-secondary-400: hsl(
78
+ calc(0.63 * 360),
79
+ calc(0.26 * 100%),
80
+ calc(0.29 * 100% + 15%)
81
+ );
82
+ --color-secondary-500: hsl(
83
+ calc(0.63 * 360),
84
+ calc(0.26 * 100%),
85
+ calc(0.29 * 100% + 5%)
86
+ );
87
+ --color-secondary-600: #343b58;
88
+ --color-secondary-700: hsl(
89
+ calc(0.63 * 360),
90
+ calc(0.26 * 100%),
91
+ calc(0.29 * 100% - 5%)
92
+ );
93
+ --color-secondary-800: hsl(
94
+ calc(0.63 * 360),
95
+ calc(0.26 * 100%),
96
+ calc(0.29 * 100% - 10%)
97
+ );
98
+ --color-secondary-900: hsl(
99
+ calc(0.63 * 360),
100
+ calc(0.26 * 100%),
101
+ calc(0.29 * 100% - 15%)
102
+ );
103
+
104
+ /* Tokyo Night Light - Accent (2959aa - HSL: 0.60, 0.61, 0.41) */
105
+ --color-accent-50: hsl(
106
+ calc(0.6 * 360),
107
+ calc(0.61 * 100%),
108
+ calc(0.41 * 100% + 45%)
109
+ );
110
+ --color-accent-100: hsl(
111
+ calc(0.6 * 360),
112
+ calc(0.61 * 100%),
113
+ calc(0.41 * 100% + 40%)
114
+ );
115
+ --color-accent-200: hsl(
116
+ calc(0.6 * 360),
117
+ calc(0.61 * 100%),
118
+ calc(0.41 * 100% + 30%)
119
+ );
120
+ --color-accent-300: hsl(
121
+ calc(0.6 * 360),
122
+ calc(0.61 * 100%),
123
+ calc(0.41 * 100% + 20%)
124
+ );
125
+ --color-accent-400: hsl(
126
+ calc(0.6 * 360),
127
+ calc(0.61 * 100%),
128
+ calc(0.41 * 100% + 10%)
129
+ );
130
+ --color-accent-500: #2959aa;
131
+ --color-accent-600: hsl(
132
+ calc(0.6 * 360),
133
+ calc(0.61 * 100%),
134
+ calc(0.41 * 100% - 5%)
135
+ );
136
+ --color-accent-700: hsl(
137
+ calc(0.6 * 360),
138
+ calc(0.61 * 100%),
139
+ calc(0.41 * 100% - 10%)
140
+ );
141
+ --color-accent-800: hsl(
142
+ calc(0.6 * 360),
143
+ calc(0.61 * 100%),
144
+ calc(0.41 * 100% - 15%)
145
+ );
146
+ --color-accent-900: hsl(
147
+ calc(0.6 * 360),
148
+ calc(0.61 * 100%),
149
+ calc(0.41 * 100% - 20%)
150
+ );
151
+
152
+ /* Red color scheme (8C4351 - HSL: 0.97, 0.35, 0.41) */
153
+ --color-red-50: hsl(
154
+ calc(0.97 * 360),
155
+ calc(0.35 * 100%),
156
+ calc(0.41 * 100% + 45%)
157
+ );
158
+ --color-red-100: hsl(
159
+ calc(0.97 * 360),
160
+ calc(0.35 * 100%),
161
+ calc(0.41 * 100% + 35%)
162
+ );
163
+ --color-red-200: hsl(
164
+ calc(0.97 * 360),
165
+ calc(0.35 * 100%),
166
+ calc(0.41 * 100% + 25%)
167
+ );
168
+ --color-red-300: hsl(
169
+ calc(0.97 * 360),
170
+ calc(0.35 * 100%),
171
+ calc(0.41 * 100% + 15%)
172
+ );
173
+ --color-red-400: hsl(
174
+ calc(0.97 * 360),
175
+ calc(0.35 * 100%),
176
+ calc(0.41 * 100% + 5%)
177
+ );
178
+ --color-red-500: #8c4351;
179
+ --color-red-600: hsl(
180
+ calc(0.97 * 360),
181
+ calc(0.35 * 100%),
182
+ calc(0.41 * 100% - 5%)
183
+ );
184
+ --color-red-700: hsl(
185
+ calc(0.97 * 360),
186
+ calc(0.35 * 100%),
187
+ calc(0.41 * 100% - 10%)
188
+ );
189
+ --color-red-800: hsl(
190
+ calc(0.97 * 360),
191
+ calc(0.35 * 100%),
192
+ calc(0.41 * 100% - 15%)
193
+ );
194
+ --color-red-900: hsl(
195
+ calc(0.97 * 360),
196
+ calc(0.35 * 100%),
197
+ calc(0.41 * 100% - 20%)
198
+ );
199
+
200
+ /* Green color scheme (385f0d - HSL: 0.25, 0.76, 0.21) */
201
+ --color-green-50: hsl(
202
+ calc(0.25 * 360),
203
+ calc(0.76 * 100%),
204
+ calc(0.21 * 100% + 60%)
205
+ );
206
+ --color-green-100: hsl(
207
+ calc(0.25 * 360),
208
+ calc(0.76 * 100%),
209
+ calc(0.21 * 100% + 50%)
210
+ );
211
+ --color-green-200: hsl(
212
+ calc(0.25 * 360),
213
+ calc(0.76 * 100%),
214
+ calc(0.21 * 100% + 40%)
215
+ );
216
+ --color-green-300: hsl(
217
+ calc(0.25 * 360),
218
+ calc(0.76 * 100%),
219
+ calc(0.21 * 100% + 30%)
220
+ );
221
+ --color-green-400: hsl(
222
+ calc(0.25 * 360),
223
+ calc(0.76 * 100%),
224
+ calc(0.21 * 100% + 20%)
225
+ );
226
+ --color-green-500: #385f0d;
227
+ --color-green-600: hsl(
228
+ calc(0.25 * 360),
229
+ calc(0.76 * 100%),
230
+ calc(0.21 * 100% - 3%)
231
+ );
232
+ --color-green-700: hsl(
233
+ calc(0.25 * 360),
234
+ calc(0.76 * 100%),
235
+ calc(0.21 * 100% - 6%)
236
+ );
237
+ --color-green-800: hsl(
238
+ calc(0.25 * 360),
239
+ calc(0.76 * 100%),
240
+ calc(0.21 * 100% - 9%)
241
+ );
242
+ --color-green-900: hsl(
243
+ calc(0.25 * 360),
244
+ calc(0.76 * 100%),
245
+ calc(0.21 * 100% - 12%)
246
+ );
247
  }
248
 
249
  :root {
 
275
  }
276
 
277
  ::-webkit-scrollbar-thumb {
278
+ background: var(--color-accent-500);
279
  border-radius: 4px;
280
  transition: background 0.2s ease;
281
  }
282
 
283
  ::-webkit-scrollbar-thumb:hover {
284
+ background: var(--color-accent-600);
285
  }
286
 
287
  ::-webkit-scrollbar-corner {
 
291
  /* Firefox scrollbar styling */
292
  * {
293
  scrollbar-width: thin;
294
+ scrollbar-color: var(--color-accent-500) transparent;
295
  }