1use std::time::Duration;
2
3use freya_core::prelude::*;
4#[cfg(feature = "titlebar")]
5use torin::prelude::Length;
6use torin::{
7 gaps::Gaps,
8 size::Size,
9};
10
11#[cfg(feature = "calendar")]
12use crate::calendar::CalendarThemePreference;
13#[cfg(feature = "router")]
14use crate::link::LinkThemePreference;
15#[cfg(feature = "markdown")]
16use crate::markdown::MarkdownViewerThemePreference;
17#[cfg(feature = "titlebar")]
18use crate::titlebar::TitlebarButtonThemePreference;
19use crate::{
20 accordion::AccordionThemePreference,
21 button::{
22 ButtonColorsThemePreference,
23 ButtonLayoutThemePreference,
24 },
25 card::{
26 CardColorsThemePreference,
27 CardLayoutThemePreference,
28 },
29 checkbox::CheckboxThemePreference,
30 chip::ChipThemePreference,
31 color_picker::ColorPickerThemePreference,
32 floating_tab::FloatingTabThemePreference,
33 input::{
34 InputColorsThemePreference,
35 InputLayoutThemePreference,
36 },
37 loader::CircularLoaderThemePreference,
38 menu::{
39 MenuContainerThemePreference,
40 MenuItemThemePreference,
41 },
42 popup::PopupThemePreference,
43 progressbar::ProgressBarThemePreference,
44 radio_item::RadioItemThemePreference,
45 resizable_container::ResizableHandleThemePreference,
46 scrollviews::ScrollBarThemePreference,
47 segmented_button::{
48 ButtonSegmentThemePreference,
49 SegmentedButtonThemePreference,
50 },
51 select::SelectThemePreference,
52 sidebar::SideBarItemThemePreference,
53 skeleton::{
54 SkeletonAnimation,
55 SkeletonThemePreference,
56 },
57 slider::SliderThemePreference,
58 switch::{
59 SwitchColorsThemePreference,
60 SwitchLayoutThemePreference,
61 },
62 table::TableThemePreference,
63 theming::{
64 component_themes::{
65 ColorsSheet,
66 Theme,
67 },
68 macros::Preference,
69 },
70 tooltip::TooltipThemePreference,
71};
72
73pub const LIGHT_COLORS: ColorsSheet = ColorsSheet {
74 primary: Color::from_rgb(103, 80, 164),
76 secondary: Color::from_rgb(202, 193, 227),
77 tertiary: Color::from_rgb(79, 61, 130),
78
79 success: Color::from_rgb(76, 175, 80),
81 warning: Color::from_rgb(255, 193, 7),
82 error: Color::from_rgb(244, 67, 54),
83 info: Color::from_rgb(33, 150, 243),
84
85 background: Color::from_rgb(250, 250, 250),
87 surface_primary: Color::from_rgb(210, 210, 210),
88 surface_secondary: Color::from_rgb(225, 225, 225),
89 surface_tertiary: Color::from_rgb(245, 245, 245),
90 surface_inverse: Color::from_rgb(125, 125, 125),
91 surface_inverse_secondary: Color::from_rgb(110, 110, 110),
92 surface_inverse_tertiary: Color::from_rgb(90, 90, 90),
93
94 border: Color::from_rgb(210, 210, 210),
96 border_focus: Color::from_rgb(180, 180, 180),
97 border_disabled: Color::from_rgb(210, 210, 210),
98
99 text_primary: Color::from_rgb(10, 10, 10),
101 text_secondary: Color::from_rgb(100, 100, 100),
102 text_placeholder: Color::from_rgb(150, 150, 150),
103 text_inverse: Color::WHITE,
104 text_highlight: Color::from_rgb(38, 89, 170),
105
106 hover: Color::from_rgb(235, 235, 235),
108 focus: Color::from_rgb(225, 225, 255),
109 active: Color::from_rgb(200, 200, 200),
110 disabled: Color::from_rgb(210, 210, 210),
111
112 overlay: Color::from_af32rgb(0.5, 0, 0, 0),
114 shadow: Color::from_af32rgb(0.2, 0, 0, 0),
115};
116
117pub const DARK_COLORS: ColorsSheet = ColorsSheet {
118 primary: Color::from_rgb(103, 80, 164),
120 secondary: Color::from_rgb(202, 193, 227),
121 tertiary: Color::from_rgb(79, 61, 130),
122
123 success: Color::from_rgb(129, 199, 132),
125 warning: Color::from_rgb(255, 213, 79),
126 error: Color::from_rgb(229, 115, 115),
127 info: Color::from_rgb(100, 181, 246),
128
129 background: Color::from_rgb(20, 20, 20),
131 surface_primary: Color::from_rgb(60, 60, 60),
132 surface_secondary: Color::from_rgb(45, 45, 45),
133 surface_tertiary: Color::from_rgb(25, 25, 25),
134 surface_inverse: Color::from_rgb(135, 135, 135),
135 surface_inverse_secondary: Color::from_rgb(150, 150, 150),
136 surface_inverse_tertiary: Color::from_rgb(170, 170, 170),
137
138 border: Color::from_rgb(60, 60, 60),
140 border_focus: Color::from_rgb(110, 110, 110),
141 border_disabled: Color::from_rgb(80, 80, 80),
142
143 text_primary: Color::from_rgb(250, 250, 250),
145 text_secondary: Color::from_rgb(210, 210, 210),
146 text_placeholder: Color::from_rgb(150, 150, 150),
147 text_inverse: Color::WHITE,
148 text_highlight: Color::from_rgb(96, 145, 224),
149
150 hover: Color::from_rgb(80, 80, 80),
152 focus: Color::from_rgb(100, 100, 120),
153 active: Color::from_rgb(70, 70, 70),
154 disabled: Color::from_rgb(50, 50, 50),
155
156 overlay: Color::from_af32rgb(0.2, 255, 255, 255),
158 shadow: Color::from_af32rgb(0.6, 0, 0, 0),
159};
160
161fn register_base_component_themes(theme: &mut Theme) {
162 theme.set(
163 "button_layout",
164 ButtonLayoutThemePreference {
165 padding: Preference::Specific(Gaps::new(6., 12., 6., 12.)),
166 margin: Preference::Specific(Gaps::new_all(0.)),
167 corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
168 width: Preference::Specific(Size::Inner),
169 height: Preference::Specific(Size::Inner),
170 },
171 );
172 theme.set(
173 "compact_button_layout",
174 ButtonLayoutThemePreference {
175 padding: Preference::Specific(Gaps::new(3., 6., 3., 6.)),
176 margin: Preference::Specific(Gaps::new_all(0.)),
177 corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
178 width: Preference::Specific(Size::Inner),
179 height: Preference::Specific(Size::Inner),
180 },
181 );
182 theme.set(
183 "expanded_button_layout",
184 ButtonLayoutThemePreference {
185 padding: Preference::Specific(Gaps::new(10., 16., 10., 16.)),
186 margin: Preference::Specific(Gaps::new_all(0.)),
187 corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
188 width: Preference::Specific(Size::Inner),
189 height: Preference::Specific(Size::Inner),
190 },
191 );
192 theme.set(
193 "button",
194 ButtonColorsThemePreference {
195 background: Preference::Reference("surface_tertiary"),
196 hover_background: Preference::Reference("hover"),
197 border_fill: Preference::Reference("border"),
198 focus_border_fill: Preference::Reference("border_focus"),
199 color: Preference::Reference("text_primary"),
200 },
201 );
202 theme.set(
203 "filled_button",
204 ButtonColorsThemePreference {
205 background: Preference::Reference("primary"),
206 hover_background: Preference::Reference("tertiary"),
207 border_fill: Preference::Specific(Color::TRANSPARENT),
208 focus_border_fill: Preference::Reference("secondary"),
209 color: Preference::Reference("text_inverse"),
210 },
211 );
212 theme.set(
213 "outline_button",
214 ButtonColorsThemePreference {
215 background: Preference::Reference("surface_tertiary"),
216 hover_background: Preference::Reference("hover"),
217 border_fill: Preference::Reference("border"),
218 focus_border_fill: Preference::Reference("secondary"),
219 color: Preference::Reference("primary"),
220 },
221 );
222 theme.set(
223 "flat_button",
224 ButtonColorsThemePreference {
225 background: Preference::Specific(Color::TRANSPARENT),
226 hover_background: Preference::Reference("surface_tertiary"),
227 border_fill: Preference::Specific(Color::TRANSPARENT),
228 focus_border_fill: Preference::Reference("border"),
229 color: Preference::Reference("text_primary"),
230 },
231 );
232 theme.set(
233 "card_layout",
234 CardLayoutThemePreference {
235 padding: Preference::Specific(Gaps::new(16., 16., 16., 16.)),
236 corner_radius: Preference::Specific(CornerRadius::new_all(8.)),
237 },
238 );
239 theme.set(
240 "compact_card_layout",
241 CardLayoutThemePreference {
242 padding: Preference::Specific(Gaps::new(8., 12., 8., 12.)),
243 corner_radius: Preference::Specific(CornerRadius::new_all(8.)),
244 },
245 );
246 theme.set(
247 "filled_card",
248 CardColorsThemePreference {
249 background: Preference::Reference("primary"),
250 hover_background: Preference::Reference("tertiary"),
251 border_fill: Preference::Specific(Color::TRANSPARENT),
252 color: Preference::Reference("text_inverse"),
253 shadow: Preference::Reference("shadow"),
254 },
255 );
256 theme.set(
257 "outline_card",
258 CardColorsThemePreference {
259 background: Preference::Reference("surface_tertiary"),
260 hover_background: Preference::Reference("hover"),
261 border_fill: Preference::Reference("border"),
262 color: Preference::Reference("text_primary"),
263 shadow: Preference::Reference("shadow"),
264 },
265 );
266 theme.set(
267 "accordion",
268 AccordionThemePreference {
269 color: Preference::Reference("text_primary"),
270 background: Preference::Reference("surface_tertiary"),
271 border_fill: Preference::Reference("border"),
272 },
273 );
274 theme.set(
275 "switch",
276 SwitchColorsThemePreference {
277 background: Preference::Reference("surface_secondary"),
278 thumb_background: Preference::Reference("surface_inverse"),
279 toggled_background: Preference::Reference("secondary"),
280 toggled_thumb_background: Preference::Reference("primary"),
281 focus_border_fill: Preference::Reference("border_focus"),
282 },
283 );
284 theme.set(
285 "switch_layout",
286 SwitchLayoutThemePreference {
287 margin: Preference::Specific(Gaps::new_all(0.)),
288 width: Preference::Specific(48.),
289 height: Preference::Specific(28.),
290 padding: Preference::Specific(4.),
291 thumb_size: Preference::Specific(16.),
292 toggled_thumb_size: Preference::Specific(20.),
293 pressed_thumb_size_offset: Preference::Specific(4.),
294 thumb_offset: Preference::Specific(2.),
295 toggled_thumb_offset: Preference::Specific(20.),
296 },
297 );
298 theme.set(
299 "expanded_switch_layout",
300 SwitchLayoutThemePreference {
301 margin: Preference::Specific(Gaps::new_all(0.)),
302 width: Preference::Specific(56.),
303 height: Preference::Specific(32.),
304 padding: Preference::Specific(4.),
305 thumb_size: Preference::Specific(18.),
306 toggled_thumb_size: Preference::Specific(22.),
307 pressed_thumb_size_offset: Preference::Specific(4.),
308 thumb_offset: Preference::Specific(2.),
309 toggled_thumb_offset: Preference::Specific(26.),
310 },
311 );
312 theme.set(
313 "scrollbar",
314 ScrollBarThemePreference {
315 background: Preference::Reference("surface_primary"),
316 thumb_background: Preference::Reference("surface_inverse"),
317 hover_thumb_background: Preference::Reference("surface_inverse_secondary"),
318 active_thumb_background: Preference::Reference("surface_inverse_tertiary"),
319 size: Preference::Specific(15.),
320 },
321 );
322 theme.set(
323 "progressbar",
324 ProgressBarThemePreference {
325 color: Preference::Reference("text_inverse"),
326 background: Preference::Reference("surface_primary"),
327 progress_background: Preference::Reference("primary"),
328 height: Preference::Specific(20.),
329 },
330 );
331 theme.set(
332 "sidebar_item",
333 SideBarItemThemePreference {
334 color: Preference::Reference("text_primary"),
335 background: Preference::Reference("surface_tertiary"),
336 active_background: Preference::Reference("surface_secondary"),
337 hover_background: Preference::Reference("hover"),
338 corner_radius: Preference::Specific(CornerRadius::new_all(12.)),
339 margin: Preference::Specific(Gaps::new_all(0.)),
340 padding: Preference::Specific(Gaps::new(8., 12., 8., 12.)),
341 },
342 );
343 #[cfg(feature = "router")]
344 theme.set(
345 "link",
346 LinkThemePreference {
347 color: Preference::Reference("text_highlight"),
348 },
349 );
350 theme.set(
351 "tooltip",
352 TooltipThemePreference {
353 background: Preference::Reference("surface_tertiary"),
354 color: Preference::Reference("text_primary"),
355 border_fill: Preference::Reference("surface_primary"),
356 font_size: Preference::Specific(14.),
357 },
358 );
359 theme.set(
360 "circular_loader",
361 CircularLoaderThemePreference {
362 primary_color: Preference::Reference("surface_primary"),
363 inversed_color: Preference::Reference("surface_inverse"),
364 },
365 );
366 theme.set(
367 "input_layout",
368 InputLayoutThemePreference {
369 corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
370 inner_margin: Preference::Specific(Gaps::new(8., 8., 8., 8.)),
371 },
372 );
373 theme.set(
374 "compact_input_layout",
375 InputLayoutThemePreference {
376 corner_radius: Preference::Specific(CornerRadius::new_all(4.)),
377 inner_margin: Preference::Specific(Gaps::new(4., 6., 4., 6.)),
378 },
379 );
380 theme.set(
381 "expanded_input_layout",
382 InputLayoutThemePreference {
383 corner_radius: Preference::Specific(CornerRadius::new_all(8.)),
384 inner_margin: Preference::Specific(Gaps::new(12., 12., 12., 12.)),
385 },
386 );
387 theme.set(
388 "input",
389 InputColorsThemePreference {
390 background: Preference::Reference("surface_tertiary"),
391 hover_background: Preference::Reference("background"),
392 color: Preference::Reference("text_primary"),
393 placeholder_color: Preference::Reference("text_secondary"),
394 border_fill: Preference::Reference("border"),
395 focus_border_fill: Preference::Reference("border_focus"),
396 },
397 );
398 theme.set(
399 "filled_input",
400 InputColorsThemePreference {
401 background: Preference::Reference("primary"),
402 hover_background: Preference::Reference("tertiary"),
403 color: Preference::Reference("text_inverse"),
404 placeholder_color: Preference::Reference("text_inverse"),
405 border_fill: Preference::Specific(Color::TRANSPARENT),
406 focus_border_fill: Preference::Reference("secondary"),
407 },
408 );
409 theme.set(
410 "flat_input",
411 InputColorsThemePreference {
412 background: Preference::Specific(Color::TRANSPARENT),
413 hover_background: Preference::Reference("surface_tertiary"),
414 color: Preference::Reference("text_primary"),
415 placeholder_color: Preference::Reference("text_secondary"),
416 border_fill: Preference::Specific(Color::TRANSPARENT),
417 focus_border_fill: Preference::Reference("border"),
418 },
419 );
420 theme.set(
421 "radio",
422 RadioItemThemePreference {
423 unselected_fill: Preference::Reference("surface_inverse_tertiary"),
424 selected_fill: Preference::Reference("primary"),
425 border_fill: Preference::Reference("surface_primary"),
426 },
427 );
428 theme.set(
429 "checkbox",
430 CheckboxThemePreference {
431 unselected_fill: Preference::Reference("surface_inverse_tertiary"),
432 selected_fill: Preference::Reference("primary"),
433 selected_icon_fill: Preference::Reference("secondary"),
434 border_fill: Preference::Reference("surface_primary"),
435 },
436 );
437 theme.set(
438 "resizable_handle",
439 ResizableHandleThemePreference {
440 background: Preference::Reference("surface_secondary"),
441 hover_background: Preference::Reference("surface_primary"),
442 corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
443 },
444 );
445 theme.set(
446 "floating_tab",
447 FloatingTabThemePreference {
448 background: Preference::Specific(Color::TRANSPARENT),
449 hover_background: Preference::Reference("surface_secondary"),
450 color: Preference::Reference("text_primary"),
451 padding: Preference::Specific(Gaps::new(6., 12., 6., 12.)),
452 width: Preference::Specific(Size::Inner),
453 height: Preference::Specific(Size::Inner),
454 corner_radius: Preference::Specific(CornerRadius::new_all(99.)),
455 },
456 );
457 theme.set(
458 "slider",
459 SliderThemePreference {
460 background: Preference::Reference("surface_primary"),
461 thumb_background: Preference::Reference("secondary"),
462 thumb_inner_background: Preference::Reference("primary"),
463 border_fill: Preference::Reference("surface_primary"),
464 },
465 );
466 theme.set(
467 "color_picker",
468 ColorPickerThemePreference {
469 background: Preference::Reference("surface_tertiary"),
470 border_fill: Preference::Reference("border"),
471 color: Preference::Reference("text_primary"),
472 },
473 );
474 theme.set(
475 "select",
476 SelectThemePreference {
477 width: Preference::Specific(Size::Inner),
478 margin: Preference::Specific(Gaps::new_all(0.)),
479 select_background: Preference::Reference("background"),
480 background_button: Preference::Reference("surface_tertiary"),
481 hover_background: Preference::Reference("hover"),
482 color: Preference::Reference("text_primary"),
483 border_fill: Preference::Reference("border"),
484 focus_border_fill: Preference::Reference("border_focus"),
485 arrow_fill: Preference::Reference("text_primary"),
486 },
487 );
488 theme.set(
489 "popup",
490 PopupThemePreference {
491 background: Preference::Reference("background"),
492 color: Preference::Reference("text_primary"),
493 },
494 );
495 theme.set(
496 "table",
497 TableThemePreference {
498 background: Preference::Reference("background"),
499 arrow_fill: Preference::Reference("text_primary"),
500 row_background: Preference::Specific(Color::TRANSPARENT),
501 hover_row_background: Preference::Reference("surface_secondary"),
502 divider_fill: Preference::Reference("surface_primary"),
503 corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
504 color: Preference::Reference("text_primary"),
505 },
506 );
507 #[cfg(feature = "markdown")]
508 theme.set(
509 "markdown_viewer",
510 MarkdownViewerThemePreference {
511 color: Preference::Reference("text_primary"),
512 background_code: Preference::Reference("surface_tertiary"),
513 color_code: Preference::Reference("text_primary"),
514 background_blockquote: Preference::Reference("surface_tertiary"),
515 border_blockquote: Preference::Reference("surface_primary"),
516 background_divider: Preference::Reference("border"),
517 heading_h1: Preference::Specific(32.0),
518 heading_h2: Preference::Specific(28.0),
519 heading_h3: Preference::Specific(24.0),
520 heading_h4: Preference::Specific(20.0),
521 heading_h5: Preference::Specific(18.0),
522 heading_h6: Preference::Specific(16.0),
523 paragraph_size: Preference::Specific(16.0),
524 code_font_size: Preference::Specific(14.0),
525 table_font_size: Preference::Specific(14.0),
526 },
527 );
528 theme.set(
529 "chip",
530 ChipThemePreference {
531 background: Preference::Reference("background"),
532 hover_background: Preference::Reference("tertiary"),
533 selected_background: Preference::Reference("primary"),
534 border_fill: Preference::Reference("border"),
535 hover_border_fill: Preference::Reference("tertiary"),
536 selected_border_fill: Preference::Reference("primary"),
537 focus_border_fill: Preference::Reference("secondary"),
538 padding: Preference::Specific(Gaps::new(8., 14., 8., 14.)),
539 margin: Preference::Specific(0.),
540 corner_radius: Preference::Specific(CornerRadius::new_all(99.)),
541 width: Preference::Specific(Size::Inner),
542 height: Preference::Specific(Size::Inner),
543 color: Preference::Reference("text_primary"),
544 hover_color: Preference::Reference("text_inverse"),
545 selected_color: Preference::Reference("text_inverse"),
546 selected_icon_fill: Preference::Reference("secondary"),
547 hover_icon_fill: Preference::Reference("secondary"),
548 },
549 );
550 theme.set(
551 "menu_item",
552 MenuItemThemePreference {
553 background: Preference::Specific(Color::TRANSPARENT),
554 hover_background: Preference::Reference("surface_secondary"),
555 select_background: Preference::Reference("surface_secondary"),
556 border_fill: Preference::Specific(Color::TRANSPARENT),
557 select_border_fill: Preference::Reference("border_focus"),
558 corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
559 color: Preference::Reference("text_primary"),
560 },
561 );
562 theme.set(
563 "menu_container",
564 MenuContainerThemePreference {
565 background: Preference::Reference("background"),
566 padding: Preference::Specific(Gaps::new_all(4.)),
567 shadow: Preference::Reference("shadow"),
568 border_fill: Preference::Reference("surface_primary"),
569 corner_radius: Preference::Specific(CornerRadius::new_all(8.)),
570 },
571 );
572 theme.set(
573 "button_segment",
574 ButtonSegmentThemePreference {
575 background: Preference::Reference("surface_tertiary"),
576 hover_background: Preference::Reference("hover"),
577 disabled_background: Preference::Reference("disabled"),
578 selected_background: Preference::Reference("hover"),
579 focus_background: Preference::Reference("surface_secondary"),
580 padding: Preference::Specific(Gaps::new(8., 16., 8., 16.)),
581 selected_padding: Preference::Specific(Gaps::new(8., 12., 8., 12.)),
582 width: Preference::Specific(Size::Inner),
583 height: Preference::Specific(Size::Inner),
584 color: Preference::Reference("text_primary"),
585 selected_icon_fill: Preference::Reference("primary"),
586 },
587 );
588 theme.set(
589 "segmented_button",
590 SegmentedButtonThemePreference {
591 background: Preference::Reference("surface_tertiary"),
592 border_fill: Preference::Reference("border"),
593 corner_radius: Preference::Specific(CornerRadius::new_all(99.)),
594 },
595 );
596 #[cfg(feature = "calendar")]
597 theme.set(
598 "calendar",
599 CalendarThemePreference {
600 background: Preference::Reference("surface_tertiary"),
601 day_background: Preference::Specific(Color::TRANSPARENT),
602 day_hover_background: Preference::Reference("hover"),
603 day_selected_background: Preference::Reference("surface_primary"),
604 color: Preference::Reference("text_primary"),
605 day_other_month_color: Preference::Reference("text_placeholder"),
606 header_color: Preference::Reference("text_primary"),
607 corner_radius: Preference::Specific(CornerRadius::new_all(8.)),
608 padding: Preference::Specific(Gaps::new_all(12.)),
609 day_corner_radius: Preference::Specific(CornerRadius::new_all(6.)),
610 nav_button_hover_background: Preference::Reference("hover"),
611 },
612 );
613 #[cfg(feature = "titlebar")]
614 theme.set(
615 "titlebar_button",
616 TitlebarButtonThemePreference {
617 background: Preference::Specific(Color::TRANSPARENT),
618 hover_background: Preference::Reference("hover"),
619 corner_radius: Preference::Specific(CornerRadius::new_all(0.0)),
620 width: Preference::Specific(Size::Pixels(Length::new(46.0))),
621 height: Preference::Specific(Size::Fill),
622 },
623 );
624 theme.set(
625 "skeleton",
626 SkeletonThemePreference {
627 background: Preference::Reference("surface_primary"),
628 shimmer_color: Preference::Specific(Color::WHITE.with_a(160)),
629 duration: Preference::Specific(Duration::from_millis(1000)),
630 animation: Preference::Specific(SkeletonAnimation::Pulse),
631 corner_radius: Preference::Specific(CornerRadius::new_all(4.)),
632 shimmer_from: Preference::Specific(-320.),
633 shimmer_to: Preference::Specific(960.),
634 shimmer_width: Preference::Specific(300.),
635 },
636 );
637}
638
639pub fn light_theme() -> Theme {
641 let mut theme = Theme::new("light", LIGHT_COLORS);
642 register_base_component_themes(&mut theme);
643 theme
644}
645
646pub fn dark_theme() -> Theme {
648 let mut theme = Theme::new("dark", DARK_COLORS);
649 register_base_component_themes(&mut theme);
650 theme
651}