From 11287c882e23e1f3081d06bf5ff3e99a02ef030a Mon Sep 17 00:00:00 2001 From: Cory Forsstrom Date: Wed, 12 Jul 2023 16:30:12 -0700 Subject: [PATCH 001/321] Expose methods to change viewport alignment --- widget/src/scrollable.rs | 59 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index 88746ac4..3f49584c 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -554,7 +554,14 @@ pub fn update( state.scroll(delta, direction, bounds, content_bounds); - notify_on_scroll(state, on_scroll, bounds, content_bounds, shell); + notify_on_scroll( + state, + on_scroll, + bounds, + content_bounds, + direction, + shell, + ); return event::Status::Captured; } @@ -592,6 +599,7 @@ pub fn update( on_scroll, bounds, content_bounds, + direction, shell, ); } @@ -637,6 +645,7 @@ pub fn update( on_scroll, bounds, content_bounds, + direction, shell, ); @@ -672,6 +681,7 @@ pub fn update( on_scroll, bounds, content_bounds, + direction, shell, ); } @@ -712,6 +722,7 @@ pub fn update( on_scroll, bounds, content_bounds, + direction, shell, ); } @@ -747,6 +758,7 @@ pub fn update( on_scroll, bounds, content_bounds, + direction, shell, ); @@ -962,6 +974,7 @@ fn notify_on_scroll( on_scroll: &Option Message + '_>>, bounds: Rectangle, content_bounds: Rectangle, + direction: Direction, shell: &mut Shell<'_, Message>, ) { if let Some(on_scroll) = on_scroll { @@ -971,11 +984,23 @@ fn notify_on_scroll( return; } + let horizontal_alignment = direction + .horizontal() + .map(|p| p.alignment) + .unwrap_or_default(); + + let vertical_alignment = direction + .vertical() + .map(|p| p.alignment) + .unwrap_or_default(); + let viewport = Viewport { offset_x: state.offset_x, offset_y: state.offset_y, bounds, content_bounds, + vertical_alignment, + horizontal_alignment, }; // Don't publish redundant viewports to shell @@ -1080,6 +1105,8 @@ pub struct Viewport { offset_y: Offset, bounds: Rectangle, content_bounds: Rectangle, + vertical_alignment: Alignment, + horizontal_alignment: Alignment, } impl Viewport { @@ -1104,6 +1131,36 @@ impl Viewport { RelativeOffset { x, y } } + + /// Returns a new [`Viewport`] with the supplied vertical [`Alignment`]. + pub fn with_vertical_alignment(self, alignment: Alignment) -> Self { + if self.vertical_alignment != alignment { + let relative = 1.0 - self.relative_offset().y; + + Self { + offset_y: Offset::Relative(relative), + vertical_alignment: alignment, + ..self + } + } else { + self + } + } + + /// Returns a new [`Viewport`] with the supplied horizontal [`Alignment`]. + pub fn with_horizontal_alignment(self, alignment: Alignment) -> Self { + if self.horizontal_alignment != alignment { + let relative = 1.0 - self.relative_offset().x; + + Self { + offset_x: Offset::Relative(relative), + horizontal_alignment: alignment, + ..self + } + } else { + self + } + } } impl State { From a9987cb32e4d65b83f134ba54f51dffe16e93a50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 13 Jul 2023 02:53:45 +0200 Subject: [PATCH 002/321] Introduce `absolute_offset_reversed` to `scrollable::Viewport` --- widget/src/scrollable.rs | 75 +++++++++------------------------------- 1 file changed, 17 insertions(+), 58 deletions(-) diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index 3f49584c..5cd94538 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -554,14 +554,7 @@ pub fn update( state.scroll(delta, direction, bounds, content_bounds); - notify_on_scroll( - state, - on_scroll, - bounds, - content_bounds, - direction, - shell, - ); + notify_on_scroll(state, on_scroll, bounds, content_bounds, shell); return event::Status::Captured; } @@ -599,7 +592,6 @@ pub fn update( on_scroll, bounds, content_bounds, - direction, shell, ); } @@ -645,7 +637,6 @@ pub fn update( on_scroll, bounds, content_bounds, - direction, shell, ); @@ -681,7 +672,6 @@ pub fn update( on_scroll, bounds, content_bounds, - direction, shell, ); } @@ -722,7 +712,6 @@ pub fn update( on_scroll, bounds, content_bounds, - direction, shell, ); } @@ -758,7 +747,6 @@ pub fn update( on_scroll, bounds, content_bounds, - direction, shell, ); @@ -974,7 +962,6 @@ fn notify_on_scroll( on_scroll: &Option Message + '_>>, bounds: Rectangle, content_bounds: Rectangle, - direction: Direction, shell: &mut Shell<'_, Message>, ) { if let Some(on_scroll) = on_scroll { @@ -984,23 +971,11 @@ fn notify_on_scroll( return; } - let horizontal_alignment = direction - .horizontal() - .map(|p| p.alignment) - .unwrap_or_default(); - - let vertical_alignment = direction - .vertical() - .map(|p| p.alignment) - .unwrap_or_default(); - let viewport = Viewport { offset_x: state.offset_x, offset_y: state.offset_y, bounds, content_bounds, - vertical_alignment, - horizontal_alignment, }; // Don't publish redundant viewports to shell @@ -1105,8 +1080,6 @@ pub struct Viewport { offset_y: Offset, bounds: Rectangle, content_bounds: Rectangle, - vertical_alignment: Alignment, - horizontal_alignment: Alignment, } impl Viewport { @@ -1122,6 +1095,22 @@ impl Viewport { AbsoluteOffset { x, y } } + /// Returns the [`AbsoluteOffset`] of the current [`Viewport`], but with its + /// alignment reversed. + /// + /// This method can be useful to switch the alignment of a [`Scrollable`] + /// while maintaining its scrolling position. + pub fn absolute_offset_reversed(&self) -> AbsoluteOffset { + let AbsoluteOffset { x, y } = self.absolute_offset(); + + AbsoluteOffset { + x: ((self.content_bounds.width - self.bounds.width).max(0.0) - x) + .max(0.0), + y: ((self.content_bounds.height - self.bounds.height).max(0.0) - y) + .max(0.0), + } + } + /// Returns the [`RelativeOffset`] of the current [`Viewport`]. pub fn relative_offset(&self) -> RelativeOffset { let AbsoluteOffset { x, y } = self.absolute_offset(); @@ -1131,36 +1120,6 @@ impl Viewport { RelativeOffset { x, y } } - - /// Returns a new [`Viewport`] with the supplied vertical [`Alignment`]. - pub fn with_vertical_alignment(self, alignment: Alignment) -> Self { - if self.vertical_alignment != alignment { - let relative = 1.0 - self.relative_offset().y; - - Self { - offset_y: Offset::Relative(relative), - vertical_alignment: alignment, - ..self - } - } else { - self - } - } - - /// Returns a new [`Viewport`] with the supplied horizontal [`Alignment`]. - pub fn with_horizontal_alignment(self, alignment: Alignment) -> Self { - if self.horizontal_alignment != alignment { - let relative = 1.0 - self.relative_offset().x; - - Self { - offset_x: Offset::Relative(relative), - horizontal_alignment: alignment, - ..self - } - } else { - self - } - } } impl State { From d36758405789d6a305d978eefb46a1ca90d141d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 13 Jul 2023 03:01:53 +0200 Subject: [PATCH 003/321] Avoid redundant `max` in `absolute_offset_reversed` I believe `Offset::absolute` guarantees the offset never exceeds the maximum scrolling boundaries already. --- widget/src/scrollable.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index 5cd94538..e0aeeebd 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -1104,10 +1104,8 @@ impl Viewport { let AbsoluteOffset { x, y } = self.absolute_offset(); AbsoluteOffset { - x: ((self.content_bounds.width - self.bounds.width).max(0.0) - x) - .max(0.0), - y: ((self.content_bounds.height - self.bounds.height).max(0.0) - y) - .max(0.0), + x: (self.content_bounds.width - self.bounds.width).max(0.0) - x, + y: (self.content_bounds.height - self.bounds.height).max(0.0) - y, } } From dc0ebdc525dcb234fb754248eb1ee1606f91e839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 13 Jul 2023 16:40:47 +0200 Subject: [PATCH 004/321] Fix new `clippy` lint in `pokedex` example --- examples/pokedex/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/pokedex/src/main.rs b/examples/pokedex/src/main.rs index 1873b674..4482814c 100644 --- a/examples/pokedex/src/main.rs +++ b/examples/pokedex/src/main.rs @@ -151,7 +151,7 @@ impl Pokemon { } let id = { - let mut rng = rand::rngs::OsRng::default(); + let mut rng = rand::rngs::OsRng; rng.gen_range(0, Pokemon::TOTAL) }; From 66d671066386cd4ec1addbdfe0750e3077a5ea51 Mon Sep 17 00:00:00 2001 From: Cory Forsstrom Date: Thu, 13 Jul 2023 12:10:10 -0700 Subject: [PATCH 005/321] Dont blink input cursor when window loses focus --- widget/src/text_input.rs | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index 272263f9..bd3145ea 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -564,6 +564,7 @@ where Some(Focus { updated_at: now, now, + is_window_focused: true, }) }) } else { @@ -919,19 +920,35 @@ where state.keyboard_modifiers = modifiers; } + Event::Window(window::Event::Unfocused) => { + let state = state(); + + if let Some(focus) = &mut state.is_focused { + focus.is_window_focused = false; + } + } + Event::Window(window::Event::Focused) => { + let state = state(); + + if let Some(focus) = &mut state.is_focused { + focus.is_window_focused = true; + } + } Event::Window(window::Event::RedrawRequested(now)) => { let state = state(); if let Some(focus) = &mut state.is_focused { - focus.now = now; + if focus.is_window_focused { + focus.now = now; - let millis_until_redraw = CURSOR_BLINK_INTERVAL_MILLIS - - (now - focus.updated_at).as_millis() - % CURSOR_BLINK_INTERVAL_MILLIS; + let millis_until_redraw = CURSOR_BLINK_INTERVAL_MILLIS + - (now - focus.updated_at).as_millis() + % CURSOR_BLINK_INTERVAL_MILLIS; - shell.request_redraw(window::RedrawRequest::At( - now + Duration::from_millis(millis_until_redraw as u64), - )); + shell.request_redraw(window::RedrawRequest::At( + now + Duration::from_millis(millis_until_redraw as u64), + )); + } } } _ => {} @@ -1016,7 +1033,11 @@ pub fn draw( let font = font.unwrap_or_else(|| renderer.default_font()); let size = size.unwrap_or_else(|| renderer.default_size()); - let (cursor, offset) = if let Some(focus) = &state.is_focused { + let (cursor, offset) = if let Some(focus) = state + .is_focused + .as_ref() + .filter(|focus| focus.is_window_focused) + { match state.cursor.state(value) { cursor::State::Index(position) => { let (text_value_width, offset) = @@ -1188,6 +1209,7 @@ pub struct State { struct Focus { updated_at: Instant, now: Instant, + is_window_focused: bool, } impl State { @@ -1225,6 +1247,7 @@ impl State { self.is_focused = Some(Focus { updated_at: now, now, + is_window_focused: true, }); self.move_cursor_to_end(); From 44c07323067fa8c09122356c111047082d946c59 Mon Sep 17 00:00:00 2001 From: Cory Forsstrom Date: Thu, 13 Jul 2023 12:21:24 -0700 Subject: [PATCH 006/321] Restart animation when regaining focus --- widget/src/text_input.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index bd3145ea..a335afbc 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -932,6 +932,9 @@ where if let Some(focus) = &mut state.is_focused { focus.is_window_focused = true; + focus.updated_at = Instant::now(); + + shell.request_redraw(window::RedrawRequest::NextFrame); } } Event::Window(window::Event::RedrawRequested(now)) => { From 42c423b4a89613c4e1c552c891c1391a34837122 Mon Sep 17 00:00:00 2001 From: Cory Forsstrom Date: Sat, 15 Jul 2023 10:04:25 -0700 Subject: [PATCH 007/321] Add viewport to Widget::on_event --- core/src/element.rs | 9 ++++++--- core/src/widget.rs | 1 + examples/loading_spinners/src/circular.rs | 1 + examples/loading_spinners/src/linear.rs | 1 + examples/modal/src/main.rs | 3 +++ examples/toast/src/main.rs | 5 +++++ runtime/src/user_interface.rs | 3 +++ widget/src/button.rs | 2 ++ widget/src/canvas.rs | 1 + widget/src/checkbox.rs | 1 + widget/src/column.rs | 2 ++ widget/src/container.rs | 2 ++ widget/src/image/viewer.rs | 1 + widget/src/lazy.rs | 2 ++ widget/src/lazy/component.rs | 2 ++ widget/src/lazy/responsive.rs | 2 ++ widget/src/mouse_area.rs | 2 ++ widget/src/overlay/menu.rs | 4 ++++ widget/src/pane_grid.rs | 2 ++ widget/src/pane_grid/content.rs | 3 +++ widget/src/pane_grid/title_bar.rs | 3 +++ widget/src/pick_list.rs | 1 + widget/src/radio.rs | 1 + widget/src/row.rs | 2 ++ widget/src/scrollable.rs | 20 ++++++++++++++++++-- widget/src/slider.rs | 1 + widget/src/text_input.rs | 1 + widget/src/toggler.rs | 1 + widget/src/tooltip.rs | 2 ++ widget/src/vertical_slider.rs | 1 + 30 files changed, 77 insertions(+), 5 deletions(-) diff --git a/core/src/element.rs b/core/src/element.rs index 3268f14b..b9b76247 100644 --- a/core/src/element.rs +++ b/core/src/element.rs @@ -380,6 +380,7 @@ where renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, B>, + viewport: &Rectangle, ) -> event::Status { let mut local_messages = Vec::new(); let mut local_shell = Shell::new(&mut local_messages); @@ -392,6 +393,7 @@ where renderer, clipboard, &mut local_shell, + viewport, ); shell.merge(local_shell, &self.mapper); @@ -511,10 +513,11 @@ where renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + viewport: &Rectangle, ) -> event::Status { - self.element - .widget - .on_event(state, event, layout, cursor, renderer, clipboard, shell) + self.element.widget.on_event( + state, event, layout, cursor, renderer, clipboard, shell, viewport, + ) } fn draw( diff --git a/core/src/widget.rs b/core/src/widget.rs index 79d86444..25c1cae8 100644 --- a/core/src/widget.rs +++ b/core/src/widget.rs @@ -115,6 +115,7 @@ where _renderer: &Renderer, _clipboard: &mut dyn Clipboard, _shell: &mut Shell<'_, Message>, + _viewport: &Rectangle, ) -> event::Status { event::Status::Ignored } diff --git a/examples/loading_spinners/src/circular.rs b/examples/loading_spinners/src/circular.rs index 3a35e029..3898d76e 100644 --- a/examples/loading_spinners/src/circular.rs +++ b/examples/loading_spinners/src/circular.rs @@ -272,6 +272,7 @@ where _renderer: &iced::Renderer, _clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + _viewport: &Rectangle, ) -> event::Status { const FRAME_RATE: u64 = 60; diff --git a/examples/loading_spinners/src/linear.rs b/examples/loading_spinners/src/linear.rs index 3d95729b..20fbe9f3 100644 --- a/examples/loading_spinners/src/linear.rs +++ b/examples/loading_spinners/src/linear.rs @@ -193,6 +193,7 @@ where _renderer: &Renderer, _clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + _viewport: &Rectangle, ) -> event::Status { const FRAME_RATE: u64 = 60; diff --git a/examples/modal/src/main.rs b/examples/modal/src/main.rs index 7fcbbfe4..8a48f830 100644 --- a/examples/modal/src/main.rs +++ b/examples/modal/src/main.rs @@ -300,6 +300,7 @@ mod modal { renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + viewport: &Rectangle, ) -> event::Status { self.base.as_widget_mut().on_event( &mut state.children[0], @@ -309,6 +310,7 @@ mod modal { renderer, clipboard, shell, + viewport, ) } @@ -446,6 +448,7 @@ mod modal { renderer, clipboard, shell, + &layout.bounds(), ) } diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs index 4282ddcf..5d29e895 100644 --- a/examples/toast/src/main.rs +++ b/examples/toast/src/main.rs @@ -400,6 +400,7 @@ mod toast { renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + viewport: &Rectangle, ) -> event::Status { self.content.as_widget_mut().on_event( &mut state.children[0], @@ -409,6 +410,7 @@ mod toast { renderer, clipboard, shell, + viewport, ) } @@ -559,6 +561,8 @@ mod toast { } } + let viewport = layout.bounds(); + self.toasts .iter_mut() .zip(self.state.iter_mut()) @@ -576,6 +580,7 @@ mod toast { renderer, clipboard, &mut local_shell, + &viewport, ); if !local_shell.is_empty() { diff --git a/runtime/src/user_interface.rs b/runtime/src/user_interface.rs index 619423fd..e31ea98f 100644 --- a/runtime/src/user_interface.rs +++ b/runtime/src/user_interface.rs @@ -284,6 +284,8 @@ where (cursor, vec![event::Status::Ignored; events.len()]) }; + let viewport = Rectangle::with_size(self.bounds); + let _ = ManuallyDrop::into_inner(manual_overlay); let event_statuses = events @@ -305,6 +307,7 @@ where renderer, clipboard, &mut shell, + &viewport, ); if matches!(event_status, event::Status::Captured) { diff --git a/widget/src/button.rs b/widget/src/button.rs index 8ebc9657..1312095f 100644 --- a/widget/src/button.rs +++ b/widget/src/button.rs @@ -200,6 +200,7 @@ where renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + viewport: &Rectangle, ) -> event::Status { if let event::Status::Captured = self.content.as_widget_mut().on_event( &mut tree.children[0], @@ -209,6 +210,7 @@ where renderer, clipboard, shell, + viewport, ) { return event::Status::Captured; } diff --git a/widget/src/canvas.rs b/widget/src/canvas.rs index 96062038..1a186432 100644 --- a/widget/src/canvas.rs +++ b/widget/src/canvas.rs @@ -147,6 +147,7 @@ where _renderer: &Renderer, _clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + _viewport: &Rectangle, ) -> event::Status { let bounds = layout.bounds(); diff --git a/widget/src/checkbox.rs b/widget/src/checkbox.rs index aa0bff42..310a67ed 100644 --- a/widget/src/checkbox.rs +++ b/widget/src/checkbox.rs @@ -208,6 +208,7 @@ where _renderer: &Renderer, _clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + _viewport: &Rectangle, ) -> event::Status { match event { Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) diff --git a/widget/src/column.rs b/widget/src/column.rs index d92d794b..9271d5ef 100644 --- a/widget/src/column.rs +++ b/widget/src/column.rs @@ -170,6 +170,7 @@ where renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + viewport: &Rectangle, ) -> event::Status { self.children .iter_mut() @@ -184,6 +185,7 @@ where renderer, clipboard, shell, + viewport, ) }) .fold(event::Status::Ignored, event::Status::merge) diff --git a/widget/src/container.rs b/widget/src/container.rs index da9a31d6..64cf5cd5 100644 --- a/widget/src/container.rs +++ b/widget/src/container.rs @@ -200,6 +200,7 @@ where renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + viewport: &Rectangle, ) -> event::Status { self.content.as_widget_mut().on_event( &mut tree.children[0], @@ -209,6 +210,7 @@ where renderer, clipboard, shell, + viewport, ) } diff --git a/widget/src/image/viewer.rs b/widget/src/image/viewer.rs index 8040d6bd..0038f858 100644 --- a/widget/src/image/viewer.rs +++ b/widget/src/image/viewer.rs @@ -148,6 +148,7 @@ where renderer: &Renderer, _clipboard: &mut dyn Clipboard, _shell: &mut Shell<'_, Message>, + _viewport: &Rectangle, ) -> event::Status { let bounds = layout.bounds(); diff --git a/widget/src/lazy.rs b/widget/src/lazy.rs index da287f06..761f45ad 100644 --- a/widget/src/lazy.rs +++ b/widget/src/lazy.rs @@ -186,6 +186,7 @@ where renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + viewport: &Rectangle, ) -> event::Status { self.with_element_mut(|element| { element.as_widget_mut().on_event( @@ -196,6 +197,7 @@ where renderer, clipboard, shell, + viewport, ) }) } diff --git a/widget/src/lazy/component.rs b/widget/src/lazy/component.rs index c7814966..bc0e23df 100644 --- a/widget/src/lazy/component.rs +++ b/widget/src/lazy/component.rs @@ -270,6 +270,7 @@ where renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + viewport: &Rectangle, ) -> event::Status { let mut local_messages = Vec::new(); let mut local_shell = Shell::new(&mut local_messages); @@ -284,6 +285,7 @@ where renderer, clipboard, &mut local_shell, + viewport, ) }); diff --git a/widget/src/lazy/responsive.rs b/widget/src/lazy/responsive.rs index 07300857..b56545c8 100644 --- a/widget/src/lazy/responsive.rs +++ b/widget/src/lazy/responsive.rs @@ -182,6 +182,7 @@ where renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + viewport: &Rectangle, ) -> event::Status { let state = tree.state.downcast_mut::(); let mut content = self.content.borrow_mut(); @@ -203,6 +204,7 @@ where renderer, clipboard, &mut local_shell, + viewport, ) }, ); diff --git a/widget/src/mouse_area.rs b/widget/src/mouse_area.rs index da7dc88f..490f7c48 100644 --- a/widget/src/mouse_area.rs +++ b/widget/src/mouse_area.rs @@ -150,6 +150,7 @@ where renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + viewport: &Rectangle, ) -> event::Status { if let event::Status::Captured = self.content.as_widget_mut().on_event( &mut tree.children[0], @@ -159,6 +160,7 @@ where renderer, clipboard, shell, + viewport, ) { return event::Status::Captured; } diff --git a/widget/src/overlay/menu.rs b/widget/src/overlay/menu.rs index ccf4dfb5..72662422 100644 --- a/widget/src/overlay/menu.rs +++ b/widget/src/overlay/menu.rs @@ -268,8 +268,11 @@ where clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, ) -> event::Status { + let bounds = layout.bounds(); + self.container.on_event( self.state, event, layout, cursor, renderer, clipboard, shell, + &bounds, ) } @@ -377,6 +380,7 @@ where renderer: &Renderer, _clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + _viewport: &Rectangle, ) -> event::Status { match event { Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => { diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs index 31bb0e86..4f6dfbe8 100644 --- a/widget/src/pane_grid.rs +++ b/widget/src/pane_grid.rs @@ -317,6 +317,7 @@ where renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + viewport: &Rectangle, ) -> event::Status { let action = tree.state.downcast_mut::(); @@ -357,6 +358,7 @@ where renderer, clipboard, shell, + viewport, is_picked, ) }) diff --git a/widget/src/pane_grid/content.rs b/widget/src/pane_grid/content.rs index c28ae6e3..e890e41a 100644 --- a/widget/src/pane_grid/content.rs +++ b/widget/src/pane_grid/content.rs @@ -222,6 +222,7 @@ where renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + viewport: &Rectangle, is_picked: bool, ) -> event::Status { let mut event_status = event::Status::Ignored; @@ -237,6 +238,7 @@ where renderer, clipboard, shell, + viewport, ); children.next().unwrap() @@ -255,6 +257,7 @@ where renderer, clipboard, shell, + viewport, ) }; diff --git a/widget/src/pane_grid/title_bar.rs b/widget/src/pane_grid/title_bar.rs index 2fe79f80..cac24e68 100644 --- a/widget/src/pane_grid/title_bar.rs +++ b/widget/src/pane_grid/title_bar.rs @@ -304,6 +304,7 @@ where renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + viewport: &Rectangle, ) -> event::Status { let mut children = layout.children(); let padded = children.next().unwrap(); @@ -328,6 +329,7 @@ where renderer, clipboard, shell, + viewport, ) } else { event::Status::Ignored @@ -342,6 +344,7 @@ where renderer, clipboard, shell, + viewport, ) } else { event::Status::Ignored diff --git a/widget/src/pick_list.rs b/widget/src/pick_list.rs index 832aae6b..d99ada10 100644 --- a/widget/src/pick_list.rs +++ b/widget/src/pick_list.rs @@ -200,6 +200,7 @@ where _renderer: &Renderer, _clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + _viewport: &Rectangle, ) -> event::Status { update( event, diff --git a/widget/src/radio.rs b/widget/src/radio.rs index 5b883147..65d71ec2 100644 --- a/widget/src/radio.rs +++ b/widget/src/radio.rs @@ -233,6 +233,7 @@ where _renderer: &Renderer, _clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + _viewport: &Rectangle, ) -> event::Status { match event { Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) diff --git a/widget/src/row.rs b/widget/src/row.rs index 1db22416..7baaaae3 100644 --- a/widget/src/row.rs +++ b/widget/src/row.rs @@ -159,6 +159,7 @@ where renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + viewport: &Rectangle, ) -> event::Status { self.children .iter_mut() @@ -173,6 +174,7 @@ where renderer, clipboard, shell, + viewport, ) }) .fold(event::Status::Ignored, event::Status::merge) diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index e0aeeebd..f621fb26 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -278,6 +278,7 @@ where renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + _viewport: &Rectangle, ) -> event::Status { update( tree.state.downcast_mut::(), @@ -288,7 +289,7 @@ where shell, self.direction, &self.on_scroll, - |event, layout, cursor, clipboard, shell| { + |event, layout, cursor, clipboard, shell, viewport| { self.content.as_widget_mut().on_event( &mut tree.children[0], event, @@ -297,6 +298,7 @@ where renderer, clipboard, shell, + viewport, ) }, ) @@ -492,6 +494,7 @@ pub fn update( mouse::Cursor, &mut dyn Clipboard, &mut Shell<'_, Message>, + &Rectangle, ) -> event::Status, ) -> event::Status { let bounds = layout.bounds(); @@ -518,7 +521,20 @@ pub fn update( _ => mouse::Cursor::Unavailable, }; - update_content(event.clone(), content, cursor, clipboard, shell) + let translation = state.translation(direction, bounds, content_bounds); + + update_content( + event.clone(), + content, + cursor, + clipboard, + shell, + &Rectangle { + y: bounds.y + translation.y, + x: bounds.x + translation.x, + ..bounds + }, + ) }; if let event::Status::Captured = event_status { diff --git a/widget/src/slider.rs b/widget/src/slider.rs index 3ea4391b..e41be7c9 100644 --- a/widget/src/slider.rs +++ b/widget/src/slider.rs @@ -187,6 +187,7 @@ where _renderer: &Renderer, _clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + _viewport: &Rectangle, ) -> event::Status { update( event, diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index a335afbc..9958cbcc 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -302,6 +302,7 @@ where renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + _viewport: &Rectangle, ) -> event::Status { update( event, diff --git a/widget/src/toggler.rs b/widget/src/toggler.rs index 1b31765f..c8187181 100644 --- a/widget/src/toggler.rs +++ b/widget/src/toggler.rs @@ -207,6 +207,7 @@ where _renderer: &Renderer, _clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + _viewport: &Rectangle, ) -> event::Status { match event { Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) diff --git a/widget/src/tooltip.rs b/widget/src/tooltip.rs index 2dc3da01..ff7f960f 100644 --- a/widget/src/tooltip.rs +++ b/widget/src/tooltip.rs @@ -147,6 +147,7 @@ where renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + viewport: &Rectangle, ) -> event::Status { let state = tree.state.downcast_mut::(); @@ -163,6 +164,7 @@ where renderer, clipboard, shell, + viewport, ) } diff --git a/widget/src/vertical_slider.rs b/widget/src/vertical_slider.rs index 91f2b466..efca302a 100644 --- a/widget/src/vertical_slider.rs +++ b/widget/src/vertical_slider.rs @@ -184,6 +184,7 @@ where _renderer: &Renderer, _clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + _viewport: &Rectangle, ) -> event::Status { update( event, From 189817594f3aa8db0c2ac00b3d4128ae7733da45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 20 Jul 2023 20:39:49 +0200 Subject: [PATCH 008/321] Update `CHANGELOG` --- CHANGELOG.md | 89 +++++++++++++++++++++++++++++++++++++++++ docs/release_summary.py | 5 ++- 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 077f4af3..632beba2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,95 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added +- Text shaping, font fallback, and `iced_wgpu` overhaul. [#1697](https://github.com/iced-rs/iced/pull/1697) +- Software renderer, runtime renderer fallback, and core consolidation. [#1748](https://github.com/iced-rs/iced/pull/1748) +- Incremental rendering for `iced_tiny_skia`. [#1811](https://github.com/iced-rs/iced/pull/1811) +- Configurable `LineHeight` support for text widgets. [#1828](https://github.com/iced-rs/iced/pull/1828) +- `text::Shaping` strategy selection. [#1822](https://github.com/iced-rs/iced/pull/1822) +- Subpixel glyph positioning and layout linearity. [#1921](https://github.com/iced-rs/iced/pull/1921) +- Background gradients. [#1846](https://github.com/iced-rs/iced/pull/1846) +- Offscreen rendering and screenshots. [#1845](https://github.com/iced-rs/iced/pull/1845) +- Nested overlays. [#1719](https://github.com/iced-rs/iced/pull/1719) +- Cursor availability. [#1904](https://github.com/iced-rs/iced/pull/1904) +- Backend-specific primitives. [#1932](https://github.com/iced-rs/iced/pull/1932) +- `web-colors` feature flag to enable "sRGB linear" blending. [#1888](https://github.com/iced-rs/iced/pull/1888) +- `PaneGrid` logic to split panes by drag & drop. [#1856](https://github.com/iced-rs/iced/pull/1856) +- `PaneGrid` logic to drag & drop panes to the edges. [#1865](https://github.com/iced-rs/iced/pull/1865) +- Type-safe `Scrollable` direction. [#1878](https://github.com/iced-rs/iced/pull/1878) +- `Scrollable` alignment. [#1912](https://github.com/iced-rs/iced/pull/1912) +- Helpers to change viewport alignment of a `Scrollable`. [#1953](https://github.com/iced-rs/iced/pull/1953) +- `scroll_to` widget operation. [#1796](https://github.com/iced-rs/iced/pull/1796) +- `scroll_to` helper. [#1804](https://github.com/iced-rs/iced/pull/1804) +- Command to fetch window size. [#1927](https://github.com/iced-rs/iced/pull/1927) +- Conversion support from `Fn` trait to custom theme. [#1861](https://github.com/iced-rs/iced/pull/1861) +- Configurable border radii on relevant widgets. [#1869](https://github.com/iced-rs/iced/pull/1869) +- `border_radius` styling to `Slider` rail. [#1892](https://github.com/iced-rs/iced/pull/1892) +- Aliased entries in `text::Cache`. [#1934](https://github.com/iced-rs/iced/pull/1934) +- Text cache modes. [#1938](https://github.com/iced-rs/iced/pull/1938) +- `operate` method for `program::State`. [#1913](https://github.com/iced-rs/iced/pull/1913) +- Nix instructions to `DEPENDENCIES.md`. [#1859](https://github.com/iced-rs/iced/pull/1859) +- Loading spinners example. [#1902](https://github.com/iced-rs/iced/pull/1902) +- `Viewport` argument to `Widget::on_event`. [#1956](https://github.com/iced-rs/iced/pull/1956) + +### Changed +- Updated `wgpu` to `0.16`. [#1807](https://github.com/iced-rs/iced/pull/1807) +- Updated `glam` to `0.24`. [#1840](https://github.com/iced-rs/iced/pull/1840) +- Updated `winit` to `0.28`. [#1738](https://github.com/iced-rs/iced/pull/1738) +- Updated `palette` to `0.7`. [#1875](https://github.com/iced-rs/iced/pull/1875) +- Updated `ouroboros` to `0.17`. [#1925](https://github.com/iced-rs/iced/pull/1925) +- Updated `resvg` to `0.35` and `tiny-skia` to `0.10`. [#1907](https://github.com/iced-rs/iced/pull/1907) +- Changed `mouse::Button::Other` to take `u16` instead of `u8`. [#1797](https://github.com/iced-rs/iced/pull/1797) +- Changed `subscription::channel` to take a `FnOnce` non-`Sync` closure. [#1917](https://github.com/iced-rs/iced/pull/1917) +- Removed `Copy` requirement for text `StyleSheet::Style`. [#1814](https://github.com/iced-rs/iced/pull/1814) +- Removed `min_width` of 1 from scrollbar & scroller for `Scrollable`. [#1844](https://github.com/iced-rs/iced/pull/1844) +- Used `Widget::overlay` for `Tooltip`. [#1692](https://github.com/iced-rs/iced/pull/1692) + +### Fixed +- Invalidate `Responsive` layout when shell layout is invalidated. [#1799](https://github.com/iced-rs/iced/pull/1799) +- Invalidate `Responsive` layout when size changes without a `view` call. [#1890](https://github.com/iced-rs/iced/pull/1890) +- Broken link in `ROADMAP.md`. [#1815](https://github.com/iced-rs/iced/pull/1815) +- `bounds` of selected option background in `Menu`. [#1831](https://github.com/iced-rs/iced/pull/1831) +- Border radius logic in `iced_tiny_skia`. [#1842](https://github.com/iced-rs/iced/pull/1842) +- `Svg` filtered color not premultiplied. [#1841](https://github.com/iced-rs/iced/pull/1841) +- Race condition when growing an `image::Atlas`. [#1847](https://github.com/iced-rs/iced/pull/1847) +- Clearing damaged surface with background color in `iced_tiny_skia`. [#1854](https://github.com/iced-rs/iced/pull/1854) +- Private gradient pack logic for `iced_graphics::Gradient`. [#1871](https://github.com/iced-rs/iced/pull/1871) +- Unordered quads of different background types. [#1873](https://github.com/iced-rs/iced/pull/1873) +- Panic in `glyphon` when glyphs are missing. [#1883](https://github.com/iced-rs/iced/pull/1883) +- Empty scissor rectangle in `iced_wgpu::triangle` pipeline. [#1893](https://github.com/iced-rs/iced/pull/1893) +- `Scrollable` scrolling when mouse not over it. [#1910](https://github.com/iced-rs/iced/pull/1910) +- `translation` in `layout` of `Nested` overlay. [#1924](https://github.com/iced-rs/iced/pull/1924) +- Build when using vendored dependencies. [#1928](https://github.com/iced-rs/iced/pull/1928) +- Minor grammar mistake. [#1931](https://github.com/iced-rs/iced/pull/1931) +- Quad rendering including border only inside of the bounds. [#1843](https://github.com/iced-rs/iced/pull/1843) +- Redraw requests not being forwarded for `Component` overlays. [#1949](https://github.com/iced-rs/iced/pull/1949) +- Blinking input cursor when window loses focus. [#1955](https://github.com/iced-rs/iced/pull/1955) + +Many thanks to... + +- @a1phyr +- @alec-deason +- @AustinMReppert +- @bbb651 +- @bungoboingo +- @casperstorm +- @clarkmoody +- @Davidster +- @Drakulix +- @GyulyVGC +- @ids1024 +- @jhff +- @JonathanLindsey +- @kr105 +- @marienz +- @nicksenger +- @nicoburns +- @RGBCube +- @tarkah +- @thunderstorm010 +- @wash2 + ## [0.9.0] - 2023-04-13 ### Added - `MouseArea` widget. [#1594](https://github.com/iced-rs/iced/pull/1594) diff --git a/docs/release_summary.py b/docs/release_summary.py index cd4593b5..62694d05 100644 --- a/docs/release_summary.py +++ b/docs/release_summary.py @@ -13,7 +13,7 @@ PR_COMMIT_REGEX = re.compile(r"(?i)Merge pull request #(\d+).*") def get_merged_prs_since_release(repo: str, previous_release_branch: str) -> List[Tuple[str, int, str, str]]: prs = [] - compare_url = f"https://api.github.com/repos/{repo}/compare/{previous_release_branch}...master" + compare_url = f"https://api.github.com/repos/{repo}/compare/{previous_release_branch}...master?per_page=1000" compare_response = requests.get(compare_url, headers=HEADERS) if compare_response.status_code == 200: @@ -23,7 +23,10 @@ def get_merged_prs_since_release(repo: str, previous_release_branch: str) -> Lis if match: pr_number = int(match.group(1)) pr_url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}" + + print(f"Querying PR {pr_number}") pr_response = requests.get(pr_url, headers=HEADERS) + if pr_response.status_code == 200: pr_data = pr_response.json() prs.append((pr_data["title"], pr_number, pr_data["html_url"], pr_data["user"]["login"])) From 25936e441952994c7791b0a3ac907ab26c3c012e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 20 Jul 2023 20:44:14 +0200 Subject: [PATCH 009/321] Fix consistency in `CHANGELOG` --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 632beba2..7e647e25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,8 +51,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Used `Widget::overlay` for `Tooltip`. [#1692](https://github.com/iced-rs/iced/pull/1692) ### Fixed -- Invalidate `Responsive` layout when shell layout is invalidated. [#1799](https://github.com/iced-rs/iced/pull/1799) -- Invalidate `Responsive` layout when size changes without a `view` call. [#1890](https://github.com/iced-rs/iced/pull/1890) +- `Responsive` layout not invalidated when shell layout is invalidated. [#1799](https://github.com/iced-rs/iced/pull/1799) +- `Responsive` layout not invalidated when size changes without a `view` call. [#1890](https://github.com/iced-rs/iced/pull/1890) - Broken link in `ROADMAP.md`. [#1815](https://github.com/iced-rs/iced/pull/1815) - `bounds` of selected option background in `Menu`. [#1831](https://github.com/iced-rs/iced/pull/1831) - Border radius logic in `iced_tiny_skia`. [#1842](https://github.com/iced-rs/iced/pull/1842) From b6bee55fa23d5f205d4cb6ed7bfde60c60b84373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 20 Jul 2023 20:44:32 +0200 Subject: [PATCH 010/321] Rearrange item in `CHANGELOG` --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e647e25..73a844dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,9 +33,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Aliased entries in `text::Cache`. [#1934](https://github.com/iced-rs/iced/pull/1934) - Text cache modes. [#1938](https://github.com/iced-rs/iced/pull/1938) - `operate` method for `program::State`. [#1913](https://github.com/iced-rs/iced/pull/1913) +- `Viewport` argument to `Widget::on_event`. [#1956](https://github.com/iced-rs/iced/pull/1956) - Nix instructions to `DEPENDENCIES.md`. [#1859](https://github.com/iced-rs/iced/pull/1859) - Loading spinners example. [#1902](https://github.com/iced-rs/iced/pull/1902) -- `Viewport` argument to `Widget::on_event`. [#1956](https://github.com/iced-rs/iced/pull/1956) ### Changed - Updated `wgpu` to `0.16`. [#1807](https://github.com/iced-rs/iced/pull/1807) From 95ff96f71f8f8069608ad08985e2b1214dd42284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 7 Jul 2023 07:12:37 +0200 Subject: [PATCH 011/321] Update `cosmic-text` and `glyphon` --- tiny_skia/Cargo.toml | 5 +---- wgpu/Cargo.toml | 2 +- wgpu/src/backend.rs | 53 +++++++++++--------------------------------- wgpu/src/text.rs | 22 +++++------------- 4 files changed, 21 insertions(+), 61 deletions(-) diff --git a/tiny_skia/Cargo.toml b/tiny_skia/Cargo.toml index d9276ea5..66ad35fd 100644 --- a/tiny_skia/Cargo.toml +++ b/tiny_skia/Cargo.toml @@ -12,6 +12,7 @@ geometry = ["iced_graphics/geometry"] raw-window-handle = "0.5" softbuffer = "0.2" tiny-skia = "0.10" +cosmic-text = "0.9" bytemuck = "1" rustc-hash = "1.1" kurbo = "0.9" @@ -21,10 +22,6 @@ log = "0.4" version = "0.8" path = "../graphics" -[dependencies.cosmic-text] -git = "https://github.com/hecrj/cosmic-text.git" -rev = "c3cd24dc972bb8fd55d016c81ac9fa637e0a4ada" - [dependencies.twox-hash] version = "1.6" default-features = false diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 22cfad55..a47c635a 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -45,7 +45,7 @@ path = "../graphics" [dependencies.glyphon] version = "0.2" git = "https://github.com/hecrj/glyphon.git" -rev = "8324f20158a62f8520bad4ed09f6aa5552f8f2a6" +rev = "886f47c0a9905af340b07a488c953ac00c4bf370" [dependencies.glam] version = "0.24" diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index 4a0c54f0..9966a38c 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -94,18 +94,11 @@ impl Backend { queue, encoder, scale_factor, + target_size, transformation, &layers, ); - while !self.prepare_text( - device, - queue, - scale_factor, - target_size, - &layers, - ) {} - self.render( device, encoder, @@ -124,44 +117,13 @@ impl Backend { self.image_pipeline.end_frame(); } - fn prepare_text( - &mut self, - device: &wgpu::Device, - queue: &wgpu::Queue, - scale_factor: f32, - target_size: Size, - layers: &[Layer<'_>], - ) -> bool { - for layer in layers { - let bounds = (layer.bounds * scale_factor).snap(); - - if bounds.width < 1 || bounds.height < 1 { - continue; - } - - if !layer.text.is_empty() - && !self.text_pipeline.prepare( - device, - queue, - &layer.text, - layer.bounds, - scale_factor, - target_size, - ) - { - return false; - } - } - - true - } - fn prepare( &mut self, device: &wgpu::Device, queue: &wgpu::Queue, _encoder: &mut wgpu::CommandEncoder, scale_factor: f32, + target_size: Size, transformation: Transformation, layers: &[Layer<'_>], ) { @@ -210,6 +172,17 @@ impl Backend { ); } } + + if !layer.text.is_empty() { + self.text_pipeline.prepare( + device, + queue, + &layer.text, + layer.bounds, + scale_factor, + target_size, + ); + } } } diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index 65d3b818..ef910c39 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -35,7 +35,7 @@ impl Pipeline { .into_iter(), )), renderers: Vec::new(), - atlas: glyphon::TextAtlas::new( + atlas: glyphon::TextAtlas::with_color_mode( device, queue, format, @@ -66,7 +66,7 @@ impl Pipeline { bounds: Rectangle, scale_factor: f32, target_size: Size, - ) -> bool { + ) { if self.renderers.len() <= self.prepare_layer { self.renderers.push(glyphon::TextRenderer::new( &mut self.atlas, @@ -188,21 +188,11 @@ impl Pipeline { match result { Ok(()) => { self.prepare_layer += 1; - - true } - Err(glyphon::PrepareError::AtlasFull(content_type)) => { - self.prepare_layer = 0; - - #[allow(clippy::needless_bool)] - if self.atlas.grow(device, content_type) { - false - } else { - // If the atlas cannot grow, then all bets are off. - // Instead of panicking, we will just pray that the result - // will be somewhat readable... - true - } + Err(glyphon::PrepareError::AtlasFull) => { + // If the atlas cannot grow, then all bets are off. + // Instead of panicking, we will just pray that the result + // will be somewhat readable... } } } From 1006206fb260e6382ddf50a543846ccb9ffa957b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 20 Jul 2023 20:48:39 +0200 Subject: [PATCH 012/321] Use official `glyphon` repository instead of fork --- wgpu/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index a47c635a..a0500f83 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -44,8 +44,8 @@ path = "../graphics" [dependencies.glyphon] version = "0.2" -git = "https://github.com/hecrj/glyphon.git" -rev = "886f47c0a9905af340b07a488c953ac00c4bf370" +git = "https://github.com/grovesNL/glyphon.git" +rev = "81dedbd04237e181c2118931c5f37d341aeb6837" [dependencies.glam] version = "0.24" From 2a05ef9601bca560e68f9a16ff1875cfed33e0ea Mon Sep 17 00:00:00 2001 From: Cory Forsstrom Date: Mon, 24 Jul 2023 09:26:24 -0700 Subject: [PATCH 013/321] Don't clip raw overlay bounds User interface wraps the overlay in `overlay::Nested`. Clipping here w/ the base Nested overlay always clipped at (0, 0) position instead of the correct position of the child overlay. It's clipped properly already within `Nested::draw`. --- runtime/src/user_interface.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/runtime/src/user_interface.rs b/runtime/src/user_interface.rs index e31ea98f..8a936b98 100644 --- a/runtime/src/user_interface.rs +++ b/runtime/src/user_interface.rs @@ -513,17 +513,13 @@ where renderer, ); - let overlay_bounds = layout.bounds(); - - renderer.with_layer(overlay_bounds, |renderer| { - overlay.draw( - renderer, - theme, - style, - Layout::new(layout), - cursor, - ); - }); + overlay.draw( + renderer, + theme, + style, + Layout::new(layout), + cursor, + ); if cursor .position() From 355ef8188a34d63eb0d93bd8b3329f6a15e68e59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 26 Jul 2023 02:09:16 +0200 Subject: [PATCH 014/321] Add workflow to verify `CHANGELOG` is always up-to-date --- .github/workflows/verify.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/workflows/verify.yml diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml new file mode 100644 index 00000000..f7342ac1 --- /dev/null +++ b/.github/workflows/verify.yml @@ -0,0 +1,17 @@ +name: Verify +on: + pull_request: + branches: + - master +jobs: + changelog: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Check `CHANGELOG.md` has changes + run: | + ! git diff --exit-code master HEAD CHANGELOG.md + - name: Check `CHANGELOG.md` has PR author + if: ${{ github.event.pull_request.user.name != 'hecrj' }} + run: | + sed -n '/## \[Unreleased\]/,/^## /p' CHANGELOG.md | sed -n '/Many thanks to.../,//p' | grep '@${{ github.event.pull_request.user.name }}' From 269e5410da8a9d04b62671042167ea475283d678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 26 Jul 2023 02:19:25 +0200 Subject: [PATCH 015/321] Fetch all repository history in `verify` workflow --- .github/workflows/verify.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index f7342ac1..6f48415a 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -8,6 +8,8 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 + with: + fetch-depth: 0 - name: Check `CHANGELOG.md` has changes run: | ! git diff --exit-code master HEAD CHANGELOG.md From d9faf4c9808f9959ac3dcba052c4c2febd1d0481 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 26 Jul 2023 02:19:44 +0200 Subject: [PATCH 016/321] Use `login` instead of `name` in `verify` workflow --- .github/workflows/verify.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index 6f48415a..84778e91 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -14,6 +14,6 @@ jobs: run: | ! git diff --exit-code master HEAD CHANGELOG.md - name: Check `CHANGELOG.md` has PR author - if: ${{ github.event.pull_request.user.name != 'hecrj' }} + if: ${{ github.event.pull_request.user.login != 'hecrj' }} run: | - sed -n '/## \[Unreleased\]/,/^## /p' CHANGELOG.md | sed -n '/Many thanks to.../,//p' | grep '@${{ github.event.pull_request.user.name }}' + sed -n '/## \[Unreleased\]/,/^## /p' CHANGELOG.md | sed -n '/Many thanks to.../,//p' | grep '@${{ github.event.pull_request.user.login }}' From 0be3fe4ec760dd4eba1b753b87b6f89c61d29747 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 26 Jul 2023 02:24:22 +0200 Subject: [PATCH 017/321] Use `origin/master` instead of `master` in `verify` workflow --- .github/workflows/verify.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index 84778e91..3de8a21c 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -12,7 +12,7 @@ jobs: fetch-depth: 0 - name: Check `CHANGELOG.md` has changes run: | - ! git diff --exit-code master HEAD CHANGELOG.md + ! git diff --exit-code origin/master HEAD -- CHANGELOG.md - name: Check `CHANGELOG.md` has PR author if: ${{ github.event.pull_request.user.login != 'hecrj' }} run: | From 6531f2789702d3490b3e7b74686c03954fd14a04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 26 Jul 2023 02:30:37 +0200 Subject: [PATCH 018/321] Update `CHANGELOG` --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73a844dd..b7174bb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Viewport` argument to `Widget::on_event`. [#1956](https://github.com/iced-rs/iced/pull/1956) - Nix instructions to `DEPENDENCIES.md`. [#1859](https://github.com/iced-rs/iced/pull/1859) - Loading spinners example. [#1902](https://github.com/iced-rs/iced/pull/1902) +- Workflow that verifies `CHANGELOG` is always up-to-date. [#1970](https://github.com/iced-rs/iced/pull/1970) ### Changed - Updated `wgpu` to `0.16`. [#1807](https://github.com/iced-rs/iced/pull/1807) From 94e991a785eddcc1c706a5a7111e1e88b18aef41 Mon Sep 17 00:00:00 2001 From: Cory Forsstrom Date: Fri, 21 Jul 2023 13:57:49 -0700 Subject: [PATCH 019/321] Add app id setting for linux --- winit/src/settings.rs | 28 +++++++++++++++++++++++++++- winit/src/settings/linux.rs | 11 +++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 winit/src/settings/linux.rs diff --git a/winit/src/settings.rs b/winit/src/settings.rs index 40b3d487..8d3e1b47 100644 --- a/winit/src/settings.rs +++ b/winit/src/settings.rs @@ -7,6 +7,10 @@ mod platform; #[path = "settings/macos.rs"] mod platform; +#[cfg(target_os = "linux")] +#[path = "settings/linux.rs"] +mod platform; + #[cfg(target_arch = "wasm32")] #[path = "settings/wasm.rs"] mod platform; @@ -14,6 +18,7 @@ mod platform; #[cfg(not(any( target_os = "windows", target_os = "macos", + target_os = "linux", target_arch = "wasm32" )))] #[path = "settings/other.rs"] @@ -150,7 +155,6 @@ impl Window { } #[cfg(any( - target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", @@ -192,6 +196,28 @@ impl Window { ); } + #[cfg(target_os = "linux")] + { + #[cfg(feature = "x11")] + { + use winit::platform::x11::WindowBuilderExtX11; + + window_builder = window_builder.with_name( + &self.platform_specific.application_id, + &self.platform_specific.application_id, + ); + } + #[cfg(feature = "wayland")] + { + use winit::platform::wayland::WindowBuilderExtWayland; + + window_builder = window_builder.with_name( + &self.platform_specific.application_id, + &self.platform_specific.application_id, + ); + } + } + window_builder } } diff --git a/winit/src/settings/linux.rs b/winit/src/settings/linux.rs new file mode 100644 index 00000000..009b9d9e --- /dev/null +++ b/winit/src/settings/linux.rs @@ -0,0 +1,11 @@ +//! Platform specific settings for Linux. + +/// The platform specific window settings of an application. +#[derive(Debug, Clone, PartialEq, Eq, Default)] +pub struct PlatformSpecific { + /// Sets the application id of the window. + /// + /// As a best practice, it is suggested to select an application id that match + /// the basename of the application’s .desktop file. + pub application_id: String, +} From 13c8d965d3295c83a6b77b1831db1139833a5b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 26 Jul 2023 20:15:49 +0200 Subject: [PATCH 020/321] Update `CHANGELOG` --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7174bb8..4481008f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Conversion support from `Fn` trait to custom theme. [#1861](https://github.com/iced-rs/iced/pull/1861) - Configurable border radii on relevant widgets. [#1869](https://github.com/iced-rs/iced/pull/1869) - `border_radius` styling to `Slider` rail. [#1892](https://github.com/iced-rs/iced/pull/1892) +- `application_id` in `PlatformSpecific` settings for Linux. [#1963](https://github.com/iced-rs/iced/pull/1963) - Aliased entries in `text::Cache`. [#1934](https://github.com/iced-rs/iced/pull/1934) - Text cache modes. [#1938](https://github.com/iced-rs/iced/pull/1938) - `operate` method for `program::State`. [#1913](https://github.com/iced-rs/iced/pull/1913) From 9afcf067dbed26b6640dde8de9c24f90eea5c3c1 Mon Sep 17 00:00:00 2001 From: Redhawk18 Date: Tue, 18 Jul 2023 14:09:13 -0400 Subject: [PATCH 021/321] Link to graphical roadmap in `ROADMAP.md` --- ROADMAP.md | 116 +---------------------------------------------------- 1 file changed, 1 insertion(+), 115 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index f1893664..afcece7c 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,120 +1,6 @@ # Roadmap -This document describes the current state of Iced and some of the most important next steps we should take before it can become a production-ready GUI library. This list keeps the short term new features in sight in order to coordinate work and discussion. Therefore, it is not meant to be exhaustive. +We have [a detailed graphical roadmap now](https://whimsical.com/roadmap-iced-7vhq6R35Lp3TmYH4WeYwLM)! Before diving into the roadmap, check out [the ecosystem overview] to get an idea of the current state of the library. [the ecosystem overview]: ECOSYSTEM.md - -## Next steps -Most of the work related to these features needs to happen in the __native__ path of the ecosystem, as the web already supports many of them. - -Once a step is completed, it is collapsed and added to this list: - - * [x] Scrollables / Clippables ([#24]) - * [x] Text input widget ([#25]) - * [x] TodoMVC example ([#26]) - * [x] Async actions ([#28]) - * [x] Custom layout engine ([#52]) - * [x] Event subscriptions ([#122]) - * [x] Custom styling ([#146]) - * [x] Canvas for 2D graphics ([#193]) - * [x] Basic overlay support ([#444]) - * [x] Animations [#31] - -[#24]: https://github.com/iced-rs/iced/issues/24 -[#25]: https://github.com/iced-rs/iced/issues/25 -[#26]: https://github.com/iced-rs/iced/issues/26 -[#28]: https://github.com/iced-rs/iced/issues/28 -[#52]: https://github.com/iced-rs/iced/pull/52 -[#122]: https://github.com/iced-rs/iced/pull/122 -[#146]: https://github.com/iced-rs/iced/pull/146 -[#193]: https://github.com/iced-rs/iced/pull/193 -[#444]: https://github.com/iced-rs/iced/pull/444 -[#31]: https://github.com/iced-rs/iced/issues/31 - -### Multi-window support ([#27]) -Open and control multiple windows at runtime. - -I think this could be achieved by implementing an additional trait in `iced_winit` similar to `Application` but with a slightly different `view` method, allowing users to control what is shown in each window. - -This approach should also allow us to perform custom optimizations for this particular use case. - -[#27]: https://github.com/iced-rs/iced/issues/27 - -### Canvas widget for 3D graphics (~~[#32]~~ [#343]) -A widget to draw freely in 3D. It could be used to draw charts, implement a Paint clone, a CAD application, etc. - -As a first approach, we could expose the underlying renderer directly here, and couple this widget with it ([`wgpu`] for now). Once [`wgpu`] gets WebGL or WebGPU support, this widget will be able to run on the web too. The renderer primitive could be a simple texture that the widget draws to. - -In the long run, we could expose a renderer-agnostic abstraction to perform the drawing. - -[#32]: https://github.com/iced-rs/iced/issues/32 -[#343]: https://github.com/iced-rs/iced/issues/343 - -### Text shaping and font fallback ([#33]) -[`wgpu_glyph`] uses [`glyph_brush`], which in turn uses [`rusttype`]. While the current implementation is able to layout text quite nicely, it does not perform any [text shaping]. - -[Text shaping] with font fallback is a necessary feature for any serious GUI toolkit. It unlocks support to truly localize your application, supporting many different scripts. - -The only available library that does a great job at shaping is [HarfBuzz], which is implemented in C++. [`skribo`] seems to be a nice [HarfBuzz] wrapper for Rust. - -This feature will probably imply rewriting [`wgpu_glyph`] entirely, as caching will be more complicated and the API will probably need to ask for more data. - -[#33]: https://github.com/iced-rs/iced/issues/33 -[`rusttype`]: https://github.com/redox-os/rusttype -[text shaping]: https://en.wikipedia.org/wiki/Complex_text_layout -[HarfBuzz]: https://github.com/harfbuzz/harfbuzz -[`skribo`]: https://github.com/linebender/skribo - -### Grid layout and text layout ([#34]) -Currently, `iced_native` only supports flexbox items. For instance, it is not possible to create a grid of items or make text float around an image. - -We will need to enhance the layouting engine to support different strategies and improve the way we measure text to lay it out in a more flexible way. - -[#34]: https://github.com/iced-rs/iced/issues/34 - -## Ideas that may be worth exploring - -### Reuse existing 2D renderers -While I believe [`wgpu`] has a great future ahead of it, implementing `iced_wgpu` and making it performant will definitely be a challenge. - -We should keep an eye on existing 2D graphic libraries, like [`piet`] or [`pathfinder`], and give them a try once/if they mature a bit more. - -The good news here is that most of Iced is renderer-agnostic, so changing the rendering strategy, if we deem it worth it, should be really easy. Also, a 2D graphics library will expose a higher-level API than [`wgpu`], so implementing a new renderer on top of it should be fairly straightforward. - -[`piet`]: https://github.com/linebender/piet -[`pathfinder`]: https://github.com/servo/pathfinder - -### Remove explicit state handling and lifetimes -Currently, `iced_native` forces users to provide the local state of each widget. While this could be considered a really pure form of describing a GUI, it makes some optimizations harder because of the borrow checker. - -The current borrow checker is not able to detect a drop was performed before reassigning a value to a mutable variable. Thus, keeping the generated widgets in `Application::view` alive between iterations of the event loop is not possible, which forces us to call this method quite often. `unsafe` could be used to workaround this, but it would feel fishy. - -We could take a different approach, and keep some kind of state tree decoupled from the actual widget definitions. This would force us to perform diffing of nodes, as the widgets will represent the desired state and not the whole state. - -Once the state lifetime of widgets is removed, we could keep them alive between iterations and even make `Application::view` take a non-mutable reference. This would also improve the end-user API, as it will not be necessary to constantly provide mutable state to widgets. - -This is a big undertaking and introduces a new set of problems. We should research and consider the implications of this approach in detail before going for it. - -### Try a different font rasterizer -[`wgpu_glyph`] depends indirectly on [`rusttype`]. We may be able to gain performance by using a different font rasterizer. [`fontdue`], for instance, has reported noticeable speedups. - -[`fontdue`]: https://github.com/mooman219/fontdue - -### Connect `iced_web` with `web-view` -It may be interesting to try to connect `iced_web` with [`web-view`]. It would give users a feature-complete renderer for free, and applications would still be leaner than with Electron. - -[`web-view`]: https://github.com/Boscop/web-view - -### Implement a lazy widget -Once we remove state lifetimes from widgets, we should be able to implement a widget storing a function that generates additional widgets. The runtime would then be able to control when to call this function and cache the generated widgets while some given value does not change. - -This could be very useful to build very performant user interfaces with a lot of different items. - -[Elm does it very well!](https://guide.elm-lang.org/optimization/lazy.html) - -[Elm]: https://elm-lang.org/ -[`winit`]: https://github.com/rust-windowing/winit -[`wgpu`]: https://github.com/gfx-rs/wgpu -[`wgpu_glyph`]: https://github.com/hecrj/wgpu_glyph -[`glyph_brush`]: https://github.com/alexheretic/glyph-brush From bc09901690cfb0ca319e9fe4d009378ee9f46cf8 Mon Sep 17 00:00:00 2001 From: Redhawk18 Date: Tue, 18 Jul 2023 14:09:33 -0400 Subject: [PATCH 022/321] Simplify contributing guidelines --- CONTRIBUTING.md | 2 +- README.md | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8782a2e3..412cf08f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ Thank you for considering contributing to Iced! Feel free to read [the ecosystem overview] and [the roadmap] to get an idea of the current state of the library. -The main advice for new contributors is to share your ideas with the community. Introduce yourself over our [Discord server] or [start a discussion in an issue](https://github.com/iced-rs/iced/issues) explaining what you have in mind (do not be afraid of duplicated issues!). If you want to talk directly to me (@hecrj), you can also find me on Discord (`lone_scientist#9554`). +The main advice for new contributors is to share your ideas with the community. Introduce yourself over our [Discord server] or [start a discussion in an issue](https://github.com/iced-rs/iced/issues) explaining what you have in mind (do not be afraid of duplicated issues!). This is a very important step. It helps to coordinate work, get on the same page, and start building trust. Please, do not skip it! Remember that [Code is the Easy Part] and also [The Hard Parts of Open Source]! diff --git a/README.md b/README.md index c72fd770..e013246a 100644 --- a/README.md +++ b/README.md @@ -201,10 +201,8 @@ end-user-oriented GUI library, while keeping [the ecosystem] modular: Contributions are greatly appreciated! If you want to contribute, please read our [contributing guidelines] for more details. -Feedback is also welcome! You can open an issue or, if you want to talk, -come chat to our [Discord server]. Moreover, you can find me (and a bunch of -awesome folks) over the `#games-and-graphics` and `#gui-and-ui` channels in -the [Rust Community Discord]. I go by `lone_scientist#9554` there. +Feedback is also welcome! You can open a discussion or come chat to our +[Discord server]. ## Sponsors From 9537c9dfdaf09694fd05b7edd74729503e922696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 26 Jul 2023 20:27:33 +0200 Subject: [PATCH 023/321] Update `CHANGELOG` --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7174bb8..a2e900dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,6 +71,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Quad rendering including border only inside of the bounds. [#1843](https://github.com/iced-rs/iced/pull/1843) - Redraw requests not being forwarded for `Component` overlays. [#1949](https://github.com/iced-rs/iced/pull/1949) - Blinking input cursor when window loses focus. [#1955](https://github.com/iced-rs/iced/pull/1955) +- Outdated `ROADMAP`. [#1958](https://github.com/iced-rs/iced/pull/1958) Many thanks to... @@ -91,6 +92,7 @@ Many thanks to... - @marienz - @nicksenger - @nicoburns +- @Redhawk18 - @RGBCube - @tarkah - @thunderstorm010 From dd5ef8b90895f626d4b8f0466c4457c5abf451a0 Mon Sep 17 00:00:00 2001 From: Joao Freitas <51237625+jhff@users.noreply.github.com> Date: Thu, 13 Jul 2023 13:51:29 +0100 Subject: [PATCH 024/321] Add ComboBox widget - Widget implementation - Widget helper - Example --- examples/combo_box/Cargo.toml | 9 + examples/combo_box/README.md | 18 + examples/combo_box/src/main.rs | 143 +++++++ widget/src/combo_box.rs | 716 +++++++++++++++++++++++++++++++++ widget/src/helpers.rs | 18 + widget/src/lib.rs | 3 + 6 files changed, 907 insertions(+) create mode 100644 examples/combo_box/Cargo.toml create mode 100644 examples/combo_box/README.md create mode 100644 examples/combo_box/src/main.rs create mode 100644 widget/src/combo_box.rs diff --git a/examples/combo_box/Cargo.toml b/examples/combo_box/Cargo.toml new file mode 100644 index 00000000..be1b5e32 --- /dev/null +++ b/examples/combo_box/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "combo_box" +version = "0.1.0" +authors = ["Joao Freitas "] +edition = "2021" +publish = false + +[dependencies] +iced = { path = "../..", features = ["debug"] } diff --git a/examples/combo_box/README.md b/examples/combo_box/README.md new file mode 100644 index 00000000..5fc87469 --- /dev/null +++ b/examples/combo_box/README.md @@ -0,0 +1,18 @@ +## Combo-Box + +A dropdown list of searchable and selectable options. + +It displays and positions an overlay based on the window position of the widget. + +The __[`main`]__ file contains all the code of the example. + +
+ +
+ +You can run it with `cargo run`: +``` +cargo run --package combo_box +``` + +[`main`]: src/main.rs diff --git a/examples/combo_box/src/main.rs b/examples/combo_box/src/main.rs new file mode 100644 index 00000000..22d05132 --- /dev/null +++ b/examples/combo_box/src/main.rs @@ -0,0 +1,143 @@ +use iced::widget::{ + column, combo_box, container, scrollable, text, vertical_space, +}; +use iced::{Alignment, Element, Length, Sandbox, Settings}; + +pub fn main() -> iced::Result { + Example::run(Settings::default()) +} + +struct Example { + languages: combo_box::State, + selected_language: Option, + text: String, +} + +#[derive(Debug, Clone, Copy)] +enum Message { + LanguageSelected(Language), + LanguagePreview(Language), + LanguageBlurred, +} + +impl Sandbox for Example { + type Message = Message; + + fn new() -> Self { + Self { + languages: combo_box::State::new(Language::ALL.to_vec()), + selected_language: None, + text: String::new(), + } + } + + fn title(&self) -> String { + String::from("Combo box - Iced") + } + + fn update(&mut self, message: Message) { + match message { + Message::LanguageSelected(language) => { + self.selected_language = Some(language); + self.text = language.hello().to_string(); + self.languages.unfocus(); + } + Message::LanguagePreview(language) => { + self.text = language.hello().to_string(); + } + Message::LanguageBlurred => { + self.text = self + .selected_language + .map(|language| language.hello().to_string()) + .unwrap_or_default(); + } + } + } + + fn view(&self) -> Element { + let combo_box = combo_box( + &self.languages, + "Type a language...", + self.selected_language.as_ref(), + Message::LanguageSelected, + ) + .on_selection(Message::LanguagePreview) + .on_blur(Message::LanguageBlurred) + .width(250); + + let content = column![ + "What is your language?", + combo_box, + vertical_space(150), + text(&self.text), + ] + .width(Length::Fill) + .align_items(Alignment::Center) + .spacing(10); + + container(scrollable(content)) + .width(Length::Fill) + .height(Length::Fill) + .center_x() + .center_y() + .into() + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +pub enum Language { + Danish, + #[default] + English, + French, + German, + Italian, + Portuguese, + Spanish, + Other, +} + +impl Language { + const ALL: [Language; 8] = [ + Language::Danish, + Language::English, + Language::French, + Language::German, + Language::Italian, + Language::Portuguese, + Language::Spanish, + Language::Other, + ]; + + fn hello(&self) -> &str { + match self { + Language::Danish => "Halloy!", + Language::English => "Hello!", + Language::French => "Salut!", + Language::German => "Hallo!", + Language::Italian => "Ciao!", + Language::Portuguese => "Olá!", + Language::Spanish => "¡Hola!", + Language::Other => "... hello?", + } + } +} + +impl std::fmt::Display for Language { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match self { + Language::Danish => "Danish", + Language::English => "English", + Language::French => "French", + Language::German => "German", + Language::Italian => "Italian", + Language::Portuguese => "Portuguese", + Language::Spanish => "Spanish", + Language::Other => "Some other language", + } + ) + } +} diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs new file mode 100644 index 00000000..262f83a8 --- /dev/null +++ b/widget/src/combo_box.rs @@ -0,0 +1,716 @@ +//! Display a dropdown list of searchable and selectable options. +use crate::core::event::{self, Event}; +use crate::core::keyboard; +use crate::core::layout::{self, Layout}; +use crate::core::mouse; +use crate::core::overlay; +use crate::core::renderer; +use crate::core::text; +use crate::core::widget::{self, Widget}; +use crate::core::{Clipboard, Element, Length, Padding, Rectangle, Shell}; +use crate::overlay::menu; +use crate::text::LineHeight; +use crate::{container, scrollable, text_input, TextInput}; + +use std::cell::RefCell; +use std::fmt::Display; +use std::time::Instant; + +/// A widget for searching and selecting a single value from a list of options. +/// +/// This widget is composed by a [`TextInput`] that can be filled with the text +/// to search for corresponding values from the list of options that are displayed +/// as a [`Menu`]. +#[allow(missing_debug_implementations)] +pub struct ComboBox<'a, T, Message, Renderer = crate::Renderer> +where + Renderer: text::Renderer, + Renderer::Theme: text_input::StyleSheet + menu::StyleSheet, +{ + state: &'a State, + text_input: TextInput<'a, TextInputEvent, Renderer>, + font: Option, + selection: text_input::Value, + on_selected: Box Message>, + on_selection: Option Message>>, + on_blur: Option, + on_input: Option Message>>, + menu_style: ::Style, + padding: Padding, + size: Option, +} + +impl<'a, T, Message, Renderer> ComboBox<'a, T, Message, Renderer> +where + T: std::fmt::Display + Clone, + Renderer: text::Renderer, + Renderer::Theme: text_input::StyleSheet + menu::StyleSheet, +{ + /// Creates a new [`ComboBox`] with the given list of options, a placeholder, + /// the current selected value, and the message to produce when an option is + /// selected. + pub fn new( + state: &'a State, + placeholder: &str, + selection: Option<&T>, + on_selected: impl Fn(T) -> Message + 'static, + ) -> Self { + let text_input = TextInput::new(placeholder, &state.value()) + .on_input(TextInputEvent::TextChanged); + + let selection = selection.map(T::to_string).unwrap_or_else(String::new); + + Self { + state, + text_input, + font: None, + selection: text_input::Value::new(&selection), + on_selected: Box::new(on_selected), + on_selection: None, + on_input: None, + on_blur: None, + menu_style: Default::default(), + padding: Padding::new(0.0), + size: None, + } + } + + /// Sets the message that should be produced when some text is typed into + /// the [`TextInput`] of the [`ComboBox`]. + pub fn on_input( + mut self, + on_input: impl Fn(String) -> Message + 'static, + ) -> Self { + self.on_input = Some(Box::new(on_input)); + self + } + + /// Sets the message that will be produced when an option of the + /// [`ComboBox`] is hovered using the arrow keys. + pub fn on_selection( + mut self, + on_selection: impl Fn(T) -> Message + 'static, + ) -> Self { + self.on_selection = Some(Box::new(on_selection)); + self + } + + /// Sets the message that will be produced when the outside area + /// of the [`ComboBox`] is pressed. + pub fn on_blur(mut self, message: Message) -> Self { + self.on_blur = Some(message); + self + } + + /// Sets the [`Padding`] of the [`ComboBox`]. + pub fn padding(mut self, padding: impl Into) -> Self { + self.padding = padding.into(); + self.text_input = self.text_input.padding(self.padding); + self + } + + /// Sets the style of the [`ComboBox`]. + // TODO: Define its own `StyleSheet` trait + pub fn style(mut self, style: S) -> Self + where + S: Into<::Style> + + Into<::Style> + + Clone, + { + self.menu_style = style.clone().into(); + self.text_input = self.text_input.style(style); + self + } + + /// Sets the style of the [`TextInput`] of the [`ComboBox`]. + pub fn text_input_style(mut self, style: S) -> Self + where + S: Into<::Style> + Clone, + { + self.text_input = self.text_input.style(style); + self + } + + /// Sets the [`Font`] of the [`ComboBox`]. + pub fn font(mut self, font: Renderer::Font) -> Self { + self.text_input = self.text_input.font(font); + self.font = Some(font); + self + } + + /// Sets the [`Icon`] of the [`ComboBox`]. + pub fn icon(mut self, icon: text_input::Icon) -> Self { + self.text_input = self.text_input.icon(icon); + self + } + + /// Returns whether the [`ComboBox`] is currently focused or not. + pub fn is_focused(&self) -> bool { + self.state.is_focused() + } + + /// Sets the text sixe of the [`ComboBox`]. + pub fn size(mut self, size: f32) -> Self { + self.text_input = self.text_input.size(size); + self.size = Some(size); + self + } + + /// Sets the [`LineHeight`] of the [`ComboBox`]. + pub fn line_height(self, line_height: impl Into) -> Self { + Self { + text_input: self.text_input.line_height(line_height), + ..self + } + } + + /// Sets the width of the [`ComboBox`]. + pub fn width(self, width: impl Into) -> Self { + Self { + text_input: self.text_input.width(width), + ..self + } + } +} + +/// The local state of a [`ComboBox`]. +#[derive(Debug, Clone)] +pub struct State(RefCell>); + +#[derive(Debug, Clone)] +struct Inner { + text_input: text_input::State, + value: String, + options: Vec, + option_matchers: Vec, + filtered_options: Filtered, +} + +#[derive(Debug, Clone)] +struct Filtered { + options: Vec, + updated: Instant, +} + +impl State +where + T: Display + Clone, +{ + /// Creates a new [`State`] for a [`ComboBox`] with the given list of options. + pub fn new(options: Vec) -> Self { + Self::with_selection(options, None) + } + + /// Creates a new [`State`] for a [`ComboBox`] with the given list of options + /// and selected value. + pub fn with_selection(options: Vec, selection: Option<&T>) -> Self { + let value = selection.map(T::to_string).unwrap_or_else(String::new); + + // Pre-build "matcher" strings ahead of time so that search is fast + let option_matchers = build_matchers(&options); + + let filtered_options = Filtered::new( + search(&options, &option_matchers, &value) + .cloned() + .collect(), + ); + + Self(RefCell::new(Inner { + text_input: text_input::State::new(), + value, + options, + option_matchers, + filtered_options, + })) + } + + /// Focuses the [`ComboBox`]. + pub fn focused(self) -> Self { + self.focus(); + self + } + + /// Focuses the [`ComboBox`]. + pub fn focus(&self) { + let mut inner = self.0.borrow_mut(); + + inner.text_input.focus(); + } + + /// Unfocuses the [`ComboBox`]. + pub fn unfocus(&self) { + let mut inner = self.0.borrow_mut(); + + inner.text_input.unfocus(); + } + + /// Returns whether the [`ComboBox`] is currently focused or not. + pub fn is_focused(&self) -> bool { + let inner = self.0.borrow(); + + inner.text_input.is_focused() + } + + fn value(&self) -> String { + let inner = self.0.borrow(); + + inner.value.clone() + } + + fn text_input_tree(&self) -> widget::Tree { + let inner = self.0.borrow(); + + inner.text_input_tree() + } + + fn update_text_input(&self, tree: widget::Tree) { + let mut inner = self.0.borrow_mut(); + + inner.update_text_input(tree) + } + + fn with_inner(&self, f: impl FnOnce(&Inner) -> O) -> O { + let inner = self.0.borrow(); + + f(&inner) + } + + fn with_inner_mut(&self, f: impl FnOnce(&mut Inner)) { + let mut inner = self.0.borrow_mut(); + + f(&mut inner); + } + + fn sync_filtered_options(&self, options: &mut Filtered) { + let inner = self.0.borrow(); + + inner.filtered_options.sync(options); + } +} + +impl Inner { + fn text_input_tree(&self) -> widget::Tree { + widget::Tree { + tag: widget::tree::Tag::of::(), + state: widget::tree::State::new(self.text_input.clone()), + children: vec![], + } + } + + fn update_text_input(&mut self, tree: widget::Tree) { + self.text_input = + tree.state.downcast_ref::().clone(); + } +} + +impl Filtered +where + T: Clone, +{ + fn new(options: Vec) -> Self { + Self { + options, + updated: Instant::now(), + } + } + + fn empty() -> Self { + Self { + options: vec![], + updated: Instant::now(), + } + } + + fn update(&mut self, options: Vec) { + self.options = options; + self.updated = Instant::now(); + } + + fn sync(&self, other: &mut Filtered) { + if other.updated != self.updated { + *other = self.clone(); + } + } +} + +struct Menu { + menu: menu::State, + hovered_option: Option, + new_selection: Option, + filtered_options: Filtered, +} + +#[derive(Debug, Clone)] +enum TextInputEvent { + TextChanged(String), +} + +impl<'a, T, Message, Renderer> Widget + for ComboBox<'a, T, Message, Renderer> +where + T: Display + Clone + 'static, + Message: Clone, + Renderer: text::Renderer, + Renderer::Theme: container::StyleSheet + + text_input::StyleSheet + + scrollable::StyleSheet + + menu::StyleSheet, +{ + fn width(&self) -> Length { + Widget::::width(&self.text_input) + } + + fn height(&self) -> Length { + Widget::::height(&self.text_input) + } + + fn layout( + &self, + renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + self.text_input.layout(renderer, limits) + } + + fn tag(&self) -> widget::tree::Tag { + widget::tree::Tag::of::>() + } + + fn state(&self) -> widget::tree::State { + widget::tree::State::new(Menu:: { + menu: menu::State::new(), + filtered_options: Filtered::empty(), + hovered_option: Some(0), + new_selection: None, + }) + } + + fn on_event( + &mut self, + tree: &mut widget::Tree, + event: Event, + layout: Layout<'_>, + cursor: mouse::Cursor, + renderer: &Renderer, + clipboard: &mut dyn Clipboard, + shell: &mut Shell<'_, Message>, + ) -> event::Status { + let menu = tree.state.downcast_mut::>(); + + let started_focused = self.state.is_focused(); + // This is intended to check whether or not the message buffer was empty, + // since `Shell` does not expose such functionality. + let mut published_message_to_shell = false; + + // Create a new list of local messages + let mut local_messages = Vec::new(); + let mut local_shell = Shell::new(&mut local_messages); + + // Provide it to the widget + let mut tree = self.state.text_input_tree(); + let mut event_status = self.text_input.on_event( + &mut tree, + event.clone(), + layout, + cursor, + renderer, + clipboard, + &mut local_shell, + ); + self.state.update_text_input(tree); + + // Then finally react to them here + for message in local_messages { + let TextInputEvent::TextChanged(new_value) = message; + if let Some(on_input) = &self.on_input { + shell.publish((on_input)(new_value.clone())); + published_message_to_shell = true; + } + + // Couple the filtered options with the `ComboBox` + // value and only recompute them when the value changes, + // instead of doing it in every `view` call + self.state.with_inner_mut(|state| { + menu.hovered_option = Some(0); + state.value = new_value; + + state.filtered_options.update( + search( + &state.options, + &state.option_matchers, + &state.value, + ) + .cloned() + .collect(), + ); + }); + shell.invalidate_layout(); + } + + if self.state.is_focused() { + self.state.with_inner(|state| { + if let Event::Keyboard(keyboard::Event::KeyPressed { + key_code, + .. + }) = event + { + match key_code { + keyboard::KeyCode::Enter => { + if let Some(index) = &menu.hovered_option { + if let Some(option) = + state.filtered_options.options.get(*index) + { + menu.new_selection = Some(option.clone()); + } + } + + event_status = event::Status::Captured; + } + keyboard::KeyCode::Up => { + if let Some(index) = &mut menu.hovered_option { + *index = index.saturating_sub(1); + } else { + menu.hovered_option = Some(0); + } + + if let Some(on_selection) = &mut self.on_selection { + if let Some(option) = + menu.hovered_option.and_then(|index| { + state + .filtered_options + .options + .get(index) + }) + { + // Notify the selection + shell.publish((on_selection)( + option.clone(), + )); + published_message_to_shell = true; + } + } + + event_status = event::Status::Captured; + } + keyboard::KeyCode::Down => { + if let Some(index) = &mut menu.hovered_option { + *index = index.saturating_add(1).min( + state + .filtered_options + .options + .len() + .saturating_sub(1), + ); + } else { + menu.hovered_option = Some(0); + } + + if let Some(on_selection) = &mut self.on_selection { + if let Some(option) = + menu.hovered_option.and_then(|index| { + state + .filtered_options + .options + .get(index) + }) + { + // Notify the selection + shell.publish((on_selection)( + option.clone(), + )); + published_message_to_shell = true; + } + } + + event_status = event::Status::Captured; + } + _ => {} + } + } + }); + } + + // If the overlay menu has selected something + self.state.with_inner_mut(|state| { + if let Some(selection) = menu.new_selection.take() { + // Clear the value and reset the options and menu + state.value = String::new(); + state.filtered_options.update(state.options.clone()); + menu.menu = menu::State::default(); + + // Notify the selection + shell.publish((self.on_selected)(selection)); + published_message_to_shell = true; + + // Unfocus the input + let mut tree = state.text_input_tree(); + let _ = self.text_input.on_event( + &mut tree, + Event::Mouse(mouse::Event::ButtonPressed( + mouse::Button::Left, + )), + layout, + mouse::Cursor::Unavailable, + renderer, + clipboard, + &mut Shell::new(&mut vec![]), + ); + state.update_text_input(tree); + } + }); + + if started_focused + && !self.state.is_focused() + && !published_message_to_shell + { + if let Some(message) = self.on_blur.take() { + shell.publish(message); + } + } + + // Focus changed, invalidate widget tree to force a fresh `view` + if started_focused != self.state.is_focused() { + shell.invalidate_widgets(); + } + + event_status + } + + fn mouse_interaction( + &self, + _tree: &widget::Tree, + layout: Layout<'_>, + cursor: mouse::Cursor, + viewport: &Rectangle, + renderer: &Renderer, + ) -> mouse::Interaction { + let tree = self.state.text_input_tree(); + self.text_input + .mouse_interaction(&tree, layout, cursor, viewport, renderer) + } + + fn draw( + &self, + _tree: &widget::Tree, + renderer: &mut Renderer, + theme: &Renderer::Theme, + _style: &renderer::Style, + layout: Layout<'_>, + cursor: mouse::Cursor, + _viewport: &Rectangle, + ) { + let selection = if self.state.is_focused() || self.selection.is_empty() + { + None + } else { + Some(&self.selection) + }; + + let tree = self.state.text_input_tree(); + self.text_input + .draw(&tree, renderer, theme, layout, cursor, selection); + } + + fn overlay<'b>( + &'b mut self, + tree: &'b mut widget::Tree, + layout: Layout<'_>, + _renderer: &Renderer, + ) -> Option> { + let Menu { + menu, + filtered_options, + hovered_option, + .. + } = tree.state.downcast_mut::>(); + + if self.state.is_focused() { + let bounds = layout.bounds(); + + self.state.sync_filtered_options(filtered_options); + + let mut menu = menu::Menu::new( + menu, + &filtered_options.options, + hovered_option, + |x| (self.on_selected)(x), + ) + .width(bounds.width) + .padding(self.padding) + .style(self.menu_style.clone()); + + if let Some(font) = self.font { + menu = menu.font(font); + } + + if let Some(size) = self.size { + menu = menu.text_size(size); + } + + Some(menu.overlay(layout.position(), bounds.height)) + } else { + None + } + } +} + +impl<'a, T, Message, Renderer> From> + for Element<'a, Message, Renderer> +where + T: Display + Clone + 'static, + Message: 'a + Clone, + Renderer: text::Renderer + 'a, + Renderer::Theme: container::StyleSheet + + text_input::StyleSheet + + scrollable::StyleSheet + + menu::StyleSheet, +{ + fn from(combo_box: ComboBox<'a, T, Message, Renderer>) -> Self { + Self::new(combo_box) + } +} + +/// Search list of options for a given query. +pub fn search<'a, T, A>( + options: impl IntoIterator + 'a, + option_matchers: impl IntoIterator + 'a, + query: &'a str, +) -> impl Iterator + 'a +where + A: AsRef + 'a, +{ + let query: Vec = query + .to_lowercase() + .split(|c: char| !c.is_ascii_alphanumeric()) + .map(String::from) + .collect(); + + options + .into_iter() + .zip(option_matchers.into_iter()) + // Make sure each part of the query is found in the option + .filter_map(move |(option, matcher)| { + if query.iter().all(|part| matcher.as_ref().contains(part)) { + Some(option) + } else { + None + } + }) +} + +/// Build matchers from given list of options. +pub fn build_matchers<'a, T>( + options: impl IntoIterator + 'a, +) -> Vec +where + T: Display + 'a, +{ + options + .into_iter() + .map(|opt| { + let mut matcher = opt.to_string(); + matcher.retain(|c| c.is_ascii_alphanumeric()); + matcher.to_lowercase() + }) + .collect() +} diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs index 3f5136f8..9c3c83a9 100644 --- a/widget/src/helpers.rs +++ b/widget/src/helpers.rs @@ -1,6 +1,7 @@ //! Helper functions to create pure widgets. use crate::button::{self, Button}; use crate::checkbox::{self, Checkbox}; +use crate::combo_box::{self, ComboBox}; use crate::container::{self, Container}; use crate::core; use crate::core::widget::operation; @@ -252,6 +253,23 @@ where PickList::new(options, selected, on_selected) } +/// Creates a new [`ComboBox`]. +/// +/// [`ComboBox`]: widget::ComboBox +pub fn combo_box<'a, T, Message, Renderer>( + state: &'a combo_box::State, + placeholder: &str, + selection: Option<&T>, + on_selected: impl Fn(T) -> Message + 'static, +) -> ComboBox<'a, T, Message, Renderer> +where + T: std::fmt::Display + Clone, + Renderer: core::text::Renderer, + Renderer::Theme: text_input::StyleSheet + overlay::menu::StyleSheet, +{ + ComboBox::new(state, placeholder, selection, on_selected) +} + /// Creates a new horizontal [`Space`] with the given [`Length`]. /// /// [`Space`]: widget::Space diff --git a/widget/src/lib.rs b/widget/src/lib.rs index 9da13f9b..316e8829 100644 --- a/widget/src/lib.rs +++ b/widget/src/lib.rs @@ -27,6 +27,7 @@ mod row; pub mod button; pub mod checkbox; +pub mod combo_box; pub mod container; pub mod overlay; pub mod pane_grid; @@ -63,6 +64,8 @@ pub use checkbox::Checkbox; #[doc(no_inline)] pub use column::Column; #[doc(no_inline)] +pub use combo_box::ComboBox; +#[doc(no_inline)] pub use container::Container; #[doc(no_inline)] pub use mouse_area::MouseArea; From 470e13c806f4239ca3f2e90e9c0a794a81e354d8 Mon Sep 17 00:00:00 2001 From: Joao Freitas <51237625+jhff@users.noreply.github.com> Date: Thu, 13 Jul 2023 14:18:57 +0100 Subject: [PATCH 025/321] Add gif to example --- examples/combo_box/README.md | 2 +- examples/combo_box/combobox.gif | Bin 0 -> 1414629 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 examples/combo_box/combobox.gif diff --git a/examples/combo_box/README.md b/examples/combo_box/README.md index 5fc87469..9cd224ad 100644 --- a/examples/combo_box/README.md +++ b/examples/combo_box/README.md @@ -7,7 +7,7 @@ It displays and positions an overlay based on the window position of the widget. The __[`main`]__ file contains all the code of the example.
- +
You can run it with `cargo run`: diff --git a/examples/combo_box/combobox.gif b/examples/combo_box/combobox.gif new file mode 100644 index 0000000000000000000000000000000000000000..f216c026dd60e5fee34999c120bd1551588ae233 GIT binary patch literal 1414629 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�KREf%)A-E?xn9(KVCGjkByG2H`j-BE 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 abfz$ zjE8YEb7H;p1Nt|fFS}g!k_JopC|V)b2vO`>D#s-!oU6hufQ%Zr|Q`y1ewb`IB$k=RVzDW4xpJe|ZA8MeBN& z#`N#a$~)TBPc^3-wzyj~)mPMe@0h%_ytO*5V4G~`{nefGccd<>2w3-{Y1@u&>$HMX z77s5~^h&FhZsY6oU)lHm|Bm>3Kl(RUG;r_a5w4t=oHarDXSCMONz6YdTK|0QR5@jO z#^m6gk>7T7t-d&Qb=tJ-o#9cHJvBe`+IG%}R-IYj);0TQ+M>!?)~S_c2U&U==H9Lp zn9??Tz1p1PI|HQ*p3GnmQ*f2iSkeEUHTuYpdBPF%e^>f3SuuWST=Kbb@62|g9@a&h z9VDkPDr^2)#2>NP`j?H=hqj7-rX3911RI1ltacZ1m~i36hKgUy>n}{{{)Bum9VnjRj^!T+=!t%%^-c)%A&<-v!>i?l!&E z8-1_m8!zbld1>a1yL#u^*t12n@}t+cBE%jj-yMXaDilH3MsrdUo+ z^PO#8`0UEg$?5*{?Hk!dUtMNkW^kXV7P@OnX7FF-=rvA?gT^+tL?dqs(Ly4v60KR&;{e}7`&mj8@A0S6d4buJuW7W4@?$a*r!d&)L} z3px#qhqM>4sH$yn+07NOftT~_i>?W6m#QQjni(z}Simgu;L!=@g9Zx!A8<$5oXFjL z&aODqq=oM?!{kf5Rw$V667g8HnP)~u#`b%4-0K!HxkM`PiTmj=?ACfT!$Cw*TjTIH z*)5B+SvAyNJZO0{;ROS;OjtxBgO0!kMP8=5jSH3keK-?*-uCC4%l`BJBnMn@&f`XS3=hjsxo&Y}sxxt>e52 zC~g_Dk%e39g3>WvHRiIZLVX5IHoRhr3hYXoPv^B=>f?BOzVhYT>-VZZwrU2r{e1iX z`u%!FzK92n=Yz6MnX(o*CQ424SloQ7$Rn4*j7`e<5z{lN1q>=7ClpwC1q`M(h!)Kj zcoHV=;Mh1R{pd!w=>@jM?Z#F!lnyaC9I@!+F|Y{Ro-)03<<0bFhZU`&IuF9w?v_k= z!TIKx#|rkRA`U+0C!I1J7fA`MaJY9N!a}8a$|v31Z#G}_i(X#KnRol`_J@7Z?{*#y z;+}A6m2(DTxM0&Frl7(Vegc&*yS6ZBMjUo&4w5`H3o!NkSVQc2{hun>BD;(N{>UO+tH%!xTY)kZa zVPJ2G6Zr4=^XXLa41WGclfvJ=T)F;UmCem%(ZApBe1Grvd+{y1t?Yhj?C+P4>qul{ z+2FCO;Q*(AOBkoAn+>y%kn`fgUzScgdrpcZSWd2KOXWRym1{xhOv5c6CR`eKUouVD zb#?2Kl=a17&KDGPdn)>x)jc~T!WT z-s3Ht;Vk<|rTW3=hy0BaE{bdy^QHzeY;bCBy%4fe`MvO*l$<9PzZ04CepxfSM~GQ6 z&0uVpmd(xRF3u3sn!qqu`2bV2xeTw(g>n(F;%Zi68+y@xs|6dbtQrVEkRbG<9zonr?@PtB@^_C~9hM9Zi_$E%C`{jwcqvZ-E zA&076FHdxvOqTk=>15=4d=d|;nD7VlI#tW%!s@W#7 z()T5fGemrd+@zfPfK}W&_)!$)2U_ zCeQtPD@Eg>q<`hP$@79GRo#_XlzR6roo?mOA*&?npdI*$n>o?ZJ*D&fB+&;fOh230 zQx-G|8zwMGt~hu~W4jTr29u)J$thfWK4@}RG$@ud9x{|xVs=e=z*9Bxdi071OPH=O zC`vQTWMv9wxXTnM;t;MZO8y?Mxjb@d8 zlh7unpum#%qe;+2jNuKB0xO4Lqfn(mqx*!A#R8&DVy7Bzc_mHVzW3`|-z~pFAM#D# zaWwRbZDypyG?9iP3jvQK8;WO$>a+=1Bpmb-@;d!+&VkU31sA#>P2phDP-NY;`&zEG zbAvz#1Gm+Sb4n!>?g(#i_qB6w;80<2efYn{jh%gGg0qEJ!}$xB*c4wlvGWxM@c(g$ zd~oWlmR14FwFeB0MhhIvcid3opOe7D{lY;+&E@L-z8OdM@vbWjoRcKFeuvJZ=!VBC zB9oQ<7%Pnv4)gUmw6h8<;^ykeE=%U==8}0L5O|@7b=tDlQx*pWtP>9MxH$^&_#`N6 zy*cRl$biZ5!9fAP7Y=+@8yZv!kFcgYct{2nGzoPq5Uy#6Wyt%`#wW0dT{GbzCy!#+ z>W(a=L zR2AKFwd!Jx7=lRz)uV=qcrJP}0DO zy;4(wC7`3_o|vPqh{x;T-yscx%N888vQcEnTH!ZI<+6aL#X>6y$yO=920_aWYZ%No z96qe=+@R_5@Jjq)M_I3Z4bB;f?Ea6I^B&vKu}83h{k^8@?uqkCUhRy&=Ue{ka_fp| zCAXg}owSpY`9neT)PpJW-T4bSRwOW(Zeh{W_F$Cr3fP)sydh=9|8-0`PRbpxWE{gT z?Piqw(C{vJvgr}Agl5JS3_fRm&b)x<3k&~&6_Vk)ynV^rAz|Ml8)KTX{(etF@% z%Cq_Za)bDjeL3RGn-06|f@1I^g z`y&-l?*IClt)F|r#;H#y&abggocH-``M=NnPk&wv_czvc;1DmF;Kn_LQ875+-}i&- zYo0mJ|MS$mzF|px)z;2Z29Fcc8g~-fWCC{cX9d*%_&EQ+VE_L=f4~3#zg6jP(Tl=K z3;5TpHTt%Ig~R>7#0JL7?*9x1OsWM;lbsj}JwAmwa0M{%yl~)lJHUG4-9MQEmj9j~ z+7u=*1sbrPKF{R6fi?C6>+{Dfp#^N20{!Saoj#Kj%gP*OLs> zv;{;91*hxr^L`Xm3{3blK~Qs}(AN|JWkX@pjYoMFxVl^rax@hA$SiEWQN*`Udx@V- zK=blvk5-;}ne!w4Rm!5b%lt)h3-5Y-6e%qfU+nbinGhi_~U12 zbCo>M{cm?s)ue%QMnXZ~d$F|}j}%Q5-&!c$@AOJ1f#s1x{wFr(I>qvHZ9X9izw?}u zBOa(EJe6E;D0f>^dgn$te?fkp1<^J=48IaY-ZbzDIVy-T@CGTza~%*9XnL2YWbWh; zb;?0bvFN|dMLEq)N-LWfqa0Ww4s)9<_qhWrB{*k(VHM!@0TqiE2d=!mV z;u1^bf1nq%B>j7o5{m#+ScQJq14E_SAOZDDO07j2Qx7qu9bmY>fTh8IxmpT$T_eMz z18mFsepCg`%qmp(HBxiZzwPo^wcu0em#j~9MLLBYa-E-a&TkN4NMJ5l;Pb_M!MdZ& z8tj|`OoGz=+W(6mEiG{|$Wq_hcsJ`b3+aj$OJ6Nwo3WPpi9+T! zKE1GIEN%%bD-xXk^zkYwGi-ank>S9SwxBJEiGN-L+aw2pJ4+h;8n|vOxMcRgr2he1 z+#=JJ4*C&pjAja)84ox=I2aUfQp{suZ+gHfkuaan*s`(6aOP#XbO$a2CV_%9qeqJh zR;=18mcVDSfL){UYTbboabC#<57-SBT~$hC;o78_(ZvvSfT5z{Du)C2Jg=~%1y-vT zsP-LTXzvp=d!SZ)iD{n$YnvW#M)8LuL6(AB{LgH%loa8ZzqwpYfn$p^TaA~w-de?| zZUz?x_9d!<5{|3_POSeQEmh4>$gg`S$mbMw$Dzt)fmPE2>&FK;SL8CfIaa-z%uvOb z?$*Mfk;rv{L1dLPtHT<_eVcg1nuVAaihNQNtZ@|+{^B`Z-%z^5OSzEEn_kYkDMlt5Z46$CY%0eXBocvL3%DL>U%-TbWR zv0L(aZMY#m#!{_rvRuk%3AYq9a_O+iaTHS|n_*M9wPmcSh3ED&}$)M3k_ zR}Abc(o$mNjjDh*w0k)I|)4LEd3JY_>IT> z00T=F!<7YW7ZhRzoQmQYj7=8DWIyZJqo!xGz?IV>MqJ%WDk=5eBBoafOkYf$y4aXS zju&eAFwbFNmRp#xy4lQ=U3pmpYt1RIP0k*xmMI=zHc8-dEQbQ;t}Rm5W;yMPqMWzo z%w4b1l9C+D&i+Dy*=j-BvTZSQmog`@7CcaNSCF_6}DS>9VpCEV7FmcVfdi*s zDVU2WG%a<0J11*tjj~DJm4EkAECn(cRwb~VdcdP~Sir3!-^=3el4R~x%4`!Zx8D7s zmJreQbjDFL2F0lfTZ8;nOJ}rmJLKseyrj^s_o9f2#gTE%`{FQ0lPl}^)edl~D0g`~ zH?0-ZTO`iBN8w4{m+bjm4Khl8CJTKIEa)+O(6ir-aaBTZ<+t9@ne3tEeX%$Hn=$aL zO6L3V((lR92u_Fk-#e^08dDZ>GU_NY-%DWK(2zZU!SZ`4qW^6Uu(BMQ*t*13++k8H zi=IgWzuJRI!OD{lJM$e_P`}ZEV+mJ!9V7E4hbi6?-~DDXBqex+?VS5{>C|}3c_;gI zITM+b4suLmUc6@+tJlF2lZR!3P3(RQ=|-=Xa5Qj=9cQRu<59`Vyu>VWYcZcv2E&5L zNvoG-t*T_)qhQ12(A?-+7Sg~K)me0|x+xDarY?GDdv?_qhk`&mORq9ALQ7d|zuVgI!6t*8;8}2bM`+Y*l|5 zXh|8Kdf5?{ym<3YE58RT7diOWIS98ju!bctE6idzw6<7%0gsoEUf8U<|M9<;CRZ){ z7&VW_Av(E1;KQ<8QM$}q5?Cd|@-i2&u{4?fnRP#A!DgKX#xp(XTFnYk30xry_0ZD@#G?U}((I`(?b!52Sk86`u0VTKD?a-1k=NbAM0%b}PHY zf%`|osib$}MGEo{AD4+U%r|uO5oBV%CNW)t5urqdFBaAC(UMXOJuf)+8SZKj=h1^u5WJo?z!2&x4n$+_$IYNU@_B`1+0q> zFqAkXi7=!TxaGMn$kth4s(6@fk6Kg7G*zzz_OJtaFWuK96)tpOITpm(b>tOWUIO?3 zRSq1}l)q@y?4P4GYn#!&yA}IhS06o?zCJklAou3Yxh)6mKjo`r9pqg;rEck*ADe#s z+4Nn*+gL1pO%a>R6|*C0-<$&f^oGtkI=80!+b;*tKb{$Tn8Fl7zkX6xSXE;=dv|q= z_R4olol?$x?yOtjd20HflG%Sw-n7YEG)K*)=fF(w-J4|8PQAP|CFbPGb85$AR-Bk~ z=&a1FOEpuk?>WmmH-Tq?@WVY*f*z=3EqLcM{Z~ZAh3Fj@`2Sw|f0RMMP@T(xW0C^r zjR%u*CS6LueaZ0e6>-hDzmi&eowfB^;os|b z1?E-O-l#uuz47mj|K`3oI%{w4K7M23- z+ima6-g|5R-aA*-ZXdP1yL-{?vwQD;WW9UU_TI*(yLb2Ad(L|AsqOvchpuNAeNfxG z{nihErhE53^56gZ_rcsl*E27=U68r_Wsbkxyaz}9Zwl^vB;IoWYnPaI{*~V?k5%g) z>DoOJcD-!McD2ueds%~E*GCRNhnHT@INcVoN!i&a{JUsx_lGC$iFVxO|86XYE|#z) zojSF#P07xl;qQx9e+>sUgLSEeDG8!q&J;|nd$sc4{rN52Mh^t@M(mV6rzv zrTxALBhRjeiAz~|HPUN8E_vm?=U&aC7611&u%#qaD5bFPU|`N+G{3v=eKix~hPc<; z|NSod_xf|~`ffGmJqngetP%4b*s3?MalAY7b=9Z0y(&A`-8cO6_Tju&%kD5$IIzko z8buvpYuLgkwD?SB?vdOlFXoD`dcJiqoDSGyO)2GropZfQH z;I+TUtH8x$z_;Q-ltxPG1_$1GMq05@-_3n+6s&5Itl_D4Q>C@ zEEH~W2F?F!XtQ<4e_bV8!H4$8lHxyf{`qIL_|=Vhn`-?2-rKKzUGNN}QiDSyE1Q&# zM!-P_7AAIy5Q7B`F3lp^QF}TJ7a!}Dv99{VVYKALM9KfW1`G{GOHWPJiQZMiX}s*r zOq1+edpeDmpPOq_{p$~>$%+dLUAm=gyS_YYQ)c1FXtYq!a$)6~U}E|~ps|NhOpC{X zL9Frc2G$KB4hfEqtlT;x6&BiM4y^pFB5u454$N`95udUYv;`l!wllst*D7&fbt{vc zgrJ6~#X?;sKP`=fA7!kGO&t51)(RvrOj|Kq|FJHEnSyKISM&GM`Pjn974hM^Lkw#|^Kz318(PD&3?4Kw zt&Vx-n4#)n=)~hzazdbb-#@OL4TqLJm#aS}*PXNJl-}u_&FAc@g_$k>n`~vz3<^xm zoxr46;36+8u)%>%@=KvhLdet&2Utv}JUGJgt}LLPud>(ClkH{FheLcF3&Rd@YOI*x z7%aOY;W%egY>FyZdc$r9cJ6{ihGfMjKZ(DYfM*w$2$%DLLtpyM7hI54!Zsds8`1E$~&t09< znX)c4HtrBExp0(I-Dkle39gI{Ocw$yLNY}R-4iFUnl!|GK5G9UAduBxWsy@b%MrmA zrudjWOwK)_A6@Ti2`^xh2<7Rnc+{o;FMHz!JHE;%ll=WEpH5S5Z5OdmFmM#O_Frtr zoNbId79L_^+4Im<-8c0^YgE?PbV%jJ!<`UAtroM+^ z3s?6C2ahv;Qxur5h;B4!J;nV+(BmkJMk8};#g*R1mt~XpepL1^_~$IUG~J<7WIOAD zWBiQT2R-EHluvNZ$vNWVEdM~LfqAi{i|=|%KL(x;Y@$95LiQ0ZmtP%VV%f8lMfOC4 zq|9O#?>~JE2c_qgc|B<5Nm#%<_e30fodNTLN?pTmO-znv%B{;5phMngUG>5|%bnPv;Z@ibvZmv)Ui(pkPPP&pXKQgKjtRf0742?oXmg5693%1z564l#&)Vqj)Ecu>VdfKjvHx@1KHgIJ0O z_oFICwigO5D|RGsaR)F8e+infw{!td&WZzEWelvB-!ke;oOBG{HKFOkjR%}wGY&|4 z70i6}v4O$HBQ-;0LL2LmhrE^x4$aUBV7vVH0gK!ZFOIOvHp@8;in;+T?9B_L?97gG z_e^l&*cGHXSJXgB?8BjNO$IjHIgNbW2M$O`EM}19c+2Z=;h5z0p=sHPgI1`&%p|dJlSIH#CavN`*CdYyjSo7U;;)&cpII{a>}h1!FW}@Tkic?T_7Nx7 z#)G`C8W@lJ{C7|kl4NBx_`vF_`G6&$L0x)p$k8dQN|rv|`A9sT>++0KCCg0i_A{Cp zFo@h(JG+$Ou<(@yjiD2k>sv*<;LmgL-=O$_Wq)8ue|b#Lvn`0ceV@e%TI_JDrcM$%u1Hz z4Pg*q>1c@%c+keWCy}+pvzs^UVAG|>h2bKa3{nR|o7#RXV~{-8u;>6oyi#26yWP%^w0h*ceyHF_xVcz2BwBz#y6t+c%*_GJw@I{-)!B zCkzqHJ_(Gr*BsV9X=;#MlFbzN@qdFfM?r_yjfN1$gwI?`hKw2=*Z0hMXW||E>s~;2 z)s-cBrFA}^PBFbv;I#B;xodTyQFFnk&0P@>cxRot&2(cyUbO~?bk?z!%3E$ao-fq= zwuUwYMyv@Ht6*k3pz!c<1RHnk3kUf;mx)|DIb6*}CsNr2S~*h^+6|^{jLG`L#{H$$ zb(Q52rd^~1ZEH<7*U6cpE-3{qHJ`4P{Iij8@GKMHdfDovZ6M2~q}0Cb%mM@D zL*A?j8#`t+9%DXN)*P`rNV~P#h;P-`Ef@dypR)*r@f7j*t|AZ#5NY!JrWaN7x zuz{~2v4Z2lK^BR?EoT!lrj}}Oh_dybsnt~2&XU2{<{&I(5b-8kTi`oWM#J|#kMHIs znTBTMJ^18RyOhakf)>}k6^)^v5)3z6erICZ=yu3~h0(prF~cBnmpF^!d&e6#ycXuH z9UYSy=BUaY+R?zM-qZRhE6|ynWua=dnW`?wvjrSQ&f6~ZIHXRw>lAF_J3%eHflI8L zvC~8$eR8ul7hmG`J&O}K1TqgMr6zcIaw=R~nX{Uy`a%&y-iM1kPik47$TRY8+0Lr2 zT>JM;c>kq^eE)x(uK#Cf%9*jkZUNT~2S%QPuPk3W{xkectE^L&U_HRfa)6zwQIGq9 zWk8@r@|7|jCy9gwMj;y+?}`|AKhtvzc5D}x<}=LaHej0i$*rZ_FfT#6^SD>f_p(JB z7$&HT@ivOP8?olN1jw+MG;gyiyX^JBIe+0tI}t|*zYAhTf&SeA=Ihf8g%gr4e)N1{WohjQf)q+szp)6AY84 zR{NSouxyYvPcVGAsnKdhv+M_rx9lB_8FKI4>svEA+B-T1fvQ^%F>?p7uX1Faw?jrnsH@3PS~9JR zd4s9&hG^Ae5*O11S{l1q9{4kFOmz}4&<_{iQz5nRAS-tQ=Y7Th%^V57`VERRwlf$9 z7zsNnrVGk0bFFe%QOD9)wQ72ShJsU?0?X!&{zV2Et}9Zw6`1l|TbDUUK1iRkH%a$! zc#W}I|3b%prl)<98#s)ohlvU>Xjp3V2Lc<6 z8BGkPST=WhxiOe-5M;Ap^ivQN4KOb~5GcVU*uRY-SCBz5BEQ9mNy7cVl0z7mDu8;Zc{SIXk!pvA;^%mz$i^X(EmYx%t7fDfvk@n%bF>;lsrgY z)j0W>>MTvJSxaWl(tWi^pR1IuU_$W$;~GtYwhw`NAqi7kPDa z_WsC*#mQDF$?Pl+oRfuAQiPcUHuR~AF{B9?8z)pP`RJ!5;F#>r5GNph^X9yZB7&=r zU@Zu)etA+bCScj$BtxGz3BHX?wF1VSA`CBf&KJ3u5Edbk#-P_0 zV8k29S~$U9=TVkTfw+w^LtdL1>jh@tiAfThq?81V^~D)N6Ab+VVpaw+&Rq51=w2dY zSwi+zO~F7zrhpH=sVf(4tt!#sTD)`B>fNj2*a}#d3Uj(GC{TSNs>_ffY)~AQep;Tk3Q_m)V;A_mcLSyq~ zk?sdf3xfrv8kim_+sQm(tvIkU-jLbKgJbT5xhvHrPH*&TSTNJtK$3BfQSbuIhbL!C zZ8VlR#3cR2{>!r64Ovm#0n93G0{^OZmo8+8UvRK&GV@SqoC(ZR3^KS|*o0!lOE=oP`Dhd;7+OtGu4&t$ zuOjY#K~JW{T*KhM+Qo^2GZMJtb-Ys(3^ckFJrg!Rm^Amhmy)O;2e-muj)mEV8#vx2 zS@ld{u~8Aw6ENoJ7A#v;wWO3OuYk>pgG*nVeOYtZBbVuSI>k){jJMyeVNPI?eyr#B zfrYt2PvU`5rD3Mh2W!L6Y#Is7K?P<(5e#kzIO1hEQw5k5FNkP-ST%JSvxbAY>;d*X z0k1LvJ>f}SQUxs24pCR={L7 zA*^YE(NiW(sSR!hNer3}Da=aY%MBUK6BzUiY--p#XLBdz)=P<9SL^Al*=q zb>Wq-RU4Uwme$ltb3eOsdr{J*&u(%$jc47HQtsA#wsttbQ-7VOP0dZob+!kY6FK4; zSgjjw=rHYKIly3XSTfc#>VjcB=|u@m33#JUc)2GQ7iPyJ+>W?f)TFyJaXz!H)W zyMD>cHy>qVMOn%wFefCixdkZ3O}v}N_o6xDVv^sB)^ig-w#r5Co7Z^mMen;8c6khK zdM_v2Jxj@ZIX&+sPs7XEe$RLgFsOZeIcML?g?dG=mgc=$-uG(xyO%4^y_$RP)v9+d zH|o9Kr1xrb-s|msuXmh#we#HTz58CR=X-Nd@6BPqH%If{9PfK`-0$V-b8q~ozgm*_ zYW2U@EBM}?%zL{y?(Ok;Zx6qFeYx-DUA}kQ_q~4T_wIV$yXSrHUaouhdfuzEdRsBC z;pzb2BMrNT>n-FOuJ`ZXpE+~(_3PI!U%oVpxXHlCaOUi}=g*&8M%?@O@zbYIpZ@;` zU9QE%#KgqR#Ky*U>hvk=s6BuF{C)fR|D8K`jKgpI{`ddIix*x|Yuu_+=;_m^j~_pN_Usu83(KWTm;U|#cmDkOb?ess`}_Cd!-uS_tS3*NeEasp z=g*(Ne*MbD#r5F9gOw{+UcY`lFfcGYJbc%#T}@3*8#it=in{&t-+zmU>sPN{y?pty zuCA_?l~s0j_T;H^zI^#&XJ@x~@#4dW4_ibWK6mb%LCA><7cOkyzFl2iefjd`$BrG_ zx^?UEXLOb!*wOWl~a7H*el7FRyTRcK-G2mx+nV!Gi~X z|M_DPabfl9)ym4sMp4)2&Yin&-@bb<{#%4y3keBHPEJ-(P%sKV`{mF7wzf7oIk`Q1 z_IP@F-n(}%DDCK%|Nm{nZqJ%E%OU3YlqMN3AF-Dzb<=*3r@N_Sb()OUtUNs^H+@y1F`EUf!;y|DD56nVFe|hK6QlW-eN^ zNIU4DZS)XnVz0rJ?o!K z^nv$({`(hQcZ=Go8+6elcH7a@k6fdVhNez2kGks+cfdCGbWcx@XV|wJd7`0 zXP0`{GUS|9_`T{W@7%&SMQ5zrarVDc%8}`d&rVwK$T?}fudlC1#PYg{r%T$dfB*Y` z>)wYoy^qafZ|yqtY{G;IhT(hH?0#TiV9?sy>gMJqA|le)*B4WE$s+pd{!{-WBO}+Z zU*Fx`9TZi+W5Y_}eag@4a{bv$C>Ip1Szp>;G4;zb@JJ_tm%muiw63wfV-0 zYyT@-w?Fy#f77x5|NsB&opJv4n~#3+E6&~fADYt-RbPbn~vKT`= zLx<+cO{s?`FmJBGdJR`fOOrvj*3!z7m6sb8J#FTCZC!PBb;M@yHC*9MzS}u+er?rh z(9}5lP3Du++S}U;9-o@)y?x!?rSaeH+&w*MO{k{lPcAv19UC4V?huw2QD$M_<>L9f zX=X>_Q^)-gvse9i8Gc6mH1qx(xsIPn+@ed_lMF1P5)!8CX>6IhaL2Z{w|5l3zPERy zm*Yx?2o9E{fKvyqF+1vi;Wpmt`c!hRxKE}5)2H^;p21V>wzcNJ<6fx$|NOa$Hm*!2 z6|3XV@7w$Pd*M`jMg}+2LkAY=Fs(FtY#JuPGu2?C1cTp`+b%^BEsPb+a~Td~%$Bv7 z(84*_Vb_j4t2vA89IVDtjnK7Vk4tt`Oma}Mwr|?Qv%m0o7 z3uc=p&3AUvTlIR~o^P*SJKxz^6)DbqHsZpPz9jdcb(|-6P2knyN|9uo7}xT~sZ~LQ z&AImy%Uh466zN;3`=@2U+xg<%u1J=KRc+2yfqY~*lN}TR5vjx-cW-U44;b3QSkh{RE zgo8mbpM}FM-a`3p=~Sa=Rza3P_Z(-@-E9ZYOR?*Ix#04eE!&YpyH(4>a%sTDQ(>+K zo4n!^H)LIm0No>P=ll0sAe(->;6Y)>xuK_d9Cwz?5IK0s?0Ug*-S2mlmxgR|`er6t z=44&`pJnw%me@uH7r`^#-yA(do|w7cmovXo!?0v$g_Es%ikYL%hJd$8CFSpaK3~xO z@3P8vJFQy^;nJ6FXs7#L)~@^DiEL zcU=GfpD)H=Touy)MF0Qy=llD5{{o5Y|JghaFiCxA;P6?%B>rRLUc(QK0zD5BWHb(P zMSW8K7j9$E2MSaA2kMu>`mmbI2&Yw7Dc1V{g zvt+T%^Nw8{HzxK~oKb#Z@qk(T$H#uV2Mr4Bo+q57K27Mre~+}$q^cuIYd$pg3(WX5 zW#N}OnygMeAz^_$=eu2X*o1hTDh^C7`rM$$`iU*ZYoZLpf#cTq7#sLg9?y{f;lO6} zzM&6 zU4@OE&&j$XY0cdCTb>IvEB-&<9OFA*?6A5+_lfhBQcvbH+fH{7);iL3X>umd*&9yE zznt5}p0J8o@VdU&6e!QzvgohQ38rh`0$a;W=Bpk}Gzgd#)H!dlEv1v`T09lNmH%{M%7@++q$Mpt9JYhQ8A)e4Pw-MUI+iB?#7 z>D9H<0#<7jb#U(awQ${}(3S+-*9*_Ay2ih3>)NO!?HJ1$*AAcEYFo7THS7IV*M**L zT`%-RJHhqK^@DZ+8@4)Uh;e7%U{#u?%AT<%NMaxB&bGA71YYI5K zoEF+0HgVHb(+8=dmsnb_Y*tvwc*jqvTkz8VX=+T%R8L+Msdl-tY+A!=*A7;mCdQjg z4$Nx;#aw)ki$2bKvh_?Wm*axlx2OLzYd*M?vy^dzTh|jUMx92+%vPg&uV#JTbtCnq zt5w`vP{S=t&>U)YqmyYLfJ^XID;ftoB-$-Q5(!;1i+1~T{@+1_8D)Avo=ktDYJ{8813`c4c>p0t|GR8wr!m+j6;`KGwD zxVrfx|H_!uudzFogWd^zC}>Kap1^QOBuBEP{lrtf_V@o!he#SbS$LZ^h1^h5tuxpw zFeyQQ+s(80n?E}g_-HZohMzutwPPP&K~kg5gLCYuCmt{aJTwYdIm1_3#P^@)#XC+Z zWzUNyj(T$hJ~mua*z3K;NkCWdZ`Z@9HTM*kTi4pwl`Re05@{T?NP9wz@sq3>ilvU5 zoL^l%;KIt$>)DwEpeA_-ouHz z?}S;J?+k41)%kgP{c=u*6z8YL=e^7r7I11muz7xHcDwqSME*jR&o4aKt3vG<&e}5^;L;1< z_3?;gcL>7+rl9wy%-j+_uF-$b_xa3|twm{9*b6*LJIXSUr8uQ)m5OcP`2?EDLvd9sB;* zv=?#T#4Kyyw)<~slTTru#J+wp`eWCnvuZzTtVQq zyMQ+b!_p1qUphENEPG9-3-lH6y*6*U%ffKE!dr9(+vOMhNe39uv~XVj!L~1e-AAG2 zpT*?uj1yQtGJpLaz*m;QzHb7TR|40b79KW7o~H`kWf#2PU*Kjqz{m8lkFBte;RDB) z1H4N=u)Q)6IIO_U@PPT1!=(Eh3=#s3Op5&XBmC4oCTB!Sn@QH&U*HspENWT6@+N|3 z4FkjN2Mv!t^uC!;|FB>R+d*!oMvk`&xC4JqWm?$%XhSi}M~-73eC7o--oN4Xu3!e! zMLw3q#>|;Bn>S9&xWTzQp`K|W%OVbjT^lAc1@ceJoWQbh7Ry8SB? z;9_{t@FIZA$XsBl1K(y7f!6;!>K_G6j|k_Ih@6ohP!wJ{A@2g`oC(~liL5st@XeaQ z?w!FlH-P=o2ewTgxYsY3bH;K(@xwW59qL_gdLL{kUHO8269+?II=kxg`pujSha&~b zCQQG_$?&9L+UuWenHzWx1+ahMV3=mnYR18k7a*|eWE0D;MTLRQ9D)^d5AfzMn6bKm zbM*<{jth%tIPfT5?3=^T&i0aX$%6$f4}B*`*2`E4d@ z7Zw@ZT3VpEn9H#Dy~B*E9}|`aaQQ5s+WNiZ*@F@vE(Uk2`H}`R3y#k{U?MPkJ9lHG z!2AGymd2$_jB~YLEN#gWOQ;gai{uJ=HJ#yq!1U6coF5hZE^b*^(6!{P`SP2Vvkx3$ z-^Rd@dy;#<1Gkr@fNP{c!>>6t7EO9lE7r^sZMPCQcf3?-<&@O{{NFrguxkpG2Jjtu z;45x5`;EYImPFPWv&z|au4G!smbam$;5pZ)296^OW-tiMUhXBZ>ei|or$n!6)rURs zT~pBHmpPrak;6K3p|sSRX@^SAcV+ZPe4oRAd;6N#!rvJfWQG$c z?g$mKF!XB*OikGL>U0eQ$J`4uo9}h+_*2F6+Pj|pU_0x=8a{`XUD5m5A080nIm8-s z=yj>ogk$SJZQob;{6OTbLmj7EPO7ial38K=OW@G-{Y*0Td(#iu@nlU=6DXhAq7x%v z?{Mg6x4@+Z6|Z+6@ylR)!rozTb2NBij-!r%0{3bI8NtTwN1}Cj{dFc6Y8*SRy&%Qs zXhx49yUeWQ1#Cw;1cVeAUuiRNTs$n+c*O8ey=l+!%sa=Y7ao{5p`K5x-K9dH@J|D5bRURyKg%3ZR?3{-^y<{#w24diNc&E#Q~0p=+lABH-^ht=;A7gzcO>S_p*iax z8}Kn0@J;x3de=t22L)$pSD!gq!(jjH%pS$FY=#U!W}P|7!*IRl>@Gp(M=|HB4H@p_ zoO`wB+?zY+-u*fELB}nqL6g(*{KuN}Zvxd>11`h55dOpq z|My%_oyZ!#L77MPqLA%Hk=TpTi0sPH!F;(nVDCPPcvhpNnq zI!qsxI4APFbiAZ`hf(0aBis1|!Po~nybCWe2(U9f)G99)FcaeRQ@Xre<}#0=ZTg3c z*0}=HrU?WmUHPG<*L8t4toCXcFGKkwfovs#lL`X8#sVC7uP_|AD3EwQ=~NNz|3VRoH=*>qe%k1kA=1NvgR&KW}6_um?DrN zDAPE1ZFaA4M(lO=i>!wX!x%m=@Lf!v*n3{3RG{qbW#&Sbyk-X03FnGG-K_04RyMpO z{!mq9kvQ{5rXB+U%{Bqav$xi~x+QJMu9SG4#gKJ|(5+o(Z{K)zTZ-`x@4-vcY6Ui# z+Mc+(>r}1a%|myX8C6&53V56qDEps#q5Z<$%Xhao$1<=AFfcj@Ubhw4P%CgORv=DE z=6x;8$gSM=JcXd%b zOd1S=Onw5ru>wDt8R9NqUafnLY2lsEkJOnSs`bwmNXvcQt*-99fraNo@}sW;$NpYr zb-b0OCm`S}kb6OFx2}MJpTNdI52c-{oFs zWqBZQHcsGupMZ&i2Dczv?n71HV8)USH@Fr)V!rs|$GP&|vhUbFG6j6lZF%>ByYM~V z!4LfBciGMpkh%Zy$n|&Jg={}BUlslMkwfs4lKoMwd+&Ai8xH6)Q!(_$%FWmPRdG-qyO}IE;@3o-gE!IFb zq4fd*@?Xy{f5@%)gg5YI!v955{0!c6-$u+AIK<1adfz*?jc?QAzn9g2ubBV6YXA3| z``_#Se{Ycg(PaOlCH_ZS{g00MKf3n+=(+!+@Bfbp@;@ip|D57~pj|;tIPRy3rfB$i z4%_uVdsc8<+rYe)@7LcQZH=D@8*(;F5&rl@rkip?P&&EGT_J{6UFW_##$k6bRX`|Y)|4Qly z)~dYK71*sOkXy+5rB|TI&eo*i5?kY+%l5g246J$vGOTfiMM}mqn$=?!KFY@{td0|4 zFl0U8(8O>^#3e#Nh(U@|)~-b&@R3WGsBYYm8G(=8`ebeESR{jrW9ByF&a2_@h}U;GgJsoWI3cO_R+v5Lhw>=qcNM6BuDQv%xk!Ath3rM zNA|>`2Z9Ve3_KM91zv}n>y$}r$(|VT zhTe%?Y)%deA2+xrO!b}bHaF^P*0r^<``h*!X8w2D#W(q#r*|6<_g2pOBC(f}3@z<@ z8Dn-vSbZycc6P3PyIkzAl9R`Do#w8PX}CLKdh34Hf)zZapPrtb?>;~7@2{_-I){o* zusxDInYPkgI#akCVv$N z4j~?f$6O2yF7MQ=1e}EZT?}1C!&3^E-J3MgqpQ7O(F^t0R!qzdyz*QO47?mtYh4xF zRW^Aj_sbNm=-edX;UuFrOLuK|SwqG`*~33Ltr@Ch8WdIbvl#mr9#{FiRhpftNnxdx zmGPo|a+`z{e;iPL=kVmz5o3Sb?@u=SPg~${!j@r0!-{Ur|Ce-Dbhn(#*?g=;>%!s% zrVJfRoSLL`J*@4`pKb~Ew{N}Bsc529vOv)IlJiVWAt>B&LX{epj=|)aie-+CrumcSU9{U%D+Sd;L+f=-lm3w?*ggXEl#0 zJg&Murue+8d2H$R)a|k5_gl^5DxWXi9#{STsCj(t_ov(A>;JP_Bs8+C?MP_mce6-@ zT*D>bW|7nhzlN*V{MnA=etR~{l!@+YJ5wh6yIH1AjSTvfh5 z^~dY3J>ia;r=ZUEzN6*6>><79Z_c~_zxB@k(A`D5F1Op)MP1j|2o+;+)p+wwxk>3u z*N5%%{;*gaFt~VLDMwkJQFMnxq~rxf4+~Ky!A;D&*EkAZyKwlu#16;*d_pTj_#*Es zvME_FRAH%SVLao&blp*Gn}Msm&xv0>S9koGDWGWWwSc>H$6=O(0!oFFC+4UKZ4>4@ z;>0Q8!Oqd-EN6DH^UBAC&K<&nidOuJu2%vbr&tK+1ibBxXIY%Rh@&Bp^L^o_%eNf3 zF1EJ_2r6otbj&(r;cnG+QPE!dgrbyzK)MY})y~Ze^Vy6Vt;8-(SfLo_SkNjUv@gNL z{b7ugMX{E2PnJSl05^{w(+cr5A12Iac^cZb=wx4s=9J|wOPib~dxdSgG!W%pS`X-%@ zT(;;$DxcuVjtdMm!jgh{5=skA?Od7`R5XeUe&RW6vxM9DO@`m*QnetfCH<@mg`DQ4 zh`(bARjOw>z;!cXLPwC}GQNwA3ltc;&PZ^JHF+gFshOW|3h`SWKR3)ddYL1G!$I3w zk4|t4yb9`MX<8wh>G4@%Q^0z&mx|E|jyK+MhV85Cnj`6`Fi^cJ|v%uEy4vW+RS*ZgIQVCuRPu?t< z+^Rb-#~@mIj^Y*}#q0{DPm>QYC2SVB*_5tWbh{AH2O>f*#rl2B_nX~lu za@GI_6|+W;eECn&?Fy^5D=y5f$eqCRJ*R}P(Za!L*$lCJTc(>|Zq=VB)HuPG<sGrk48T_+bz~yhaQj3$e+lPWF zDNnX-WngGqz`?-QShAo@=%z+aGveAqgC&ttp5^(~T( z8=N6E_p)LsmlJ4U zw7IDmx`v}Bu8l#N;lLS_o)c46+oanb{CNE5RiF1M42(iOU8{vx@)pVoOn)!3B+yQ- zr+us0A9}u2nb*u=vddPZ<4&i-#bsr?4yNp7nDu16!p$OH%};ry z*KbFA&Reke>)!mj@4r=Y1RnDJk9cZdFMcOM-R*?ji`;^?@7d*=c@;-g?FzfX?>rJe zUUAHHUtwSQoyYR*l_y;7iY86J^F-af@>J-)qG{XjJk@Xi$xymM?a{G2&nlWKA~G6Y zDB8V$X7AqOEpF-1B>)__Uv|s&HKD(Y`Br*@0=UZg*d~A7WrgnBY_+e&ldC zdv)_BK8BXtyw?lU4%W&iHE(iv;hK|a?z-W?m-Yz<7bPD5?QvzD;4C4RbsQVtIGmdB z**L$YL||jdJ<#xHc8le zr+vQ*L*jIey4p;0DOJaF0-mwFJA0YsIG!Ko5PLE4hp|J~24ks;J%Weql$AQRd3PMn zHeH~_!CI}?Q_#qK=153v z^r{qc?&es$&~V!>Q=>hODiNzzI&N>-a3GZVKw|`l)&j=j%c8bD980A;%pUM*eL2j` z(&TtY|J1^cHAzQ03S2s0Fg<&G*vsUQq>F8k%h9z4M?+Fv*G3!-YdN~A;%LN@qfuL2 zKRI+qUpX54B~d%QVOZ zD!H%b>RjTHJ*Q*+Z;pG(oqC!Fte}|zjt!X5;>@`$Dx0L#?#dv0~{F?=RXpN_1p+Z`4!ldF3s|GM7=v!=^@Lq40Bh^;C~WQ?CTS!P3hMPkOY^*x#NJ(3H{8 zTI039p~LZQhXixO-AWVX*h_mIBD=K*)f^JXRYTs>CT%{91aV2 z`%j(8^rwSGVanOvvwufio$+B+gsP}s5NCi!<1;0Wt49vUr)q6xW=PcKSSG`9$;4kG z`C@y8Rzm2tshSN;H@3D|T<&ZL`&4}(b1O$!=;^Ku=g7SVIjjsXZX3KPROn`CEoEsC zatJlM#q4t=yoo{KKf{K3+H(#R`d;>N<#_DXVp0^^E#Rrbai-jNW<~AhPK{9W-5krG zT%Y_ySx@)!N(o*TjV8mt8~^;#>AD)pc=kr(SBFWe3uJgMcQ@SVbT}k4(YeRtW=F%# z9*=8%4rVV|8cua?pYFraUE0AHb3ldl*0zJk=k<0>3=L_C5H6SHShJMFX(8k4o6euL zI~a61Q$C0E%!ue?xY0G^=*%h(jTx8M>CSAs;dF_CVWDW}&aHl39(yu=Ur6rmFw}Ag zUUa3a;P$6GDo!e!4txym)!40&;b2(8q5m~{mZfu(hx0B5yP#KQ%L<(OG;T=;2#Kh6 zo-E}kHlA;Nmg943%v zCC7rc3l}cjkZt>VZL7`FV?bZK`itRftGisdvBGYkm zLzGD&N6gEqi?+ti@SJ?EwL|vAp7bA47kBaHT66xZ?eMBp$o$H&Gj*%1&fbox``#wW zw3w)ht%xh`z1+2efvcfKDWvPf+52KqJ30Ddm6dyY1Fo- z(Z`;~TzeY(>}lM$r}1ph62zV*sy$0GdzS3>EG6t&YTC23vS;aS&oZVx%Ut#>YumHz zW6yG~J0n?M3&o z7d_Wr^gesh_w7YL+sg@JFDI(KoMiTLvfIlkVK1kqy_{C|a(dg#8Pi_QT=sI-wwJSy zy_|FH<=kg4=Y4xQpY7EGu~!S#UM(_vwb<>|lCW1x(_Sqrd$qjn)rx7aRxW$BYTK*T z$6l?u_G<03SL?pLTF>@+gV^hhYOgn$z25BhdP~^rt!b~fmA&5H_Ik&(*E^TJ-nH%Z z?qjd_TzkFu+3S7ZUhijnb3p9PLA5uB%-$Sk+quW}&C#?s-rt%U7#I|PvaoV7Ffiya zFl=CmU_o8e`6jmf24q?1nKNh1BX5~U-hKc6y-DO8Q| z$m?JK|Nr>$qsFD@IYbe*F9Y`0?XAckXQ1u;Kjq^Z)<<|McmT zee|&#H*Tz0vEs{@FVCJmD=aMJq-T(xS| z?%lgLZQ6A0+BLK2TkF=X`||Imd|$K=X-m5r%#{$^XD&FS=s;p z{!N%LVb7jDe0+TI@$p~3epOUdG%_->h`N%Rn%dCN5D+o<*x5%lH8t=4|Ns2wzg5I7 zTU%R)h@+v=b>F{#KX&ZczJ2>09UWU+Tg@XL7{uK6iaBfXarZ(e_JaBxUZPv5a)hi=5xq@<+9ix>Cw^xS*)-`Cf7;_`nJCr@b8gbSrw7jew@JS56EiKkp{{~9O%oW1hH^Vk0agZgqCU$;)&RoA(8-QK$;UH_9Ct`J_+`B7;+oW8SEDZS<`uaeZt``S?{n_7dK^GUKM+K+uG=D>a1lMoT_@^p0@tCWIMuDrtjle zD8a(>V9lwW`NG<9XLf9Sd|Yq7iHc6ad*{Pay7!m72`KPBBWSAs<;=tqSD6XHtK-h@ z+M2y?5&JAPj#-OV9_mjv-($OR*3p|hzl-`bB!0L&UO!no{@k9OpL-lcv?kdWS)9KW z+3sm_QQ)VmOvL=||MLF(_WboaU$gOVY)0r8|R;CpPJ~-m$nrN2#bXLi=%;$4sJR=3C zctr+Xoa16CdAVBQ=uYK+j;9+r=JlApda-!IK9-CnQ^K-dF72;V5^XN#?0UI;L7UdA z73N2;s;*qIY}Kn(Yqq_5wR*#`|5YpJZMv5AdhL#9s~~GS*B@ZhezW07*p{S?C)8HI z*~B?9Q)u%AH|@7uu7qX3-FibPG-cbJve$37KWNi_x8n(TP3N-J?{>Y}_WIrK5686M z@A+~q`~BV@&sM+R_vhQ|_xl;xbv_(m5zqN>kVAdVheJH(Z$2CraM$^GL?k>1w5D^- z$73?(Z$2JZXxI64LS=f+r;{4X*L*sqv;EDd(+066L+>P(%9rp9M%<}PDly7;;Inu>d~09(p*U$Yx3 zkC++EGNNU|?Ot*`DY;#0rg%ZHB-rQcoyy1mJIn72CU0iG-*EkB`9nVLc@q>mvMVbd zb8Giam^s1wN5xYP?>gmY&T;1|56+T4V)1nT{pXc0ncDLN#CsOUJ$kwB|LL+feV6kL z9&TgitbX_B(Yf87yZ_Hy|Ncs|l#x<8K(`R_0Oe4k(M>*QDKBmVt+J?$^k z3>gL?foNu%glwJ_2eMQr1TB%4WR|vA%ii>aL1f7(7Gn-wZa+3fzK9c-K3ul%%bn1C z`qP8@RZWh&Zn*dh_T1nMoS`Es#KOXMa^iB9M>8c>rMAz0+|BYoGeS=~ti8iyrlL@L zs>_lo2JHrxVNa**IFewxQNh7wa{49@L#?on;o&aaeC(H;_D?z29sed&V&!7x)&fDb zWECZ;%R5$^=Dp}N{20h#JXt_qEvK*K%v4$L#ez0z8X9#yk_ya~s~wFtX?NEwStGM@ z(k>G=uAnIwPbz78Mg$sZESFlCdP>5TAtgv5KSfgA`sFJBM=BH9XEHMI3Ai^-Xqd9P znnSNM$)j=Yq^WC)p1L$NxkuP(D;=BTIXQ&$Oy~Y%11xSF?QSBhB;kE^MARVVAmH@uL6dYmHXT z|F?$IfjP^fX;JC|woqXw;a8JdjY_=vYBju+v@R-kZeEnIP{XaUMxLtaOP6P2TvJbZF=>`+x;!&u$~s{Zc4*H^Z?^@PBRX}Z9C)85Q_ z4F3;=ZBq!;%~QO}%kX8J!dHQgyjY=_?iFDyJhJcd-d{N+y5@kwIa&4K+5FN2p)#3+O(7Ew6*C^#`k`-n;Eob^N2ZJ1 zI~7%!6>c^=>=T^$<6Jn?vc0-?N2~8!Pfb!#y1-H~v#@Xd%`1{jGvAoFC^VV+l<~^U zb7M0Sh~l4Zq1emdpuVDP0?z`6gFy~iweHSg zzo=v8eYi>?%fMwJ|JxNV{70CW8;?0Gao8f5arlxlhjV?u;e=@JC7cKJI?Sg8_QdnJ z$S`gE#<4H0*MYl5R_H^U!?_0nrVKOYwmmbQb)=eCaLv#BH=-OG5xfkB3=8(hZ!VwC zC}7Uez%0YMal6B@&fKP&=A-Ao$3k@b%0ffk72_u z!9yQ@I7s<%RZ1UOCG$Uij^iA&K0lE?3cUBX9x3k;Fy5fN`?qKZ58tB93Dq|1ZiKZt zJ}?ld62B|KAbw)r{{tP9_g6kh+|ai7Va>Uc^ETd(&Nf6b7PL0HlqxuhoiN;0$f`DH z*CnQfQOX>?6Z(>WD131{besDUN1^(WGhdcjS+1@7s=ajfy?luia&?V&8)Xt%W|>(w zGG6G&j7gSK6+dBdPmU`qrCEXB-BPq9nkTbjw@B3lMxCO@)TU2+-#aB0L^Jn3n=7xv zQ^&v{JYiN+x^bLBM8}>R8u>pPCmep1W^Tr?#&$yTksS&VZjNj_E`IG;EO(LPV!OjH z-I83MBP$qYxC^gn3~B9H^hB9q+kfL2#R;M@cAuCnnS*lqGnyvY|8#x8#&9C`{AK(9 z?vGdx&tm+rwQ07M$maw6+=4~yA8Q!|>KF{_SOberHN>zTtYiIH#}JVG_*u>O?Rl(* zkt`bvnFHe)E^zUFXRdeVX0Z@(Pix><(ZJcr_C!60d3(V%a{(a_fiLRC;wx17)#Bb4 zG%yS1GbQp^Gce5A#^y9V)_p;yibpw9W78w|I@Z9Z+1t|D1)G@^8$~SY#VVR3CN;BP ztohd_&?ug1V#Q|1G%IcWk_2O1d?T8kypqE@J$e~`xV zu=RI>fRBOS{|hPT_ zS8bspTOJ~i9vAP-AIiY6C4i^CtfA&{Rw!!(0}Ja#u16UHN)Aa(hP;j2 zS(!H$`nYntmIM48)u|e1Cy)4 z6yu*0m9HhSe&p)*oEp6>WA4+`^qUiSGpmX$l{RiSo8UHuLvVt`&lxNmXDEkFHv5@Y zKb4V>gQ2Bu;w;Xovpi=;n@yEdoiw*oZu94foCgybwlQ!%n9Wj{x9aCqf3}2mGut+L z3hFas&C2o=kZTjDS;#oGp{ySPCd{Et31?%P+O?SKuV|NItHO ztO5rFq8S#m1S~e=VzijG*i>pUQ{rN~ti{ZRi6KFt`$B1Z>{M2wPJ$Q z%1Kr$r$nusRweMUaOJEh(T9e@=Pn6s+pu!cD$!PhRm-9T&Ks*O-?d7{QA6P%`x>d$ zOcz&fidy~Kk!hRN%Gm~@iyZ`*C#*gowdRo3nj^E+Rz|Hk5hbwSN~mqpnscj!YCf&G zWVQC(DupXmYj4b2du!L)JGa)}`?c0NXjL~8!!@pT&#KnFn6>WJu61v2t$X)t-3O`l zpRCq@iCX`yYWwoQ9|L4~Ff4|lJgMjo# zp=g7JSptuD3A8r|$Sz=EXjsi2xK5aR>Dz_EqSBkxsyFR_%uqc`ct*pf_G1hj4_ApA zZenrVEc!o@N#XS-tKFMrzOZy0+I;`lN{7?gH33^TcnP>$Z}Hl_Wp2qDpWj;oq_+mW zHoVBi;AFiuV)j<9kga~Jx5oY6njpO`$$DE#^tQC>Z5gw-W$oUUb9-Cf?`;Lr+l#EX zmqc$btKMEQdwbRH?KQWz*Ztn!FnevTl7Oo8j^u5t+h*_R+P$Oaw2b}j9XqaWouKXM zIa_e%Edk5f0v+6fq1HRsxG=MS+`+B5Su}75!-bvme*2o;7S5Zn>yq@9Fjd#_OI-bvYe?)-mk`(U=f$>==-je8&d_E=^uuwu6`&+UCLqir6q7I?Z^ zXzgr)^V0i&1#?`vE&O-&e*UZbUvM7?HQCW(z27Bp6`Riio;wHl{u~gHIVfavP$cG{ zSj|C+IR~Zo9F)0pQ0~t`1(`!iHiuMV4yn}~5;Jtt*mFpSNAmXVL+^rD=?3mMh&gOl zbJ$|eVXHmsHf=e4|I2>6KdugQgg0+E;P}Tx?)G8#Jx6@*968{1*iYtYV9t@Cn4@7j zBKkE)e=+Zm@^RRD`>2S?fdrdlDQ5)F?h-VLId<>ze#ZsJc&F^olQ~{wbG#(xcv;Qy ziaE!t_8hOdbG+`)@dlX_O*SW5VotQxoamTyqU-;j6FoI+zu!JFq2>^W%*iQx4o{9b zSz>&Id*V^)gC}Ra(GOW8I?HDrpWvzaZ* MK3cRRX%uh`5u?We@@*L+N(ct=ej++ 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 z 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
d;M+8z-RFstwB*)D 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

wMVD~_&$0rZGaZb_5_rrE7-c@RD>!stuV7dC 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

62YnfOoE4H89NdJJF3#Xg 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 z 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

i8jEnn zF1RRa6;h}#+0ew$mS(x_$=mPG>$kVxTykRS0o4g?sx2i9GZ-1Rgics_H(TjR(Nu>Z z1)HP1EcNp*$Nx9kaq$05fwSqtj+1V>95P{;ak^Q?C6TK!*fHZ`Z=QH!I78A`C(&yc z+E#cTxTO+g5a`p=rm*rFZ>xpNgFPSGWh!qmoN#ebGYd54I3dr||H4HpY@#{G2KS3x z&-NV>UBdi$bCSf-6*3xmg*^{0w%eVnaMoCNu{VE8pY66446GtLKK{+ga$hTsnsKGD z)U!O{_-5hZbd8Pilme?Um!~Yd1p@;=LxYjn%Dv1A2P7^FoM17roS;{dIO$|zBR9hZ zW{Vo5YQGKbDvSr(8#xY4U2n3q$V<}uhULQvES0HxtPZCiPna})!{#L{Q7gT}|826^ zXR_>Zlci6RTCv56lC-ekF@$ep&7j_cNd=<{=lC<}pi_O93-#L>QEK-7L#F18Re&ELr8#3NpeZ2ha%iQ?1xAKb4D6u-P73mO z9ZXp#wV9MWWM-b(z+lsGHDFrk6!{+wcAKpj#S5k`3ctYO8eQ31Dt3fx|WU6L0A z7F}f(Hq8`!;n2>XBh0W|fJ33FG5px0tBe23?sale^$zNfb7ZKH^@!Dcb!vBA17Ev9 z2lEesp1d|8hIrp*ZWZtF+GPjVJry~@wrPW3;5jh{;U5kHb_-5!o3wc{!-vcORw1wY zEGGu(0^OL;udc4IGhL&{kP*GN>U!gXP=&}9I%)P@cbO%>u3)!z&|)m$mK8`;co4y+ zw;`aZiRr*9xeHGUx8J(D-YjIYgKuu+&R5~r?}bf?;a#n!R()3|rew*%h&6HFwHmHO znNLw^J?^mU!hQ1@NeYu=*Ltp(isT6n+c{HqRmA&OjpxH8)-c>?@VA|CZQ?7Fql;>C z%>!*N-da}7%yvaFZ+3Yd>Jc*E;yJPGB6k>GRP=hbnM9N<9>9pZIS5O^Q;c3)~n8y zYK0$Aty59#`EZrDz+$POu1WvSTdb1vr)^(Yl4^fgtHHN!!P>N?rVMv(ojtW~%Q9KM zO%A&Rx;0+UyteR6mVcpltglbQ#bCd5^VrD9+k76Uqur+4`3P|8Ff@q#+@QrErzoH# zaz(P2fuXOxC$?WqYE84OhxgZ)!P}M{+$p1~=gz+SxlTjl{E6#0bpEp{J!o98=nT_K zN1aOv5!~Ffcg{V+eBf$iX5{8jMYW?A$)0aAf^810Dsd=uDVAng|4o=@udBz=g9eNS zYhotr2rMDl)re(Q#s zC_4+2Ekln3Q{NJ2EBVF?dCUs@ZaY>_T%CEtC!6WX*E_1m+V}VylrVB~vp39+ZD`@m zG3JiV_-XcW1202E%?@w9jWm5F!kKP+|8zgT9HMVh5tlHvrP8dG77xJ<{0e~b&N#TazI>&P~|`=7sV zoea;#8?o5I%dKO;&EzpAcr*W8rB> z4s6VM8|m~nLB@iCK~MFB9LwUDuR074b@MbNm^8~N>9)mAd~hUt?@wXCm{~?0+%qY=HtSeN-vmK2yuk2&|C1DJtbk4^BV_-f+g#%oLVHNS)fjwF}8qGxv4F=u^K1g?XUSUks;qbCpV;-@> zVTqbduxld+)Bee;+@@&7G_<-guy{CI3La<`>R?f-XfCK|O}@~mzq{E+qhp2E`aJEU z7gitswEOV?V#@~R0}Pu2I*ODG%~f<5e=uY+G?;5JD@8QM=D3C(Fl4yE=orDypuw<= zsiEmstGh~5wE-i;fhIcx)-nUvCXS=)v>E5JFhp`}77yuIA=Tkg(3Hf&AX>pJD{!K* z;7E9gSImu;P#cSgjP~`L_bG{VR4X*)b$c=-xHDKdEiLh25LkA(=or`TW~o1`a*r@A zRq+!3;K>lN*K^4!cOAw$28KO3Eeb4_+>hDS53t5qxG*@hH!8H2{b+A|(Q2d2p`@{y z-NB*Jf>n0I>CliPC5xLQ8rUbPY_9G&Vidt%uz=Aq;dG-z+wtgAGgUgSD(~;|nZ8DZ zqi6wRQ$nM|lIH)pT=vCBm<=r0V>H~{6*^WZv6rkqI=7~ z41Fz`4kiZnoC?;o4Q$g?nlfWr_+Kn5G1{#o!9Fd9jltpEsS@_q3f8JWT6}kWU$~g( z3bY7FaM(q7GBEfw%{bQlc~_$Wqi_X#Izz(=kt5rM7-W{XuTo+E%fgWIfc=_GN0vr2 zj{wWHJME1V*qKE+_7(dxRItXkFsmCd7MQRFMYy=XVfD!JXsl?EhBe$n!=0tU zO~RDnMRTJ{du@bPWrlteN87hI&F@7zKB{;n^IXzd>~Y&=+Lz1ho|oF1wHu6tJu^0} zvWZ|(cIe1aV2u|r|Ie_Yjkl*|k4Q(eax43U1L+2>D^1wVwzQpPVF-WG=)Qnmk(J#{ zgdi+Lk(9sK{t{<+xyXqvgAax0cIg{#I6j3CkN-us12Rq-(J2 zC^W@JoG{nj9Cw0!z4GPtLJX&wm@f;PS6Q^0GqjaF2vm+>ssFKwk7v74g0G@Lhe7fQ z4~+)989oA6E?cMi6%_|c^qy(l5jZ=^v#FxR`9<@bElv&`?K}bv_!lrZV+U~f!tw_{+Lc&Mq$!7r?$ z#V4V~)q-92g_To4d)D9c|J@6k3l6k;D744zV6I%sEYRZ;AK*Fh&4H8!Ev`4(roYdtqhuZu z?QqVo^y+G%hKRKWQlcCjG9B(6tVXO2Mzasw$}}#mI%=-Vkp3WWrPk(fhwTw3S_+-p zj2^U$?`^K%a5{7E+G(lIA~9E`zA%J!vE+xUh&t#LWZZI3X!*d+TBmVZUe#PAm&G&H zVdbYV0Sy7`CE@lvJs1qy3S~GF0^A!p7vmuy~T)WO1*>Jgi5TNKR}B+wDS(omAY zZoY%<`C`A43f8hC&Dsep6Jvb-Gu&`%Jkh?Hg~jOuYiY|}sSx!CRl#;CY%;POflRJV z89Urp9W=?r*%cS$dCgm1omuN@A;O{&QR^1Aqpi?6m|;Tr z`qRw02bk15JQQU)1RU=1uZXYB4QLc-6O6d(o?&g!(VC&;=p8cpuJnR!)=DUdq;c|!-LATF{u~XlLge?sjxUXtVqpp zZTfKCmi6H7Vq>o}57`6S16bH3M9r>8`M4J_D6ZN4EvBQOAW2=#oY%MGv+KTMm8Mc& z<7VSV!3Xit*;~vVT5C8q`y9|=aA5uaS*mf9>H2tv2KBl}Yp1fWy2_Za;CADW72&;6 zk-UyZciZZITu$U@4?5Mbj@j`vOT)=Ej`N(Il35vCPq{R9cr%Nct-RD&+7QNmZV5+T zoK19#WX|Kpi0h3R`c4m+eG^!0vsqItEL<-&GFAAQ&s+NKQq=O*m&D{mCAMkF{MN8q z;1tioz`%B0utCN51XKF#2Dur>@|PY{O!M259lNwh#X!SU&FoO%5vKo37>iktPug;^ zBztLIfLGyE?dw@>&U;uFUVUWso59_gRUn}?(k`tzy3IsvrN@r|O*fAI>fi*1@B_29 z#a6jBN^Jj;?PBD8$2}@0A>huw&kPO?%tBXB{uh_!nDM$vV@*m%@1_6AH?!U*$nXXn z`E+rH3~PACH5c7Y2@d`Y7H#WRH<*iZNNF@&?eSfhni%ai%{%EtL`6%d(Q&SQ0pS%5 zu{!O79kJhw&8|;spS#A5A>o;_G6$zZi~Ei3-)flSL)gDYbwpR3oaMu@&n2bB;JIxs z%MF(9P27*Ae$SDfmOHpDw%X1NP5RZP5|ojv4xIWL@h5 zGM+7AW-NHon2|Znr0t|hQ-sA%qncoEz6Xs0Ig-Ukp4GB2igbME31PT#c4An^{8+=V z9jrPhPHkg(+al3ge2uMaLrdf{{!?3DTAWm3_`u$1;QoIvb93Qrcd5PXdg~5q-`L-7 z)G9MAM)BXpKyT(-Ecf~!TdoRgmEcYPu_f=CZio0C)%9T^5}&t!l4?CE^SX(HX@+yu z^q|+rA3LA?o669^URc`lqtBmnLyKSQi}qXU$GZaDgI!o`*gkVz5q!aVt(Mj4C{tv_ zk%=mA$xn^oc?BHHn*ghgcjov3xWZYLMny>ReOP@SR75unq)>2E;JiUvQ{M1~ja zN37BhigBozHF176pTyF@)seN}_R>$ET$yZK+!OLE*WL_EaOd%h`yat`#%lN8tIACB zz7H!F9B+U0e#zYZ6=7Zi9FOcQ8l6Nte#&yJZGF*rV)dof26az%-}AjCccQtqYZZ(A z`;y|-9LL*2UH4q~{cxyi_m9up7~dTDo^ww@VYgj}XMA0Ao^v95Myp@xDeDtQ|L3eI zS>$jfFD3p3bKQ{iiYAj9GIK33+f{(q17 zt1o*_9_4dvTyeQwV!O_Vh{lY}T#d%OV%D$)&HYA9779#`KXO)Ttw>kkP}#v&p>c9e z3R`@{OQsWTuRbk_(Ae+JVe)rDZo>6RWNJNxAPb53$%G|tKUAOr~Mi0 z&WO-UKD%|7{R)@St7;VRWN2WuwBO;EtGVmb;qy${F(=+Cb!$&lF%B+m&QtJg?K{n1 zVCS*_d!s{eSkMn1@s3jch@ZT-6KA-)^00qib-`vw+kKl~ljFmk3Y!0yo!Ted;V#C( zDRJw6q0f!$+^pxWv{}Ch(PFJ~U)ZR(`~E_mHv7=V4@*m1mK}=hZ~4^Ru5YX_^1NAD zhdGNqsF7jUYX7!^VB1e`PF)o~sUpfzVbQAp_|+TH42A~w(=m(_KmFc#gq7`Rpt(bv z%GXxc49kCPH+L{~@CvIjFf3S{VCQ}Ql&jW@32_JQPJ1vagltf3kmKV{(|qxed9Jgx zyk~VY>&;_LPn|?=TwU=%n&AM$okHO!&N>VQd`ZQwnoGAeJ!eQ@Jivdzs%sj4d z6m1w*%t`nYd8{*-;okyL;Xpozjww5oIHR6zSmGkZs%nu@`i6Jnde+bbj0zg6_x4nM z|Md3tcl`$kn%Msf>*ZJ!^zUjHH_m(W!|=(8N$SDta()^;J2T6?_+1S{gKa8n=adV9 z%Xp?Os_hcr3E#(NRzdcw$rr5oEuKHjVEE$LV({(;s~;i_AnRWoNyM>)0gS;G8Qwg!C$nP%?1ZA;6!8I~9%tH@T^ zJQ5Jp7HSo86-x~|t7-VOT-Z_iDZ8TV#v>J8j{O%3eM?^VJ~|T@Zc)-+%bFT+#cKB+ zrYyCY4$qY<&In$=S5UHJf}4~)L(l{pR>?wN{{Jy0;tby>G>b1ix@60PCI+7ejcV;3 z3=PcZzaC&>kVw3;*i=$9#LZBMfx#oE$HhHZ&XUpKjFHO?H6PoT3;|5p3;sn;;Cs@$ zNta=RgyfO6D*|TTUUrp9;7alJHyx)dY8e`Q9W}*RI(F!bhB&EYrE)k}pSyZo?YL|@ z+p^<|-8M!iRcF^2{XZ4EOLLa?!%aK=9n%s0(IpQ7z$3(#8=J3Z+uH57;m~VRn#X%Q}AIvZifPfyT|Y!d3rRV{9wahb-5YumR?+YP~f}LEmqa*bDZT_HovmJ z_G7am!xsZ{o%v1HSGHD*MyAAxmncMDFkWTyDM@<@!>5kte38y?Wv7`;dL64EvLwqf znt6ej6T^;=9%`D>^?%$Hl=s_wK5PBo=F7$ZqSt1#Ui|pHk70|F*}0Mn6OUdMV2ho@ zUh%?Idu@Wl4qmy05|##re&@BE|9{8sSa3J!+U3B18>MxBC~VnX8nLLEHSq|$)YTPxI2;(HD+D(0VrKZf@;#TL z7Ki+c1)TnS{e|zmbh_=8akxp~f})&+n^%*YjGAh5hD9+W!-Oxh-0v*0P+)Opkxdc| zlTZ}1U~$lKv*_8x`QCpuql5k=2^NiSJ^U>{Jnt#AurRFfugbHT{OO*?amz~^`^xq# zPAn3ZN)u?}SNQ3W^G9qp{|7!A?Oi2}HJ1z~MB7bJs6Kp) zoxx&;FW(WxX;(rEKYUo=!}Wm6Oyqz=U*`$l2_GBzDyKRBIMAM!@wmI9J5eWT;>ll2 z*4iCoWY%c@u+3X+^32B?9UJRD$uP`NvgI>mI%l&;dw(s%#N$Vl9khjyHwbN6z-FuA zbTOpCSHVHjB>I~6!S*$K6cQE0wyscB)btUG+tM=oPKVOhNvzIpK?WCC4!agdI8B;1 zK|xnkRZo1$iTXqSi_KJf+$}jBrsaL9eZM->vv;P4irA4D1`F1TKF0pS04@gY0uKQj zfpeTD#gpfpX<`p~;VHArWRld=jvTHcu1cB5a~JKp{(oLmPT3K7-McWqr%b^!i z4S(O>w(8~Ld8S%A?^OA1p1#axIN`z>njJcKm)Y+9vMZg7oH{Gdu&6#@XfTdrT$+&K zq`%)aFSfn=0ju$jgM81F`5{O>`p*-e8N?W;-Y+`Q_I;d05#B_SI&FV=mV`FJA76d}fKo7d+4 z&v}%3`$pQlZO?zLDah}wTIydCwCyd&^V7>po50yyvN2z2%u?z0Wf*?|Ejn-|}4Xy3cbz?|E+b-||AU-j{{K zdtbQOTV0yG?#oi+y)XUht*$KAE8TNzks;fIBUd)B`?~h=?pN)B+zb*2zHXen_sxuN zyKY`y_igKT>9^gDEzS$heA{_>@4F*Ys}ueteBb+d@B0}mtJrruDOLT#`o7NI=8>@d zOnDYH(FutT%uLA@M}s%+`!vnnCGN?D=^`&u1$sDLG^Z)dP>I<0Wtn@8f{atuo`%}0 z#)k*oq8zHUO%@8XK0Nrcc>V9Y$!VXO7BcEq=>K^*{qA>$jJ+vG)`>l4PWyVK-tNof zcYh8W?AJG$VHba-jxEq-|L=S4yTteD|NA)kzfYKk{jbaOza3b;|L;5ZUxNRd{(ir_ z|KHU7=D(lU|Nr}W|Nnpg?HSk>Fvz*7n)I{sC@`rlVA4}yHhXZwp^^DktOEnCU2LyS zB5yM=Fq}Da=KudcZ{NIr_wJp2)LuqL#`o{v{|4<%yY3me=KH_@LD3Bz3x0q2@;|rw z#M>|bkDPw{`t|GQfB!QxGn+@=HjaGo^5x6ZXV05NUH|#-zj@>h!>GG2UcC7D@#Cpe zr=C84{_x>L78aI&|NmP?-nET7`s~>=i>PyEQJ~FhzkdC4i(Gd3@@4agn@&+{Eh4Xe z{`ddEg9jTnY`Asn*1C1;u3WkD^XVrgjLi{!{{3`XU)2H?Yc$8ZQF?RfBygf`RD(K|NmF5T2)wB zXcT&5`SRs<5y$@g`E&gEanI-#HqrOy&!2z$_U)dYo-cnv+sYan8(pF{zWnq5_wPSZ zQBmhFod5Rs|NZ;-og#L*Ms1rrckaG3|4k!r-Me@1=+UEFwruh7@$vNZ3=0c8c<|tt zFJG1{Sz=&d(B9r|Z*T7xGsQakYH@L~Q}oGaU;o>MA8?F56c7;b{?C6-PR_-P7k~Zp z|Ha4uN6$QHZf>rss$J;D7zhzjt5!x3I7JtGe2Fs`StCO|C1+AK6C%Sd(_^ium5{QY+ShGuW#b|?FV1Z z+wk8$;n0aI|Gg9Uy?y(B_3G6|kyqRMHhli}KP09#yx?BT)CVh8te80al&h<2e*1^= zu3Lezizlu67n*zQ$m!=<1(Tdp?xfW}DXw0=`^x{iy1E((jr?-w`hjmzD zzje?5c<|VZ7ytif6t6jU?n!m)wuH*-Cr@2Cc=F?kvuECact>y-+lh&bX7?#Lcgc7{ zcd^Bs+_V&V7n^pRLx$?|^Ya~=xn#Yzthl(?W3pE4sVysmdjjW$`6!g8tzHG)#ddvt z!eJvG#cgZ6<D+_jRetv#|bGO{y4Tdh4rCvV}J(H?%b;1mf)AM|HZ+m-N z%UHNZ){xKlK2!ActA7L5McmslSv&sRo}F$HtbzOQ%nS**=)u7_qwkU6Pf9U@&P~>W>OxcTv?M!Fc7dggfq|ek*Ubf;<*Uv}`L3LhLG0xCc zGoL&PVyaV}vgf>peo}_7+&t_&UTls8O&bF7&W)~dOd_Je-TITb)6@5G6=GA~5^=ieEX<4sUu2{C})v7hy zUcFkq;n;tz*K4+11Mgy6^?Kc&Z?9gjKftE_X2TJ&>^B=vsI7jp>5SRyH=8fGX}{fa zB`o{x)*ET7-);l#V%z?pZTBi+7R!wcPTX^>qj$a8_BwCZBfTYgd$v#VUf(X{@xjmH z`?W49xd|#a9QL!C8W=GA5UA1CX85phL(4Col=p|%tg7zTw0`1X*fK50X0@hVyUwTR z2nK`GCp4DFh)Kk*c=PFW)JC4qXH4`}i_cm-|8se#`E&K_^Q_oyHP7p|i!Z(4QG9E2 zaf#)OFPA6i<=(Fh2>-j{N?7{Zt*#OIZ@*sW66F1MBSl`N>}JN~+Ok_Y`FqQ57dZbd zyHmn`w%Ez5C*b=%t@Hn93kW!T(5*O8Ctt$CkixU>$Klq`TYfzLZpQcXNl$Rz&tsF~ z*IDi;zy8D|Xuh$?FVDsKc~vRJzg3(XCFi}fN?h4IMWV3EF{H|Kt@V`MzBx7}zh56{ z7X9tJUwoUj<4jrkKc5nDBUu3gvcbb(*p>hlfmXM2jgbzB(yj;8DX3%ebD^u&)B zha>BpAG)8v_)50cJ}CL>^8Ej~uW$Pa7w&DY|No!;Rm_B2><5^3sTTj1=3q46bf8V< ztUg=Mf?xp;D~?sHbOG3? zK^Bu)<@$Bt#bNpCI?$PPcIeKX9Wx=+8s6=JQcQW(-i(fRc&s@(@czs96T$Q>P>9viTzdNvEav2 zgMJpS0EvVdC;kK&G|xPf=A^;E@{^sR@8y}SSI?_YyhwHAOJE3)IWX%1&vJ|7p67~Y zeV!wCOVH~2Ofk(3pXZ+Wsb=&1*Hiayf1Gb_<|CuU_mIyK^2s>G9_OFuKq7|3r z;mCg~U`+vAJF6p~3p>-Co|+Z~hP5jk#co~bJJhn6p`zD;KS+6jA&Vu~N=8@CBGw62 zUzRGLWN}pZ#WCYniNQ6-hCdQTQ=6{5SmsdM-63Ffae-8*=Fcge-uFSv0Ug6Id ztXNm^)l+uMtn2%JeO=$cyC#9%`^F)uZyP#%*CdIbzH!Xz+r|mKYf{v`Z=QWvGKJMfdph56Tx-8ky---Pdufb_l54D<^={eq<+9}f%B!2m#w8+m7PG_Zjo%@v|@7tbbjc z(6?oYx^L#w4+}1NdOMUG3nfhG30K_h$}!!LSC9A0X9d$*ju>O1RE9ep$BorECVJ-T zYB!fFyV-GcW%?SLulTaZR8VjIX3V5OzcGbv&_mQvRda_y1js*&%%HLz^{X7hCk7M-u0E95X-nv9J2iV+H=5C*1u$ zO`09k$MWC)=aZ@@=Ob3{iT+%-^UQ47&ogh!T>iFi=edb@-_4!A_L&{~^+SvkJ}p?j z=7pR8u1nMBX)ZDT`$AIj^X0imuW9=KeN~pGeQo={v|8mOPlXRMUhi+6yOBTdWSY8I z`K5E;w(b7=wxECao#%evcisN`uHyXed*9D}-}n3P`v(3!57_;G9FmT6UF%V!T{b&w zBE#Pg6Z-c&xoY&K@k_Pw$(03&F(5s{nG3CgK8NT)N3}@OD3|gf6QjO(ePHZfls1Q$f8k1L-S8~ql87| ztLcq0HyY)BG%83mDOohBL^P>YG-=Fe(%R9abE7FCEJtsKrt{V+!-(cu)@HL88n>o5 zw=*@`RA^fNXxywrjg?+RUZhI;=SiqFi1tUFqQJ2c;a6NsMC zT6C#3?u634Vfo zE?C~tzI|Z>i;+mGg@E!`fkusvg%fMo|4(G#IU&$1E|f4su=_;EUB&vX&+8dB)Yunx z&RC(~m?5Ys(6y|h>&~_66&dnO>5gJ1n}{Hg<2n z(S2x!#|H)m{tpbSjXh67dj2>h{9|CKc)*$d!H=VXfkA-zZ$QGo01mwX0fP^{44qm`t=%^Tmt&p)cRlU=>MG3&-|>P zfnkF7g+7Lc2?Yx$y#67?Q>o9SnZUw1fu(SQwu1z}q`9DG!sitnyp?NDzL^ z&J@Va^pW?zg23$seO(6_^8>ke2naJZOcHBkl>Xm1*+r3oNkCn?GyX{s$AkhNh6S9d z1xEf145jHtunF8UF)0q#l_$UZwWeWH_U<~n`%3v^q zIgq8baynDujJi*g|7_)BSit4V%WWuy6*u;na>yfu2f%%QMv{os9pMz_skaOs0#TE}8&{J z@PJ8;lcDkf`;`TpehQon4Q##+3pf_e<8EY>C}46enCh@gU~}Yr@rBdkBL!*Zlga6nfVkys=EfygX3pTgxbWi3#U2K8MP~^J zXDwr9oGU+JQP!qKUtJj%wD(-QFz;)y97GBCcHh-XQw4FX#(FAho#JhOPLNXz0}DvwQB{7;EYLJ%n}>e zoEVrDPOj>Znv`!PaBOG)&Z?En2Pa5o38)*e3Ue`d7_4FY$oQsXLfWns9#u;wcP;Je z;_6#9dBugkke72N{hIzdVt${Nz=oG<6;bi;zcCm#FrCm8D2^293Roe)#bE3yaEf8_ z&YfJhH?T7|a$j>0=x`ADq`+t7waTD@<*yeHlOPXM<23%n4NMccYr9x>&gAyGX~>|k zQB#tQDUgT3foG8d7f<*4{aON*6V@|q;4gT&U^N57?Fs9@1WfoiQ{Z>Uj4urvm<1Oz z{ZCx}ookaZC*#oo)};aS!aF&>C`?{7f!pl0K$0dutKn+q#z|(KOj-w)G8ZzP(BzWd z%|FSKHG+%bpuuDl>vc&?+rD4rS-gs)t4csla$Su8o3#P6m!`l%0Tz*)tjz*^pA8tj zZ?gWe6u76!DaFh%mxUqPTEKe4lw}Mn_%HHSdkdsrU|~?;4_Gjzd4lKU*^?L?JedM_ zrZ((k*s!?n0(?&y81jBEdfF*qrs=GC{k86I%|tzu#j zU=vdi;MqK--daGJo8d1P!=9V0#utpREw%rdHHZS0eJ)pnsf)S^(Kr}apZZO+q?pXy&+dh`ENE--zn;_7ZHLX@t zAYcP?gV#oe1nzkST#FS1ye;_{HZaIuHu5uIWD;bY<-j4BAh5LHfOhnbdTt}8jeEpa z2`t$#MdUZjES8<#mfR(QJDCb+GB9{DOqjypzqE3^=5MErg=kZX|Ge zOYTyWTr=a#L5bPS-aENhM;~O~$TiVhK;Xh0dZ%y8hyN)v&g9?!y? zEJqAD40@*B+HffKf?<#hpR0|)#NXRf7aV0+Fw=hmuigcAb{~N=4Tp=I_P?7dp>%-% zt%JZ}28P~f&ftV;tp5Y&Gx-R3Tk_0kVbPpDMURK!m4U#!hMBAfXFuU&SjsSqd%?^; z8x9`k`B^{LFbEvtX57RSc#@&uKxe^WCPRKpD*?3!hdK@{&YQiT;Q{CQ0|t*J4MGz( zuJaK%$i?7zV6m&^i9;9mE{GB+;$djk5jg+h5NqMFh5)viHUe1>SOgasu3}-hUa&X! z&dwtnrfex#*A>8hU0dL|0MF#^!%MRFY&PJytYgTWc>LRr?K52VGC$=0T(g|rZ6?b` z2G2}xvzzR8rv;W@Fo-QM3du2IYGh|kHawHr#k7#4bHmXK76QDn0`}Yt7B!b%b1`&Il+atS z@%w?<-n>D`D_}fg#OBucd)+ySG5V1m+hEoHI=JFa&VNPGD}m z!*0vNaMWWDli_6b&s+;HT+O&?Rfu~#T92bYHOc&XYMbF&2r(d#b39pxcy6)n|2X1XHILVaA<^O^E=nHNpM;5i8 zEYF=dFYjRPd2(jou0za*SD6)$g~_tKyfwT0q{qDf36qvM2xu7WS)(Jcc-DEw;0Z@| z^B2_^WIsCoHk5(k0RIgIfqey+4o^5~kt3DSFs+l}uEpN|RXh3jyyTm7cFIEQ!;`sg z)py^S+Q9Yu#}S4FykZVqpJof3UGQLA)NSU4{Z0wfv=ew66pq(EU|$k@^qS_hNxQh4 zH=O-C;cQRtiCTr*PC1tuCiFg@D^S$6m%-t7V-)ML3C!zw51+IZ$j`mU{E_>V$5M|| z9y3a2Uegu0ardE|)<^Xhg3178N_D^>!Ne={uJwadItKrid^ z!rhCk&s`JN6X03RCX>T=uI4i9!8^Pfd{Z5m=)mtFI?`p7~z>8Om@oTqmG+ty@ zoL2gB5yJ)6=bQMx33xF#F7_+nJKpd#o$2`p*V{%63xl);wqIaeb8bFA1DnHBu>xwT&ZWjcUSuqmQw{&GgcZ-(Gzg7)3@+?lELsUP3hf- zr#o8Sp5)&6B*}7-(fQ*=Iq%s7dF{_GE!TX=a*=Z`14Bl>z>FnlSU+;HKjgW{^Fnve zwfnQLvMrooP;)PR|F^9F-xC-<$^H}gcEd<(&Nr5Y4;p6e@0~4h-hkPnUf{~SA1sQ; zw0hPt9el;q_=D+U@2A~giY2FpR6bN){ImA|_qH{QxUa3heXH-#z8%a9zxv!ZsJAva zn)iO0uRxN%Kw9KC=ENynF#;6|myXSu(7AI{@gJ_-J!`Mp?JTetIK#kSQ_m!7FTike z!hQw@=47s>|1JU%2EAssKY0YV&(s#UV<2#3KJ&8=ubCg7sb9yII$?_a*@Fumc4>cj z{>W3{Z44`e=CSEF*%=)98AKRZXEPpXZjW|k(BqoMxPiw(zD?WDK&PYip;eEpE&47t zoxm-iU2HzHOmpuYnHl`tZ=P-KKNhKw74Du5PJKmUY3$CS3@W;pPXu_V_J2)F2szlI zc(9E@B=OCqLiW}D)m=X;J(nao7Veff#-Olx@iNC368E$?`h^&_G6)qO)o4ka8P794 zNqeUEWu3|Ol3C0fngvwa>i&c|*UA{n~GLzp2^wdxUbgJeU1R!7B*M}qzT z-Tn0$4U{kJOaB!R`YUjnoa8QovfdWI2vdTObcTEmXhFzK-tPCQ_JbL|J zK8Ku+J8?E?wj~|**ndt!D$PtJMPreIsg%wMF@}=j6K-uk3|g0Hy6LQ4tRor3BHCtR za)y)PoMp2~+m#!M6Pms;J+Np?xR50hBXR1m)8}tbHmkq=#bOfR$ga92!1+HvtJk@v zgpOX1s|HF(&NQuZX!6!5o59e)mJ@wyan!V~G$jVNmWARPj1$@wYwVg1NwnR2y@LDh z8OOz(k_j45&pC!LZcw;;iSa=HL_d}VJWg&+8y5V`i{WXIaC-BCnZfG|xAKVvH(X^C zmmkd#E9Uary5J_m2Zsad)=EnkvvMnKR)}Yia0z7SQeG*fbXO-MdU?#-6D!p3u`H0= zZl}bi#L(wrlGyq`WJhAVe49m5r@G!sc7`9FmpOy?X=;eKJxPACImn3l0jKG_mmK$- z!aCn9j^g4nb>r|oD(=QmW;j`vVcSeWWroDLeGBV@-{mTb{4&}+x5-V9qw9*_LNVp$ z|Atb#7UZsZxm4L+MEk|f2??sL{5w8ryx39uO_M{w$tR*AEJRW&oNa-Bt@sj|SxgBs zJse!zPh)oNZ0A>(IJ_uN{S*iLVgoKC#>JUjTzUyf3?AYP-IA|1bUSk0mSiwhnV4c4 zsHrAv)8_4NTY5D-eQ)Uui=bqI-~~4Cc2r1doOt%Dr&wu6_<FzoJY@EKlhsd&z4T+RTq6^8K9B z{C}rr2&b0ECWZ@BSR42lgy-~bC@>ZXw0UjHYB_K7o<%#F-YD`LX&pPgLVV6^-6yrm z7iYTf2;^nbGtAY}_D~XAuFqhSsdA>m=_-Q&f6oRUhD8jWEnG^=43;cYcAmWWR2&nl zMn{sqV?c|M-L=-rC+idrHcWRvB;Hl}@Q|)viigD0O-gMZi-cJddsctjus|!o+3T}$ zm&>v%%{d7yycKgAHCH`zwO3%uusX8TGh>E#+_y{9_p_+ESp@a){bWi_v}sp&df2WY z+TzXQIMZEZp}N4{|0$Ch8W?Xf6mUrwHbjWoxW;Fx=oE;!NU%COYR>yHF}i9A*OHG6 z8@ZVHrqs4txl9O@-nz+i3xfjpiU1XcKE{TkDT@^xdbrmFY&hK%;UV}eIcndtn;va{ zUTTXy@phcVuu!doxlN8E!*E^WM7xN^!3kU%ZZ?f=U7uPxjg-Pr9CtPs&_77RSaU7lZ0=+1vB`u4^q z<)42#B*Ql_B|TJ|uX?H}?B3&c<14+2UxYeiZoTqg+*=we@~}b4|AGo5X9nvc#sjX; zwrsJR<5(?kDado?g&<#tX2*Z;k~JmIu1-`5F>@%L80r;+umK+v~Czg{PEe%}9*;XhUG_1R`WYMH(!-Kn%dc7SJR9m`h%5@vob_lRMVJxgV zuv2}d9#5CDgyfF2O^c&EV}FbLvN9f!a4WnYWwU@oNx)Ihp_x(0PeDOa@qEU(`maYW=4+a=4e*WEWz8t5(g@D zf0%N1OFAuX5?CZ|vg>%L+JzHpDLa&-L;tTSw^j02idFs>K$I~e_qu3+O)%@1Qel=OuI3uM@&G6&$kD+6Ic{wFkA|Z(> zc_yaTcVEX%dCK!=G;ByJz;qVcK!!{Hbds zAJjbhepuD+V|{d@Km&*KG2IP?ebEk&S6!OAuVk6|-IxCDRachUm97fE z`zri+)wQkrO4pU&eI3tUedDNI*{11t-=w=&-@3Z5Y}@v`Z}Z!$?>x0D-*x@&yYl1J z_rC5c-}n9Q`+D}82dwrLhs5uFXm_u9B)Y%inEAbr{p~eRRP8HIh2Q%${dmnY)BQg; z9&h?QpS|{lY0XaVj(cC0yVt%7-CuQW``z1X+iTyX=Fhu+{@%Ck$7>g4&2Ou|_x;{? z-GeO7dJ`HZzxnt5xO?5R*Ar@xRMXQjU!~8X{?F6(-%QTj|M&fP{lBmK>;HYf|NlSx0S1u+j4B71 zOb#%+9AF7Kz?yP^t>gfE%K?rl2RN4;c%R(DrLw1i0oT$D&;i5Xbs7H|7#QBXdGqew zyUect3=E91}6Y}go6b|pGG+Bou_Vbm@2$Xl$etVU7y%pz`Hx^(%)ix;a`uXc}G+0)bW z_wT=R=g!@@apV5|`&LosKmPe|7IkOt+_^`O9(9O3vSP&wZf@>?fPi`P=I!3S`_ZFE zpFVwh|Np<7oP2I>u0z!BS+i!PrKNRrbSzo2R<`SV-1Ze6!- z-LhrNY$Hz`J9f-A{ET_zy`!feeg6Od)~#D#{(%nkoiSs^`t|D{hN^dHC>Q%cxV1(fcP)p6njI<>0}CHsMFV z{{DaW)&IwjA1kY<{{HtrDJdx-A;HMV$k*35BsA0^Vl@-1_U+rZPo6y4-#CTxHA?f>&{{~H<_3JMDJ1CLEz`s=~_|5i~q9UL4sZ{GUqeK&T5i^fn`)?m{dCj&vzkdCiIB{ZMU!R7@4*R&P z(Yae*{r+zdafg9XaOtjpDvrw-S)F5wF6=q;KOlBeXjEN#$A1Ra@Q|d1y0)dR@rT94 zrRS}Bs;uMZm3pCP$^Yz%71`CN6RTd-&HBf{n`0b#dF|SD$Ig8gHJq?;(?4eUzTHPZ z-gxk@qU*-m-Jdrf{hytkZDwXRVfFvi@`J6tYdWS~+IR7P>+COf0n-DrP98n|Z1I{) zrF~yH)CT5_8o_RoEM|LK1dy968WCSK{F)PgxD&zyhs=KqcZx7|WoB8%=_y8g=E zHGR$YE0bpLJ$3rxhV5qvFU{Dv_;^2fX+}`W+DRJ0tI(Hb=!cy=x%shYlYKSn(u~W? z(GD1XeONZ`aF?w2wlz05XIx$t>uvfXP=q1iKXPx3MR}Kq< zGY8v*wd2n0*qFSiT)x{iCuq~t(=&{-@9o)O;BsC@dA04qom*aBUJ<-{oz|~K3bWS7 z>s8*Y+WPkPj^fvGzLHCByIpU@mcGkpIU@bu;nS(x@Am%K6taHrZ=nhA_cOF#d4J#^Th4}=@85+Pa52lj zF*tPP>hBLnQq*+j91%(Xv-Ie}#5Es}E2x{~pHP{ubK!*A@->F1w6?!7IIVa5kNz2> z>wBI^Fszs;eb(%Ij!Lt&_?yoc9)I%ra`B2(@0Uyazn%Va`LNdp{VO4tE8gU8l@K_} z${q6dYj^ncBloKKBLxmJWbhj}#TfVg{dzllS;GV_W)}fRE+-LI#XB|s|FcD87dt-L z=Jefm%XTMb4whRtMIRJ=3TpnYYgsyx`Dic;o2vo~S9|o8pAHji?S8&E+PN;^Df>*h zNrG-H3R`{h7W@5r6TXVUfs2P*cgmYB-~Ci1_(LCTe1D|)#BZnL_e4NBxiW26# z=P&%cBWmQpwROVuD@)24wtQ8o`|Q0SQXoTqs=DErBP$&vHQBBoMnhL}gKO|}w>&EkxT?st?9^W7@25^Ol&z;s|2HA$84B9=lmE}x{rWtgfp>)iyVr##sV@sSd{;P$XIi3-F7#D>S**aj(!<^B(xh2mmS~7NFdHpk(f8P5@hWAxb+FgvS+~9{vpBobul&^I z^127iObIK!8GwNvoc+1&%4T?&FjhoiPB~MXIF)7KXr9o)z!t? zbF)HQgD>*Pd|jR4yE^LnscXyHrmjl9>+34s$XH>vfKk}t5PQspMu90`)(La0;r{iK zk)LPVhFr+fjFvQqHHCkDBMl82%bCI$lpd^(_pG|!pcKY1KX(myX$ITYr4y&F;XL!I zX+Bfw2E7$)Y@9dT?EfFsz_je_+Pw19x68Rqw-&u+({A&Q35z%+{>;IhXNyD2ZLS6D z<(4uCE_vAFy5Yf^pGO+>d$MESeEYWh0k6JSJ@=hEKOQqWdaSRye7jBYiK6J82aMuw zAETz;`?@beRzq;Z#U_J_X7=J0tL>gEbji$65@QhCPyt?=A-47D*|REp+M5(x5;>eb z@&(OoSn_W;a!Uv_)_%NwvuV=;nZ%64W_=0QYO@?gJTq7g!&WD--~MsT;+T4+a?NZ` z?*_rc7EJsv8u;=`ocU`#HtD<(c+j7eAiK!G)n4vmQtdtq4x?p-ecR7G)qOwX`0AN1 zERv3o*%A`?Yz!LB+Ag#!lr;Z8>9ON|u{Fc_+mFH-w#-fMti9F9*U`Xj6VRe0By;{y z)q}YuVVME0jZYv#tth<6_Mu5!u|rq*&H)y|jtBepy*spa=7Cm;BMsbz-x!2u7%=i* zxW=3JpjG1MU;Lxh>P7~P!TCRKh1CZF4wM?KJ(KqM{Qff zaA!hyh{{5a?*<2ziW(W!5*k=9-B@Q{^RO=^AW`tjhEl^NioIzuizLr|Xf@xE*q0KM zB)0ekgZ?5#-eQ+#R?hRR+Sye{DjGnbpVdGH;wj%J;jh=Z?C;DWE8Q%;A^~M`Mq>$<7xG_-h^d`@Wpj zh&@;y`%P8iE?eP)x$i75?9z^z*urz0St{fJ1FO!&X0Z%qepikr&4&B!DmjlOCMhrp zI$dnCxzKd9D!iK8f|1*H&0p@P6-Sgh1ehxpED+6+aQZJ~aj{e7h#gP)@xvMg-WP5> zIw(C97&j|$>k6=}Dqu03z(4l`YhnTa`2wEV z2Y5G3V2M}YZZ6=II8gmAmFrajkJ<*#(+ON}xAHVMu*V2+RX(WEabsD1pmf!P#iL_1Men*>Ny{H#3Pa!zcMN{a35H}B^}1Kw}GcQA?*9| z`Vft(KiBK0f2^N&l|jjXYjHzT;sU;n4y@-kaC$?l_w-#`O{8!*yc7a_;fOV<> zciD!R7ZbR6PVjSNwEX|Vc<&pxcLWPd1Ctd4&)4U%p*y-<%UdHfB%?CoV?7uTO<;Cb zXq&WwZ{Gv%T?y=x7h)s?cpZPRKKj5>JcBv$0qfKaemVzOd?xV3e_&l^z|-%*dS-c3 zhyri+bgt%OOdbcA3>$dwZs2*{((HJF{jWiW`Ei!w4<()xxMn+qvy_JWENFS`(8UtK zy0?M9nIUQI(wa|g33fNI=B*K^-qFGC?8X{(fJtdN>+}G=ixph67qIS` z&iu-O-{wJYo&uBpH`X};oXrQAum7kC5#UXG!Sy78>Es5E1qGZoA2{3-*pL2S#-2NY zeQE*AZF5G&29~oMxGfpDXE!u{zQOR7gJn`Bh^SUf$MB&UbIETdy%NfpR@LCof@-JBCa!CxPfuQ1m^exE;R?%m>jGGu56sn_z_n0- zx#GXUOv4Gyoy$244QB3p#x{NC#95L4bAI~mIKbDEz_mn!(b$3GKmyO7O5WxPyl*cQ zhcJ}HbIxY_6}!oDcH6_L@(t+!nmM- z_rL*uX*Y(92@GdG@PFUH-|}I}M*;p{k@X@1q3l&lmrh;4^-7#ai)nKM@0<^P!R4GR zGgz*D;F)T`b69};cmi)N!=ke{tIucFt5z+#wsO&)GR{d0IL-wx1H1Q0JG&T zzgIUG$1h;FzZJ0H{|D}4A9$q0SY`w;q&jqE1u$?fV7w>H?sbaq@&w)m1+j11mo8Zq z5w&Y+&BE5HoY@yIa3)S*|7%d{EXl_IpmEZNj>;KajsnxCYb;WE#Z;ZSsIGGP*7mStym=e{RtHHG%Y4mn&qRu@SwFST4$!nNkI z<(h_*NjDU@H!Wa@xsac1&Ms`h@+E=kLRW=V)rvPWS9JgK*L#q?gJHqj58R(UIrsxu zgf_5p1~7kW;xZ1TA(F2f%nP}j`r!PFEz_;XEAr}D*5|`(Pskh z<%SfE3oLsbIQTv=GflA;R5AT3|HZ@^z|bJAe@k2cMs(M$ zZ07sk;ft;IncWF~n!PV0kbhZ2V&aFx63^mpPv9$)Xcw%G7Foc0VZmxowVGE3Jcm9U zE;`AYI-S{6f_Z1a()ww$=Q1=JKHyomfqS0=yY}@(D<>r7ZdkqS0Dt)jrfSKB&1USJ z>gBu&b2bRNAm=pMZbExH=KO?BTf_~i=;v*r zvKO)>0&*r@h<(787y626qub2955ZgRunHfTmB*0z`J3Ols|+Fw&X;W9_-x80=^8C2 z%Tz1Iv_p(3PhgV_Yk<=)?#m7wR~Kwr|Jg=o4|9QlWBmpe!7rRi7Y=oP*jw>mApLpG zWs|ArUdf2P&0$)7hgIal$qLsb)v|crTdWIK)TEb27PnoLSbO39k?;~T#@eu}tZ$>@ zthi4dUtBirqL}Sf4~@LX^vB_bF&;xd>2euy<^?x$p zSfO^-;_h|1rI)SmioSi*vH1e4p28KEw->^1GB}i;U(k^*rhDkzvn!!<)5~3>xni#- z$6lDzdnHkqsjMx%R+On-jY0T9)U3Py5lg4^dM!C~fs5twwF2GiC1)+~ZDwmx;O{tn zz3%R9ezx$&yW(*UH>$s0{PZRGA=_1^55WnU7u&wwS-SSZxuthb*{09(P4|$vC3oRY z{9VSg|NmU+WD8JiSljD0Ke*tmt`EZ|Uxq^69aakBEDg-Y3wWL@aOzChv2X5u9@ZNN z_lh3&W!*d>Qp(i-#N7p*W#MORZ(hjFc+qyGcv%L&Ub=7YMV`M?FG@1q>Afi%5Fzz$ zRx0nbMpmvJ4_34+;J+EI|N8Dd7KiI)wH#hi_s=f9Z?rF0z*--hMLwruATU}!AAb3A=fBAOuWJI<{N?^)$#-2x z-wxE}WUWyUPg`(y>wgA5z5_g!z3dVNQ#0gVp5_k8KKHEp;j^L@)rEQKop)c(`}cBz z+^a?JUa~HoqMXOm!oX7R$6)>8n#KqACLPB46WF#Iu(BRtKM`?DE>fW5#$9QVrn=|*`ocs6Yg529nc5kojd&5=m_Qt%oxAwigzK`)>17DW{ zf6E2#2U_|T8<>`IFuahvZyvzGw}7W9fOD4u->GwNztz3}G4K7aeeeI=d;jm>dj|Or zO!gmG;yOV@%|0uQpqs;w}lKK4n4E(bD z{Qn+&s7+)@Jt8sd07G>Gt5gApF*nP$wR;&F*iJDp^C)w4EMQa?V0HWd)%_rY*aW7C z0QL?BjytCh^)fISPhhiXV9H*=Y>>bh!t$+5UqmIrOp1Yh;sVAg2iS5xaD`4_$bP`i z=fE7vz+pUrDX#u|-+f_$1jgtFF3lK*Y4Hqv4D9U>ID#0MW>_&R7clnQ|FSG(3Tu!<`DS~CB)2_vJn0=sGev%bI|Qw3(T2~5fd*i-}9 zA`_Ss7C7(v|Hn{}Rf2{23O{qS0Hgl~_N)L7r~e}NFspRfn}|)RXN_1& z;0Fwczl&+9QMe^LbK1K&*a5?lL6WO^VFwKN$9{qzFf7Snads}`fZ-P%-k$T(4;be7 zdhOU;EC&qlJiP2Q<^jViuYZt>`-6JGaC%H?Lh+BUZ|@(U4?bY{?|*g!2S#?44Gzrw zE(VUQ;wc*(+2vadoH#)T40G!rF#sPh?96Y^V(231uCmcZ*x$v_RWv+hqpNs4=z!t$ zB^%wO^N$$1%a%Xc=q_K+V&tLNuCmEPx!=XeQ+0aECQtSGEk<6N(bhR$+Ur&HjdZp@ znY3NjXp#Q{XSPGD7aHt#F+O|xiS!8*)B7#Pdu~5kviaP}V>+3B*5989uQu*owaFj0 zG^6BmfU7v@fMNMolORv^rCWl$^^Z=m)ir*)CD`Ad)ifl~U3F_nu)nKmXlQuq*3j_y zR@1P^^rc(FqVtcMhR2pa-5MTW&uSKt*si)QBDvqyEHZU^>bA)A`K@MAnah`Mi^^Vq z)GRu8`_paF`TJSTV+xOpp6F>_reGdhdOdY}Z2A3G^LvtCr(^_IzPDX((D7xe#>Hl) zqvi>p1sEfgiv=G|S9D~#)wHmUwJl<|QQ{)=q;CCV5%-!3H<>5*ci;Z8xZOGK#p!;3 zH_NB-o@yL6Q{(sfG0jL{wli(^=~q9}=9WL3>0csjwIh9@p-Xbc;%x698B3?9?aEv} zzs)LZ<^Sc&c4e(zf6OX-?e=H8ve)ltv(DLgTy1yG=JRgWxm&NN?atkPzs)*t=ksN| z^LD>K_WO|Br)RtK_y1?JDLBZkzNg?Ye|e|x5%Ka<@yF!bZHi8+FW*yiTK~9B@mcft zU;NM6v)h(jbXVV7a^ZuCEqH0h*J(24wq-Zdm+vjRoqyc6{BHU4z2*1o+3hMGwyW=} zc--%9SNU{$`o7BN^V{vJUM^o=XEJTI`<;|G+n?{Ne!rjHzUE{6o_WhZaaz^?*)mz~ zL~7TaaQoYHER+5(X!V~}ui*HqU;f6=hx|Q{el6ENKXYl4WaC|iLRNNGvkNMj1qs(y zP29)v%d1-SNP;`xjD!ET{q1S~z9_+k<%i?e+z+ab%85sQOm~_hc}PL-4@bIEDthved#=E9_!d_>m;B ztvg)x$}V=tvm{F#wQw_ z`|meBl>eA^sO?DLgkz5qeLw9u?7WJrR9i7c`MRrnvrf>Y*PkA%n(jQwqdIBw(M3!A z8Gd*MP1|JL=E9*RYvjccacPQM^%L#6|o^rIx-~VgHT&zH&I2ZQbdcS9W>!eU@~Kqn3U}(=N|>?vieG zb*Eq1w##$hx1`%Vwe+vLc6lDN1Op#?f`8q&%k%%UWH_)|1vH6WS-@_pZuhk_pv~;c zLjKka7gejkuCCyPDk=%5ryy&u5Dw?&0+p{vOzvXjAhA;L;TAc zxXze0GWyACFpEuSHJsAO$Zl|;IMVud)1s^FSN7(XZS}rVv*`jyp@sva)W%kBmIOu~ z0|u380{1LhHm{z~dmwAOT_mf| z?Io+k_I;_B4J&!J~n|y%%-T#jkpS2U!mQOzP(O8o~ zBk-n`hBy4A0-Hu`KD1T2XfG zxYfU9>F2ZJIClJG_%GVR%%XUeH71L}W9u}2`2**U*S?$j__gm}udA1s?6#O~ z@5zu?zj63k@0yusxnqB9lU#MG^mDssL-S+31s4~#u3xc#Rusehnb$7XW~I;Xj^nry zdFDdx=jDO3pQ!!+dh(U=NG#Gi-t+`^H(sVnlppapm?lXpn18jv88hH;~xN6w{nXP<98_$2QKt{{e z-`JEl9Fh{+z@i=9m@{I@URc1pvc`H}&Rf@>7^ zsdzZDaxF~HeYcQF)Zk;J;(|8a2@6@mJsdNGWg^*P9QYzM7^P21GZ@U7!+4zc8`HUf z&lWclUafsru~GfbU6D9NM%EcjL7)GnanuMiML0NDi1N2VE;M_De0y&faBu>@KchmQ&jj>6{}UfZxgV6qKxWBQjDskwwr$oT-)yW$S)4mV27+&`4_x+r{P-N1P9dG?E3y#rjE zw!XRV_q)?gCnC?BIC36{R|7_i}o&G@Z&?+L(cR92c{H;Q0@i=#%&p^tvU21 zZm0<{Fxk!6dq#=X%%I_r_1c_WOb#d3obqBeI?yP5VvUA_iRlXF%f$@$vYEI$^jt4n zzqQ)-Ly|!vLZAJ{{{OEwTu5Tz(P0n}VCM5^{_}gkCwGJ3j{{OC41yjo$ga?F+|VHJ zU>g#_^k17nNyp~$rUqGo{SFHlFVEK1c(FZyS7ScMdX@%e#~F>Mx>&q2R&gxYe}+r{ z>L*6_56%CD7#P_jm^42eki5}kw7P*un;~@qQ_uukb_2a!sm2eJ7_EI6q<^U0Jhf%n zEhgC$IxYe%78!?cep;O))O4z<(Nu%MiT{qh zz;A1Ji%mIAEsS$a*b12LIWucsV7%$gpi{AJdv)U%Z3deu2bfMYxy(4oU9p>WLqop6 zepL>Z_$Le+JGRZyK6uN@@uTN9k&4#+#SA_h8bvQ`wQyc5G{IJC0<#bY16u>*KP?8{ zj&;l{8a{NjI2bfp6}Lz-G|DnCs%x+aB`_EqaA((OX3*Fne?li(;2`q`26qp8^$P2P zPc0v2F=<@b8UCR8Khq3G?GFY^xQ;sP*sE*IaFdBewxCJWVU_fY#xK!LpPcl$Ib2;d z8n>=)(EPF6;>D_$+6|@)7$rKIxCN|V&stm7!{i&%7NoIVvcT@9yKG3N^%U{W}+>{7$8W~NP>8ChId zxD`w#CfFM8XficsaQ?wOWA~a%RqND#9B?kMV&2eT=&@f@;b7*TwOJwZ&ISw$2iBZg z)EHgSYJ6hn)hI^SmS$0pwPCv%LlibjJFG1)*{A+OE8}ysgTw^4T&vTX9tQt&jheoEW(?qN2#9IETIIm(;d?;YPxkd%riA7??dJW- z%-YR*90yuhE;M><@s!nQvHiS^_3}nmgBJcP4gSrmY$NnTGMwai)?0traK);@*rDZL zmp=0b#?wVjI@wzoKJ5O$#I$kB-c4_oZT30MaDc^JXRTqkj?szzJ`P$O8Eyg|jm0kO z89JCWZ#eOqFj%fwV`!mg*}X>Yhqc6xfTLS^C$fx2)T$ z!{Bv7Ej)QELq+QcEmrv+OBDOzG`!h)_Il_ zEz6Y7%HL39-mS+Mprw6+h4+KERrkRUn;JgPI&#zKILBEv^%HBPE7ocLIN+49C7apM zc*0(t3p+n31>_k8yx?N+s%T|w(0gj-F8X7)l!3l>$7PA)t@)oXurM_Ca5re^ZjA2M z*U@c|uP_$z4czy8fmrTl)_}&K3?|zrw(LJzj5AiT&e-n}(9DvpReYye(t|<0V~wIN zgHFZnsVwKtJ3xAT`d!HQ1 zd1bt0lCI$kN@L+#xs+=*#wwYEiq1i-S~m2nRQ2l{vAfM-@a@L%%?wvT<6wzf3PLT=)z{Mz%Q59 zOaIs{=b$UOVGYNL9cHV;g*^5|`>yTU)5d4fZka%Boj`IMxd?n5{Z`fTdxb=mj?g4aN!Djr;dD znXxpkdA!V+W4+u8eN*K#AG}!p-a5g5S7}z+~xH8tX0x07%Vq18g(=apRhk_+Yr4%hx>63^2R1%(wl8Hm@RHN=h{3JmGC`%i9sybWU+38dIG}^T}B(_-R8ez z**OB{=r#o0ReNf?@3%>d=7q3dpO4CQ=y|@ieWJX9RpA87i5+*m9~%9!KAjT(f30d5 zpAn1lhc)Mf?(yGl+MmtjzF6n4tKILWRV!VZi`O)qdX;F?tuNEMUD=G`l`q4Wqy%=4 z7V#I2QWcHv>l&k1G)hVA%u_m>_B;56RUEqoOVHgDf9J+r&$>JwxC`-J8w#HJtjzyd*1{&tU)ZUz;5&&Mp&rZ2!z$#`J+%ua2|Z zdZ!g@{x?j~H*ekX_NpUyge&{)WuhGGSA7ZZQ`vb#D3wWin`%MB1zrX-j`g|%FE&?c zT~g7JU1H+=comBu%T62p;y0U^3ak>h=_GA4S?t^3l)%uZ*WlctwWztlA}r}K>(wn+ z)uy_g&PlrZZ`NU@%?(Gs8boi<5#3?B$@v1m&U(=o2X%cnCQg1{>6grRDAlEd$@{aR zDaU&A6U*c$*vk6t%h782V8tjlE%iW9#(_zW3#K}#|Iq5n+xf$|fhYQ*{aH2XAJ($D zs{(S~teCX+`l;~xqj$D%z43d_`Xep3XNWC#IIAXPU~8XYxx}h*f49pFKc5v$k2uU2 zY-5;Do;|^!aE#?c$p1@|lFzTxFN}$M$gOXA!FWm4vx2_$|F<+MWt(tcxW;nf0INfU z`i;%<-r3t1J%9f*sVv9f>DJa|r_Qq^q+PwFzg~yo(Yqb{pDjD^Oil8LF;7oR?c|rt z3{24+C-SA5KNztbFltyir*Y!!H%u!wZdH0)b9PyPOD0>u4*LqdmAe|ORxmsHyf0Nz zzqD@q{@1UIOZUFce!JgITk?nX&vS3B8E%+GGjd+Z&2?gSJpKB|tWzu(&N4*YWC>v0 za;Ry)baT$BS4;-X{MHTQCc4poC-}~NeKlSe2N_H;;Te}42M^~0{DYSk_ zddv{e{Pj{}t(KAVit}zCJg&#R{}7e&pM_7~M)@$)3MSJDtE?Be6s%&nJeg_v?PXa% ztnF2|ZhOi+KgGarcg$6$k4!5V8I*TRO|WH}Q*e=QxkG8NE6e9xq07E+3b_7%5XfI8 zXkZ)C(4?lbTkFSe5qo{l)^opO*80q_m2l7!)@#tdv6)MNS?2n(b{57(M>p9`ZuU5E z^itEV{i~UHee5iM>=vK!QiXrD>iu~sv(N3n-IyocD6*kZc)_84VOuQ9>=YEXbDdyv z^%Ka(0g7I=R(|#qhBzCRj=W-`bF~x`2 zu=_PcTLdoI#F(q^EZgB{&ighmDc@MX;rQzCs`-0wMmHJ#S7Up@c;;6X<9Y^0vj*J_ zYnVD%9A2zCeb12j$M>8l#t+;zM{hG8j{Q-Pj8=a(2&yk&5>#ByVM z$kSIMc}!uV`By(ZT0h^`ct_JzJ%f8kkKU|yyD8ngUZ{y@_nQBYm|2t+zDK_`6*&F< zH2?Zt`Ic+gwbve>$KjwUYSDPa`+!MC6Ng6Kl2r`;1-=zuTCx_0?|AwrU;p#EsJAQy z8|@df#LTmGSdjAinwp1z!BOF6!yVr@TQz9!*vF(0dia0N5q*X;chyW8nzYzESXj9( zTwqXSIK&{zHp%nFhlfq(tQImJ84p<&F){tmu?$Fiz}v#jJ;5;HL82Ht=YbHOf&&b* zWm#oJeoQ{eFr(2SMlK>@0n4gJ){-v)#pwz?4C>4`GE_p2&#*NYQh9Ol($ZF!2W-nM zLpY8r_GZQHGnvrY?9kW{*HZK1o9>+*Mb9s-&Hk1y8LT81RPnJ z=ap(lZ7^cs;%rILo|YDH@C3(A{n%fAJMOB!VGsy$@hE&|e*b}*FWUmyMAq*g4jkOw zyLQU2ZyI7(RPGoVOfF$lIetJ`u&01A|Hamnphl+{h504y6E-wti`@wb%(hl(Xlq$- z7!bqaukt*gymn@VQkUkc9ZKCLe^sS=3{P1o_nO|SQ0}vQwL`gojweHdBJ+m!fXt;= z-5-V8-8Ekl_f1vf4x{qCCDJkBQ(xRI_^8UE_dd_kDpNM*W~$EhS;T&iw{%W{YYUssh65Z-e-~U~5|~zz+TCmQOJm8zcVCnG zr$$w2E}NOPOLO_$Dyf?cvoe%cPX97dYI;M@xuvUOsxBRUHBm>cD}aS*FJtR0@gBnq zeBWK8Tp1M-0`D?~tr2`9<~47Z&gQdL+?q@0ds*vly&6@myX|IE7z@L~zE^Lioj<0o z*S%q0g#)kD)eyiL_lL=JRfku=(s4Wo#J@Z2?TYAxDLm=q+s$4w<=T(tin67J&^%b$9>S)X8pd zV|>>1c8&2ln`^=!x1SB;F}~3I$t_l-=*x#@;q503)Mx1a+UCF-ap#eXaI(XqV+(xQ z_nKbUJ3YtvMq;%1L;ZafJxPp3xv{e0ZMe1qllxz+QWo-ORQvwFF7cAeF$ zhT_@guh;JWXZ2>H;DdhqmAC7x-|c)YSHV&r`_KB>Zf<*iG4LV@>x-SEx zs|cg**Q?R>w%=}M@3;MaxB9>BkB8m%c0Zraj<@4_xq83dZ;d(s?f!f`ZEyeo@7Lq+ zZT|gyz2E-Ox8MKm8JIN=FbZvGV6#zR685nFXSkt}uSS7IS>qsQ(1s?lJqm2bD-QA& zZD^MJqrl;;aY%5|h88s&MXul#heS7RXw|Dx!Wj}3bxBH_g z(5!JpQD|d_n~jptuBFCQ6*qa9(*TbknAw+0{C! zNk2}^@Kbvxuy&8CUh&PvAcrISEFW9`*VgC zhuh3@8)FcwL8Rhls*Cvto%p}?~OqR zhTbxdylx-0$29V`Vbtya|Ns8@|NqC||Ns8|vy8m(@!$Wi|Nomu-F^S&tw+@IJ*WON zGqZgC^WQr1w0YD`n~39obMR9XZM~xGBUE} z5m&za{{QCf+l$xUzx(??J|W@31JI$OM^3+Ri&=N-)G3qDi_we=1XvN9V4?!LfNI22mc#I-aK~tk*BAZbJQjS0|Rw+bw(!6&)@#P zdiTLR?8LKY&;0!S9isO+My)dpJoe@9{}(S_FfdtOxpKulYR%N8ziq=0e0cksfl=hs z$B&O6Jqn4gJb(M&tKa|I=lzUMZM*sCe@ywEyU+ixTD9u+m;V8gwa!u7Hy`~!f5|z! z&{dpVT#FVhx^?T;#fz5=yjQ<{{URhJWbWL#npVZjmoJ|_eY#KN)b8$Xd5eC1zde># zR*sHN)?vF^TigEr`CHa{`qH!iS{~a}99PA}#M(z}IeP5a=g(j4qR$^Zcqlxf@%QiF z!SVfBtskSxA4Ww*v5LhWI`ie&)&CB$M>^;Ic>DJKgb5Rb#1yl#vIPVL>+9BpTHthYLkUiBsZtvQi zFPE)7asSi*sGOZ`-SYyoFPK^fpF01-A?c=7#I1)f{;k`3olC-F_KN2GPP!Xuz;ks4;gI8w10or4yHVv*gXX@oO`9 zKgzw>nGdxZ_p+Z`wxU%vez}iX+)n9~1yAl?SnNID?{3c9nad;Fm_9K0gt#(`OZ<c!>N@#pJaer!CbE@odfcj?mJuYz%UKPEr?{f&W5<3R(9lo+?;$K0o~p^qH5 z%=h`8dS$-T43Uh7;Qc6$oLW~B{gzgKRrGI+c{1HgId8?IE}d;2H(Gp`u84@XvE3n* zpa@MgQ^2jsYX8IA2j#iGan))vJZ{-pgin6q?L8D{z6R)5*DC=1fUw z(|k6=nsqvhmhYx5Onog+&BGN_5J!bRL+nS9dJx(qmi1y`huSLeQK1=A7XSVB0(4a9 z%Bsj1@KK?+W-!eI9~Ig+)pI3*qe3+!IT@xNKszdQ(ywIDeiYQBLbc!Rcrq>f-Od-w zR=)!s75Z-Xhhy6B_k6jQ{eJI{XRF`u`}6Jf`~3{;Iv)&%Ud)m=WEkp8thaf!A`O1yR9ynuHn z!{^`l)Yo}6`ZL#7vyhs_k^1}Q-S8IY{3^UKe!{QE+v_8Kif{Cv-OeA_pyae=#+3cP z{{*xD&$}$t@#UBM0hzz&^`^`|!N7gufVymf=8|Xy&ozM)kDplIC=qj>`J&UoDICWX zgj6_J7(d~aw ziBdDi#deP)JOZ{agyin&*9aCm3oV~9Q`M`rRmxJyxyQh1Qo_W#5T3{3YdA#JwJs>G zG(5p8#B{W$Ca|Yq3YX+!rK7!91R0`KI=Blb9k=+kQAc^h!jLP+osF9W920Un6#t(% zv1q}Di4$0^DJy%PjP>0#X~veTs>UZzM&xdqyddSOy0ho0px#YWR(!dl8GQ0o*sf1g zH}ovkN%uS*b?ei#sai~W3zuw({k17*?;lm~92aX5eH?SDKxpLdtK~`nzD%X#0od_Qy0 zF>oETx@J1#>l!7vfFu{Sv=RJUpO4@D`2)2VPMsm)5Iv*v4!cq~37Kp=6a~^XHZb)Vv{=7*aM(QIwK$U?hxv}LJYG8v3m9x< z2|FFm=u_dKq4kz+V$W`#TmjRy&wbx3-Trm$(#g`8{DNkOm>HbSCm3wm3^}6CJh-m( zZ=-aKY=g8$BBM433){Ma$E-gXMdwdjFL>)rSQN{`N8Be4HA&9N^4{Xe8To(1N2YZf zI(Z# zb{FLwnQpT+rH{D_Hb)sUd}U=}6f%BcHC20UgJbj~{_I^$ihl|o$|f9o`f1wEJI~|d zW?hdl|5f)|GhjlasluZ}S6>{`+*i=b{w9ILe1$P%65~gwl!jgW?G_RS2Q%3u777a7 zZ#ibUF3elUf!i%Wo4G~cF)PcWOClbnVp|Sy&Adp zE43epY~R6Z`;Vc*BDv{pxdh7+(Fu&%7D_xI+0dKdO!@dLKZIBjxdPZe9?fKVz^>iEF|n-P$f9}e)cRk~CC!(YA3V-bzJWE`pdr?wfy;p7(6TU| z2#)<~ET!KHv>P~QeXIC*ltGP+P3lE0;|7+M9~k-;q%Js?dGuJ;nq^$t6Id^a#(xZL zirT=ih9TSJMqA#FNVAIOITM=`Bw85**kUiRb!=eeZ{QSRNS_eK*5JVX?i;)GHU>}e zMuBp+S!QwR|4*bOB*aE6FP)jtA#j|_tAK6pG{)QwC5#D8(;OJHuV!sPinn71!f!@A2fS$WI26c?>o?L)|S|@BiVO5Q&d^nhGR88Wvr7<6t3OI zQm;_LIi0mjpel1((@Qay`6t3IrFJdb)^+DbZ}ru#bsds_)U$Xlu;nR~^i62bRbXk^ zz!W`!%kco$iUy91<%wQ17!RIky^-FdJ-sJPBRoUm(VC zOQQUq#6+Q!VGktwdJX#)m1i{{bD|D5%aVe$oo;g10uti+PF^1zeYNNuN&ZK9i8dS}g&e|W&#`SY@ z=`jW;&nW_xQz~Y5d9Iw&d9XguwMyw27moqQvmJ?D6FB?Xv+W+R^(FLYu}+(>5t|%2 zEz5N>;{xWc1}>+7rbROtQx9;7f6J5 zpA6v>N+y&sM}1&u`M^5IvtUI+Nry-5gqxX}+mesJ=#LVwbbc^9b0^Ef4Geu7Smt@o z%1WKJqH=m8E5quWbH5#nST|F0=l?SHCzb5&AJ`{+s1Xq7VtJ5dmr%;LqD|rht5XA~ z=L7ba-?|wYruAB6rR-#w7%_9sb2gFfT;&@I7#TR$C?vHPWT~a~uIQNiditz;kqf_F zpY_mF!gxWE!t%tr29Edx1)ZiGP7G{P#}>9fNY;K(rQ^x{H#2s^iaCqQ*&+)%tT%9( zv2iY3#t@&7G|i#RT5X}{g)FhCCE{H3Bu`05Y*?ruUevxt4uJAQc;cvCpeXz>D9JMZeV?@J>rh?Qpo4dL;XQls) zTJz^t*fyyR)k~u?zlN<6UC+fGbJBGE7cVh|4G{qsSkGm(or%g??zZ9guk}w#r~lfu zuBeqMt8_!&)D7I#o7P|5@Z{HqQpJrI3^qn;)*8Le`nYwm*#GK{;T&1!yEk)fV40t` z*?RWodCNA7d2hb*HPe}Ui_PuL1*w~|Lzk*_Zwk_m<~zM9IgmGh0{amM9*zcvzzU0Ub!WjgjtT6Ur#Xv1aAnQr4h+~9`+IAWHGA&rZE@V&Vo!6%TC?Z8-d3c& zJzbi$u6lbQ!}iAA+ba#&JEOP7|7N=^u=DZ?wxaP@0|C0=K|?n zi>!AoiQcuWde@5CyH;iI>d$69le)Dxk<~(htxAAx+ik`~2H$ff40~?xK7VERfz!Kp zbMM(@y@#E__u%Y3r>ghJKG=O?_nr&Yd-@-6FH+!IXRy2K!=8(~_ujd^_ulWl5B^K< zdt|-uN%X#F)%#w|-uG(vzBkH#B*%mE>R156tjr57+VzhUIiIl!~#fRMpKp#WBCg#&DV4oLkuz!P&oB8D~ezyU^{ zLkfEiaIHBYJ?D_X1MUq89E%KiwtiqSJisXQV86zkLl$!mTkSb)bLX(#pTiC^N1SYq zxWpWBt2yE^=ZM#yBQ7?Kf(w{FS?}+1WXUMlFJ8bDp~LX+^?nYX1D0zJNPRf0z{8jl zb44<)eGGBBGyU}8LT)FW(P=S1I|!{Q%~1nL~^a6B5;b5uQmG0NwJjm{xWp92ecPMM!M$P;r) zR_4?Kn}duz$9VrR%01Z6^5&!s595>swvz%LUI*CP3OEfC7+sXj;H{JLl~6 zIVW!ZIdHq@$OD~oPi*)aO&B&Ru&%qnJ}ZFvP|jJNKa5{=&Lq~H|7UYaCH9h9?Ilm1 z3yifA%(2Ys1s6DEFY}*0QTqSRQKo>)c032Z&bd6rfTvi1GufCWx`4;`0qa|v1H2n9 z^5mS=xO>I#@0EbNSG4wCYQ1<#_yDu;14hH%3&y@@biVBXEZy(odFDS=s6 z-~^w|&05*pn{01y`Fo(A_eOal>zxLcJ$G;K+snR(m&@?M>CW5}(hWR&*7E2FTvz$P zezcY=!f;A_BZAmRpngUmC089S|ro(3$ zxBk8NLH2&o+cP`nieG)epyn1ST)G+Zbc%XXWL88IoDYk4=4Y>CwoLl*geJ%r2{0D{{20kSPrUweF zM-Oms-oRb!aDjKh$%i`kt@b^(@jJ6U_I@cN>oXlDqXSHCc~2A%Fxe_R&<%LNzV2vg z0F%)NX1@YXe*s=q0j81w7M8n*c?F)DI6QT|aN6n&qag#c{s)dJ4BST(&UI{Hs5f9z zFkrIYz%)~VS$P6y&UCJ4x?Fp59x_dMY-{(TCGLg$pT`dW?Zlnz7%orX@SU*t+!SWZ z0tPb%=8LsA&F3Eer+p@Wld7~|Gloh9=$_#I0`0`utw#=jKU%=8$FYz_)E+~|;f zs_5`E!r*XX&w+V1j8isnZ&u*is=zV(?oH+fPFahKeH*x#6(p1c7H?5teyqT{Z345Q z!tu5`(0&xlo)?{R;@$t)G%q~mxpP(e%|XpQFXa~;NT@xw>E6W!3QxDmG3rlXwrF6M zy}wh+z|b6LDB!Lx$gm?{|t-|cn(*zUKHJ?f01$B=CQ2;4wVFyu|Nm z(g&s!556Bd%PeHTXu5#&+XWsE2i8*#d{h0HOy>OLn80-K0#~&IE1LkDnZX@_2do<& zuspM2XjMpZRQR^np24B_M^J%FkTVhQ%zv{r_1#0K9?#3%bNyPL564B{;^~- zu&93EWmvepl~s=I&_)A6CzlSn4?#Aa51B$b1?+bnbd+#f%NV(0-I&IoDYsFN2o(!uF%ME3eqV~e9O5h$FFcpF za8~G~bR00Aq%v2;(xYI*0v*1Y0?a!KCJG+n+b&@AH7HL0lCVC}IRFa&^z~G`98YFc<$USbBWA{u4hnC)` zUkwMFK0RGx5qwQkzGF+W3gf1RtvuNNr$faKJVnM6;o<`?GjDFs0Tf}0kmCPhFHYd(ITX#Wl zhgeghBa5h9QXzx3z=JKU(lZXKoh+MG(K5-kZK9Lhq@<$E28FVQ&IvkkRb@-3CnX*h zH9A|f8M+^3e%ECG;`6TN;Qc6ff9)#pWRuE>@KqFaJIKT)C&GPDCP_}|V5`(24-V<1 zBMEAJ!W(8Xvo~5iNC?w&5pZ<9>hOhy+w{_oKyi~RC)hjW9vo0?myohhY6{zt_17OAvt4`{xQ|ZA=dwP@U`x&VDB|ZuyC5px1r)~t5w5<#Mw4o8p2JS9tCYZjCUT+ z-09V0m@F@~M)hRID+iBROBRQpI?^8!Q`yoocbgh$Kg#`GuQx&WqtyA?FF(lG?QNx@ z+QZEELZL~b!ea}I;1|uGn-0fqIJ`M~R)%Vx+VW`*4V-;9lv$*7{9ds8A8B~&R@xQ7 z%sD}zJ?iE|>2n|2)S@mh2~9Y_G++7vzni!O$D9WC&jRxH7X%pp>sK@i?VaJeX_hI2 z0E=TL^NG2eXP7aB=q!-f#u4{tg1NKQwF_-;0^`1v>~NO*cA?##rD1-YVw(}?17`UT z2RLI482KF(YLq6h@y%Nx{Bxmyt?vzI{)h!i>}C#3pBFo&e^75e*13>5^Mxb-6~-A- zbCjhD7tAPp#L#ZivXIsE!NKPl4czJ-iUv$84hY&YvIu@y%qggFQ1DoSj`5V{jIG*= zmxC&{Fz!$kt+Qy;y&}LYdGEsH`7Eg#t&^M;rd^t{+$B|u@yT*?lZ8IK7Y?wiFfcND zEMVmIn3A*PqrlvZ2TWm44*fcmAtlrDusUwefqf?m_8*}e|&vg%uliZKNNL5s7V}E^kiUk4NDSFlW?Epp&_icq)Bz*1t%4y!Yv*t ziQGpoT;tBV;29`(WdXaYoMz}w$bJ-AZf(!-?aE#U7HvDCDq3>#H0KYY8P^@0wS5ev zWh#;tp3ZDwT@&HQ8|Z;9x_c-HKQyGsH(rd?f=?)v((3Kuiq zkxSk2J@?t??KrJj)S!N##+hr*!C;GuM?$}Z8rakd`l^qtSh}WBO)Ao1w)lqxrvJh# z7&(;!xK6P-C+ZY93C?&ZvGCg3Ic~n`EIJ7i96FyO0;{w*j6Sjo^e`~wDV)sW{Lm0O zMR~!KiwzN_yQA+N;?&M$%`0fNzEiUC(p0e(2iWgfHSRb!b$Z!UhB)08cEK+TWL*W` zvYI3`njBGNiH?y;|6a~ua;`06Z3DCBs|T&h4i9AH8xE?3eeM>?nP$39@>TkI$y*n% zZJN8>^@#VrBWtFwVG)YfIIe9X**rI7!FK+(f|kinVUNOY91=hFA+|?5ieIJBfVY5A zcdqr(xj77MFCRO_{XW1ezx1%YWx{*TXN~Q1T$}hiBLum%9_{$_Y7s|&2Ae>`0p9!y zMke7f$-Ofige)@-E_i(KG+T`WL&aKOmSq#R&k6m0^4$g3Hb3FE^D`O5&re{@ z+43S;`o;kflXH@*|3}I)S(O~_ubT3;Lh3-{A}yV{mMfRC_!%(r$utTo#Iy^QY$#Mc zlfbxAfKB>9LA#s7+x2&<*0|2!TQsfN=+@P?$}_3=4re7S4pUNS&M{GH%AMW7bDz&# z!0Q1|;VjMVx-(d~KTP1zxwDb=Q2=AF>j5U~J3piiZv|*N2(l|oP-4C7-8>=sVxxqI znMAcBp=u> z)^y|5CjAAUPJO@s|8dpMv%;XGLah~>lo#&oma8uc#;`og*M{?RRL$F zpboa&3P%4#1tEvFf*pd96Ik^f*x3>V;&wM2^bmOJWY68fXnLYiy`oXsp`Ck0!$AwB zr?(jNvl_Gl^w=yJ=WkdM-R02zd8=!{A=e%Djsh)SFIrt+w8mAm>|88ma@+po@BO+@ z4w-NsU}8CJAmaRcLz76x8sQWHfnufqU$hT(Z&F>bqDlAz1Mde0p&QM`P0XGsIo(D%Yh+v;za%^N zXdN=X*)VTKlhy?W-W3c&7ubHz+EwDQ-t)sc#)5{t9V~2{XM@HALR{ueXfRpbpwrU8 z_2S@{$qvpwn|W6>L_4|9yWsMLTc`LjqpOi?@E0cbRXdblDCj?6RNk{Re9F;!7LQd6 zTw_#DG?{p;(>OdQzr1o5lVn%E84b}*5@CB( zb$L!qGVxrx<5;83iK!_k4SYNvdh!b$VDkLIX0d?Tx`DYoqdonH1l!~NlUYtJxU+W3 zo;}k{PA%SZbh^yE&jxeEH#EMzDEDq7BiknJgqAa&U9-)|Wyw;L(>tb|*3D^Hn{s;h5$}#oOf?=2`@Wps&vNE~$eDvG zXAYU1IqY)gNXVI^DQAwAoH^cd=ERgUCzqT#wdKs|BWKQ>ITJXef6tdQ=SB3`1}8j;S3=HSO*wn5z_pIdH^Okcjrks1Z+t&VMU8|Gnk>k16MWE;;{e%lY3&&adNOWe8~a^X2@1mJ1A` z7Z_D9FqvLpcD=w78eqA*k+t*!d+P;`sTVkxUf}vGCA))ptpF4E(+hlGFIYr3Z2Hj5 zuX<6)G*Ce*kYPiMaOy>|(m?APsh7$!1AZx-zdq}d&eb5+vkY4#nt1MBG7!CNsCwDR zG+0-c`9H(U^Tw%{&E}rx;b{1;z+%4ivenkh)<-YfT)k}j^s?R8%l52S9Ac-7ie7Ot zz2fY8#U=ELYw8uZ(kt$*S3IU(@mzYvYwH#7qgQ;cUh#c;#qaACf7Yu3qE`b|uLhZ3 z4R*a65_&Z>^=eq@)$rD<5mT>5F1;GH^=kCdt1(xv#y-6o_w{N#>$L>YYl*7Yl1#59 zyIxBPy_TAKEv@ugdh4}}sn;@>Ud!5gE&J%ToU7MzpI*!RdM%&zy3pKUhK`GyC73pG zFl{=)x7CAngU989)^N?gft!CY?~Z7#IC`Bw_VRCsmfEe|dS|aU=w6go@aIwJ*4E`_ zQs7oj=&p?oYHYpnKZN1GZUJ{!E6esBH#UE`zI{hi$JYq1xr{x!-Kq;3cpPr@yWUiE zy|n$rjVYy(!gp_MNN8HG!NRa2e4=VMPXI&If*aGn-uzv%cIyrQ-x-mcUfh`PdW$tS za*=JffbXs4XZ^V8?^d|7<7@O=necT9tZl8`MXcPdZ@D)8y?xa6 z!uGda7OdSXw{}l{%XKpK&gr9f&Ro57_UWB-U+nf3 zY3jXarT3n<-g`0i-b>xk%}ejS-g|U5E5oUy_uhTI_n!6s2hsZ6~_!^V3XB7z%4yR~^+IG-i_e{o;?>Ame75Bby*Ee}2ra(gHe_E0qK zp;*~N@wSH&(;iALdnmQ-q4cqbGS?o;K6@zl?V&u|BL%TXifWIP%pNJbJyHpKq?-0f zt?ZF{+aryvoIPde~{(6RoHj&rY?PwI9mUQv0|NkRv`;7yb7%akz zEt`$}?)J3CY`k%C+lt5QZUk7U#T#(6)TXvdojww}iXl=q-a~{if^qKe@1OIuY*` z)*5i`df>d|of*xZeR4-#yQL4XMBck&m)5{|j@#`Tm*2c@!LaD92U26drLwI{>dk#7 zRQGfP$DNF42|hE@vdeBtzesvy^lY6*v)PHXT(OANPrHQug46t#s;*5f`gdEQB5g}X zI>UuW42-E;Bbv7RCY0MntDfNF3P@*gxa7&#u=6b!*NbOHFVglFq-_3?R`)I9|EE2V z*LkF^<#@46gT-e7Yv?lW;%VH8&$?6^UQASbImzthWVe@7!d^~IdpWJ_<@C0fGp4rG~_H@kIvxMe>R&0Jsc;2+29wHw&h zf9qsFQvoi1A_qv1i&7X!l+6(U3>}w3<%em8fXIozP-nci*-`>>e zc)G44d+)X+hKl5(-kfu>jZg00I6bdB?%kW*qYO@en+}F`&w6{wY(~u5j^~&DU6TlX zyCvc=&x%X8_`3h^{MXe!EjQEj#@ZX{>pKz{BvN*IT;JhvC+r>9-G6VBWEmcdal10) zZkqAp?NhFPwuZKC-KL^%pO;;GaqQhXgP6u^T+i7Ws_)+3`y%qgvFi`|ve!j4cB?)< zd#u~0FaP_sYZb>*|6Yr|+LrVGUCezs?l0H68N@&IzkSb={(-Ih1AF@ij_Dsbmw({e z{(<}W2cGL6c%OgZ`~HES{iA^RM?v+Ee|hiNsGV^B@k;3arB7z6*S~eK|9JOjMxj{w zrLScxr1ta6ZZAw+o3{O3q1W4257-*Mv2i!wQxt#BCAYqRA#ahIYSE^EqO}c$TLT(c zpPw&$#>K3jx;5d`p9i0|ulV$<HO-)GScEr0%XncJ}#@OE2!Jlk>pCuK)-zPdF?F$)uHEoClKn{=Yr`qG zuhOjCBKN<>v3KvRYjD2MrT?RJ%LS%@`r`EwWgB;7_{bkvtom(p!aISjERpj|*KTN$ zy}-4tl|}jOjac?({e~Ec{y=5cW|6HeJM+FtT<@w5?PlH3V$JY<mt5tS2V~* z6pDXOvA@CC=XPh#bFNnNUmH6vTHgQ4q8G7Nfkj+BTE_QRkNAO*X#h zs#Z@o6JTh_V&Fc^+ho^Xyxt+T{Cig)dqZv92d%v~bWS9<B@?M4x$#OP6 zmV^%v4zhEI8<|L~QfzGFZ!ridFmOKH!!4Ti=EMgc=ROWiv!1OV4>l>Xy_ZRO`BC-E z45Rc*YcfBpottA-{^`xj&*~QzIJFDuW_{7Pw8U$=QRuEi3akv)Joh?Q20Znhz#vy3 z$|?MWdAgN+#48KsC2mff+1o6C996i!R#rYC_Q&!}9s9WXN-3FN=mxH<= zMYubqVDmf2GeW#stPLE74|>xDjeceY6#FPHw3v34W7@)}&c@2mN`5X7Wbl|T>BMwk zdt&~9g}jSq<@~Yu^yJiZ8_i|r8E-u%*JY|{bgv_< z&_vBit#F!3bLHWhh5S)<$JU=l6=4^nm|tXM)ApgjFY{$sBIc|KHW+!#e+D zO`NsJTsiJWj>!xgc85xeOu4vxpZM=T#ups9a|=&TDBK;g`K;{R5QeA0_oX$Hv6{GxwU^2JJ_=<6T&?IkA5oYucU4*L%(H*KS|y za#l(8;*|sMvK$xQhwMjjzms^E?d1!Lr&FWrET7HH-Z$mi?CO7&%O^JYO_{rRcAeF$ zmCB*MrmH~vQ8u2ovwk~+KLE5JWuNu?y}$oie>e!;k7D!bBzQlH^?#c$7rpIq?MJD% z`vu;Q@^&|LKg!*|UvJmjgZHES|BJRCB|d%a?2f#2PSAdoACp-BwKNIsQD9@wI5?-| zkivHBj_F3={V2t{ii%vp91g->eyw^niT_>1g~bkSXfyi~J9CQjVd+mB+7DY#;&0Y) zd0%@l&*bJqfypae9<6+<;P9rC)m@+<(^=Aniw)&}O3o+K=LDvo@P;zh`DQs1m_@_^w)~{c05q0|C|Nj>*TriBf_2b|FmoHvTn=xBfR_^HOM~@yqe)#aw zv*#}?!q5Kw`}fnI|KI=qw~9QsV8MdRmoFPc-E)rI5FH)u8MVSJ;<|a%-QM2boZQ?? zmoB~i^WWUu;?SW(U;qC%3A+*y5U_jq?megf9X)!~#nb2Ao42c1ueo~ls#)~S$xFZ6 zMxOBT@$rn9D<&rP`QQJbsM?b!PyYS?mx0m1DRTAw`w#3R4$Pc6D>E~5*|KGQef^e^ zms#1^w6#IkgE)rovX9zz_s;G3`1q2Nl6C9W85kOdCDd*@@qh7>CFSMio{>}S?ChMQ zcek~*9X;7QD~Z)h#hGY0<)kO-)T)TwHVJ%wgb3 zw2wUY_U-%m^XEsDKHRZ$=hP`v63efcyJT$NzWu|;_xGRvKXv-b%5f*{;Q~{{rUf2$LD~q*M^sGKAk^xCL}nx zuCDI=+t+X3yt;P(-`mgsj~_pN{rdI1_77^7)gEzMzyADZXjj0+;_DQ@ z`{LCPAKrhSHf`F38E4d-*K>+m^UH?3djB!E=2%{7FRyZhv9ZbK&703Z`G4xni9=^T zojrB&!@GA;xkvWx+kfQ3zp$8^1>64G_%)YyU1t_fdiDPQnyt5O{ijN4C)LgRBcj() z-hO_=?vKk>ZV!l^77#T*zhX(p%*WG~KE40p|HecAos+JFq%JONIpUji;PkckOZNVk zQg-fG_%2^4_dnBS|r?WtgCITYbCtn!%)bb!Nsmi#uMj` zkDea~AL`FyQF$ZdwPnS{#U7KjVoz;Z3EJ_Y#Of5>8`9&nKI`tOt*{**VhiVO%DBAg z%&Kj$9UtWjSR6Qm855$nufM;)ftg#*XNN(=K0$AZZ`O}BA03^b>^;wCXVI18f^+A@ zsQm1DdVYa(x18@TgS18+mp;$V@R$9&=9n##{IOsQc*loctyI+E%L48UEB<~lJ$+3i z|BBCs-8(-&zpz-n_3Q746Xw=LoA&-@kTvYNB%2+Xf zqP^P6CzE{4UV?UfXg-}15|;UNYDC&i`Oqlj8%Wfe<~?L!C{5q?^4aWyM{0}>h1W8l z&#i#$_~2CKtYg!9v7iNc$H$As6Wp|3f_8koTslK7q|?D9?bXZW3&1-*re(caxnfyW zTF0twuU@U*aO}U<>or@hWxZaz-Kzm^?LmQHtjbXj-c)MaMONE+K!K|q{jFA z{w!Or?|6nmV8emGVmTW!&N46@7qO9f^WpIPgUS~)mpkNqJle95*+Gzjr{Uvqh3`iT zPpC|PGmTGq_L@(pbhf|wblTv!&gU~G;5h&j#Y=2v}X>Q4< zZ+Ctl^ZkDJ>#5%F_ddS*zc;S4hFvcCdTVEb04vYJ4HM#;%+D!5oTB(|!V|WYD}}hG zSg+feI$`zkSI-vwzP_`5W_#YQs>Sogla?>v-WT_(t?~JljD$^A3;7F)-C_pj9b`Sbn#|Njg;3mDiv4lqf5XyEW!z$AX+ z0Gri^MuDCMEb1NyxuQNaNt{{0W`5!zU)6_Z1)hZ*?jDDPW(lY(FdPtJQDQfq^P$z~ zQ=7x5iTo`-Ol_=%3=FRr8{!^Juzl`16R|8kG)wU9#W5A$lSSjQK57N zvm%G#aqCyha;`EsC~z8i=shd!ul=H&_hyAhvp~bdUL9T)Wz7lhL7&VfFIl3huX)n- z!9j&C#)eN}O_p5`99{R{R#A5kHWQId;ptB}=k-oOV6{&Q`|;qXTCT#}Z2=28wKb2p z7I50cz7sOp>vBR-Lq$M#qf4!TVw#q5rOzpq%L;-F4lFgn3MxD){Vg{-O-j?xWW72z zn^mZT(SebRAw-!;Fu_GuqsXqe!cp<2Nv!4B%Ky?qKa%uct~qAp5zw1;gn^;GpjoP8 z18egh1r7^_^P)-@SyT*`&tv-OAkY+G-}KQ4@h#dBu+}u;ONb;obX%l$vmcyypBr*gldB>FI~E_O`~fI zt1%OUsBVF3w3L=W|AtmSW=X;2EKVT|0t;A~Hwvn-D4l66ILYfe=@17)ptM$pNr`Uj zs*FP%3@$be77t^bazj!YSa!JcG@e*4%c8{gljjLn;SKL#MuRI&Jqv@QJ(hi7c)-}` z;3Uqw_5gd&L9reyz4cY9Jk!M!BJM5p<|YPvPjG7Qzw@@+;N`3afXqh;lr{_*7jRhxSpx=W*&;~+`!W) zb7(eOWv|46!;%bJMCUz!-KniTd*3Y%;l-jmjwyC3fWIHOe9Vs9KQ(o%crxP<%O*^N7ncCS2a zG%c`8Fqe^$`6F}w|0spen-?uO6+m00)SX@_sH9Qb)hfPJAw zxWX*EjyCJPkNlgZjM6*Su!y(^@A>lZim{uA-QJ!=h5NhC+ zZ*9&_f!hivzqp&G%<>aTF=pc6IKZyN&EVi&y)s2jOGr!bN)+<}w?w|O8JtD$4%qIz z)3B03a7jP|Co==%&6Xp~ZWn|(92STybvUx{?cS6cdntx))`rk~x&oPL!4Gcz7xOsy zv#g-yFe|@7`%ZbY)L_FN1x5jb12*hI46ymSaPcC;jExK9#5@$dWTX09Viopo`Q~t8wq4VQN(D9n4koMF z*$ftCcOuz+wE2~|W{Dqp9d}++H02Ka`2(RmGSeAYLuv%>Y?Ni-{L$EXJ?`$Q?C7_C zYUTGXFRE;aN62iPm7?Xh=aTK|7Px5|Ik##H9S zP=*}>f6WDa66)9)YonTL-X0fu&(4s;z_3YylOvIpA%Rt*LO>#emHk7bbccYvMU!HL z0K0;Kas`8Gg@ERcCbb`p{Ds_13mX%Px%&iM_-}~m74R`UaN=3W;IM*$L$JlkL(p}F zfJ=nXV+Mv(3IbLMY<4e9^-OsEr!;37x=cU7$nb$B#)47GfHA>BK+-^fNkJghLm-)h zA)SLk@X>&Z_!O0b!(&=tQP_e8UjU+rB@pW2sa35DwwW5(Up9VIdDNM zlOWT^3Zcy&0ul|3Ob7c!nu5Rg+AIBCFoIDyISL$~4vMy82OniH5UADEn6(Ub6y z$tJkhj-mHbM2}@6%WV#Zs?TgYHt;eOFftVMFbMR%n9=uohsoO)eQ|{yb_)H>oV@}k zg-Uh^vc42>QxM2mU_McSt!n{mwF2{$8H|b(`j{8?y;(6K`J)Sirho)Phk)cnZNrH< zFPOyxC-O{W6#viJ!}O6!NP(wd0VlH{D?K%ZxS^9_0V9*c(y1nV1^6878nYY~Tt`;AT+Z$l;ujXdnOSYFa`F6?i6fTF`YqSN?~Q!f{Yn~0@J_k5NO!Z!t6MW;RBDy zfwIU4TdU%J%3Y zWA;+^GUep1hG{I0bM2GoUVkZa^QJ)m%&AOT-7hi(c)g~EM$TgmG>qCXiQ7w{VI|Wu zP6o3J%#sR|%QJd&Z}KuvWHoY`#(E))iIMy64bJR_U{fLpF zc7v4qf{-H~(@nL+%zsS?p1I(f2E+atQ~3-h_DjxVP+0h0a!O;RKyfBxrpI!>s$RPV zQ&TmV85|a!jGShvDxiLWQ}NPLng4Bbmi_2RiCPw4XspD^VD)O*j3|NG1p@vbroKDi z%%;f4#>jMpfx)VPvq5u}nSnr|Cg0};)4w?gG@n?qMS*+kO}5!u0;_*@S0)HpOkKh5 zIFqH2y|0S#oQH{t)=KY*yzMucFYaK>^_o2U!R%KC0&6n47y{Ueb~?WaV0B$E>$Io9 z>wx7Z3=B)H1e^lawQCCS9pE$hu-3F;7Q+P2=bqfZ6a?;bF|5!uWLD(x%@Ekfx`zGG z3g(R*eOwI3txQg?TH|?e%~=b9+*JailLa=eTF+pxaYZEGvQAEh1q_`E0!x3*3kVS4 zj5g#BU{+vYy5S%Ys<2)-Sl|yAgZB&rmXAEy|5+IhNF}p4GTr{lweA2n!^|aDPi_b= zTre-QSCXN_UttS#A)k%IdKN*`6*Kvm9QkfoZDgLv5$dpN85e`Hx4=#Vff*0BSUs3^ z%5zB+H`6Ufh7fCk+nxd{S$rM0IC~VlnKnihsL4&f9?s6a@`Trxpow#P4FoO*>|p)a zt$Bps#Y*6z*OILZ*6Ss#P7`2t)!HUIo5SS5)>5nGY>qsB-U3g%czGvpV<_mDlFiGy zk)45o=gdxib%r%;AIsF**z(yKu6$kL^V*o3dxy0lH_OCL3IQz3SI*HsJ(u+(OXo@^ zqc8KE0$A=X;6G3)Fk^us!-Y-nPO>rtth>*^a6?;Qs{!k+|6B}i0ZU$Am^njR;8z1* zk%BJ9su19zX;xXSJGeug!|+ZpEAakTu`5D+{qaLa*tMJHdX0&}y5 zfVid6fy})Nv;}4!U~QVU&eUKBg8+ZKB&$`9fYZ+|w*_3RiYu5LIWsDm?%wESI3R2G zW@$b<8><43(XLfSnkF`P4x2vQ%~#dSps{4q{$Gvb54|lz-P{$Lsf^F44KrfvDcW{Z&<*= zD7CVRN7Th~M&rpXQ5J1eyBpso%;MN{VyD;aTaqVP0uQkZu4lTqcc%0vCrKtLgJaUh zyv}!yFim9rv%vg66GO8(v+@DiH97(bQ)e%*JROjD=AmUT)5O!Stps=v8y;M+&n2^8 zrh)gB)L!4Llb@@W$MY~;@)5YP`^>UiXU_W^b5%I2{j>Xk1LtJTH5(Nb95zVh2Pn+? zIn&zb+!mV&S1S5kdp4v+>}0rL@aj}^lE$L1J_65A?O<9sn`6&Bh6l45F08(}dM6X_ zS(*RA3(t9+O}YHb88X= zcE0J+3SgeG!D+_tZR`tq`?)v%RS>wSAYc-`?u^ZZ29FC23744@S>_qciFKH^UR!{L zyObmGwBzLCo_~edcg@Q=HQPTx;Pg#{***f>Cvfg5IKgH({azs3b8Y_E=rb>FU9(h} zAaj^aA$Q%xw`Uj@TywT*zos$m@r28D#sb+6tn)51DmTnA>Y7m9EAlD4wQ}e5wwr8i z0&Ko#3|r2&`RlUB#IPtcvx<5PM83W8ln&r5| zjc*diSPB{CUvIjlDUjX0E|lSBu&#iK0FO(Q^X-=hmnn25@-Th6uv+`)j2)S6*E<-S zHKs94;3?Y>U!K4|_Zo|H!n9pa_n89Mo}ID4q=3uDV~Wd6 zmN~PJ&R}2<%oa#{Fw;qabWf|V6V`k1m|?>{j)Rw`ygnMGvA}2ox2?ljd2WU^0c^Wg zuG{nAqITs(@dcL{1lU|W1wJrrHT!>IWn(Sl>zmA+RgAxCPkWx4#w5r$%}!v=?)&9g zkJ8r(moRK?+`C2iLhHAVt_GX-Zzq;9ZD4GiE6~8nu=WFAuhAE=av?87%u~F!WnkQ{^YKQv;TB2ez!fF;JWaoLc7p&Tg}LaJ^*5=kgc< zYyDn7ud__&_cPx&eigUNpkKJ^ufS@l%~3V{CuJ7c{Qvx~_>1@aFMf&46Z0Iy`@hN` zv<_I(6&Ek8b<$H<;ajr3u>TPTo&%md4y~E?!b>tgYB_%APWWE#|D9tCgSo`_y8quB zW_2sud7Wp|P{^zv%pUWoyn6bZh*8ZQC73>E> z^5@m()EIj4Im+=gsw_V5_^t65pJB!Rg}+w&J9=FRWNGAJHark>{uEoddBU+jA|};k6GgYB2pqH*`1;@dudGUg;X$8! z_Kvsh|E)~@dp-Z(tNs7p-2eCP|Gy9N|3A^;1`>=NAE9gGj?M}tYR5+$>;{sAL#@2> zup3D1+hig?rJS0o8-Hw0Di3g`xsGpCvVGkkcgBqN$M(OtRUrAW(; z;l{%yin@yoJvEmv*|b!{x@wb`?)E1}%e0l9Tu$g6SJ`}KGJ|I0VtwILMhi{Pwiut& zy|2@8uKi!c3DdT|37h@xSH`SoX!+3c>7d8|H!Sb{UB$l&3&pNG@q)2cNoR#n=b_7! z1AWbDcLRy)cMpeC&>bJ(8%W|RpD*1WSN;B|`Td`to^Fq?|Id2kbOXEEj)Z1@H;ac2 zf}uMS+vVFLV%wCLS=^8}lF~oXWo{N0)Mw9TnKH3Cwc_AJe>cn2sjF?ml~mN?EYlJb zr|oSdDr?ksyuCVDA*x~u1 zNlRl^{?WBu2Xth_+GRBN3U9iy@T4f$hu-FG4>+Hnuoutt)eKPRxbWWT(c}fwgx4A` znr3`vUFn5%@l&6hbNKHnMeNevWIsQXJ#LAJsF%Nz*nE>YwiDhkI0Ve!!(sPpQ^t|I z3qIV+`M7{9VB)^tlYZ^~R6Z$8e?|HG^X7sF7Oa|oBLCXO_Wiowj-Ixw`+dBs_}}mE z^H0|PYP@vc`OsvGf1)3h6OB9`aXg*GAa$Y9ZX$!!pK{HP9V;3Y91k&@b}apWLo$Uo z>y+n3y&aAh_Aa!Z5XAA#>e5^%4Mv9U4=3ucm~=HSX>2h+lE_yI+wqYk&}!kLBzCbQ zdiNc{sXJWM2;V?b*ioM_Px5NTB*AqTdpA`l%Q!nRT3(x|D!e6G?&}Ws$!8oCmOoBb zV72sc61y~^U8Rdx2X`a?A;8mj0!}P#~bvzjIT^1LgakF&U>H2tH8xuc+Yu=lZGdA2)TJ>1L2~ z6!J;d>tkq_I3X(_E7+A{;y(|H*V~;4A5WXOiJ0x+?&F1IaGk7C(_5 z(XAP7ridFzT&;p8O}ny0zfq0BMR9^jS8L_O3Quo;t@R9!Nz1&i^kq+~5S6@lWx2iS zH2K;}`2~6(XQmzGOPdlIqI~d*;^!$HKNt#Fmn$t<#W``A)RM@Ft`4ONL82WYg00LM zIxed;|9S`<`M!I#oJ)crNDYI7S__OC&CVQg)Zy!kYc_#$Hm8Ug2jm`3Yl;G z>btg2C{Svd`JW|Hr(%|gz>cW(3PLO?ZU=5nSR%wyWx6V+mm%PqyHU#W$3Go(^^160 z)-0cK>Tpc_e-W0qB26n8G8!G6OxQVZbSTW(vPLA#y{#i*xpjuU>;9e)Qt-*{xstlO+l1&A7N^||5<0g0NsE=|gl}ULI_MgaqO3+Ku$*~D}+pjdWOo7jt_bzF?=90~+(?07Xz>B$ilrz6*!HgUBCG3+>4 zX8q{OC9@~H7#1w9x?26!A>Np;{J;5uZ zeJj&R1BSXa6Yd|hP}-gIpCi{e>4s?3c7=DM9_cTyUl#J#*vIU7xME8)+g>r2oop*V z)JK1L*yM1iR^I2tQMRKK7~alMOiJ@G73~p}h+DE>{^utLJ)NXx0mg0IiuqGNHeb9L zeHGcCP=wu2;Z9ddYQ(naze=j;VIqE@yu5vF!i)_MPC> z8!16$7Ov}7PL$1`TCFT;=C|w3#NOZoppaQCZurYAPo z=cP0X%u`Hn@A$D#GB4_OyNX}>hC7|M0v?6IpEw$0UFyP1n`T5Q?mke(7Mr0gZP#(S z+V=XR-+Xfgb|=2&R5W%}xcD?ed7oOubdDVl<^JdNeyCBnkzC}qVclG%t+fiP;{TQe zePs6Xwmr$YvDRtdn_Dv;+)~(lZ?C&UZmGHKlXrpT9S=n>F|BQ$tf1&`*Yk?+$LY%{ ze~tcko-cVnv0wP7vb;j-ul;OgKc=hv*#Ft~Z*hNQ`fv^Oxj{sjtpZDd-Go?H2Uo_odKKMuAplHv0Mga~k zg@#SSeFDXfK^s}TXB?D%a!~HeL3x%#3L=LTRSqec98z{Uq!MySHRX_6$szTYLmE>K zX)ZaWwdIiZkwZExV)mDuc4h9xVaN6=09@P>!`jm}8vxi~w`Jh;!)N7|Zke{X`7 zxy#JJ4COD2ou^bzu#@1tbkcd@L+c3#4%_q0-l%+J*-r!ON@2Yt&CVr9+;w_+T3i-S zJR-xzfxfKdIe1yg|Ns9P7#Pl+IdkdKrGNkaF)}j#{{5SYiRtUtuYdpkWoBkxwrttM zhYv4YxbWxCpDkOqynp}x?AfzFfByXO<3~kB#fA+V&YwSjXr%#_YZrr$J$&xEqt~`JKeDUJN-@kvasj2z+@#C8}Z#Hk(;HymoI<&_U(iT6JEZ2dHM3?>gwv(uV1sWvTA5(G&MEt-o5+FmoM+$ zy?gxlab;y?RaMpe`SW+|*m3>(^*eX&ym;}Vudna;@#FXJ-=8>fB0D?#^y$+}OH1qP z>w|-XySuwru3XvK+4=P8(?f?2?b@~L^XJd!&Yin?^XA^Yd;R_WMMXuuy}cJKSYTvi zl$x4)@ZdoqA)$bP09#wzgoK3t{{B6C_Dr2Rb=|skw{PFRb?a7hbMw7>_fDKRaqZf* z-rnBE#>QvQp4HXW@$vDMmzT%K#|H)mu3x`?=FFM<_U&7{cJ21<+q1K?Ei5c#Wo46+ zk_rn89UL4cPoCV`+IsTjNhc>K4-b#Fwzi(09vK;#qM{-b6B88`m57Llj*gDGbLWPH zgd`^?=jP^eb90A=hT7ZPXJ%&R<>eI@7stlN`uO;Sg@u`!nMFrO&zm=I&YU^z?d{vP zZJRxNc0)r$R#ujqo7=Q$(@vc_wR-hx7Z(>#PtWx9bUQmccX#&>A3mHpeJ&;@CM6|B zOG}H3iz_WHt)QSlP*Bj)($d%0S6p1&z`#ICN=ipZ$I#Gl%9JUG4+Y$o zN}cNx4#N%-y}T;+b|@nQYu?>Wx|-#ngG4{Sx_f&2`uIlve_V1tJ3t4C3i7S;zT%QJ zUrP?OtYp*E(}J0d0Zj%*t`Yf$;woDVxcyue1v}!-?%MkLy1iub6qjN_29}5kQj0XA z*NEOY(9A9G7o)PN?@&WfL?!29qedAiHoYCfiH(nLY|g%aE;jr9^a8_6{}rwGrhZ;{ zfA{M6^ZRP=xv(wVwg1P_=Ni*LJ%4@w{Qmv_SH1ija<866EaO3=3-5`Gm1Zm39yANM zX*_I+)pZP((z$CmLzc7D@nO3{n}$+=>xv_XVpn{fa=$}o8+ciX#^WB7YZ;GwEkFl} z-flIV7X0y}#*+yyVwq1SdVrRd#H=+8knwQ?Ei1Wq)OBh^+RCTXVvv`WJe!%ZY~{0A zIpAd_$OnlEC|7-Z`Fwr@Vp$2-@`Ob_X0K3|m87kDxol3^tCuLtN>;sEwPqU`%SyB# z8L_bnG;F<7rahBGQNV$jk(h%--%B@fT(7KtWz52(aF7A%Akpxgk4Gia*L*xCQ;s-D zH0RSvjrlQ%DJ4l*dJ6fm%}U&;A=*5dh^&*y9~mX&PMVXwFH@uXt$%BOvCb~2}Hvim9*u?GCJESuM# zm+^Ah;kK$*P3z8CWv|=+Z~2Q&tNp6qHs9;BezWVn-R?V0zxPGGIduDG^~b4#{eR{h z*Vmu<>D=MU-P@!VG#ug>If{WTD71~I>1@&LwY;s9l>r!i9<4P)EyLj5*WT7W)Mr?VaIdD zpNYkiNtGqTUN7chAEUrS#s-1T-;s~{=kTa%UvD=ntP7g+^hh$lx28qmy3JEnebTM( z{?t@BcFEgW3{$^Yk~^%OYb1rEp^Y2aqLa-K8e^DX8Z4a~n29fi0v7-dWp8dMS- zqR(8JX3WaqYw?JIkSJ z25a;Q&0D?arDpI+{{{EnZkQmu)bgRGKxI>4kgMscX%nKFoOUR(FYtBFVEuUImv0lt zfe;5ql?g128V9pkU%32LNI0_Uzt+RmOb*RatOpJ>#5+~F0HARA31GWLL3^5CNK(35J;9(W)zTR zc&5v`z=v-|pxz<@2jLmJm>91uRPdeJ$S5Gtlq)LH$Ij-!RFKeM-=Uz$AF+<7X?x?Z zmkrBrg{HR~+NANe?^H}tTiAI}C+@)3ivLIXYc@N^?O|ZBX_#u|c7Vw!;ki8b5*CgF zEVon^II}OflpU<`C{Oajne=Dh8U0tt>q->1n!lO6jO)T`#%&E-8*ex?XfS*ZaQ&0` zp>4*&B)iY$lHKVa*`}VIs-!<>=@frv9rp7X!HiWud2TmdO<+v8Fiqr@Im-gE1YWBp zjE&qY1KqiwFjPEX4&yCo_S9(PHHp>Zu;RV*tF~d~T)r&LP~PmI*}IQa3!AUHn)52W zKm6$Cdu!%!e|jW-YvRiJSGF<~aNKS*U^G9p?!IKhDh6H-0p8Qkau-`h3Gl}(Wa)}H zz{?}Rt>NR)>-j`?JL88;#sv?icg%gWv)byDQ2*{LN&n@tR$uSUn!B(1-p6UGXV^bI zGQL;+I3lFc(R{*DAqfZWTZ#1Gt;J+f7`9j{yX}R_p7PW->xi}RC;D=%az84-NxJw4CnnLnHUoob6pHH+O0ax zA~`N_RmN0Z7FD?`@yC&&lf&njWUjy(Zim--)*EklpZgS69r0#b{&r2nGdrg*u6-Mu z_518Yz4GvDbNOBiH#6=y(Ck~4%WCfNY!UmV66Gn3BF#%y-R??gP|;C;thb};n&tbi z>nGcMmg2j2)7+=1q&Q;t-1aHA9P3ps28-Tjzxb0$>cJ^_4uu{QW)nB|oWH)3C^ zMcz;iac~uQTB32;z1B6!RVRR5zJcl1XC|2wjUfsG0>X*QvE5LGV6EhPFv$Qz#y=|pt zqGd0R`7IXnnr3Pqs!^o-y+!eOgwFL=?dR&k9*xdH*@f&udL?aoCd^EQtlS$Iq#evy z99^8-nnD7azB>ELg|m9Av2<@M$eYTT*bv7wfhjV;-aLR!rors=Qzq%>6$}4QtBLZc z>@v-Y)F@gXCcb`K!^DWn0F}xXp|+$G%6o+!uc$a=RJ7HzFr;kAe(mBi^FcbJ15@P& z4yFrCkpWD_sVr#&Ai;2expx64TPlOj0`}|zhFgaiIS()~3DmG1 zWL|JAcH)!HoNEp9js(Bj)~f98f5)Tj?$w%RrmlrEloKloGY?CsEO2Xl*z@@*W4xk( zh6026g0?(%Pv$^leuKozj!a4gERq6@2SP&2mW6aX32=A1%@M9;Run(EJZoxc+FbSc zXBw?pZC*E{GyQj+>^aJcuA26~AG8P2byKfVH@}pH+FfL`fmU-u7W2d-?7ZD5x7+q8tCI&Dq zU|?BT!2NYI3vZ<8yE38sC$tzZaIM`iIbf$s(9J1o>O}=7LP&MV7OK56xWGIpxE&S>{2r)^G~1`#FnUX!fR)LR%td|1X@qgLCHU zowE%VP2QI&x=V7-uRyLM=Q$w<&6YlxenL{2TX@>pND;0D24^Ja>IN~m2XJXSF!3vx z-upTCf#keL|1IY|iJbSWa^8!X^K6}&6a%>26=qy}sl?^L%wx>MJ=y5T%=y1|&i`|B z{=c8|8Kf34SuGISY;dZr_@k$?533&IuLvleOXTBLJpk>0OG22zWStQMPSEmGu~FKeYVv1GC7t;Ke~ z7CT5Sak5(C61BvwYKa+ZUdznIdQD6Gek}=*S{h`vG$d+i;Hf1RNlT-4EseRgH15~Z z1gpgnw`L_qElaCfmN9Et*006MS<2bJmK8`XFS1&mc59ib)AEX0%d2)Rui;u;=A~RK zwW7&tMa!<`^-@z?XRYYkwW8;L)Y5h> zQmYnOt!nL^~Z&In=ptRdeb@nF4>P@AKH|bTc*Eub(Z@u}W)aKv+9XDI7UT3yielb^`@6^o> zt2bD`mRocxq&$ql`{-iF-CII@~AHSe`BuK=`CT|8~tv}o@Us}?!aWdK$m?2 zgUkif@aS#HGq*-@ZTz%?UrrJ-o=n$zxV+os{x~mgR$4IU5?Vb<-B)oskUF7 zz~sTb-ShSC{oH$&DDUA_5GaqZZxLYJ*}Z4o>OCr__nbYwa;o*7BPt9n{}c8IJ1{19 z@3maL_o(6S^U=FYc5>}_y?tKxKI86vM;7k8Q0?~P@jh0D-jCY*wY>KqPTc?I^uF)L zdw1U6+5dXK0{4MKj7gJk?R_2XQj*Eg(y%*Qdi(X&2Y62(IQX!om+Rmp6^7#m2bmV^ zPdvR_>d!_Q9vQhaD-?VVlw{hkNZ2Eyu+4kwA*tPmRxPf4u*z-e=~@Gs!(SJ(%2ymR z?>Q{8`tbUThg!V^>~%aVR>XZ<%-Z*GyGG9u{?$iXPap2F67Y}N&D0WC@xtlFRtB~P z*1Maxh4&ogTzz!y!6P#@TJJ_InRB8wevNZ^M!?s_p0BTaX3aU66SF>#$2#Us(PYy_ z(Gt!F|7ZD4tUO+>!4>7;oA-dn>FG8v(G$5gCl)at@8~%(^~Iw3dvxE0@YvVvXA*U?j>2IQ$vq~5=6YP83SegP@ zO%AYSTwrh!U|h?6V#l0yyY`%Jy|a8@%&r4E44DUb7!{^?B-kH%VCs~>>b`+7(12NR z19PXw*~>BOuGUD-(OI<6XUW$&OP2C5SnuaBmBd~z zySujHuY`+kUbXI0kLs)H2F&Uk&T&3qR5A!a_Kj3i414io&yJM@FBquPkZn$~<;Wo7c%&X7dGI)Kf{ow(TvnN)zEZSVV$Yb{| z;S1-!v)_`qV4Ib~B-y}d>u`tjf6ko`U3X6YU2@)cN%^#Rlc}j@7Z~yvFsKVK87yW~ zN?^LfdGEOHy%xr$Pya6QnYvwR0%N)Zvtk3Iq{1a5=9}Mi*Zzo=*zn5qf&`<|21dyX z41pi6s}wMV&v4|gojdm=VkOH{C3?Bo)vHE!_*sXtX_9t z^PafVtsz)M0 zJ=L{(T9x=TYTcrUdE(Lko~qq?TEX}%#qWGlo_OlKXA#xUvKBte`!^$}PAuQ`Nm1_&0)Vcws~)oI^UdJ_a^w@o3roU1Twxg)_WV| z_*Omd?d86=oa^5D9DIBC-CHllci(j1J@$KdEccyfDmxgXg3KU`k(!QtQs-uEBu7(edN`6%rF zu`%bPZR1DD^&c${e$09EQJ(*kht4Mp$4{#HpO$of(p>XN`}`-aH=j)ZGk%uR`E26& z*)adJQRC--t3O+x|NQLrXG6v>j{0Bp9lzYj{^H*MW#8&AdI!JwzW=g~^XmfbufhIb zo3g)ZH-4S4`m5H#uaWP+PT>4jqWvw||65x2x0KFrnd`r)9{iU3{+lx6_f+lgDvsa7 zv%eSjfA?AaUFqQW+V|fT7=L(c|7iCAu`v6GOyiHv^*^Kz{&@cSM?e414cb2?9e+;E z|0&-1^YiMTv(Nw3d;N1h|1VALUt*5G{%8ME>HMX-`q%37zqsH05@P&)Q~S4|bdH+AVb^nUa{4-hi??e2*clQ4s-~O}A z`#-7o|IhXRZ=Cwiz^HJ*p^24O&SgfxL#H-gS-TdAz(+1!qPlTMW&}QV>yx#uV~G?v z;4w+ncb?14pr>BbbYu6mNCrRinPr-L@5s#H=YI2G2Z_#9?3F`0Nc5{h;3|}5CEOve zA~vO-g&ZW>oQQOg=-iWG@1e^|gx1(U(cO131QgDfjC zy>oGG?EW^{+mHWeL6()wUXpWfZ|(oKwb4Hc9v$u7&pI#WXVJ5qe*1R0*k2_x&aRC= zKJTw`>ASmo>$k6s{ZsMj>Fp-aL88A7KD)cW{r~L0HNU>T4ey;F|Nq~~?|=WZ8yuMS zLwSP(^K~HuM^^DU?;Y6XTP7H>sV~`Z=&{lf17}|SO&gr~?R|2c1>IE&wFLZK438f6 zO4;bj6WU_vCV97Lqnq^4*@o`2N!jfC`$~(k-=;fDHv4^ea>Ur5 z^X-$(=efVKm|W=lqq60~o&PMZCKtPSQnv(N5ot9EYLi*I<?{AZR1bL*FF zNMHDyY1a$mb~h=<#nb=kXD+{(WcAAY|NLcDIxE+wt)?Rkq&$w>fvGY18g^51$>AR^I*nm~Q@l%}3S+xBjWgC>`Xl-%@Z?+-XnY zIk9#b#pCM7b&5`NF0%Q2RBwMw@%iv4HlNPB@7HE%bZVbda`m;7?boaE%Rhd(#@)X6 z+lI98J7ssHkIwyYxBmR9^81bI^THl}*0ZZz*!MlU@_B8N+|TFB&udogS$X`P+Uw`% z_WfS8E&q1)$5%aV5KmY$R zc89f`1r01qW-;#G-t$vYAd~Bi9JA~X6OOX{Cco7Q-}Gi|`OlM--^~B!!52G=EdpHy zEwCL*1qdM#Ix+PvKz4ZBhw6is^G-b*R$)g=^Z7T~) za&i_++p-^TK3UjT!ZSnGwEeivtBFN5EHmW)b9mHpUMf7NkfO+YbBD{d?1?=&Pj<_7 z?(py`n$)y<$!@*QlRk^GCpW%cqHe!)dq7|IlqEW;+x;@PhpZ}^T9B=}J&yBqL{#>) z%*hG5i%Y#Xi7sf|B_pPPnawAIb8^m+m}!Q`+k8?rFK3@onP$A3?QDYA|I4$Cf*j1Y z?)1&mdNAugOS;8TOTVINm*+fpNw>PX)30pX<+<-$(runv`d3}MJn#FFbi1!R{p-G6 zp8uaE!-3T*pb2!4s4Hk$$%Tmt3`_za9DcDWF^M=NFq=F)z#X@NY0?=6CI*4Vm(RWn ziSB9OQJ*N|9BQS@&Edcx=@HM!RKPert3gdzpn=iNL5PWifq_q8rAN#qc1E2?p8G{! zc}M)x3@0N<)43zKBeH#jtYQ)ujbfv%}1vPV(Yd!2iD_ zHpg?)tMF4*T&#Mg+FqBVZZIE7VdAdP_OG?NK5^F(ex?h|DXv;KcZFTsI`vnBH}mS7 zE4UUgvj#NySaUP*hbVGb894F0&3(E`v$}cf3J^H){cNTtI?C!d!={-tMdFnhd&>+t?iXqK9CfL%4hiL*|i%l*lewG0AH{`DJgH8wafa4$H>%+L_b;!~-T zW5B?mvSDSU$rKf%r3^AG2bh>9xG?51IPeBNN;2Dh^Ga-&E)&lN24)EcMm)yQDez%h}n#Y29=S%wb_SeZ1O zJh>Pd)YeSf8uj(t%A>wZm;E~+;Hq&*qKko5!(t(a(FYc#kX)8{IRHkPAxBZEB&V7u%2wi!I!r?oM$_1Tvpx0AdtW`>BIuoc?w&yjP1T? zJ)QBGd!6nH^9`>iuDHHjZ6;&8yU_=tw4*mAO1_4fXfP|^)vINNcXvSkBviNme@ z#dkltWN9*8`?ut5U5$!i#8-BUf?`)@hl?T)b~`Y9DA%6N$1;&`WtRMbPG9xNBP?={ zAE)kL{O(Z521bQ7x$d9-H`sD45a>=d=1lOLB+zrMB&g#H1ION#Y8(#S_ubyTS!%ze z*IVSf9;+oojbek&kq6J@8JOhUCNWI^cDLl{^7SVeKQupOZ{XG2x;swUy7pIi#=qsp zo?kas*WT?<;h5OQ%ymJV$z#2`#QsmWMZPGnHI(R7xUia|fc0H<^W6^&><=ub?Arh9 z@&UG$tM_hVU=V0HIeG4#({>CDO%q=*InH1d&S+5IVW4|q_oq)Q_epcIif9V|U=~nm zRqSApzQAC`;K-rDA;iGU=+N3xEYEcNfa;#fd~Xi$^BkNaq5n_&AiD;$K#A3Kr4~5_ z4wWU2O~(7wUp77~-u0zxH~Wl33>{6$bGi=YpLS4daejAWwfY%N!7ut-e;G4Ktmk{t z{H186Z9(JnSBK^>F+Pgkw&qiVpa;ux;SJ3d4GsbgLN9F0dk%a3>HB@yrF(HFM?kZ& zLesg&tEXEq2wF5NcW7MQbueY4%PtO-btjJ*B3Ra;t~>et`}d_wm)^gB|MBC;2M->6 z`t*sBk@4%-uW#PGdH($Q%a z_3PIkKYsk@&!1nvetrM`{nV*b=gysLZf=GwdU*Z%_2tW#pFVwh=gyt0SFe8g@`Z_s z>E_Lw%a$!Wbm-8%d-pC}xbXJv+h@<7{r&rQ;>3w3Po6w_^eAL`%ID9YtE;Qw%S!zH z{deu!B`PY)$H#Z##EILtZ#y|TH8wW(^z@XJl*q`)tX{p^&d$!<+&m>E1-{0@(b4hB zl`Hq}-)ClKzIN@}mMvS(o;}OL!UA79bKt;%Teog)+_-V^;>E{~9b2+wNli@+@`9KN z6DB}bz)YV$9kK{!!GZ;lPl`fFQEAaI$d-v|GtE($2Dk?887Xq(n ziI0!BwY3cl3`|H!SigRKe}6ynB9%RR_I&v80kYEN%;|F`CMMb0*(%_bC}@jUIyyRf zdwbj3+9pq)Ja_Kg*49?Y@)7t_m6(_q$WjulYgTe{a(sMz1O)}Lu3VWmZ5m|p3S{PyhY@AF@1UFfBDfaSQwZ28O2Qme#iRj?S*`p5DIx z2@@wxo-%dX^ck&;EsV1n<}O&cXz`Mz%a*TLxoY*Awd>Yz*tlu)maW^i@7TF(_qLh) z_8&NS=Z<>+A1-{~4IM_J}7hIM~b~tQB)&!@|Su0?J-ct$Qhcb?4;gi2d^*>s~Z$k&jbBS@!}vPG#Ggn=|asuZlgr?d_GOy#JsZ zbj#IScU63Tb=Ufn9{4;JzZqqqg)hR>Kd;`g@$vBq3q|{Uc5Zrlx=$?`bc1g4*?G?0 zaw|0`@`}+r)Cm+$>v*Y9AmWkT&=l&>s ze0E{6w>W$GuCK3e?EiW0+}_>a)2{CCmiNDR{qv_6m#5#Km)HF3`v=zf>E`zP{{9Yl zJ%4iJ{{8jqe*IN{(6Fl2{XrwgwPSHjJZ2uV8u>u$UPQv67wCeHQvt7gdDNjYE#pzA z#xn2)x|r);K*y={8|ZO7nc%WcIANlPTBq-STX!wcc`BQ(rohfqA$sA<^LaIB3tyl& z=#sMV1skiiD`sYHlG$)_)4N#h zbs+{Ek6N~i>IA&q@y2XvqXHAh!?i37Yi_^W>&>~Lg^{r!Kz|>DwrT?hXNvTPgSwgu zP1`Rkz1a}JtU9U~vEk~`~nDKGyMbmR|T_WDx> z^F;~|{@W+>`K(f5i~-~6M{hoRa2XippSKr(JCRB3j)Lw*H}km@8N?Qx-f}raUF4`@ zxcfo|e(o=~9j_)Rt2ij?vTSJ7m|yUr^hOT5NE2%_&%`x~m$v18w{r~%IILi=!f=4W zUC(A4gTetO?muk?9YPEq7aAB3 zcsnpK9uBuZ$0En`pplcI#=wJ%m*s=Q|IaKrNgKYtU=MCmkP<0q;u4q;;K<;?+~b${uA@y73n#^z%j#tS>gi&n}P!KsZWgxA{Uq$ z6#5z!rW|9Gc)-B6B9DOvlhOid0<3?lC;xfjGqf6wS)l~}+i?7+b0_2Gcrr;ig3Tij%n zJK*uclYim_5jMtx8;z_U{{0irsHmA4+A_`Q{ogUm=jP8D}y zJI*ZCD?fQU?$@X32Y8klw0oXOlKMR3gwHag=_k*mS$&>)p=X)Na?i6_QJ-hsIJ3-b z`^mF;Ri9@+;8_m7L3h^YIrwhSJzw|h^Lz&06%OoP7n-ELEa326;Us?QLYvi>g#x`R zAQ$L{KwK?hDw{PA0wr$7RwRz>IZ{Pd%Z9Dt|-S0b2_^vCOe)`TctM5B6^sXye?tS-F z)OW}Qx~K2HtNOnC0q^>XC-1BCMITP zW-cx+0|SGwu&}JGtel)2Ha51@)YLO)&Nw(YBqt~L^z@{qrKO~#{QLLs)TvYN-o4ws zd-weL^LOpqB_}7hY}vB2XV0ELfBwab7b{k*m_B{_#EBDwgM&LeJN^Cr>+0%^jEsbY zgif3|(cIj;cI{foir7a@3XVBV`5@LLqj7XBIeAQlb)VFYt}3U1%)3!eth}zc*Y}vBq#*G^fA3lUMGrxcTe)Q;3NCWf0fdfmHEP3?k(Z-D%YieqK z{ra_e^X3N+9mT)A@P(xppRuU>_$#GWu=!pDyvA#Km<>gwmupEor%!5f~}!Hcdh zU%tF!#|}u_^Y!c3-QZQ$eSLj<_wGG@{P?wN*A^^T5D*X`Dk=(JM}70=&Bu=)@7c5G z;K74ar%t_f>(>4I_t&jkcj(Ze+qZ8&efqS#yxiN{J3c<1kB<+z$q8Rjeed4Aef#$H z_V#YyzP+)rv8}D`+&NG~H8(f6sHjLrMuwZ4TSY|$d4aT(lM{S(^s{HrR!h-HG9t7dGn{sEWp|1T(D>lIZe*bU%rByoWKA41vfcmJT_3)y$r z4qPGv8)6&2zkhJJTi$=)o}ZszTm~(*-uwIehsUSq`|scP_xF#_uh+*X9Q^vfD4BH|&*jXhWE(+ifF?`%}`>upYxz)BA z$^CX8Ii8f-^X;5G!EIMq%Ku3giYK3BdD}%!o*cADEOn|;U}tJ(c;3%R)8e|WrOwc4 z^n8|nk9A4|lfKUaW<`l94oys&b3D6dmKC+B+uhC$Z{}`VGl8L;NnwJzMzvg5?2+|Ny-0$Uu>Kuae7VSe!eGfHn;nDuT8jiY4Y2x zO*yA?x@+No3-*%h8;*#F>x3PDX!E8}NumEu=*jyj zIYnFdtdqHM?C*gyg{SrYtA4gK7w#!K8}W3``E!X(XNyBm{!;!j&7EI&>iL>WF~yg> zoLRq`+7?XLJRj_SH{{yYGY{^vdKItT8kFS!xuION02k@eQY3Ct{dw`H``%CIwoj@0!f@K}Z}{2x`Mh6lEk08FeM1eu-G9$V{pY=YK5K5N`?X@t zc{}%;`}unrrkp+>`sbT@bNxU2LInoVKg#YKDg+L!;aJFE$8fOI>x%-j1=-bdSSQw?4F4oLR_Mo-vP=C%ZM`neF=6ThOyu=DEjlt6LxYD$XpH`+nlM-LH@R4LnN}*ga1;Nqw5o;j=_Z{NxEY zt4|Xr^ej z=jrHYpQgWl@l>IO^Gwpb<{4YxEYmO%8qg06qi|z|Y@m-xQT2mGZtZi|Ym%7+xm$XP^>k2pF#*009Ult$kQDd0mc_~G% zX@-KYrqY*{91~Z4S=#dBxrg^EpBcAGmhBPA^eprWuD(~Y`1}@C|KeMh=kF7lxou6l zN%gDX#Ze+lZDd~sWWTyHWzm!+!C}2w!K-y|#qU&2-vtxySU*2xCZDUKV zPKuy*WGxF5a#QOSLj;Q&Qd5hOk@4TZe@skFkT%!fzkgFxQ|;~TPn(;Fc3=Fihvs<-l)w_4^3=9moxVVy%k|0g3_wV1Y zSg``qKAJv#dS_>6U0t1!kWh1TGrVmDX;}62^h}vD<gEbR5`*DF`9L~cW6Wo7yM`x_Y*qi z{LQQM^mMcq)~s2x&>C3{4GoZX7Nn7d+`@v7nd<212nq@+C@2iYMi!(M$oAi%p}<2& zs{h22qLVpR^DnF@@md?T{>GZJ({HWhR)uxUP`qfeY+cpayxsRd?5OcufBXH9J$2{b z|Nh_5*c8mn)W)ajq%O_c%GwMc6@)g?qD|!#xR_ZvIeWQeg#;F$j0!qyFfq3p>_Hk8 z^pt6nIR_sV+{tr*=gvdusNhM)*RP!f+63Obgf-DT-+W?VGW+#b8rnpQdZjMl;M@uw z6?AQ6(t(Z&UcMp8DZwb>^gQ3+OS|j$yIlb_(T;G6>TzUVSkS=0DxvZt?%bYAtH*6-M+AbB+7>#U z+njyhPxnx>sEErJ<_V3hth|CdR>z;OoAL15hsUSeMGt&@{PV}>*UOK5`1kKW1Dl0= z{a?3wcsh+yeq0`)%MzI|&Fc?))U z`Rmm3`tKP@fIBJ$FfEnD8ceQg+ZYr%pA%a<=ddgf6; zK){kEOaA@;@8#w7_22)(!a^=CF0-gRpFe+|Idf)iZff+eE9I3IdkkHj-Ne!zNe?>>({R(B_*p?tuhb4;p5}8 zcJ0~^fB$bf@qfaE3674A#t}D-qVDe4vBNQHmx6+VebhmBclV7OHzp<~zJK#JBO{}; zv-9uYzm}1w%p>jvMRnEJ*Bcudx3{-@MXqp+*t>7vzNo0EhK2^S=$k@9LUwj`$;rtp z5B$%{%JPYtJ8|Mf$H>iPWo0MNo{Ni%)790z_u{{CoC`EBnnUVDG%(cdY{e*OIUtF^Ut z-qLgHw%>AyJvVFCtQ&9t+uGW?xVR`QE1x}m=Jo3@j?w%2W?t}(Tl@Ci2jl3w%Xa)Z zcKyFa%)OA<+Q67@DJd!6$f*?_H!IsuTzdXLuKZ?R<&mT3f4}au^vxfh@R??3i3E5B>ch5xBVtKWV8fB5+AbvvIIRV|x3=fuf-|EngxdH4R?s`Y2P z=6*=8IQRP1>-TS8zkm0xtz#bHjkbagi<*<|wEk>Zw)o^^4NX0U0EMNer%TwkR2U10 zLyDG@D7`;sdj@Rn{Pj)9~}# zx39aqja!ECLQ_kU4nt$lCxIVN-nlX{T$18@)wEy=xMTs(H_SLcO?3x*%K^7e7ojaI z3ez2D+Zi%wOo>e7Y&;b8cnNa@gTPIA=TBy>$r1-GMMiTj;k6=viw;U1O_+Iq3g6#n z&t9^uHn(YHV32z7;BfbUQ17pDp%z1cLXeOZD_=9?8jlL6#9RAL@_QX$5wZK&Yiq@A z6N>oXiVHRfD|Sq1Wam>kTnXN2D-tFlr^eRH=%A4u!^9xS!5bvNxJJ;0jbXJ)%Y274 zks}M7LPH)ZF|0bv(7?_avxLE)dy9l%v0}~C0B;5h#)e)V4-toCX33TE3@9#FjE6H)re!{xnepg~I0uJ?=QM{Y9c~XC&MAZ>X)_gWm>|a1 zYA|62Z>2(lV@^S0kO+6ts9n2kARyep#ah%|hEiO&5Er%WYl#aC&ZsK?% z>A28t%HniS1_w`Pj}M6x1({U^m%0{J9Ao9gYFnrKtIPPWg za(3mmphffK1YMRmT-D2V;pX{yVU2^jl1T14$VS`KTZ0N27KF{693}SUy~Ej4ju!;k zV=LKbF!?T&W3qhE9k^HeW7Gr*mZRdX8$}dXsh;IGO%h;i{KM5C#V|qb*m}+w#lTL1 zyWC41(n}Pj7V%mZN?&4Abu3yb&?xiqT1@%duh%tSzH#2q+-P(`h{46`!qy`Ld|Qv@|{r96088+dlYBR);uhI!#qS5`WR*<=e8 zafU9~8kacSkI}dIX7L3X#<0p!jaPfTwJlf6WM1(Z)tnndBvS^_05%E*KSalr1$T~lj-rV z7ced4Z{Tio^1pghTCU}OGVj;Dfe+MI?!R1WVQj+W!c#TX#ie;$|0kP=g7t3!0^U{IV|C(+cRSUg+KZQh87$v zIgA=wU#wH_ifrYv`7lfJ!V`s6Mjn&?^BvNdQo+EWDRbhk)+8H+6&soYdKQT+uaFez z$>r_65dU4E$!zmU0fu@_kN0xR zPwbF>OG<)Lt7gZo6&@!*y+3=!dCnKM9nlq1VNJG~adAhwAh(K}!iAZ$pEZaJ3S@LC zb=;6~7INe`BB8}S_tLBf3<6#~8y5D9Hy%=84dQsH%F-{d#B?HLrHu=CzTsKS4ppC4 zQRsX_=CT$;$b7@plU;XI4yA9K1D$UWR$J)eP_xhTT+yu0bJPk&3L3(uyF5sbWA>b> z`e3KU_61yXf1Fuv_g(Y9VAZ3R=@J)}?AbvR4ka4(GrWK3EYfZK@~EG^7c}7zcvqt# zLBq3w@m=J_zN#;a74DuDn8PV%)%InHhVM!*Wux8RyYiPB^se+t_qsgm)|X}XdlI?N zZx;IX5HjJwy~uLbhKC%cGOL27pSrTl>g&pY-c=#Xy{@i`GIjc~dsWzW`pq}EX7X1} zxOLLbUE$LWHro}Bw{QIqQf4A{!r_VAW9c=yxhZ!i@)p`Ci%#Hp&n%bF!+s`d&kNu6 zRo747`?l-*UOW>HJ@-QnICI`AT_g1AU`K{UgRD|VdyB6Fe7?c_%tJoh^9^nrnYT^s zDp9aF*duye?bCu5n+HE;-Y{UboHF6AymFcFu?HWoiDafs`O?55t57tV|2DJ78K;vA zU*Df%`ss;=c;)G)w?%UM=4elpU=*DFhl9<6ks(q+;Qtx%mz$x ziQVGR#B+shpXM;~Mp!@onaJI6P*5srf|Y=ja*^8S#b343JfCNYb{;sYqi>nn?Xv4~ z?cWkdiw5tg+7{-G%%!d_YhUfzRHeY7Q95hW%~!2^c3mqI-LiyJAvX|f zYtYCRt$4uhTXcJ_eQLMf&2wqmn-|;KWdujB-E}W={ra<}*~P!t+|=_}v;Xg#g2}Vj zK5P5B?fhGV{LR*D4#<7qz4zI>%6ikgOp-^W4H_6FR~%r~;@EM3Rj;{sZVDsEeV#+A zlRjjqI7%)e7eyk#ZRBsx|iNyNw89ze@=O|`iVCzfj=1{-hB;~-}^S4b@vTn=Wl-( z{&gr9@3?i7ue`Hl?|YxAzollyl{cPw_#s%FTS%^s%K zrDb5fa{8W!J2V{jm#2Jco1Xf9Ip={F(NPl)XICmNoX*Hr;-z|m`N79E`F~~N-nVeA zP+;bqF-cf$eZ#bM4?q0gsm2x(P_zG^><2GVn}_TSr3@?XF!>qS9t!{XkzXN(U96(_ zzp%}LkIS`>e=*TwJYj0kpnHb##jWG6Tn>Ci-?QbPu2}EMedB%Mckv}GVjmoW9R;?i z>x3>SmVeG@7*edJED&tKAYCA^<3pjKx&Z40=BM8a`I7`5Z?9usAj0~g(6xn;ful&w zfOThk_<8nP=h7061_tg86-j{=+rJm8CsdtkWK{Z5%N)Su$Izgcl?O8Lgp+WG0-H8Nk-n+` z+k}oc|EDu+FJP3qz$zNRWbnY4VM9yoj@Ez(Cf15@?GsH7qWK0l3jEw_SrggPCE5%* z7=jZ#jaD$*b~JJ+G#77Rm7mVUvAsfaL7~QtuDuov+6EQ#)x~~?GpTG8$}V6M3usw- zy&%~_;CKXU=0>*A1$Dd{0uDQvjDiHD3|yE3J5(ny+X**mUudi2=n%5#U^-Y^@j~sf zc-@xmT%8$=p$bB)Coo9`6f-|ilf2NQVIgqPqG!stvPB%BOERjK-(Xr6&S>pXRLsC^ z@PNr^N4=ytv)XnxrwFF^;?1wNv!2>mA(qjc)L1EboykZ;z{7ya{JQ;x6@_BOlh{7C zWm^cmVrN$WU*I@{h2d<3&guk4g9nUP4cT9rGu-^q-WVYuY{4+GnCZ>*rs4_Ro(mh< z80*fyP!Y~xREQK{JkY0=F@gPM2xn%Oe|psph6ZzwB8drwbGI{WTEVz$#w2+`W~l%s z^9~lS19d?X&9g7IsLq@yx`1Jtd8<|=!>jhrl*WRKGb9>Urg9Y&+c~#r3rM*t3AhCn z`z>l_PAFgsWZgHT&(l-DThfwq0fTjtfObJg(4+?TjcjK#7_FX8kP2|&t7v0=nVOgx z>V936D{`8KIa9+6zuJuqH6BJB>~l6}mUix7G(5p@XhsF|!kI^#>bN#Da4x8mWzp^8 zoXj(kL2~-sX)}6R|1a!c#mEplp_R>u{Z09lR~1r{;+9;AY+?c(ehUhpW(xc^XW0L# zT_;7r>PPE3wrM+eh7@ftIOo{hGo$e4cA?b=>X!ekEw!u&dEQ>SQpVkcf!VykG@X&N zpuXm&`058NOJ7!79;mzdv$ES$px=Cv-UMa?1BR88TjD%TI~AC%S{nsB1mkpBkr|9DB|H9m&SnZ^oZxAB_QbL*uA(`X z;bB!vjY1csHZEZL$e8Y-5WRpgpnOhjMO}jtQ=~e3oZffZ3Iu|MkWEN8T9 zF3?q26MLzPwPa8>U{_jcb1!r4t(^?rD;cE9H?nTrSP>KD{mcn$ z1+#V?I62X?L%#oHUC6A0Zq056FM-di=l@MosS#HzR$ykFAlCU{kyt{3Uc&O5Kl%;1 z*9BClmSi$soi1^8)h3Apb<7?!@ABmJQz zd^6k1pN*S^52!LUNC_1F`N0^viA(eWqve5Cl{srH8yJ;dF?DKm|M{;iFmpGP(;l|f z6Bs*Rbn<;F{Qqg6$>)8V9AVmL4#}sk;@CdHXpK$f%~t6XTOupmVqYvbe_s2prJ!>H z8;U7VPQfVNl(`Dcc?rgltk@Tm@_rVsyj3rmuwZwDO33d;kvEtm zsw+F6%Y^!zwVc3sealML!ma8b7X58xw3*VXy+F$FLi734XQU1kEB`JOP!%#fFsbbS z3r4LEf=`}bn$~$%KAg#F1J{lVJs&LD58NzNo}je8-2hy^r;q}|-KHYnw;0OtXQh!ut3xfpi6 zUAX(M6x)TBmj46R>26qf`j1d%1ku!v?md>T_co-@S{i#ybip>cU($vTm^2NTbPJe5s)TneV31$H zto(sd(&1){=>wK?{%mrO_Ax$Endh%u_h@(GBdt0=&3lh_9DHQp=VxU1xG?as**RZ} zd5?29KDN>GwfpxtLGX#wIUkp}C$5E0JoR27#(0;3V`2frj5>yi1utjb zdpYml%LQ_;7TLX868CCZ-K!PzUai{qYR$b@>;ApkAoqHc-RmuJuea5`UKhs|@$H4s zQx?7tye}H~elai}iFt_~-#YMg&pCf>0rpP;EW8)qz5Dm>gWUU1cJIH$z5iDC{>QxczxKWV zbMO7XfA1OOKQP&UV2S_0R{w!x{s+!@mgjbXVgYQi588qcFo?u|6s!LzG5@2~{*N;E zKg#|8s38AI$^Mf{{3o^gPa5+-Y3=`{bN`dx|4#<{KPmrTaGF;?uuyrny{nv>3U!&~5ZeZZ% ziv7%9`uX^R&o=Tb(e>Xl=6}oD|1IbKx4i$~3go{R*?)=s|1}{#;84To_ymr>2H#Q6 zZ~y<30@YoOJEjF;9x8G z#W;b1F@SOM{-2B&eyx-Ly~+OfmiXTx`QI1p_wUQ+;7s87H-SM)lz}yY;h_BY4g6nO z6MmoC|L4s8KePIO@0{=7_n!Yx0*6_`tdsM9t=Ip4^8ft5{`G&($^Uy~|L;ltw+r%r zUp)EY5Wt=k!0z(lpGyF{b-;;&dGbM%%Sc zb0ovwAU4`=%Zj)mVrVWgVqQC-7Lu(3e2ob79X4zD(M{Pe9G~QM}%2O z;vy#-w~vA==lSG~uHx}68&`jMw0NVNbp8>;ON!Y#4r#uTPGPYyKfWMO;I#BF2{q~ zEf+Q{Ja%9uuWvNtQ9(Y71rB`7&6gb3$)Wtn%1psceR}t>7g)}iq&g+W zCgNRlT#=VjGfNlC&fM+y-$kTMdA@9S-tN*6$%PCTPjIsFBzBaxv)tuf(4`_!&~jk@ z)2yZ3dGco%I9N0ioSk_Wh-tBQuMY@ZAY!5LfTNuIfXea+qlD`HF$>rP@~+3X-*w&j ze%ao#+xgdZ-Z$&`D74I3qfx-3kaprgEc3K%M!}sS76KVe1rl6oTX}b^7I>R*;7)^P z!7JAlEJhtgZT30`3>cPi%ur%jV;E4)ec^k+f|oa*FW+C6p?t`;{_pqa_jT^_dQD_J zHbHn%;@fJ8j0;6UCM~{O8(hvgPjj#eS>P=2fbTaa!#55E&i@NfC?4%#(176w+0~@eGN7#MxH|- z+66isLs@m?T1(m3%uq%0brSZEeXE4jYGt%LE^8b;gp@lNjq6bTB z=L+=|<)m61_1qtR?h-bFU|A?)!Nj=9VuCZLL1#zZiPehOs#dxgtMQqwQgcIQ&_}h zvUZ9{!6(IKK8t$Yco|$ncZTfy_SMF>H!FeFI%4vl029#-O@dcaTZGRXbo?)>a6@ua z7o&IRgQdw+xo@7)5}3_(g~8zfr{a}m4BnazS-WfkV&8iSC?6M-lqhP4iBjp=M0#>?mW%ef521BM1fg6B7xIq#REfThil9~CvVOW^^p8v zw3^|BLgtbOj$8r98{D6y@UR&ja8?i8!+&(yR_}_nIZv(QZ(b1F{{5(ah$2&~Z=s`l z!%1$mpNIJuCmGSXtVxiY^pDASn@7~k@0}RVy06K419kUGI5`B)c9Z| z9#k-cGw8$l)*6N;jSbVSvu&6eO%i2)UAu9tV`F|@>7L}`ch~n@G8Sm`D70HGdEk7@ z@_!stP(z2%a~9#e35^m02UtZn1QsbsH1asQFzVPH=lb`zxxH!AlYjz8y%>!nJPIMQ zJ_U+gYmHVFC;7As-o0_I{F+x^<(_oA&jL#ELcI+36c%Ym~bfkC*pu!mDC z?;}@|+cTc0hk3gW%J@B5pf@FfTQfqsnJ-AwTQEa`?SR6((7msgzu0+xecRW!3Ww&$ zz0G#rE7aR45oYIhJk5pC#+nv-kXwMUk>%kN_k(H_WP4*%PifC&czvb&;EPWc+Drb>iX?lH;DSMun8C0GM{l_|G{+`Dg^_6Gh&lOEO9rH|2-||T5zO2shJJ0Ro{be3C zd}NV1{6bs4@{;4eqGjv%JT={3d1a~H*BS5cyefNVd133m(t8|#C9Z8aW|&Y|x@r1e z*9{WY3@ztMw{4&67RSEZ^g>?QuIsYq#o^U5clMR<6ISPA?x?==H#2q-%fS!r?lq4@ z_g5S=ec|RudDm(zHPt%_kDZ)pQrZq zzpmf^_maIuQ!0Sv`S<(((;MwP3RtZpTGUpwFxwnZ%V1(mIKWnNfL)}4d%^+EB?q{+ z9N<23fal5qo|XfAUk>oI925{aD5!E!$mF1~%R!NlgQ6)1#Yzr}w;Yt1a!_CiV~7Xy zzu)_1t~kzUuoJ3a)X!j&TF}T6azIUhN%2E7==}DWL%b!2xKbRrdJb`Zao{X*;GT0x z^2#CICx`UD9MWewY#?&jaEhbI21l7Y2Tekp|4-&{uwZafRB>VzVNgjqWaV>6{m5bN z8BW?g4q9&K5-WNanw?z$?l4C;F+UAPh8?u=E!m!{9^TH)38dFZL+Hz|35ij-<&lyino$78bxWJ|= zaC&1%liUl&jW(w<7+Asu4oUKy3_8KA8qns;z!Kuow&M?*!-Lj&CZ3@U-aGHKFngTh z);O`o2D~EzKPDdrQM0T{4Yj_vGU@+G? z$rr=2;|=4vHw>-|7!So9JJNFY#+0+JF=vi#@m(OzaAHbFPDL9Z1Iz#S!Ytu8PR=tq zlvLtn>%zEH#%Zcx4=zkmKM#=j`{E^FMM9-r95a*PI=9dVClX*gO<`?F-KK540x%mwDP=U%^Q5pQ62@MsNTXj#H@{(8&-9^Lb2Q(CUF_%qcye4lb&Q1zlvtHZA? z=S7a1{h8A7x5PQLA<%k5^R^O)Zz2qzSPrJiobP8j%Jw$E^+%(80c-e-Q*1uR?J}CU zf1D^WIWNz8o|)xBfyqV9r9nSk0!5ErvP%y9`@~PFqtK>ZyI|Mwi>$z>8b(PDF= zImv-taDh*8Lp#?}M(Y>N@*3?MRJ;o$+EWC)ODY<~XS8i9xgfryb%zg|Lja5Z4@Qm) zp_|_{+WcTk7GUWz@h@j+-)Q2^-qGe4z{2$8N`dHgzf_L^)9bdkFG;<)6jbWV9&&Y4 z4!bHtgK0;*je$4A2G-<`mL*@BvO7-8F)-vDVB0Lxn!*qf>(S~_!J2f`&(Y$V+zr;? z6UYA-{kUGSftCFQqsoiMtQo8!KNvr6X?1zQC~VN!d7w4p1>3fovxTWQr%iSDx4k|? zcFmn5?P9Uv!J!9IYr-2$8A}D&g$&wC4zP6wuzLuw7%X7TQ3$K@Xk~9;D-LL?n848z z8qxNarG4x5j#|dN53M^w+S3&p{TkQ;HBKiK}Fk}khUEn04Q-p&uq}3tX5eV&T;Oft&{~+l z-g%?#{gT`NcYnQm-}cC!ySE?SUBURH<Y3L4JI zwC_l1&spGYuz^|M;nt2LtSzi9=l7oDI}oLMgH_0)p;{uU*rV0&LtLCfd$vbgiNUS# z4cFxg+I>GBoia7*4H;DPG{7B%OGs`uFDsV4qtnZ??mwV{=3TLSky_GhK{ z)`x~k{Wu|hfsMhSQL2KWM8mr>qwS)~fhS*>ssoxnF7^KW_JW5+*w@tiK@vB@zWRhW zFo!d=L{>E9RWzR8+RDih*0qE&`~rK$S4U>K0M@og8rPiI${uLlQ|4ILaQ6<&{Xb`! z1y~#{7`&GAJo6%Zhlc0I+iEo^v*0x9f z_Y^tKozJOY$dzGDjA==p;{05 zg{zOH;^O;b+p`2tPhxGT2xyDu@OvMdqPn6rZO0S&jwkX9p0K@O@Tp7k`}QoK&(WXl zY2iKjzu|2(%Uk+;#Qy{h#G_DsTgH&bI4WH`18dp7%a`!6%Yl#FlycXUpTM z9a0YIVh(Ln+}g^H9VuTICbh%GG>l1jL27;I{S#mBS$<=>@a6fZvyW}tBEHzBG`(X< zZeWjH(N+=B&}+&T((od4-LpUm*6w>ZdfvTQz3){&-^;b@W=}llKiSP|N?7KEJuYGi zPeWE*OPumj(5$su;B@9YhPa4_if?YoF{I5GOIvWSHFq6L?;pmH3dWEJtZ@x&OV2i^ zRWSVRec^5QH2Q4X>SM1?{7YN=?A0kV$@O|K)z-Brow+bgFM7+iG`2bEv&`6v654m% zVGAx`jd5v|-_h3iHdFFl1GB*0TtBwdfVRvT9{*EzG`I$^R3BhdDPT{&(Y~YQmAFK! z@{+9FV<{)g@_d)&oSv4KeK6Yu`TM>x_hw|4IVqZRe!YQH8ckXurfxpZ;(k$4tVp}FHcdT_4v8tKDF;y z_uqao?;U&i6bpq+h6(K^2Tsn`VeR_!ZXQp5phSLDA4}1S?3^EM(HiaL0a5HTqHMyL z*pEgrt$QCH5GCxWe&{ zn$S7pj9dhBMkv$PkQQEk|BrF4oE_P5GuV1q88+M8DZA17UsV78j*@^7fmn|YmbeB6 z;TfMYu7*VmwD0IkW3oS_7~Z7x|L8r}PxkABRMS5>ZlB1=;H~P>V&U$c;p?3mdo}EB z%hi9bA`Hx%j<%h6+8X$vwa}yaj;(j#hntlaH(GkrQaxIk16ri~+WZ=rtqWK)7}%@l zc2wM8Ev!hC)Ne@&{j&SiU5RhdZi&Nv`LA@!Hp+gGK+}Bj$u}Y3{5K zQ^H&iT%PN4{0U35ctLQSg@Y6WvqeWsZAU}l3$`QymJ4e>wX`zdJ{n^k&?+Cm5;CJq ze?nlPJbQ*id(r~7WCPYDg-aG&%Pay~=DuML4Y*{{+T0mdkW~KTzmREJ%Jhn_2i&vY zedZQ$o1u4s&*o4`jGO+Cqk$KgQ!Cm_Gs?pmf($I!%L15k8rmZx-Znqa=X}E)ZCfF^ zm6>q`i=t{<-i3UHsez0FhhkmW;%$Be#9U~r|FLxX*^c=?mb3SDEq^?34};>8i%(1f zUWhQ+eyJ$1af;jU)W(24>jj(hH>RiwY#VbLLKN8ZES#9#f4EKvtPW@0`JQ>{nwGA6 zo^c^D^^44*KCM!fWgEB^`FdAw5MZ?)J3k6xRK-YZpwEGG|^pZc$2^XG2+ zk0bGa?ysL1rNZdFrAATUgy@pSbKz}=Q%e|DuvQe*WWRgH?dx8@CGg(yf75i`m$UzS zx149DOkK>I6OYp!4PLZl%wR8Akx-D)p6ig)zqE=&$4B7ozhCm#-+r%sf4%-I!~YtY zqyO1CL^N0gbTU3DI5n9ZI3QT^;2~oYdw}LIM`guhJyPaHZ(e*N0oU~(^y+ieg+ufOXj ztYq%`?@;w{sprxoUBZWR-~2Fqa$=Ht@VYq@T770Unis!&^V9gng+=a@)vRtbuD`M> z{P&~>zf9lU*pz;GUG8tQcXxJ`e}4D&xA}($huVep^ZrfycC{*=Bu|u)TLa9@AR)tcR z=Bgb^-MYJeDD@bgvUuFg$!EaOX!&Y~a=-1b8#jARxGYsBx=K~5O!Cy)sWRDjQpMx` zKrc(xsi9Gs!4v$lcB=lL9$WQObw*;>PsJ(WvnthQWv<#8IW2kDPqjIPr!3Xyx=h=t zHm~y4PWAZ?TO-vMG;&#KENoS(OrPJWwM%2MJzHc06Q9(B1jgpDERAI|vv$3l(_!{Y zbH&0gt6THs;-u0UCl~F~TD^AHtR>4ApR&?kyVdXNvQ>i5y0V&=@B5{_;UJfG;+kzz z)jFF_J}Y_5SNh=qv*1Ock8d_7wFInOpC}c;z;-#xP-n-(uH9K1PtB^<+tqWAgOyQ1 z-~i*EkB7VusBqnQoyN*@%7KB^zvs990mjpjdAnGpYc@|X?Vbww<2n3$b$XmCmz)OT+G0<;6l?j!FSba zHj2v*h3^yHRFIRZ%+L`totZ^o0pI=`_j&lfH#!GQVDQ|*EdFIVtL%=P!UzQiv8016 zY7z%Id}b(U+C12_O7a1l0!Na;xrWw1iU}N|Cl-9kQ($G9@QAN`fg)qWLwk`;8+#jr z61g91xKEg%{XzjlZe29M*bJN)BpWh zKDq4W=|-WF5c5Tc{s}C&(5hu3uYt6fUxvt!3Ki(4Zq#;^J#^HuLx##{cXZ4sE%q zjSM~y(jS{hHJl98V~|ogp!_4OF^lgU^Uu}JPdc=29Ng!zz|&SI>7t1VQ^~@TrJos6 zY$q^@?#N*d-yQad>jG12kpquQ!L&E80@zu8`7?R_IA985lc{uCDhE7|(B3V-g-xudut6lHKr7AE7vK`pOvSZpU zp$&~&ygp=c-<4{^*$_S%1G3%0M(TR6+tI&|r_snPX2d$u!PIC%94gXyDB z+xH6^80;D}Qc3*24Osp?J;Xmv>GG|FYf?`SV-i zYqJ}1v)?Llt}OHM2)ww3Wr9=t*;Nb@FY?)|yO|i%x)Zz}ZaX?DD2jVsS%e3^fOs#1_1XjlHvl zA!i!H0aN28`8iiigLhrJlxfW4?2^LqmXUGV2F;d^f@Z~zsSG=RroWoI95oj_6jWN9y=c+ROZ)z94K>hRASmAt-jE z%7j4XvNA~?oxtb+na)IQ7vM5xEZY0J@b~8H2kgvu%~ZOc`$! zUJD(%%X)%A>A>s&JCBW5f;uL!F0oxHn-TqlU7z`(kgQ^Ry!9iq@Ar=AuKPUqamrl< zrLr#W5AB6UR|PFjWL(*$$=bu)&}P}Qp0Q{`t7n`qZ;n7ovq?uo+?kk#JFopXdwAaF zIiL5u5z`Ot&{@7}_Ot^`ubzAo$>v))J@qcL*o#9C!pgRZbnks1tGxRrbA8^H_pw3m z;^!m&o?~4{eR!5scL(k7_a{+7I^Q|y!(dF%=Ld=>|gPDzI|s{+%tQw(AX%yH)!)f8B| zPBED&u)aIP?54oB>h!mpH+@?VD2p@+$}p)4I39}adK{|2)peRRO@aH9=j=HQ>H%|4 zr#f0LUBFv(hHKjbzIC3{d>FUBMIFThS<@`cSBD;WCql!hH{?-05I45YOV}Ytd+sdEu`(;X>z&*oO{r zT~ANlGUSz2x+hYpC}FlhVv?f5w-dc*8l=zl-ZAuG-N4QCW9Bc3d9ssccKqPl#=|N9 zE%Eo?M1?e^#yckzV|+Q+%zen}&{65s;?wwQi=)I2hleH{Y!27hSsJ+iFbWzlEOfl~ zV1JXm=S@O@xVjA-OJ;IsFs!>tAh11@EiC?&3>MQU-6 z>vgh9FjatQZM}#J{%DJCt?%TAlNZSW(lw9tp%n@i=Cs6Gwfm9f8}7PC|}dXX%~IO zn~xk|^HF3>XcYY5`0v3~*C=s8mkHi~9T|HV_itfjDmW-Bqrz(1#MQvWVbLt+BETES z^dRJHhG)N2gOm0PVWu~Z>suH&J~C(qIB1J7X@B5m(z)xjEWz1sNvK;p>j7!T35-_H zyqKq6c{F8$U;u+yPb1fkvtlMq|2{Afk6mwkbvr~#u? zMg-FVhOLE-YzC2>FV4$GFh0m=5NlxII56k5!qRBTM%Ec2k|z#bJ#Zi-?EmBcu}jmR zon+_{WS!C=^KRj!(6ga0eU&?Bw9E3UDKtn0OpD&;ZSdjT9UpPI7ycqAdOunm6v>dj zHf74Kh{k_B2TfTS_yQO>J}BjeGPr#7-?w3k$;qY#JI_5?Aj&B5G%YA0v~F2>l^f@l zt3}h6T{?3>{tZLbI|mL1M~)>8j5`jf1~AB)c(BP#W(<(zU}(G;AcNaqh88A{hATNj2PAe(U$sGnafL>cBtw_f ze~BxGCj!zKvsuGy6_eOf7&HPLL|nQ`gc?|P%yM&NWKwbL`1P=3n#K&bPPQ$IOgs(u zUe0CWxM0x~ZrSQ6pv(B7r!m8pTke8@$eZQ=zPwnpcF8}Emv;p;c@5*%?U+1C>cEGP zV9_TGJZBgT7C8pLO-p%pe(JRtrVP#LWtog+=`-@Q;vyKNUieGT$z%@gZH^FRoFXi+ zqx;{ASO0c!Gf6Pc`=nvT#^9~gFh9t5Vo-0hz^Z1g17aH()0!AK3`H3mobGw1alTl{ z7;tb}Qr5CM&E;;d8>TQQzUY^^axMH(@7oostScIrwurF)I3Vp3(K=OIiRYkzMQ>^E z!8J{<*BbplA(1N8#mX=@wehw}11paz$BKiB9*oit4hZh(7JD%#R_(J*PsO zEtr^YtbPzMTeamtUC_H^O@o-pRXK};;*tjhc7&|n%6sYo z1AD4m2n#PSkL` z^7WK#!>zRiZI_iwQwpaZ-!8o7H8@R?jx5McPd>zstgf{qW!( zHix{V4VNSid~TW3C_A~?CRI#@;q@-Z(;rV?ZE=!JIP{v&pXrKY)KdnFmA+yH2V}2o z;C-IQ_q;Iv4#y{j59~aQTY0q^S)7$47!)50-eH))wcsGv`d119j;lhvcz%eoZ+IbYWv_wO8}O`Q2TozzVp=#@D8m-N_}xJa*c3Etwi zxx+R7%i**yZtY(>OSZUsYkPE?cy)7lPB&RTuf%J=$;JnU-sisr?lAGWU(&qB#CQ4% z-^X8kUw`qdPxt@*#hbY_p#E8au&I~y*TDGHAnj5Q_uVp+C1zi_tdSDK z{Wj+ES7D>mo0ph&YcNP%X%r3cVU1{%lxUFpw{s!j{k}UJm#!AD5 zd%4vQeC;@6rdrr79Kk4m;UN2tt$Fj!^1qh_{NI*U%fNfr!O^&*@Os&*5C*mhuZqhx zv%Je$g3Oz181}z$%$aE2DkW(ag%>4CP^IG-? z`Roo}sv-YOR$P0x^z_MtoHqVTa>^gdG3UP;0C^cp6~Y@j;=b8<#lFBgt#yZlfaT*Mgs<^Nl|me@6Wkx`RC@(Qx8O#?i>&m zN}r=Uiz{HZa>Z#su)5TH}fZ7VR29sKCpd>GNa6)gGL=uN(^(j zt6$gtuiDr?zmlC{p0@R!yOE!R8hA9`m%aC8=s0-wkNJH|j#bI)b`<~85@X=IAaHG^ z_1lfryVK{-HTKwZ{M(X{0~{F*Dt``22rydiTg3R}_mYlAr=PoTTN1(<|J-cZZkl4Z}rG ze#=+=r@F1vrUo!({MmZ^&mm#!v)?~4EZEfku<~60A4!cVsv=CPcMeFGSTgQNKYqEa z`9rm@qTj@@3F;>fiY{QhXlpxhZsx-P+wIYRU!ASFraXVHKi7_0+ieO>PL{vAj~)=X zFyYqeAE$Qg?XBMZ@4|mZ=A0>)b)*>|*fzi1d-}uP`|TFj*zNd&zi(@iWGXl$qs8zq zf$8dsFs6#4Timv{-Tz&^v4inQQ&C;z&vT(yivE>W{<{+Id%u0(3r4$_&*yEpC{{Ij z!@V=SRl*H25{u?0GH5?J|M>E@Yf-y<#T}-6a%6~^yh@`XD(~MZcKZhY`m56aC#vty z=Vx#_D3E*BjAPE6i%-1G=Q1i05(|l)}7e2ePb8@=>3}!Y4 z0jnt)fs5TIs)g>Fk{P_*f1%q{tEvC9LRW`xOuM>kYIgYg_=9bt(xMuoU8L;-7$E<*~Tqy@WQ~-#qg-Bs0fG6OOFc*PR!N}(uIqi-TI_O7KH4XG4X&~znpcO zi@~Mz^z-u_+r?~Wm1JIC?#m>*dsb=o_4SFzr`gUf%e}pQ|FoqX)1L^ia9FfdO;K>@ zQemrC=Wk?VY~08AkL_8+2ZfJ3+?r zv!7pA`}_OH=hyeof75V+<$=@+2FZ0CElgY*D;d@a-zaEPV&ZB%*lDiuU_n=7%!7ue zIFTJ5JZ&WfN)0?(4;-hlH!8X?N(eA0^6ao-_}|!IZ>983SK0zl{XUcG|V7T)rcL5JiK_V-+TgQq9E~W{I&7wgD3!EEwm>f9MVHEH{ zcgG#C1HL=7eiXGzbqb&0Ji{bV?ET5;1cR3%BX7tBM^4=-C)5OeLoT{X=3WV0KTqb( z;;Hwdj2T!fnz=8ZzEbo0Z1+w`=C@I&UN4D2J59gn6b z_C-FMIkl@qZKAc<&BwD!?nNd~YvhZ1F(r1{%@>O&`ppWToqFi!gL(dSoUc~=l)d$8 z^+vTV8B2G*yY+hg`(&%v8&B%pelvR;TlCwlH}iIDZ#>@@{ch)ZzuRwje>@lce&K^< zx8Lt)bies-FQ@*Ug2li2Vm=;~4FCS&xMKgGr$?mM-}!Xwx&CK<4O|K=Mk1fBRy8Z6=`;E)HK5Z}4zxU%*HUIy( zpHF8#uWne?-yc_XbaMW^U$4{agC4xx`F`KK(vAG_HTN5DB`PXiaF^%z-1Xt!-|yk; z>i+zEc|LkO`^V)RT`~^0<^KI=h7%fj2K8?YnU&lg$CPu7pHpJIw~ZS;fuV>n5}spHyH^lyI(`y3|rLv)OS|fzbbx zOISq$6%S-MnO>CWQMb-{D0uU;lce6nPH*XkNDhSslM^19>ppOIT3{j&q^iJnWMWwR zrzH$LJ5s$lXM}OpL^RrIF6hqc6575@b&bu=Oui#8L*^Zt%BX%q!6D^L#7UoTnx<(D zp%=4++5U&HYBTo)GWzWh-Vq|o?CHeG%zDCsN2}Atcb|Kw@0Ta)_TOE)JT9uZXZUe$ zx-pUKMFUT%z+oOYhed{oub3@wG`Q2p%I6xC>Te{mx@{16E3-nd zHgYo4jfMsX4Fz$91qT#580NeYU|^Z|frDqq0al{}S&{w|0$0unV6~E9F<@D6n8WS> ztD1mgxA%hv!GAygGdA-aR7veF4saMuxEQXyiG|CBQPs)y zfWU_>%xVEkM56+j**Old$Zc5FE#bhzA+UhWKj6_O7KxTn>nRN~JWYxb9ZgXwUpRbD zPF!=Aw>R>#RP4(`Y#Qwe+8Y;r<(O2Zz#y@LNuH;uRcwYPYktF8K`lvLOMwGIZWV{w zVgecsmo2c&d7$LZ<}gw6|BKfN{tP`_|F(#$nKUuhSsfHma1k`g(PZ#eI3VfeEx0J| z2(u5vL4`F31kGc_SfnOQQ{ijr5bp6{UFFK4$`Q#RuENL?v7*^t+kll_xq;oX_+76z z`@Wa&W*q;@cuFWM!iYJiQAFWFla%NM?i)ghKC87j7~2@c_fPu5n@q=dz*VDwesv^-V8f=9ZFvxCUVw@##O|EWn zvsGydzYIeoPls{KlwA*3225&Ha}eM;{DbHC)MK0_)pIg^qggd(8F(D;NNzMXNoUJH z$q;*9Azrgug*i}xK|bbzn3u`%|Fa|<#5QlZ!#$~VCPT`PqIv5a1SQWbWZ0;{ARcr; zHS`{*h=}E(ts(+5&1b8e6Q0N9+VNq6cM~^z+r1`-B_C#s+%RSnopD$s&7qB7fPK%r z6O%=FA9!=wT*#cZ&D_^uZ)WZL*_z*_oqu%{F#Be3FrGTQnRS*ii@8?xn*0fY;$K$8 z3amKL^Zm#t-W!=}aldCRW#ceo)aYaME=c73Dl%a?2jgw!5*Nn2z72Dj3!Iq@8bX>^ zE@t=e>d5Fkcp<;wkc8x#Ca=<&+!Y?1-49J=Fcom%I;Qk!@4|PJYCg|?6)N79$2Uc$ z%f#$-lI%ojK9RPLjMZ+&4Qo}B7BsjCCQXk5wjA&lw3gCHi$o%);`n2j^HzYXfS zcJ%p*LjCeTkM#l^xEX>U_e&n&IVab%CEhO4E63J7^1hYxx`s7OYZeH2xH7QvU1VDr zziI=|$@qWg7~C$OpRXDm|M&0m+nLQvF8dhm;862*`(DvsQP;0jcEGpe{P#H4pEFeb zU!2qBTlRC_`i&h69-leF6Y}ntoX&5(N9zS1@Hz;v6eh6zpWh%{kg)&I3WkISoPEsO z93F@#D6knRurNFpaQncPU%sPPw0`Z(jkURDoS<Vt7NzS4Mr3wb$9VrT%7Feb@ zgm%2p@eHr zfn9bAtuv1L7$k7nWbyA>%^IDGB^H64-KhjfD;{@iYmD8F9L4ADy7boYKJi?E(L_7MY!b zul5MalomA~DU|kqv{pbteAC28g9m~d3@l{}m_m+ny}qcdb%0eviTe(dQr$U0hHS0_ zrx@nE5;SRH5DD55*3G{xfnPlHw~;{m!vCHJ z%Yzmu2D37sIH2Hlmh*#y+oCm0S`NNE2^SVrGJ3sSUGr@G2G=bd z4+QQkU=2FJd!~tVlR`9CgXY4cDSj@zItM09XytWiU_N(%*X{v}mjbuL1EE=unWa2g zMS7W17}-xPU@1FrRU>gT6F+m51Mdz7#&rqIs~Q+T91x6H_(3m;Wm+HiyaZ;u2h1u5 z*^5}%xj6YP@>!1wFsC)_h0z4>Q~Wf5WervwX5N*M-uxi zXY2nOPGWZ&lnNH8usM9MGc-DkR+ z|GTU@&z14j13ot`&Yp8BMU4z1UsQM&FwJvVC9pv7#8K8f1%WUT2`2}}c?T4ZoMrDoYU2bmB2M#_RCVye^YvmBK?kX1$UG{w-e|7aZU+covnm;N})(ksAwG`MxNn zF!26xaOqv(y|l-@_JVukm%w`V@_#QP-7YfeIIy!kGrV}gCq{vtErDg5JFD3NCW(d$ zzO>+_K5Rh@2lSkH%NaVD7O;9Hu)3Y8w@~soI>4jT5cZpOmWL9n%>kxe4@8Zh8Mz%` z@>-xTHZ}0S^j1N|uaSof84i3%dnYWo_o%AR*Zu|VJb4e;4lPM$O8CvuusdO@P;^qD ze_E8|v-m%)k@Xh>7n;WTy9YJ07<)A+)g*8W2r}=R!mwaL%w5xj%gk|4wXEo)I(*4AxFtG;FJotC<(Ec>Wf(ynjWXSXFDD$BWgE%wy6 zoV#YRm&$UVZVSKlE%*Q1YhjPd^1glxeDy8wuUXiqvV7L?z+d0;dCdcu$_qrxJsXmu z_`es5s}+iu7xl7e%;G6B6pvMzUSw%*uTw579Tee_8F0Tjre>-ti`oLC=}G3>i({wT zH7t7Om%t{F$hpNqc!>hb6=M&P16<1%WEwTFcP!xXC@*#2RvK?!shh^IVJUCa!ex`3 z7gsD`uYSTN(7<^@RBeHgLC^Q}iQ$z8&CTYq2nuxbCp{FDV%)>y#Py`#-QXZYB9q>> za08RA)gM1sA2zSgKhE@_VadA%JUk`dA`LtfrZ8l^xx40S{44PU|E;mUhqxLV`FKPG zr@N{?6OU2YzMfmD2cG-M(sFi#koK{AG$(gmZxa`6FWu2) z`F5=Z1MeLd&8L0}%NjV2ENBt?G`s9O^S^}o2@O^LhnT)}3amNspJf@BSpu`jCWZtC zj*0|!wQu3iBYL$H7(P_62b@&NuwYGFz{e8Vy!6JG6*szMEwvI7*k&ERJE7I(iC?dw zld{1BULD5zNe8$XI(a&{>zf)mR!o<$OB)9`W0Kb3Et3%vVyq zUV+&naqA{$;gW=jikm0O@0{^_El`fHr?_e;PmcTygY(&UW6^+N6Y!32pOl1%27P<9&rl11nDF$Pg zUZsxjN*xn9t+eA$JxF$xoTjNXqx-OsfCG2aO=X)00Y4AC-X^~10>gWz1QwPMu78zX z%vB2-f7zKhM71AS9Q9;*p2Nbw=NHPSaPHybEq^e5+ET~O(+_Dd3AVLL$TrUPY~q=9 zSpH$sT>Ykn0tb}5lz8fzzcVFN^X`Z?IB=EY0dtkqg8$9C)(LY>HDF-t@pWl*=04$| zxHpe^Rx|U4ODb9nC*~Zy#K8YWn=MsHwn`lmAOK9h^( z0p4SJp&9ppt?-x6V zHSc`(@myA3Fv)rbYZw>9LjeX3x9Dw)`)1_cp26E>m`W_ zJ-Fr2z;3I=dc%R&WeRr!H>1NtqhICU1%laljM*A;1o(^@Z2nveahS#1#Qg37?=FVP zdQ4iD54cvPotUE=C1QDuwQFDYoi6qRGoK{{++3-Aiorl3{U4*1AiS5{dl^6>5jm)}YoRGAGF^sg?M zxaaZS)vl9@L@gNRS^e&0W|Kpmsu6^1*pE+`m(`{af%4?e}xV*fJ z%gKS+CV@50fv+Z#Pr-YGpaS=X2L3Mlx-@()Hq0*p>zy6$X{l}U0TJv0ZW;j?s z`|OyI&3}yJ-p&Sr68#;XUHnB0{Eun=T3EA6hLLRz_cz|8cLxI)Gxj^%{84ORcx!&z zfrp7jU{0`S?FUhwqm%FNT(IvaBU8hHMiy=$$k-$;m0&(ffKVH$OW&$GZ9- zkJXkJ7bh7W>b-TeX*OfDK}2Z4!Ih`_6}d8eHXiEXVKrQ2wN=)^u~9VIFD0P+&WekR z+2-9VJ@-|=StdHDN(X4~gRZ|7Y6d;%%8*V$17GpFfD(!1{otIKXg+Y`oy2mdjBuxqO^Gux@7T3Ad(eRt8a>JIVQyjf4-oA+M|6RCs;ly@cOLr!T z6)#if6rJ--pIhcMGj(3oyOZhj>;8FOnATwXlrh(r@nlL{nck_4#eH_KWal;bd1Wr0 z7T1-T+VrnANYp`K)4|v-ElaH>%jR`ut?KcbmAQJ|KCbLFVR^5n_piFwmA!7)JE@lp zoBna-Y&gWHEwy&5*;KXlr}R$eZ0_IWm9yp2e?RZsEyt|7bGO~fyREV1Y8`jpjz_O5 zb+`Tae`=d7-`Uu-OU7@D=$vD%{KtXqEd=W|~AXH9w-yQ{WTo^~0UQ6u%<7<-2SXC@nsoITz3v0mE@9{I!V|rU_t9o<98fe z%a4`Y-S}DNrm<}gOF-pWp}U{?Iu4X2J`v&wILy&>dG_j%2F5G}2kn%C>64!vb?jo2 zE->kszIw)aCnlQ-|Jj-sE}PTHRKB7?IEi5@%bE2W8C6{WW)&@9V&KwOr(3$19(+f%o}y56gcRJW+j|`(d$4=Q8P){OUz#5<_Mw@4NTpdF^_~ z)SP8%c4}oydu5MY_}Q~)C({%|b)$mGo(VUPgxCgl9nnc!eT{)Z;zI+oLIrckg$hOH z97i6P4-N`*nVSW+D6)i|IN({ZNKkT30;{~m1W~7kb|VYLUUg4K$!(R>ChvLg&Y5vg z{zyTKeUE}J$E$8ezXxq*0*oAT4a)MN8=81|nwXk59I%+(#L4ILsEcbxqnYUfrW=3$ zw>yS^Jiu4cz^=XH!A#$i4eT}_8ky!i;CD%I5SV}2bGMBuYrO=s;voYj;V4xGi4O<3 zf(oX{+!5x`-f{2znoF&_1;4r-{^-E{D1(jPX2KH9!h>vP3zz~e9a+O9oMp>4Foh&7 zcQBmLD1A(U&1lIL2F(wd?{h9K6JhznVJy+eIEUd(!n~{*$KI@tXI$DSTfoTZJ>zhl z!4q57)(1j%fp-+r5*V&qEaetqU{sV4V4V=qz#Wy~P*9N2d84p_X~qjDR)d10T!{(% zJ`A278W%duKTg({e8H;e)WjfAz$l`6;yhcDkkEXA2JIOO8u$$uTDX3-FqdmIpO+A6 z5Yu7Y@t-AtS#a0m#*HlrtQ(veQp_bTPtj0d4>*wP;c%dHVp1W?85Sq*7aJ_D%Q>;% zO(2`K&qRAoAqB7(10$Gcs!lXcF4xB4Q50!b zJ-{nxK4-$7he9F`n#DW}r&)(Q6ja!7L~_yvVZJ$xE4WuN)znUEF>a7xnUTR5`niZn zqk)BS|AkEv9vhprvl?b@l>S^W_YpHw1|z@MLuZj03`|TBhj=q`maywx6b^D}s)**`d-AmEkQB-pS}gsFk4U&D~uBd>s+CBc#VHn*qHJ(1~} z5(_u6>}U~mn8U)W;mQ+s@WAq~LTya)_L1{NTfpU5~W8_w&9Jvov8zQfyF5OOU;1!PtH%Gez3LX|H)G z1Dl%z1A9Zk)Q@dPB+E4zW&Ag=SNks&Ex32%xDi`x%pYEOM z41M07i&iGJ7|mf|o^+I(|Nmi;1|A-#E7l#oJW&@4n0Ow}6#Ky;?&R2EF4@3nv+#g` z-y;^D3@1$o!9Jb~7j{NIXJJ+p{IEE9Qa00+gKZ8cjAeHzER$quW@z+q^b&f&cC|H$ z-Dt%Db~6Sp%XXH&Lnkd5*G*`W5LxhaRky3^&e&}t?bV;>?4RT;YS3aM{)?}A2IG;* zd?#+Ka5&h!!YSuodn132zJT6|$0EmsIsz6NGDdNn6iS-cSo)gbNYn;jrc(!41!5ld znR_;z7EDOkE75R(rNi~DA5*hUcG5IucZZWZ7d2QYD{$}q?9aMngN0FyAwvucqhyZq zoD+Pi0`d+g^Em~0eu?$A|BiH==X~J5wDTgS8OOMaL>T@ZXOwYZQwe2Me!#<9=3y)# z)T+%871_XS`H*qdXAaGWzEX;8mDfs^ht>rgV9ZjeB; z0z%3Q6dFPpaxMs4F|@0c+l3vp6xqNeb4@gQLi(Hu?py~l<|Qypx-Or(KqT5in&kl7 zc@vXA>C)O8m|w7^#5QtttINzw%e%vFKZW7H&{GkHjSEC9wlH>*Ht?JBE)Y$DgT22SI++5MC zX~ZDbAf#c)q^Q8UbeRX;^fFM({VAzMnVv9W(EG{xt9%IdIn3>zaKHD=rX=3P!NkYYr4ClVc zoc+is(!gNfHu2tf&q6cK#G4}FjHv-1L?$r^c?Yo1?wq;vCR?T3Y_5X(n!~Ddr?_9p zu$2yAOEF+hzA$xXDC@S5lUWSd&QBC_nb6Mqfl=O&#X?c~fMPa>L$-7W!|@s7h2N)! zT@>X=WleP8$UVTR_>sk}kU2T9zDB~C(Lgk1CWCT7Ug?DYGiQ5pR5&E+B_tI{sylg1 z=Ulab?_zKLb;pexnVJu<#ssvA9+>3GY2Rfey0$=QUK>M~rk3IdL2UuIMJh8lek}HK zWaPAn;yxCyGELn6IP=%3?nVMa{SS;)$`$s$n<@d`0)t`vGw7I(!ot@Vn`!Ji7p zg3mE{y@ZkK%u&Fhaj}hM0@I2V@e=9P$Gtclnj5_f zR}={d{d~spc>1Qrn-oPEGSVAd3_}=%JQ(T|oF!)}Dr%(1w@qZ(z+%2h$S_l-@{9A$ zSK@`sSd*BNq_V};7w%*UFlYQw>^fU0X+pc^!Hm$4J{ttpgs-p4G!g4faOMeOC}FD& zxX7j`$hIJo;m^!%{*JCP8<<^%d?R;Oumv#oIWR;fi2Jnk)MRTlNbUH3x{`SUccV>Pe~bTZmwh}1x5wtIR(spZd)1-?$#(|QdDHW z@mfUU19wv3p5v>JTo~rHiqHMY zqB)UC@t_C4wBOzbQ57v#91aJU7O|Kcu(-MGFMqWCNA~e1D~5W8q{a_*e=e@jI+(%o z!Nh38=7yzD73!>dN)Y)%8Q2ucvzmBxv9HG#5hLR6z&z%!E8klPyGAf9%9+h^v z>&?(%@c(e9IL{Hb^!3s4I(t~o1~SBYGFUWt-fm=85UkyGTip7MNLnUK!4ZWO!osD& z3~qD8J#0dy8Io!YSi`5dOFZCA7MsU5p^)Q4ou;R2+)t5Y1|f$BO&SjwHwg&sRdD)T z#oAltp69^zXX$*=fKnC*b{4Oo#1DdVZH}K0I$pl!e91~isSjHe7IG>sV6-!3E^5e~ znc*DWU7wM_CclBzeM5QE9g&MaPxuO+yyAJ%%jZ~%0h9a#MrVek0|9%gKWJ&1WKE*$fu~k7VGJs9<1EYZh=c>n?=N6u>Ie41! zLA!_pyVwJ!(18DJB?nk$eGoj7bEcy4jPJptSq;o#1`G}l*7O==|7_ePX2ulyfHAy* zVNJv7vx@t&4A^uRF!4-Cc>1*>;|kL|Zw9*!%mxqG)*R(3nUHRDU>~Ex-USBCJOQlI z4a{q=R;jZPyIs7d3jNy^%Seg1SuqIu!ZMEH# zx9z%oHfzDcr9VtLgD;5P-~69(Is+4@hnR=}m)HSLZLRzp#$6j_g$`V33X;58VsvvV z??a9hDd~f3IeTv^KkT&+S-MjoN->c$NI+RfK^?T z2$hgov4nvqfl)ePenyi=-rbjT%q;g`+{LU67*o7>oVr`B61IQ*!EoJ zFmK@4%)w+)U|qTNTdC2v)chY-lfN|omvvyskbn4N`Wc2ImT#>e8L#$4Z(7V&G2x{8 zk{>^6e$3CmnR)-`i$v+0m$`!`u;v8#PJH~a{JpfC08{k@)+ry@QWh|&nEYbp{7eR#3Q|Bpw%;PL)HC)fWueg4nc_kYgw|GlXH_p<-rtNDMg_y4`Q{_pMc zfA7Bkd!PT`L;Zh``vnih|9Nh2CFbz&_4$8q-~W5h|No=@|Ihyazvllx+5i9F&-MR* zpa1{&{r~^`0t_sCDiIeRIJR(#>ZRPc@X)zKP}Ofq#KlLhJ(8w*Pi|a%>^?!!wNEAT z(i6`qnxX4bZeDuoJ;N~d+>*%4&wS@tmcDy(^YU~51&*zJs!>;71TOKMs+W4}%FEyt zflK|CMqPasx+ZdK-qTxGUx#lA9uR*WbnNsr>rx z>Fw+9;}0~l@~g$%_>g#{Q&d0g&W(@BCnl=;FN?YPDfP@u)BI<5ZhlU`u+X(%E%w%z z%quHH*QedR^)>s(#?5Zqq+{@LBz+nxCs5+X#B3!GhbMe6j^@7<}q`QWg& zn102aq=o;V-`tx2{GN$b;bZZQ)=HY?>{?4gW>NZzVYMJkvRG!Y_GhY1oc3kq%ylClitt%oapkREQBydK%EW zrdxo4&B!E!li`ZOw6KiDQ?IR+V4HPtf$SgW2F2GG7!=$kSe=xvGF03xiz>Msx?P*^ zR_S&HE}no;1;1a>s&^V+oi0@16NvmC-@u&K)ez7Bh_S))*L)5s_oaLDZyctsnep%ex}Yyo>rMQD|_3_%O>HE-lxs0 z{`NC{L37x2fhn`jIA$!F9JXsA%e1mznJX4gtIArndfTt8HJh(hWv|=)?N|1O!(!Dr zn@*ek&e?J~tU7nw?XuswJ04G~&ilXX^|s%6dp=*Q&foX@+wc4X%;Gf#hq%rE6dVx_ zuPHnxUH+%=g!1&7qEp)2{}i1uzFt#&&iebG;tS5=wI!Fl&Ht8M2@bC*H zo`Ef(fmtPik+;HuMJ=F_J0*cx_J;$9TR@ZWk_1-W3P+x_fM)3@3GB8%90l3}T9j21 zIejafM3x1#YNsS}$Nq4VI2O=myd;q~x58QGS-{nH>nDl)wLhE{*aAD8RgwgID_m66 z0z17^l7#2}aM5rJ>S5NwVzQ3U`}lf&JA_lI8#YaCcw}n$WD0qR3n6;i48au{$M2S@x%ghg;C3 z$xBjHbt^r6(t;+>ev+bY`_nU^EojPOl~hgNO0SS*K~qM{B{Ea;-<%U zzyJL=j=25i&71e{-@kkJj)8&U_3PI!U%otZ<_sevFrca+f z{rU6f)TvV+KYq;1%WG* zvERS{Jb3Wn>C>kdE?kI@kMHg6RZ~+dC@45_;>7gn)6btjf9cYtM~@z{v9T>*zPzfc zYQ>5bot>S}o;`c~_;GS_@~?mY4;?x*apJ`J^XJFJ#BABJrLC>)^5x6x*RQ{K@7}+E z|E^!VCMYQQ@9)2pCr_G0-S>!E&B@8RefxG15s~ihZV3sAo}M0MWo2Jq-_p|3)vH(k z`t^JB=FR4j*JWj8w{G1!ckbM;U%xgsHfB{FzkdC?v$OMo0|#_>IfPjGZ`G2mz z`CnI8_x{U&%ZOtZ78d*V?YnvN=EjX1LqkI&A|n3${cmh+oSmJmprBx8W@a0CYSpS$ z-rnABZf*t!29V2y|NQ@N5P6fAmv`#ask3L#c8pwZ8GczyOY7&~|4xyI6crVJ{`_eb zd61Qrbf)-Rl&w+aTf&H#c{Ad3kDT zs!P)8nwlCN9UZIiQx;J-Eu+slM{RV7Ir07f|Mc|qUAuPKMc=TpvO010lxM_p*Qgyo ze*Ad*=f7R(=J?9nc2VbJN-v+g_PwK{!!3G+Wz1#UsH2C^JbCl}?ThdKzkd6_<=Fq= z$cpQa{{8;@-!H1iH*(&B<(J;Sd4KWl?@3F4hvuH}j5+%5&9@If|8F_--#=kZXlz|! z^X0|6|La6wUAyCQNyA~U*aZ!_$Kc zZ1SS@4^B)lXgt8AIElk0&hSvtXU;^&IgTbSBFAL)8_O>=TsM93pjp68W1*+AEJH&* zMhLU%R!yPlpmg)EM4((n){~~ zT(}$`Nvfz$n~}Ea<+3?#sv7z1vJa*>O60Xn@!T&urOma;;)obSRm}e{N0pfq1t&5u zlTqhA9Il6wd>~fmUmD0G0 zo9oIduLnn0iA7|(Ex97RO-mzS)?KbE4YRogy#se~>oy4RiAX+Qw}pXS=fi=Eeu)d$ z7TPj8$}zuWZ{TP+86g;{B@-6Fd?u|V#rKG!+j{4)>M%)%;g-`0wIxek z<)@qp;AeU&_SC^%V9n=qHsAl`u;p_q3Y0LkI9|yAVpy`GS2}u5K(Dal#>*!e8VuLE zIN2Xr>a~?4?5*3MUpn7zq)hL<>EW2b$ic9l>k2z7=hHP8-FZ^p8n}OWx#Y3$-Maq< zjSfF^ zcHf4dT^aNFU#`5MBw4vba5j&q-30Zi&)5Bax97A-nQk;U%e#7W>5?u7xvB<6_j7Bf zHM>+tZ((H+IH5D~wP5LN?b{*3U)UMEXQZ3BsCWFkz_x|y1Bb|L{uHJwqFe9&{`2K} z{{FDGJL~`d`}6(%|NmwuW1`(y4=_o6XyDiqucM~in4tQhQJ`l5i+aW6vnTtTB+e{g zGe6bXBNwSKXKgd*T?<_o+S$Go+q57 zK27NGS)wF<@`Rh!r->7KmZ+$Ep7e_PG-<|}C2Hm;Px@7Tn!JE#sfN4fsi0Y(rmXN; zsuh0nRM@UhQ#bT1)k*g}9d+x|v>j)b>Xn~79S6SYahXB8=b0p_&ofT=EHhGV=V0V$ z;AeT*Y%CUyBPqRxdlUD$aB%0~-^kFXJ(R#1?J_jtj~T zGc?yoGit|puDrU*>UDuwz}@I)s|0s`GM!TTbV}c@&)3(Bg-vl0?T9tK+E95gPr-Ku z*B`#!0{er?CU?F)lEnU~VQNh;)xP3K?Z58vnjt1dB$5_8V-On?vqgi>*G0yj_heYZ+T8(XveM>qR zW@hA}D`b>3C80tw!serc*B=2<=7yt!oMF8(JCqsb79Ey(_oylJ&!f3Mi&8}jr+2Fx zMYi$WRI>3??JJIPeXFI?Dx!JdzJSv-5itdhFI-F&%VhLgH8M^!ot*9TYxe|&2{)D8 z#W*HtZh9s(qv-!hpLvTW8yhXK3XW7zQ0thzphtj3dZ)6`0|&>L1%f)8c7#YgDw@s` z)NN`VaKWqZv%Kt?WXI2zN2->2%>B)s+_J6+&datrw^a70aV*L1 zdG^nu<)*ownf&yatUkq+#~tH58fV3_G_j~#xV-k*!oDb@<-psiN3NL(^w&;~_HVIx zdu^-JGTt{$4KEnxZ7^TWf9XZDOaEQZZIL>Ub>AyTRcvYy{NXsMC%^g0?aQ2zrmpj1 z-!>KOQPn+MrYd>wgY>zd=LG)$+~IgY`D0_uuRvY)1N+a_2t3Zw=U!#)`QaOPgM#Md zC#vfop4{sz@Na?JO`(ZSXHw$?5`~`_sycbdb6tAdVIzH8Us&xzbKYUz&y_DtvpLT1 z*PU3(KHG$oG1OILfpgOe8%5E{Pp|FtJG|4p+FMlI(0P*Yw~jxz>?3%bmRIkcuwCBe z4Ew{N?a{_rtKx6J?AT&`H`F74igVq2)=q|ck+;iEZ=QXNIsRv>(4vNB>lS8D?lM=E z14-un9tukLgRWX@{ye!p;FJ13lN*k`6Zd|!^!Vd;lI7bs#*6VW4_|Ifd7C@`;Hm8^ z&uf>RI2vpBOHZ9;m8sLOIyR+NsWlH3P1NQ7J1U%&kqG>|KQf!+${BkBo~hMJn)~!W zbIuX|7jx?a$4b|g8}|IZ8Sld7wp>7!tujb}aTdGLPj|tC!CC*zJx-g~3!9YKxl}Cq z(jXw=D0IWgK|nI?yQf%1qtKSbjmxbcntRK0GzpY6Z8U6Jx3o#4!(r1jO{s8U*@#B{ z6>fSJ&HfXct$x_s+-SD{*zB;w-pQiHIxZ&)+fUR|gxOf30QzCcu{}~+@g&6-bFg!94D0C1gEa;qY zL$uI=hv_2M>z_@5(oNgn#dddW$mG+tmifjP_tO@ezCKF|Lx-hL2 zSkBDQ;wr%TfkE6-z>b~aH3!3uj+*a^0-OO1YzG+3Hc$HYk-_kPWgl~*n6(3=mC9tc zjgw?8r!YLWl8zL}3DkVn-pkU+kbB*NP0>X=v!7uB6X%3UUC9FW1^q5Jr=~n+=bNA= z`@x1ap{_G{YWxCy_K6G}3z+6!Wwo+YTgl2W^?_uBrhxAz6TS@$%?Y+~Kc`=KG->g3 zb^QY@)fZ&hFED-!5-4-f*`qLJ{ewwUH?WIMU3Aj4y!N$Y>+ zIUZu@IUsqdQsCKgi57u5?1r|_(iwar1-vg$dBx0N7%-dZ*TSof3_CY6NmTY#EMR!_ zu;1da!179gX#%3o2JFEKEPk5v)MpB;`#Diz*J6RBy48!63J)*hDV)h{SUPc%^o>#x0z4n)GJlkib6^mez>v}Z%LQ^1Ed~V$;fkvwp)3T)4H>j`}GIL5UDVZgZo+;p6)aR8YFtuvsiY&=)rX;q4 znH!ZBi5Jc)G#7Bs6o@epSQ;fzShQ^At<`0U%b6CkJ6)+uWMRGkouOWt>m#dR=_{Ak zRV?vb%I%kJcX|o@JiL0}thJE~^;Z@N^iQ4JYbC(5YX$R1Q?`YS;$8xN3s~egF+?h8 zPVN+NeZ+n%YJE&%0z&~;m4mUdhk!OS!-A7jvN{ENXRTwHu#nkXpgVc?w_6*cHpnoNZH3m``40scYj3aembE&xoogYd*+R~iYN58>t#!Y*U){Kavv5av;*QSK z?R}?rY){|v?)$ZKfwr`-HZK?BZXH1` zCdJ*;I2ba$S@|4yvs`2gxv;bA_O45gU4JKVu1yG?nXqT=hCQdX1sWIZ)=cD{dx4MX zBli=9z2~_1@=fHta=PP|blaN$+Iu!6Ze=qG5*vl6#5x$bA$*zqP?ptC_>Rkpw^g9FTpJDC#Om=rstO$B*u1PZF#ey-j> z&-#c$#Ssr1$t4k@Oiz#9Rp84%aNrm> z!y5&G@6rdoQ~91u*z;n-LA5{JXBGCoYUn)o|LUIm1_JwD$1o?hy}!+6_4Gi{i(~m` zB)rbBheRKI&&@Df;1t6L-qeJBHFrAFG#K7Dgsk1b|DS=gg(Ix#1`k6*c&_%|58S6Z z0@$wn=C+hMShIn%q#=aq;)yL6_IY-kocTuFi-%$E8G*D8j>8H9A+GITSQsWw;P(G> zlBtm8_3n`448F{Yrx_ehGk@gXu;IWd1_tjJ{tOIVd~-O@UJYP)aQ1frkMf)|r)8wi z@-X~X5cni;fsvQt+5)bLJf|2Mc-%j5Hwthr@abS?0#%FVD-fPZE}IG^r$wu#&RGF<$%=lm>1?u#WnOa*&R{-3?)L(K)|g%_Cv*(P%^ zoC^q@yn zSbq5CJ0>I5IHlUoo~+- z-(K!R7dS5(>_0z&yKe&b#0S^5eBj;{aOv)yZ6OI4dG2s0pDms4d##l5a^cGZ(cBE; z54O)rJ!&7r{@><$DC_ z3{gCse++K>&$v13u2@=bK#C8magD%Y-Ghp{*N+yk9GSowyZ08eBWp+k@8bV&Z`H}( z{+!L08^HBcAw;;9&>^xH)tMp7`$QGdOi5_m1w|J5x8_xpHTl>zT6? zKb&CR$hji+(rX#c@3p5E^8`NNz0L5T`1JOn<)3?9p?B2Q7A&%Yl#*a;}wJvyHIbjrl1 z(f6M2`>!Bi7b9@d_XtbkgDV#}Rx9w_u;qUnD!@Wkiz0*l*;Yq(cTc;S}7vMPax z|L8fkhesJEa5U;YZT5RHT`{0CRv^A^-|VG3YZM+c6mTCAxO;OB*Q^gm++_Ffj5)Ve zM_@q$uaI8HbOEmE21jRp;5&NZ%G?jn>i4}W(R;Km?udBA(+zc^OE~x+*$5m7c=z<( ziCwo}uuXi;aDhX-f&cji&Q(4Gy_n$IrdE+s)N}hqE(={rld17a8^^xAMMJIJ7N+ z`>nziX2S!rvU}{$OZ@x2pEdE~^En3&uHBvan|sxQ-O~deiZ9^4n!vZEfN^2~UzjQH z#0IX?3qOMDIddDhrUbC(7ThoM zeSbDb%j_5L=bk%K-+syduiZxT>@|<2c%HE*USKF-W(Zt%*^+_b$<0$NoDLQYY3o#* zB($zHFtV-;SQ#PEpw=PEE^#v=V6xjJRo{6oGlQObP1B9t*CHAG%x9Kq?!6;3gP;4& z)2;u?A{Fu?V3BLDoa?NRmqE*X=YGm@_>}I^J8R9gB}@k*cl$E1Fl1cyTD(6lI5@6$ zR@mF9ZMk>%m1c>(i`iBB_TJIi;qUJ)3BDNRT5UZ0WF*njD`OYwczEXHPD>eB7TOOLESb+xo}-t-6uJ z@FZD2{$I_{pG+c8rkNe6{q^_ne|7^0Ms}4A4$S;629B)aDH|NwGn}?V+}O$tEvtN$-UVSV9gR($i#&c<5z#TxGM*l1(`$ z8+PsEx$I+pzs1;Z+J&6X{Y+PuC@`4*4Bo8D!lSWZfn6e3LsQfLeOEYyEyYu}1Zr#V z;B1*($MR^2nAatS26?9l&sO;q52gkt0S1P^-nc@O(9rOyf|q8jnQ@@6$%!?=n?Xdg zQ+(39;v~jNd<+M|og$dNHK-S8Y*jGeN@8K~cQMQi2wT2%+by2hwJ)c#Gpsns&!EMa zAixl(kat3gGb*`dKcC75a2FK~EG%3^DHG094Uqs^LA;X&fU|H;dCWvzZ3 zyj`U?+OM;7@)U)GDm;Eg4$5qPw;EI&xRMt5Gga)c%G>!|PM@)-*RIok@*dNdd!n_d53YYYAKz~K?b-#GTT7VEm32<+n!WcC*S%5(g;z~6_MD+N``zt+?zy1zXUS#X zB!yfCork|v)~lO&HcmDR-&g&9fBG4b1yv0DYd)V3KO^j&6Lo*t)r;-+bw87DS*kr| zbYNy!?<>W`@bNi&0t4%cNh{wTNmp}ZWDv4&U^BbWXti*vr`$&et}ubR+8ZbTb2Tyj z?~T0BEYFh2;cDR|H0?r*x=SKg=nf~bZ5LYgTM~IvEu5vUU1&2uk_f)(@!N%VdzK`D zRtpy;v5OtI9Py-fE0&?Xc)w`G#b z#RXD~1s*;#U4-VDcpmiHd0M1vfr5i~vlqvOJ^h^i%GC;;tn;oLPO*8&DK(Rs!RNuo z{H6a{Vpt6u#Z8RdohPy||J7z;h~i{;^YPLg`8f`JTueKrvuH8$8FPxbg$t!WQb=ND zT>39*LgR|shGagEgWNiT8&?!Is_fAA_$TmdEwhY)DxYn-i*AI+jF5gN4h06uK!y!X zItMsstE7G4a%y0DkXWyL^@R5Aih}W6}%=7*^1V*3K75g1ug}9-3=IyR>p1;qv20UmPQ59?U=Y!3@OFw$=9}cu-+Lub z99hnwz{;R?ZTG#iLG0STC$qB;&1VU7n*D^CfhTFw(ktt(?bzt8y6()Xi96I97~iyX z=9wzpopD5=g5$(|r8NN-EG%8ghLw*CkN(~j66Tbksd?Zpmji>C$dgIkuAHUyT|(z4 zu{2-P<=DWWpv$6?Fh`&BeFf{Coz81i7~d;*N@#6lPM&l`xVz$MN$DoDKTHn$n}tOg zg4icB@ZUJxDShb1gVloNObRoiiaKjTneI#ukYM1*&}WE}W?*7bV3OW&(8uaeqTKP^ zqS7lKt^Pu{n^q+7I4JyorO~3!vh1Y!{Oq@kVOQB0UQgnhCwIX^=*S0_!a}B_tc5Q< zyKW~N9bQwgUSX~0qDmp@lx?%FKZ$nqdJsPSPWu|QPS&g&efz|2nl!mGRTU z(76W8A?Fuvy?kk!i~35Tlm{xT6%NgnLK;0A9T?dU8+3A)zX}zbpZdUm1Ti1`3ZQHsxH?REm?fY!yJC54s6-~c==eb+?uB&_V%C_IW`@Zda z6&vg8itE*hN4Aykn|y>>;()_-i!YK+`O5aXAK9PVIW2Z5OjP0AlG0?E za`k}91M&Jlk()2s_w7{Jb)56h)BW|A*C=F1DRT-3G%|TuC!I9tsj{B@V)5xq96Jm< z&ph7G5yF$S$Y#NbmD4gdBu+ZOdxr0H^+uj(Z9WmllLl4{2Xfl-%ORDJL#j4gR0NFFS`KMUIrMZx z^VUe|Nfw$51SICpKBULupwHsGb;42umBR~vY!2*_+HJ(}KiP=kBIiMeji!!*E2r+@ zKRVfY=`3}Jo1I^^IJgQ92W@noq|vZec$HC)IY-W{8LJH^IW$3i0(rVyPP`h{8-q~jR?}z=r53J|yX1sW* zgFQocaiYT{4QWMf>Ge$FEw`+eCeCtDY*-T1$)wXEP_S##3d!i5OjVj4n@&#B_1x1W zpvzVw6kfBvrfY+cfkwPwGvDUfx+~WwT6Q`)iB=spVkkJQ`(TZ+0ZYb7nS_ljcTP^) z?!=kO!tnKTlWYY`LS>`(t@S}K852G>Nz7o5m6~?B(XN-nok74l?~U32oIuVjrN-6S z(!0A4xbHmLeO)na_lo@3|Zkn{=MD3d?RWZ#?E9R zW?7)wp=as(G{xM(!Qa85nQKRr!R0-EnjGvs=bC1mo4n%OBn<}N5KhmPdvqr5nyhhV zYR4?yi>sOnSWg-;oQ&dpV{$&%c=g%K9U+s>Pg&tVd56E_mGe^=8sB*{{D0y%DWOH+ z@6uaNopxDkyfRdoD%Kv*;q?E&@FzPU=k?@6j#AHA7+x&7@NUcb=^t3u{oKyS+VJ0` zbIa+|i!Yg4yX{vPmB26sPWP(CoOR*y(zrF<_3U^_i9Xgr+ks4K6>e&TX)Z*@H=Rjx$5V<|YZz z^)f5pDK)4mh#Ie`oY}0|&OjDM}9&!4ftS1y8T;)8KX+q=aOIzoy zJmT}z%p}lzN)O|lH|wX}aI=hIEVwymgQNYjm5ipI46+*1`a78B3pQ_hx$n0_<-4HB=LZdf&#T-Z9ZvX!aWJJU;c(WT&&TCJiaV8jyQ9u- zu|Bl=YI0!RS@Yk?ouVh4{<9ZvnQqV+u+l-sVy!RNg)Y}lCfioNsLop@H>R$3nC-Fj zKsEQ$z`c`r?RY2bnRFw3`qG=Tbe)9-cG+yc>0^6yE~~Rl0!y5P^L*7?i%f4VcD=PE z^w!eUTgyssEpNTGV(P7xOK+{(dTaI3TWhY~TKhC=x#+wN4_ieX)VLcioV*~|@#

Ibpwv(E;!E}ry4`|jrmh7}?#0ULjNG==Xt&~)K$(~0KNU5CH5 zZnK-o#BI^sQry5C!C-%*p|z?p)m4+>1%u22%jcX7(g#-6Bn7!GVKlnbEWD(_R@#jD zhp=^z-?^9vk);XQhndyC%y{%$Og2Dd@(jEYD8*4UF_N9-5h&Y8O& zW*(N<`*Jd;S?9aU9G|urcps2Z5QyZytiQHut%BW@riLm1FVu!jdcmNh*LnG=|HH1N z^w*1bobF`3w5;&N;Z5EnL}D9n{&D>oz5$k=dasZKvCFE5|FVI^TZv@eVWNWME)bn9urS*IVvO z%scL?>T(7#h93LmCwpK<;O5X!zU}{~hMd&pG;By>x-f&u$6~`J4xiFa!)V#wiC0{E zIlWh;B*dB8H(UrVW(ZDT(rbueaM;gqS+$f)Iz*C1F}Kt3@_B`4Oj}AfPv4N1Q@8D% zb;Huj92^Jkth=~jj)d_`Lk8_1aW(5$nx>>zrEL?w5ZUX%$Q{7Y`J3hcyGlmx1woTE z7`tUcXG$3VJ2E#g;d)aAV`bElX19#I%WJ#BI6pn*WX)())ytI7c{)9A`;2LsoO_-v zk61r@-OIVpGUd9S&SQJEKEcx+j^|OT)WlbC8dJp|P-1Ok_vJ37TpDpy6&HU-4ajY#bv&HP2 z&YfG+y0(>N%QY=`42->1%4=c4U@<{#*1gyJo-MTby||Jq=Guul=~i3Ye7X09<;c7W zoTVVTB=N$`?r8!pu9i=nXI(fqA#qDnhwj464W=<%r`1Gea=2Vb4+XmpMEkhLlC$2vi$ zgyb1N-1)Bs9=g&Ydt?5BRV|7V$5&jA_pof>lW4J8#Uhu-XnX?W*0HLZI`mrefA@PSLeqt_~9OXthQ3dHXfUoB#OcrKHITvGDAX+IiSf|%qbrZfqb zOzP0JE)a6h5q2tg*{Inma(!z_U)SG@lgWdr?qzYC*cA4JMw!hy4^A-}oba6-km+nL`1xvwx^9Pix^%C^w63*HJhg^y zpPH+i)^l($vae_n4Ve5ruhY&;_90{G2YRgt#NfE0$OSdDp>(~xfe*e@|5FB)LMt0T)AN91Ue;=8- zYw$XV##*by*>ZKnAJY-$`eYfx6filrkg+PztAG7OjJl43syL;cqb$;RbDXl!4zhL7fpfBrRq02dNPQtXh~a}Kj#MXzXy5(I-Jk1aomlQ z{i@CR@5jrgf+~iJuj1WOLK?F_{}N16<8)?hSz0U&^SB#lFe?WG6Fc7%#}5il4D1R#dy1Ya zEN&5EcT=!PUa+uJie2!J;)P?*4E)MmJSzhq&uj52JCn(D;F3$fdio`m8>!1$U9G~d zh)5i0a%xoNZ|sR4N1q-LKQC_aM;37#$m$faQ=w8 z>2eLzRT~!t?`AMc>&g0-z_7BK>pzE$;ss`gJuQi9Q#>zEKC<65Uroj30>i^4EPPCg z9SjH48W*0Nq?h~4XnJrEMl}=2x3=H$%{ z#n=2eBEKmy1(sdV^l1&a6lA6_rGam1O!^GBZ%fS;TScQP6x$@Tb}Vf5;8=3darV>; z!e#HjrbXqdo||$gP&X*FHJn3$#nma&V{5Gcmss-)8YTrllqWbsZhDM-SX*aceldQM z&CzJ5kGx;*^GOA;H^e1ml*s>|vQM@sfS<|n=9K6=j2C7`y7WGZ_2{3mggsE$_K}4D zMvs<5j($8-kGSMkYsfWYTa(YluQ0g5Q z=PxQU>0D8+Tu$c{mx%isWtgmR;BL{Juu6U6E|K{RGLIA(_;_BmF4_AFeAA=#n+WwA zo&sDBUzg-0bM!`D*8Xc)dfTD(iq! z&M!;%OJ?seJT6=Pr|_6m#i#i_EH{5#{eMEel-=mG?(RQEXADoDk=nX+?N6B~nK$Of z=WT!gF}|>#Q^2G()ku0>c!kERqcYla9Nsc^2-=!n4UMify=KpEwY)2``mgDY#BSSf zA%=6zTJs{;FzDaR-Tl|>PT^@=^ShU~zP*Y5sj^=9K~ zJL|VwZ`WDB+xdE*_4~cQ|5<-H$Zc=)@u+mY&8L&v`)xj-wf=AO<)XK}?boZ(^|s&q zYbV)$zgxY2O3I3jtk=IkogH8IWBJa|cR%0m_OJc5Lh+Z~|G!_g<@f*n`Fj6<&mZzC ztPIzL9sUV!Xn4N*sE^A85l)T(g=>Ny%)A;0IdAzHysM)6?#ta1Y2=52<|!H_)bV+ zb=Ha_s#bbz+RT3CK8{^{3=i~Q7arghENT$E>cUhvp@UR^(&p(`Pvw8dk`NQkCQq&u zPlkkK?c$Z*drm5FMFgDE$^O*H{%+HZV@qZoX86!7r_?g@OwTDz;b3=8i%&DI?OFEV zLc`hIqRq4K{ZX?xta+|b>0Qec8+EJ8E6q4W@mIZ9K8cxEiF0>kLS;$wb;i9Z{u`_7PBC)+1ZpN!F_7-hfEcaK# z!&&Rn#7SG0sM%_I1+Tg^b<>umdbOH9$y%3ZUfQzEY_FzY@v6&nKW$lV_g6EZS?kI| zp{*<2Y_))OUiTi2x7 zYX6VAyz1K4O}ue!eX)7JHMf3*{swQn30+P0z1Rwqe# z^^K!O+cx&q>ZB-Z-#i(#ZPT>9I%&qMZ=NmMwt3!PoeXE~TNfv7+p^47H!FDct*e{1 zZCzKZo0F`4`{t!>+qUi1%`0Ag`|hW0+xPv|Eoj!h^H6B}j$^iZMUz+Gd1|zM=eb(F zlEvD0Uj}X8b#1R++2+-E-xh7(eebVc#bNDxA17_!^UPMi>hkJ)UpH;v`>s~M=CStu zpO?1p`?goV?(^#Ve?M*C|L?DU1GCNpM&TU?*z63Ngx5S^HQsTMug;)FS?3{V@Qy=b z`wZHQ*F5Ac-f>v&pFxMSpUxw}$vcjy*%@{PuX!Z8dB;(`I>Vl1oyU@wcN{a@XV_P~ z=CSPO9mnnd8BS={d7>!1^Msq7(WJ?1o~Rn{Jn2_wG-a{QQ_bL=r^3oMC^0eN+G6z9 zB=XjoGiMkW7~Z{m^XAPv`>4GiK73$gWPJVl^}qlBZ``=?^zHvY|NeK(`*rlpi??6? zdqu9h{`!AT^|AL~{)a|2zIgeTiHZ5_*>lXy%r9QNxP1BYPtcyFyU(9LzjWzRL`>Dk zj~`E+I@Q|R`sdFdM@L6PL&GOep4`5D+c|Rmg9i^bY}l}G-#+t*TleqZKX>ljqeqY2 zqE@U}v4W3}@5{gcPoF+LfBu4T)Qx}t{@uBA$2{W3wr$&NqmJy}y?f@&nU({S&d3mAHwdv{U6DCZkuC6|L z@?=0jz|qr>!o$O(qoccfdahl&W@Tl?#ls8U!O(Pon_0G z-Mo48;lqbluU`H8_isl>$ASe5Zd|_}98;N+lCo~yy1je%8b#d-iK;q&{CIJ3aaeRk zSZrZrT*>%G0bSFc_@Wy+KjCr*Tfgj~6DB_O)o-rn9Za_9HI|M#5wfA;h_1qFqL z3m2|kyLR5Zd2(`c8X6i22?;;{|M&6n`St6UxVZR_zyD{?o*f$-YaV{lJo?7>fB)b8 z{a;a0@&3)*umArWMBFfnx~rn1^7-@UhK2^`s8#j#_4biRmhb%^U4H-MnRDJz^Mj*0 z%_HwhOG`UMZ80@9-FWJMT=^v(9i5Ng|C>c$^p0Hi_22(5U%p(p`u^kp|2H50cX4r< zvh?Tur+;(XUd>;6;nLN&Uw-{xyZx43^pQ8OzHU1D-#vQ$iQE4jqxS~I^i*_QIeF&t zpFjWg^zK(6or(er2TUg$FsAJ*(@}5@#v9o{t{vQ@o_xtbv%!)%l{{1Js#c1Q=SH~K@%kxeD-V!pdqE}FBaftg#*XUB%b_G<2| zjtaAk`-dkeL$?@d+pFHW((&=2Z=iwvmxG@SefR=gR>z&)we|IN-THtnt2eM5zR>tF zDrS$N?8h7k{eSW| zM# zP}Sh8xg3MefftYa9oRU9WLSMa1tjy=YD_9GSh`)H#4J$#33!W!<@oeSuc{Sf&KA+#fruAZh0aN3} z87*q7UM%V{d-Y=R1UIdhOQwWny@kS#{qZ?{|t z%YM7{M%wDP+wPRTe!KlaoA$dMPo`zR+xcSI>UX=|YP3k7ujj z@B8!Z_51w{>^dI~u!!e;ILM*C=EET#^EV$33(SArz|3@3_~R6jn4EV^3?<3|`pljR zjSlBB?mSXfYnMK2%al6VsE2otO`Z`$hN5xLZjO+{XYbxRW87oJu;KIh8{dL9Y20jd zD{*z!@6A=eCHQiSi?4sI?v-;B6)uSQMezn+jq~mk4wk(Iww<~-ZsZsqR(?dA6ml`SxS!1B*`$A&ify4XiuzfV;>K55IhbKNBWxR|HY z&TH+sF!T3a%MG)W|5;`)>gUUTxh%P@>eZTc=d4oK?YGN%!TwjhI(y@NyR3J+#E(_K zpMU5t>xWf;{cM&WE1&xGBd6;5JxkBo^M`-AWMZN}2rHf?Ql#37YUVB-^5#!0>dr88@bX~Jt%4D|dCWmSl8notC zDaOj25R_u`X)_3!{5gkX#=6QSO{|9#`Tk#2acN|jsN~+_AtbG&%CMzC(Z(b~usvd# z=BK5KxtBdeUZ=WhMXl^+uy`bVd6TQE(309^n)fB9|Ijw5679iSgs7ev`Kl}o~I2(D^K@)*fhPI zSuLtg)91XXvCa`2wX#Vo&$JtCo_R9xpz*?;6EcG?TbQ0WV!A!)Z0;eo+4pMVE&i&U zElgTE`&kUH)!CirN|KJHzpL@GejGWovg-1@FFigdKi&KsVy3RaDhwCe=KK-~wdQrVsPhU5db?$X$xh9n>Ay6W8g2D* zw>T8M-0SM9zTj11XR{WsQ)t)D__{iQ_qBAkW7x}%uWK4VHRc5+Ic?c>)s~}TbY{-eVadOEZo`@WA^;x=JlTKL`%zJ3+HpJHww`@ZkT+4qY&R^R`}_iQgu=3CEQ zPwq24U!t?6wUhr@_5-%tDQo2tH#i@Xj&0Ofs8H|P(I9&!@k7~=4xgq`QX<`58q7ViCB@7;ZpC(Md zGi5HH6F<|-w&M@9In9oX}uV z;!YIWeIqWB&Cz95tNV=Kf@am*JQ4(X0u_?Q*agj;GZ?vND=waKpUph{2rq-v3}%K` zaUOG7?FyPiY7_)TIrhX(>@VVRxyR%AV=t=^SM0Os`%w?eITSvEN=@=#a6 zeL?fBoBzvBoY>o&-c#=SnCYe|L(GF0lfKNn%TV#%HH?p8X7jG6df!hStF{xEWv?R7 zb?~@D&&HnS2QmyQ{vO-n4JVX~v^-}%nQ=L^^5cSN)@Qsow>eJIose@q<|UJ%`OW5! z=DzW>6`tOhsWC%WAb>&PAzR`$U6!C1=4E$Zhb?rQD%)f-<*l>At&|gbMQ-1dIaI_G zl-tfuIoQ>7Ay(mff!oZ&y8J8-m2@Ugw$mCv%MVz$-sk9amJxcy$8dr{nr-7YhZlOh zomKxnIxFvd!st-hbmNRnv2=$s>!rrS%m?H+ICtD{%&S`SWPt?t&8=Gmn~WN791=ax za6oy6y})sPzvm1S_WakV;%C_SKlNd4U@mhy7;e38NyUZII0xFpp{h1Sa zStoK!SP0m;3!Hw?sJPuxQKQK@v3}>(e1-)~r_=?a%LU5P1?m?VpGzxadC1N1pmvUM zqwoqImW{bl0X*x|1d7x0H$UKUHAv^2!EeUQH?_SbWJ`;Wgow(DHtPpWwc!H&8+a8K z3&@AoGF)hKNjFZ|VVsn~b?U!C4U=K5?&R9i^75x_3>OUqEG9HCI2b3mmB_DXxih`} z>+uYxhh=QX>lZ0>uqx(9&M0FIEM~aCW3su!a(eTBmQEH&;{a#lt7+v?4&{3q8kiG1 zTxU2}cyw88Y-eCd^%dt@t|q{KJ#USNKysVWpMV}_My}cnfo&3v2PIm$HgdmR;JYE* zc>43|V?W$auIMqn$akiqYY#*3GO=D3$KK`}*$f4}3=?`861dttdhY#b=&|7DQ?0u_ zBP%3Az{I%5V{#`;V)^0?eW#!I`5o+8Z_&dg$kTX(J9I}s^TYm|54agMyBQ7ym`k+n z67OSZ=u)W6T6&C^tAl-7 z@Yp@(XV}rrb}{doc%7ZG(NlGSuu3kLjodvKni&{)Oe5PYE87>JnCvLX*<;2(;emkc z&xuTh)f|pI%oF<<92$Znjg2#F{41vhS9V_9;LlmuW3Xj%nxycu8D)$wbB<CvT5G59Mgv~v!U`qR^5S%X zq;zh9=TrYrE58-ab9@0mi(~Fn^-diqo{g$~3<^s3bIA2X`QOKCJJX6@>YkqKq zz$Wz>%oB@dnWgV$<8_KCV*2RMv9ygrU`oe-4}q@+0@W+~xeRBE-kjrJIAhN-0eKAu zj)_H%HwETc2z-we$V({id&a(^f$PJ{Ihrmr-s}{bsU|3|ky(0;XK{k@zXk!VRsrh` z%#H^-`^vbo!wSPa=KeS~hgC~>qd+>-O99SZ=@&CfSsXhT2QX(B3z(QMhK=ca%N7eKmUemy7$xM|y-K%SwOCJ((>+UYF+0PBbicYMJ&zUL8Zm;HA9tPb@PNr6`FHvWu@4vMOxvXuZAzVCAfU*s-?H0bs2;j3Ix{NT2+*)Atbo! zw5VWhX&gu3$}LebheX-<9HST(tYqG}djG5Vv`~Sd;0Vz~mCdu(_^`^Bo3384b&b5@ z%1ggO52XqUISJhG5@1P-xcw?@pOwJFRjai(ay^X-N!`dHDHy?haV=+I?AuxKoMr1D zZ58{KmHMYkkYSm?%UkPNqBn4fZV+tTz_xn>&uiD2S2qYqZxpiLC=$IrE=ro7Ac|LAMy)-lX??lY#VRBkRq2*TYQyS8ukMz1d1zUUJ)J zyWgANCT(`$4m)SH<-^uQx77hV8kMC2xlegFPpe%klUeId3*2uNzN#f)+r3NBg_ULF4yHzVrobI?iOS4|TUjS=+f?my zk&9ttmcW6J;l^Tnz9&cOGwxwhT*GX*{gn0IE75zeRqwqqd+)8?d+*%dd++z&2mht_ zJ+j{SBzoVo>U}R}?|Zd--<#X}-u>S9L3;lhHTGLt`~APNeVe`i*Y5p)Ztws1dq2Y+ zujSSP)1?nI7#}cpT+cSgdE@Q_e18tKupZoGtaSLdz$ER15_1mf7;@&UJ}CF+U}51w zo{w71@i_T;7yccW!#~!WBfjJr{y2_OWA_!ZylDN zvd2lrUOM2&`QU>ddye?rIpX){NPx`IAe*BhF-OB{jz-Km8nx$W%$=ige~u=|983BW zVqtSEt>#$9oMSJl4=vzg@bZbzUvq4?&~d(rOcIPtYL1+rw2tp=TE%ivaocZ!{;BI% z2MI1ZEjWRjq5uEY@W_G_H8EPnN&>QH1d~<^a2?ofF38Zty_d&uL;o4=UD|>g4hPP2 zN9^qqJo;K-*6U+TjZFRxar5_RE3FYR@ey=ibAof>fsJo8&vXk+6WzM2d%y5OhtICN z&3lA|(wG<=4zXO^xm!kSQa3xR;MS5FfyFukQUS-r1=mhL#mID!<@_7%z-XZvZ(>v% zIm8y8eK<$sm5pTa?p?2a%#PIvJe4`m8hrNKob%164oL}~;1XOFo-O31koaNE`6EK= zJ{QliZamJx7{%7Bxiv@dP>jHiYJu*;t=%?)-J&PgdJDwgK7HfQg@Z>{$&#+iM>W#iiZV zD>uC=bWrxZm0=hWUi zXYSrP_xH{P*}Io)?_P<$d#(2Fjk$Mk?Y(>F?%jL;|K5Eddpb>9e5dTaXSF_?YVWhzU>v5Jm-N>;7yxAfjnKodKR(Ntm^fQjX#W3(3(1Zz9=zQx zt#~$U;eEk#VljGm#p5LP_pWTZr#5|^)P#8(X4eTt)Cta=cOdHFgN5@%db62Qqy-!E z1ef}Xubl95rQLe&O%FFDM(!!RD#CXsy7ASmi8r^}>8`hXQx$ab*g3tPyqkO%_$CXz z)@*!q@}BzQIH7Law>Rd!y|wS{oqKQZ{d@aB?%gB1cTeKpJ*#{7V&1z~``*2|_wL=l zcOT^5f3kajqEO7v@BNQ?@1}C_TN(CzopfG%b5QyYyY>L``_~Ze=Csx zUS$8hB>sC@{r8Ib->de2uetxd?*I1&`5#U8KU(5{wAKIUnE#_||Bs&gKl=Xvm>~ai zlKsyq@js{4|C}-Z=dArd=iL7}@BhyQ^1l|@|5_6NYgzrT74v_s+W%|K{a@?;|Joq` zdz1a|E%Cp%)&Jfx|M#x_zxUk#z3>0;1M+_k+5b5b|L0i!pA+-{oZA2A%>6&-{{Oik z|M!yp-z)Kduhsv(G5_za{eSPs-2Z#;|KA7l{~p=@dlLWeS^d8k^Z&i_->aU$%E*X3 zVX%=Qf@LRTI|Bp5+qcLQ2A~-O`>4I|-+y3aWP1Jj^?&e$!S8?n-+uYuKJSN5)as+B zUp{;D|J~RBIn^hwzxp2>UH|IkOC~0!vuDqmMBe@R@Bj1X&tJTFaq845W@hHgmoKxh zuw1%y>Ep+bj#29#Jb3W+|9|sH#N2>;)Uw~de?NWt?ELxjCQ&!8UcGwf&YeAb_B?+4 z`2Cyr|Ni}3w{D$v^ilK38yhxkxPAL}T3XuCqerbHPMAgA`}60|{Q2|2GX(FRJ$rWH z!iC)2+?6X={`~p#?c3ME(Y4LZ&7VGfTE2Ywty{Ma9z6K%&wt2dz>+0Pe*FJmU0od& z6?O9D$(b`}Ub}Y9GV)w^PtV-BbN~MR=kD%q9DVcCzyHgZE}J%O+R@VwZr;4P^XP9Q zBcq289~wnJ*tc)r_3PIa6%~_{lY@eS)@;9H7ID?z-~agW+kPZS6BD;_Flh! z{p!`L3knJ*Po5ke9zJp6#1kh@I7aRK^yfb(C#QphgOHHW;>C+)Wo0`%J9nS>A0Hp@ z3r^XJc2 zkyp*4E;lqZ=<4e3*sL*!vgOUtaRtnc5y z|M~O3t*!0r|NpkOwkOY=<>BG+j-0n^*RJW)rw2!MMVH?1?d^4m++uES9uix%{J{SO z%g%d7EdBE3%ckT1U%!3Z+S+>a!T&qY|9|=MUrS3XujA9CrQhwMk8C{kKcW1*OU(M9 zm~N+-eKImKH{SfWi@i|Vc4gwMvv0rufAjvmcie^(=bjur`}ytL4~uvHfAs$UrRV=& zz5D;}{hJeKPoB8^-!1V-!|eb0mB%M8`)?j|$1iGfT=`Y6n1wT!Kf8GI=d;iMkKOto zm$y4AWl~MshBaF+y?y=d#hcI7{ZB%2PVPSUf9AS>8@Anj^zy%d?)?MD?&no3D{eZp zX2<6@FTeUm&pvqbf9I^n>vlf>_y2Ew_kmx;Oc)p@PwZ20?vnAuF=4%)+ zG;_&%ZGlf1XrAf!TkJL0Yb$)h;I-3=xWiqt-rLsP+?;WFRqSclgn>8GnPm6(LnjO# z9_|p<7Mq!~@$vBq%HGSkIX*2sIm0;n-kF`7Z=Ig!+%4z3Ys_|Nk?vX@DmT9yD^Ot$5JHV+J{s>|u)t zc)}oU#ltq4vKJ5A71}f&b*N0sc+{z}Y{jE4@PvWEF^$JPCf70^_gXw#@wm_C8+gJ% z^T`AkvCJnEJ=9h{ndD>k^2y`?H_fNu34^H-X)B*jiz$2gbb3OY=Cc`>Y@MFX%=mWo z?5vz+FQ3g$(`^u75je2&mT=mw&PRq!Qx`wa5)zp5e13~q){BMgUpL;+>@dqx)?@O0 z^kT`BE_d&xkTc1UCJeYjn3gSD^@>Il29w^h5I14qu4A}Q#V6^o#?HE5uU0#*HMtgZed*UrvF}SAZ=_7m{dO}$n$zu8&i1$8 ziccQ7d*gOVJ8Rh8isx&;->dol|Lynt4dUAQ4_fA%n0qb|y~5$tEdK6?SF%0mOtSF2 z%B175>wbF9%zwAjW3F+@kLOGDMXFw|h%T{m>0KW8?UmHQcfa27p7g7}-zmLi$E)q% z-&w!h`CsqPha=+oe?Fd2U%$tJL&4$er|stUXTMzdEw}Y#Sh#%1He&>>r05PaJ612|3a%d?Z}yn&AX@4=)9OkB7o6MF%Hk z7zl0H;h`fU+9~i(Tkyw*1wKg@Tnr(}OhSPQ4F9t-4%a;Vpk^TB!Oh6v)S$2rBK`(0YE?iFL|$ zN5pt57du^=A&{?eQE@?p2kT$Q_TedNw?VKcw>6JZ8D#)CgJPc2aPU17cc zra<(TO-j379A2RF%AX-&i$cnT;|^||4S_5|bGaN>cx~Kzp^+z9QLop-hQ;Z8 zOJGXT*40;-vK_C?bZt@zRmh7yq5YNfYEfLEL|4=*hc65H8NN6uq+2vQxmca`6F9Q2 z;%Qg}=cOy{pA0uJ&s-A1xFEQR<*@%m9gZZ%1rb>`!HPvo-#9cW3Y__$78X65l|hj! zLm;+f^IA5+w~j3jdzbq$O=8kK<}GYJal)lgg)O=-iu0@2sY;pd&|z+fo~SJ_Psn8* z8{-NE-bZ()IDJpswlr^RM3=z(Q^jIzi7BUqHXVvAnyj$*$rAaWJAB?-1uHzVIC1t~ zV(izT({-$R9y&Kyx~mDP^e{NI#jN!{(IXM8kY;MIt7TSVw@H`+ZyraB_@zi*{WIIE zdpo4Vd?xt)>0iktxv}$Ps{Nr!6SuG!x+fP$-fGtPGp#McFp?Ch_nBz zwHC_Fe(v+!>h{lb73Vh3`+nxR-S4008~C;?VE29DB>n3`hu@Y(;%8sDWqa`TvE6u~ zba#Via8=^8eI~n%*1oL0yY}(|zOPdhbh8R?uDc?YExU@{?N#XRUspZ7c-N%+zK**6 z>)MWUTi2DJeI57v*YyK@+cvcOzDbh)edC1RwoTK|zDcwGee*)!wk^wj-)2QipWn1^ z+qUgz-{w{SzWso&bJgKkZ9nFvMo;{<@49~WUD@v6cR%!*?>w&iKJlWo^73`t_bp!A zRjbW?mn*Z>NAKzTB*8roIQ%POKCS)GX8q@(K>v;->V6-)qW?USIKShV`MHmM)qfr< z@b5g~?)PcZ>_1O5{`>Dd6@Kp1wB3K68mLb{knHz))@>WFgS&U0D?j&n-tRxp9r$-$ zX!rZFNc!&!5C31CMhm_y+x+{1-*sW8MSfpbMgM&jaemje?dQI(tN!~sfq(an<9^>Z z&Hno)!+-a!>*v00ll~hNP`>-lbHDGqZqI$SyW8X3`+KUzpKBfFr=8@v$I#$u{OA1) z%RP~sY$wiC{`aw!+vbVq(jOM?TK$zqr?&sp?of>z9T8wtKu7 zr(gaW{dI%C?5kw|-?wi6`?ll!-go8af8YE4@B0D%eIMHW|2&fZ|Ko)JzE9K7|9NKp z|L2ANeP8lzf4_|W|0`ME*8N-G-%A_*Dc*Vi?`5Ob{|VLM@qZ4VtafAQs}pUlS9p^D zzwVs=|6hwwfBCZAzU9&S`loyBRsLMB|0LMJ6w$yYk#noO;qk|MqlI-`KN8idM6BdBt%(Why|oq zy_jDAe4CJAhv1uXk-F&u3)CyQI+`m#HnS!+>(3CrKfUEyV~fKKVZIYB(HEOlAGYW| zYzeEV{ItC}=tgVY3j3HJtzRZKm?*X+RkQ^;w`FL^u5xS1t`N-X5Y7A1rY+chJ+ZxH zMtjwc_C0Owzl8;mdq0~PB3SN&dq2Pb{eJ^Ki}^M96lTbY%x~Ymg`CCA%*_1f&!7MQ z|9|@QiHV5`auD(6`K|$f_)vFgST)1@U z(%G|T*R5N3>(;HlzP`tgALr-igV#QtKYaM`#*G^d4Gjea1s^?n^zZM#6)RS(TD8i@ z$469Dl#`S5*|TStFJIoWWlMB)w1tJm?%liBu3fu&_3G~K?qC1@|NHmv+O=z&H*dao z@7~FiC(R?T{{8#Eq@-l;-o3|A*U^CX=zngSI5T21_uW(Tei$8VvSYQ$;`}5i-?mZQ8(ty znPX>X_w(=nkdTn@n5xN>C%d?~oI7{UDe}OFKmYBcc3VW9H;TOc`R{-8$eR`sN5230 zZyA26qM|}YMa99vK}JT#%F62J&!06lHF9!tIyyQbQRR+No2r>GUXcJ11+V@Gy&c2ZK(j~_q2|Np;u@!|;+CVc(+m5+}vEiLWD*^^6_EJ>=m zefac~!06VTrmN4t{Wl9g9~4{X8NJ#m_VU-S|BWN>r>Cdu>FHTUAAR%w-S5Bu4I}PG zL_}P?`#UUt`nhZGH*C8aR(P{*&JWMz{Wl+fPpdrT8@G1RvTO0B$KSvH=9+ZcD`MHy zMUN&f`{@~T`2ElSM=$@6h%J_qlCq0E<{vrFChC@F>>}srW!sMaw~ajK9<}|?zyC{i z{$IB3eNE5Rhj0Juh25|XIprR?F(m7lQ_AUGNB_M4_W$+UPyhb^&uD*t4scX0> zz0U=q+>0pR0Pg+7o!Rm6=pnZ47LXH} zjV>nmaaC@9etrS8_j7qg@anj=QJ>wmu0iSj?B4$VKDhS-UM@A1dp{}DZl>C&ErTwX znq6Ra(|1nEwV7A-%21a}fqOq4Se8r80H4T=)cXM~mm<6O^ZI)1HHwx? zb*#BxE_&QoiMZrr{?^3NReZ~r%OT;pU#~`_ul;&0=CNt%^@R3VQ=X*qyOB3DmaqK= z?)}^@IIjEsPRaGP%M8js_n67rd?Isr zUgg5A4aGap+{t-Yq-!P^JVBXZg5HFeyq)hXcP}|{<(EtEf_=MotUv#5qZzwwU6o^S zz?Ew6`WyG&zZX>03sg8{F0;q&wEF!uCbB2*O)$E|{DJcmb7+3RXWq>Bd-lz*=`Z>r zYZw#o_EGq4ZieG3Dt!(UHf-s0dcI_R4zswfQh<&0OaFl9?3MHXp83l8jyFYcMKX)y zjYI*)XXg}t1uHO^lndlnFf;tt=wM+qSkBC+BFS76#wfeV&PMPEKPx8_!v;fv$Gk30 z%NQ7R{VI4F0-O{cGdS>ZCmj+n%C2KDnD_lZUyxI8PJqHs3nd1zk9J-w4mUDwY~^3L z^ibED^$K?dSVfux`r0%KrI=^BI4YDow`ml19h6eyCg0^4vuy9R8gW-hH~mo@3MD z776|imWfA{S)4eZur4m%p1`6l$K>Jt>QsZMA?r^D2Yv>JbCU%E+nmZC_Ox!fGs+mGa!RmJ^=d{5)^p zC0R!w@jdneL9L5bIPBG@@iu!rTEtLsM7fBOp=XkjKsk$pDMJB21IOk`OT9T11!rkh zavc#@VoZMRF_HVy!=zTGovI8S3wO0naT0mr!r>G7N_%?Vky($A%(LP6#M|W4xSUs# zRkQPy9-CB(9P7u!^8XYkG>2VY9b$Xk>u}VDjgv|f(ri~pUAI~)w@EbdPR;6==U&%$ z-TJz&;_T|U@29Ts`}K8w1MivycJCX9q`qzF@LiK6e)`5St8W`M4u!d#V7qxL>f5Fn zy_~7Wr`N71{I+=k@7fIa)9d>ueA}|ZcWsvVr_EP)ecO8Br&Lb5_w8H%Z++XgQVQ8_R7DXz6bsL zo4=Gv=K+)Sj{_Z_behD^JYci_aZsRdLyNl4L$2r_ha}EzXfr?akgpoCTx#}@BN~1i zyPod8C%XH`QG>pXJ?V3#nUs$lGdWinQMl%@-0vU99r!j)SeSHAQQC6DB->4srk{DD zX8rSIfZSDvMLtipqJN%>IJarq_A^iQs(+qN;M+XoxX&}A*+0)@_-&qb{me77-9P`I zE$G`k=ebY%M~xpEv)2|ESLjStiC=QGip_5xv#y$uz^@A(?+j~%&%SWmUwN^wPH4We z@5{w^cV3!tZp$+BvoHOse_dX{w{?ZP@2jBMzpkwC+qx?J?5nWdzpifR+Y0UdcuwC3 z?fq1FPyV-c!(Gug6B(**oH!OTk&}61s=Bp}V&S*V%YAe2`$gTl`p<9UW?1jXeCr>b zcSW;*-+AGO)ce`K=eh6us@uQs{W!OM-}kfc>wf>f&%nRq0K47uWMLVb+viR!P)sVA zukz=C+sRT-F+brVXB#b{{XZf$+@03e-1bNc)ce_YtEYbUW0eejp;N)@geTaiKV9JBzLNv+L6Ib6=KO|9u(Izw63!%-&D`w3F)6-%dsBf%krP|9xvv zx#I-tUWFG75iHFNtqcqd5iwP-U%zf`ZFO{XWMpLIEN?fQ+Iw{G9L zd++{(hmRgVdHU@6il`QFr7+ z8uL!65wih}dCLi>LdU$-N}7ZuODt7blR%5)uhw)vb9Q7v?zHY@h+tXH*v7!X@c;jR z1_p*VZ{9F6GXDGbpN)+zIXT(h-X5~eWW|aV9UUFa%*>}wonm2OId|@yp`l@Wd;8a~ zUw{7m`RC6cE-tQ+kPs6S6JK9nM@Pr(>}&%AgV4}WMg~SfLBaFq&-eHDL;9PuX3bi; za%E>{=j6$go0^)qxw$W2zWn?5@3Uvm^78V2`SRu0uU~)v{QvRe$KSty&zw2K!NHN1 zmgeH(l9`$5>FF688+-5Gy~mFqU%GVZ!i5XZpFcl(^yrl z`SSMd+js8VdG_qt>({R#S^4{a&}I{AB+$Z(qo;vza?Tl9A!V!xNLsa}GXq>R>$1$Rlx4@lgAVQ=7BPJscVqhzK>z z-tZt+;M?05m-%BD9gZ@wurSig&S$G5WZ+b}pVtII5pujf$HIM3ZI zqtL*>&JgZc$Q726Xl*1A)X04AZ^46Bg|>=w-1h=MEbP!&_M*33ebtLc-B&koJnk_$ zmJ!oy@$5uTkJYyqiw$i4X*`**gT?d7M2}rbDgP(=n0cO>Un5XR9%f~!LQsIo; zbz)JZ_D z4lITZ3YIS-nG38L0*|cPu}s{7v3bG;2Ei(|1KNsnpJlx%;Okh>ST1eB(ZH+fP$0u{ zR4)5%4&w=h1qy5n80N6BO(|c@b$yz*bhSys1V(0N9&K4>3zq{L3|2F;-{)v=DEDAx zl`%iEmtnV<15c-qf=kI0Ht-&oGgkz=R33f+ciR3#=B$YBwS9l{`Md+W?w1QL;-Fre z`r0p`UfY+;0q(kAuORi>%HMvyp3trfx<>~zXSICoHY?RNZ@)o%ZL|M)-i6Ltz5RZ! z{J-vx2QA`x7RinB>wY}yF@N{t@dRk6?dQ`O>Fa(zn^XSo=ko>adcR&QnV$FS<%;F& ze!W_={oSwE8;&^D}|9*csuKyo&kIw(UKc2(x(P7|O zz`*VSxktxm0h9QN18i2%dvrVwaz%ZB-lKDnuj)gy0?$H@&}-WSXMJeV@L9+Ox<_Z% zhgO50g*@Ujc1Yg(&}MOFAz%3k@I5*XJc|U{J&q_zee3{Tqci=)5jCriodMu$bdG98 zee8+=U!!wWuj*rW0?%TJzk!DhXMKcRqjTbz*{+G%sWpo!yGG~#WD4%lnSSz2n$_o- z7kZYNEC=1A6RfGaXPMddndPXDvn$-piM&R~ z;_OPl@>7@R{ra-pfp=9vyVsRPQeRhi_^t|?e(K6HtFJ2qdRK)k|Fyd^=C;T=xFEY6|%CjPoF+zVPV<0 zaifHU1f(6!#KdG~X7=*sOJ!x{b?eqGU%q_z?%ik3ocZ(TpTEDqii%2MVd1}j|8L#8 zb>P5(RjXFT#Ke@AmU?=6LaOhaoSc38_HEz39nxS>R8%Y|CD7`va<5=@i}|; zETp}`#>V#V-@kL`&i(%V8`35*G&H<&<;u^WKam?J-@kwV`t|FtU%wzNhxYb%R#w&! zaGQjKgCjdTo12>((k6klC1PV^A&rwSU%vGB_ussE^U|eDkTwHmL*@DN=S@vbw{PD* zdh{sutN&3G355Wj22wB6Y^IrbIyehtq=a^&cW};#^Kv%H%E_KX>EJAu7h@1)5D^u5 zg4DrTBFW7l@DtI&VO3YyGKHCe$&tNEX2y;Ui(G@b^t0}q*qFSIR}QhJXP?qS=qBKr z^aR*FgP((ar|Ua>kwIG1Lu~(s`VAz|q8?ZWC(e-V<73F89?KP4oeQkN7Y#xd_1xX~ z<=unBoB!$UBXLd74qq-lHw{H60l$ogtv^FL9=6HsTbzi!f75ruzeo412ktdJpav4Y zMLj8QCmR&_r>tC7sm&2|Sb>pc!?QV;EfqRAN}j!xVbow~SgxS*;N+xvEpqP640b#W z4uY*_uVOfwm%MzjWY<)N1Dp&A1{~ZB8Vn7KrnGs@=9#~U(}7Xq4MT&#@~&4}xm~9; zPY5tbe0;TbJ!|9Zb=$t4e7%0-PcGz5z+W;>z1cina6%?y%ZZsR3^op{*Cw%8Fls3> zzhGbxzCF!ba_h5Yw`Z(*wXIuX_d8-Y0lVvb#AqN1rL%w*^{k0wR$D%&^Muy+Km4cr zw>LS`H?Zr08%RGMc7R5;soX&NbjJMspU)TE^>H_l_U-?`^x)9X z3+otKe-&)ve=GQLe!()XHXTL#bzVA3OhT<3j&r`LYc14qifUzW`o$5kLNX+&kw;|; zbC2-B%9#tAwsRfeH&~%lqRZ4IlXGReSYfk3mzSTo2+JNW112Vg0s(!K#CbLu95NhD z!Oabg+^HTK{PR2o3|Yi^7#tX^KN|S+Png2Xb+JW^!6EE})B{1zuewSe6Jr(TfbJQD zH;|5d95X_0AbspDp!A+WUn(__{6DgovSA$a@c`Vy`2YXEN#w1!Z{MCdb0)J3G#v2m z-Mgo6K-bc~dGjW={DyhtEtAN*Mp3sI85zwZ@0v&6c>n&rQPhpsuV0%*+_H^2Y8-LX zDC(|xeK`Ty_#%a^arqb?hTfsULoi@5gi;lucf z8`06xj~_oakGyIganB;+hDFp(>!>RpQOj+kP9Hn{*d=PSVdTv}|NsB`|KB+3`mcZg z0|Nu+%$bvxmSz-jXTydKU;h60_V%`mIBp(x5{{6ply~B2k-vZce*gd9BI?e;g9nYGZ+`px-z4(BMdUe;=(UR%FaG%d|AYw>wr}5I z5p%V@y*)6x=i{IM)2B~&idth4dGYSuyC#u0ckkZq6E*$ZxpP+0=a(;E-q6rs9&`8g z+xI{I|6jLm-O-~*ouZE!MBSP)Wr|zG8sq4@VPRn@DJhM!|9++)xI8J|9VG7kq`jO-Ax<=xv44iS4!o;>Lsz5V#{;}Q}Q zii(P5Wo34uyWfBNuc4uF;lhR2zyJ3y`)3h;cK5Nrb`j@5liwB=$Irg2uC9Lb`m0^+ z?Sl3f=g*(tw{PFITc5n+Ht#+E-zENJQsuRE+i!jU_0Kl?_|~mkJtOD2#_ivC_5bSC zt8cyfudAz@T>ru`;c`e~Ur|xff&~iUuAS$JU*^_un@9=F>0#w;y;MTJ$(PbH}tb|E4Z{lu^3##)E&GH*c=)IMO+BXKwWl zpTwmbj{X-C5?XWUe^_+I!Q;TU$wjX z`uZ5(Mp^3(JV>i{^%d8O>^9K4)5ibq)!ozE*MnB=?ygBV%D}+K+5Un@(xD*vAoQ4z z)P)l+aBfKoU-7Ip`OK!!E23AQUIxuupS5}_#!$epqGHd-jeO0^*rldLm}cDTtlaxS zwB^HrL-*H0=B>j8=ZQEKzPofqe(&6s;8nZj3z$QM|Nr-_TGjC$ylVH}Qp1@Vx3pcS z6!;v9`vh9GTW|gEpP+2AsDPLz+XK+5U4NtfD~ADoei z8dF%?z^iso8#;xxXl#4&sM{cFTenXHOW9qQos0q;Qa*159``%2k+5nvWm=|Mn9e-- zy!A27=W|N19P>e^d26i4e5?!MmkT+%lWX5$y)`j=@E`MGlg98;E9F2Qm%C1(Bai(T zgOo46YYdl(T9G8GZ^NYFvPx*e={psHC56aKoJt8}Q!Kah5 zWrlN1t}-~t?R-#TFDrP3_i67=$4S;HJMSx(`%QSUAULk-_^f)rAFn1Y<#koyKQ8A{ z*{5u7^&}*{H{iz1&+9JSPF(K&>&cwgdOtsu{`NDxHhKRVo7We9hi(+*x4F}8xcA7r zWMM{$4-B!}7t8H=@mSxa?(oCav2{;H%^3}UKHpp~@Zq4oy#4Q8?(6@@F`7&~%FI85 zIf+T3sdmMI>TfUaoqZB+CD`FmJ2!alt7qZcIK}i!M3>C}th8g>S=0U|37a@}`{R2q zJATOc?X4Keq`>HAgIW5Y! zdj-ukoW3XqR`}*faC)X&iAG)2W|TO5IK$mkBWGhZ|A&VH$20aH=g6x_IT9~e=zdhg zY+YrVOPsJH#}V#jAKS}y?uve|n8vUmk-6uG&-Du%+u8RVs}86UczQ$Qh}Jv4-hvbk zA>Ko_ZdQeTE>o8LXi7WczGy=K0+;JDJPz!pOa~4Bz z%gfI;Hk@aWR`B3c>^vDiYeUQW7FDzUljoMRFbK0kux{^_WVQ7(_m}V)PkY;=alPULgJ_G3&IIYy_OP2X)Iu)RCGpI6 zQcZHatZO*&sK^O@hm5lmUm5gI%h6O(^}4)_g@K#@Mgxn(a|ckX`p`oS2A2bSx!bO^ z$j|Y3^+z%|N^YuxG6RFaKjD+Drv#_ztj$tOkGj0>Q7^;Q&y6Oo3S!DOYqXr+&KHsV zb|pbiWMTf_r=jv+LiX>yGRM1iMdzRu6N{QuqsJlaBEpOiN)ra9*+V0ZpjCk zuB@6~@?Aj<(>Bh?JNnqcMoRHq*0;?kPwND^SNmOBR@i)+c}-UEAzS~D^P)Ks2RYgt zI6VG8G2wZ>a|Y}An`i6Oil^znU9SIL>&~TV6BZtKeOFk!`l|Z6Z#(5QS1C=|$ygBf zo^gVPGhb=7TgRts6VKe$HhX^R?7d?~dyf9qW52r7|HZEFN)vexi|q^C%d5l0t(_1Z zSN8j0-n8kfPd(L_>T)CTo~Ba2Pa87&vk>bwF3` z{=RkN9MY=Y?K_V9qRd;*pUwDTS|gj$!km95x0zH5Q0J}vJ~YKk-{aZPz?K&9{_h>@ z`)tUob}hC_FDPg;x3TBHz5}spx7_@=_`kvl#~JQx_U}BC4qCPQ=e}(I&KjpW=&IeS zQ^o6wznMgHs_bxJ)e^{MKjFwAK4TlRj6zAa|KD5T{bg5_E4Q-(|3&m#G zeVo+4_l>LH&r`+Ebx0u8hF+2t*zVtmYF#o zPF~ zd^y-9_cgHFTyU1$HG$b|0`psg8kGxm&%^l3J}~c^z*XVEs%l=x^1b5PvZ_zzjS>-g zU&8CpZsatdP_M6Ep>u%6B!KfyI(N#42Av0GCF;2?>I{McjGP9|h8`7PFR)rNaK$(< z8!;5}JZRFl$TjXLcrV6yQ?1ddqb0tbkyoJQv0I~_217i1*(JBe4`t;-Cl~}aw1#Lf zw3wHcU2ox0XlDQ3eB)bl`S+&S9fjAXF&J7jUovZ6Z_e19-X>Ymesf!+%nljl1ZKtu zJcb2aQ38y5ADDC+*f|)O{0{KPA7C-~AHc+8z^J;RME3)u{0A1N3rxBWEQ$e4E)&>9 zC$PB~um%?}iZd{N{lIL-!1ek-bJ_tW{SQnR4shx#Fo-^2kX2xpc)+m5fm`(er@(?v zmj*_OfZR-mvdjr=m)IB;4={*MU=U4c(JNq-Pw3Wfs1bH36;@z4ah;i0fJx^7XEOt{ zg#))m0JHFfK5y|}rvRo*1@_DUW{HNHt74^@ADa0Bm@iH1D~f1jy1*zXz$E{HNj{;* zbOM`v0i)@L(o12?KH|Bu0=Y*u7;F{TE`~AME~wz0FwsdNm)|ni{{fTU0fvwtEblbf zO%p1ZF7VqPV9>kJr=`j8(u2iCAlLQ+|FZuY{YeiP0u6F6N=&qU$sj+0A<2NzsiEe? z_O^;0Q>u2fpWMh<_kt%>fW;$#QNV$P*MVu#2WE2t{u2vWbOabB6WD$p;F*1#XWs*k zyadjFA6TMh@RtU#S59CrW#Bt=fwMG#H|PS(wgSF454aaIa9<8!|FMB#ngK^=I78t~ zzUB{1q6#d{32g5ac(yX|l^Sp@pTJl6lS`$6S(Rb>I|eqL24>C=EI!L;mR{g=bg1HN zU{+z^{=vX^kAZKp0hiAPo+%8>f)^Oq?d0KR;JNpJw|pjx;{ID@>+8-DQmHsH84m- z&AFh!GG_vR@GF+=3$?Bb7_SJh7!>pz>0o?!v;WF9raNg9@BMFMP7;{^a9fRVWbTDy zxy(OvEgt0lJ~?0V#+3g%rDlI{cqqX9%DqEblX+@G^Q#6P_X+Ip1b8QHXqdEs-%o+n z^#cd12D1SJZ$klVPypw>^3^jBOm+R>a4((Pq<~{`0=w&h1&#-pBpMbQY~Tt{V833# zQR%?Co{LGLfO**mj=k4eUnwj<9Kf2#z`X4PbH4+#NBPpC4_x6J*tTzIHfmU47{y}w zfn!+#v+DzvsRCS%3s}`B@HH?jk8NPs_JM=x2J6`e9D!WCr2@P~SzNz9aLA=H-w;?4 zdXry9dvZrtk;Q{jW%1@Yx8}=zUwKY&m6^e+A7YH60aG0(tP3jO3oT&L{Lipj!GPz( z1>Qmdo<#-?{U7)`9as$*IP4R+mN9VMHsHTLfumi3M{Psbxd~jI3e1iHy!IDZmI|;l zS~CWIU{rBfYky%&8Uy#*0#>yK-rEh_h7)+C7?`-SnP+}r-8F07>#qFu&l%Pyu&WuY zHz{B#O<<4x!12m}zrT$CqQkOl0j#GLn9m$odqaWW(1F?H08i|JMW)=mmj!tJ0$3h> z;9Ducbt-|IX$9lqa;D$|8{2oyz0}rlJFJ^2eWHLv(afk#1B3f%-u47efeE|*bhN0YPn?~#+d`*s$L!tHH|~BIz}jRnAx&Uo z><8wh4cx5`{2PC9e2M1pDqwPQ;QVr6XFtORgAY9WcJZc6SeOvNLGcM+}1*_v3iVG|b)V<~o zf538THdo*O1kMW$EQ=Mmigxja25{`Uu=Ya(PdfwK90$(13Ot7%EZ!i%Th`EYESt@M zfq9w%r?M6=_Z-I8mWMrF?2_DGV;OT=Wcy*87|GceoF6SC1O3|XnC^X>dv9CQ?Gt(TGEUpA&D}BQ^yG#7e#y+)AFBNln1c>* zf4acy>A-s60;^xak%|fIQ4TEn6WBNzcn*2<8BSo4`^6kTmtC)biTA?U`)61S6_}$O z&c#%od#lBexq$U;Hq-S0*0~CtK?}I!d6{_}PA4QBGdJLgvF2d-%h8x~EkT^=!z|{y z+1zfkI3ERYPKmvFM1hqtU|od(&&35D{RTYW84jJDJ$stKRka3&$+0)5o}J1e!2Mu$ z{)c0`E|<-FtTs*kLay5nmV0ci&)O!wbi2)T;I@5lxufotiH@}_AuK@+TlyOqwiobi zyue$rfk$=1g6su+D<`lRJYdrOz#{uUfN8S8devTbw````7{;`_XWMzs88t9BuB|Qb zWfGjprmn!H_TgON0-jify@drVIu{szX)qW(;GQ&rx#cWN!Ue8^->l0gFiLZl^}gMH z)n{4u1D38E)!7Z}cQx>M9$*nXU2Vy*yy^k(k_|kvynJ_~Sj-+AtXuWSJb}4ifcu02 z*K6_HCN+64YH#13#%T68_mFL#qyme1%NM2yhW9Keiuz-Eu18%Oq~A2>z_EwfhP|c_UUXWnV`Y)?*Wq_LucUL1;TUKFE~tAoWOP< zVad`54RTrco_F0#=RKC)@JxNfv*&A8@0!aXzk$n@=lsD0_UhQpItHvqC77lJ@Ycz( zbF6#Nah9c{a%qbnbEz)>xdW^_9N5_EKdcO3^E z;JMDn^zi^|Ou+|*{15TGjYccyzWw&*if$3m2Q_>mE;}Vm0USL&Qz{?$Tul5d8S}*g1b6qwXeUmS& zeI&q@XYiJ30)u+OmY@ROdheqP7c7%Bn0UHjkNE`7b8eihw^>bBpS@&usW11!9&!HP zuHbgsXe)SjZxg8|8*GChU~nz%cq$2KlwNF^Qw)X*YnQjywJ)QFl+Gw_5yDH z7uFmSKN&9zEdJHNZDPO`P`@tdK7(q&*Dtden;&rd^z+W(VczwZDe@MpnZq|9hMPhE z9r!{OnBOmFja=20_dn-6!}41OHA}@Abpp6=ho5j;#jQDm-7cQlB7lA82Ch(o+4I3tA#%|BB{}Omu`Ed)glGC!Mr&!PMa5BoO`*=)P@YrLLiay7S zfS{)*xYYgDv`8AKam-Y)U$Vy1$jNV#pw^l@Hy1GaBi$sN9Cg8f`9R33(6w<#XNA5F zTNk^xj#WDBO~j_uv-4bMLvIppl@5OwvuXA$mV$4tY~A9VGJkk)8lE*ui(Qhicv*@- zi`+|wMh3;T((`N@cFkDvh|P_ajaN%&!j@xV(*t}mc)ip)kMyURG^J=vR1g0@UCDgM z#e|^c+#T+3g#u41B+ObXZzgmsfywR0RQX*e9xN`0#OEERV+})sTpTJWtfn%MIIlLzbEMS`8QnYFb zSIdvi6&#(PR<4kea`9TxXL1B`lkgFNg_FAU&~Flcd`qQ4>CjInPBE4r+y-pQ3!Frw zS#nb6_*tz?JE0fVsX9gBKm|{W)}#}QH?y@gxS9r^d+8=B$=0|~jPdJE^%)6jj7M04 zb51-oQ=2s7ET?DDN;dg|MK2Fc+im2?H?8W;hQ8@#lRh4m_WZx=#6h+<85T=s>eana z5>IVf$v)%Lk{OAzQZg%#un2!iXrJXI#=zzue9x1$zv#;5gVPGnxCpn{6l#7rFwrS# zgR^0afRjtS?UM6(`K*2&sHi?8vwTIGq7S~%!AA5$fNj6qwv^VY{%RNm4ZT# z21bJwE1w9yUR38YtMc91!>k$ec0THI@jF?5UwGO=caip`8B3pwPxEw}ETPFu3<5Oz~ME>_lk!F^W57DLw-pH&+edTc@@)n}RJZCJ>Wv#qf`Eifr#Zfo$Y zi>_&pmg=cmOD0s$m8`W<-NzB|<7BjggpQ{B6n7tkb8SbGPe!w`tr25rVw3532@MQ!4owO&PJMRFsjM9rn)v6qFl1_YGFN?I z6#Dc39fwMTgUGgTjK&5B1w9L#X+B94oxhqdF z^K98Lndie(*8dk~xI7WKz^BfcBDH!0Glzgcx4uE6@Lz>PB2p9BbPq7FWxQedn`O|* zGa*4hC*dHckq48(fd*FD7tu_17X;^R6WLaL*OR5{0`tN*M;Pa|FiJd&5<2i9W0mlV z6cy)5o-z*-+_QO423QH5VM|C*$&=+`GgxqKNy-7%-cV0gtp`lsLNXusF|LnhEokVxdUd1NjRWj%1x>RUNz0Ewm>!9(R1O{C$kHww7lyIXLw&7Up`w~SZ)85x_p6r zrfG8;Uj1_2qyP8BTC2~OCMM)+$b@m-Fq*(9v*c%OL^ngVrSKW9Xv-M(rx`&J3>Hhb zMQX%}6)X~ctH`8%<6?hX$r4rBX`5ypoG#G!LAdVZViWF$-2y-K+P=;TpJ>3qk8VIH!!Xdoy}-3$XtD2dmy57_UZDNl<@Oaj;P6n&9&og(I-d9Ky=&)|uDsXyX^rz~Bzkhvu*Q}<%RbP2f z*vdGY?aO4TR|;%qIgPzObDC>ACmd{(ypqFFvE%NmtDCt`tX{wTaQ<4JjPIvz|IPRR z|5W+4+{tY-s}JsXv8>aT;5xt2=I!*X@LTiN9k{l9_11l*EX?PgbgEZ|7SBG{|L*qJ z@{QZ`wjQv&z08eq%YNy7uPiS|Kk9F{(bk+-cq;tfr|JE(b^8<8`u=}neYV8Ff6u>( zthP3@F2-!t3p}Tw!#}s=pg|z`==U-tJx=z5aihU4P0=uj$*2KfbHh(LUDHIZ_WzEXFSt0vz5dtL z{dK}qzqUHNS_b}edL&hH;9sj*=kc%hF@L}RXZpV1zJK?=B@X7>xwkUbsIc8MV&1av znRC};Z7z$~wpW9@lD!>1D%)i&c3`|=$L7N|x!ClR@WB(t`%fnC7j`))65{CP%*MT- zMX2GRM33WQ1_y=~&i{uU|F1syTN-+kaER4@QI$hVCWlVXZY=j;3yNq^D>-c5a@b{*UDOxd#QA~VZ{W@ncMmyjc_DM#E&j=1}{xU?Mc zTyn%KK_*9oU5wrjYljC(?j@PrCXb?HksN#|DbG*#uL`%qtv`Y85CCBSkjy26WUTwnizxIxM z=aCaVS5EXkInnpUBirUgtH{ZTDkp^%8~R;NP6;_VHRa^Al9SVA8YbwRoVn!WES>Jj zEhpz(IXU;q$$4Kqr%v&lEplq1ir1 zK5}Z!l~ZfqxUZOVYCX&8NEL?FHVmsn8sc;f~nI~uN zT=DH*+z@Zj@c+^mW|JSxz6V+^nKZ;NXgKO}`e@DR)mxbKXRszrIeVkV_x6@^uYEl4 z+&TO9i64tH%cU!ft{)gUJQ6*yvOZN%(=gNjy*ea{<}&*ypH$Ilyh81&+)Lj zzkPF#@9TxgEM|KHhVY1{%^?j>rZh0_VD^x>sQAK-&DD+PsXN=-^Z)-GWnSwp@zzx) z)OW{~iyTK!d>0Ae>hJ^iP&!Qmg_0ML8}f*PPZh4VJWZyP0x&tB9L~?&TdOfkwIhdRN_! z%?ZxCa*@sUk|V1pQ^F-@*DI_>Ow2bJv@IGw#hezlZLqdzHh$2+_LafqL!+?*i;IWv zvnl@k4;c6y7`M8xI3=*UYWT;wG#VN-R#I6(&%r%q%6^FU~yXB^t5OLQ?ueR4Ek_bTIq=8~_B{u9ny=bo=@^+{XW;K6X6aX~{MZ*xLS zW8m9sf4?-CePC2R(G>AED6S81^q51JW2G$j3Kn_kNxr*M5|NQ2^m zCffs%%r}~v{|3$b+T`jHWu?&^r^CG9=uO$Re)0vZb6A;NH=JjTV2bpJa=Mm#uHJI8417CUmY6o!XM}GFjTXshS+ch!nZa$JZ&V~lvw?=Mc7{Ly z4_^xoH;o@>%|5vDTQIvZ++ycw@#i?E^MduU%*7Ke&G)}F$eBhhIeJr9qG{RRh<@J4 zNvU_Ql?u8tFkLcf+P@}XHP2n!x2{|Vm@b(x{Pzf86pOtRYuhl>v?20CGy4Z-(S|5y zh9=P;&FnXrWjpTP&xwnVY22mit8jtwQfT8I(POV`BkgB2&o^ywt+>s+B5HRn!;UGw zW+&oAZ!llF!+heaD__A)*BQ*yZO?s@x%b89-u;^B9l6&SwtBhTV7>IG?N4o_sKt$) zf6qpC+>H%j{IVpjEB3VNjJPLrnU}CKG5zp8^7Q7>+&jn5#`^v^%YK06sqMp@A4elA zBLC?6F4dsgU{{Gc} z{Zm)h7yisA+IINd{&babPE6xnQ-+PM&1JDoyG$7b?7Z)rF#Ola2p9R#bU&wMnQQa? zD=c;vrv)8Y#s0FT<@(E3Fvxa>)>?RTonSh3w{=f$^Zk-mogH_L7BtUMJ$qZ0!PqT1O!tY| zyN6kQp3b6=a;`lSab)4rU^|z3&;G>KD>;55H(FD^-s^D<^9b-^Rk#lkA9rCO+6V{~Y_|AslF=d1DJB69@O3SO3NEkVo$89!_qat!)c{wqW3#&>*FnzDthLO2OCPqT#~Qh9l3K zmA)|v+un2g@OqQY>t?ft8Kn<)uRZp%XS>_omD|qBAA9w^Eq{%{?HX5B6Nj)%H4VHknv*&1 zGCz208^O3$<^5(m1`&-%@e&N28QIJM=i^K6vv;%@)jqqQb6(IRf7i0$r%&F-tvFxa z8g)nQoqI0xB^4G&ffiRIJ&TBsQjb-a!SFR6?7kdh>Zn>nppn%n)ZMtcb@s6tj z=1ofX7#6&9JuI5KL-xa~x(3;f)0Q`qedHQW)-|{339a$$*8Djlatvy#nJ6JSMFqtW^NadAk|BYdeVB8f~{N`OWGe_*T7tLoOrK!{+s*XX5Na13wxU{iTExtKbNfWqWSo_miQk> z%I~i94Lqij|H+MI-+$JvOJX7!&X{ezWOt)svRy;Jd0E_&hKcnI{sDelr!?pa_-=Vx z9eA(tTKQku15L6sT1&1)OQ!j7GMxFZSde{ZI>VPg{yd=!aup1~>QjYb&FY`y`#rPb#OTXoYXedHG58%nYOSOCp{P3=MOv%0In% z`C0wK0;hH%-K;Mfm$2LN^IjX+fEBSrz<10P=%w6sJfhj+~ReV{#Y68pJ`7$b!< z5jqL3Mm87H)=X`adyzCzV3Nv|jkzK{JAw@b7BzON^4$F3@PI=<`EX6C?j*k0PVYO> zKl3U+C7NSp+(Tk0(z5h_(S$i_Ez6%b3B|cly-VVUl2X! zaZ+=`edY)sGik;0r=pzkt+EM^m?!sM=w_V7V!_a%rP;ul?$A_vASwC6RM(hUh0h{u z7xsota>_qx6rfVMagoyhQin+_%3ktjCDN73Zy2XLiA*SG5Iej#LqM@t^Y|TRZ;nTe z@@x!(DQTZ1C){Na=~;R*LcAAG zGiU7BHo?PDtwL+n%2m5oHE^f>&|0(cl$G|{t+%SQ*LjMDOlQ$>e0Wb@sn$t6&Au<; zXhgDx$?RCwp9aajZ8I|tc;wazw=Gnf%XnNTr0>bmtgDPKW0m>eG%~Sv=U$VXP;!!xk#a4PYGmue6oHl8$9iLjylGu_*x4wvY9>-ttb(lEX1CEu93-8`Nm%cnR^?TA7Y*` zqx1k*_T6na7Pm#t{8A)VDlHW8KuMMIJ3ojNOk7t~DG=hJE9^+zZli%?w>n?0d-+yFcgquagPcwtMYWOzTnmoYuGLB^&3y`qLyY+VVEgp~_qSky4}JgXfI10*)941hhTQT_AWe zaoU7^PRrK+IjFQr<1klPLxliVZw)lLIDDt`Z)*qAHBRPbc~79tR<1-xCOJyuK+>)KhKiIUOI~jFtX~rVH7^} zTBP)WftYAVK)+fIgMilbwcjUhnzC$7=ju<(PlayUGeQ_N;7SvTjf_`+B4?Ma)g` zUF89D14SXuHy3p5LK>z@Et+BQ;ef)$CEoH1%NR74r5FkAILqL+VCD7;MLIb*99<7& zFc>zi=qa&OcD7+)XL^>Zvwugk%uT1pSl7>tB@V5QA!aj0lZq!#+~pC&V#vV6lB83) zl0!x0p?c?$qcho7axCY0!0zATlDT}3reCqwq>w|Kpf?GJFwDqh@IJsa(I@M8yv8Z- znG<=XzCG}B%Sn{K_p|>@p=+B!T&+z>8MV1?L&MiaMB%ZJ62hCW+m-;tcbK z>k_SRxKs94yx>TgzU4_k!A$3`^v=OBrHVtAJ;F(HMW(X! z(Pb)MKL#Z-yx|l%*sZEC%P;xbrfH%D4GiTBezk9BFJil0Y`EPuCQ;!3#wFW&91gC3 zozVLz=#f#yqa#8uCX~wrNtkAGu?h(u;rR7|!AHZ*wJVZQ{#3vTHv8=--0GrA)~|k| zYP|ELpV+Be*M2KMZO|~kw`t{eq1kJd_qxRBGETI+8a{jK0*j3iZk!Q6o`|d5++vXN z@1n$m2G(B(!WoZOA22(a^We6odbINaCYb=m%x-5Vh=uW z|M!tN!hdd|e$x%1HisOBoxKMRiB$yTF~3RBjo&M~__1$R+U4jQNBqq8eO~*%Hazv_ z*MHw922Na_Bjq6GlpQ5u^3iXXLzBP*Hj5+5`zBR?-u*~yzs0fgNBNz_f2KG$9OB!y zfKz9VV)LB1t1LGgSWW&M;!gI+KAx;s+?BrPnc05JrRI8{=Ni8~vp8jHQl(zWyvs7r z-R!L{HC9btYP|QQU%l0p#d=>?2Jd|pw%_X7=5=4!Chz45bZ5DK_+H6|>ex4F_SUy9 zulu%j^W3+d_11SD|2wtq^4@o4`>pSNUiW?P=e_Ui{#V~Vt?>Pz@V*b>+zgL|*Z(+b zyzgUQz0DJ4{hud;|L^-WZNJSkFnC-3{xWp48-c>S;Nnft!3 ztG9iVtpEGw<$d3_?YDg=x&PPQ&-=bdp0xeYtpDes@ctji?Cm~@zyJNzc>hmNPrEOR z_5Z#M-v8^G`QFc)*Z+O{{K>C-|LuMp*8lhM^t|8C?Ek+zx&GhR&HMkp`)~K_v3~u| z{rmrY+i(Bxv;D81pZEVazi!XKwt#_8;or~sjB*e52`*sLQ(!hr_@t=7;`U&vr2=c% z0@gT%m!1pQ@*Ye|T)c|vXrMZ!)9hb zxbjpy%x1dxJz;NK;u$CIxoipRJQZ)h>0bL%n71wQnWx}$O@;fMir=A0zVB2No-Og; zB;?Qb^zUDlz-Rpda!Y@UE)BZIA7r-lm#%6^R&TIh>JQhYp;5e{X-~h#s)l>@hSfd& zQo1za7FWcyr_6n-QJdr#W~fGs#YgQ+ZQHUmrbsE~nriDA)wp}}V&A2Zql(%}e%E3vpSNS|*p8rWPFYUoAatURs@6P|324 zFu9CrYJoj!S&tTFu6yRcWLdVET=p?F|2=BCYV&gLJ&U@gmiuT~&Z}p6pVYE{J1A2ZQ;X8ms-BlOJx}Rc zo;oSLa+Z3^qUFh}o>y&BPulf7=}>yjsr1B4&l7JwuYHuB@Jc=LQ+oZcP63`jF4Lzp^q~9UabiJq!IG#ML*NZAg=$J!9tl6 zrCtUqWd>@!oMiOU-)d!mQ|1&eP5+>k{!uTdCTaR*z4R-}oL-gb+w{_>>*b6|nclNB zeHLZTTD8(^lcx8sm$MJ8^gNa6bt!Z1t(P8;GCf|socHOa+pm@GOj!%KwA_SNxkJKGL#z^~&Z`*7{#r)=aOhxL$7%%C?l!wo=O8 zq_x_@NZZot^=7Bl=3dzrLD^fQUYjLln`OP;R`lAWYPD%o_Kq%XlS!*hX1(6INZWYT zYvWD-vv=>xHahg$@YL%)m$D6RX&XMu-uG&?{wHmNU$6Hw<>+zc=nLf>lzOA9^hQVP z%^@QlZL2l9PB}-sbaaB=Xhpp_nxvzd^+vlW=Xli{qoy47t~Vzptx=t&qqXRb>Z&)I zn{rO=$}u_gM)}m6GnaIfZs}+|%29gtM(tD1xnFNgnQ|4l-d+$|D<`F^s-!EgwN}L_ z_mWkvxzk%2ueVo%bfu$om6P5oWUW;!%DqxRM*=Zlio_q(p6lvR%z8*`AxaE zcI8?f(iK1T_RghTm0NFRAH5ZO_4eMUw<5pR$};6W;Cd%5v`$3o-9x2yLR#yjjq)B_ z<=Hyv33(^?#jY(mVC6cj85Qd~6PRReEAg@AxOZvzzsfcTwKURqJ>+y%XK_ z?)9NOhg0jgFXg?xm8bn^o$#wX?oWB|f8}v9-Ny_KXdaqaXp0Dctx2E?lUGEtu<^P>;3OT z@3~Ip|G${;c1z#r(R!{|@Be*z@BSGk1TU;%4%!RJmrw(13J!O86L57@2aIg%f6OfKLIf54evz!m&}D?6F{`9tpCaXhC# z@H8j$8b9Fu9>@3k1K;v^e(eYR%>N4o?mrQjoh&H*QE>C)7ixw6dK({FZe(yWeC1il z5L74U3iJ>~;)A6UeESd}+88rm28nK=37FfhD05VC^7Bz?1= z&4Cb!2D8sbvIU#{=QIZY_+&0@Y--;j&T`afzTsxg*EgDHd=9ACY(4!G!;==qlt#OB zN89hlL2DQoLR#$kO+w!=ILd$VlVND-(9>mSVNm?Z!pgI|Nj5_=l`#N|G)nK|L6bzZ-4)P{P*8H^3MPNfB*ge z?*iIkeZx6=^UwePfBXk+Ik%76?Hsk?#i#!sQ7fN+`)?U}?(e_<@4x>4`RD)VfB)^H z4u1Oo|N6WCW|3Dv{`qeib<#HS#Gk+azx@4g9evF*>ip+F|BWN=zW?*zHDblL|NkAM zwzx#?bBI3o_Rs&X|Nfgq+%Su}_vPPzkC=5=U;THA*!%wH|DdQIi}33$Gd{lm|Nr~{ z|2H1~cZl3+5q{Axy4x>$s(b7nr|839e*Xs@2zm1x6BCnl%x$OeEyr*FU%K|(AG`A3 zEo!@4!ZF|YjSex#4WsTHxbfdRV#1?${~hDbZ#wnAY1TK7hz03|Q$PLvZxnj%+?7we zF8p^2Tf6Dl|J{e4|M>mCWzL_4yZ^5{`rjhv-n&o#eWK<$g)Xa^`pY(S*Q3w>Z@>KC zz3AVI_y3Qcew3S=`|8X8vp4>S7o6X8@Lxdu{Cm&-zxeszJ9gEjyZ`OOkK2SEim7;U z`r-ee$kwTA|4&-+Key>_&4kB?F8n)n{*6!0Bh%2+c9Cbo(l%t3t@Djq+TOdivg_*J zV=qr$_GMyb zGUhE<_a>w9NmTyvl)Bf2wHqfacoPyoVfTrDtutSQCA2(x^yvHF{}bmwK78u^+%5ml zUw+X#;dFl0f(2{tmG-{R%gc+3ubHvr(WJSTmu>%F({XIiv2Q)I&S$p1cTT*~JmpS6 z#-(-Ju7+kG$!of}YSpUf)XrPCZWVUizyIX-?nC#k-~YXK&;NDb;RW|+uKKch z@0a-UE7i@bKY#w*)YO!bk+EX?*T#;OC(hj5b>P~RY3t0*%{l%vFme!a5T;X#5{|o{ zieKG1xq10{0h#CMP4-pWwdEyb7dd(7 zVE$d&^=>fS{j|dMz>~=VyPl;W-~IGV)O&hD+sf%I+;0`0WiHStQ0ubSU}56Oo)+dk zr{tPuI8WKM3a5EB-y*|g>e#eagf{SHy;$fa+Vx^l57W|&#S`4Tgy;2pWxZUg^>8PX z8zW0WfE}wy!^;&*m^Qq0ohw)3u_Ak6(5uy&%l>CwSheU-*6X!gC!++`?)dgmq|nvdN{8%Nhm;nN~8Kz7kr# zRw+hy9_I`hG zq*M3v{TShOKbrhH7GH?w`hB%28n=+wu5L}b5w#j9|TjYkHf3W3vcmBVIC-dw6{rbGL-{$v+?e=+&PmkyCuYGra z{r*4fSNH$_|MsLj1N#pd!Gf$hmXGp`;xlBJjXpHKEmUAp?~vmRLODlonlUp+U~!M& ztPhsQJ{;y@n83*Jr9r{A;vuL0q*lpk%LEu4j#=fLm?-;cgGt+g%l!W>CovgtBzMev zC@wVp#E~}=i#h|2oE2W|arCCo#;%Bxv!a_%9KDjWv3s&4gM{p-qlQ*$LL7pNB{_qR znQFB$D|;MN`69q7$FYcI%8e#nw+D?|Uo7NZXTadI?LwO_hmlWi$>T(xgN-FO7}dE>^=<3T(mYBY))WN2`gY`=xCI_m(e1@@Ih87 z;?iVE$p*dhmB(gYP~wJvI0QN++7QxFis6VSjUaeyIE@Do$xi%kkO2M&g@CIy>uI5E_IaOG*? zY*3$~z@44J%EZvnyi08Bvhb}d9YR(G?MiA`#&I*#Mb%3{PQrK|)6A8Qi=rl|&uC!v zm*8Mo*Tu|r;^E3FUyi`qRY8_4TNkpObd2XdbfYm~DwBUg4qwrPTP+(HHqGqSVPLsE zulj$}6n#z$28JygcSrtNAgU>GBA%Cl!yrOY!t(=*KVt%uU(6vsh7E^RS19@j{}E-H zbHZ6JXJLy`%p%_E8F?yM3@lRH!nSYI4zM+?Xb>+*?6lqSNa&?Q z1ABx6qn*hVrnw(j6#ngKPrUM&N5g<2O!GjecFaLBjTy<(3=bJ4#gA-|Ug6Ng$iS$u z;UI7H3Vl(7z&0s~M%Iw0EQ;G+v$DiIl-{#}SurD^O)Q~d8$$x40>{fP?F|drE?ros zD{z4`GlucMzzGKiZZ0Fvw|+@;<{GrC#ym_kU*gQE*`VXdvml*m_YH1k2RFGp0c^?) z49pfUT58%avRU8x&XZ%?pPPSMJeS3RDfmO{OctlB?$Qg{4C;&oo_t`jwK&A4x1oWR z;Q@2lgoSMW5)Crz8d!xcES8WKaNww6Xm*;=%yZ>J3$Khq6Sqzx?_!P?c8!LR$_yqp ztAYmBBJR$J3dZXKAJ*$-`mjrPJYZuIXkg|#*rT$9fj#_0ld{-_28I<0jLsRZJ>CvY zrhg8KJ}c8?PAKT%EMeSKQ*luES|V3Y`~gNj1~=7egWN~A5?If3wDG$vU=BMFIL|?B zlR~6JhiOLxqu76o1|AuK)`$xU=XRfK;uHJWWqRNM6R(8>2UlQ^LrIc?!+};!8Am2| z4F|Sh30FtS1Ke&73+2oj4ociBIN3Pkfsld4LBq5MotDLmc>63IW%3FbSv4L=lyfm`FjEt}cTw!{S-WU+bU z$KA7{p`%ejV9p~4KIQ`lg-^_FwK(CxSR2vAraPD6n|nNM{z?z?i>XVe5_u2f3UCm;}B!vR=_~*^+%BJ}#}4Ve$h;vAhBX!v=>h zLOUAlPBb)CBr7uV7S#Ob@CaZRnZYncVFMEnL&6{KC9@f~DmZh^JJ7Bkvyi!P!+~>- z3XK9f2d0@kVAOrUrY^wLwt?k<0>gm=Tni1D4x0!liYK!ba7I30;GMu=_kdY!21Bp_ z_rwECyWNHgDiIRN&TT z;PEYBky;SXl*kaWfPuS!PevjAQUaIwbOv<^CLsX^`2$>~1qF^**_;$uR03+fH?Z(3 z@c3R}aAsgnyTHmOz-z;hz2G`~-*Tqb2Rv=<6YfH7_hD>;JxG)o){Xee}KJ) zfu&l3#oz+_^8+096IixhVCVinfnhZR>xy#L!V3&yp?p08T$>m;4K^^u3oy7m;K|>> zd^v!FeF4)fg_NQMhA9Ua*e|dw+QEF?fK71%LvI3`R|3PMY0OhL%y?}}90>}CfY^4I+$q6M23fzqi*^?DGcpfk< zVPIcu!P{HFcwfYiLx4qn0>d?R)&&c=wjXdWb`wx#V0K&#f^%9+g6aW==H+}n0?Zo^aO+)QmseoiT)oM?2<>>rc7WJyTJ18!^AfQT$KvH++~hjL+ba(8zYXAGpTLmulBv&t zt*U{iv4HJ!dD6uRta_>Z9t^CU*H||)F#Y?^Wyj88rNF55fZzTAW8(u>Q3DR;udFv8 zum>n`#u{+hDKN`!Xz@?rbTVN1_<_0q0(0yERw)BE@d9Sn=}Zw{9wz9Ox2toxA7Hfo-%zC%kj3;c?AR49c6Sal1D2=&PD2Og z=nQ)dw@YPfG^8{ zF+G80t^jwoLbVXXRIdrMR1DZ}9^hCjz&Y^(b8-RmlFIBQCUS|I)5;F=hbFL{HsIh| zz{ESD$mj<9mjzst7@Fo@V4D}tJCU8i@hH>W3p_>_7}k7X_Yz>?Phebmfp6gg7B>ZU zT?RI`EnM~!%GOV1vSDC0_`ngDz!KQNYPW!^-hp}E{|^yv2l$*A7+el;%ynVh^MrBA z1}07gu22JJjf6w5gQm59pLa>Q09=p z;$^_0)WF{MfjOXnTm04}DXz(KTCCO|a;rY@o)%!1yufOo$}&@-YUu(-PX`XC1O%(Y17?@oiuxq_$jR|0$#K78nfI)o&x0FCkvnj(B24>C= ztZxr6Y9=sov4>0-XkM~m-RTt!3JbzG6nNKco9KOjfN1 zbAkVr7n`KR_BaJ@^AGiDkLDh7n9MwZ`Ps_;KN*YNE-;xmu$5k5jxmTcJ;0iKH8)-tb%p`~=9C0x zs|UP^0jz5$Fme>IO>$s%Il!RZ&@FRR)@t|WqJtiB2iSBQ7?cf|Tnl)AUEo-9G&%C{tDDMMro~akMt1ZYjOXb$yz;L92B_)7Gwt!)x zG;>V~lm7u`o(qg;W-+-nFuNXOm2H@u7{KoSqO;9`>%76ykRJAV7L1Y)=9d3g*!_$p z%7!&X@@p~M1=cGKJRuDH-3hFF5|}v`FsyfAi+#XmR=^zffjP!pVB!I8s|^e<1eg~W zF!2bq#JE?Qv9h#$U|?6+$6CF?T_MFctK}84H6)->SYnZQsGz&_&vlimWRODsoQVw$)ZxNJW(Je+t?ibvd0CEb#Nv6Pi% z?gi%h4Llte7>qWo5lvv`+Q62$fYH!LV3Gj`!vcnz2N?Hm(6pJu!oP!+UxE3;2R3B| z4~YrPnY)?hUtrEFn9SM0&db1Hw1J_bfqi*I{)-7meOGyhGwfrIW^A`+;9+H8*|2Qo z{{T+W3tZVeOs52xU#BvO9AIW>;5ZpEk9X;DrVp%BH!yb}U^r+TB)*{d3JZf`fbSWu zeufPvP9E`gSr%cR>mzxT$?ZV7Y(b%xL)C;OOza=HL9 zA3t!2IHFz_lc@+q|Mm~!qlk3`!C zj+g~IC$};u*)%_q`Q4wz`#>WdXBRz-8?@ zmrreI(M@1dONi)TxDX(AKK%lt``uOD8(0`VupV*Xd2V}eIRj^L0N0(BCwhD$m>5$^ z3)tp1a5ohcDgA|%uf$K}eI1>scylA*!q;X&Kf#;g3>;@A~ zvt;v5D7nGRc!pEqj9Wm5;S1*82fV%kT+1EueHYwxxxm2t;HD|VErtVZ%M=zboy)1W zfkErTgO3UipWbEhwOhB9SMF8K?d*g63lz9_%Z8MwhFLPOToGXZYr|;0fpO~HRfnd8 zMt)t*5Wulk>+Tg>0lxpd3}-&DpEF^o*>E?dfzynEr)>hSdjm^o1IvtcFS8n0LasB_ znlcD9aPO$Ok*LFNX~1x?VBL`q%-VORSpDT_Okfc?z@#d`&Rkbeni|SJ?}6b39x(%! z#}D|X_r0tucoQ1Hy6^(?dx`#twcYWd0x2{hDVEZ z7?yl^G_Qqup21_T4gCEDyxKQe>>GUeIapj?J~mF^{iFSaiE*-Cz>~Zl9;bjsj~{R+ z2E5s+(7arLS#$!2RXV@$1J2s5mAeUUX&2>>HmTS!2--u30zDMnAVLOHN>$vjVG(16!E@dr|>k=mut98zxDE z1!4hQo;x|rE-$dc5VWM7ZjHp9C7==5|SFMlfXHFh11Z0`2zz3`-RO66PK{D*)do(?ksTdnyTXXh~dH_ zHBW8^hIu=x7#MEJv#@FKNK9~RU^Q-3>D|eAC{k8Lf@9W%Yihg_W+K{6M;eoOHt;{U zs4#3$WEaTH*3;PVd^vkBFYl2Z)rVVI=d0V~~da^t0Ey1#M;W6ES7WNgoOg*xjvQ76duRz*F9XhbiOTF zsJ!-b{I9QX?;oEZ|G)0v-@pIa4ICKR_na4C;&(A{WED@@;K(lDV&KH7zGQEh)WFDKJn2D`0Gmz*i-?8|gA%*t3I#`Y-;m9mOBii9n0DF4DION) zda@#sUv%%s<{rIM8ZJ%zQyw~Kajc4BoXEMQ>S3#lf`#)0=KsqUFq>?jVseYZhfCf1hA*2N+S$!2R0Paq8W{y6GhQ6w$h_g<%psX_B6Yh>!VaCy zXBiG06gH5_a1h}$x^R@8-JxMw(=>($E>~EkW;|u*eZ}C{lqKi5z?|WW0;83t#f*b| z;w&$gh45Tpc+kbybbE<`nTDccn~Ox?H5TO+8ys0Vk34SZsf;N|;EL?p@baFH#Dya~ zEE*R!B(}@v-EinoU$!HuTmP6vaYY zk=JZyG*c93PVw@;!&yJp!+hhV?&Mh<5fUui#V zbg~FI)M2t=LZU!X(#m#$V2_Nfjy-}7$BcqjT{yE|&*Y*aW1w0<6Pxceiv#V3&lHbL z<&&Fnh>3I2+65hnasmzw>u(k|^Xb$?IJD+>pJ-v>p2mA;FIxis`R_i;PgUSc-sl)$uSR_V~#j*dVh{!GtE%^-N*D-*i0TU=*@8C=1CBBxsu4zSH16YH++4f;=-N;PkYFj$F-aNJqWqTxFo7hqf{F&Mm7+5tPFx>fYoSmt`mgUO- z1fE$vkD2renl-;HX5_SJ?-xj5XVXz&;Yw&=O8LNA@L(b1@*mCOHWxY-ZYU^ibWtvVAHh)ZTP%FH`p z;FaLWA!^aQ_eMZlnnDw!vS)+DvxFY45C%pygSjuG44R|XI5KemaA2M$z+b(Gk;~M8 zk(*~hOWJ`4lZ-Afa77$oRxDY--hBEXw?r7TBS)e@j|LOB#skL4j6>{P83&{t7qCVZ zEMWgHmvK;Z!-gi;jAJYk2l)9nJm6Tsw1E4%#}TfS4~*P34`p^=XyM)<&}~$~AP{+g zNx#gXDVFg7N7)8PnJ&f<%L)a~Ul}btdJ`I)N|dD+6+Bm)FoDI4p^>-yfaqc;gR99A z4lG+El%)4DGBFx>F$S}`8Xpf}SzEG5c!mTs$36`h&^-q2d5T?7{}YT?`G`H9HOkEMR2HnR9GS zlge=oiT{jhC5{jMuPAb=vNg&4NMK^#a8T+phnvBa1twx!7+BdDm{^1=tr!#}8DkkX zD@}}P^GUfW*}sCJv$=_pxj=%^z)!g@!oYZT$sSU5}WWHMLUvc&yY zELk-hHU`*EVA9iI65izDB$#2q&vqg~)Pv*5x_}9NJ};VNR;_RrWJ-Ktt?zq0=bEcQ z%EY~b9!^4<35Vl(1Uij2G|RqR!N7ZF1Dnu~1L87$PTUa-*8cjkiY-RNg4^L=k<5uip%RZ~xf=#wq_#Bh zniez*NF;O_Xms1TIUESe=yt5CzWwh1!EblJ?knH-eeV0V84R6UQX6(Tl-d3=WN?*u zE8q9nCSVT}gOtL9X^smMAMP@9=sAD%Q;T?IFB^lgK#Ng>cnC}EjMScb_49=sSN7Ve z?Z{c|xW9s7hM(ht^uCv@DgT+AZZxoDE4T|?QDHCcVdNH{!KA!yOEJTW&fGz=KFzE9w*CI!_woxBAHAAB=XdK* zmLktujrjk!x_5s3rm1R}xO3X;J^m~CuNyo3ytqw(X!M&BE)vKGv@n)geyG<-dL zQ1%IE7dg9Oi^HP*Jc^D?nR{Ec9VSFL?5}X(4peFTsjwrOMgGMi<_(9KJsLDM+RR@t zN}tqb*X)pa(UNPx+H^{Vdq)FXK*RsM1+5YXzvxpFl2inZE`4#A8S z&Mrq768E|v>F+akYcpa{`P{@);Fd1a*wk#pC8?t#-I#ucLH|XQ{^O(j9<#>0IR@HA zzDFazr?Eu&cuC0d9OmPtCCAHKj&~cnv&=YFvE_KR&cd=I$7`P)ud@-T3t)}h!Ri{o z!enrwS*4-L zXpQ`Ee8!ZMGkGR3Sv7>eng`oOesVs`sRf{2d9Sk3q*G^xL z$eA-!d=5T2b1uaF5X-^6p=YMTE zf4}GapDX_DyUzdna{fQdg_C#AGpYs%a9v<_y}%M0@J8nXTWLUVIL4X7hWH^z|R`U_40zC>P4Z{a{{gxMPdbnQ!k2@2A&PMC^7ZoteT5bTQ5o< zJuP|lqU=$AnXeb+S%cV~UQ~Q~QNi?*^4CD6&>&gYOKPP-!m*b$LNBT>y`(iaK=Wvj zz}8E;PlFiFUee!sK~MCuVXnV{>18I>%l}P6FTc0BY6^wdZWUUbgS`wG$0_&T_@c^vXw>D=ur#I;UQ7YxQw$4LM(O#dB%M?w%{&yl1?w zUh$pk>+|)>nkQERL_@#-xf1mCc%bXm0Mo0XPmhO`UiC`78nN|w_|mIxQ?Evs9*??u z)#>QfIML%A3=OfO*KEFCO?rDQ(e;{z>9y3eM^j3#nWSFJSbI2q={3En*Roa5WnB%^ zI(jYd>$QB=>jk3M3stWdnO-k;y5SVR(f-K>&+QcZ_ZqLbJo_Ivya}KbM@xj zr#I()y*Z!t)&kL63sr9|GQG9f_12QmTT4@KEi1jXy!FXVAbR(r>fKAGcQ3o%y%Ku&Drgt^-RrG)Z%n;=bLrh%TkqaJdiT!N zyLX@7{eSQ4-TSQf9*Ew1sCw^_>AlCU_nw5_dzyOhS?Rs!t@mC`z4vnIy;ocBy*_&H z&DDEvpWb`-_1=5d`yWK_e^kBy$@Knb*ZW^W?|)6b|E=`?_tyJArr!U#^!~4{_kSO~ z|L5xczfbS~`+EOB>jMU{2aIYDn9Lq9yFFkDd%&9ZfUWESd)ot!X%9G;J>c5*fcw}3 zo@)NMqU~&1H|Ywms55_DJX2 zBi(0@^u9gPXM1cQ_SjJEv60#1|Hf{QO~M|Vrad+*du-nJ*kama%Vm$Pwmr5!_Sojy zW7}ts?Y=#>XM5rx_QX-`iIdqAXSXLVVNYDsp174gac_I#G3|-xvL{~Ko_HU7;&bhZ z@3SX<-=6rhJq-|h8mRU($n0sb+tZM+r=e+2!^)n9w>^!R_B3+Y)2MAvqmMm}x%M>n z+0(dhPvhC1C5SysRC|_W_AJ@$SxVTm)U;=5WzW*vo@GpXmbvU%*0yJzMN00i%%=`8CzgNss z&!|{?jv)l;WVS%e*| ztgL+S;DK564JRijgW$`H7Am+$^>7X9G(@#DF7Xh%u7Qw{z0Lj*bpHJG+x7PcB_^ z;l}+hy|b@Rop;_n?M7hQ_UP34v1uKRlb%jm@};qJS5o1!72CegoV#uMqU)3AKa0;< zK7IQ1j@cjAtULVw-+#hOCk-F+x5`^{ykTi@KR#I_*o%d&L3l%iR`RJiGaMgGpJ{=) zbW)h>#nJ!<1{d!695Pe3WSwDR<%zhvDuD6&`UJ$%Ng>tahK&xIE(=%AMZSVKem+aX z4&5C`G#PX`npIpCT+iNb=3HTOFEU}%)6zbh27$tkCR73jNQHDK&Y!SZE z>8+17glqm!pP^v-$I0(zBL^tp{er5J-b}W^0l4qPSH~a0<6_2`fw!KJl z75(F;;FG6#jEmudMJQ`tmtpAy!88Vk28VQ$jDS|wou8aV*DyY~>g>;xc|m9@?~;gs zbcZc03?YmU7CVO)C_QoD>S($!jqPE3fE930nL5o;cMmn#@vHKlvAC@ONMXHr7cX%&(M8$PFS4iZvnsXwW42xnS1a)6nEIlxt zCv@TSXwH>P2ZW;I{?9z=oHJKs$zm2uwF$EpbagFv*vz$LwF9?Y)|-td)K;&FaEPf4 zC~}rsc)Nksb|*{Ij;oOZs;s=LFN!bX{SxDP(nKWPEq#a5g$^!P^$AQ5xt6TkwUcwn z4RMDxZCZZ&_@+25WjXrkxMLEN&4t!mOa%-KAN5{;I4t0<^U-a!uew0+As(~m4o4MK zQk|d5UCDP{J@=tVd*#mCs*~4>zSeSL<99vnz|XN|mD6RR5^bkOKkyaAz8ZPYgBCfQ zSUA;5Kts~hO5l_P@0u`Qk#kqn>>U;nDOqjuS@~yxu$=u`b9O{f&Dx7lWO=-Bt?R#s&gUs-} zpHFAJ4{cRu)AXHiEpKYagzapZ6IVKJ=rP^wY|X>UqBLpgJOL}o(peKjHp~z&cFGg} zGP~LSLxS9nnd13>KAvdbDizB3VP}yzuJNi)tokzaU-pW%#;>@1$88t$H_f@Xc1vchMn zR`|(NVb4YGh^q8u-JtjDAVd)>2rRQto@(9 zmiPlsuIZ;P&r>^U;CFMSfBUU-Zyk7@SrZmS{$g&Jk=wo^AT`Y+IVq%FA)&D%lUHN$ zsjKB-TNT4Yv%-&ig>}?SRZP@f9d-TJgw1*?Yjb*6$Nc;pvLUH-T}AKeXi=u?dwxw_ zQ|;>!|KBTO1>3jUa@{pawN*EodCE3U2z^;L=Rl{tg}}z7-Zg2eyXG>hT#cP^cTI-m zu2%gT$B?;y-$V;r-?}EZg~9Z2Ff-ot_9ZhZtY}mF)KP{5YBz9vn)RkDfVe z+sDIO{yY%nU~1rWzO^clcS7Qfb=jOO8V9si<%mbb{rrD6h~?-*wxHHX(@C6DZ@$Vu zsl&j`yG&T}9@FfvMIjc_zuGnAI+7XM(is{ina>qv$a(vueM#QK{i!Pr9p@~X&$8p^ zg$2hFzY7`JawW31PFS~oNx6c%PJ$|H^E_|&=}EGdZNILWyKHdE`ug8Z=cu$O#OZ~XQvTgLqLWpnkMx^-E+`EhBpxi}AG3jJTdecOB;fqOy< zj~|4^#lHOYan^Nzl}~~l%(I#kJeUGM2S?e$gg37Eda z^)XjzO1t??AqLBYjj~!CyA?QBIBgWYz_`@-@0iP?u$^Q3w(G#0C75-nB(u2M*ecbah{JqB&_BmhH^zT)SU0-$c_P+it?SJ2vpZ|UD z_rLE4`1gHi_y6-q`u~p;{`)>^Cy{3*k7^FcK@&I=l^}%{r@lM0-opZ3;8bm|EIOZ{@-_hdw~!C{~u3gvN903 zVj!@Bf#LE3W~l%fc?FS51_oY^hBxM+oELcyZ)CSq5a9kHTx}pAtfOPO*ir}BrvHnFbKA?&s@lu%fMj9!63h*$#G-Tuj5VkzBBk3a4|G6 zGB~iXd}I`7U=VWSthZe9`Q{*y6-dC(Xj)d7znPA@dOihKUP! zycigG8kl()7@QNB83Y)a6oYJx)QuOreWGp`HC>2lvC)ITnl}0Rkos%&dvb z+#48#8<+(h*v%4{c?1|m6j)AKFz#Q`d%A83G~>T`Y=h zr#%EpH2Th22=F8@pYvd5c5G+3!16+aIfkK!!GYb`pl3e^!}<@clR|}~9ZVYxnwdBD z$O~{}Z(w`Nz-DT|qefGnJ2O`b1+Q* zz$5p8u~vhbw}RV3bB@M?dLGH(ux8Fo2Z7HV3@Q#xM{hFAZ(wjfz`AcjGg~2(&VpI4 z6S$Zr@-AdxQ2pP*a*%;xp#Up`1CLn1ynF%90s*ds3(T$$SVaynls(`Lb`S`jz`g$h zQP!6w^NwNz`!_b!2$*aCWZ;kdJhJ zaT3D>UWN(tnKrhSL<$5xVC>Ie-MWE2cmtzEL(9Pgo;?S6CmmpOn!qKgAy717;Zse4 zWd_Wq3NsltFikL6#2~;UmcY0(fy-|PqhSSO_yslr2M$jLX4Z)uOp1IqH>NTS}FJP*&6yRp) zU|{H1e!$C|$T+K@#q+-xNB0B9;vJI&yaYTL7?LNulEHmJ7>J(V=Yk{f;lZS?YW)`;{!%~J1{QngMj4haCS8#3)5J)y)^HAW^ zYMA!cLSXhOfm$m8-wpxIUySkz+=U+&Ke7~<*TuweV3A}Nry0k>+FJ}28#s**uvNa8 zE5N|0bYV@!1b*ocOuY;YS_`0;( zU`gD-Rybk4QUj-|1kXn;fu{*f;sR{zwU#jmFf#tARiP!@^z# z#=`<^@(nx!2ApRZ_>50;KfBPyP{5R0u!v2NC&NJCi`!Bn-GpCv27Z zz!-C((c?qQSA!-72M+sPoZ=2_$`d9@axq*t5B0YYn4l%#rXet!fx$OoHuFYyNhwy1 zgmso2j1Lp|jkCFm6bcy%IHV4AW<{->yqevdf#IS!b6x?9@dl>#8`uqgZFLve#oyH? z*1*jmz?wL_g=yk6R>tPJH@ox&YBxP#x^{s5m6m{(15^12-uwne)gAnwvN$fP3rHT| z5X+vqBZ_1HY3}rnmL(IImuqg4H(fpL|0>Rw1MIgJFsFO6XOST1#eDfdH5_G!kLpWB!m4>By6sKdb4a$(~m0oF+YY}pHzF)4Cu zCCoXmEpWc7rImppd&YX!gAAG)jFA^u?hCLBDDd*NGRZqI?Kfb3{c4IwE@|O$-dF7nn6R9AenOt**d% zuR3s3^fvd1l@bgK4=&)i&cJWrz;?!gZJ&a`^@iFU2}b1yjJ}n;ilV&Cj2sLHc;|64 zs7LU+6fnyOusv31m)^k0F3oo30khqKJq88rnUT!56$FkQIK|e;!|uqaJ%M#f4c`Wf zhRogDZnHD|`LRn%f-%m4tx-YX*@nH>F4QtBE@3#p7MUQh#YVvR#8#GxP5b`LtSR81 zt-$Ez!yJ=vhP!LKdk1#|fZrfD;|nH%>>fXwSDzcd7l3RvAc*jx%YKKrbmpwYwhkZ;oj z=9tXhj#*m|f8Z;8zjl!bJ9ct2 zFrR2KxWJ?mz$VAQr19a5z^V1wA6iZ=U|$u{uA8~iv~~@{0lrcPu7v*+W=<-Yc7=zb zY60^%n=72E4KfSv?5v#9^J~L51%YOrn_d@~VidZJ6j%;#STSn?8y^?zi%fxc4tEka zbj1`jSm;cjrnTsx*K+rW%bX8+SQqx3F%XzPVXNS+vvR9ut?gh>{=p~`z@&O%PQiow zhjucW`v}|(XwqCKz@spGljpYmKFsnCY~>41bRJ;ee1X^g6(>{SIi|v^3IUVPSqij1 zSjeF8kSTC-$qpvvOvaB=4;U`+FgLEBrYZ0`fhqmxIdeV+W8Do5A2@{sSf|9?WNu^* z>1bq7*z5OdC$k}U!9KQSyEyOn+!JcuAgI7{@yCpm+5A5xnXeu=DVA`7$&r20jLt*< z|8o4X5(ro@k$oYHB@Y9~I`#wsj)X22(E@cwX~7~5wvb+yHxss|-#)7nxzMEH{5SXO zOpSB@{cTA8y-T2r#jl;cd!K;5o`B)H)@wUn{gmXC5a7|@AZ5qLwB6%;nxnHJq;5S^;ZueUe0mp{N?tO*Jhfsf7en5G^*p=`pAwiv zv;@Ss7#^SH@Jis=5hY;HwNFc+wQOHNVnd(PgN~DS%rRYzCmt}Z^L{a*YC@}rK%|F2 z@4snmj*U!>57c=W=Duc|HsRy62W&F)pPbvkqrTuh^F@wtyBcrYU{AIbsMcl5ioVYz zc#f%X+NJ*%jQuBG2~A-C%EvHm!Dp#_o^uI}6Y~UqR0*u?*zNUq>$wXYGTkhPfqU-#n@&bu&Mi_4L`%N2W$)e&;f`TDU1oct?m38j6AcA49*@3kDwv2~lAN&Wkz>6Wm-*_RQDSTfmUGb-Dj8 zmG1>tKI)x2qO6xz&`{mDc)73~6YmtW4ad70bu7e;9x@$ZV`zwJh}f8*;LIQ<#oHq8 z$ui4C-GpI*VS!kK1amQu%O-EJ{|ut*cb?_`b<$cG?-M7oIO{W zxwPTK0Yz>O0S1ZdN9V=f779``hK?|J8t&PS(pe zpVYc`eF}$|9@9gH9jOY%Umj#In=>>xGV29-b1?{(Svs|6I0$7fV6D-7slp(^(7+U; zw$Y)V+s*1Vn6Wbr8(EALyXS3cdY~w~ z>laspWb34aiH!!G>Re)OKQ?e$b0`|vu)Sk?z{YT_^DukLKV}CGu00!+wNA~k;b}O+ z5V6Mah89zU0JlzrdZ+MO0cW;8gN&9A>HmD3tBh0~4hS_EJdtQ#lE-FsoK?2#(;)>8 zrHi~vwJaYzS~bzY!jDPRf{DFB=MaO#1^!P8X}zK!7jF%V&Od4z9$Wr&Yj}J;t64;1 zb*)k(58EzA7DoxGhPJ3hT+iGN-l|CMs?p1C;+hWOQ zCx5mEy*D*tA%T<*tX*e6@+s_VfQ26L@s9agHHlTjGR^uY`k&1X}v$ zExVx*^d!x|#mS_uv5`e`hNR-edkG5V5xd_Xv(Df9{n_sP{r}l)3g#DBiZNI)EKnCH zU)jmbAb;ba8>^7aWsA4oddD8PxgV9~=$aT=Qlr3c8N|tO^4)`m8EfBNOq=D+#Fo&N zI&1Oi=Dea~&C2E0(y22wDx40wGaOQU%C?L3>q1^mhZmgfYXUmB`b;V=A6=fg&(ZB} zPazBc8R1PFH<>KI{A6v&XXtPi3}Wn9)N1j3jWB~)0{a7%ypD+zuDHBlbP!~yadEoH z$JpS~p}?#k!R!7=U}~d>o3zZyHqC8}4K`aI7AXB-aoO;M`TwK~kHzjiP++*G&M14P z!CSh4`E^BMXI>7gjQWB(4^k|grLJ9QGe45ZSGvQQVM0>SnoM3#7X!AkkWOXeTU=h( z*ck*SEVNd;(5R5Ip+V@x8794qgY1V2T6e9{=VY+pja}0?_s-lV)tm%I+c<|w(l(lv z0xKH@bl7Yc>KxK)6IS$`7Bp}74}ON?jSf64k}eE79xShaaR^;vYLhEqVcDSF!p-%G zN6)lHMRcXZ#Tgz6PN>)50^Z6b@P0T)9K z1A}~#yB4R7X02s{W17w}!H1R~=c#bAn|U1C+1RpC@3vKjMArePxB|_N88=uNKCm;y zJz-$kdZU4LlcM3I9YU&y0uS2qu{W58F$+B4P!c?FVnXB-Jq8)g<9gRL_(Z2HOHpR_aWxfV0W*<&F|%V1=m!@;1l z@PHJ5h^}YTPgyIKY03(h4w~^S7_{IVOWc zjWRWU0VW=2%k~@+RGh-Y5Yu4DtR~PHz`MlCphBo;>*fnVR%J}~YJBc?3Z2|B2R6>} z{NK?XIcMstq$dhSD-IUV4gA!Y za7fA~Y2E>Wf(uV|il1It-&VT*r4ftXd8?~0D-GPkt}Xd2v7X)ZhLC$-0SDioU7WU- zW@SOXbJA9(^m9CQ63%((o;o3kEy2vpbJw5DvhBC;zHckvb8s=sQNAVoNBg!^A24cU z{lcg!G4lY!{|?>kH#{*{845mGu^TnCq`Tkv6#3oZ!(Ca`+3MoLnZC9v#j_OFr!$#J zba3!#vOB$)WOVLACig3~{At_oJk@Xi*}^@&#hR~$$^5?Gk>i^$eE#sq+D^Vhpyk80 zS?mr^l#WN(?u%$UQ(|K)rhM4si9k=BSxd-`3(Q+SyBirP7Ra&soDKQg#+L{H3Qg4=^+g@3FKqC4Wm*^cbBc71V>=N2PF zGJ}FRw-&pgkAZ+==iN`!kJmgi^`EaFxAYKC`j0Y){KGp-w&^vu^RxT(PoI@i{ds+R z?VHs7m1+zPiR|FPe_?$gx$HP6iJZFg*N|2oIM z_Eq@(U)PV1`!xOjpXZPZc)&|1+w1>4wXgqm{r14%}D| zO*zq4a-zNEM8}j9olC$=C%ccpFW|wpbP{p_Ps>Tr(#a(!XKgt-`w0939)e3JPp#Sl zyMX7(sdZmK7w~K#e(B_w)B9P@91uBkQ02@alQV~1&KwCjb2R15v63^#(UwkLIdk^O znR8#xoM$7>Z{k1FRsnVkO&T{?OGTgmzFE$4qsfi9i=edPR~ zE9d_{fi9h75WT>tdV$FlvUKtSYw88I(hKaZ;H8sGFK}(WzEuQ6){7ETFG?O^(~EMTrIVKwL@z0-UQ#l> zr0jZ0CG?VN>Ls<(OX{tcG^SqCTzW}s>m}{8C+ZJe(tUbK@9QOf*2@N>mkm`f8<}1< zb_Fk;G)=v1R(jdI^|Hm(%a%(oTWtj`owT`n+4kvWyRVn+SwqrF8XS6^lwV8@V_+~< zxWZ}@5+8WQ)%So~>lL{vA+bN3JwqKla~pQuxH5lL!+fEB1`mcQD;Rd|2=NI$;QN$A z?FS=h(&GU~z+1jZ*OtZyjm!?AoL52^7@8Ud7$!Nef2v?ge89mNz!1vN5a`OOd*Ui{ z&J|x)rnILW#t%AzRr?hf8uS7h8ZR_Cs&b~uwxqE-M6L~)^nicTjj;JESl*ssVN&SS zVrWQO(QPRZ&M+mM;l?#LUWOP~&H!Jwnzsy*tPQ2I9Cfao$+8@&vK`fL8CutdGyDnN zwScvXL4kb|M?*I&Q@{f5rnlD{Z-iwqFf__?lt1MNt-Zk#)3hsrmC=KJ%7chE9E|fB zt}1OK>e*ORd z`#&x3@b-Y+1c} zwX3V^<9Gkfqi%Xct~W3+`1Ai?V06clB}@MO`R^3H>(9Uc+qP{p4?p+xE9kJpk6-`W z$D9m|?tk<3|JScy*B<`w7`ehNX4SXf|4*O2IBorZ%c#?qu{T{~w%JCWyYuY-_y7NW zqUJiroOg~obnNuwHT(WHPXD@i=YNN&W1f+VKmPjPJo{};P0ji9=L=hI71k}AFkynb zyZgzLCwA=EasU2(A0MAXhYl$#E0>g%7=>Qb($W$U5wW+ozjNn~goMQM<;xEqJb2*1 z0rTjqXD@!ca^wBiAOF{%{Qu#{|2;<@6?T2tbNc_}IhQhPuiU)%^YZimt9N`nb?5(; z*ZG_8$M&IO}gf(Zd(7|DHJe?Cq!j+m8Ns zjyrnw?ze*4-B|?_kDUGO6n!eYcwyC)-|aIV?mPZDHfL)}`Kh|@lVz=E&z?CxbLPy$ zhY!Da@ggN9B{nuTJw1Kjwf}3^uI1(B-L-31$GksQQ8!IYOfEk8-_o=0^Y8!H9{-Qb zJ2rXoo67E6JNDo8PTdz4H)-O$XR+mXYG(ZZ^y$;qgC95SxIJn1!Ia{CJu^WI%Y363 zMI^P&Tm5v$;g_#py-m)WfB*IWx{ejT84s$fs}CHx-qNw?_^BHOwL7||Uuu~AsAb}% ztkO+{m!nNw#M~6l(DKG((~^@N5ezC8CpV?KGBK6znB%#5+1c4xmZMq9d7RpUbdull z*(^#sPHkO{yd3Ruj&B9O;<81TF381bZ(nzJcg5#dcTaDBf5DsC@aV_tsq1_XGYDLc zaoDl(@$m`D-t%fU^E~okvNZJ3oML#1Yl^iJgRbDg6BkwluZ}yrYiq~_Hiijy5u6Rv zyB7;;j1+UP<&xMu=zPP#d^YaUfz30E%;3V0&f2*3wpJ|CXt;hJM z{a+yQdiM<-rrC}hkU*+{TAnU^$W`l zCkq)B&NOyajQ|rC*6;UQCDK+rY;&1=d9Kra&1rKTdu=Aqa1kjgnd>+!)a9(-UfV4q z&K3395at!=yvL3pX4}Y&ekw9cHNGE z2G_EePp2oW+cw*Qz2sp`v--g&;WcbCD+H$`9@Bh2r^M;lOvhPseoW}&>-7wZHr~2i zpv7J_JYXu{#~A@?s)`5Homq`sGUiSR%X+yq{iw%hv1WtHSO8+9xcFgdeq^}Ahfwn>L|v$?){x97{X?DuN&BtRhL5q0akB1%V>wY}yF@N{t@dS6hpHHTM zm!qYx`}u56`MaOb7qsjBda-1B-mjM{md_KkTeW+)&+E3?3nz$exa?K^cE|H|zuzSt zJox+l0ejg49~e&PUHHH#BLC;pnd?(cPn~twuZ@-W$^ZK`j8}KU*&F5WYeTOW{{Q%S2g$l|HX&poxdEnXOQ~PASC#} ziKF8Ho7DtGt`H7pd5?o!a{U!QZ_j5ne{q0AEu~3@=iz^w4grC#4=qoWA3FMU91=_N zZ)Hnd$en&;*S8pMMFX7Jmc*ZOe z@&4|@;8NHX!4fOFe#TL~Yik`oJql!UQE2KEed5O&$-u@Kz{DS;$U9j>RLJzjQ7g7{ zg1kGOggKQ|nGzjrt4f#5kWew3P{NRG!@$5?!PL*tak~6n zAQO{L0|Sf00WrP=2A>or_UR4rW*V8Uj4ZknH`v@(+FB&l#;9PwywTTLYeU1c8U+;& ziF?X?1r07I9K6nPG&1e^ApLi*(XH^YvVt1?A8W^JpQ(9OkQ@X6^w z1>0%iDO%q)zm4(|_qcqc-N$Sb+sDP~e|~aE3%0PFec>cy@p|&5|5@x?cKA-8qQR)M z`dqN$a#fCS?WjfuhXX4tG_Gc71u%NbFxYN6yS60rnTjQogK$h%3hSmc8O9A8Sr}g& z36@RlO<%ykGV{Abn?!#V&y%|g73L`!JUq|O zae#p>fI;=u%eWs_HGDki|`J(luym1i>iHqW|#=9$^K~?Vsl=>>{K;oq29&enEiAuxY-pQU=3`qzfCeG!}`!-QaI9OGU!s=widr zXP(is;-~K0vh4lTm%i1vV(0$bvf{GntH9Y(ktGg?R)+6gBeG)F)eZBeu1@yNj@&E7 zu#VvXtD14w{4cw%&Ej)e$y&t2AhJte+@r~VlI;X}hU!aO6*@E+7H~26Nb^<{elZbY zVrB4npnkvZ+mf3X*dlt8ZwNY^mSSOI5ob7XljUXEj>@K%%I@3e%VvDz`t*^l(S_k2 z!-WQi4na1aoEAn7_a6ZpbSG4aFS%{M^Xp#q+!osv3=I4XKe*X0HAv|kVPf8B&ai>8 zsKsKTLc)IukCTiGSQsK6F>07|F!LEPFf55tFi_}_W;jsLWYVCZR`Bhl^o0gSg9U5` zGj^WhoK(y(=Z`{AgNL9SU&BoQ1qyQZC)l_yF?e&ZJc%~*C zHpj#&Y?1J|v0rb(EcGWZ?ZiFgcs6}+dQki5EH{IX(#6j*0x7TW+qEuXY-pS>?83*; zP$R;{*dP`o`(T?yhfI~>1hE8WhME6O8CDnwh7!Gv* zdcerg7jMpS%5cJU?kDWb9=jaf47;w+KJdUGf3E|N-h?C$m!GVLe}ot|G}^40Cr~tj zS&^lwox>tZ;ra~Q{|r70DjDW9ykibLC^W~O>%?Svh8+U?9nLgz2Xj36&2rGyQsqGf zgUrFNO$P+#PvG8ryxJq7o>`Fb|8#aCfvN^`yE6s?yBHWsKIC0d7tq{ZY~xTRt1j@` zjhWezi{U{Y!-gV-6Z{MgT-qC$7y?-T9AITo;E_7O#9+XrAHX{Ic?t8v941E=h6}tW zKh*sV7r3A<;LE@eZ_u=)oR^`1BS%3X?EssN2IFovhBk8n9|neO2L9j=dCUprOdFXQ z)dkuMc-}EE2nMvU9ORO57YLPLV<;$l=D^?nfk{fCz~qM&iy{ltM=KMDW=RHyT?=@a z3d@)l@@`UKkzK%e=K}Bg|Cbr=S`U`A4>C6lcj7vW7YjQB;7I3f{cFup0v08yeKY)D^1N)r?#b-|l zTrO*2JkAxqB1cl8_w9kE@8$w?ZZuu?V013%{GV3*%s@c<0^6@Nf#wN4jST|MKiVX& zSIH^}EK+D4qhwnhzspB=r|B-$74nDBH4<5Q2e#t&@a91QyvCb2DKG-O~9 zU}v~xz~nQ5aft($)BzSB2S&yY_PhT*1e6`x>@)=4b1<|qaAYwstY%;^abQ{Uz?va} zd5=TKne^_{!i@|99T^i^)^BEK`dAWVz^IVUxOfAzI|uiQAG{0)*cv%lZ5ZlnJQ%Cn zx)?Sv*Dm0eJiyNIfG?J#m8G!ylo%J&LUyKuOfC-7#a@)vM+!7KFzbI{dc(jVV;~@9 zkjuI;+i(G66DPw-1_qx1_S_A83KQ}YJ(!m|@Gu`_XEGNEHW#Q?6S!AU@65r#&Ds8c zdtQ}83fwgi(7eFB+JPk}fS;jY;Xn5UOpeT~Gnpe_%`x>7 z*f1lj@YTx9pPVnJvDk7l`TS@(URiCrz3L9<6sC`pm>x1MVJ~{RVM29QXYDHM#)5f? z4jp#``brP5>8w~B62LOkt5JxZ!MuQDbyw?d1HQxn7JCNfX$+N26W1|c&#feR^d=pI%@&5BU{E!0ha*Q_aCa~vR9gH;11g{%Xh(AWp9C% zVtKX!EO`qyPs>~%P{6i)0i$T;%6N0`O$JOqW-{wYzFo{>i03Pgx%-V_J2L zv5A}EL4bgT#R8U(oQ2^6dlUrvyaeL88CD$F&RUow5|FdKKwyyo&-P>ie~zsZ4{~@u zlqG8{s$03{-|2o+)Pk)yv;@wbT)f4K{mFNR9sj)q{3}+~ zz3e<;Enr$+EnCo{xq-vPfF<@1@oBZL&rV9i#aFlW}L_`Wq&Sv_<&akAq^XM)n@ydzX2MS(U&UjS4cA>UF(1#N31zdhs z0_-&`y4$l0CNK-lDcBG#Aa^sHZd&VQJ%GbXYhpXRZLn8Md!qJx7=E{AffWvOnF0?o88S&FFt5KLz;L}RX9M>c?)<;)Y*(K#iT_&Wy5P_*Hvypq z1%@^P0SfHaopTu&xL7}O9XhaBv3(!g#of&}8EZGJ+RwlcWj)nn%@GEMW^aa~iN}~S z7R);~fyG*L(V6Sz>sB&0UN{=5B@pnSfJLxlrJBI0V@!N6dzcp;*X<1D!`_i`OIWFu~Itu;o*w`fvay1P~y&O)iwkck_<}5oSOWlX% zZ`d-9y~*YLf04n?=dx$Rrj!f$j~N);Ie0u{ni&GPj_b@(E$4cfX?OW_ZQ+fo_0x|s zOgO8hdCEt*wAs zL7jR4%bD;sQ&tO1lWMb&U{jbdO}&6=tpSrV!xt^NPzIp&M}EC*Q`IT#*3;5)u-;*6QcSZeMvC$h8(-1j)ZnE8|4 zdqG=auGQNF)=viB&&yfjt{2(pT$$ccD7U>_qk9WW;f<$rZwS|v7O#0A<3P!{ zrWR-l*lyr>dn>o^8^dLHfvh`R8!QB>-Fp^q$o<)Cot(hF@d96(0@up`0n_XKW*$!! zKCombtpC1!hw=sXs9tW~KPQ+UKCu5Eey|}y;L@wP+!OPp4iv;FtV+yjcKCV0BjVV* zU5~{TSh5Y+8}8n^Y|&W!fN7H0oc-0+Z>t2D&n>_8r%rjn6bbe=#_Nwa#$Gw8BjAzC zENdfh%R)dse2SvCz}*jv)IO|jnZV-HkX!PAsmOsjGJ`{wkKyQpM@$>5lo^`xG#S^Y zKV`Yd!q>Hs$?%!o4d&{G`?+>j`Em1)IrGms(bBf8<6zA$X2atv9R%b%U)pf6@W0Jb zSf0bjR~&A>w|iZdLIi8hj`mFo3&djuf|nm>TDY-)ra<0Grgalo=HHtkmQW&j_7Zd9 z#5bA(-o2-H_X>mxY&GR*dQvb`M^ixR0?Sb!0iXYWN)_1m&eay+jlNg%a}odEHw+VY ze%BLNboR}Zj-DzF0nZt&3+h;wO<>{v$@-L+A=!stM}nuAfoVox%kAl0J{;4PUN9-n zdABlnzP-PIrsd>DjRT1ebsv`XHd^ei!zOpG_kznUOft_EVyvu^M zRe|yTvW;an0;LXIuNuC~Y3)n>*`hOJ)-$=L7jN3;*}Y>pP{zOEMS#}=n*;Nb6?$11 z@7c}%$+0n8>)+Z99c&p2{WIsZhDYr2&e^(a-(=Z82bi`q`5a&?h__*VIlcQ-!Qk6dDOpMyGAg_RBwfbv@2hB-8xP2807WA9fr#W2qOc|UE{SI6i3^xQU_!xLwUD)B+ZzGPfl>O0?UZq(PTYincs`BXlz{8wmv@__L{ zyN{XZp8lVWEQ|_GC;b^FC`hgV}Qc&$z^EgHO0Fj6TkP#e%KTaRHaN z{T;WL>4#Le(*l_)j#DcXViv60)w;lfxkcC~;srPk5BSy%1_JmQOx#PU(LW za|728i3Eo($Gb~-6&Z9SL>O#Dn~IrK*$SLEEk0)?N{Dg?dUQ%<9SAWBQDkNjkYe0W z%p5Vdp>&fq!;E8MHXj~5JTR~4N1q?3K|{d-BgTTJu=Xks6aF7>rmWXv5DR(Hp~|*! z;j*k~n<6A!H#to5j}P81`OE)F6PMX@-dN5X_iG!oZBI&r_QdTyJL#}HZ8B}*n z@jD|F#L1BS<;6>G`<`lkh96&89h&4rI((Wq{)BQQH0C+B-SqDg)?hpBR<=EJ`TRDk ztd;+lFWZ&1TD+?_ZqA~^Gd44}lyx-n>IB?OXc82YY-knFD_JOYY2TWJt-SMoBu|=c zBDu+1Te*~l_m=@rLtfOplgHnO1TgN~Yi;~=gPM#G6GLCqg2fXY)*rJeK5PDbPw{#C zdZ~L3K^NX6ojtYg%k6pZ!aTZoPu20{JdG-j4V&{|*`$!5HjV}Ai3e+><;6a+Id55#cilOGNpyz;o7siN1se}DH-Fp8 zxaEC({NyIqxnfiPwKsA}28?s%4D ziK7;7M$<0#gd`o7yt>29Y}>`&{FY>yrxxy3*Dm&zA4!(`y2IV>+r|ERmJ|h6OAjZp zOB32%Qj|n@dbpWgn%LixqM~Z)=@oWq()1%KYNk6q{mL#)p3jo1;cDp>H0{!qJf|^6dL8=@v&V{feetp7Y!#-RkO2zp`zY=e}=Aw|Q#mUv=&B zyzfWS?Y{2xulsg+{(qJX2Ue?qCb26E*j+Q6M0W+WnO#}P--8`-OvMY<_ zSu;Ict%4>^yRt;xHPb6}SJ1R=SC;CxX8NRB1<$&6WtsWWOuy1y!SlXdS#Hmo70_xG zvPkUe3U}A6psBk;mYH2$>ED_aveYVcRoK;4;YYK=w(bgDS9W!EJZpBuQLC^`)2^;b zcg=<`M{CWFd1@8D>)O?IO$7S2T5Z%rmp=JI}Y~l`OT6eHC_n z*Y%@$Wm|X0zAL-F`#x)a#Zl|HPt&gNdG4BDb#-^#w{6$=zHiO1d1@X1>)Q2w-;d_k zecc`Z@7wkL|5*zfSm7u6HHq#?U^BmQkiQMS98LUKL7VBGM85JHhvnG{J6vs&gr?s( zqV87M6}l%$Z2OI)`fY_hsW!<{*KZs%KUUaRx+hug`;FuFY(*1VZBmrPZ=P^>`(HF^ z>Yfxe^P4CA+lrlD_xUnn;mui*0t@& zO4pU{&5rwi>-v7SvJI`aIZ5KTZya|k+cb4=PMZ1co9Elgwk);H%?iJL>-sV1Nq)C) z-)Ae|anv@iX!`9t&)v#*UEP~k23?N!)Hc8B`t5t)kCpFRew(lM`|bPx*(wg4WVI`3 z62J3+-M!+F=)QtB^E(gu+bfQ!+7)(%-+3f{yyBSYzQVrpJCEhrD^IxE6-`<#z^>|E zc`9^Yk)PfHLp^a1R*Pna_7iiS?rGWSux0|AM~0?J_>M}0Vmqk}ohJ-a7#Pkruk)Th z|FPkv7d&bV4_Hs!Nq)IM#39Wtp<(rRqt~_%S^Rb>Nb*}eV_*uj^1F2JYgF3-!`TPU z+|)EK*>-%BVCnm1mv{1U?sHzGUO0n?sidJiu};>gZTgwJhRqd+vV~vt+An+XSy}-3 zp27_b5iIv%_Y^WPFns^_Kdj*5pFe*FK$A`SN}H_N`jA>f7J{KmY$PC@5IGc(I$Cn{m|jj*gDw$B+N{|35S| z)GXqrrKP2ejErr>G25sk&XH>^BQKdpUjOp<|BDwd%p)$od-u*E@*poSuTA6yyQq`q zQJ22_`~U0jfAh$@_wL`1j*j+>TJhk)gKz);uUN4nAtB+zKhVvJ+qZA;?(V*Q`}UM6 zQw|?K93LO=6t(I4jT?=PjW=)Jbcotx5_#|EpZ`yvJ{1=iw~RP#6mk3A-~Vskyirh4 zaE#oxckkZMpFgv+vp;+GY}vA9R$<5VqwaqC3p!co+S~vBQ4>D>`fnL^-Z^rwRm{~7 zU;leXEo_apQ`E8NpZ*(#T)zM8zg5&t_sA_@{{R2^@4sK%+_N|TUwio9CFYP-#PvUa z{_j8X@7$#?=dQea{rA6p%!M!C|G)hD-#qG0?aW`R5B@)P=E<3}=S*X6UcdXxH*Q1g zoc}w{{eSZ2|B3tm!wSz{y?WI)=B82jl}GRYU$}4~wCH|8+m$0X{@-}<|Ly<(pZ@<3 zjj2C(?%akA8y-J?{Oafbl-j4xVQXy?Zaw_+Keuv4&ys(wvtBIN{=c<*)r8rXmae}X z8rN3Ub1$Qy@5Q_SLCLGyrrg+d;P%CvpHfQpq^736{PI7u=}mFpx4oDD`y}q1w&ZDQ z;iAIo-3Lznd;9T!P|n5Er%oLE?A-kP`~qin7M=w~?raQ7%ns8hn7UtOJ^iRf(UA41 z16!>1oSuUC0PRK1pu=`5;*6w9Z>Q)!QpsJG$Y7)CE#A=IZj_Ow5W(`W^znnk-T&qN z|7qkjFXLTiy`ttp#|Jn0Fn77BVLyNW`270*{fX*FKmQR-x$W3yE9%<7p|;{d6HlLj zyyJTT6X)Q^9;QxSBC(BExdc)VJZM*F(^you!ZPHc+uatCSjQcjS7co`L2YLX$vQnD47%9wpuTq|do6q4$q%2%?~X}Tt8 zbwgX`)oJ-hB?23z0v-RqjyruAyYl4)75R<2mK>eZ?>+g`m| z4O!i=TFy?VX=z$eL+4M)VX-+&I=d9&$^+3Po(FSu#H-Et)?`|Z{n zX{+CEyHoc1?e+(4+V6HenU?)-=L^W{hS%?Qe>kT79%XgI>-YN^*mXWYRyS~{ulaC@ z2fVt$UFYKwk?7RL9aYpH3S*X7xQ|Vy()_#5OYqvby2C!lkQn z7hJ^WhOBo}hp%o}eKqMyNci4BmaugEs~c+HTq(k~xUSrYx!p>XCGIVD_@bCn`D%ioOB)kIii71jrn5>DI8U~} z*M7p6D=9gdb#3@82R(*_5C&G!gxeen9r^p$h-kR{be?D!cY!IuqJiDzLBpE^>q}V; z8~ENGcL=vlSL{E?!4UjOf;r&;=(an@WeNf+CLfwtO}gY2G>M^+LxG9O;~}SFf(XY1 z{uYBNp=A=AteaFAT2%s=7@QKAgj*i)Fa$7h{!j8a5@dV9YpO95!zcFrO$jSHoht+W zO4De9ufpm%HV+tiEgra3^(4l;`+Ffec&U=*0qC?X_zDoQSkJMB@^Os*!o4vPg` zD_9&D79_M9@wiNn{?VX2y;I|eY)aMCNtYFp0yk%MuZvy(Rtt-r)o3zUb+PYR`(ioXmlY0LmnMm|FH!Sd znPIStZR#!&6P?|ZAO8ono-9$yNcCGvIoYZg`|7NeF% z9#P%JD-JsH1PZTGnmVUPfWw@@fwjfvt8Um_&d}(p&?31+1@jk-3`Gi)baq@_Ymw*{ z%<6QlF(7o6kz{t{-b!l*8Ad*ajuxkg0}~`To(PyTIA}3U;0V!S;qUMD5aYYV(4yj` za7Lm-_JmhN^8-ckmfQm={6!oS0;aNcvL49bWV+cSps3iy%8;`8LsZBAE87&}0z9%g zoo?7NJP_u&cqGpF+7TraMuzVU4YC}cZYc=32r?u%N{LwWH+^VQI3#;Qjc-%09?ufV zCJ7G9Kqgsd921X$>;U{MotCcS1XX?DdHcP1J$5t_hf|yTkA)-BO4bpFXCgg5+ z6nrGWp|Qhj!jVm;5@re=0s$YgMHVD5e4H`U;hq5(gG7|V?KF?Y>{WNNc%B@ZWjAw$ zc#VMDpD2Y579GkgPF;#RTNNf1xH~e<1L@!&x`=HJa==%d{{{k-?x}lK+SV)5!|qbB+@tI8tt1QaG_b z@DG=&eT>2t1rBQlhPy2il?vxVH#su-PKe=Axz8Zrtj}^Ne=2{=V_BOUnB}(C(KgTBXC`q=q4@{ne+IpasXv(#*trGS7!)=(TbRf(Ja}-dNWbu553|EP1`i8{60Y>-Gct#XR>bOxT7v$ zUBKBgp|JK@HM3z_znMU`L1VpnKD%Nyb74H&!}2$30!bHGmDw144m4eTZm4J>@XcHx zPF-NSs(`<`fQ&2ilCV0ak0GuR0>9J+td}=2EGXqSjOyFUA=A#v`lH3OO`vK+y61`% znIAPwf-P){S;49Ts%8QiAJ}385~j2Xm@!l^DVDP}wlYuTvYx>#F||f?yFhjUb2xj2 z$%1T#1ZM7|VNd=C2sAhdPXOlubAiYMZ3^2P-7hd(Cq#t52xpoY%PiLI=FYXpT_BL1VF?4n|Lp=% zYF#f%1=J0~yAoQN8o86*vc9?r1kcEj+Y#oND)4@~K=U<$6{-Sh$C?=&co;5lWi4Q3 zzn;5dTF>ko289#2c3BAA3>PT-z`9yP;L-{K{pA8dt`UpM`dJnlTOH2jUf9MY*va;> zHNCZtRWWq3YcxYZ!=VQa&I?$jJgYwhR|_`guuo)R_>ju@A^YzPf&B$x@f#{{aWKqM z$ZB|z%>1z7{)wKm;R3$@3u3H}rbI3c4i681VNu3>ur{N;`6Gv+L?{RAw}j{60zPVj zPCxrO3R!C0yZh7xrYsQP^AL#GHkGHcfbZs%yfA^qU!&q@IEh(t zl0d6~x~IV3Ql_idxZ@RA-W4>&PRP71I+@QfT(_c(^I$#K#h|EkW+zR~lc54xnN!?f z8tl2AAh)8y@~V|OQ5}6z$%s7Ygt|Lv&NjSxeN-EE_*UtGemM(%>8hK`9lFK@ml?MJ|oB#hqT)e`h`VGrVR0YmQ3iKTa`w}2vQP5>q zW%z-U!IYh0*#-g62l+b|u#0S4B4{ZPW|_^#$nC+_Z+W4wYI|B_TlD70iN8GrUyFlB7Jn^)WrvdR64D-)SpUW0F<;SyS6Aw&a|HyIqTmISOc?-Rg89wxHcv<}0 zeKFI=!j%C@H5CHWA4D)5V4oJSZtg0B{!W3mYt5AwOT$+R%ofPdpPsSg+L8kfQ`cnm zvuw}R&y0H zyQ@}BS~gRkgCXC1s_@0&dsVa84^E3uV?VfSd2-qu{cQ!#ovBOIIS=nBzA~*%XkujT zGWHEG1#F@Owtee$$~F+*wSmQv?=k1Zm0vm37qq2+WuD5#P!k><{34Fou+{oQT+@Ti z5ibR*Z?UKe&*WNIwbC^CuV}Qzf_8?40A|C0{cSvZJOrmbSlhe3ORkcyw~aMSf`7Y* zz!$6hNosSs4QqT$V{%sJGC1U96qM=*IEvs}#_JPIBZ36P!n%5=>)Tj&2+`-*&6Hqbyob4j1}3) zCg2&tyDW{>k@@9T_7|rFSf|D69^H3_n=f&@fc`S}-trx+3)zdVv%YBODtr*DVP;&= zzx?eLn0*|Z+2v+z~kG5s8?qI*TihCm4<e zY{g5f+PP=vOk<1N5N)DkFzs?sPR7>cIf)VvSqn^?*#rCAA_UtsBDSU;W&0m^Lh9fN zg@a7e*U~(B1RK+KxgRTFQOsQOEaqHjKj%lbIa&hqZwbun5eTn2-Zy)PmSNOnov6h< zN2CN#Fch4!ay;E-BQSwS$XcDnasrFp>zXq+=1g*{6}!01`9#Cx&QoHK*XtUdysR$h z^56{X$5XnFET314L^-&z%S4!U2?kd&x$exJ;=b~fkKys#XE+?sa3!7`sYH{}Rg7i{=`J>F-fz=t&gOg;j7pU*$NV_;Du&RcNdug)prFQk?J;yxuQ=W1iim?QK?pl$?B3??In%5m$dd?(z$y{@9!l8*~><@ zmref1UN)<}Y%%w;)!xfCcQ4!hz3d=+#mV-HOY9Z5+AAJ&uXydf;&bos?;*ZsZTAbX?9_C`zWjkekw9dmDV?Y+@+_eS5}8xv%2PO`l@ zCHCgD+M6@x-ki1f=A64X=l#98K=#%m+gnRwZ!N36wPNnAReNu(xqEBf-&-4GZ*Q`_ zy(RYcw%Xe}=HA}5_x7Hnvjol|@7oVk1F+}}GFWbauI?$wHUuU74QwdUTdb^l&%kbAw! z?)8?q*W2n|@0j;`*S^<#?!Dgk@AUz>H;3%r9Ep2#tnST;d2debdo%IK#WVljT#$Qv z$?olyxVP8p-rkt^_SU|)ckaEt_wVfkxp$B3-aUzX_pI(+ysYDkeed4HnN7IzZqdhg zAJ&P_d}#l9oC?L1#efUBP(LmMU6oE<3AA%WOSQ+iO8?D$6 zy7Al>&0ZuZ68|x8qNdb*@hMk6RwVlHB!1vXbW@O*`zF`V$cR1=ej8~Z{O#Mfii(Q8 zy}jMt-AqhO|Ni}BWMn*l{`~dp*VWY2&YU^3Wy_W~Z{Botbi9B6-qX`_&z?OQ85x0r zf$!eEn>B0Jgb5QKJ$fWBFaPAplZg{2&YL&ya;UKPk6+xvxvI+{rh*DsDn1)=l=Zt|M%}-!>GIV;Rina`v3mxf6J)j zUw-`$h?@BP%YU!P)#lOH{{H{Z%F5~(wcRT6w0X?kkN^K4J9g~n&!4stmn_4s8in5o zh?;Ts?0MU$Jy)+@wU5|z_3eMh$UV1i-TL(B|BrwFkDYmD7J7R3+5eWIhaAIKe*OO6 zKIVpg$PL%1Jr^!~4vVb~h-!6=zOZP~BCFU3mN7RUJ^N!GfA9Fs|FzTJdnK&jzJ2?O z6)UE${eJz~fBlHtC+`1$`1Zeb%thyj?S-{lR_^-i6}xxcLD0DP)kpu0jg9T2&KXBt z{qg^Q_kur{Z~ym*m=~7N<`+HBBWByX|Not04t)OqKfLhK_I>x7nwoa)+V%D8*J+EM z?>hQ#_u)sz!53<3YI1XPxw*OPX8h`${nR67u~Wh+o3P!brKPsEw$K0kH;jI8|Nea) z9i3CBPUV%)3rm>t?8pDhH$Mc%%>4BWbPT_ckkGPq7Y<(ffBoL4#F8UtFTQ#H`ro8E zH(F-DkIXq7l5;j9A|j&T?6dd(pFe-TWZi>;<{Kr==R6a)HqQB*UUNOWV9NaM|Ib|g z;vc{G;K9T1Km2!fb$$8rV&_-*=%|7*5? zX`FDguKUdHqaO=8-?sIxyLk1TzrTNS-RsKsP2q{NtGe&yRvze?e&N{JZ+@vqTe_F0 z7Hvt(>Av#re|qzagsdfrCFjD^cRYUlc*Bls5)u-LiHUQT91737>y&VJ{_^ujj^DiX z^8d7H(>83_FlWvj1qFp!i?26#?(XdDBs>sqxUd;M5Z>c}Z6N$jLt*2&`3}vuQk1r= zKpqJ1f7b1_6?q_Bo4Y~Qd)u0un~?^>PobPTe}8`iGxt2rtPP2+^8DIyXF%Kh41}HK zUgW|~o&TxA-X!iM#1P<+^ZfFP;MH-tJBuE0iFQWuoZYqU?d=`K&+oL0ZhLnhbn1Lx z)VBMvD#3cweD>@FZS&KX(cQc2>+2hv|GV&g+kA<~w>Im)y#KyEKPTQhzdHW>zP-N> z{=b)<;x}R6AMil<`ThI<|7T#+c+kKimXVMyA_E!-H+%7*S-?%>VT(vu#zV+9Kbf)& zxm>w6jYl0S(=r})YAl1CI{&EK;F!ka`j2Np1L1w?F?}}QUOeuHZ1WS#d@|8PZRL|m zK4veUOb&3g6&Uw!<%%FKB}dglo+{GzWDc-142r>$N+ct$Mv~ z&$n0E-i$2O7Z{l$KD^#|LP#Wsfn8PM0K-YQ->)~ZbADK}<;FX&wT{=EX20FOB`-Q) z`-5rHt9P(W%zn3P%_8dwyWSj&UbUO)p!WN{3odat?EUd=_R4*Kera!*`z@B`!&YW> zpO**kX}$Tdn8#kHaIv6&j^QHF_%$CFaByT#*vy-+vuP4*^cM%$gLxAUo|M;kaDa)i zUuW}-pC1$^6!EdHZe)W4|F;{V)brdka0+O%P7v_`{ina z6nhI7yQQuJE02#rqlisJ@7J4}^J)aoi5A{1W$>53;INBhaqjl%+xGq4!t(gq|Jv{O zjc(l$yv;1Tb~^*x7g?hRJlfBL+X zXRHt3Y|VWC>uu1zWykg8UvXaan{b<9&Apv(_BeA`yKIx6a*2icp`UUetR%&pFa~x__l`~XYQn5&6xyMnhsE>;JdlreUo_tid>Y`=rpG6YQ!p96}37V(c zES9!^>iclHsB*5i>^x z7YlC%)=Mp(dY>k7I6688F)&CoB(TijQH@P26!1Icr0~syiI-tQds9fGLY{<&n!=}+ zsB4#a^KLM5@O(PebY%gTb%Te2 zs$-d_Ko%Fv?29Z1B(n;b!k#JeRbEJQ*>KaFVasHNy*|qwuV@Nnim6QG>RhU!e)PXi z#bspxU9%c;IZKPvTORiENH(3KJ4}lBJmrK6lXBC6KJZ z#9+h9z{&RMTvJZ-3Lnu9XZNh0+Agn!OpU7hCoy2=EB5jAVc0(tIXV!LxzG?w^-{zwZ}?IMxQWT*nDTO`;5e zf0j6fIiB#(nbdhqB+JQU_q8KpDJ*XaIHcA@tu&HgS;~KNwS!>Nt@fTUPOplU4m}JF z9{=;6uriBwsA*nmZ_E%?mNq@1#VT~Oxu;nnC-jZug~m1mh3N_!226s#6vG*04l3vy zs5v@Fb~nE%Q#`s>&siutx-q4B%WS3=7si0oZ45~Y_gN1Z$T&_Y5IG|D@hF=kQ?x)B z#}Yx7gY7Owj11?Q7O*o^s5o6w6bSgWSfO-oW;*Mkj>Z+!6zBAwuva%~t>U<$$WrDJ z#OQFlNhMsd|IT3tGo6P`42KnJ9P*c(Dx6@?U^;p2+7u@ys|m_1Vh1@S^PI#cUiw~j zZ3)LkLk&KrOWfQo2N@ciU9K(YxTu%1y-`*pjNhoOQRVt#rbyOK;ijIq*QO~XiFs(V z1aYhrQ~AG}`{SFAt2_)=eIW{y3{Kdv7&VKqTsp~Q$u?0`C`MBM6c?AHHiMI)z#b-r z^QC3#P6dh+B6+M79oQJ;Se#s%W+;eQt@Tg{Hej<|f)#EBu&icZl*RC)VQ&DRyU--9peBby3Qi2hZUK9< zn=Ga)9Jf6&hrNie<<71Hci6Vot53RJCUIm<$pt-zFE7KJTW+0V==iZ&I+aQB#?J!` z0`86?YacWoaoFtrU+jbwM^k5;h}B~O%{Hf98z&?OT)KRAse3Aa%SLuhLyt9q z6W(*}e9Dx0(BX)}geK;OeS7ZY9pe8~G+A4g!KyXOB_d#g2-k0ghI3FowZ9` zgc6x0pR?6F-Uu4;dF zpTl#qB|rUcjc63?2&->u7qnw%SmjX5)>y)EkawkO73;*>)+0G04@+1trZ6fLa|R}s ze5>t0#MZAWuzpK5TUtV)X`#8B7sG`*rjK>Mp9-Y1G3*o#zWYpIR%j@*AlEN8hRi7? zYp&FDHnKTQD2hHRc#^e+>0ugYVNUmU0jIRI>t7ofHncD^HnLn~c|A>_a+}Ngkl^X; z3|S2VP8V8aJT$@!1iKap^h{`GIMBo_SZ{QcjhBsqfsJYX6E-K;Jm!m)kyk=o)dfrq^ zSi7TRpLs{N0~^;j<|E~m`x69jvUk7#7Ri|*IB|o(2L|u*_91JrxCb4bI`L{*D<3~4hBQpa-JLknoOcyKJ5~Eo=C$&t9-I69yV8HLM z!L(zWz(tEz4#&PYPl4|5>}(gScpp|A5*2i^6p-=|n8-4@_GsA2?E z*f`OtU9jTBL!*Ya46g9%6ckNAj5%8;s4ILddFwB8L=j`M!j#H%~RNV z^-8tG#u~3LQv@3ebsjXcP7DxYoWK3&Owoh$*%!`c2w>h=k|$`$oNFnN&e6x@$jod} z$bQjf&zETCjd2=JSq(IUVjg%NFY$XeQ$tcs=*LWfFG~X0#RYepEMh5K6o1fDU2NL_ zh|bxT0!&`s2PGE0|GIG6C!Y%;Lf?N1d~Fl_zH(6^qZfB&(lqr&ZR!GsUIN!snX6YW z?%dRD=e2}gkZHxnmd@|Y1s@U?tG4PbEDY+>39FK@-z9i8At~F}8o zm#o%aiCTNDYVD0#Yj5pZd*{~Ld%xB`kXrZ1YTc8lbvfjWFy@9QI1IO$QT)Q{$+}^x0h9Kub92PYWMb<+uQ4YZ*P#^(PX`&C3;6&^^T6&JGyr7=()Y4@Ar-g(mN+v z@0=37b6WMz8MAlJ+P!nm?Va;}?_40gYmxP?CDFT4brKW6X$wR``c+x!3h-p?R&fXU_nOUwbbngbkj4sh)`z;ovS-=6~l zG6#ih4vNGa6stKXG3TJvo`W)X4$A#Gs33Dl$>xws%ptX!LmG1qY3(_rbLWuWpF;*R zhmC9wo5UP8t2t~j=djhD!!~yg+xwo5x1Hn9&?U(?K$Fe=ZN2*BLOl; zgKUn5HrX?Mv<{hblrPCHDn>fu&e4jGN0}zdB}+k8dCD;`Fz7HaY-WgHfedc_`~RPT zf#L1jxBveBV`5_Z^XHF(g2JyqpfMqnh?_tE|2K}j_51hlYj6HrN1V5fJoycL(v(Hy zWs|7uzyJStk6d9Me#1EOu6g9$_kaI?|MUOTzyD4Vo2{d+Iz{esjy&-G|Nn1){(t@R z-z93TdDM-tg7fB)*Da#%nMB_I_4of*(CW+^|Ns4WkJxbP+Z=AW|* zKeS@S3j4^TR#8Vk{r~^@&wrEfOOBDtZNg4J`SSni`~Lya(>C}TgKe`^B;63)%NY%fByVw5qb5; zzyF{A{oi=<|M4?VEyF+;3f{hb+dS&LMdUu~h#OPafkw_gfBWwev)VHJ^3I(*KmPgO z)6-K}v%I$ROjh0H!lt{<@uy$^`)?e2t+250{KYSO4&O^DJGX$25t`yYlwy>~Ry866h?9q3h|G$3y`ug=7-chs9o<43Cac%YL)m&U$ z){%#=y!)@FrWRKEzJJdCuEpQO5<8CH{eSZMfBV?0K4}MngM%ZJ=S*7k!ZUVmNyGZo z{8?@DKDEsLzx=@el;)QQj(v#D+Y%Zx<;BncQc_YK(;pl@e7LEpDI>r4@#Dvf7A>;3 zw}1NdX(0O6j2#D$+?Y7$ zc~s%ub=&WE&pdqf>eF>Qt|k?4&1ikO_29>a+y3uA`E|$Pms_@MdHV84ZO6*``udiR zMKv`wK56HxtE;`U9;c_L*K|LKufAK-eZ9WEp77w-#RYTw6r91UJWo#62*zCH`RdNe z&CAcvcWCC4^+FxoTI@9!b#M#mN=4Wz&*WP_C6HEmf(N(ce0FT`wQmEh@&pZTfzGh< z*$Ermf~@lFmh;`U+G(rudi=NK0VKOH+XRC^}VyZx4#DuZu#xm@$vDA$=dPf zAcI@p^Zg)$TiN%|?cM$TJ!F;VzCAxbzW`mSxNq<8?;jqYp6|bZ-(SqZtp|;eRi0P} zw_ZF1t@6Y=xYc8F4K%p*Y{g@IgIhC0EQ3IUTheijPp8GKTADgNfqH{mbIM-92DcV{ z^IEw=ZKwaLHBlWW9YVK&&am2YZPvAw+n!0OChhtLTII>6{RY0ubIr^^9oQ<*s}H?E zt30)}VsDYL%9H2abY}^hfJ0p7Zwi`YZFB@!gu+o)d0xBA@aaTGr_ZO8$uoOCol5$u zG=VuwRr#`{(Pkb!8wLXzF?r*UImO%C{^)E8bFBzpk;7#bu6EFbN4`qdzO zQBa_j`M?+6opuxcFuXY8z~n9<&am$CiE*E)$q8iz~tV%rHQw!r0t8qrrj+allz)&JTxVX&IFjfS2Ua><6JS(k0Hij zUgVLdy*?lRGdE3`s9-0+aoEV+vxP-Sv20EUtH>rtH6ax-rjPN~j0MdOkBk+gIXGS9 zFP&}Kk+W!GwTF^Kl3jDe!%XIr37(vnjyH)EDP6Yc_{GrRP^+c6fT{C|!>Y=_#s!HA ziZLChH4fRgBq*>}-&S@K3JXqDc`|_^K|y7=dtcj&LPcK*4rNYG2J2h;DsmYyp7ERv zL32X#^jRBZ@;+=W^3zFboUqiv%tIhrVWNWJ)h6YttjkI_nHX|6oG=!=#M7#>kh8qi z<3hs*0U?LC`2wDgLxq)&r*b^n#5ytABZ})_6GKyFae)TIAIAwZ-IkPO-enXjQMlFg zreO`cr=ydkQb*JO4b7`-w+6cBS4^n%d9!ZT9FOa2-q#x)E-Jaoc8DqkZ4>cOVbEyQ zbLv^J?;IyfVOS|g7Wb#?jXIl`TN`xvDPOvI=amKr%gg8h;YZQOq*Qh=NVK@9X$$=L zyIJXVhzF0trI^+;&azBDnH}9KCPp0!Pza0RD6K4y{hpY-@IAAGy>gRj%bKYQ+5-0# zb2TP>C}Lvxe)mM(*=l7uh6B8&rjH#Yy7!qdHSA+P_@st2D5hEB;jvzcltWRsCkR?E z+0Ub?<8&-~;wL$lR{0nMUuhiyj{1*B)>y|nY1If=%7`$mi{Qv%EVyx%*JYQWnuoH& zuE53}2iB_81!~s3e5%R(;Qx#-3=CE5pIToqDjXDUEd2cCp_g` zGLvuP(MNq%0zbJ__A|Y_cSI-YK`P%8(Mf72D#UZ{<|c?sGZ<|6!K35YHems`oeGEc ziaQhdwoFmHe50|4bCL1H)LF+fmtEuzHM+UhOl2omW3;1@?t~;hl|9{MdCnyPP0>Xv z+*7TM94&MO{JB}Ku*GFM9*Kp$X zE7^PQF;=ef>zJZ^XxC}pCC85IaxfpZ7D&}@xzL=w-F1UoKnkDb8LxMDRb_G}-H<%e z$uUzy;yZ7{j8C`k>NRb52x$;V_b64k{-38vWc%yB&oNr%8M$4C-}t7M%2IMO&0Yq-%$e+`{hSV3nteVjdh-2?A;0BUdfD1>=+b80jtS~Q&AA6;6o1S+%+Mr<$?n5d!I_DUEB9=ysL1bI8>lLUEs_CTi%7n0hcX#r?YFf3!J@NYa5bx zpj!BO(1o1_T=YQiOrQvij7PYxtS*NOmefc@DPyaV9;<0?=)@HRx+A=m8I~y zz}N2rZ0@Gqf}Dzp1@4ZFjm{1l5`yzg1fClR#08`!Keh^=A&{FPur)N9{a|ar3gxRQ zLYfP5G%VVRHw(sPh$LtT$+rZ{s|ifr5}hnuFZ8j!bcTB6{|bSw6#_LY#Ji2T9xJP9{EqF}A3M|=S+BL0$Of9P-O9%>A%1B_myS}= z<%PzV7AL7aw0Azxz2k&(ctGvpik=fQdQ1$N&)n!at6?y0LC+$f zqxa5@-g`fKA4v2)vgmsf(f6#P@5PM1S3CON+~|Avqwj-6|0j$7FA@FUD*AuS=>N5& z|Idy7e?R&eBquOgPGE_gz*aedW99^|ofCL&PT>1FK|pe%kmW>?$cbW=6D4L&l-fB_ z=H^7XpA!`%Cn;G@Qi+_TRyj#y<|M71lXPxQ()&5dKytE?_j6i-2*J+H%QKCvYgQpIisy|M#sz((bH)V8nUgGMPKlg3t#am!nKNhYoH^&_ z%y~a&E|8qH$a2<_$XUxOXRVkyYt_zKYi`b3_jA?;$=RDMXK#s|y{&Tgj+wJ}?VP>m z=InhxXCIK9bI5Yek;pm6D(9S-Ip@^QIcILpIrnqU1ocHLz<-8}6^PW}Cdogp~tDW=S+?@CB=e!S+^FLY6{}MU>Tjl&8Gw1)> zIsebi`Tu^-XOLRJWVL`LY5`l-0*+Y=xOOezxwU}r*8%~lg+f*fMWPmpRV|d5wNPr; zLYZ3&<$f(xkXoc({T%n>TOWx^?5mjXQVl+_h`hg9i`( z{{5Sqo6E+=#>B+L%F4>c#igsOs|Mao%EH3p>FN3N=g(uuj(zYvnwhp;^pNP7Z>N|=C-o3s;{q)kB^s?m34P_XJ=_wPoF+rwQ3c^AOmdw9U2Nebfo%EEGasfV>SQ6 ziW0B2QR{E4DLehPYX5@`5xb>kpMSBX>TKTb`yY1H_^rSF{>PrW^Y4HEZ)j|4ZfR|6 z@96C6?&a!-+u;XE*Xyv3l27O2y4Zh*s$<$yMVIS z9FL8Qj&@5JXWcomaq;nfB6{5a$?bAK#{gI8umzOt| zhpQ{u?Ee1Zc6-Txzj+lEijPmPo?k2H@ayY`;O+JD`|FS5#YIat6Acg`op&7sfzzyaye5t6x&tyg*u6DwN+56 zRo!;tdWK@$@kQMx_e`ajf1Zta+?S;J!6lnD<3(JZjhN*13|^dixPEV;*Wng4$(M+A0(^Z-_E6MNXvpGIVZ66{G8oU>-niR_vS&76YsmqRjV z&eRQ%%xS)9=bpX$_8-{Ey!#+HbM`PZtULwIoC#;nT>)oK%j+033_wV0lV`IzA%)Ea6 z`mI}_k>T?4aG*x( zKRKVCS$w-Rk7?JJ*M%#mZ|K`=9sO2iN40#t*dLCMPcCND;A^*uH*IP9I=zS=d+ zJQ5l9_5UhwerN3vWff)!IFQKjWx2xt`l*~R9)$9D6f9u)t2$#r{a4!+ia|^g#)@tK zb*DXSQxTfl(Ae&{T%kdA+l(p9vlw?g>d?D(VluP*Ig7=;HgZ!J_i=yISQ5a#gd=5w zv)ajE7T2H~3tDf-{#Y_8lc&baD_J^GXWfmbGmLc^(o(JSJfF>y7ZtcU zQEAhOXLD3{b~a4OT;=(Eo~S27BoogA$tCk@#BK#NGs>)BU@p9*zI@??B$oz;@>OQ3 zOJ>BGysVp+_G;xaj z{r&*E{+|y=#Pk1rJfXh+&!;oy@Be(h;I9Ao%a!o_zh7^pumAh)PWk)4-ygK=|NHS| zdj7wkFP5+W_v_8}_y2x>IIjQy&zI}@|Ns7YzW)EeKi}W~|Ifg)fPvlP0F%^*1`eME zOyVaFuvvX*6zEyNqV92!E9yg&#F+(b<|hvFRefky;91Dw?r}(H)`u1ipM_lECk~12 z`p|07gJV^kK)c5gC8>`c9zKhNrk^;XX7#Z%pl6W?WKmpK#F<56+fN+TtNPfTz_VE5 zxW}=pMzcQlWcVPhid!u6+~c^_t&e>bXBNwSKXKgd*T?<_o+S$Go+q57K27NGS)wF< z@`Rh!r->7KmZ+$Ep7e_PG-<|}C2Hm;Px@7Tn!JE#sfN4fsi0Y(rmXN;suh0nRM@Uh zQ#bT1)k*g}9d+x|v>j)b>Xn~79rx?g^aDK04B9=RWDM&1AO|G&Pz{<|MoFgzyA4e8F|Jfd&CUm!H)C~;{4H+339UUFJ#G95;SKs~p z|N1xR(3r3P|Jz61vCz>Opff2cDGp%=t)uT=z5Pos=&E=8Dyzs-W|0?M!jHN~ z@9664G77uq6t(uyp+j%K{C5jo5*Qe0AGPPxU(l4@&6_u?s;XSV*7^GSzJLGz#sB{s zHf*qnz2zOb$}r?yXxv1@&|9_-_6bK=!Jiqj{SE{xUh2N%J}&B zg3dRwRZo{MUmg^HV9lB}LGkU+o;`c}_U*pw|IK3V`^L`+jG9(hv*p5t3lkSTT5;fi zX5+ODyY5a|`02!zPl}3)RntD*c=rGHoqJohY_W@2a`g1WsHmvWw2dL@don67-2L*u zylJmf+^ti0|Hl-ZSiJhoJYsKHhHm=v@4rptLuFM;9FTJyF?mGMb>sQcK zOQESto2S28z45`^b^mWa{3j|ZYHMrjA70Qm`*3dM;-;pi`u#f(C(2Az#MX^aZ43c`J2<_ls@PGW9IWMY;{@Z9{&m4(5k zcMFyo#VIQ`v}Uo0ooL)J^}rIb4h{ ze0i`~Afzx%!a0~B8h6Ch7L6ByVgFdmrAwpVK5M&?ql z30f(s(Oh~WbsjGu=f4b~`-gfA8cU)YZn!{h#o-fUS)urVm*H5; zv<5~`lVb-qTFI*jJN}iJ!gZDDTVQbCb zNf-D9{(gvm$RW#jASu;IMb|M>=m;B&MfZ%u%LLB6`Uz|eeeC1ypBwjPIr`=CbO(mb3CHtaoj5HKxe>vg=@lre_1YB zoqVz+o$aSU){jlXCnQ?x-gtu=22M^J6+IX>`08w!F7UIV*NSH&yEI42zQ!1Xa&|)p z#{UJujy)3k9R_navKcNY^1jMfdoFZhquHm!O(_9>Oe^`mum~A5w5-9 zhC!tGEyW&Twx9kCDw|!JTpXP41%<5+anW)ko3}gI67^aqZn6W19?R7K> zI;K3~UL2!=+N>)IZ9W|T)Jo1x+x2CsL9b@)xl#s}FM-P}&aU(;m)a5(l-4!Xk-?8C zd`kGIFDpEJR|QS)5>$3v;GdbiDrC9W)m2fZ8g{GPNRCVs1%FMGAx{ zh)-x@4&u7DZP(Ye1-=&}&rUj{mZi0>;_T|U)l!aAwrsN3PW5o&bz;u<$X(yzyCz9| zwaCvMPpuWXCVRg*b>mdjw@oud&oK!+Ja?w*+vWwlYf}T7t(UTdZCT;FHp}%iXMRfQ z)(yRDbJAxECjFl}ZQG8sYx54ao)8U8EfKrBwxHen&LgSsJ5KnnE1G`#&ND0VTJzd< zCCk0&Dr2W!q2ReOL8;_XFPb7012reVX-s&kNu6Ro747`?l-*-VeR&Yo2@G z|8?v8z8`1T*L^>I|KG3g`x*E)G_dAE00v=tgmzsok|2S&Ux3MSP=dsjni8UV#+>-YkRCY5zzN3Cnkx3b1D}v)6`AVw)aSUJ&|U( zG=o*|*YT%Dvv2BZ&G0NZeZ+TlOLmS~QQ78~&|CRxXG&lxx0mr1|X&}Q6xb@KvE z9|jBSlyl8~TNZ@}y|7bfx!B#eWr^mc7ta4HFU>gj#YyX~fJgSP%L~{TmLD&E88Ex* z(&A~wEB(*Da#?=sd`aHcHCz9@a$jF{ZHHd*V%uJUxaYsF2i^O+miJM1f^_wXL(7Uc z_Mgp>R*$~AF>l)z-#IR&Zug?7On# zOK!jH``*CZpqw%3p(&Fk53@u9|E2}4S&KXl?6~dw;lPyWdmQcsTvaWT6y{MqK_|MbNrh)1HRkMHP zHbe$L@IKWY`yu1-Q5ysPUrEa)mN(mEO=576`^5Kvu{&PmvG#iIEQtlnn5p@_<>v<-7J=2V6y@gUs5`51E3&}r9 zS;oY0>soHAd4tf4m}DXD`hzwcAH;n(6&JCU3jb()s9H8ntU)27>5OQ(az>NZidc;s znIE<_8B{d2J!?{tXf~S>t>n>czN6XbMaJH5O*RrOJFhk^32Sz$Xjw3|*|np^=SGX) zkCp(5)*y@4kcif>iq?o3tx-E#d$zL2Scr6fXic(cONnSpd!hckpe<`gxQl|omJMwM z9AUWqATmsV#3D#5wZl*xa z{D5w41tzrztj-&ln`caD6yP}E!R>fpf@1-b^9Kg!4;_39dze1*uBzx%OW^pyG3m^I z1BNI8j_DOl)&gAl4_M_gnH3V4O&dB+c63a$U~qQeb{61@JHYHLz+(M@Enk3z=^>Mz zfxyWVQ<*m~Pqbi|y@8W~VPaf>fXxABra{|pSV3Ib0(1fDT4+;ZUeRuC{ez$4ti$uyC#;sW~*1_nC@2Dbzj z1qOx#3_NQTn0ha;GZb*Wci>QEU=VKLTCE_ki-AFufx$I_BUh4zH-LpTk+0c+qdQ@? zAR|xj1rFf@OzH+~PZ$`=CotwN;AbjinHs>!uz@}A0#jlGXNkb%iH|z?RCuASuA!SjZphz@)T+!|MR^V*_sU2IkTL zc7_1;g8XKo+-vh0Kgg zzUJvu?*;RFtrnZOG1iChFcmIgX`E`Bz`|O%{Q3gEgT&>6 z#Z7?~8Ukyy1iB~8VVTI!IDwHxTVR62s`3Zx<1_>U1r|tfG30lwQ50Zk6<{rOSjk|( zC2(oMSH3|L;eVFiQ0#`P9l9v2vIaqyksVlcnJvLRw6 z(?rHg4D1XOcvvnn$p$PubAqX+YN>?)tFJ(tRRi;K2aa8l(>707wq_NdA_HfTwetK6 zOb!8zvR%w;q`C?Vco{CRoxZ>%+_36SREh=TwmlnoGB?a*eaOmtpm!tZw(|+x(GR%x zGIU!l;Eh*Ulq=1Y`+?`p1C|~ImOSrOP7Dlw54fs-uV!FiVVcO z2^YgY1_qT4GxHc20vY%j0=VaKv&l1bUuRgyc9F@wLEuP3??z6BgA4e#ZeW?>z;14^ zZTkmS)eX!()y!+G*k?7c>~&c6N@}vfg4qi>815|KIKsd%X#!(aHg~20qovdiyRyX$ z0!x`LvN1HUujgdBxQfLvVBy>djyo4vbvN){HDJ1Yfi19rxhH{_EovWw1Ao^B7WWTK ziw_(Y*5+H+u*2#DWq`=g|a9m$=^FJx3iwq2*0Zd8`Oku0% zxEOG_G4RL>FjaZ)(q~{%F%VEJn6csmpC%7O*90~P1{RM7_N5xU?2TI+xppvIIPjx_ z`R{5Dh6XO30LFxZ6?+&MWH<1xm0lYAfJNVcX}g!eeFkQRg5?%EOpiO4pWndh9&p&~ zO!BM^tUEXC(`jFt{($ee1CvP(%dQ8jFCO627GQI0n9U$C`>z(C{sq2;JPgGb4y|Bd zdR)nTeHNSO0v5*r#y=N!6=k!e?Am+IhS83JN%#TJKB)sXUILS<1cVhh1Eu&*=xnT> zaD0`wz+bL2q7xP$U|90go3mxZoDckJfI_BWw48N;c2G8g%uOp3V_5Z3QX^#7Sk<`S~f*%fxq263<^wt6i!^>W@sy5iu=I8aDYqRVdb^}*0&527a7?5GnpM9 zFv&+9ou$C!CeUN8z{%9ebMN-94+}W!el1cBxXd8XDs) zJizDDu;rtMKsgtK?gehkp5ux-9HIeC4i9*)R|)=(X7NZk&hkHsG4a4$h65ZdYv=s% z-sNDxnIFOOP*dRe1D=dqY!*5K%mOSi2QG)@9*^YZ?msD@WWb>sz-Sl1yIpFN?gTa# zop}r&`X;YnF8RwUr^8abfz{)~qKO+g))}l<+`zir=Z4)i#^qgS0w%Dn%MzHrnkV7` zTiu5lt7TV+Uf9pHk>xr!!$R9zTP*~Xdj&G8)-J#Bm~~<|`^F_~f-G?bOqpH#+a}#nPoC^s=5U7dF=+oUdwR!# zMO0v#z#qmyhwCN(wy=C$n82_>@&E_-n};^XUKoDh=ywn>FlY}y#qGU;R^JT0 zpO0en1l|fPUD$iZOyMc>#w6B4<}K1ovJLhJ3NTp-9OG|1!2FTzMg!xE0CsZ)mO6!Q z#tl!3Urb{@c#KtWQ`rVqn_Pj!6-%qU-wFk??%KsXg_B{Qtw7=(meT>OdGl6tU1I8v zWUukN&)mT1#>W?W_xZ)#iQNqXeg*>4H;Y=&XwHdyE&J? zHF6~zyTs)QkLScC`!TQxcQH0`F+_KAu@tg}GBB(?efY0$NB@oew|?Jba@^Wn`+Bve zK<@vQubC$@E==TFc7fCCJ|}|$@1YIr`42K5@8k11{bqXi(hK*VT&@%7?tRNtxc|4n z*WViib9)6A-{vg5u>R#ffs0meyKjEpWxJ5MfGI!WJqP0pj>fICJ5MkqbbU}@aeBaQ z^@rCx;X@k3JLZYgln;DhxWK2!%@F*ayXpO{0)2tZf{!NC7{wXZJq=*gQJ8XAV-1tx zC+j(vnGKKdKX|qC?sw*gpV&9D8uBw3`|qBeGh^EV&aDC5?U~#R4D7K5SNR%wUF`(+ zU0@AR=;k``g!9aoe^qZw65iGc{E0pAYfZnP^v{{{+AMbr*c;YyE?e+*ioL*5dx2Pc zf!z(uE(!FS%$aWe{{s863W1FOKMfMz%U{@4e1Y{vKKJiat7cmW+_}KCebzLa4c`~) zyktr|9oz70B|pP9gTK8EKNuJt9ym0y^2)i)2zcn!#w%;rA`$q=rAt&d?#PUZ4_a*l z84Q@5F0?s_GtA;y!<4|!;BdsHU}5Q^#{N)wmS2&V@)TqkWcl(m4Fft4NNcm19%5{` zub~pqFrk5wA*-EFiOGQ(Yb*) zDl4+0uUR~LLIXF$ybDYY(;FLvycSsX2yx7ke&@NEMIfeQA!B1&;tQ!}B}aCK{vC== zE!RX8xOIOqXgtwryt0a?VcWI^OL!S>{YdHL)B3>3B5&~U!=k+%Obr|oS~nBf#SAhJ zs~zRa>RE7H$@-kg>~iO_Ec~yqZ~LeVS4Y8?_paZ_U?`KGDfnR-rtF>wv(D z$*Kz$v@OW7DtOpyzDI|-L4ak^88wIh+bojUf0eCxCeqmTK*`oqed(4UZ~dbt!M^5C zw*>p!+AdJ=V90pb;q~W^B3r?&43d`{JcLvWJCtiUJSf)kc7x37C7 z(80nWBspb6?s18Sb0;%6JPKYqJ#81_R-9i80|FTwW-T~>V6k`r+abnD0xb*+x|CjN zJ3kISbCb29goW#tXh_3GP6pSitQC^`d!!aJdvctboGQb$vVB9l!_1@Wt@9WkwC3M^ z;Wg!P*9yng(jKm_86`Lmt(7sidBo0;HR+}5Wa+4V9Y$$ijwwx!DZAO)*K^*Xb3q2r ztaZ;#7=9@9@%vaV7q?;1P(C|*l>iHWFXM%_+{Q^#9TE&@E-E%mnH%XU{-X3lYO9hP z!}3mxMGuY#TK$_Q$S`kdkt;{<-5K*{t?yU++Og{War^qe-=FWV|NozzpNS=iCwk5! zHuDFO;dTOB7$%%mIGybAo`s2Z%Ml01*TNoILhY^pMOzqI6b>ABxF*o#!m~txVTJ1@ z1tnvKmd6qv7Kd0GE_5&WdqzQ5TKH{*h*VR6aD-X+-CNUnga#&vP!Nwu0z_RDl#QsJHCysv#9#VY; zEayd3n9YPl7&;i64LFW;Bnx?1Ff=gpbtbUfe&H&8jlrWr^^s(qNnbEW#wHN7A|J)G65lmJB=1j3@kb)mNokeFms8nU`V|qz@){vKzO?a8$(~h z*+9gtIG$5Cc?5bM-hFOjckvx&Nsk{+PEMD28x0m|vNJkKs7+YcByw=N#DQ!99>xY& z38hZ{2uX$phu*j+O=}r8MDo7dIbqvY0fzs64UMfHO{WF=zAj|AA?C)e6vzy)jRklzzq}F^dH<>uEHKF*7)Fez@4TNzYNMqVZsec3^Mg*}$$}SD3`r8ZL5$ zC{3Gt)ZJ)K;5P9$r?ktZ4@zqVGCKJz_6=2FlF)k^HYjbxjYPcRy=TG zK4#D+w1@1&RM1DT+-|XFK1p#4#B1S6paN>PQf9UBSXo zmcT5opy}youxS^c5R2-R7U$IpH(0KmnV!b-TAHPr+3cQx+k9Rp7EzAHia7}#3t1kr zC*_74wS`5$bWz`f`d`FO<5B;rRRIU)8FK(CQvM`BH$(S-RXlA$LbmdW=&&P10M~^ z-@3mASBM&B#YY!S{OE95$(WIit)R&;!&M=0hs>6yM%Kn3kESa7pE&>Bwscka-B;oF z<5#dT6-@fP=i#w`eN$>{KQ`@&dUfaE>M66=I5$q8Yqi4E<3ghDrp?`NZeH;_A;)xJ zvr9l{*@jA=bu-Uq36_^D+>ki2`r|29>6Sz6S2B+AzDk&oam7i-#@6HR#(kCN%I|%i z?|**9$H-6BS@#rVj&rcdDSm5duV5&eUtM-Z=*!h)XI&xQsz>5_|DPqRt9)N<-f^A% zQhdvkqboDLgl)T~Y!PNwxL(?BeI;^k_MTk_4xQ0(l)BMn=lS80*wze2&J|o$pQhjc z^W44OwScj~e6zx7iOd6Awr+N5YImPM%dGsbc5B|N6z*w)f_ACS94sqWe-T!-GCaT% za)4E*Usq$j%Ecy*DGt61_jgM3UtTQo&%2*t3&+po1N7O_9S!CWnn(4x5A={%@Lc z*sSERdCOsoDTghW9JbnW*!sv}n=6NHpB%RPa@d~bh=a%xN0lQ^CP$oIj<|#zaZNem zR&vC><%q|WBc4l+cx^f2edLJGl_S1Sj`)2!;?Ht4K;&qk%F!T`qrommLqd**rW_3` zIU3$_G-Arp$R$Ukwj7N``$Lm>6G>DvNR5{UPa-!MgL`%qt)|3-%B`4Zj zPIOE;(YfTr|E?`3x{sXbxpJcS$%(!%C;C}VP7pacQRU<$larHOPEH9qIW^_vw33t4 zTTafHa&qR9le4y*oPFfvoGT~iJ~=t>%gOmHrxu8uTBverk;$pWE~l1+oLZW4YFWvt zy~*VCW|z}jLQZc@IlZmq z^!Aq1JEol8x#aY&EvI)MIlbq~>Ag=*@B4CkKg*c|B4-Y&oH=B2=CI3|BOzywrkpue za^`r;nG;jaoLq9|)Rr@+kDNJk<;>Y9XU=^&bDrhw1(CBCRnA^AIeXdV?3IwSS5wYj zD>-|;*yY@lkaJH{ z&OIwR_q^rYiz(+`E;;vV%emJ_&b_&E?(LIv@4lRS&vO2Q$oY>d=RcX8|Lk)9OUU`J zDd)eHod4c({>PN_KbM^UwdMTpBj^8IIsf;``F~%||7W?tAbNpO^#YUW1!mU^ETI=z zQ!lWUUSMy%z%lg#=h6#YTQ6`Qy})zz0`Jocd|xl{vtASsy(p-9QONY7u^=eq@ z)$rD<5mT>5F1;GH^=kCdt1(xv#y-6o_w{N#>$L>YYl*7Yl1#59yIxBPy_Pyv$}H(x zdh4}}sn;@>Ud!4Vc0*)(_SI{-Pp{>Dy_U~H#pTTU<;25?L@?O@I9ZU~cmY8zPwdLSQ zh-x%oko0J6k%(Hf)p@Zfhn56K@{eZkh+8Zc94l2hYGQ9mRxqtjjbhc{aDNbGU z&`~eiusN5*Xu_Pv3DL|94a^T3cGezV>&j8x5YfEiR#QYoKWjsmEeC(WvgU$@1*&(9 z&)n|1&~Q+cV+Cu2WW=4uhC7W0kqcxyWEAc;TCgxM+&*pUY#YJB%@KQ5lw-2%t*ffc zW(pk_bvynuF~qbqL`o@em?XqrKYCc3fq`*GY~zDwuUoM#FPuazIQSe`8Xe*o7Br|B z#Mz#SVg3;Jo|WN!Y83O1ds9+5c7%4kJ{!k);ojS$hwqzm_z7^l6utX7w&PQ3#P_w% zUqU$!>T=u@?O3+xe$#@u*K=e3vbt(JJYehx$KeFwny5>9_d_rr2FiV z-nU2kY>y4Z9viAXHZps>*4XW_N!Vl4w8v&;kIma2TTFXwx$Lpkw#U}T9@|`dZ2Ro7 z-M7c~Y)>4-o;a#KaWZ@2?DoVZ?1^jI6SuM_?rl#zrakdo_QY%36YpbBe6Bt5efGrf z+Y^7brvYM51J#}enLQ15dm0k{)u-vy5raGMA+tQMsLUY)S(I`U=J;-~)f( zzI|&FdF$z$|7XseVPIf*^XAR}|NmplZ@hc=?(EsKjEs!0-@bkP_W#qTPa#{GUc7km z;lqd5uU|iZ{`}?3mshS_dH?3^!-o$aKYnZ;c`Z6R`qQURX=!QZk+=T*|G#qOO54bz z|Ni|qkGf|DV7AXU&@B9JT4^ z|Np=K{r8AmXBl;IY47bj1ieBr`{Y15`H zSg_#QwQCOHJMF`-IfNYsU4nMu)!Vlp?%cU!AAS15{r|gn?{05zcaL6bZf@@C>iY2Q z|F{4Cn?~QV4L{`?HhcfY|Ns8~cM9LQ?eu^9sH^@_y(dqe?CtHHFk!;py?gUopNE8m zY}~lfK5A!7>9x~${@W+qt*orHi#+uD_kWN0z2;%(b|3vOAtCYV%YTcQhcDj#-*EK* zg)3jWy1G(}cieyeKP0;1<&XdN_V(9b{r3uAcJ=B1&Y3ry;*J`I-{@WPS6Nv(H#hgo zmoKm1zPAZE`~BBHi?G81adSOAJ(ukI?;d?Pt@hcX&3_M{`4Ao+ZeUVbX#} zi6w`#sxIfWeGZFn-gD~z+@;6Evv1VZ)rBYZJbwA#Bjf3`B`;z!mn0-4q?fGRyzlwD zx1V<(`Q)8>IluSMiSvIq?YvvrvgG;e|CjGQTeN1+gO^_ku3+r=*uo4x6D4vZ>&eL) z*2`khZ@znVr!#>2e9sA%LqBH3$u%OsKCCW zpVP{tVFP!sw&*69K@3?~Ewm6#bDFJ^oX z)d)~~)|$fX?|!iDf~HjK(@PyJqK_XsedS#;wHbOQ%95l;PSNiHnmoRS0xhDxO413; zZ#^#6$;=g-IGG_uA)sB^(cr$@KFt;vmrINau^pC>Gf^}zvN1n=%I5gjGIgP=$gH0i z%6MloIrK2UR0H39x4g7aOhuYOt#iwC$3%vNbhn8N7aVu)#^A>vwP+lc$<0gZh`* z6RN+at@(INru@vMopS9upH8Uon`J~YPh0cpl+N}yM%h(fPD>rU_JOxH-1&6U>ie6| z=N+1(4H!6>8GJ8*w>E_8`iPwH0c~yAW+WN3aL&O4fg&G*-hREF(9V0YAndHpx0@Nu z*KP|Ay0YQh?SkXF=9y9FbHCrMcy4>~Le=;G@VyP)OB%AI_Awq<*lPan$Kwg^dOx2` z3D5iabOvMv9g*N1kQn-6*ZS92Uuk_uFE(&6CkKXF7&PoTpLpgyA#eNiZgp0F_^WnCHc=I$?G!?noOJ6TM)BAI$Pqn zmC%P4lQj#a-kxy(`_Qnv`psg6``_J_*or1}gv2X;{c+62N~pH`OtP}P=gE({M_DGF zNmezVX}h!LsDfI=0VboBo_@0?RTX^@VVI-h<+Dzpq1|SwPOo_9VuRyJ%s(9&-87E| zo%=NXc(KqFzDZ2pZ-OSp%}Gfp;5?J|YE3BD#Z*SVhLaaBOqkhZImdYW%gth9PePB) zS;pmR>X$dmxH9*bvf4%u-y;ccnx6NhpB7r^9ktfJ?OONNb-lVf)Lt~I{^w|6 zVanj-^ia5c&rhAD=0T&wiH7LAzrO8Q?RiY~nn0KPlW&4dA04tLddJ#rZ4ylOXqVcy zn$0nzNxJev55qC*dow3&-*ffr8sR&EP2c2>$oB4VKB-J zGcwxvQWThFYZ5q^BV7fY4or**dCar#H_xEM!!xYFImH$V2ts;#MaWoU4&N!+(n z*Gb?~AQOWG6MM)6R)%HW6Rt4rRCr$C$QgIAO+jSgAo)H??pX1^y}`&+_O4& zwS`muZ%^~{$f{nG{QH{ZVG+gkZg*r-BKdx@w=*ylEaYx5VmT=0l)yt$Kg&RPdS4b z=Ol-FDi*hH?-yv*sM`C+)1FCS=Z&??uGhA!*gU!`Ay({I_vTI2eaW*sj~2JR@6ETB zS2_E6TlqfYob>e9Gafv5{W15u?*}{nf>u9+1`dYY1LFQO*~2WFc`hvAQ({QqwOMgU zBjJxRP*53s4c3TU&w zbCCH6>k-Qhj$PIn2bgVkF!Q@Pc1_|=l2N>INY}%V&o9JD#IwLsQzIumC_$MoT7t2% zvVcD)LRR|qjYAq5HSO+Oszt8uXj8bdpwr^XLZKRg(p{bjw^!wdOP3ZL(fIM>GwCy`D22b)gV1r~-2i@(YLIKbHQfzkTSL$T`)EpkB<+1%GS zGA|NqmHN`qQQ#B7Y-7>>U+IfM+qZQMg1c|9D*e0AZaXDW^`4+?gdG#MkkJo z2RJ73Iy{nKVPo(OU^+g5t6P96dqa+Q0B_R+rYJLJJp<;p4cs9G+%*aeDj)cM9N=Iv zW7+tDabp7i$qDQ>4;VuOSpCHd=5KG(xzWTKUa8j+XZWLX(f0y#7jB+Xj!&*-3=M^A zFYu^cC_KG^_2PCWrbJGL4~#sb+`R_%kJz}K5;%W0B&Z5-@3@d6ufTM&ovmj9*K`I> zy$wvOKd^>uV7+miIlF*u>v!JD1MJEdc#j7#9oSxHe1XMx0iV$a#+wX0vp2BzJYcF< zh?jDRlRLm^^np3zLaOjG&Z-6MXa0X@*EV35f55!vRLdafX_E0z7FOIG#=5&sflPkbz;b0#{i;&Bh13hXr_A zKkzy-@Y#J}TwlO(#evoJLu;}^n`s!^jqe;utX{_u@`V;25_osFa%!b^(|mHdx0;rfHP|YlU@Vsiw4eB0o+qJaMmUyRPW&2 z#K3LDz;N>dAAD5LRl97WS>(RH)lbr&`n;x4(=lfY}Eyv${)D<4x~6A;9k?f zRc65EyMaGVfp_|X`FAdGtqtHiBf#tXfN9Ol37bA}*f_MrdGg0kVE_Ak&Lzvau0NM- z^_cs6GqbNI(~b-5O&gYOZiwyJz|{6&#_0>Z$q$%zJm9`uz|Am$n`vU3yaIFY29CZ2 zc2x!Dj{+>y6H4|66uWg~F}z}|&TLuDz|&{I#QBRu?!oLu72KBp(>dY=csD&ANr~4Z8*Su>j5*v0)C4HTpHI{ zx)0R%9cM0_&|YU1zn_8g>2@ybiWU3X>suXI3Kf#)Iq+70NKKi*onpXseZ!0yv*yd* zTKQxv%U{ijn-v!ANZ_wE*i?IgYr_X-r3bue4y=U=Y^;*p%^SFmJ>b|np(yqL2G+R@ zHAxQqO5U5kJ>WcRz{2~0JMP+=bHCP1THZZfe5r(3v!7M-buasyt61z8bXhH6o;G3Y zI|B}eOtwq`rl|@X%a*NMVNlK#SpIPp^MjLIF#$}z7m}nVT(om$6e&Boxc zK~HU?+p0E(2^$_S*gnsImtT5g*>UE(2^(idu}OBPJSnYTcq=t#La|c;!~I{3Oy3wY z3|QC|cn(E!-%a3VkKD?Tz`d4%ZoW*-smA?LWYt#Le)^i+wU1gOoyP=I(8|zqfs! znz#4A+xAyK=Ic${Uaj3R_uF;GAES4!~Y9AKN#z+BM7ysv>d&0)nR0j@;>+?OWsSS0YSKEQwf7R$8{ ztaBSUR3GraJ-}A@f6obv53J?~mLz=J?Kbn!0q>K3)+e>^*s*Vz^7X*l7XmCIVqCT> z7^M!ZIWvt##ftf6!S1D3^B5A?r+r}FlfY)A)nLuB@6Rn3rG~6irc8}mEIU51hAm*6 zHH~HJ0oL$n4#xuSwmfd^;OeW@y$5E zrJ2t9Vh`)|4Xm3E#FQ6sr|jhEb70MMV69bPR^7m5ae-rE2e$7b+_Fui5=kA3)GfuvJ%raNz@B*DvH@xGO55!z5_In#KFPvf%|y_2g3ut zgHlXiUhY+9*taB%>9IBM^aYGl|8Lk~bb!_T6no$q&U%9c-d(Jl8@fbwcvA~H%MWlq zsXS|*z?$8VWVC@hGvEr7!>LWL_TN!pc4FY3;lMgIfOR25=8^>VbO)|Q2RPFYu+CNB zb!FJAJb`720*mScPN__8qXh2H1JhA-0W7>bn92-zOAfFf{l*s)u>IEtjxzzQ+IN#|81{KKFdR+icu~N7 zI+XSG17^Jjj$;RSTp7yV8*o23wXdg**Q$YSqXEz51lCXmuGb0dM$ed~wC>CjXx+e& zDsqf@$pUr(&55fLI8+}nuikJ#J%YC@VB)p^4(!zzE_N93ADA#dg@I#kz|2>tcxnwg zV+8mQ1hB<#XWL}Oc18S9Q|*-2w_ASa-l%E2@p!S5wpnvHu8@N8AMb;SJ^Q$yw=0p5)bTc4cair&Ds)qp$MfK6y0_k#l7 zn1C9)vl*!u*fSU&{+z%yVFBm13!qiYlDjw#o#pgZV6ivg=uP0eqrh=zdU0n3bIAto zi4ja282BF?;GBDa<4O9WuXnhfUT63az_&(#Z|(&a`2VDS z?BRHLzwF%whIw`w3=Av|3|kbKG8Qz)Pph1#6>EEp{n`Hn4l4%%dj)|uhu%Q7TY3xF z=XzBv3}D@Qf!#CX$%Y55n-ciqt(ct{YJN=TUBBVQwFzut3f$WnxaB`E+ZQCrFJS)v zgL&EmPNz85sS7xb3K*0YFfZn-IWN%YzwYR*59|-45>75>cK*P%_ravp4V+~R6P*_@ zs|u`}wt)FnKytVH_P1B#HrH)^C&2UDoGDGMS-Ixsx)yfV=8JgK7fz z>I>Wf7R<*UOwQiGId?&i^97#94ZM2~aBu8;eJGYQ@J90QNS6bCa|brbIB_$d@DC_pH_&;sNj5Pz_(H$-cca(i~?_n0Mp}R%*qPfeFA*X0{C1Qcw89xrN7@? zrNA{KkF|OO_mc}8A3fRo3NG{sFf9(qT&TbuCct}#fxkC_CthK?-ZADy3%*BBV1MSo zx9LCcfq>f6o@{a(*cLM|oY}zr!GZ6Z150KDm!8;3|J(Ovp54Fles_GoU3Hyv)Bmvd z@_uP@4jDY`425hAArBVRIHW((k3H>{!!RLd*EE*U0`8Im&cy|J74lp)0c(WIasth{ z7y@0UEQ{QHu60AuvL2nttvhziIQW`-m8rK==cCQ4{Bvzw-6}mEHS$P0^s_L0deG=T z)24DwjMUNOB@7HH3>+5@sJqC8gl${HxwVC*)4e~BNh7(HYpQNd5R(Ff>$Od0pK z%nE%Swl1tcXz#7iHxU~n_VyjMnwoQSamvblt~lPL7d9RdTCHM}@gb`GNXN>+={ggorapT<#hKB@ zYo+71{~<<9ZB+~gv$o{iU9$0Iq2e;Z%`Ka*oozaC;(D)uO-t3WmC+5pw{|j|-Lleg zI~#-4iv8zKRhM}2J3D({wVTz>ekI{)TxhnKPR-^okJlYN|5dy8Z^7sMzpJ#?vdmfI zz|8Mr;K(YTvcZvEzQw?aQ$6JZ3qu*hgYGk{R%xx;8^e5B<9v{kvMOW3;oeoZZ0>k9 zySrUbnC@=EkvL7#E8`Kr^|^#4obp}{E=pRbG|oG3U3W^=Q?+=d?&?`tvolwz1=j@W zimjE=I=%hSr_*---mHGVfAf#qpZ4lz3KcsTXr^rTHNW3t>}UCW$!0(6_h()=tlaj1 z@$8QWpAUHMba3H!Tk+q_*>~yJXQz&8O^!3>+Ox<*LXqF`pT&cA`B|0>z5GlMTctv^ zBF~#LGVvOpURb2aIAKMQ6|eb~bJef6TwY*RWViB`_GgbDEO+zIFx>UlKJ)*Hw83@# z<35}B8%YurM>9(ls^+(O3bGPT7^Jny*s&&+~+_iW2tTUxw!(6XxpSPd9Ny}?( z%#ufq?Y>-|s`80<1dmNlym7!qG_p?fl5@!Z(9(NhjEo7K-{#HYGVhSy_BAZ_s@KHu zSZ8bfsGl!3by@e#cAe~<;HX!*+M$0hzk}ZPR?D=R>C1Me&CcI8nc zoAC75m18?|x8HBG&fEEXnY13SyT$ITy@%R*-p^mzBeHJMqodh(@_EGk;by)}dYA`yBADX~uengQuVaH*HCm%TMZJd}|ZXA{oyV&9GvPf|A1XebN zk8Ng4T!czbIBSJn>x!D8nZIHBDoMM-q0hnv}@iTy20l=D3pc+Os& zH2uhvvtc)!Y#$ji)NWCd|N6pRhRJA>eaZoz_cK~Owq2UKz9m&B)zUkvEU60XOdB$;%Lu{U-)q; zOPK{{);MbKE?xyM9 ziMv9U9SU6LuW^7$j)BdlqER-Xfz5C3#miFR(_8QGGb~_WRawLk-r>lgCU}C2rGZ&uhZCd2Lk0=4Z;RWPCV6a?xN%VG zz}BRew_>8FBec4{uGwJnI;GY6PFR@O=HssK?r>aaWfytCYrRLCJt3k|%H`|y23r-| zlb+`eUE0>Q$#zZI`W?5A{rficplV*#)ozc+YS;I^Uptd2K_OJiqk(zx(nlg04$X2Q zhD_EOj2uxH+L}HYFxhTkU}JJ%Oqp{)^h7{YF7xRoJ&p)QuOE6mkqqqN4GXxV7?jz1 zE+mS4nLbbCg(LqjDK_qi1^W%Y=<*mRv~;pO$R$Rex(2c0_LdBKY=xr66CTM2Ut~NngP9{> zL$i*NBCG5-L!PY-3EFuQED8c8cuhFK!X)7FL2Uu+ zyjTZ6;YKE{D2C<5GY+vWlDg`jW65Ny;pWGEp;5xaf?-?f0qGEhS4nvLKy+V$l_rDa(jA%{U$Wv~N|m*9&Nv{g^!KL!60=Kz z4;C)v4q!g7mc+bO&q2+|p@VgW1K-ROnVK7V8?)TEikJ!fV6*Bv%97w9WXXD1-6@vA z-oct-_p?&Q8ry5a4@`vT3+&)}wD+)F#k3dmH~eCnaNw}qgDGsC5e`dw<-$%J+Q7TK zqr~t@!q<({EN?68yE6K1WSsGMiwJA`L+(d%S6xmxvT|!2<-5e|%(db6-4FK`3fN}!($OQ z7vGXa`O*!`#2xrfa2#OaY531$`9S0or$NJszXBDK$@>_NyD@R+{AOAp=5VvQ)Gg%x zhGHHU#^n_o-iq=zv}|~MkZIde2X3XnhNL|bZBO2=%~Eb`F-T|Nu;67DW{@klpR?eB z*n@BJ%X7-5mmFXenXq43dpAderF{nDx~|4T>7BBhwoL185&L2O?69WhgN4tM+r=9c z*&7;}ezY8n-p-Vx^Au2Ug15*u)UPBqFgt_`@cVj#b(YjrG9{u@MdTK5v)p zvU|SB?zJ|9jfCw*ZQCo#hm?E-X5Mm`6UD$Wp;;=UQDTBF&w}j+2O172sq=hTqy1y! z1Mc0y2OK13HE>>Fo%4#}7MG50#8zI3HUC9^Slsw@aHa6U*WISf9t~y(G=m=~etE38 z@z+7Eq@7GV%q1q-I4n`(63`aEv!AJhrQooVO7lTh3r6E+OM?Zwe2tq_R&O=9u~6@T zX4#5GVmB;GwQU4!Y=mNV8C-+vguK+hSy9x_|Di!G#zAOu+-{m@@PJ+5VBs; z3X{1iV{ozlcQfh9ZlGBYPAYad{7g|0tU{GMqz>WeO%TY z4GbbWy37*WJq|Q*792b1#h}Y!TA0w}`QR861Ea&D!<-C_E1H;UeU5WDG%*D*mMmci z$S`$~Qc{#MH#o8Ha92arVdum}hZ!CmVST~WaA)m;JBQgBS{a@ws#&zMe`vZit7%2k zfv%p0E1#NNuGs4ut?sJc)b&_V-o+s)aLs7aJJI+oszK%i!@3^p&q_AT6WW<3FkigHG{=hZot0^Lhly^1_ubD; z*&<3jJ65vq*vwuVFsF%O+MR{}br=*jIBA=#eOA*Tbz|X~H)~mcv@m=)BYUca^#r3t zQ*-tiMuCD>@wWz=9*0C~cY8cJu}Eue(_#j(0t<^98)ru~7`?XQa9DYQ+nUE^JGbqc z%sZwJ{~Qp|@vHDY%5i~7qk&mIm(hH~*#ir5<6Bh z9WeVSvTl{ld5fvR4N47bb9AldXco6L?K^agqo5(`aC6!UrQe^pJ=*lxi#Ffm5DXrc<^o|GaUvM2a`8T0=0}9JT1(8r!?%cVKj~jnKO&&7S~~x zgq{D{8SJ<-E=V1?(KD4vv!YpJ0@F`#lRDFeOC|g6D66YExU+Yxx@vNQNrRPZs+ruR zX4VNTp*+@}3mSW`Mk+8cnXh0>T^*=rq&?}5P34Z29zR%ACN#~@4N&YgNo5U|us9|W za6PcKG33rdi4|cINlpF5=CO0!1SVWvDa5W)(5!yrG+(RYJ8g!RCyIPG4wlq5dWJGe zoVX$NAwsjD*?dLg+}YR7RnJ$8-Z{9G%bTIW%z%mOf_8**;Dy;M_@1nN-(?-^VbXf` z0;dNjs>TDK4oVa-+%RJB?AXE)(DXlsLDR#v z=n=!Qzqhxn3O~e}pq$ez)6k&(A=y$pw0oD`GpG0paQ^J&e$HM+N%PO9=8VK4}d*S6N06)Clqq1~qO{*&4t{%a7jTT5*q^LznBtYM+V(iA{Fuy$#7gYqm4~>f&0YV#`Q(Jt-@AYpL<;MZ?k+uli7(?9uAD& zVk=kznD{m@oDXU=I}pPqa4lGY;Tenbf7S)&mI8}7b|i9#ZJ8Oh#j<0Ihnc&V-CdS| zhMlJvd1kQG&S6l_uvECAcX(4n=l%;VJV{qAb`xZC>WqXy1`26c~PMw=U!FAY%5c&7Qenbo63Zo}o^$7b1S z?a#E1cSdcw>b!^HMH0sZi*GsSHCLo*YDDlk#0A|^Nb&zG4)Jf;dgpk3qu1CIw|VTV?i%)MAuZLR}P*iST? z9bgdiV6?GdUEuUgKls_2dsz~z8fWifQt)78NWOYtOPX@TR&5K$C)*nISa&mZY?laN zeZOszG<6kk0E26=$^X4^TUi^}yjl#y-@SZ& zE^5)PW2_o%*Nj=W2WNfyxAF3(M$^4+_b2c9vF`=*nnmht+c_$j6huu`96}yW(c?5Y z`E1tez^kpoJ64*luyA>{)j#5iMuPv|paz2p=Y4lGrF?iMBcjXY@H9}==Nfl&kl7P) z^Hmb_KSrjnl2T_-tYTC-QIHbTpzXl)PEUhfVYysFdy$q#pLTPrC_ivcVr|t3F!;Tw!SjWt2m@<-41?sgy9^&* zKHy~#YiKm+*y3@TrSo-Sx_bVeC=;F!O$&uDdar5p;6C6`9xb6%A~%cWzeUDA)(P#C zqDo3<>j}JAoo&;qaiSq=&MqzoMwvHX)mI!^v5JxV_y&#@b_Nkn1|OI-7Btu&*~qe> zL3jeQ-T8do9qWr)OP5S4jbg8w{z;W{c9GbN=b9WjTo&;pY>E1tmSwc%2#61k`-&IP4zgcj+ z=DSqYqUV3!%+@vCrhB(}VM)%J8^4s+g;cHIAAElMqJv)PI#$P7trv3%#5p?Ep5j;j zZ&ATK$=&x|b%V&BMZ2~y;@S|rT~y;cGn2@S$Fg2Gl0}|189kXN^zYR6KWDc8`+lpY zSSL0(`R`3Dowlzl-1^qOd%km~kj52Jjb~Fo8Lz6HAJoA5p5ejy)r;GnzWlGWdb(+( z^HcT)#>syFZCN{*1Qxh(C@3-pbZq4cn=GZf%P_HRJ>SBvT90iyhj<(m95fbm3kakqh>3WJC@;Fy5h-6Z zM%wl|XW0USSkB|pu?^rG4&iI{hl8L>;Di$;I@^6bzPfqp6>%IMB`Q^o> z<-zOo{_Z+``LyV!d4Ht7efuzFrUc`o*16JBw%hzIKeBah)`&gSwLbsPTSVGuWumBIxzP!HF}<BFDp8o-B#PW^v6GiOmX9 z6-r&2dQ0v%==aTq@sySJ+O4;$wAbx?wM%>b-e148Hyq@$ z*4cPes#<5$Nv+*Fo6lPP*4c8=%UXBq)u?LSZ8x)a>u$eW^;>tx!!B#Rolj>~>+O2E zYPa6*x4VAp?fH1hT7U1?Th;pee!kkRzyI&A-}(m_xor#%vP#z&9OBg8V{n+)`j5d8 zL2nzwqoUC@hQ}nc_ZS|Rt^Q+pLb2P%=%niG8l(TGG*|C2I<33=kI@;!(>BIuO>fs2 zpR;_u$N0SM??1*D9Jy^xF1kwBnq2bK-fME%*ZQx?l|XM>)2pG;wWil1v-g@_kFEY| zdLyyh*6e2L>{_#1nXC7j-Ok_h0h|jofw?4_l?{ zEFN`g@3VN^YyHpS$wY5E%coPL>nxwm%-(1Dd~WqW%NGl~?W|rdon2@3YUS#ERli(Z}ah}biK`|liK@jKA*MzZ}a7%x4rGx ztI_qg-)?5_xBY&%`oHauhu!veKcCL7xBK;S^?tkGZ+HK<`}6U%z5V~cUvJmj|NHrR zzy1HezyI4aFl!uO6xz_hW~0C)yy5_>(S}C88U+?*jf0#)8=A!SD6ko?ILKSHp;_*a z0*AB4A;C!-TGVV5xq??565X_+Rj)>oCt2gLLuW}~7cyz+#r z(WZ%gH7Y8~nkPMjHcgtgM@7we}Z@o2KvkqiWEsc_vY4^NeFQYDSY+o=G*@Jo8+Qn#p3# zvzbAgXI8U_G-8p zue#VeAFrTbAn8YWgH=U7mSq%QCaQntq{aEpz_q zFwfn1z}N0z@Mgx+74_Py0)Mw%S#scQqLl9TwY|mqfIMm)E5TsjfWeF7!e0l+(A&Nk===7!#PB7#gmeR`|sDUUoT#~kdcu&d-g0B7uVCb z|IH)s78Vx9m0t&)C>?bqIXQXHo;@p8tk||~+w0e_fB*gy78cgn*!b@KJHx13r%s)^ zc=4i3^l~;fw&%~En?~KRh`cH&D0uz)^>ypk85$a1y?V8$r)SozSvPOq{QUXz`}gn9 zpFf|Ile2j7V(Z8g9UUDO5jXAZ?Dp;37a1A(;K2hO9i5{`k4~I8(cj(npP89y7jrH?KK{p#ACDeA($mxPj9OtCcJ|JlJ3s#a zw}`xO|Ni~y)2BN}Z~gY?|F6IQMMXtDJUpBuwi|?AH;lOX<@f)Rl9KA`YL|%Bc2QT1 z!Y+LL^WP!-SZizR%9SfE!me)IxUsFREif?9EbK7o_;m}5Z~y;4d-klauW!nfDGm{P zD=I21qAw{ZD17<%KO`h%;lhPao;>l4oM{_#@BR1xA3uI{h&X2!bwycO*&}*GeSQ6h z|NqU*%q$Y_@$&L6TefWe{P|unn{7h&ct=h0OW0)?ef8_tuhvmF9UUDn-~5`Inrd!t zK4;Dx_vj-Qao2sL7I?%To;-PSbab>?%>7lXR@uiK@0z?{Qd08mpZ`8SK5kKaOv3Ko zx^*kP@@VtCe?d{*AqCGuQ&t{3`_jtF$~N&)OiYYZ%UT&CN6w2XXSU>uuVY;OUuj4qmrhcxcUF}n=hexH}~KE-#72hxhvnQ zI?rS_zgxKe(UrUZ%P0MAocO>u{g7kq-1v$YmF>H0T2}Wj{Iz_?-`5}h2Sik77tKF( z;zxRVdhNt3hfm&r_vU|G=>;t$7VkQ^@A5yQj9UzP=uINpXk63@2NQ z2MU)LWHE?z6i!p(ZZx&K;+mDQ9)3yj!v*RBhZ?*d^c~p7JYPb@ScGY^Ts!};{dvY8m7aPrHvE6|CSXF^~KpSHEzmbzihz^Zf=$=Nz5~O zbH6c2GpJ0v!IUTA7|_pB`f);igs6){2S?ldbRS_*|sN+by@`iT0*}63se{?xI|jn^rm#WMsqBQ3|!2Rpf+KR zQLp8M1zu58jyaU*Zn-(Dh;f0VT=q}*3!9i485lP5zEucV%PKl6fSJv)^qE7p;1k9T z3;~ahaB)dGuHo*h3K3{n@oe?`eSf}ri?KgdQ;=lLerkS!sl)G!GK13&jsx6GORFz3 z*Ko8POzTc~vRay*k;g$tGSYg5L$c19*$)3CL}oj9YlSpyVCn1@*vWMF#Tv&OObVQA zLi!dul^#to4LtwEazS^E@QMiUd-?2$gIEmbO$J4V11(N#uO7TmWgC5D<0NKXB0~gI!%d@1?uObmrc0);GFw@7VS3N(dBS(B&%KhqbHmDX0`r{B zx&k2rGG8hlfbSadQ~SC2jGc(cyc&jP%cn9v^Tb*z zpV}TgE7o6}bx+_Pv*Ux?jBn&OY?#k#$@AyWm+SfUX;pil8O~g<%FVFpq@V{&M#uy? zhE*at8$CI*7+8)Lwq!6Vimx$PwDofipKYzg2{wa^E6-kitMDnAgK65+ZH0;~Nm~t1 zv}0)j$4}GiPZ{4x&zl`w&(I_tk*)tx|yBr$) z{uZcbpYANYWWeal_*`MG1qX{_(b2Y!^I?298E$bft(68JDZV%?>+lqInS=-9&Wp_%Q1qk^o)Le~)W&21G83R5EDL_~{Je>_xClh$z9wTYwQuc=Cl z_RmEQFRpU#n$V(Pmfcw3U^L%eFGW!0&|<0Zli<5XqIWtb#T{C}n8OdbYot=k?TSG| z@{^^IyGAzam`%812)%2>s*%wtiXC#-NX;^RHldDikteK%0WIdzlTPK#`aI`_PkQ39 znNyDxyo(XKxWwwY=lQBzn?oXYEVui9^8fidqfUF{32|@#cwT6d`m&%Qkwt!6=Y=+_ zFAD`!y$zJTE_OwIS!C`h5qhKZVqevl#R|MDJ>0!670=qVM8kKbSNN$*kR!!c`lNeZ zo^|UB^ z#S?f}M;!OMwrSSaH5tCEqpqL2wheToc<<_%=U&%$-TDgOkn`*7`UdER9I0;`z(r1%}qXS$Bww=T)CF>=f}kiA4w^75{4Tjyqa z&)RX-_QwBP-?laUbg<-pq@<{P= z1>xHDHImZzf8N44QhcM6euY~1W+p#_=+>vwXCxMw=>~6T+51cL2Ukl0Lq$M~`k9BT zf2p_DE1fvWw&fw;>>X2+Ef~dxnAV%*upPW+DB+Y)^GIsBU`n}8$In;YQukv{)|l}X zX}d3+!1(3p0j5bQ;;m<%81GxA&l!0@^_uhJ%Q6CFn#B%v-v^$)Pc1rin?P zfAp5`&)t6W6?a!35akGDP#4+dU{khb+3%&A{Wo(Mvn5|FbC(VF5P#xWptf~YuGMUr zH4zO*M8B>|_q}wM<&nGOmxNWEMHx}Qe_cPow{1ha@0%p)-#1S9ZQC^c?3*;}-#0Jx zZQIhS)tVW7d%@Lx+qP{#`!=uo_igvf%sY(gRPFSnmgU$F)j_Er0R-T0?Qp>+Z)!yU$kQVthx ztLGe=9G5<>nmt!%;Q?o^5WNXnGKZyRZ9T!kHHpvmgrh%|9pW19Ci~s1XY}bm47fv9Qe@M7{bIb zLE(fv!-lp?n`0E_J2WwbEO>u)zLSELfP-LH!EgNoP2ack{}fj{_^q+#jslZ_!!!Gj zohQNbH$*lt=4)BvTGQ5 zuV{EkcKHirrX+IY3vfvM(VJk-<0#57fk%7+*M0_uPzBIw(2@qMYZh=ZSky5EvM_w$ zWO&eUz<|SQ0rTbSEN>J9PA=e*G!S6e!DjV=RrW+7|3an%9~w?B;5{Y4GkY!d}I848+CUZ|JZUjFQQu7^5nYk4h0083K>w--CZ%`mo? z1_JCmSiKbl;uHiHh4Zx+u&pd-D`)3TR%egqV2GZith} z?JD3XOK*r?!Cx5B-ps(mpupo0Uc%tOJE4KiV@9Lrj$E|~jLilDt_G}GFBonsu=X)9 zY<1vXvVhfNc^k{Z()bBXhd#9bxKNhJz)-%Og-;6JHrwM_A>(A3he`D!>-K zg4IBrOKSo1fr1_ehB6Tbj^7*%FCK9CPUxM$QTCsK;ouIwmF5CpzIR3J1fw1g6aL37=MUFev0*XJD}PJ>p}^M87NeFj(4 zf}*GDGtP(2U|Ps|OMpj2Q()5rzAXa%mk&&45a8@gU^^wi<88pb_Q8Zl2@TAGO{w48 zr*7b~UD>{5L#woUDN7++{R`F%1p#jX{;Le7H#^v)ma|81m@O;bAJ9IvN?;Dt!OnFD zxET&KrzLc=?OTlMC1r+@~sP38;Oao!ef{a*%uWf#!ez zmzR36^QLT=bEblK?FA0W3(X7(ToV+yTYoIp=48ldV74$|d1p{&lC?~3<&sO=D$aDY zm32;L-pG390sFN`Mh^of%?)h(H{{g`aCPj+3tC=Ox}#@#d1Ui~_R|^y&JFBNE6UgX zT*I(^dCV`)iUqvs3}p-o6EY>smsEMU6#V;0lJIXe`(w{x*| zUMRe-C2;G16~`Sd0pD=eXwEs276Pv9J+a}r{GJnoIT#KGw9L7{BH6%O^?)IFBTMEE z)|yO#m9N&HDl0vGVcN0{bM6InoSfMn|6#fJhYfMc9gH*zJuvw ziFX12#IGC-57_Vh=D7ENb$62jgJ=L-#s!W#1^zP=c%y!_UtQMEy)bf90;^WSj3uXY zP78F)tz>@c4wFZ&k_eNel3AtYz=C^mNRVVn;zQn<2v`h zbk>v0IV%=0ZIj?COJL{MVPC=78NGw^-UE(|35*#Z*k)c>8JJ%4eRs}J?e5};{XZo+ zMH$$ZU*O&xz(-SKkYCQrNwHBNf4Pbf7&2X)tm_dQ}Qo|OeiM$Ut z9IM!HCVNl0=mxf<3>?8fcnd8!!UXDz80ItoPwaXbHibcfBVz$~=moJW7kEEA@G}*z zdZWYfazb9T!cL~Z`8L{fo@xj@I>5`q$Z_KpFT;n^3=@hE3(VePQ1bmi%P9lyq5_U( z8UmjSRxt@K)GOGO z*-5f3UtY2^VMlNP&!Y)#(K}e85_k=NEz3yQ7xbf)Wg~CshSvTEtbGm4TOAgh*4Ww| z&iU{`pM$l)L!FX@<&nV#td|@ZUthb)&dKmiYjMNQYe&QUZp;!8`CeFJD{#<)SG$Wj zwcvc)iR(f(%VM|R$&|^_M-|{64bXIpD^i8c9FF?PkYqXV+OnnPv1Tn_P{qo zAb5KbyW-WJoX(~TyUl)gh|3n$Pq_2<0w2Qy{z?sjlez+T7Vz(wP+oR`bJ>RO+bfvE zCNR!X5IEeh>t4go@{`9F%;LOsfcII$o;kA^7aFjts|)xxupM6Tkm19W6}MUJeF{(B zT`A4S(E5N^Qi0>!>HQ1`I9>YqZnB+c%gebsZ3*+oD%OMbe!Qg>A6P{+1ePygPGG2L zV4sn>uEE)W#l@>}xk6*`2ezoL&eQ<5`U#EuKa^ZbV9#h^yUxjQ^uyvs|37T94ri&~ zz$QPBG0BQ^>GYcY<+bA5izOG7N?u_3XDzT!TVR{Vt&YLKHeCcjpLB;7z33lx~ z58wS+{*FnIvss{Jq5)I00gHcn@rO!oldSSB0=#tr9aaj@gw4x?ua_5_zZH5R5S(84 zvQt3JypZX`tEd066U+pnvQ{j6Cm`V~pjq%MQTw=I#@^&nG54|Km;8!fN%pCwhXx*Izp1e>!4b zCmHc&@%1l@pBJ)P@w{SSIG?b-V-MHt1oqSqtR4#voZ0u8dEDK7byf{8Sud^(TTrB^{?Yn;O}d|e$cY-?_bspA zy{(DQld-xdddGadYWz+d3-`*`sWQ_3uVFLh$H{GK~=*`M2rOc(6`IxGIY zQvdhH{J*#M|Go47{@;85|2~lacf2K$L4dZ57&dZD?7Z?;07!@5@ju*>H zY~XkxB=U3rzyD7ebw9X)jubzjEW;+}G6Qy`_>Buf4H1H%BgF$ByYO0S6X3$fwX}YodS|o#?`OGqvJS0$&#NHs2TsB8w#AO+UoXF2<=jPhhv&lwn@ib*;ZuQ-f5$Md9BXS|(1@nRb z0gY}JpC0TAhJn6er-D4#41=OOco`l^tlZsvV@J~A<{1$jGOc$ubL@Z27p2nQ zQsBLU*+t;f1Vy&jk2ku@*RvR%nB`%xXiCeUWRFdaRUgt9Scx3sVeqPwa9t2|Ci}vP zj+TrIO44k%7+V@wiDWpnS8d>HklQuqfomIEPR2wA%P7W$T|!+(P0Z3lObhi4iwYG5 zPPTkfF#OLNrNY6^Z}iDuQNGnA$Wxtl6Y~NFhrn(7CfJ;?GS6APc46Qz5e_cZugndu zK7yed9Adk7J1g__ojAeTBIn{^z~GkY7|!66!od-586?o4!Jj42+!#^O5gEoPdg5$j zL#^Ke4!)wz&5dVrUWDqfbWIH^Jg&MurkLCMU~hh?Er+$23(J9a#{L7M4cX$ePWX4R zO%hv}-JE8vkDs=t%rm=l5=*w`7$Ng9w|6%0fwo4_b;6d1)Rx93pGN7fj_>Vqoyj z<8xGab11AsKZ9{wPsdv(OAU)95)~gkx16>+5w?i2q3O&<-!_|~lj_U=EMQ5S+}OK| z^-~uE_c{k7CV8eEd+u5tPiSadBf9C_nd8L_4_NpUHWy^J9tw+5bP_$pFQW4M&Fcj_ z=CUPxeqivxq``7l%UtEt&jdIMT9OzJFxd1jkz)wm>tyZQ5tFjOp5f5_^Y&+$G7f5= z5a2tI*u=Adnduv=*P^1|?~mL6S2#M$w(;~=q2{j!rkfjGG!*4HTw3^CnA11*DSGdo z!q0MJ0%x2G!;OP1PA1c~|8J4t485Z1z`RIVAfQ0OYDLk#x-ITZ@g)ts<{!8ou`Duf zbzwJnk;pPhXYY~2Tb9JiSnq!a{lMIZEWNXjwXxiE1<%Te~47l)Q|Jn&$0nN)o3vLe@n zqInD(82ULjM!76WZLwaHkX~AHdcgu-Htoed4qqycGgTBtW}HqkXtnf7vTF5U z@VMo?Vp@Z;KtmM!!bV=P0#1g8{~r}sJ9jXs7MzMm6A->RS;{G_c)~&!eg-co4n^Zn zstiv~u+<1~C_nMEJ=s&NyrPkbBkUNf{~bnd$u0BrZ_nH#$i^VbpuoU>q3vvQNs}Vm zhlh?l4h^zLR`JbHaQkX>Lb%akz2cNaM|JTHfsF#qf;BH##F8#-OWJm2seY@b=Nl%5 zKT9Sm3NCVVHR}*i&TL@IR-WJ>k#+oAMXR8Vw7f}rf?rF*@@(dXXB{3?3Y6w8NnmA| z>G6xXdB;^pv#Qz7Zk!jkJ>hlHw-a~~H)GcVJvo-7(CXQ_LSp7VU!Ja9>Fl8p&@zEl zhspDxv#$@Ub;KbtGbJg8h8~F|xg$;sD*wL`>R^v6U}8Sdz@{Xj#gH(0@tLrEg)1$~ z(v*$VTjnfFU|GPoxZ&mmSEhzYwuqKL9oueopD1HuD{x{+dmzu|v5XC zj*Cx?5xePOC9roZcmLO9rJ}!1(TBsX@4CKKiL>Z}=MzU2##=@X@(U}QcZljR%;Z&f z&TJ57>{4LoULpM3p|MlC<+I`j&W1XX#(9lXns#wzzU9$1T=U`QgLpa4hH9_02DejBzdDM!PhP+9VQWB0p`tbAf&1oM#=oQeHZ# zMKu3VJ8q;=vCP3t{mIL+g#K%pji~{PcSs!3VNmRlp8lPwr8@Dnw%7t=M)snn=8rc( zM~W|DOPDTo$DzS2gOPLFW=4rM38`L9y!?BDCP>93S{u!J5GAhkl#AOXkmbfERghRe~ z^D#y3ohsQNbnei`rj zq9CTi-oTyIFn5LCleH`b=EW0lH(EsW&*n+o81bv1Sytg3@7`bAA|xLCZy8C(>w$|Qrw68 zfFrNyla3{g&b>37cM5dJ33ZsQV7}eiAsAxYX2F~Ga>>!v%`zw0TMntdOgaoXQoNr* zU{S-G#vhF`l}8{)inpJXvx;DmDCrbi&|JBAmoMl@aaZd#OG0Cg?oBufI#QfRC%nZu zGUX`S=A&U-IwN~r6{a}8e8nH(a};r;_!kS4kYj0cIMYf-j}#w0Qe1e19x0xBEv*#! zNbzggN3Z1&f28=<>(xiE*Id0``}BI<*X#AHHyT85G^*ZcGQH94dZQ)uMr-Pgw$dBz ztv4<%nE1cr?XjSeE`AG@uD2)nFGNgmY3TcVqMtRg`^k+Kjx7^YkFWKx_;+XzTsrhUS2r3&uaiB#OtNEU)6Lnr z91~kRtQJIV<8{CB)1a}SQTWHq{=X5s7tE5)i0U?IXb$Rd$d=n<>b}#r<8XCH;3W$N zi-wh6i;t$>DSETiH)`gzol{QEz5Typ&l%U_*MCowW{7QD5Z!V>V%aC&OS$eW5wYzP zVi;!JJtf*#HM_q_Gqi>dcs zF1`0^>%G@U@4dNt@9ooj@4nu9&wBrZ=>3nX_dl85|Ll7IOX&TtsrSE?-v8cu|Hst( zKbPMBwe|k*qxb(@z5n;={eNHY|7U%`AohS!?E#b717^1eEMX5=(;l#uJz#Hpz%lIs z=YSq5ZbSN!;wdkC*SqNPxN>mdTu{isz;NcwnRoBry?OJ-B=Qy`Bjfw`?_a-uefI2G zCMKqrFJJ!u|NqpfQra@#DuOOO`x+`gGm8b({Rb4<4+qulMxyOiN3%x3^DCO`SM#;)xR{4j(?;*Vh*w9$s8r{OA9F^N8!_k@u!e zoA%@X|2=#5sH>|tG&Fqu4?356{rdI6!NCg`E_9Dtk(HHY9(DQ4pa13M5h($+S=MBB_%>aLP<$UH8nM^uC69gH@0rwT2N5%>({Rj|NlEg9{&0F zKN}mHv9YmH#Eo6Mc8QCNhlYk4Mcw=J=TB5rRAptQf`Wo!)GhnSQw9bG)=@{leEAX- zRpS)7)iUCgdE_n2s2d#}9sT|N-~Rsp@#9BRQbyntJ=3sD@$vCDp8x;x@4rjpS=4&Fn-40zyF+Lw)#hPO<4B-$+!Q{|NMXd z=512Zf$c~B?K=PO)|daGag8S~{wS&6wRrR2=?fkOC9blIzvY{9bn4RYu1S}3YL3@* zooJc+ziP_27jOT!Onq|Z^!db`x%&=3OsaqN;K^T~#4QU~UMy<4G=1H_((YIJt&jE{ z|G8w%gYbgO+xCAxbLLb)_MH{mKTe)=u%>O%p_7k0`ZmTVHDp(;E2vuj_U-HUA3mNt zcYev*_b=bQCAgq4Ly(!lnx~(~tD;3g(Av>rRm{mvj|>~FS=rK9( z2xlVCVJ>b@4iiR)zDuhk&=(ZWw-<8~_`$9i%22_!&h*wJ9am{4-Ih(WxA?2>YhZ?* z@ZIVpu)!nYPGbmLm7~P+2XhyP#;Dwz^W{YHxdqPMkOhUJ=|Vn7(j^)!ym-7=H!M+@ z(xc4!tZs*SVe?%scE<1<*6D?FSE+hgFdT4hezIb*_k2Il3EyVIXJqx96xx@IEmZ!0 z{cPl)1CM#n>d*N(Dd~6HVd+KY6*{U7+&4bIzJGrI{`w1z311Sa@)fz_>UhSs zWHAH3h)XjYYh{C=BG1Ky07apT8$8s4uPwdM&30C`fz8-r!O~>aD-#wtL@JedI&M{E zdE_`<(8PhCMYZB^HOt>tfthTf6CW@!BxpTZHmB^>%jL8ACOJ-LQFIXC=gM3$L6iM! zn1W+%$^V^89F_!KVVuR#p(r3bWz!Ue#Y|@vF4R~xI$cm>2#8wY(8i(C;t)C`=&*A$ z(}u=isoFyUqU5=b7gn>y2F%>R zeDJ~BT^h?lCw#M)E)izt6=HUtd~l9HNs-)_Mqd@-+X2zscXwazW8qaaa1stXvdUG< zrbR11w&b%oPF4w*mS?DJsaJNAy_c?FFaWUD+)BMDWU0NJxIj{TuZqN6;8?V?@CBpAE zGClb0FndNtkz+-T!$Agy6B{l~wF>N;FmJ{4Y0|1c?&<}+mR6MuWYLUJm~c~IZrubP znSY9he>42n`~T<5_4sQ7+_DAkMU!Pyu6|^h$-r_i zY+y2VLYn1~;;cx|*JfesrcF6lr@*t2!#zV#*z`;_^TX>(Y!_J>d(J8_8+kNvIUQiG zQ7Tb*c)}xO%S0BZC;5V%XPp1P5ZT*kQK;%;cLL91iHVOGx%xi#WcVzWy8c4`Loxp9eVa-y#@{_0I_>MO0{IV3hpwO>{ zk=c`lH|YXfveoCA7kbp3Jy`8Bqdw2N@#d-6=96dhsy@$tz_Z-qxaYYd@PfkSR@YCS zE8F#X?uVY`HsA$?pXdEJvmCOZ@Ym=047@8G*uB6D3ORgNIEkNvEGX<<;i3*%P$+SB zg`4>)Gs7pwD~qH|V;@+o3YvcE%Cc#$D_&T!$>=}3(&?}jvY^oF z7?aI1i|QwblglhbI>DFj*=wbR4_3>sG0TaiWsI`%~c^Tn8Gs zD*fvC)Y&)qZe8D@`ht<6dUJx>w~Z5WPbA4J-8d2TZIjSUo#!&$H_thRZGQQ1O}hK( z@C!yuHZAd8o9????&7L%Ta!|A6Joh<-};{vx~+HX+PvRg(Mv9tZ9kx!CA_7eQK06) z4tbAtMbl3=+)rXf}GCNweW zY=~n`3E%y$cRg#v1e51%u6v%?uCM!C*|6o@)xEDa$J8EPefQJ5?*~5GFx+EX7~B8g z#6GW;4vm674_Wkg9AtCUO;E96U=IIr_(jNu21y$R9u;>^jc<}&l^&cT{7aaHIUJcP zIwm+OC@{$A$_s-U7(1HfSvwn8cfHOq zm6i^v&)qy*`j5;(sadY9oQ(W34(SXN4ls&2G*m~%W;h={a6soq8Jot3IPMePic@}k zUTFN``J1Q*7g;*DB>&5KAw1{6g~y_wHZ&SYyQVI<#msnU;oWK`_Jr-s`~eQD7!z2+ zgh6LQBacRn0&o6T2L(HZ3~k5V>K{tj z-`O%udhGaAuYyOlAmL*(zY3GPe^r_BgT(39^Xv`szs1ayEoPIDdcYLO#4o~-D|le~ z(_-JogVNv1*&F66u

CCvW$rj^BmlUF&v-C$=4Z&)RWc&kNWb%P+JsFjok$PG{Ox7+dsQ;%-^q=j$~r8?%%- z>U2D0A1#-b5G&?&U@~XdG%HtLzdUw^yFlwPeTNMt924uf9FqAR8E%Fuauk+wHZuHE z7dUQ^J!`QR(?*UQ_D0@xMzxd-@f}T4Hv}{d7!-Ci+;pvFe^|*JpwFwW#MW5BtWd4{ zqiv~RrD1d8DK-Wl3kH?)a=r$i9n<64KQ=#OX4oah)DqFrvLgHc^hU1+23CP&$^Qiz z9vP*K9s*MuSU4syM7MR!nZjt+;GXTlRP!S}u|nY1*4C5ZC`|utT1VT8&Vn7?D-_!eB9e?0BaR1TTzJ;-^l4>dg}{dA49XK@Z4P8Kgn6+| zWQgAp`+jNcM2^hK91NTVg%-cx#mL2m(r$OSpG=XEL%;y4=_c{mwl#p^{4CW=Hd z3O!&FZ)jqDIN`A?qeBC;PynN5K?`SLsnUTsF?JT6f{AA3ZQ{&KMXU@zitV0c^syd{ zd-?x_&1(*ZkckZ1PuYU7n9fzwmmPa6^)#z9my#5vOlO(f`OBvM5B`T zLyg!4i75#M3)0(MJOrG@JHCgN3M?$qzK|l@(5ouhz}gV2av`PsMdsE+YD|S;tP=~g zB_?pEGxH_b7H^;YB#rUX4t-Zn2F8Mnc^=)q8Xe3VYJ(+b7HTj|5}zQa*vu=yRlm*n z<#fgj=4$2x{fa9XEIgV|N(gFCi2XQ`;qbIxQHchd<2`JK^tUOkn6>W^ghQ zpSPUh!?N67w(^^$0^J+>%6C+?l+2j2Al9{9K({kf`v7y6#>{J)QjeBPO=+L`vV4NW z0tSnX6CeLioyKIyc+0hI@3#haM+Tt{r5uiVS1kp&Eg9BvHpr?8n3dPhyxdaUEO)_? z;g;w;)`!y%YYKF;&AHXlRhCf@=_25&AYyo z;kg@UtJ-2#N6znQwtCMNux;b$eZH_rO62BG>D!jVlhg~|r7r$-vzS|xNw$IA%ONAV zqw4WgMnwnC<^?Rm|3BC~nTO>88GlZpQJpI zQS3p&fkuX9Qk{oZGDrw8cuZhmN@qU5xuD`hoREO@6os5OrVOi}S93jJ@>cA*6 zp}=g{(lug?vKJV|6IMmK7g_HrkvCY=6P1y|W!PS(;oz0L(sE(3)HXV(g@8FNhA z6?=XKgZPJOjL{AEGYURzoni6+*PJlRxOpDgt(xoXW(ylE&rxY(ZfaeAsAH1*tn^!~ z;t#*Y@gHax`PHmmzADc{K>k4C>oikt?G2&@8769$dF3lkv@qNV(_gfR!NOZ0`y}(9 z9ULkbR;vdv76ulqOK<1Du!+loY08IkJ#PUof!Xb1(|MLNOpt6m5Y_i7sevb2z{6nv zmNrJ;X$;e?1Rj<#&1cM-_IvZJ-NKIA!V5p_tk6o}cA8boyu`4X#Uo(ru8kZkwFSK{ z?2`PrE7UujD===+BZkPRC2PEQS8U*Dd?nBv5GONjOLN1n!(9Sala{ef+%o(29<7Nv zvyb))cL?myl=ZqWkLSkH=QD-n1t$F{&;R)U<(@~}Vi%;NJPfj{S8m}-kX^K?WWn)S z?`H`sPKdP-SY~l+-Q(H&V*>YaH!^5{uz5Fi@9&-at|`tjS7#DxU}Wf-VrjUFi-F~> z=GOe>`$g`E{#h-+Hm95`aPRep>06&|oO?}}m9v*A>Y!SWsQ4U#DFFsN}#TWWac)`jCTpg4>!G74u>!k1EWY||3Hj6KJ4?i|bebL?^;d%+&T zI)&rKHOJdS*vop3*W5W?_vd(n%!wwO6D@1vQxnU;OJ{$<$K7ncLMu?4_vq2oIW0NE>4jzo0*~7fRn9}>wE)G-v+@+Hs?R{Fw9`! zO&8$Ww}GuIfsL<`V`Br?kpmp zIR80^?KK0>5eNQ1ITv^sFEIIDSgUY}W9}u-#&bs-xfuf3BN{ljIIw;AZ@{^*f$Q@H zj;;?JT#P4K9-b(hb5ZIqM??e1mJeL(CvaWfBT&V|&~<@ZbuZhFhD!_+SZAIQnxrFe zXOF<#HJ6T^xx~a6TAFjdZvofU1}@$O+&>HWRwuB{{=+d_hoiKCcc}x{og9XC2QJ^Y z?ClM_OBgsK7&w{$vNSqs=A4{${~aII+&h_w}vT6=K~FT+~d+nes*Vlq4#c~>Co!PSH{QaXFZ z1EyYO3t(T`z`d@3H9UcT?gg$H0mmaIaNid=vpInG%>wowUe2l*zIzXNKRw{MxqxTG z{|`J{H}I`$;8@(iJ0XCJVZz-_0bGr-TuV3b-V5Nqz`*_L1K(-`uEhuL&8%f(uI1en zz`Je@&&>^7I~8t39=OcvczdhuZJv7%`0ia@z4ms#P8Q3@+uL#(mOS8iIDtKyf$#bP z_8ASVr5|{gPhgK{V3^#%mHvSHjstgJ!1b*QxZ@LeuQBkP%DKbvfcxA8uEhy#-fuZS zD+t)V<2_KoHhBYU_yf*)4E)zGaJ|{fwU>cmRs;W&0=5+ePtp^(uU+8S*}%HE_V$Lq z50cJ3NVI#Fp!cw%hLvFh8$-f{&u`e%8o2jHtsW1J0mzoY5OtS1|D0 zVR#f_z^#6dZ^i!t)@=(oj}%xOPvE z&3pQ!z@o?Q;=%%+cLF?%8(6=dxs@jOdXwMz=-y|=G7LvAp69OPD9U9!TEJGFz?;2* z>-`3vN(0U(27DapJfjfNx_lz%o;i+T8}4|4eN-cIzpS(or4`~jcmT0WV5+$Sg8nec$)+yz z1NcvFU|ZY3u`+-+e8Kr+3%J()U%(T_$Dp{M@5~3*brarR*~|4N;mO;A6N?hwS1a)R zm~f?U0{5y1+|>oFyC2+KckiTl+=meVXM%knvU#pCHJ->)IN5D;tB!&D$-FD)ZTZh_ zU{i=Y-WR|#^BvEY297KHST9fbRK>t>;{nH(53Jz~d?y=tjO*DL5?(I)z^nF->-q(b zjs&(F3)rtR@IP3`zG%VC@B)6%*au4uxE>a;ML*z5DY(QO|8;@=?FjpaVJ;WC9z2b! z=U8)qYl#7OWdYmn4_sRoaNWGXv1$Q(#{-T&g?ASmp5J|N^GY4-iw|6j1Rk+9u&x#0 zo_ye@)_UGqc`t8%;5+kxbK3##xf8fL8aP)wa6kXQf$c;C$0`M$=nd?bE^zJ);98S# zZ|4H;Xa$~>1?*`Bw}a(>efj@t@&02U75G>;d|l)bx&lM|Jvsq7H6OEf2HI>PsOLS52>GKa}XS#+Jc77k(JXdAM<2Mom_f7o;5IeYVbORZQDG*-B>Cd znx%P6G}54vMM!7Ef!4FO$0C&_a--jTiw-*CdTd|u<)f9WtID74OrKxRW|gt<>TG|l z736n|>Y>pY_I*O)|yrXOqP9Z+1KL-R2ALsah=tJ>k3h{mU+PhNN{23%1y5 zap`W+jk(y)6FA{8(Mq=Y_Bw75?t)yVpZd)^jR=j{G>v&)|rNm>3f?>OCLNqS#_`{ZUY~;vd+Q> zQ9Io2zFq9EXGuxyY2;aX!;62>3ASw+OF7&X+_kb4SjF5HwwJdYmbx3kY~*s0%l1X0 z=m||$C6`W4#$SqcX%ejJg^or(7EIzjCeD9~7PjX^OcKAV;B1hwkYiHfLBX{dtoj=j zBpp)}xn-*^vhgNNv3aC3;e1P)$x_R+_HF;qyH03WV(8h*IqB!Ym;}XEDTapDu&zVe zYTfcGNl!$B7#;||vq?Ldl;UG*b7;nr70tHp5$qlcPW%_6QvdupaM)c!fxBtP`4ql~ z>|s7>3!-*PhFn{^xx>vwJ95Gb*VRH2VI4~sUt!7gaJ34WG;KNKLuLmC-UEkqRxC_W zwLWdWl&Q0@%5@GyfV1CmPR{DIg)x^tu9VuN$+3RR6^2ranUV|*ocXB_1CF(D$?-Di zBnR~vnH^mm&bKhIH_ycS=1MQe@T^1Y?rAJmbOe*V$rdS*#s9Ts6a9KK{ku|^FNii3ce&gY zzDem@V5nkNw5xU0rD@l;lx7|Xk7>TV_t%xJCV#sEg(caNTPhAP@@>ee(wld#WQFn3%)sfluC(8DkNvmtRlQ8x)#YuaYf^2q9rn$-w*6S? zy3)Pbao=xU-_KUIq184gN&NPW<8Eb}rtZy2GrxWFd|TO;rM9_g>iSyjMysv!U^s2Yv;=4n*6!MuE4zP+WaA0AWz_5NvB5Tq_ zb7qkZjC@NRSy(s@unPFUJEJUfTmFX4W#$PCTyGp$6BQ1z91tp5`M`lqYlkBnm%)!i z`|mz4xNdbVKmPx;+w66(chvv9H2f#JiW$*Igt%Nv-g7{sJB{=MbmXgN^I*C6B4z|Hi$anDKK20@kuA8Z6H#LN0B zxlbI_X7X?0{lPUUyOFb_Ny>tugSo*-fbr1g?f053yP6NYnC-A}^?{8UySUC+@$Rwa zyR!FXw%zU74kwxq2*~Uc+Okh1#8Lj>K1GHd2a9*VU~W+Ma1iZaW_ZCY`=jw|aud^! zE=>o<)xr#B3z$2cn`Im9e_q}xc)*6~fITBe(?RYAMu$e0Da-~2jLrf(gg$Uh%4XIV zXt3aDk(|KASivOLu$#NZ?msV&ooUSB$Gf*J{d_<;#n~#v`I)ifOJ_%GnSX-!OXtGTxl$Y} zmV=<7( zv;E=H^KkH-VeWasQZ&LUAi`d5g6sLo=6|dif_WGOCs?0JZe)4Fvhs%&V9kC84F*jC3rPhACX2?p?nWku z1_pPxSrq$WGq3)`j~qvt4G4-NrYkOjQof zZ$2y#b2{~m^LCk&JEol8RdJN{1C!!`(|gW%2T$pmI>&{fz-8qGX2uzfECo&-j~QnF z;bL0BvT}ku1IMml7B9vh%q%Y&xGo%0H(*-%g5h_u3tNLv<7yV?E#_Pv4gx0*Z~b%X zzP5J{%gK%$>+Q2Ww)7mHm+gDq$J=tv*|Z}LoJXAhcg#8cK;+ye2`1J#dmr1JyB&Qp zf`?mM;mkp2C&miKhp!n#3(i#PSe}%zkaTERs>8T)4WrtP2H_bDOI;Wk0&F=Yc8E#r zIcV+AFoA(XfPvrRERT-c<~fJAyX;%1a=Pcs+22Rb-??-4-xSAdUk)V6oMQ>SFk73s z@iUiv%Y~c9E({STMLwKbUvN%s#$E#f3wDi$Tc5euHZb!tG#u~ona^^H`N2631qL<^ zMu#6=b`w~X5^Pr3Fz{wDp5L;)PJ}^zgICuVTZUXWz9qh!15W&jIs0Gd0>fQj!9C6_ zrWcq)FK8|eTAAU<{`PEDwCCdNbIch{3<(X=4f|O*eAaJhe$8|C{~MRUj_8XwUo*&9 zG+7(4*j->?Y+z9P(NNj5W8oJ2^#>RmKR0BQoX|-69*x4Gls+ z7#C0B5^vaHrqHm2B~Xqxq<4+4(^dcUB_S?TLmoT3{dGCL-sGT3NsxWXrKGLr?NY3~ zmtJE%Yo~KHWNtOX!_7?kTkR!09Hcx>ZBSq_vAr15dZ^O7LFzA;*o>>@48GzK4a^zL z3=Rzozi`E^J+BaZNwIZLnr*knRNvG;zN(^O_i}<#a<6dLhPAG});{;NSjz7II$O8t zPPKeKr_s*#gx&#$YUZ=z515OWx|hTn*V_wo0%aC7=`l1s z7H#nT(Y&66u~9f~<%7#Cb}mazk8KHwxmt2hZCygf+=R}O2ix~N;Ej8rGw%`i-8g=> z;(|AT=uz;>ksGq1vqtv@dCDVTG4G;(d&eP1VNM@7P(AA7fFTi)Qg zHUIA8ZOt)S=g#W$J$B(c^3vMhucJwV;p|oIL-HqrE#$6l*LZxQm)m6;_d(z8u9gSe z792>nJ(eB(B>3L$$6vaPcu%jl@aNkQthFK8zSNKRL*q7vi~Ot&d?&g!j)`czyS+raD~u){iFkEtKGz+XYXV^8AF`9FF6MDJTlve@$n zDGg>5(!K`U>oVNlwkYmE#`D6q^sK23CKs3tJ~YX2Fv}R|X3Fx^^*yg=d(j~FqA^VI zjp>W#X-=1HUbLpYXe)cs-uB{u$Fvun%U*PCd(nODMbEX2X0?olZ43q5UfjI>Vxrp1 zNoFr6ySkW3V)?9lP z{48su+v_c1ueYYXZdZG~$?wVLyw^LIz23DgdwpH@4z}c-`(E$+_If|tn_1_w_r6Qm z*LFZYH0uc8o1H@Ab|EaA&NtM>Mi zS#IUyH|O$h&AivBBw${s-NY;LcFr*ywhHs#)^G1z%l&`WFZXI)#GBg|^~?z+Vhp?& z7?*6xnRD#6l30Vx-M7!%-W_`8 zn%v|_Z+NG}VDvYTP2uvaBf0GS4A0i>=j8v$bN!>Nc+P@n1s$dZ2Ob~baIg{AXyEo} zR*GPJ#LK`L!6XpCsHeclrqIB0;62lVWWgD>*O?gwDi|e}zxmPEz{t?}U+D%T>w|ai zuH;vh*xs0Iduw)~-1N_u$Ft=Bf6UsNr?~zAQw2k#H52!Zg8{xD1x_?d3G8@m%b>;4 z$p7^u%Znz4z6KeIHfQk$HHD_7Uo2S|8tp6?6x7ZrJjko$j$^ZM5ENrzTk<(1{A>5U z57zwW#C#6eem}{ufT8g*LsUp;WpR^pev{mcFA8amEpCjA2~AEH8eG>fIomfRGPq9c zV{)l))~aZJ{IuE7z~$M$Lk2R=f_Bb76BsI2H<--`*ADo=B=OBNzd2f`fonk%iwx6}Iko~8_x?-% z__RcY$xL8}W`tL?>0#Cn4g4GS$J}w{=Knr{|9heO_la{d#YGrcPc%$T|2b8@;ihi` z&xT-U1xC#|do?%Qu3l=ZD#6%T%_u1U?b)_dOa>k+O`7;L7{n{ScndVna`h7OXi=EA zw?U^Vj)$Sy#Uo$*=UVpiN%}u0%*hm9@U2d{dein6wKv6#9W6iEm>E4<1Xh%@uW5)D zULll;)j^v_Hynz>D#K`?}>d z6TkmjUw@0S!u65fZ)Ss*g)U87)>l1BZE#=S$iKCydir)Jfd+YnU?z!gMim8Tv>P-9 zb|{<({cnczx^7LQi9a3hvEW#kL;?Gn0O6%h_tfu8ZS(-!^{ClktkC<@o`}YL!&qIk|h7c5wbTX_ooJ zU?z^B0@lEi&m36v`^G$gU18YpG!i)>94O4fOe|{%=;gR`47M6m7 zuL?h{zP-7%z4-mRy^5(9A03~ppa0M1*Oyn<#bpcFn;6(CohXMs-m zjuV%whMn-O-0R$$!W1rGdq6aFx$1@EjKy=dO^8ixTzG-uu%HS{xP*pEBNJDR!vWTq z-UR||5xpyv{!fps`l&iYeN%)o^n~wKFE966+HH9pvR_iAlcDfI!u2S&!U=~Z*d#lj z6tJ=$6jf*Ad?qd$87kl~l_@4Nl;KLJM*57Y;1j;ROrFhxp71RdHJjC)pYVN<>o)j=??0D%BP35uI2_}+CV(;X#RSo?+9L_;7E1q*Ik4*WHP?eO zkBhFdiuy@SS-)}exj&{i61Ag0pGyUu@V&Tg%5wMrsR;+UB#ZtSPs}_!J(q)DBf**F zrc;%;Q%Se2#lzOg9%Z+{Cw#wZb;-QVy?4$kSNZG5H!fuJ&9ituxB8sKquy>itCvgJ zzy5f>5_H1%?5-5>3E$N|E4G79_%4^Tdb{`czv^4tUfbDxJo^8%^#{-i-&+q!gHHG^ z@3i@RHM;)q%yZuRZNJ}L|HJCr!)|-K-dok66Tb6ZY=6Gp{l6~l*=q0!-^!eJe?TXE z2Y$N!-=5+8al3zl8yeVLI{!1RIKV2F-@sm@!18&z16$CBrd7oWEXFGizV^M)B=={* z4TBvA1t)DNmt|4p3g$2noVKA=PvkCVsK#N*q^?%|J&Js%#hj%+ZD>DxD4wrb z2br@O$Ls`(T;z>5cB*cAD6m-LXrSoF4o{mCLUUIf)ve3#iu<$Zkca_;<==GXi4&ap zjUKY{-8mi5^jJyeafF~o)5gBCo{19M#aLHQ)bUW6psc`b>8@~Z76!b1%>SwkO@^ z$P1P=5exR~ z)ZD?y{)T~tUsHuqY(q1b*@vbu-jj=Jy&IVG7BtEJ5iI_^=jHTQo#*F%`l7-mu)I~| zlabP%2dv+I-r!o}VC4LRVb-_C%WOs;nzyqgFh^E82>c4zsGu3bRIDJ$Yq!9AtAGMW z&zr9Q3_J%LIeV_IV)AHYQkf~b?t;S1>qj)>_Ab6W?^Ee=F%8BDwh&RC$_@tE9sGVv7iB(3YuS3R9TS#@Ud-DD{9Ls7m4b&X5IM+zyN>+YhlE5o=+N zu59M(`z$J@kYHynz##7+u*N0l5xeMY=eXwIhxZ9>-(ei+z_(-*%cNUxr&UbqbF?#H zW@KPuk=O9xs+%Y(D#77r{NfyBbXnMzC^IGNC2(+mIKayFh`~+n0ORs2 z2N-7soJ!Sd;Pt3vbQE}SP3lYn!@ik^gl)809~%AWY%$SmQTCa{XyC{oaDt)uZSji5 zN)I-C7xdxW^k1mujNt)JCWpodCI)rq2@SeGIGMvs1Q@poxG<$QI`DmPTEL*wsBP%M zAS5J^#1X*2xYd_|$!`OL9mhfkmWGWCzZ4iJi6sa&3pJ=nt$F(HP3WPxZI2oD{kk@P zr5dBP#Uc5=gm&qM2W-|W7?_kC*clBLGJjz-68tcmZTEprwzf|bqRSoJSPn31DjBFU zOBgWn&Pdf|nb5?uV}Vros#ZSk2Bs*EgsaRawDegWn3(&N+jS>fS;zh}TD9DQK~44n zW0AH;qn)6_k~5`@%4^>+<~c05wQ3oI;ExuDmH+{Zuk2Q=1+SU2yce(-Fo?t`3fva@ zz-Hy`qw9ZiLLXF@lRNi; z`}FatWsQfKW+nK|*gRL+Xu0Jb^A!#D22wndey3|MTw*jxP~GS5&?THE+$=FAfv36O ziO22Bh7j3>4_93*U~t&jz`EnVF=MbUizmCm+etGUI45Z|@^1)g4 zYBg)#u8Y6l{8;a|Q&TY;`-+28-U=1&QLtnv5^Ip*y3pvDnQ+i&<+r}en|>^{zUN%o zb>zwWFoDzZ4V+u&9w^B!XkocJjgiCPquM2=r@~w0HWn0EK8aiZuX9iBw|D9bSlJRj zFh5DSnbKy_FL^gpmAipC)qK-rM`1^u`Ogewc^ zed!i=qMaqfk?#bOM4NN_2qbeL4rcy2q~ zkxh9dShUEZj7Oqrk>#nmObXZdRG8LI^wEuL&}01Xw&X(6(L2&C4vpMr*cq1{m6v;v zDZ*eVcVN@p%c?pJ;xB^O?liR)wuaO+F-ZiAa3D}Z?Q$yBg?uc z?_D_8gkF*O!mzlsRnef4NkOt?<5~8CCg}t2Dsql2H9m}Q7RP^4UMj+1_~~GoTwyGzy9^=!P|J4NP*cT#&V=U9D(IXqAdb+R`^2Dr*#PvLraL?O_mH z;^6ykUjCDlMzv2lQyBPG#JE0jZB&?9Q;~2)$2Do^0p^qj?kRVTL{A*M8pggy>ebA- zp<-%bS*l5s&hd$=B@3NPR8vdQJC|gpmRff<*-b5N-r1C}|7z)%f-Te3GQ!TMm8oSK zolb32%hEcNF-s014wH&cCS=-cd!%k%%Q_FKYopVhs-|u|-Gqr-gb9vv?3cF6` zv#A$pohuMiFMf5kP))sL*4ZL6_0n0lirv)99-S!(Q!jTqmYb$taqL7{nR=z(vGO+c zs!hi$rm0ug9jRQVUNi4_)i(9otRvOO)a$yA*IZMt=L@R)_x#|S^m;xGmpkeWax2nW zSYC1}yT|Y`PMI95A!aJ5Q7Wa;6!*fQcVd%EUz5Y^nv{-&AdSi>jkakoGI$)MejJ$Q zAafaba5EPEWdZ02=rQtzCl(N{OQ+9KJgw1wLzPWnXz_mxi7YyV$##HIJCt$fVG z(C0H(FO-4**8|rOhKQKX*cmg@Bv}V9- zao}!dX7Rlh)6cE+Zdj=&%CJAfLBvATbV!ukZFfU+;IO3>a64v7@neZbsuA-rJYpUae28oiR<-KR5103RP7{aC;C|Ss$ zIA^NZvFp3G#qQqqdd{KjIh_ryu8qffkCreV;#J{boZz6C(#rm2-Zrt815OMVL|Ilp zZD6@^l>G=pm_?)G0Z(2Dr;}nV0uqxMPMkWrDfU=a&h%R=qf{97>oA;U-Gh~6gBAYO2kaaF`oA4aDM3h<=(^+pKEUyv5z_2E&-4@IG^g~PUB#B!K5l+;ULfu^FpyTLZIR0BE4rG4XiqjQaJ}w3teA3y<_t^C&T67 zdr@y?s@}V}jM*{`3oF*VS8`#BIUwO8=G@ow@saD|Ee;3LSlL>lnQk;{9%v7#aXspz z9}=k_p0fU1mgM)c_l?uKmUrfhD6nvcoM2*TlHq7n>1o*9bab^)ck!P0j7Qc7H8h4e zG)SCb)aY^Gys-FRlIvHsBVT{L|8Eq*!2O|Ks32Ctz{%w<(}g$wVl3yl4y+b)_#IX7 zN9X{rN2{pB!Jrrag#KUQEv>c zAJTVR&=|5KGvS5M{*CVh{au9?e-L^eDr{|7vui`UhZo-s_eKwgFc&8$mj(@4hpxgx z297tZk6Cx_JSg#>l`-HQ$Ks8g-``7_M@a8Bta2)B3|JZ9cPr?DwzNw_e3!JSK&*Um z>+iBc1$74Dj8?%6KBgOv|K=5PDj(rA-^6uWPvv}(=Z+1vDh(QuPJ39{m|YsfA{hBS z8dyFY(7)oKmU2`*d_ycl(I2)0@(HaHER5VC4s1U*T~I61mOr9>xTwI^NH=*o_w&vZ zjjrMxjU^ixq*v%WH#zXs{C73l{obg$kio@4tCV$LW22-V<9x-BO4^3zn>Xszf7WSt zv2r}%boMjHgV#(UhZgQ&5M97fBh$e5!GZC}I<^_ypWd~LxxA9eIv}q*o6AQuXa^&Q z%K>hO2DUv6^9^tDu9?eU!@BC9v0vq82laFh4~=IxTsh`6Fl~w8YddiJ#q8B5dW%1P z60P@1WM$xqIKX-5rID=YJc&)dOXvHf3;SL#DG(CA8k@BKWkgKXg2@xF)~b}o-Z>ul zlyy?ztfYls4{y8{KjYFD+pJLTOQFf7d3JtFoV?CW{pwKq&dBllmyNzhBl${P??imO zr@LDy^zr?e^TDyVOLNxwnqLbtxjLz_<$uNlA5+PlfyvAT4$fuY*Y&2kw`|-Md{-hn zvwWM4ty#w6Wf{x2Wo=i_-fot$uPo>A%bd$*Xc&jHcRhj9U-Q}Fi%4>GtuetpF*Uj&>r{g@{IB1D7vh!H5Z+WHp+PwHvdHvzo z^E|RAc^oGyS>$T{XgVLW@()AXe+KKYGrAsU-5pknRqSZt7HY{ukQb$I(0|q;;3eQ7oikZ;T;y?XEyd6FY4X=-{7zYi>^}x$CW1wAGkJMQQUI# zVZ540f)EGe8iueZ4Chs^Nl8UoE}ft7<*C5rd08>hNwzPdG_JYm9NM(<7>h!qOW#|G z`4Ur93OzeU%DiV5B~CaAZtC$utGm`1O4=vw6yiV^I;SS|ykrhI&~)P=i%kQMiet!4ca|rr+ySxz0S6i< zuXmPR=cp036Kt<4mwl+5 z?<~=kztxfB?pli|rj7$L84V#RVX6rSSeCdkxZKrkVc_*R%2V*4AwuVgq*gMcMFU#~ zgLsPu^AQGlhXYaK9Gndsjf+@i5*XO7FvyE^9g#@oxA9z~aD+R=v7v^QWyisejZ@=0 zZcAt^`Rl|WQ?q5Us6)`(a7#F8LiOh5m zPHBh~ZV+&2P;5AG!h~`6V|`~MMn?;VAdgwTTN^^o%*bLmc<|71;WG@Pn-4NLFtG3( ziJHR5q7dtJ!*IE*i`12dtMyI_47V9SFqX@TGQau5RMR9H(j?(?kLO7KHM;|IWDn?e zI5xd?SIPL)Hn(PmNA)S;a1Ra9A8|@ajR!+lwsOBY#k8e?C8dLf;Tq$Y{|yn2F|CY; zczPIk3=WhwUXnh=$@qaG+~bx>FGHA$u+>M$ueJ^x0uC%a2N^X!INUfckhAv?|60d6 z4!ju$c=j;7RAdzFI9R7L>BtF&aE^oQDh|Hy4j8B`{T|4vypVxIBZOs1LlCEf;GMH6 z%>N2_|J@PVGCO8bkamjb4>#^N?WJ2x8CiC*6)*)l-G97%Ye~bt_g3*2r~eC<=6V&r zuI2=TgN}efx>F+qE03HYLn3241An_t!siK(oH?0TrYxB8^1y6S76Ap0h6WdTMn5^F z4y6YSZOxo~eHR!WGBq3Olc%RfH5x_f$l{Qmm8 zWqX@1D!4MSigXArIOxa3B0P^nAbGPvBZJ@(nF^za8zwL_^{99pP;hV*WGcR)l5msJ zO^+oZNXOt&F)Nd7oooYxO5?$+8|HFkcod#!>~z;ptI2r0nTy5MS*YXSCAS7XCj&2z zOaaC=*-X6y%ZeHNPB2X4{dC|5yV{{c(GQPLx1V2E`}_OH+wZw%)Yt$2&&U&SfRR(@ z!U1N%C#$s=uy`~zvs-2y>^!f)klfU)^W#kWJ%Nq{(}`Xe9xzC_ee!AGaB*f>!sOE6 z&>)kr>Az0HHI@opvw0c93!0dmB-|K;g(iGF%#fFGLb0RAS*nYnWAG*#`qJ;AqgcfP%LJAd}6$rlPw>R!K7e9<@j?tZa9Z`#Z6=O%Rs z`Az6$ur`>aq9wX1GB)4gvEZ<8`USImGnM5B-0j= z#Ap$?F@Z%-j!%g(Z>`34h7H0BZF_(AEo?O_%5Y?33)5C$QrhyOQMIRT#v{ubevQTN z_pR(`ytcsbe9Y&wJ7ue0o_FMr{c_RMy}+?Y>z}U2X_rl!L5ym)T@Bu>C#E!bvAKD% z^d#8$CvN6I>}FNR)G5LZyfx2Q zn0zi5J3W%PbmT&-f%gFkv7%>PZ&8f&yA%3L! zzysda8V~dAFG4LU5BQ{BG_eR=V&UEJkSS2vfu)I|k@>^}MVSZ9_m+uF;(Xx3{ABh$ zEx}mAJnyTS9GK|@zb zLOAydCUKPqO^jz8ne8>yy7+{dYt=XmW20*!ynkdjHI&E{xI<2l>AFiNS|HRe(!j2@nR%k>szU#{6NBAO z8n|5!3Uw}WmJqto#4Ph*b1U~D0fQoj;5Q2xmVIpqTs9%H=YK^atGFe@WDO-IttsY# zQlihjQxdrD?Q7)HtGwdu^nlU4V-34B!{q|QIS==Wh3}O8_MzR8XWF_sLRzc}jZ7j8 zOAXfESmN>1fsM_f=_%_2W=#o({5VzVn=K8j@(nXZ>?X6_jZ|RXKX+rG+5{%{IR{Qm zUBbcVw}3%%RoIxp7Ti5f9ql8d4;{Ziyn!6|8abK&&S^W zIZr;nwm1qPv#;<@X!pP7CCdEUJJ^IZP9FPdNd zJfC1%yj(^4g>U%w3*B<1E7f1TaQNICGUZ*#+W%6og1`T|{@*z1;Yp8*%t=2(L{2_i zyMFKW*#GRmZ$I33=edXjQ`v%pvPUL#dfjkjihM7|9GAfS#b&9uj0V%s8}lkcciX<} zEw_o;l_V@$le9&^z(sJ~?aeYA3)n98onke(#B{X3?ovPGmoXLN!`mJ+&`=zIz$Js;6 z=?{Ye1N#T&i7OcR3t0XyKF28H#C+?RTHX@#ga?kVo*HR9VEm=W5b=P&i-BcHgI8W2 zdshN;$AQ30XISMPFvhepRy<(qN?ofyTIZSBs_F$owdalY8V zUy?BM+iP19L1r#zRy$=r9|oTPW!;}Yd{8{Hp4Uc=k13Ju(QD3#24UNc(tBA&Tn%N6 z{TPJ;Qdt)8lqsAOVB)$fpv=^06ZF8w&Vh9ur$9r4QV@gkEC((wWkWmWk4y?Y28-CL z9OC(!IOe=!SY*i1_ffH+fv?nIf=)Bj9S4Rx2SSft~G!y_M+t)GM=&#CPF^!CI>BOQjhZqFE=9N>Gm zN<*%}>Dl@!rUg7E3<6pSCKU|J1la?O_3#mC$5!IiGh_RK{&=k(Di}k zpCV3~$L4klyeSSJjDi^I4%BEdF|NNM=LZIki)7M1-*Cg*b*WDcY-F>shM@Z3oV z6g$L{X25VQh@tJlWH|xGunfi~2H#`P%pH^%Z+Wr5;AgROX8h8_DB{CY<|eqkgCQ!J z@xcRT77tewPP0Gn8E!2(bu5L^;lMAO&DNipO*W{~3d@p^=$s zQ@qB~oGrnwT+12c92loP;15~A64N4Zu9@-B1LK|sr4SY0H4VEG+$_&OW_owP)y|Q- zse$Fhu|G%j*(KC`8XV?ZG)V8=?EH|~=BTmD|Mp&+g^zullvFelY_>g9ycWdVx1c-j zC`U+}@R@c-j|MIw#T2*G_Oi~3VhIk$8yNUX*tnV$4V{indCN58fS6$tTa*J!p0lf6 zf}sn4ty~jJi!$fB;I zD2ORC_#`qmY-SKsbYNu&IGN{h&_ytG4fDQ~9J>aN|0@*u+ETe39)*Y}1Zg+1T+4RO z_6Xi8>c8t!@ZPTvWE@uWEM&53Fs}^$v%n#gRY73NagBl%3zQzPgq5x_(di)u<-OMI!HG}Y|B+P0**WhVa@u<;!bGTUtX&)8MGnLXsI@r?#n zmqq3h37`K3dDVPka7e6odCVjwnzlcMnPpMh)iv?GAq*Z5EdMWZU^Y=;HJHi}almzj zgR8^(jE&2BSr{_cmShTsYg&BGl>EM97gM|4VjhPBj2Z`+b~Lc*O=QzZ(&ca9d~|>} zkAcI*fsre5?;Qmjfko_2ZrlkDOdbjB>jb4&GpI;B;9yab%MHuxzi4Q5!1aX!#~F1d z8HLSk4z5}bLBbscyyk^7!wY9`D_l7J#;G&RdV!lYTDa~d>xw5ZA99#4aX^>!;WA~V$$4kM4frV=eQRRR8-W802ge@NnT% zIAE{4xR#Zn{PDD1U5^6fSs9HO_*QLa<8oy5_*%ibeGxrMQrBZFC4+Ox9Hz6o2j4%{$UbeQR?#e{`Ty?1v^c&q+Q%Q^P7 zh1-dB2^(&dA3AMk*J8)IbJEOf6AWiwNa`~eooQ9g#L1^sn!wh(F=-Ox%}IeXcg!=N z9BH|8RbFvq5_3@Hw8}o%y_P=aFfZvrL!Iod0vyS=Z?+D`&5+oU!re>_oj;J1gh3O3pc3Ic>|#IagWO?g{3^V{w_^5&mZc8>I)2gOtL4d!Xz-t;(%ku727lk>Wos*F7cwh2Al zZ1%CcxTkB1lW6!En-nBAqxj?-by>J^%C){R_;ZBNW%FnYMgcmr?n zp?Mujnrmin+k9R(ILT?h#ilJ$eVMcOZ{)AjOj^6Ma!2RvmFy4HiWzpV?P0Kc%kY9% zP)9kY;=1Z3uSp=_M@8)`@ z#jJDAKMsZPvyYEkFJQi=p)#S=b-aiMjs~A{5ZP_$+TjBxsMQbNnr7-mU;s|^H zO5qHrqFVML2UZz}C0$NTDGkhd3d~a$F~=xy$hfcxZC-uy))K7*&PfWKhszHrAK)-b zuz8`t9Q1&tj+raQ%QdEf+w1{{+6}`~yB&HR*lHM9ra6S(b6%p+!1PFGc_;&il@w!H z%~A&@jxWZX%MN6pJ%81>fwk!gPI z2ZeVEnXZHs@-fF(WfyIaASt`C)84 zHcMirJMrz!PI;oh>@tTzE+Zwzh1o2Y;RpvyPPZ!G0`?Ft+pZ+mU7e=72icAK8RkVW zb`%<)J#+2uZG)f%dqr85l@dd=?{J)GVSSgd_no=0(By53FBi8xHGapytmnimv&flG zEg*bxGHZh3DR7UY<- zY5J{ujPd#&g*GM*-uJ67u4H(8e*xE$D#ak?j-UgsQ4cu99&mCzd|d6oq~yrZ=E#%g z;KEU=QTB}Kl!Jnb6OX|>fhDn;S_jrdJ`!S582gd2^MPG#Icd@U2oXvU6sSVd%KGfyIcKb=8B< zvr9CZ+F3RPTHIj}duwnpWP!TV1LGnEAFaj7qMMXvG;HN~C??Qaf8NDPi1iQSqW%U} zyA?VD0t*?KSVT{82rxAI_Diwzy*MDq;Mm9@V_o%!!)VEgi7NlSXW4WbEj=|=CwkWt ziv)&-nI_q{_H-IAKR4H=`qv*$lNA>hx^zp~cA2cawA5#|RV|n4sw*pUr0`1fA8 z$Q!wEVv`eR$2ZxO6?+vL*kbQYaA0EPQ8->-BO}1*-lM9{$t}He!BOXok_QjHjm~)_ z_nO`7SnOpOcr>}+?jJ|W1SdYvl!@p@3Bus8>WQyjzVm?om=|bbd z@L8U2#~G*92skj6)QT%+rM77>hzKrdV_~wmqR_w>&eovF5>?V5m$i%Y15=HnZ()R@ zVVVmAf25_OLj>c7gR`>NJAS+%!=<}KP(zAC;7BUVlnHl)Ru~?4DAVu=cs6rd$ApP# zilPjyu8ayFA37==k+{b0%kklGCgXt#cbL3)9Gl3|Aami!3L~9@12Qx6LJsiG{?GN` za0Clif`SJZ)2T4VnK};cEFVI}894ZF9$cQqpUM!=$WtQVB-$=}fWci~W|?c`^xCh> zMW#RHC^*2x@AIL@TCKC-5SRX$g2R0FJcUP`bS=dM3mghAI2O#@#LV2@G+`=_%+FmH z_?X{19AG)X#c(QodFb=QiPjaT#F(5pF1T(t;rMWJ?th~PObSc^7Z0wUso*e) zMzH@E+HlBOHD=~P=bXi5k~P689{TRq`yJ;x$;2v{@Uq_TtA4lZdBuh!`~LIQd^p7K zU-L0oH#3RRA%~$&I?{2;L4i=V3yf0SR}LI%l&<`9(12Ye=o&M-?s5}Gk2@bOFsx1D zax0QEUZBdGR_l5#)rVukiMev31_yPScs>fU`7B`mF4VxaNUhByw3i_u!a@ASalx|+ z4}{MKo#52k)ZEw5s>}1Eg+XcJwkIndI9xyJ^Q6Rp@rn-vXQHF*f363O?G9{=C6Nat zYLdk^3n;L$D>^bLIV`u%coy)1)49QDQo~`14r|$iF`TyH#(gdi40IoKu=6cuaQt~J z*xutDi$xOWe~t?an1vIR+)qumcYK@Io0GFxx;lN2#i_!+k~NEE-@llmT6rQ=Hj+`C zYhmMI%SIp03U0+)N8PW4I5LDLbl+kTXzLT;t7UpI=eizq*OM4dc78zzAv?~dfHosb zrWN8I7McxOlUDnzn0UZ>%YlZC742E;6Bm?;1x@?A zI>GxPP=(VX@uI=z4u%^C7#$~ohWZ;1dmJ!7V8y_(=a|^G9}Jl+3I`LD7VIq$JHYg8 zVp7xGLOyp!WB#Io8Qd+xf$23KED{ZkjWP-|7O*sOohhAh za7W=Hk+m8J9&{Y<$@*WiSmx~t_lYew+gmR?OI92@c_xX2vBTF`=j{numJe-AB@cWO z5A<|u%xvU{>tYk#IZ4op^U4A{mQaO-2NFXzc-1N@u(Wp`*c0sKG<<^FjtYga*GSlYH5NqJ*Imqj;l&a3(pv83Kfx-Qds4F22CM+=l3gJ{RCNYx$rHDqqB`pqNUye-s#Nl9EBjoQ^wyi8Vq zvq?bH6D{+dCKAp(EL@X}IX!~@Kk7WN?1{P98n3HaRu6<<6?BHKE!yg9sF7beS(;hv zNWw0D3!jQthtHhIT~sH|Advaw0E^U?1fIqg?dWHxu3t~+VyF;h;1pnZkX5K&`Z80U zNh!c`=}F;@$$^c><^^ylW-Mfx;+g8!^1zPigJxC^YgEMR@G}kCWi1yEE4ag zsuBFzPr1(IJgN$cE_m?0X@P#=8yvCV%5HZFz6!v}<;W;h<$W-~#Mjiu;P%2Aof zumC~x4+)CWo(`;hm)Kg5ILy8}(I7IZRe)*31B1(7jaNQi;wJsN>Uz$Rjs5k!ZxXnx zZ`eyV@bNV;8L?hhR;=g{wh-!kvVoy%9`{^^9Px&fI+s)YmX7Whz^Q< zEyxz*#E|rWFEaJR1fC+6Rkjlh-2F6yHaUEq!BXJYaCWcY?5x`=>VJgh`V^{edgsF+ zLsr}-C*+L2vEL|d>Jb$+Je7&AQym0jk7yVrq|Jz$J2*^L+ca%}%9n4ODy?qzywT;8kkHstGojgV!d2z^M+diY7i^ZwnXG&;v3c*t zVD*U(S6QSu53FN2D|4Vtf!$Ida@%&l4^|V8vYtFx#=tcWZpC{V#Nz5M1t~!cF;ks{G#OxXP*NHS;UEsiIc#OJ^$Cct8HAYu}OE~^4-dm@M22L_=DOmY)~m<$-s z7#7GS*2Pb+OPS=R z9%9HbVs~j^7COK@r;s7zL0iZ3hRWlDe##6P35?U`*@KO z6F82kFiR@1h8XbF1~hFvCRiGw9`m7_|3Ev_1GY}%6z`6{mp24`HCo@k=zGu6Z!Rdz z_<*rTG~}}rYvn^hqXwqfuL3C&EIUIODvy;sEtlXgsAJqvP;-Rg; z6#un9$AMAaktJ4?y_TV&)F>rIP-bt5f(}D=UZ|imL#$+lP{CzEy$dY=Zg?gJFs%_| z(EOmX`h~P%a)RI#hQJG+mx~w@J_NHLV7&Bv!v7xvMF~a?Mq#Wgrt~b4Gt2lNERqo9 zc$J-b0&}}zWACPdK+nE=W)oj|O!Gd`_pxJI=E`Yq;=VlZcc1S6+_xAaGLD~6C-0p|J$r&Q1RUKP`_JLmsgIe(>T|Mi3a z8MG4^gAEuA6arN~GKwr<;8zHkcUZ<^OPSYUm+a?J$*v4S35;ADm|j;3%}`{NG+40w z;)1l}4EzgP6@O_xT;j$N!Qkf5D&b%uU)VS4W{~GsM*ajw6@dcZ?e^2ugATSz2`Vt| zEtIsGAd|Vlq+=3;TLPnqLLHx%&ee@fTn>!+NwUsmQXC45LKB>7l9-r2Fh_q8)LFp5 z#lZ4lS@74+Wrxe>|30}a_tmoEE7Me17AtKpezHh#oztw(I~VV}zQFQUiRaX8CB=nz zH`ym<1c$z=zAv`0{P=wgGGU*eWBfz#q)Ys75TX@ zpRut_+VFoxR04aSkl6IZ5T*dm?t{hU)0b`as>%MfZ0D-gyKfo%&0M{Imm70|fZqhB z|C>VUgV^308L&3Ua4%pIyues!#3;rP%DzFYnQP5Wu96+6R^NTK_Wmp7eXG_!)-vE= z&^oEeZeqaXbitMV155w5H8PG&B?SVV2JDj@Sc@1`brtHKyjpL6eC-3R4b0vf+!WXS z@7iGE#89>&Z%K(nBC~0Lh{0E7rl*RNe-txMnzcciJBl%SgFN>p#b{yn(;HP+3r#R* zeSL~0qf1LGk%9ANQTz*>Jn+AwRA?QUy1?M;r_Tkc5(*=2805v=$f zXrEfBk-J4eIn3K#`~Ox}=T_(Jt>N063>R*VKD{;e_11XqZHe03lD)U3W^YUH-j=y~ zTgGW-z71QGS22W0Y|qZ#CYG?hyn11Q_4bm}+iPEMujk&;sJ)~4_11{&9qqr@wyfUK zeR@al>m5m}w;L{GkX*2R;_n@XiHwpD7V<4%D6if*pL^Fr?OlD{JCC=18zTR`5d+$Z^9fA8M^bM^k;r~mK&`+EO>?gNZE2QL0*@G#_iy18`c_;W&`2S0|$hC4vOZe@XZlfmT*w|%t6^dA`)*7D(W0kext0ABP>vJ$SROc z<;)>nodZD(4CV|BEDwa$a)d1y80rm#yC(=|FfcejIOM2vTt05=D{otdSYmPmx=6PEx zJkdee#720IfpA=aNWKB9sUnN}aP$Y?x~$vcp<7y=j6;cyF(O?nO$V9G7_FVN5pM{a1hUbhD9;QXRSH4`pll=AB5!& z2qzl|dpHO$IB;rv&*>ej8LbW;VQ@I@`;pPak(t5Z%+8!M$M5W7+92HiM&zK6uyp~` z37xZ-b9Qh%5ZSOtc+;EHSI(Th`{wL@o^ua%&OP=y_cZ6+^PY1j)Y)F1IrsL>x%WKh zKkA(S>~sEW&iU^>=YOs_|NG4Ozi-a}=efYBdx6>a0&DIC_TCGeYcFu0y}At(ytk*S@`8&wHa$_eQhtjn>>7?Y%cT*WTzpd!zU5jeg#n6LoJ+ z_PseZ_vZB8n={wmoPGA@+_yL9^WIvhduy@pt);oQmiOLTx%SrTv$xj1y|teA_D0>? zn|*I@&Aq+7_x8@Uw|Aetz4z_y{k(S$>fSl*d*^8Go#VZCPOiOk`s|&vZ||Jvy?asj z?q%P*S99-P@4b6-?cLjF@7{fT_df5vhr0J3``&w+d+&Mgy_ak6y*_*I?c00rdGCMJ zz5m(w{@2|5-+S->Ts!Cf@3Z&+zPOFDxd*Yh+#J%r{=ej4}=bre!d*aXcG*Itp zu;0_ryrb?W)^=XrT~FJ8QO{P^*M2M;b>y0l@# z2FU$YfByVEfByWPJ9j>P`gHyJ_1(L7FJHd=>C>klKYl!R?AYtK?~J1FtX;eI*|TRi z@7%t1>y}C6-Ffroef{=r=FFKFE?ii-a^;B=C#FrC{_o$vz`(#K@BUx8a^>dDo3m!k z^7r>&vSi8qhY#-GzdvWr99CA=?Ck8TSFdt&bN~AP-`(B)z<~pX5qGR3_v`8DO`bgY z+O=yxfBw98@1CWl<+g3xPM$n@=+GhksJoy4gKnaViHWhbwcWdSuW{6khS~pndwXSM zWPbnty=>XCoSd8+H*T0m-u3nMwTn9X{qO&Zii#C0R&3n3(IV=idE^yEMMbyh<>pa$ z7B61h-`~G__38-|CKwtTnnm5JuCA`Dt7~j*baHYkDk{>@&@hX-Us6)?_wU~Y3l@C& z`#&r!Y|oxOR#7M0+uIGpuA4{RC@d`O=;-+M>(`DQJ3^x?w`|$s5Wf5K=g*rrZ{EIr zyLt4@?(Xiy#6$@RiMY5pr>I@2si|%eD~zJ=r=_KR`~TlM{J34@N&E1_A|fIoAtB$t ze}DhxtxfdRE2>XHK8ndg{M* z?5$hR{y%vC|K0EZIyySBBb^YI~*I(1q(+g^L^ez4O;@AJfhY!Dg z_j=yO|L5-ica7V0`}6{N_7Z-a>)`~r~W##4N0gJtkzVv!LX=McOr4y$%Yh7QTaJWm>d)u0u zn{_w4#I|mGaD1ET`a^TQx39aqyW;b!vk^-k-ELOY%(MMbo|n+p?EBAm&-RUvk55qc zo|p68Am+3`w|h#Bk*e!?HA`t0-2mgKmsbR@jypR`Q=VZyM_q`?hLcApa(QlMJ9weQ z@l2lXueOyO<{w)3O_#|(yJzR;=NA@pi{J3r;;fyoajS9Xv(&}24zvFI&#*awV%lGmrtj!O1ybd zo+r0+;>?K7$^hB)V<8IestuaY=agK#8P>FSu#H-EzrjmhikQ zX{+CEyL0Mi?Dhw3+V6JUuH$0Z_GH=Wce~zfd;MN&BtRhwdpeay|F^ z-HPYAUp1?g|9g4eZ(x6yVA&*|_v2xQ`nn&F4lX?>GL8 zSh)V*Z^`f*%ehxG9q8odxEep{H~-G_^=`MTySZOnpU73}q41Tvle>>~Kbz6Ko`y@#GWUT-f;Sahz5wllOt7PH>dCila3h%f)tvHo_ zU70fXy@HX_q(27)Ws6Sw?JCk=o}=isWzu98hm;BH&n%5J+vzgnfS{uHfu;T}o&rg7 zDuVm3EH%$wSnGrsM=ErZ&he94bUzQs5uJrkTbohio_UzR)Yt_o=P3VGJ@kS9xHRgmWt zHv2h@3|RrLL9B;3+;qOKdYgINqT(QTV?n9Hp9Sm;28@%J%wl9X#o?^2@F}FRg>iMk zQBV7Sg#v~mDni-4C*{~Kg>_s}5-Q}?@$F+|2-|aXowGtmEaQXr=@HBfOBon6@4XW6 z`NPC;*?@&XL;J?LQ%^)1L|;27X-_zo^@NMPauqK_LH}91Bb#PCU7em@Ep+Msvc^s6 z9;^whLN^Nyrl~dxc<3?+bcQ%Q*>qWBt>eBAtkYShZ*#O|%jAF59?g-$sL^^%m4ShS zVTF@|y1)s^DnSlLjt4ARJD9RqFLlRpq^!Ct>QT)2fYT@Ck!T?65m}Zb7G;J7`x{>9 zDK}L|HkFj`*O`&!xUXAOEJbzSf76cog|l~kV075UV!67UGl{23rg8ldh6b}Gh7%HF z9*OqsaH`nYz*-{UB6W-5fUdzq&hLCI+*}n$i{lv?bTXR7w@G+t*%(g9P6*q4sG!Zn zLq|Y~IbokjUy*a)!7d*0BgcX^w3r`IobX&Kl8f!2b_nAJ9?cWZa`y~Qm@`c1+7~tR zzdXZ%qe+YmJPZww_c82nX=D}RXXrR6RLFKfgFzsM-TUVS?vC zpePWrpoF7=?SMg)AV+3{rEIHgN9)1Hj{8*>qNf;+#W4o(AL3kcIB&0x9#2r$OQ9;w z^R8c94d+Y{jycG4{zkUlk7r3CZ>GxhMYrp-B=zpER5~$Lj$=CiA|8XwO$vwD4ygRw z_C~QJS)`8Ruzs5WKi`IAh5o)W6`P5#7fVE47dyHkP59DXH~u4%*RGYR*-Q*~Sk5Sz z&H8zj|3prPDODUxEw-03ZeVwqzv#+o28VWk!=A&89O3_AY{47RX8>XWEnyo_OoQ{49r&l)2Z$udN2aZqARW5{tXvUbi>{ ztNd}hFfV~5ftx$3O^>NCD14geT`B&l?2e?Loq*8y${kFSUn0D3-_Qwme#4^qwO*2k zp^#(A0|tphTUmt)V@i^RIuuqPXLY)^qq|X>LE)G-!$od?fn>>P5oTA{^5w5_58FIP z_e9;nHGNSlVin#oG#H2FT~C>yB)o0L*W2@}*h3Qzi6<58Ubaz?|5DhU%Pf`04>{lA zl4fRDI{Ac4v}9si2Ezfi$*DDu`#%bvkZuv0!g0iyD~XMDf+R!ax6O07g{m5T9<9x~ zk*^i-zHDx^JcCW2^?!y<>DQm$S2~i;aoAL+@zPnlsc)+p_I+sA7jQO+RS0y*J;E)- zoBUX5rx<%ALqM?j@?3XQfs|Cv9S3-qFho?FmNOjSIHoG_=tBC8WfjLtBj1X%`MC*v zGOt$&um4`o)UY6Nk-LD~^J3<}RAvr_tIKn{-8qxl8EVZ0dfm8}T!{F+HOxS~d|CqU z&hWzR<^r-EQ9&OX6)G|!%LQJmvaU{Ru5RPV+FsLrwY>V5of7LqD6`GT`=H#*S%8O+&2_`47McA-$TxH;AcI1kS=-i|#P~Olv z>qMtWTPagxajdJr6tk8iSJQG;*}f|9Gc@osZDh|h6Ub)enRbEq-SUL;R$g24QnPS@ zUkRL@UyE4}n){1#9K2e;|3Tl08<9FEqSqYYx;!i_T_NhH1Mlq3u~{Etw%!O+Z;0!;I(4GQR0T_czRTPR zmF(pU*ydeGW7-(UQpm1*Gp{!_^uB5zvtnpKXs94Z=nT$K&!ZfxKCto~<8YZal|fS= z!Lx@|Fz#b1lbgX*{f9GGGA4F)T8JHsXJDAA!_c*0g}}5(fiq7N{*}&dNei9mDd71u zA)KMRaltG@_Ws;dws3>cGpw^?G@3uBvIPDYU=^NL#Jq5}OylgmmVs(1eec<(dA815 zTq)32#{T*1yb#ej0d4{-N@vF}VB=F`@K2k|)L8SWbUxp+gm0Dtk35A77-qlj41BoR z@;B#9f3aB{7w2+^&D2OQVsPO6wsSt`!h|!X@heytX)a%=zI_3UAnSEa;a8Fi1ycDK z7L>8)T&YY63w1jMINg?5anAfbb;f4R z#kN~5-_Km6bW1?<`qH+vc`A&{?y=6=adU~NU>vL9;xMithF43ob_qmj34geuoU?t| z9^-art!3_yO5;({1-0!ubDNF2W z!AjP~m5!l&N|7tm92Z9x@;!gBGLUT*lj5qNi#%s1crWu>m3VR03MtW5UIH7vJl4Ki zwPV)mUAtEAxwU%Vuhj>n)y&^tBg2thYi+)I=mu(;1g?G16*`N7A>V;j;G+$L0h`i7foV+w#R>vXs@8>v zGWDkD{bXFroX92qP=jTn7N?{353b^8vG8SBZNKAI2HVY#wzoH6% z_FC6X8!tTFAo@{_D{-Bibojel0)GqzLnf(nI&M;pUfE=zpsCHS@13~of52voZozGe z8!V;6bBZ=I9TZ!bB*@6bu;Q|S-tEous_Q&AZs546#XNC~mvoR}z}B$rt+E^0ZaQw3 z3S1vNJ80g)Eoy~p*cdm(SBE}h5tLFA_|PTjT)pkH_{M_StJSTy8~xH^o4Bd$_G}hy zfjk9)m%FxS@7mO~dbNA>j*i(ox_0mAxxJ(B_l^nDJ11H1oD#irTJ_Euvvrg( zo%4S0TrgY5PkL9N+qQVctxHb(o}0C6iz{Pd z0y{n(7JJGiaYpd4_Yto>M||!a@%wWmK;~$W&C!sUqhU2iBQP$kN{Knfe3@Zw7L!`S zF|pQTEDMk2=me?B950DEE;o4tgTUUhJ;!T!3{$L+*RBaXD}Cbempxt+_j5WP;`zUj zqs!;S4C8|$2h{{V?q=V3h@s&)Gvk31(R=>g7MS(s#BOKRfZ4lQ1DUIM7;+T3-=E&f z{!l~FM&NrR)5}@1)0t0oHe0!J3qDCa%yRJrd!hWEH3CPy1=(^=?`J-I-ul4YJpxf1 z1jKe9=4;gLWH@|mj^+1iq3b;Y52MfSW!}J9s380Bv=BGLnll35Po14N`N%RRQPlvJ zn`;C-0cIU#b$*1)l)dU!KPw2Tg=dy=T;pTPBdvq6`zs+-Lb?`ocy8`Yq zBG1=cT4l_p`9D{n_=9G{9YKy>0p*WMN}mMul`iv6xy;OXZpEE-PP!IV1*d!x4|?ia z-~V+b$o6VT?A5T^s}XarM(w>CbN6c8->V6-*OF|nrNmxKtG$*n_gdE8YdLqX<^8>O zYnGPjT|o_=>zf`QDx2&5boTX{yVvV%1BGM-8~3mV-;RemWCtLPfos&8u$+(5d z@JRPvOLOTnhK+0;HaE+Q_ev#RV0dtr#qmnDt-!RkHwzBmTz1!H#oSw`H{UW;ytHPn z<>Ea8rLwnIId6RV>g+sThOMyzJh`_wUA}!F)=Je@;FXTRhTGc?%UV|S3T*HdIOHqP zw)ak(@qt6PH(lwq*($40pS|nme_4w%hFhFHckjnqU7O2#R!2bI_Bxm2p~W)$-o)N3 zc+BuA_Wrlp`#x#^B!>Rd%$z=K~pPJ^V2<3N5_Dd+>^&Bm0#*2e}nbvV6R4pr`-Qm*w3r=A+v8m=w?RHy%2lD{xO&(9l=l z9?v;@*(=P2o9uN3WNe?jWO^cX@X9QPn<|RyEd;GcfgIsvab0kwV4(=IbT{QcZ$;!WrOiC3ED89e3Q@X}T^bhUv0JORJG zFW!H$ar!6l_1B9G!F}SnFXcAB^nZBPF5uO&f0tM`K4WEMSzh-lvf>J*X&(sp1ODSI5 zaPRpUJ-q}yfx~tJJM#oW9p5s4+{d~5@=hZGU4vWcaRM3vr%!1Mgb7IB&=Z*KcjacC zVcR=_qw6-P1wOu|Eud2O{{JFw{yFbi0&j6N?h12w$ic{Z+V1U%x_wr9A4KkNZq9u# z`reFZ{>Q|_7vcL?tjwz|H(l9v(bP1&nEGo&FVi} z%>V4V`Dt3>Yb$&GM|;lL3clbGylcN-uXnwbRx^n-olM;*cMOX>}M-rs)C$Y99uO>E(d)%J!T=U$2o_$ifm zBj`7?Tm0|WkG}9TvMfu`o*XZ5``*20*#i6d|Gd2Popa&0<6j;#I6UJM+;RBcpL6?l zHvU)qBKq;C)J%HH|TW;tkgLZ82H$&Pu8}MMKb7#$0SwX zc`h@9o_bBwjosHG8T`y=mTB(2BQt}a`^~d;&9drHS>n>ASg&#BMexg@WxjLmTBSl? z!7i-QKB>dro!b%=(6O?AzMarhjh5s~Yjf}JYn2Xv7qhGM?Y*P3x2Htxt^NCtRVLy? z!l71PdAB(cACr#t%G$TdM1D#+HB~qM*qq4EY3JtJ*0ae*eaX1A)OWty+^DZv*Ve}F zZ_5ps_S<89|ez&_R71@i}_jf?Cf0ocDdMJC9kfojXypw z_IKI4yL+)*Sk*2c|F7oP*SGhN&yW9K_wVoD|Lg`1jO;2K9GLlC3>;a-@8k%x$+s9B zVs8%Q;614~$-tS{JZH_srY9dZC~V^Td{Bwc-^K9g0k48JYzzk?IGjb(muz%fGmD|& zQ0p6p2fT-5OfI@9wyPAaR8h!cG!$R#v}~hGSBuf98`l&%&8DtdbE0dWoYKmUz9a`; zAI;+`myH}nYdtDjV8+Ohwah)_(M44m?W|49jU6AoR?u=^6}&|Kw91wXhyHg6 ztX$pL6!~=ZglQoh$EL5!$XH-uyNIc^v13BvVz2b7&6k^Gt|Tp5EH$s z4+SmEFgMbU$lqVO_Dbt6(d?xW;-@w*S-i#Mgm?3-J7wzS?x(IT$PU%wimCmsn(I5^ zkLt@yQxuMRUYzHr`ZBJUAxy(_Qi;up$U6095!x;6USdnD%(*@)SX#VtQg17sbxpzc z5>tYIzlhz+CtdMvKi3CeR*hI_9`EFMdF7qAPU%fix+lZ!16NH|bB*#n#oPNR;>7bg z$!%7zR{a07wLrPU^;LxG0?}WK7tiLD+O~L>b=IZpCZ4yd6y{qeMP_Zk-`3;askO>! znbTm#8i$jvNsg&&_8aYT4Z`E zT)Um|!|YXpk!~`}GWFlRcylH^J$7aHqoc(O)>$4CQ`%SiCqm_TX;iiLRmGy2=cfpK zoA~ltzx%$W54f$u7xr>Kx}DJBW#99DW{c5^cN^W4vKO44%x+&ZSLND^pN(tUS5&S^ z{5416AiJGM=9D`9PS@U;pB{Jmu88liU$L6CLG(hnfQe5wZ|Liep9~4Mr)yP0xz}`l zy!FYBLF16?&ft#4B1!iDV{4CyN(Or@mvOWIKlMY!24xPZ8=;dJr!A?LPn_nluYK~j zUY9!6pGQt8d@^l%)2CpUb(_I6!%3;hyNdbZ1E*&S1`{+cD6dH|blT-M_$gL9;=5{3tUiC2ixAtOheoJzWRK#Sc3xo-II+J)CFfVk5s$D-lcpa@Q8V4?=~s4X@_d$5 z4OdIAplO$;EO$xO3f<`yw(Zi?^)0D7sg~YR*Dg)lek4_|bf^!*NxD_? z%d<@zg6FI0iKv;VPSdj;DLF>txHJLv&PZ)Ak(vY(RYob@7%a?Lof2SarDjIyLUq- zY1ge=_w3oTyu7^Iw?WghGiT2H`t{p|3l~Diw@e>OKa2LuG{+qcg$@-QbS=f8jdKYjXi{P=PI z_zgWhJyWMnh0M@ifBS#&w)atG52jC_9u^kn!h`j9K;qmp) ze@910$n>mxHq(floTEwo*zGceEAQW zwtev7e?&w?OiYYZ*bbwJ8$Qv~93$7+MP0RzI;Wzd;v99@+uOUNqhso_Kkxqica7N) z7*&7a-v9e={%<+<-zDa_XXLuNy1LHJPM3%!H=g}}`SZU~)ZMe!ey`hp!!q>n(|7+J zq7P1(d1~&u|D~NbUcLV88GB*-+5Zo|{tu0=sGRoWkDh**Q2R14 z@Alf=ACt;21}AN`h`V>@%*n0$@2}o?v$k!1WB1ON?_PVR-N>$7Ibq7$qUvQtOw2x* z*r(v!CF8ki$;rtY!K-30CuVPcWCTyl%6e@Y1jo1UJYady+& zNtJ6KoSf_2E$6%I%S{V8=c-*?Qo65N*7}~F=ev7b?z)ZnukW4Rz5V_D?&4^Xx=9r= zj}J`Njz3qkGpX@JzT1DRy*t0YzOgy`{<*!ozrTNQxc~pz*w{TkKfk!VI{y4V(8R2z zoL_A9`nhYKzC3>a{Qmv_pZ@%-{-A+HEaO2VhuVq~lYGoxKA9ZgrulSANLc36sS#-_pH2f$%qFyHKAVv;E%VvTjAbjI&C1#K^4aWy zW8jI|%;$3}o~?X7ujbp!=kpubv|cQLOw6jSdaXP9@WgD{ ztC!2uq?lLDJlvD@YUK(pPWM%7w!M0_dc(2*TG`F+EEccV?pRggx^B<6SFhJMtmAsK z;YgE84s>GH?DdZbG&7n@WOq@(74K5gLV`ea5c(A`!<-Nl5&AyC`3s{;>E+}yJ z$Sq4rpYVg#K$59*z8Q-XPos;of(rwKJev?dLrrrtlO`L(vv2`Jjw9^cEC)jWc1woE`rx^j|J+(P#Jm_mj90v-~K3)rtQK4@l|`N$zaal#ux z6>+AQbBtLou{3U2*tPAn%y)(h7G@tdDr{qxl$yEhSYv`x4MRYz<0B1$4ZJS>Oq#CG zIhfe17#>X2WNFZMdhY1(sG)zGN81LDh3pJ>9x42i;CRQfsLw^DXj0nZ2hVj*?zefx zD9<$0?Zvym2_-B-ISUj#>=-t%HeD%Fn0sQ0EaL+{hCPcUnJbSOvmN4XY++((30UH= zsME?x;j`pnmS;CwGEY9fx=3V=Nrzz><9~Zjfg{rFf>*7C51z{7I3m7EdWl2b!s9Lp zf-*N%PFQj}a@2FEh<|2Y;xKFDDxFio*_W9aY+0Gio7Ob(p3w1d;bb~hxM;J2m&Ia+ z(9Q|&`vMh~m1r=uEo`@+!pxxcrCD&gqd@<^B`kt1oj&%zbgCH?mP}Py>F`F}%1F;e zWY(UemVu5OnF#{<_A(v@Y%3<{Yw^oii+X(S`PHRjRGRJA`pU7-U7$9>Ks0FwTOi{B zEB95#Q&>O7NANE4Y>HXD{O0L71~rTg@yo6X9(-Uzt8{+|wM_f4z9v)|};IKF1!*X44KaAQ4C%y=Nakw>_y5D3jv{%?W102FF1LGyAqJ|Kz(bTwd6!83k%+*qI(VVU^HgqB!rHw#q!l1(##rJd&J!c=n`J zhdhQK4&@ga?m3jKVAJDXr_eiXHph!)J5&V%ZUq#tQfCyn_VeLdG0(ZHoEU5^emwor z(Cp15_{dy9N#J3F%M5w@#eqF%RT(dzQFy6p7|5-1gtuN`VWU&ijfokvStgtR?^N_) z>dQBgoYla;CGViP(V<3-bNp=@4nHL#1P-;9Zhz+LarXbVowKY16wXY@V^mtOU*Lm` zVo5H?$-~W`rY&A6%TQog!l+QBD)(g1w`8|t+)ga>`Bmy>Bv>+(*$HsEn4jcHwBmGn zP~z=&>ci|#%oAVVeWho7B%yW!V_U*3{^ac{cUX(!I4$HDlH5CPWC{LkHeeR+ z+;07(SMF2Sj6Ejr*!Ikh%M&=bf49O(YXzYszWp2j2e8O}aEMrLCvYQtuEI?76Hg8A z7bs0(_}1;uamw{x=|%6gOY~1VJX{<%f#byNr4@uW+Cfwt=Gh@AwgL}(E zQI`GxV^;L5zK)N#T-@>e=k2t%Z?g}oeXcm6`0VSyucuk1er(_W@B8`xi{C8%&mhsj zWYNG9(ZE*Gz%iqNYexgmjRw9S4FVF4LKcl85shLMjS@2&rFJwbev*<|5hwGx@#5n~ zrHaJ!flV4SnzVK_ec!~U^P|Z?qS?rz*(9RbtfJW>Lsn%*v(1fWyC2OC5-m;^EiMr) zT!ngWE6hA*v_x%g@%hmbAki9R(Haub8dlL7F{3qVM{CTD*0>+72@-8d7HugJZD|#4 z88h0lcC_W(Xv_Q2Rv^({^g=+dL%`aiy<$dt)sFU>6DI06+8ZP~nk+h6B0AbCIyxjo z%V%`--00~0Z_(lRqhpdq=ah)fX%(F_W^~Tl(K+Wv=e!@C3naQ0S#&Ll=vr3MwPHrs zsvTWxZgj2t(X~OMdy_@?mWb|c72P{#bnn{Hz2`=^z{U=N!1jF>Jx44=4n_2wn9*}; zN6(oXvd3@qT#)F!WYK#iqW7dw6W2y5c0>7VH+t{==zSp3_sF8}NkreXioO>!`d;nm zdvl}j-H*Nx68)bn`oBc7FnIf1Qmg1gfMj-3;D zZcgC)IYA&(;g-Zik;sW+D-~{3OqAL=QRe1EpToU!l9QAyCq4Su&Lya?GINsF&Ph5q zC+Yp1WFR@&$a1ntGPR-ak&ADP) z&Q9gLpVRD_rUeO3XInU}Xy$a2&-*mJ!E#1R(( zbH)V8nUgGMPKlg3t#am!nKNhYoH^&_%y~a&E|8q1sx)I!rLu73tQ9k7t=c&&)p6yF>~&%opbNpoO|!*+y|2L9$m1U_at)Ov&wldX3l%Hb6)pG zspTia^ldN*;A)~!W) zzZMxtEjEf06tr4wR<+n-)?%w&i*0T#w)?f%L28MU)e@JeC2mzqJZ3HN+O@>z))K#2 zjg!7CDHmKC6ty(WN=K$@Y1FQzF}Iew?Pv*kwKOS9CDCfx8K|qTH!(!8 z+=8vXhIjJcym@01c?+$R|MKO_|NsBPJNeI_KY#rA@rxHP9z1w(>C&Y~j~<;ncka%e zJLk`zU%!4m3kwUR55Ii*@(mj{JbU(R<;s<-SFeWjh?-o1Otk|kVRToWctm@{Y2mMvQv8yl}( zyLRv1y{M?DlP6CG1O#l`w(aN7pJtJFr%s*v>C>lu`}Ubc-u?Oi|BV|rmMvRm9(BL1 zt<5&-==JN@r%#{$pF4MM zPfw3y#GcQ8{`>p;$Hm2M-@ZLHHPt<0Rd#lEO-;?@$&-!3Z~XZC-`Uyu*RNl$G3%@& zFRa@4-!}Y!S=bGBc6J2?1qTO*UAuOLhK3qM-Tm|Le^phLW9)G&D=VYudmsP*cZ%Hk z{_Fo^$BxIu#Qgm8-`3W4?b@};$;ryf%J%m57NO@ipZM<>bKWBQx|^HZgLnUfqv|c9 z&VKm&-#=#hgE#-b{`>D9vDrBC!RO!q&)@y;9<%%VzyDfVS{ruUy7Bz~hadmX-T3Ae zzR)3J37s-0Oe;AH4kU5PKsg?^s#=j)?fi6BmE^#jHpuzxe*m z+cn$2ELwdvxB6h?od5a}cjB{VPni9rddlasr_begeoCr;wfE4g^;_;9IsN3;lmBN= zpKR{kaO2+hhQ4#Tm8)HnZ`ZUfnmX^m?8R3?v+o2IUap_~{N=m19nhG z+{ypXz@|axPJZ~~oJ=W`IB+NboQXG;I{6FQv|g=PG7Z$pU$*Misx{lRq`6oQ{(tpq z&6aCfuh;H)w(2#clMh*aEtdTT(#e0DX>>v53~2Q=wod+&Y1!}KoqXig*FT=Eeh*oF z&A_gMy!slWlMh;b&A!zIwEDUzXVr=(VQt~so=+!aUq3Q(Tr6P1&#+<67Y>GvAx}CT z<}++CIxXA3>4d|~6r~FnH16^=Tx6*EGeLV7!w0X+4(&SJ47TD&O1%B7S-v`ChUl7I z)aW!6Fc7M>E%kR5F*MtL+~&z?hY}5=2_|BiP3DeAIsQ-al4DYBoN(8k|4E0#HkG(p zck}tZ*d5h`TQ-TX2|8a;V-T6l`+#A>V{?Xv_aW z@Pb8^zu_C(#UN{j^8!y=9U62*Ivfp|1->~v&E{ngz3hI6$ElimL!Hw-4Hg^6(+c;$ z>ZDJI_`xK=ARDyuh(5(72JIpPO5Amd!dghNL&^ z>)B=={yign!Z+R&QKrI$tj60mmkFrI98~7`ptWK`Ob0*1Rf!Y7{^xKolqB@0vo|(7 zoO2P7u;VLZ_;Hj+dYQ`~#szJ>KOcT(IN;>Kk*{!1d7eYX#sf_fO10*X6&-sNoIOQY zq=R#2d=*f)(CcDmc&W_6*w5B*Pmo0-$>fB#jA46*4zJRN6USuEJ?Rdg5~#4H`|+V? zCj=5Xp0uBzkf@?CQBYYyH*JSNhp_6*japtQd2BbO#FMujIIenR0_(!q-*paOE+sbZ*T=MiRF)@a}-{`Sv8$5$r; z+QoE=m<}#;c+@Ch!Sq0$>E?aMIf)ZOca+Rw=xFm`T+rL-kSrx6*nE>^k?-Vx-I+5b zX6coA2`pX7r}%~Wz-NVx#tc6`D>O7Lb$F&QVJEL|+h>^*Gex*;4^$?JoiNcl&~qS6 zc|nkZBg+ACM~PEQB@asQeq74;b;YI9Wt*0Aih8iK8ilN3WL=Q;bgISnjtN$L`W5}& z&(De+v}o-3+5%Y5j@|yoHU<@7#`9PkdAKeb1>`dR5(z_*QU;hQEqkU-R5r^or@xeP7P5uls)b z{=Z+}_cQQqXkhnwz$E?S0Egd(Ch;>5*sOmX6zJQ~qVDsMEBePFiE|s;-UfB@R{uDx zz*o3rmGUE@**}hG_-*V8Kl4az_m87|ZDKv?K98kt|2SrGZew5ho9)Uro^RmWvVh(9g_HEJ3mtx2 z7KxvI;b#5o;)K2}OVoW|dPV=bG~?WsW#(sJ`c?nBynt`(3U}XEL9>5dS>d;JRruLg zVY`1_6-w&HjDoh2QpF*U!Ey+x`3QhraE5 zp8LM9y8Zj!k8|7ieV@D7;|9w#8vw0+b{>L%ve;+6G?|Gu`UwKhu-=`Vp_e@y1?&rDcf1eld z?|tF!|LfB1e_vMk?|l`1{@1nL|GsYM-}@%r|M#ui|Gw=I=X+j!{`bA#|GsbDzo+ut zxr(FfZz}q-*QHNd|L2)?ee&-5eP8CP{CSzJ_3PUCecx7o{ra~0f8gEiCwxEd_y6~4 z_WwUG-q)6{n*ZZWe= z-A~~CoqzuPdHwqJ`#=8|ZhL?8?f=V{FE`ElbKt-M25JDd{|*fW9y(I}CzceQ%(0q( zVMU48+NkvrD(a`-R_%YVp~6RR_W2iEs?O%^zW-rIjo-L?ydz9}zeDwIq z(`V0LynOZg&D(eHKYaZ3`ODXD-+%o46~p%1jpP3xP8p90aZQ@)IwCPAHY{{*dm!gE z$7AE7qumn5S$8Znlcwl8*_d%2+z6V!`rF}yIei6c+1Ab!USjaubIXd0iChZ2wxErL z5$sQGK5zQ6^6Kh{X4SK}nzsF{tOlY7ycAUqP3btjeLZ;oDvfzludx{i17F;k9WSoz zic?tsae+hOkzFC}wc#;SEW zulE(`oG;0}Z;|!1=KcQz3$Ubw8*9qwml95$K6Ccmc}Pl75mdWz?e?9!_wGNyof3Zk z`TOrb12dP5$A$$5n>mEFKq=vHyMQuMN;t7`F-jjt24yDmnSHKV@vA#OnbgnE-{%Bb zDImhYz@Wpxuz?|h1+s+$xm#Ebp9UZojdmcS{bmz_;yYOA+Q5Osh45m+?{_Wehn>TOn*s;UX($X;O zVo6B}A0MAp#L<9&fS>>WTZW&WFkynJsp*m>OAI1GCEUDu^8%t*ef$4^<;s;7QK#0e zTNe^pXCHU8q~U;rgTtc_|6OAC+D09=i@#wJbI&g32519wY^+Q2mH7DhFaQ64{P@u- z`t0h}t5Z``ColPT>Cz>~=)<`RZVK)_t z|Mu(uDXag#`~TlJdg8-3|ATWcc6WD&hld|KcI@Nl|4C)XQ;U|Jy!b7oIM0e*OC0NB=gQ_mLXIh#Eb&Sf{;*?s+gVfW9J z>Ic2^9yRtH?VPZqpy6zB=e4$}7uRpUdG6XP&!j{D{``OW>~nqlN`iw3853I$C~+`z z>hjCHA&M?esr;7im!o<9ZgXs4o|`_qQGivU(e=6RkrSa^ z69W!AY8fg8uY(VVP*)xq#*6qBr}&g9vt|x0D$sB(O0}?{N%@b&3#DIpNM)svK}cJT>Z} z-@%g?C$%z7HMr9vF0~}j`?H-&$A)mZE4LjagtkOF=|6G*0NTP`d|*c5$|hzx=@6kt zh8@zkUAtB)I4HeOGI`7GHTMM_mytpY`AVHSrfP-M}6IoM?L+|zA}Uh%qVqK z7gmvGzkTt5rjyn>21WO8VPAGS`N^edFmS%QvOV`CLjb!56Juhq4wGPVuc|ddj%Oi7+Ssz+7d=_$rXV@|GJW18* zS;&*_aagJ-C4_xq7jOBA!*ah2Y`Ims8U80M7f^lky4}NPkZE&~j=J?}+Kw|z^~z74j{Eg# z`T?G02JN0_lB7P*IN`I*X!^-BX;z4|tYa z9QQm|H0$%6MK6zAUO0KKjO&fqyPoAXKesej76nLsJF`@0!qxx%buZNBGqf&aos_z{ zLCRznv#D73zLbVLJ^CH&y(?UFH|q=jSx_l_c7@x2p@!H3-_UP69e$g6U7FOUYQg+r zo@cn!8AgYROAUHo2E}nLW)TcrhOveF$|9++D?EHx1x-J7Wtr92l>xn4Zp${bvY+r> z6_J|xYSXFE-hYe?qHk737t%+qS&wR`W3Wpp=E;0 zhgZU@IJ(xeE%bWH!lbubYMcMOpMEbc1qC!6C{S?II*~BdY5U=*vh)Vt*NzO_!e>vZ zbhDjwVal@-yA=0ri`8PTN1uuq&-0~ZtZ`kNawk04UH5ZV&uEh@J5j{A;Res+sakq59A)w`6Fonv z9Fgz)ST8U1@POXYt;bzY+%~%{B&I*@IKz#P72H9|lF~o54dl+uU6m?$psie~@`NG7 zzp^J8v2$E%bXA|F=u!b5L};#CcqwZ#BWw_%|C$MS5J5eddl_^Pf&GRQ zgM~BK2_}y4+fh0ze|W0ooqfGOg@Iwep2vp$M%j%&7G6Ig#%0CFDfwZ63|MISdUVQy3ZcM6?Sm%k46$ zdBF0Qje+%2K~ur(J4zn^6*w3<7#c$NFf!CkU=)0m!0CCWL81GGso;@E571na5~c@HTOo<_S@%vwX@VH ze5rGnG}7lYu2Fp2^8V0z^Z4^dDUU^3I~Wv<`YRf9>J&~0oOsM%#F?;}N${*#2cOS} zN|%H?G9e$9e`Hnqd98ZBl8A=Oe-oBZoD4G<#92PFGL$ehgas^Q+V9Yz-Q>twb8gXL zriIKO868^87#c(*A8_4UkomoVBX&aN<>wjp4#M9QxMLgyHb3Bg`hj)*_gb+P0+|Ag zA`M(i99XX~FvvP^&pgh4L4l<#fJ5^F_w8~P&*kL|4|ts>FoiB)KjXm4yfLFhLEu*c z<3uxog9-wQ2H7nI&C3-8{yyMmSisYq!1QWD*#R|y^n%8q83J$F7{b&AHWjeAZRfbT zp-@S^bTtD*$cO4^b%EasJYoeb3k{f!chtX`-pull!`gvs{{|k01{RhBOa>dW6R$J6 zM)<#DV9-loT4*5PJcH|vd23gMfP6tN)BlaUkv}-fE-;oUu!agS&9KOxY0h?)fw>`o zJAVW3wgp_F2l76J3G|gUZ!l=tJb~Xyfo+O7Q`&?Mrou{w1jh6UMW42nS_|+s8{~FN z^fZa{C%xeM^PN@4fH^~f--(@J#e@n512(-4rAsDMZc1Q!$;RNAp2H!?wW5G?2|L4` z1N_n9tV=ssk`x3I!Ud)=Fw9_Jur%N}Xwfg6z`=5Xiz$%b=|c0d2F?c^6(I{GE=9C4 zeQfajUUiL~;rO$R{bm8i7ufDc2<$Wy@L#}jRxFo=F`r4W|MQDlqYpW(8%vlN`O*ZK z7zzsgIT(&IFnm-OxO9SZYuJPv90ja}Ikp-C%>P^2rd?qB5Kwc=h?hZtsjFd<#L6-$ z&VIcM6T3R{jW=XV7Vt2Ovah~S!%)C?;{(_F1w7k6a6eP)xE(Qp!GM`Ty<%zlWaf>{ zlq3vPH!mY*q))UE}$te znc+i2Vr1hnHI|hX-3$kq1RJtK1KKjpTdWhfn;$T_WC~QCoZfYU&$3{~jRjo&3Ih2B zJPZXa{u5X~vGMFw7clUw<6ps+q$$vm&|JqbGd+`0O@K3zgF9NCQ_z4h=)f!n1s#uWEBIuk84KeOAQ^w$%%&TbDO&xxlq` z0`v2iolmCMFdZz?Y~VO7mN|1de`mx3h64Vp3pn}&+Ma#mdLdT3;AdZz<$^0=3^ytT zL<1OqD+o-i6xe@^{r&=7p;hxvTwv5WP?WNA0<&XHs~YRI3v(F+`m}yFGk;`T^MUK^ z$}-l6Oll_=?JcWd3-mvFfc^giUImVFj*YzMByvhE1@0*D9{pC#bdmkk0=6 zCw{R0n2;^GU;#^E(}xJ|)CHN-%>*(P1RhT44XesNmB6SMu*~HGqx=5^wuxey^;QDB z0*r+T>>CmUZd9<PC9rT7)8=n1iIVI|4cvVW{1+_*>b+Jj z=@Rf4V2{4u*Lo^D{Q#55gM6LsMVSkhu});=yx1plfx&(`tNr#e;Y7~XhTdoC0=*07 zvoDbrP7DZ734;S|gaamU&|p!vzLj28L%*0&NZg%Q+a&K6L<#WE77#HP@Z4T>i%600|A{FfG# z_g>GazKO|t!<}matknYVwFII*tY*8o$>?;}4UPQB1sjBCZwWXpcuSqR#e-4)!WQPn zt%19@zBb$v^LuN_vZe&)(yF&*%-)u@dt1)!ZF#@96-aL{iuO=8+g?^JU;cZW z&*bejx3||xi+uRJy~%nK!S^QaVm=HC`+{Yx9l=+a%c;KwG#2Pse^|X87SG zz~dCm)~G8nIccKN&hyDT=ZNiCVJx%Dcqi+_ove-VOolOQq6MtoQkg$81f}ijU&h3g zsPL~@urWa3Miay7r%pUghP$$}cD@!9c(98(km2ejo$QUFyHW-AOxiP*Z8!76RFRD_ zToYn?{wp#BC^4M|KbjIM#fzROi61_Ob**Mi-Cbn;N+y9j4USC&AX4y{FA}^=j4=Q zCu9m4Odp)=ie}(nu=k{?Ku8$F1?^LEZl@y61nw{0%l^QrP3W}mhuDakV{DDbHtD44 zU6r@95m>|^bXAFQs*RSzg}8t%F@7cjFRjm&Dn0>7D99xm0oB6P+jP3W~w^k>r;p$6TG&En@6 zqYeiMoSu4)BT$#sVHZ=N-razciI1xEsdWUStCAAudO zFXgdb=1gRmEFH;NXm-!&DoZ27nK?GBg~5Kh0{;#P6fI_PTyv!$RW>nJSo0cFqVBQt z9|VdH?_)_kkffWil!?JFP>aogi#R0|-V%FzTkY)~b8qk3dwb8_+x!0BJ|KJNknNo#v3HKu-Z?S%&Z)h3 z&fL9oPWNPLZz%K_^)fEmY6!4sT@MyqYs$f%9Qj zhS?7Vl_x0tQ$lv8RCfN+Wv$1KVALo!04usvofbmua7!c@p$P^-CNk0$F!G4=zyG}CUeA54kmW4Pz@Sic@F9D%q;|azx2L?)d!irm$Z40en)0y&=7P){ecrSr9cy~`@o|Ww>VKWX=6{$v zf*2mBzGl96QTL)|;yg{SODw?#hh#3?cyLZamjCmmC6P}9ZTS`)=3kJix%MFwgDHE1 zhJN8IZbOweW-ciK{mV=$lbs$0%zf(B?<=}YuX4hrr#1p54;f4tM3ej;avFZjZxUcm zu<)!Eh<8=je74iG{@eK_k;-95m>Z+h_V4BEwVE~Wp#GavY!@%FB`|PpP-M(MIhCJ* zvmxmZH+#z>h6VfIHrfAL68~#i{jU}Cf34d8Yt8*%>;C`RApd)l{qHUDzqi%@-ZB68 zuKmAjRDS6e{@gR)-*&HHt=!v#>jOjT{sgfy-l-M5I_bi`MSlcUbxvdp-jUY4lpnC6 zkwNbN!iNcSTrbc2`)-NKLZd%-Z-01X|CjBem~O0K%)Eb$tkMleGP()hc`yF?Apd{b zr&zIz-+t-`GAJ^Dw{Xkp{9t(4*vKPb*CG-4$fZkEH}1%cKmuF1wYg+YOjzL59j(S? zkQDqPV3BLDoa?NRmxwLgEf&0dhbveQFtUW~tz(rAdlRuK_3S*?*(hhqQ$| z{Qb>sEcfGdm=?T_JA~N6ZT)Yn#FdZmE!@w#Cop;loGf5rFk@gVfN$YG_u^;5|86;H z!5%e>)&vEQ4X`cT0k-^_D~cC?dIa6V{iS&mXOo)6kHw6yAX~U=VzfE3yGxp8KWLPA ze0M)+3-_OC8a!Fc=R>w|haY*rz|!i|1AE98ZsWy@TUg~=44gRCYgV;%dKqSjG~LnQ zXlfKu;NW<-gL#4OJh`R>Rw2!ljjrPHErN@f7#Kb-w6RmpIHsUC>!QLlHm*g-+IcQ` zo{;EwG4fP>7+tuqr|w9e$GVz5dW$rsA2IUQ-ClFN+YtY#63?W)@%9KBD!Y*0(@`P3j~$Fjh)W6zQm#{>`Pa9F?Pd2w-(+HNVIEnQbm z`)ydaXv(#S((6ahEWBLew7{Kz&j~>#<}j6m3#^Q8aw@$oaCT5vV_;xzu;O?WzQlpc zF2mqmn8S<67Ksl`kJd6MOpom~U)STp`APMKNux)?G`BzwE&fH@Z1!+GY4)&Kt0G!7 zDU7+N;1UZr0~g1HQy%$@){b#tLs-!B{CCPA? zVMZhaV~N^{#@-4Bh0ewZF(a`#4jLJ02Ni^*8^pGGiD&G7uja#K!N8!TB)U%TMCwE~ zy^iL_1NS@_jP&F(y0%rFky^yQ;N0|uD?c8yDc<2G+0ZPkDix)4P*JIP!FhGACyV8I z7m4lO?q{FTB5tyL@3)QH;@8MRyx>P7T zzH6F_rse7Pk&~3dt>R9+P#0A9IASNe%PIbn$5s}TM1|n$cyqHwEiHmaoVfx#4zf(( z2-xsHP-){1K}QxLW~ED)X6x~sF+XbQ#~k@yQ${J>>T2c;<{*`cuUpb>o?7}>UAsK* z`;m0JuRHzgzFnUGpC!YA)heJ#?8*Xm*9<4oT>))oR~GWOX1J(Y1$KeAaA&xg?h5QH zyRulGHPge@Dri#Ngg!$wQOGQe)h_v6WiQgDqdYFX7e(5=_)<`quQ&o0-uF!jZ*(3+2XS4PF6&7s-Gp# zlFG%5t0S(?TFopZG|lDZ)2OFiD_C7pvMAlaISRt-)*uwPIdM&+dB*lJSnkncI|B1@{f_BRn^1vsriI^K8kBq4Ya)0TSZ>` z<=HNmz#?&{)$i>VVFufj*|)izcChc*k`tzJ!AHGm$2GBXr(2EmTgmZe>lJ;Y+>+5r@1-0akc$}W?>wG86pyS0f zg-Hi*Jan*T__6Hze%)2s*4YxFDU~hOToW3m?_#~#&0^}zoT*az-})g(Y=g6%z&p<= z$rjB97D`98#lv?PH?2zbJtX2**rYeXvxCD-`Q@)yrQDBB_M{kkDM&de1?_n((Rgf* zxMeTj_qMq^_MTNf{News{uv4l-{e^K+q4{W#`?<&PHD#1Z`wArbfhvKXjFP1RHUAGJM+jN0jt|L zFZ_NP$kfNtz;Y$=qP(U9V~1jLmh7!dU9X-kHSJx&yruH;{A=g`WZXH%GhOBK0=Lpt zp?kB!w%@wCzO8gks%>`E^;_4rA1hr~x;H!S`>pHy*~&Jw+U6vQ-@b9&t!&fOy*X*- zw{Pw-y6q^`J>7_JN%XwhvTd=O9J6n$3V3BGF>F|yTV(z5O19)#hGhm>vwL>m+4k(4 zdj^MK`^>XJGobHXH8 z#pTbrMy5Lp?(tdh@^0Jyq4A4pQTp`9&O!xyPRyNA!20@iUit~M<_Qi)R?UAL_b@!) zR@rbiR+mGwsXy!ZcPyQ^k00F?$ul2QVvX}CJc9v^`7K& za13L2Vv2U^brzD?p=Wx;%~4+E=|bs_H;P8JO&fO1l)uREj;$!^GQ)w~ZyUP`%q15N270f%SY6ld7dFLqmcxlP1+mlwOL3^~5ukeYkJoN8B^2urQPo{=PCucA*=rGnS=6)e5 z_-0X~29r|fw7ieDO&qH45;!;|1e%jI85HLH73z?G(#iZ{_EUw9|KclbI}Vs>SO~Vg zU~E)a^~8Ylf`*}u!bG`+jgHkE&pKFNC{1L4!%_a*`O;7O&VUA~M!UnSoYlW9V-9Gr z$vD_$;ZVO&sPn__04@iH2aKPx=84WU>TziJynrLeo8gawFl)j(EzVBCMgy4#U2={M zfh>y3(mdOP#F|$)a3A5|k60fq)3M)U=e8L}pQPpdT3kwl#7=s!&kP@rCxEFj+-mZrB5Ad=dkViAfY$MkU>K2?(PmV z9}YuL7Y2qo7o0d)JItFTm^N8+tc`FhELtq_L7=h2?$U;iRg;~Y7bsaS@c6&sG{;+p zrh^v8n=R&9YB31bbmZ9ZMxWw%@R09NCX;1C!@eJO7c)DRZtO~o+1H-o`0%6~kBvv6 zm*ugS4xJAe1ssh#8csBGcK(!n9{$HAT9#nBU&W;HFaxBt^|<&tV`XUD%=%2gW` zCoFJzYs|6wfO2bw)8Rw2E+1GuM@4<^1HP3{Iu_2c>hy393Xy8Q;SpEjwOqvhmvzSu z9?pY|x^GtRYJQ>Lq@dR<-5Hl;xUA@C(*c2&2i{FD8n09~Y;-vtDa26{rPKMMcXP3K zi^dsKsm6IddxSbq@6ze$v+3y9;ZStp3_c@Xu+V)q3nz5@=w`CzZ!*nP*i^KygVBO}*o3@R_B0%{K#pH(GXqMh<49FoZ#^KN%Y9qMwE z>0zI+Q6j@d#x-c-i>@6aXZu$i(baC?+qJIE=aSaZ{!0>VM{+pXqL>8^aODU~YpuOx z_;&Hs7i|#{ivJxh1sbJZ?wK*m#VT-uKuhC+#acPRQCx1JA1_)zz1(=>vK?#4`X9kF zb~HHhUU7E4;u3nrHT8;H=@s|ZD;`s?crLx-we^bk(JMYzulPQ_;`jB6KkL;1(W`-~ zSA$Hi2D@Gj={(N4ejMx5FEnSUeIuiC47+%$4%xXa#@V*0u8rT zXjk9e{*57^+_odf=5)bSj=DXc!dqRf)gzjkJ=y|yoQ>CIYK%C?+ORNxYecHFs;qH` zvj78^ZAVKkM+0kvbc0`0!OC=vYmFKgCtcl^F4^#vrJ<+vhU{0Zri|=KCgTscC9!Uf8IzXxMrj#^tiHRQK_iNRBmBqin`XQm$ZG^aOVaLv z_qCZs-2g8WykQb~*Brbo>&Kt}=8@M8qCk7Z-oAZr9C72#`**gHC%^sqZys^!>%ad` z-~2a^xZx7D$|mx-QN%6dsB7ktcfbDs|Kacdw{PDXMcw`X|G#0>E$gT&cV7NC55G2X z)>*r#-CzIww}?3VeQKY#-TS1BX8J;AF_%%ZXbE{(YyZ^5x1No z_P9iEwT(LR?eBlHs5|f9zc-7z?+|mCfq~)qxBvE0$4;C%|KZbr_o&rhzWran{f=YQ z?n7rD{rUUv*Wdr2{{R2{_rF)v0{7_k?orD;qF4O?2ReMmD)RihckfKXFPKN2HVeOF z5q0Oqix&=2=gq@zn#bI=jXb?_=l?se{`*Hxy!Z9LO~iSph{NCi|Ns2!zg_g_$7AH2S0uKQ$VHpa%r9y;?Zsr;Z@>>khL z^Ai^TKYH`OUHB=x&<$7a{&$KxU>A2fBxeB!IS$Dqw{=anZ|8rNrt>1q0 z%8fVH(KikszEM=S;^^r|DTNch|M{O&wQTaNlZIx92^|H zY}qn>eSIq{D>XH>{{H@{Q>T`emTum>+0D(Zrlw~5_U(d#f(;D~H*VZmwQAL~XU}A1 zWse*=^7ZT2kf^#BpZ=Fk{AinSd(pQ4fjL*Kq8~JOAGC)kc7WRaB;VlX07x}E-widLn?bO`W z-(r2Ym1sXYyIX)2y!cnnXGei!q44#kcd}=wJU#}xRm5lKrqtete0KL<@HW`4tg@Qd za%)p@uq%&!T-@1RTVG$FX0N2TW9E|`Gs+UhO=>UbdvDwY-q-dc`YQKJoi(!Gw|#tm zVX^mozq=Y){k{_q?>SeslGY$`hCdZHL5eG3N+?%&WN|>0UutI^>t>WnBru`u+5APx7t-ew~FX9hEFM) zxUd<#ByDlQxuws;D~+F#e0YrzYa;UDHEgD76dhiJv9Aq!c+G19``XT6J-o(RTlm@^ zqn_f|}&^}F3gZy68h{5X*Pes9S{1_r?&-(J5D^Wa$GP#{}!AYj*j zwL7bXj_zIg;qX!;pO`#>aGBRaV(Du>21w+;`FPyx5yz(!Gvyj5oKRW5=98=1dLnKW zIr~aON9*mEZ7GZk4qXn(KAnFxBEGuxT8#Vd((4Jvze`K`R<{(~$cQ%kmXx_YH#^VNp%mF3=(kLOu0_Vo|h?NeY~fqAQl z`TIYgFSzUf{W8(h=kM3(sQ$m-?v%g(`~5+?{=XmKC222~^OtGAO1|QC{Oxi5|9|fN z3S$5JE=`5nu?8Sjf{E%s6e2fe4c(ql{8fNAj5u z?Pit^j{jR6rbJxf?(j(Il;6VGz|Qf6JM%#}FT;ZFsTPR}GdetY86Pk+{88vk@Hr{& z9x%a#p+UUm!3j>@Cbq^Ej!MyQ9*H0JINlfWp2tss=?~kZCJP-E242SpjwuZ-4T%qV z_&Sqi#cv8qIW#b`2|BYK*ud+~uz-alqS2w?0)L~AA`5fl6RF$_p1$i2a0xRkakvw3 zsEH$qmB)dBLBgO_V$laKi4#v9c6l%|#2nxWPjKK#VrbxuSSWuaWr-30qFK6pDhzoS zSRA<=-TW99NYyhqm~7d}&oIG|YmNhhG{XdL8Kwjw){`!L3=EA~4Mhs|0xS#y3g;Vh zf))4}9E=hT{<|`;@G#iQc!=5+c!}$MUcmS9zJmmtUoFQH928T{rl_Q;k3I}Ca9hB3xi1lBLgST5y@2*jSdbD z6HIP|EYB$QU~n?H)VQTvo>NkS;nvm=h8YP8wGtkhT?P}xBbXRAN^nTBDP3feQxRr5 z*(^UPae~r`5QR-Xt5X;YSXuU5?qRsW8pM9ddlgdxJG+IJQ{4r}#so12BL)U7h6C3Z zFgZxY`LH-1QJ5h1pTnhtfq{+T-i08Bge1PdOAe+;&b0CuW0=w?>tVMkU_v?9lXVO) z4mqxi5UAXmu+?>j+wnvYCdcjr8q5)k+gi)FHTxW73Sx86UtG}Td}ASBLPMLG z+=ZydB^!C&I~q6`E;JdR2>Q>!x1!LotVV#En-d0Y-;Qy$lmt)TT6EQ5FeRSad;4(8qzNaZ4g!R@!Hq*bGhq8;1k;R7~<1 zKd|#~FJb%g_p^KoH^XeM>yw-HnisaO$uRhLU?y|s(&+0m(;2QLDMa5mvWvxuC-jWT zm87YKbNtt)8eK~`?te|4LC;aZ;EOOrXGDv`E)Ir`Tt^s!9xySK-F>Z6=fb&NtwUs1 zVi3cHMRyohFqa4OGU&fqB+Srppo?`=+Qxt43?|FW`tq{{Ts|rAq}(uOc#++0H$PNi zg3tF|{CD5U8!y6Hnc{}Q2n5*;F3 zlX$senAp@BH2ppEUi2v&K4B?*!Do_iEL*`z;nxQihLl-Reik7Ll0Oa|VBGMG?_W5> zQnrQ$@w^A`xLS5^V|8Hq!qpJ{g6Tz(NQV}CP>F`LY{iGxFPCdOOGTAaVwgDJ%-Z{b zQJTepfm7aEl2@kXThSDj^$~3jpBle5cFf+aZ_%t}dhXrs{s7i92i|0IJN5droZ%EN zcju|Gh46-&6;D|vPOXt_;bk&p?lxfRUY@?vEP|!5f|Y}7 zuY$m?1(9ygSd_n}_dvw-kY_VTU;t0BK;$QPfjkBV z)r5xm>9SQo*Fa@aZUn z4+jHF0<&2IGm8TQYXHLs7Xd#8c3l%z3j?;S3V~z?F9rc8BgGukjm2z^?G_d$!ORRM z4IcIqEe;-n^3S~0zc>m0Xy-Y=pt+=#yRDeUC@(8aQ_({WPO0uLQFW(MZ~4yHmzo)1o;83B$O0z1F7Zt@V&b!it5;F-0; zi%FoH;Q(V%Lom}pMlpwuPBw;4H3p_DU1E*D1;lRhTLc8&%HMgxYc7QGA#>`!la$sAy0dB_-<7Vw6HLC&C?RiK5%q37t6 zX5LCCmFfMQSD39bnhOpv=p0}Q6q_vev7NcIONp_C>3_n+=Vg=3Bn9W5FlO(Z6p!-x4{fS4t!GAXwes<<(`nXU*%WiMvqF=>}G-d@q<($XhuxP^0MVBU9D$f$w@448h z%I@w50j*h!Uwxj-tte-gWs@d2@A66k_bkEP#!IFsn>$$vC>9Ey_gv&tW%JK-Df7j} zp|>oRel7a=KsaL8(nFW$B}v(*{92T1WuG`}*}~1sOkW9n<6M$swY(&1d0EwR-d{^9 zb}g@YrB!und4tr7CaV=KQ7hW2R&>l-(Y0$u&;MI1`hKmLAhmLm)ygSRE2mYhoH1+V ztX(VT+*&#B*UAM_tE@jRUlg@!S=Fi)vsSIzwQ7x&eg3D}D!Ud7G%jW>oXg(0cuAJP zCkMl|QHHTr0`r9hzbxPrU$~Te%n7v7B_a>d&oAiEfGLYVEWWCuWdb8R8>dh9jH(TxA zY;$|F-S5o~uPcS6x41-aajV|q(JkaWd&~PxTYR*2xBS}T{&{0i^wzNItr4@gM(y4j zb9?LJqGfT?+mfue-JUcjrFxrq^!kk5pe1Qlo0i>U++g-v$t361}{nb zy}dzt2Yg8y`mG|}^R8NMGI_XV@@=&{ojXHTi#(88I`g%PMbKQORde+dH&`|9T&S(i zyn9#IrFBLJH?myZb(c|4^7XEUOFOL>?%v_8wkmq@TJmB>@;eJ^J3d$oJt zo7?-|{oeOMdjBWu{a>Q@f2-dAWA^@EyZ8UOz5n0u{R}b(m~0NP#2jGzBebCUz>K1O zTz3w1J=@DCbI?d+tI!*rwCIEWLY5MHbdT>oXwbAyJ8`xgkLKfBvm26kDmm^}-lL$w zBVv)Xm+9gm?KNr|2J4J#l%#Bg_TM~cen!QhN66;R;gCgpt$GA+NXt3RIr4(}pjVCB zirYs5{@D7gnI9|zx>ckl>S)BCqcL}m#{D^(Aag9q=2%M1v9y|F8FP+h?KuWok~Swe z>d&zv!Q(|WS|vJyN-@W)_GlaJ5iE~c?eOt<(8c3&a}F?1v^*Up@aO-kU7HUd7U>ao znIq&lN8sNsfzOP`{B1;~8`jko?)FyP?Ob@|;mnh4f0mq|d9qG%xsu^7u7?};tP-~0 zBlO5yKw*u*+TRl|41d$p9}3F(UmSJjA3jM=UIXEx6ofdxDa>Rh`k4Xx&_5w3hA z)b{7tMxIT!4;A*USt9Isg6ZICE}u2;1I|Wv32a)mgWI$HViy zj;H?As7#HyD6v-M)gP6offpqA$_e=j{;4{{!pIlExa-KTi=vDdxh67c@#>%K5!@$y ziD|*X3;MN}tskG(xpdCruDr=wp?ez{zuvj*5_@It$;-wQPqWWC(YNWMo2`V;-z%X) zS2Y*1hv;67n2YaL5u@4VIct^k{$4Axy`Cw0y`=Vfg{{+jA3>41*ViRp<~u8B`R00M z;}wPn7ryrh8v5QibkRz*@Z=er8$Gr+S0wH1J1c1BdsDrM>8VW&>S0`VH-AVSiXGuf&~j^&Ybz+!Gmqvwt+Uizkh%C z?%g9tj=X&N^77@&&z?OyfByWXOP6|kdw>1@wRi8{B}D2Hw46M7l7oZe@#Dvn zCr|$O@1MWFe@skFK|z7Nz5VUmw>332SFKuATU&eW+BIQe;ZL7Fd3t)fxw-xQ`?svD z%*@P8PEKy_+_@H!SKOo5l{B41-Y*Sjvti#V585Cd+Bc=^;gV?AiP*QwyRkLk-zpz2 zws1+l+EVCN`T3gbk+;g{NbQ4cm2XwgNn?;+sMvmXUi@+JR{3q0T@KXVy_tR1H1ob^ zleg-FSFhi^eb;w;#q-|BH;mu^`1$MipTdv+8^8Q1p2Bdh$^PXpO_UANyTv^p$=Wb0 z2k$gv?#@m)LifBOV919`26bbY3NpY&<0Kdr$8O{(b@$&1qw7;M&v0_ z^ZoYj`igwib2s)wpe9Ox0}qz%|BrMCR7`5agC?G5j#145ZXU-xgusJkUg8c6E-D89 z57=XuW(=?_;OAv_8-;Gqq0IDWH*!QKjHfTS8kU=Zx@aGb0%UmKZp&#mY%O zo1Hu<^VyuqtN{l*4YpVwn4J`LNqugEl~@Ct-my7AyqGz*RvWlG4shBSiHpLL}kmIRflG>%nv+ps%7~mv4yLIH*K5sLSXx+ zS6ZF5-?UuTE)eTJy};e5;MKB~T-**DRQnD*Uw7W`^h%*?LAT%Z-HeM~yZvy}Z{0b& zx}r0;t@gA2zi#a{sn>bBC-@fVEV^E`>)npKo4WP3-R*jv-TU{NcFuan;#Y4L{e3n2 z!~VDXUKeP8JlFkdo7;|6di!oO<>()t{BPE}V{4RZ^tRVut18&3u>8%VqY~|}-yAlm z7W%lU(`$CdN#*uEuaA9C`?KoYgGYOeFWmcARdkBWIL2^`bGG#7%QMgTcgOT-cKF{-_Y2J5bzBh+-}~*D%k$kWPuukGe%S7$V$yPBLeaYK`)6v; zdHrbW``15SO>#K5=2<gu!XmuRPzXcRBGsm9KVeUT34c zPPne@qM!2lqIau=-*0*=tTUlUK$c@-Pgg^~oZZ!}(*3_4FzT$di&WowV}-`12?c!BOV3t` zxy-+JtIUF_>Vg29Of2)pWsa{8o@N@1*uj5m1Ha-P+3O3Y z+n-#xA$95Q`P-esSuPZwDcQJNj=gflrbn8A^<~M|d6!qTF&uf|^7)t0zcXpOn?B~2 zcYR)THSF4&o0@^8tkrSiMoiv4C??c{3zcuaZ}8Y1^S5PsYvj4W-hY#q{H>`tQgU-u(kh;3|JJE4;q7`aD!C;^ zH&o+H+M|VD$845q+prxmspy$??#wgk1(ADnFDXsPQdnYk{3Tmn+@$y}oui638Qh9? z3G+THS*UZlv+HH<<$3SVs7pRtdA{yZ>->K_88Hl67n-ELEa326;Us?QLYvi>g#x`R zT-3cTc13+zByo0yoB64WeN|r;EAX!LaQC`2Y1Wq|8on#N!Xa1i{s-N`o9=aa7WfX{ zOqmah5qI#;@~RR7Z{Q5BIK{F|3$%fARl*#ttE-~Eu8KIjDs20ytLr|st%~Da9dX?2 z+NN1w*UVznj=Ju}wsq6jwFSMaW1ipQmcHn!)7jx4vx)kzvi7xa#)ZU*EQ`;r7aJ^uF`R$cyEe=&RUC+Lvw_ zecyQ@^q$co@4K(kPVBsPc3s)_(|6xhec%0ncYVci?|YwSec$uK_y78;>!Y`h>BRcF@7fHS5ebak5{Cus62wg2eBW0bq+2h3CtjoF00UbF18a*y z6Jx^zCbnz(O^m7xED8@8_yio8%?cX+cs)EQDCfj(_oabncE#avE7!>~2@C=Xis=Lv}$2RdyU7>~+Vf1FNYGQa$!mj1e!X@L$C^Vr_z%HeMZ${(6Kc=F~(o3GPcI>+BWO0B! zqhOJk$^(`;dX21VwGFb-QjEvU99A>?GWktzVA&|=z-4eCHHx``@$NE5&bS9}1sJOL ztIBQbIj6(IDdWlVQH+Vz;1UySfWm&(h=UWeKIAhlxN(}PgMr;orIF*wb!K&;gNs-b z8l~o}sP18N=*|4Vz~!@xL3^5by>bJC#pK9)MnVpq{0aG5&vzf+7}l_oA(ye|Ou}h~ z8yimv9%xkdOt_@@V*>jj9R_}xPFAh$UprZP3PiRfFc>_@7hKX;B(^f-TM*vCCvKdD;hk@6am{c^Q7g#h&5bYQ06PH^;oT zEHmnxn%c0;VCNg2`CpcPwr=D<_?Kau*v~831u7zQYR*i5UfuR(-u-Fa4~}xUGq7-d zXymnVV3fXCR#$G5*{Ux0g>T0J7Qgj-m2(x|F-N=;5Gz>1lrryh^z}bIHuk051`N0M zw0#gz>&t5YeCPQhaRyeo049#&C=T^qwomeFTXKHOeMwxl?Sr99K7&B~DON)VZmSJV zJSGjyr{ni(tDpURM81JZpxuD;)_n%HmOtN^1S)r_v)p^0*uA~z@o}Z+<}AW0Oq-vk zK2|7m5-9o4d>}dPdolZiGUf!Poad>h(yDuo)haP2?laGHpAcU)y+M0ZgVP6V*$w4R z3lx|Q%G{G0?WV^YeNZfCOPBgl!DLa&bfB6!p;F(yDF#g=iq<*O}?pjj5c+<}GmZTrm9M99!HI$4E7)%@(TnrqI92mqNFbF3wDQrk` zSF0DzXgBX*kS$;K zR%cnM#vs0;=)b^%_BqG0=;Ckk1Dk9w}0C@~Xy)U({ri3*aS zqn=eFC#h9V()cN$_<=z#fr;}1qud9EZnoxX14ho5EKem8G&|+A7O1(oF>?nL)CMGq zi?IgpnEZ^fP@{~?8P z{5M$syLV1~_>oaPfkCsOJvNL%Gl9W4fw5%;2Y*;&mZV%BJHz~TmMQ5B@&(g7Crqn; zDLadeK_;P1hao{?Lj1oK8BPirCEpmGB3alO7+DO`xeOS~R(3HxU=VF!EaPO9Z>ZuA zXp(xykein3oG@#}$qv^E(}VwU*d~9WP}jGtJ$&jA@-G zi$DO&K1&9zgc3FeW=;ksc_t>6YxA5Y%wU+nq-rpI<21&Zkx6GIr|B{<7*Am6l*rb8 zkgl4R!@Pm#|5FVX-2^7N0H*!SOg_t_c@0X~x$^E!E`6#gJ6kfFErCf|fiY~`Jm&|q z*&LYIHZZAjFmNZ#Hwj?StY8#K(-2``6#T##m&72vpyF(1Voc_Akq?Z<42i-Y@^2g~ zh*M*{9Kpo8A(g#=@j@9>*s|yg#~6JB8Fra5WLqq{;K(3yq4-;5vi<}{eusHZALcPD zFxzS|=v|2C-;g$$jq$DpL+!MDafK4r@Fm6#Oe*4xcB|5|nHc2Q7e=ZxBr7aoc)-LU zz$kcuN9xtwjc$s6XVh7HEIaGSAg~}u?LhXNGzQfN`M+70PkUbQ{~41=0@JJTEcp)% z(hQ7oCsQw6V{H7T`2Q3W!@^ljx&@0S9b3WBz>rtIa$P1P{|3e<(~6x8nE!{d)JgEp z`?Ydi8l%pENd~XH7%nght24aMWD*QW5_6bPZpENdRxk1({gOM&!Z0R2bp}?g*%~Ko znHvNzvn?!Nws>zEqkzK7qh2eW7epspZIBS_xcY0QUIW9VSF@V7&Ayv8{Xvxyx4^1T z78B$Hx~t3+1sm21Csb)MEL2?(?^-qckvQYxF2SQ*3-_lnZqUk;+`y=ju)4%*!>*2* z&!(^B{Jm1-z^Y$vEb~*zpYG?0^Ccaaz93GDoE4Ps9t}V zYiZXj2G-w;OdnJ`H)JJED`j4=^1pSp49kLYX>S&p*&CTRFu8Ki_m~~;RjnlRpiq8+ z+F#Dek_Q-+c9*)|T9YzuQ)D(nej9_BLy^vd`q^v@3I;;u$C6zfwtXnycFK^EPk?Ei z*JRy{Rj%0#N(_vzwKAO?diWnOnT99JZZFpkV=C2RaLvkV?%oL$S++4dUN-az0qnrOpzzLdhzsQEu7%d&vx(3_IMFcI!`T zmVKCdt&?eT8Y6=>OY}0OB&(U`*(?XO_Z|N57!MHZ;3Jy^g0^uCQ@JKsgiEKOg0 z%bi8AfYG2pMf}6g0QG&*W{JE7O8cr9-p^!w9JN_dph)$=x+qJAJK8yx9fES#if@@^ zDg`7 zFvv6X7+fg$ziqA30VXj8Mt%n-gA2LJvkRg!8J?-tF>E*-^Q^1wHPeLj`34&p6&rSl zU$A96&>>K8(DlMT-xwLL^!azVlq40V>QzazJQ(Yxi7*sfli<7_ZpjE&*d&3P->_P8%P*c~IIGlB7c=Zc!YmOU!h7wtdE6W64q z@PLuEfq`%NijHra0z$n}>q4?Kkh6jrh1BzH37{n78MI2WC+`TBXoRQ_iN~Z@*4Bm`v zwk)d4S4>=W!R+sXtqR`) z2L6OR)xDQ=Y*|@9Tr!ZoY-D@cB=)jd?PZI(m#y|*wz+%R?(by>*(*-AS6pJRxYb_q zn0v)*?-if9u`D011jt?uvb~Dy3f})I$anC@#$wr8h`0VBeXkZWVK{SM9xC zbN71P-|G#sH=1m3w8Y+MtG&@N_eNLkjf-1v^!>dtLH6b(+nZBjZ%(VdIm7lw?_BT( z&c8Po$lh9Hdu!g_n@f;3aQ5)Vu7hvjl)bsE7Pf)&?ya4FZ$me5>fSh53*ErEZ|Jsdev>f!yQY zwRer;9-GD8)USJNweRtxDKR$x9y_eNX(IQ;CGH8M-4nNYPrS}q?B4ps@7)v2e@}wm zJq)ya8dmo(wC-uty9bf`p2o#Ji2e68>D~QAyJu;2_fzYhWxczXx$jwC-M!p@&x-8s zdDuNKvwKij_q@vPZsoq`b?5HX{(IgOcc;du+K6CHQ?tgDC z)V;oB_jYsK+iU+`-I(`w^}e@v>R#RZ_ja+|yGQ?CK8brbyYAhKx|gr^y_E* z{>Mi4pUvYwo5er2nE%;u-)EcqkIo-ew6}k2Xa7Yb?u%RgBaiuCl=gk`@qc>s-Ax?K z|NhnPdrANMvik48=Y6kw|Gwt_cgFwU8~i^s+5cdV|IxPoL&y9dy!(Ij@PF+4|3g^* z=cN3PQ{sP0*8iMw{^P9uKjrWLoTvY3f&4F3`(I1?KP{{Or9J=Gs`sDP-2Y|x|JMfp z&ztOjo5%m&w*K>u`M+)V|K7v@W#9kb+H&6xt-pID{?CotKPTcJ9^C)O_x_)A{9hgA z|K_dxbLIY>YxRFm&;5IA{=EzL|Hl6R`+)!3Bl~~J_J5zfe|l&Bzx{jvz43qb^#8vE zx&NQ~pMQz}|Nrg3ANjX`?f<{!?tcdX0lrSx$AU9M^k(`#7nYjp_kU&RYth+P^OiEa z7nc$1KbiVja&FlAo4Mbm<))v1S^8Uc{`L1iYyZm|1QblzaN&c1VPN6JjTb)(8U+7x>C~-PzlxfLl}+1r?VFf+c=`10*T0KfL{!Y! zapQ-CWn|^doi~3?cBY0|H|6M)y>;? z@1LA~eEt0W_y5Z$I5aYIikVahBs#TnOPZDZ5J+9LbMFfCV@1$~)v4^tZh1H=FSpyjg+3=C(_o_+iF zEquhEiHV7mlk@7;tMA{x->_lB>({Sm&YXGw{{6>~A78$F`NfMDOO`BIzI=Ida`Lfb z$8O)gT~bnV>(;I2=H{(ix9;A(yQin;e}4iWto!WQv-b9OcX#)& zurOU+T{bqhRjXEMXlUHIbLZ5lQwjn?3Q_PclPo2Bb+&ffw$O%y(_KsyHe{|1I8+%pd|J?Bo9T7dJA-ZswQJqI8&564fO zgdEK}UF*VS@XQ1FkluTDP47R#c1Z6Wf$zUI8%>e@4LO?iftuE`I$fcyukNp@StpYh zoUs9NNUzQn{c!gHZL_3P4_+iMVo?I$G5OTCU8O9Sq2ZG1Mg`Exte|DOAr=vPPq2Ml zesQtKP=5VH1?vIuGF{X= zCTB!=bW}WeJi+CZ(qSK0wUsIVHRBiyBp6(Dz?V!~CNM-8B{eW|MZ8=(J!0366Vt4Y zd_FimqfA^)nVIK8>Z}5>ozIkV_enmVYjbX;$J~lsR{*r^2* z(z_<8&docuD!V0V7Z<~t-E7_o>$ks~xq8D1C5tA7Vx%moHlztPlQr~GZW{8gu`quDhUS!|4zt$xA)6JX$Dqil>?6MMj;o} zIQEBizd!gh(en_4zfjUa1_O~C^+O`p+g1PbGby}D}C$}EdoG6>r zes9wArW>yunV5ANn-qAaTzKX)r(17#UPH3wVSzCI4Tt!1v&6*%TMlsR?=9FC_nLu4KxV?qi`}^zd|9zIv`uC6Fi_bqMj{{6n9~wA(7BGpQIKXE0p;4e`0gJlF zL9VC|;B~s-qa!~wE1(@6dE$`Rt`DsSpra!#7VBO3&}MOFAs_hY$PeufIc>bn9!Hd< zK6ZF)=@*@J;)t5n$IgI~bE1npTq_b5c14_7B)0to%E^(lKK5kzES7p7-fFt*ql|yW zVwvY2$E|LCL^(Ng{(C41Z7rIy!R7B_}Qw&d=bZBcC%bNj)?{k*|1}$?}_v!-8-f9r?m% zxz+WP=gM|{p8KI^xy^IW^LC;S<_UH*@-{RutK>8=cTYZI``(kIDen;z_k<%XWdV%+ zSB3pJEE)t1*z^kiE?`>SeZ+xxSD^2T1HPIaF872!G_)T&$!NCVB*TmX7Jiw9oDXg} zTvNCh=y*j$Sgc@Xtc2mENwY+Jbp=>BWuh2ZEEG7+H{9YgvAW=R=ZlcIf)iWa&5n8h zzIcoO&tPJxxWK$zOq5aTK_g?4!&O(Ct73u))BV>+EtTM5V9?We!MJY~%j&r=1=H8M z-ecPkw$0CzBfqyv;hEL-^_Lbfi5fI2s3kB7yF8dD@Ztbp)Q3jS8(UU36)-SbY-nbS zVVKS=+sNXR5XtbPfmy$Uk(Z~dfyrUP#-*x9*u6e92?-n!P|ld_U#$?yx8cBg*GC7U zJ((B|-4kY9tLvc1!_dIylfbE%8O-EV(D+13ge8h`I%C}jCXt*ij7D!f`Lh*AZD@AgK`Fqh9pLX z7T!HmIV>U?|6dKe!1zV1ls)>^E6$<=>liB@>~6Zz*wWn4tguIv!Cl}(%*G~0Mr((J zUCd3qD;6-DTZ%B4URc{4-oUKf(9Ln=jeeg+z%rHt3z!8Q4mKobUuO15@OJY!ASl$+ zz_~|Zf6#>kjL&8<1H*UYy2sjSdp2>8G_N96(2J=O!QbUOC(E%3~i+sxSXe@}*#I3t1&yzcN*^pZ$D}fz{!{U5;&k zbObCO+%(obaK0_zRyh9x4)%`XLjDa*%FGPcOVl5anjCk`W?)tLkRUnX zvcR3_b0vAX(}f#a3LMT0Sn_>6D}MVaBa7)n^I42c%R+Bimp7#3Iyq%-pWEu2OJEd#!NA@Uz<6bD!aBYJbM9wd46}_G*e=VutTPn2DCJSjU|HbEZennG zHhYv*Tf>1ZSGh~1TW#)rpX1;%@pbcm=?&U!NAH?7&+mQ3wERG-Xo15`(+5p59E%P= zRV}!|I6JN`15o1-p!SMOk(iU5OrL{G-M;;3u_`dJ*iOaW6zi61s z)4+Y=HOH-gQw1dABc9mRF^B|wVmB}gQ@L?~)wP1L*uSB=+?!!D^EroGtcn|0E;tauA{MA~x!OD3;{l}yAY{&GOKQOX7FobPp5lsD`$$5;0K|rJ_fJv{ocFofUwgsYh z(oJm>(o@Sh9+}UMStOktS zlbOAqRa*%#r)+QOn#!R1y;*NF!;NqTNdpEq4hE)VhD~h@-VYd$26Jc}ur^4D6ntP* zYswLl!4Ou_s(Fbq_7k(v#R|V^A)E)8^j5Sla!3&W9$2$A)&E%{k3sn5Am$uqhTKtHFNMJUd#!&dQ zDL{eMM}b9(fzhsjCD(~Xc|sAZL!6cavnd0kp#zhmz<=Q@;UT;SVw_gQENE{(Ys?Yo zkUm$9(JFyKk%6hzj8W%<0o#XYh7I9+I2b}YY7THH^8_${o?(62jDz!m`N8M8jum zxS;mje1c9>jL8EgwQ1G`<|azz3_jNxSQ(fs9vCq!U@%kQl0F*o@SB$VhID6zcBVE4 z&CIMBQ;Ryj6*L{tKkZh=;J^^DfcZ@lgZ2c*KOB?UKJ-g4RGMijYiwY!o4~@ffq^kC zO;U7Ky;BP0MsDd=ScQ ztv++=CWcR+if3rr30+W|b93fh5pli`5moI{p#jzrEmhWC=m6PCUkUe1PIGU>^1D-v7C2En{ zt_7z`7HRETqyxWWvTA`Q=#I(%uuCSj7Mb2cTr#QlYq1;bl1bODC4N#%gRGW@L@gEP zS{gQMDd>{PsHG9NmL^CoOR`#K{A+1S)v}CP%d)%{rtMmm_iI^!)bhW=K1ETWb-Ky7 zmVwsk-dgUoYIz-aovtp|iWcxX-SAZlyTHqI1+!L6uv$6AYUQLT&@$cTs+F^Dt(+IN ze9o_xi>y|qORZW0TBf^n*{oG-Zmsg(wQ8Nz>P@#6Z?Iaut!lMl)ao6(R_}>gwCmRD z15#_Gf2}?gwdUBX1xKpZoZ7X9W!9QAzt&u^T7E!e?UkstoUhhgo3(at*V`fsz=*LJP{b!&au zsrCP)Hso_{V2a+5@oE;w>Qo>y0AO8^x+OO3dCUwR@w??TvE3 zH!4VPQnKEJZ=EjMGF|B{PS&txy0f=r&?opWyQocDX@0_k0gtamMm z-nFcH*NWM@R_)%k=Ju|2zjtkr-o43s_m=40+p2f(n7w<~?%jKC@80)&_W|iWhphJ; ziQaRpde4d3drs}%bLRG*bHDdokluUAdheC!z1OPu-k81j*6zJ`ZtuPKd+!73eUGg7 zJ&E4;teS*nx@M<6S!xb&%sId{XV2y>2bw=J^T~)x8FL0Xa3lyH^!#WhvFD&njQjM< z2NincrFuA&We%y;9Ew~rRb$T~ojZs0{v0xpIc#Ke*d*rvVY8aU7IO|;?Ky07=dj(M z!wxb>oNSJ`#2j&}IpQ(rh}WJYK6j4z{W%gKb2P~2Xh;lboo>XOqfz+R=@NZ(WY?Y( zJ$Fv@{W&o~=Hw)slT%_&POCXNW6sH0drr=|b8_CFlM7@{EwVYaB<9qzno}$0oLaT# z)S5e|*8MrPLFV)(o6}ojPH(F@y<^VlU3*UNxpR8opVJ3q&K$Bib0p@>v6?d{=A1dT z=ggTqXU_dOb3x|pC7ZKXV$NQxIeTNy*;{+g-nn!3-XHd}57xM83vhtPrfeX$x@=^K zV7Uw4LjV6iXdGtq=FNBmekbL8#ivOT)C2kg@u!obK}O1Q>RW{w{G2|M~{vk zJ*uy-fA#9s0|ySQUAtCTSor13m#<&H-mqcA^XJdMe*GF16?OCG&8JVF-n)0t$H(XN z>C+)0A)TF_{r&xlii(F09pdHXoj7r#sHmv2va+wQ@02N1CQqLH=FQtLU%tG1_s%%# z#?PNWKYjXS7IE|YzyHROH-G*5_4)JXD_5?(fB*jX@87nO$4w*e{`vFABYO4x`SYD3 z_k8>dy6|<@tXU5pJn-=FxO3-@RpdFtsC%ugtrn42dV70MoH(&;*|MCRoa*Z8^XJcR z-@bjxk|lfh?hOnK+_Ps-NNoSa*;n3v{;#E_Woc{)!(k+qL7*L9d3L z@3*(gT~stPV*am$-QV9oINbeTe?=|iYS{7;6U&HA8?K(F%hj;!Uc^oGP+R$Al8@QT zCzAu*z(aGHPp3wtt$aEyrtIa@=?UPgVW(w2BmZjHUqQ0d(pJ4(Hm9uWk>tEKl&fLq zI0Z%}uQ~R=YuW0JvYM~ghFv-}iJ*1c@Ym8jKkw?E)IlIzSIBK>aX&A!tCJMS%et+(No-jR2^zdVv!@AUcF z>i4U@t4(>ok74#LeW(9yIRz`2;8G$JJ$T-k;KaK1buYY5SVb=Q}>tG@NC5%=6`9 z`LUb{Cs`yI9R$TYJ~Xh{3T!dB6fu9Nw6ovOQ^u#X4-^z_RVY!va5ZwdY#KuW#}gLE zW|1xJ4sjjQ4vbP69}e-b1pH56z1FsxIgW016$tx`w^0}W#u4nfZ`^m_?Lx6?BhsVWvt6)W4(Tg4VmQ^pAMcV_O zaC2N>bQC@?ubJUSt=!eaJI(bUykow)SKtHFf`R}ZmI(|8*tT20-#g_3cS(z5^zF3{ zY}^tB0xVa}HZ(qrW)%GW{mbd;67Sg+i+28G&v5wSAd@lw(=?;~za&4{xp#GoHEi0# zpwUqJU)Y0z^+E%q(o<&kGYU+ShnNf(@G)p|I4~(qU}RizUg6E+1+1ng4oTnjS76mS zk>oR>fuZC9gIdgdhKI*R#AEyw*fSOi{9id)hQlF&i*w;Z-olDQO$859M4vnqSgxV` zjCV;52WKLKQUL>#$wURKhDTieLe5PleO(zj=l*;spTH}?5-DL3$;r2=Ig2r|C-aPQ z*N5+pZ*_B-BnlcB79|V&Lg74@ysro-SB{c2Ag)XHQ4zaTtac>GHXos)}Nb#-=T&8+y5?2~8o8UCh z@Kd73JS#mEgQbUzV#~%yi)ilviZ9TIr_BDcyG}WUY=V zzi;m=ZwJ!}4k;-s4|%Q%+1`2eK}P9nsg{@SyST1xl51U)=KI=hfdWVCg(*rIvK?|9 zkAmB4w(6CKu8#Z8<*&`4uwJ53E1vzd*#2KFi&|orC)zrNG_6qFIKh@9!Mcc@L1&v* zNADUPb#1|OS>HCh9n{E3^}3`}S+-?`@7gTkqFYyYecQUBcWq9(wx9X`9gW*+T3PbS zPv5@x>)ZANyz2_uz3)7d`o80Y@4BMtr|&$o`o8l*@4AxZ-gjR`ecyEhX;rW&|3)68 zdmoN%vC&doQklAIR?CWV(4ye)42LIuKlOdzkF)FRx?AV|UAJZLKi&-uqCaOaO8Ax`5oo!imM#&w zWc#P)BQlCn7tEZ~;sorBZ!sO>Q|do1>%#HmPOOE$$F7qx0#eNfIW!!$?BW0Pp-Euw zYo?E%*;5`IuMxiV(m(yiamERG9_B7w?3zX^wlAM>Qo%|&!+-a-4GIG0N-jJpng!=? z>IevMury1q*zWYlu7cr4t%7$x2j8J}<>j^xm&DUO9;+G^eKb}1G{>!@$C{VHCj4Hk zXvfXROKfwe@;_lax$L&XhdI)GTN+t)8Jf>(PkJWy$Db$Ae(&xb2Yxk9x&E19#eqq+ z?VXS-?v5HnYSIsgBOH!xW=u$&N(-cZUqqk(Hj1J8|yWg%|t z2U!GOG>Akrid8g9%xIL_(I|7HQSL{hf<%*&MUzTIlUhZS#*8Md9Zfnnn)H4&8Avo6 zSu~qOG@Dg4Tg+&-+RuN^HuH(LCDv;;`B23fR* zM6`xgv_{NmjoQ%~bE7rxM{9yaTaravN<>>)MO(&>lmqfIe zRkT;kXs_DQUUQ?p?nirrL`RcFM@vLUTSZ65jE=4y9X&TX`u_jum>|(P$)a;gMCY`M z&KWa0XYJ^mbE9+KkIn@WU5hNbmPB+dtLR!WqifZUt~EEh*8S+(Akn?aqI*k3_qK}e z9W%Oj?daZfqkG?v?gJ7%hb(%IMD!f1=s7W?=hTj#GdFt9{ph(M(R<0F_ew!kPff zsUezL_m2xL37ZLqp@+|NoypeQIlK`||t$ zpa1{O!|(O=^=;X*b=|skQ>IM$`Tzfe2M=_0bvJC-aO>7B4-bzWJ9gNHpD>8Ldhp;u z_ox+~QR~g4u2@9gwT-@W|NebHKR=7eqt~uoyKv#ctFQkJ!|yxB95#)jarNb&|Bi|Kbc0V@#6OrmeY#Ef z)rAWe8X6h~2M1e3-H(rtUvv2X%OC$g|N9@1xXvKts!#Nx@bGZ2h~@9U{GYh|w?q8- zy1KfUn3xkMPB=zwa*JIbk+#Go`lOtkTyAczP2^4I$o=1c{J;3%pF{XAo0zNCQP<9# zIl6M?%JR0e1qB7-;^O=E?Mq5Z+OXxeW#G04@BY94{r|+p{|@nwuDOw2&3{o*QS;}|H;#Jv{{Mfch>JF12No?_q!oBIJw3gmaaUOCG~d(< zJ1_jVirnlMyDd1rsk(iWU-&$`&eUBQZylYzWBdhnnSLC_g z89&4FPHx-(dDof$1iO?O6FC|bb0pFnIFda26=aOPJWpV-6(hr;5{47sE>v)ATt2bvrQ?)%SMj710d2yq#~wNvg<4E$VQ6Td!0E}c zC80rQ+Y8Wg4~_-R%)R2X7@T;v9IxcsYA~akgCXIFlaP(#1gRv4j3l>U#tY00>@gxw z9dlX~o=9@8{c$1rapr@IPU2P!5*kbk6_gw$ryaN)DwgP}=BVHhFd<&!ZCeB9&$}vY zjjX3$JfGjdruAZhOYibI4hvZen#34-67I=Y@TJH&Msk+8@iK5Y%u?hm^qS>h=~cDD z*-=P9#ZkFuR*a-cZP$ftf!_ZH4eD{GQ|7Zc^F=f;w0XD-6tOTloM{lg=_HlFFe5O^ ziFJwMgfguIO%EKi_*@t^a{e{EvCY-z&NG4~3D zHqVgroS?#Fc&c%W@X3$Is`*2`E+j1Ea*3+)Joh{&&KErD!frE}wLPuJ+ybRlN=&Jm|_Ajpd{3Xo}JTblu z%HocU4qXfmD<+hAu2|}Ngh7GZ;WR_T|2a`^5D0Z5enOHdvT*X5RX{XY&>2*b~i;bIz<>6fU0L zV!)tok-+#^rcw6ymWR4qmiWl;y58otkmp8vKg-m)6IMUqOKFt06#sHyicQx$@TqKe zE?>`K|JyHaa%o5p!s~G{b&lJL7LEPG1guvOev*%_Z-#$GYhn3?U6pY%3>}-I=`LxI{|rV{Xtzp-xVb2RsUtcxMZ3vS>_c z&1X4zQRYjV0H;rZ^7Wurhd;XD@<5?*M&90+>lY`%hmN+hAa5fwV0f=1ePB8($XdP@}>*l7umOs z3Cv-qt~x#|m>`zd(a&n}$Z-3r`l)WSp=&D%8M+UFo#Lj~BusOh;YTzKn8oShk}nqeqcR zV2P%WO^S>OfUXDZ34xbsEFiYAVQ3nO?} zM;!MGbE?&-6Vq88b^X+}ZG6Wq)r(ihJomc3E9{x-^DU5lrb4b9HVwy=r)~<_587v% zy2?rzvd{FwkEh9)`%E3A6=3^JSNN`l?lavA?oxW+zV-jsw{1Jlt|hBWiM-KtJ;pv$ zNSE^a>HGhFec#W(SK!fTuw}B)kpoPA8=9Jf8QJ7gR&n=jXt6AAVy{`0`gO8@c7rLX zOKFtOb(TZy_d}uC6?*&@&AM!#+Sl?N(NXW)*z+)mY5$MQNvGy)>?^MkVNZF$Z!}e+ zzuo7_;tLnOT>UmpnttYqn)T0<0ezdMEcbb;75(#6#JNq=wx4;bR}H@?l&@O-M5^EB z8t&Cd7lqD=GP(To+~=vnEg#RMf4564U+`-4f`!ry^NNl;a%nRi=2Bu{%y}TpAfa5u zX1vWYT54yjTt~5%CCf%h7rtJ$2I&BaSyC;(F0IhZTPFC4;r>Sd)CFP;GIEDy*Dd>X z?O<%FBL_np`-cq*3)mQJI8EFRe`GV+;b-PsYCAzG?%j1J&TVd-MH{bXTs6`+Jm`BT zVuFnJ@7rfmwmI4evg`TuFm80?h|ukn6bxPN_+sONjDx=KeLqc6(E4$Gc?IViH~(sd z!mqvB77d%Lr0*>Hu6BYe$mGJoJ=VAWz4JbhZpVYWEHe)#ViCbkF4Jn?>Cgl46? zGd(eqb)%)Rzki2r@1GKC@Y(JTh0CtE%J-8&Nd&dPC|m42PUK9`m4 z@Tw)&DdwyevmLD*9&NcjcjJeTr^Vvc*R+ZxFbaSEahLu7jp=KCFe*=UkkP9X_&!1H zA(Q3Lt(^Xq`@i|U6OiO|=M|EA>$C6E0{*=(-2H!Dn*Hy~3je*Y!q5M@w)@}L4gGuH zr2GHAb^G799q0GHD?k7H-tT|k5Ag5%(C+`|5&v|qW9L1rC!PQE>~gsLx#=8V7Uv(; zFnGvy<@`RE-3$J{tDe79=f}SPKg=cneVqOO&kO(m4;D}0zsT}*dOb^pSQrC?v4MaD1B3hn#v9*-pKfmuF>H|jSjUps$U38u z?;$_`L8dS4B0dcw5-S>2UVtuKv~&<)2@}zrz@+-4sa=tYVMI1| z9R&IsSS=-5{%ve#E@aVD5O5FRwzP1E;$Jvr$9GtR1Y;9~c=LYJCo{ zR0VLJU}t!|fu(B#=h_DLmIqA62fF+U80#N(rmrZ>{88Ukz{ym|-yguerhr{fftkU8 z|Hc9C1_c5A0B&~$p5+G24?gf5PT(`xz}R4cGB7k0^!(kxc1NRQ>y3Wl!fu8Hp1217CIzMr z0}h4_Z43rHD-5_D91^S&IL}?+Y@NU(zJZk?fW1_J@4W+S69a=;0(0XBuDcJo-DYrh z25_A+5YT(TdcJ|n%z-V1fx*gw^@#yT_Wuc;1`b?C8Ui5(lN}P6lW%Z4cy#}(m?Hd; z#cpO3lOkW&2cC=sW~Pn2mI_P@Hu7E-U^Sk=*$}{P>^Zr^K)@=2c{&59Jx5DO0w+@- zXT$}*#sDq{2i9{Jnwb*0ycw8{1Xwd15?(vA-cFd{IFq;U0qdHEDQz5R6ed1oU^uP7yG(&8l#|o@15^9WIjj?B zbXT%kAK*6nF{5k(zotU-@(6Cd37m!jTxJ1W{r?kKV_r68WzG&0;52-|Yo^eA(LrDx z=WM1xuJr*eTR-qxCUE{cQ2Sv8vmztI@eTZ4A7)zxFfJ0{InK~>?&X{dmIC1owS6bJ z%_cCv6X02_AaE~$_w<1|%NMY3Y2eGz5SXtiaJ_-2If2!ogY|d-7lXjGz71@h3=CPE zvwtu!och2Ot+8n01-^S9_`CzSvmGWgH*y{_V2*BJ{lLJ|k-*h1z{$O90q?5?;Rm|* zC@dDW;(AoT)7QYM&(Pvtz~aZnV0nR)`C$_S1LuqftslaHGlf^NMFLc&KO#u#*6SEe1 ztzx>!y4;E}bOD3A!g7WW-1@UPHVdqNv|;5Q0gjF&&dmq-47He_a4;+>SR11u@MSr} z;akmJGuO09E@l46xMl%gN&<7p1>U{`y!RPq>F(nD8p$&)fN|Oc?tKEB4GGJ<3RcN~ zSo=^*;0f2_%?iz%s@T^kFyH^cAK$<+je$k4g7XpsbKHgXiJS}u1uZrISFAtsN~!nN zdiHj9#T}EpgFcb5R~a|X_33L6;$Hi~NtNNO`nORr%5xN(!_rfcP_EeE*D z3OGJ8FkC;dE+k;SK0`mVAgkVkMy8GHtxj(~$+m%M;gqCVP0a>eyAP~mGGyDkfh#b8 zyLCagrNhQY0*gLpujf125d|hxz;>rkNCi(zhFk3C)=(KEXNt9u{>=2 zetcVA_ml!|h6fE?kE*)Pc(OSx=w>Kj_ef}+!o{#uVO6uWz@1l2_h#*o+r2|6oAqc1 z->U;$%NH;#SKu}}z}NI);^_@6OoG$;xEUTUXZWSXQ6jnPpT(|Zk1fps9E&ILlulqe z@qc;Cngd+V8u;`icI^8wN9y#(HNQ4Ko5j57!H%;69Ge*!${JXEG`LR&tUnhmkbI#v z%X;rsX$9--z1xp*zcCPK65u#cz|s1F>Cggp#a(<14(ufg0*wZ33=_D$A1qnQ#Sj<3 zdOwPr#c);Ug|?5ocP^R0wAq30+itGU0=usl@bx|5xb4uqzhJ!%Lj!}sniUT?*kZcX zHZ@r(G@noqh&aIVXZwavYReoo1^77`+CMPq@i1Juz{{|J-FgGF@q}gDUUR712(%Wk ze0ea{&{BZ4n)A8ADlduYw?6E5-@&|Gp?-4%SJ{PD$2raX3z$PWS1sMZcQm2v&hiBe z3f-3i1WuIm{r@kpXy1kv3<7*!0o*e;9Id*rp6Ma?)CnAo0qhJ9IJy*gwmK|J^GZnO z;C!qpu*85nV*&SG1A)2)41NLp3<3PVW*pbAXnJhGv9Exq?8522d)QVh2!t(|@K;^n zkOVVJ;c)|jGZ6-T5d|z$cK6Iu=$_1RR$qWKPJw5O1Gna`l~Wj)w{GD6^x*`nU{?gg zxw3*)9tr{#9~i?Ya8|x--S(&HsR0M)D$e)jjKU2pi5(N!16jjfux56#hCg6j>%dXY z!SLxh%ajWjcx}&$FJLf!z~Xy>#jk+d`T@IjzzIR!hFKS8Y`nRYS+GmQfkXL5?|cr1 zUX8}jYZ}i4@btZA3SV&EQ8Q!@w{^McTbm6j2tN{NEA=kT?Hh#a9d|`bm2g5HLfy5Qp zEOoh=4qkTPy~4d?m3nRCr#082?p_YFV3c6k?Yn{b;rA<%FMvs;A8Udu|(oyOFoAGY){Yhf}Npeqp8e>-;`|s%@G21xvX9;mncQ;8+3VxO_k3H+&v%G)L3i_Jo zFIOnkd%7Uxx%LZ)L z2ED*ZO2GvTc6tmsYz%2GFSeRHW*V?BvSYVsU|z&0n6p@qJCR{+;tN*B%&a4RYz&ON zAN1yb%AfK4<@R(2Z#xFteGKnE32YH^U=cKBO=Rd05!{_5Rp?+kr;dSb!(;mcwk!`{ z>{?gV&&*I&C&;`=?aDqw!H18p840Kgyg3 zxSB9zo^@kNU#uF)$I!dw-RA4>1Q)uoT`+#+Cy*>I7;y1}$^?ll6@mYn9}c*G5H7T2 z|0q%SPvFEBhKkQ`Mf7XL{tF25GtLQO{`%0-=beCZf#Jb_dRYeW81Q2bxp$j4yh z|C!&AWp2p3i+uSF%LJ_AKd+qrw&}Q#oI68}@!&Pjf)`=-)q2x}uG}j-ttc>8Pe37GAh1~Ux|7bMeNLJE zbw>P#Ob;KcJL`PBC!p|wh2ubO^#1S9r!yGU8?sMeVE>@U*6^+C|B_%si?4}q&N;p3 zZS)C^|M__PQ=0?NP9J(Mn8 zLHGPWJB}sZW@4DJ>62UH8<`D4Y!hB{|Nr>)LVY^>1+RhvDU%QSKF!SB2A>=ZKi-OC zD)#?A^V8pxVb)6=-2;VHIf5BZ?h`rE_l{ffGlL@ZqEMF^0S}$pcx8#WDAcx1LZjt` z12c=GhvbRlPY<%1@R}7w6hFsuQRoyYE`|q;A`Jme`RlayBragN-W;PU!%%fNp{a$P ztBCbgSwhqTWflzzCJ zVPiL8u197BL^DrQfeh**VyVENJBo;NblhW4r&t zgg5sXnsywDOAtEu?C;;?{u>?#`$EcYp3U(K&J2B8}ZTp1^6EL_j=g{fhag=8gDgEXJQB3Fz5QOb@BLbx>EHb{v}YRrAV zXbJ41(Aisj74G@15!`CNow=bc;2=xz0?RckS8ibvU|=}Y#PJ}}tf@puuwiwb0Rt2B zH<1PoPHuq%9hT2+9+)tMyqN6&hEJ=Z!_$1}wy5m&N6n&h{hJ;zgr=1Wit$!Cb#%uu zzQ}A8J)ppG#?2(a?AlJYBypxl&PzoLq;D}Wh|g+JRf=cw^L}8>TQy_R&AmCQCwL6E zw^}51sxRB|$m?iQ1BbkuMTtVA&CJZOvYQjQ7tWH+9ELhxNAE38Fu*HdyflENl zU;)qG9Xmet>}}fdX^)AZXhsXGmqrFdg#5N0nak(5S!J#KKi{i?arY-z#s-spOoyeK zKY3^*GAJ-7G-$IwaO%yk?OndSmXq|Q9uEVBCi9GJukG)} z(iQxscw|m;U$^(o+ph8>$#P#SbhrH|P~bky<46L18O3bRV2<7Y944GNc~*hVRgF>@enuVOO=T85_VxdzS=W!G znJpDMGIvkF?E5U~7Ds1Jn#8+g&SRH!tE)Tx4sx(ge*?KFblQjIQ@ED_aveYVcRoK;4;YYK= zw(bgDS9W!EJZpBuQLC^`)2^;bcg>Evx+`qkwySINTeD-HT7~brc6D9((d@XdyTbQ< zySl!fH79}9I^vMnwGHjAIZ2|sBaWF}+xWk~H77;YI`UN5wN2BH=A@bKjyzX(ZS#EA z+zeOis7uqXZCUP`n-#h{>e{wzTi3Vd=A>Fj-@0~f+xDZmd8NCf?|r+reLrhnL92Dl zBeCl{j=Sa+P2C;y%~Px0NhWwaxSjzjbN)v65w` zdo%sYZ(W|xR=UE~HY;fQtt-pj$hs)>d|TO;rM9_Q;kR#HKUTJF>)zbF^4quXvz6~S zYMWOy{q~*bZsohK?#(OPe*5nGw(>nsZS$+H-@f<#SoyxMd-LnQ-@gB!t>VCcR=a{G z@jDOL-75}>?ki|Bzw?m4z2bR^*XkP?5x?HZGP;eGupmG~ug z#(Ucd^aryvY94=mD%Mhvy@c;s@!AH*lzX3AQWz9X7!Lf%TNh?ritYv$vOZf_Pl$^HQ__VFM z=@naJ$m8o;Ec5xFykeMeWHZ~Q&n%J&;p`ht4kC2JnX&AQ6S26 z$GhpQ{)xN7MzxFq`+vpMrYl%}ta&EAeZ{SU%v(f z1nkUf*RNlRPbwQ9yKcNqO()&6|Jx_>q=B*F56Z&!0ap zU%qS>e%C1S=AlD}<}Nx~T3Whv>C&rLuReYHbp87EA3uIPdGh4q#fv#PIUhZGWE6Vt z+n@iUqN0J3lZ_&7n?>DSwQ7}9)X^0yR=7m1`1t>SWd14r@ay0H|DQE$)`krmj3e)w zN8TtZDynas)6&vn7IE$2!-vgnknKYrXk;_&zH-_z3463ebxhHSBnzv~!&!YcBHapcu|_wFrRxbX4g$M66AcZk{W z^80`9_zhuUVZZ+WzjW!6Thwuf=*zZI_pBm!ef#x)>eQ*{&YfF#hQMASNmZ+D0}y=BW@M@Prl*x29y|9|=NW#h(;_dfogwCsm< z_!TuZwdCaFoSdB3fB(Pu{QupT|31;{@4xszVZwy=_V%E}xgUQ2&(6-y$jIpJ?X^#O zWEyhZIQoux)IqcG3r0ppT3T8=ckZm8_T4IIe|7yH1qFq=x;n?O_2(b_Z=Cx>C-{r%{VFJF<*VQSo#OX|#J3nmUGR)v zws-H|?3P<0g|{j?F09>n&o%zk#FhU~oW5)re)-ei|NHjsGc`5cvuDrQYu}FF_}eHI=$xg z!p;9T?faTrw&vE8|1%dq@y|H(`t|2mZ=bE)btkLke_(W1SVG5yS$ihUxf~q5Z1=wV zS;eQbN)JAN{pJ6^|KZ71k@4jmgx2v%8Kb)s;C<8xs}S_4 z=L=rjUw!J!D~E)JD^j<;zVhte_V)IU;@9&|J1R=eD(1U%tV6`%CX2c~6T?D-CB9FX zd+&v|75;b!Iq+L{F-P}028aI#&P>?j$nRp*rQslO)ax^QrNK7Ty16_spCLlwfWjq6|?N@VA4bi+X!Ss^bV&{c6Phvdz zZ%kN{xW%^Pf{s+C(ZwzS-Od2bLu*&QSkz-SE3Jja)$#(fvM7s&m%dVzEW?bqE0?%P zT}xT&;LGK@!nsr6$-xzQR*>uQW-a3v_&eM5{RU}=_~<1sys&K5RS zg?EnE8WPs;J^yU=`+a|^N>4dz_eBU)%1cErba?Gm!sa-&*E=AAQ@-V$!~KaV8(cZQ ztp0dRrkp3F>m}od=pJU@8o`ZB2UUwSnP!JH@_pG@e(}&jK9yqE*q|%nbK~t&ikwBA zw`^?RG)>-VKf#XJo(Mt$4ond#rB6f6=SktJ(E_JZRw$$t?dTy6(rL9`k#$ z5Bl8oem;M1r<$C`AzdxR@|NrmL z_xJz*Gw>{6VE4d!>_){@2?hmDkrpXyqaXYH3JNkG{8+%@9y(_BVjf-SD`*^{Hs9 zkIKJaJ0@7RWGQrnEKxbzzNRI^BbGz+wnLZMNxy09C$apTG;!Tj&z69W_IW-_zd2-1 zu&MM?XlXj2&lBVtddsMKjS7c!+@(XUXM*^*^Q3((;$)b@xx{p9<06CUI}MYBmKbOs z2zB%-mEtk{JS)z+ndwAx%bh<0vmZQ}!5#ErbxX`UgUxfo`z% zYreiwcz&e2y5Z%2r^YKA=7HDtb1^JAAx=XCzAT(yeR7UW6GN)gmqiOd z`&bzkS@cv*DVM+G<8F^};*p5?YlPe7kpiv0A7dzKJYuEHcnDNiFLyjg|!7!y(FCk z*c+cXD0p|QjuYO}+8B|jaQDQ?`0rj38`m%^?%HwGn(K4~lW(K?oDI&dGj82Db?*s> z-O=uEgSir?_LXqV} zYL+d_CGL4;jK^$uwZW#zD8!S?|;GoO!W%g}Ph6RErJD3!Am$+rp}X73zgmESY|XL!%l zpl(x<^s?@TLVoS0dE8ChO&f~1CZA|`Si%+6xI=O4oELBTPB}L58%Qz)7qHo}HKhni zq=+zO9&>mn_^feHh0M1ZCJb8|Zz@kmE5thI<=8g`=y#$6&)2B8rqX2QY1Mx7T7MBmEGvGNViqtX`t!8M$X zwi5(aJlboFYMnSLS_hJmDxBRAI1{GwJaacA2ef%KyH0t|@E!qbMuD-eB8t zE{CBcNyN`&(|<<;`=5LHuPe;euXMbp&>I(1bN|9KBgbz6&zn5zfAwzNdj!2YJ%f1S%UUnJ4o2D)4S~6=?Wg$*_Q%wUL==Vf=SChJVYd*bD1_d{5b9 zz$?kYup>->O}$d!do|0#O0N%5v#wThI&y#}eH8?5AK+%X$ie%tQ9dJ@-(7&+Lg2*K zLgvO2mW_=Em$SJgu+~ql`ozZ2=q})5kAxF-9yShT#M6F@flq9pQm$c@xC)84gslUW{XN zjAZ^;#3ab)FTh>*zk%7Jfz!`Jpx8WCg`mL0@43Ynz3@ z>D0zUGxAonb+cSdXT2C^znp8mX>X<}kKd96zC@&1zz6PaIm2*@%ph-OYqOKlUJ zn9dd$?e(CKZ6T9pra<)n4XkY*lUV{M7JZm(`5}(?W|U<^+q)AjI+EcAl>&Dw1e`Sm zj5#}*FZO0mpKNI9ypnW@MdWp=LdQ(>{(f7#AIj45cIdjsF{i{HelEBSR>cWCXtgQljIT@B-o@2RG zGk25V;+X>H|62-#ToQPEa;{k`!z)k0Nlik57a8s{sXXkQH~VS8%}RqWKU219O58OO zxL-N{p{4#$&rn}Qf$x=q9upTZZ`5T{WMuwTC0V?H|5n81nSvXg1>QI^UYIDrWVJBH z)%O7>!`_4b+!q(hRRtYz5MHmTBP6H>I>Kdw7PH}eb*W(SWTEFL1*SU*a2#ML4_cgY z)nNXi#SUFz3S1041@nKulwl88lChORAxcL0!IExuW3^rLStlBrcr8u7>VE7b^w^D* zsAXx8V>fm!%ee(TcB2S(JzmAE zzD-^$q&%i+35W;?PFN+d+)I#W!$OXYQZ*k0QUzBxsLbZQs5~o5;CR$Ro`Z7RwRG%P z%@y0o*{ZcBPlWR~qe|2&fdWM~U87kusur>YuF|m*<78aNq-eZSNR361Q_X8_Hp?8r zL?ev}i@7eUa9>!$aZpY{i}RqOfc6KaYfVcS4#??VV9dKBm2ZnLKjyGSqu1n zTrH!$PX7OIcb)@gr7W9SFRo!1Tb^=KaMIijy9CyAF(@f4+~Ty}{IqL8mVn#G zxiXGMo(EN)TM6vsnz_VigTJ%~SJ&1pmlStaZQ(SWzj&w8(jsGaF46dEU#kOhysNiz zE?j>p(oFO97S4;a*(dn3JlvdL?at0H^Yh8odcOtwudEVdT(q1^vyt1QL0e#A^(HpM zErz?-F)*l$ZCpC-_l}h=8wDpSy_vXL+HekQq0&5WkF8t`ECvFM)~h)U8Q3_c%v!+cHm>JCxcM$O!=o+{)&&fwyRUUCUSVrg z_4U2Z`pLhUOE8de7klEa#*bI4e8to63TQnRxbGqlI{aJln$X0#&tBbV+vt1yh$a`q z%^RMEd%SOUZ&dL*vRblm{=ru_cQWo3Nxijd@2#dMK5Kjxlt0|sWP5u{?Cou}w|C5i z9r*qC_5s;D&;!3~@0^$mJ@EV7-#Zte2Y%nZR(lt6;P;)ockdnl3p(-pk?p-Fv7i&b zU(CJt3Vh=CyTA87fKUAX5_|s}_{8sDd++}NpZLun_khXn0ZZHiwmQ&>-(341@Z5XA z_wRv#+(RL|hazzg#p)hP%zG%c4|L$S+`oqka-fA6Dsi9#zcuDP(%Sb(=iVc|e~%30 z9vj&`Hi>&|R`=Lq9_YYtn|qJ#{ylb(d*WmVI`G@A?uo~|CtmxW_}qKq_wPx7+*8Ct zjCoI^_C1Zc_cZRF!z-@Gn70T*#&#jYyZ`=y?h-T)zxnRnyO%Ft{`vEViHV7omDMQX z?wdDne*gac`t|EyzkWS`{`}wHf98?5e*XWzV#SINA3mHqb?Vx+YxWVl4Wn*7c<`XD zt<5;(;HiaN&Y=#OdwZw>w3jG>*7w7J1n+`uf6!3sap=w0 zKmOarUpI?5_T~To&wu{kc=7+sU(nEJczF2FpFgK9{pRoQpO~1qb?errPoFwP@BR4q z|Km^p-~RsZ6u#>B-~W>)O|l8UW)pqKI^yX0^XEMy)@5d9&YwU3`}gnO(OVp%j&0bm zVd~VW@BaPw4qIYrY1z@y;SqJn-rnBC#N_Lr|K?E-9)J74dGqGkvu7VZeAq1X)UV(F zqobpD?b>zh*s=cpe)I4>E|J?(Qc^r(_pdzy+Q(;TXc!V#7ZMU;6MoS-@xrDv|Mm6t zqoSe~?)v}e>0hJBYhg)!UeU{3U0sWdi|^dI;}hQN8h?7{v4835={IiN`1+qj|$d%_W|4(aqGkw`_MMcGHH-G5p=u~yzfB5j> z`n@*}9DjA_@b6=1?xZ%pU%c$usy+WF&OSPI(c|^IKTcls>dM>yi`V|{pLDr&;veVO zO@-B~i5T1UKg7;#sd^?Ufc^Mnjo`2zg$s)rrfDUgnq!dwKeq)sw(GTJ#l&kCus}+$Iry4jD$_b$3BWD&IW~zRb~B$Wi*i zREMox+MKNmP6j?`RhB!whI7HHC#ON@ww&3y`FU3f!vdihYN|{O9l~Y}vu8bj)i|Yb z-!V_iZ;lfIJHeA}qT+RxDBwd+6T1Iwey4UFM4$o3rnq+q*kL zi(wwu|0Qnb^cA;v3jMUSh zLoWOq3@0!#Y7`umXPs+tAwyWULZF*%t-(Eq&LdZj*NZ^TZFzaSi0xy>K}RQ^kXT1g zt1BF0?L1SOqBv3_CMMh07F}u=T4>r~r6;%Lpo5~FNxMVN0>z6xtVboKoY+e^8C1Qs zjwm}BNTkf3(qs1O#o`HROXVCn1sH-D^tdL>V)`PPBIkUTvEZm0+tJF2c}%GrSNKkj zo3hBYjq`uYVTU&YCQ1{;R0A|zYM2t@9V59^t~>6(^<$2sql$>bhKXjc-)z3%W<9r< zS+et1q60(0G3Q)^E3;OL#}?k0mb~-0fcH^O%L!J}jkg2V^DthTAjfIC=)U7^FVNWT zH|^XYHja>^qKqrl8EUwg8V+~p=9EZz7(`YF`o4P=lJ54#a?2`5Wu^!B{q}xppD^pE zln7%|*3n-AQQyU`Y}jvbT<7zd3sV&XR>;J%A7FbT)}rMVUSy)pz-bin(MMWe#qfls zY`|@XfX6BV-2$6~6Z^mz z8=4)w>*=*!=g!&7xAgI5WL@8<=hyyrWnYEYw%IbADv=x(y|@3Iy0P*vk2P0@%cQyu zQZgG<_`(|wCrO{anXz&~^davP0+z|XTdyoxGuJnFN|r!4$Iala8+s?rGrQCv^yc1TvT>v?^<;(*%>mQ(VTexzWnM8jU+m85S_GO?2eodX%_kNySl%ZJjnB7IL+iC?9v=^HXPg#JJeQ zQ9-}LV-n*5E*18lCp8{2JK9X(YD#fZk7?L6t<~sBgK9{Wf`(YL1WQv(qsybq3@;cN)b_S;^S6lH3t-~4`|!N6K!Ke>;xOkw zn`TLd0}`b(ob*|om>DiSVA0%W%)l1=B1u{0aQBB+hX)&()xYez?)rkAK_aljJ;#}E z$qi-(GusIX98321RIo6d*pL!j+$_ydz{JoZ$f>HaP_lo)H`69V7WItV>sb?f!_736jKd0Y6F%ubdC(j${6vl+q0u3tAf-{}A41z31i-*D9EGT_$F_@ki0vEj6OL357Au9M~y4zVyC=us7aa?V2i zOY3n30fP>uy9^13ZZJCVF(f!BgsNFH)HqC#7HQ#hKXz2QM`1z-bApgWgo|U@0iLFg zN8IiTHjc+G_BLKQ$n0w7d~55S)YcjYwz3Z_XYxO`C4CWR_#oh+z@}8BUz5mD!+wC} zKtr$hoFopz4!4Kb85tZomhc5_vu1cVAvKagL1ZKQ0p3T943;Mt-!nM0ICwnly3hTD zx5eY%v-3W0{K^{ybu>2pcer3HpsX_UHq+16^PEbYLOhLZNdYbyO2cDw~Sd0T$yp9W$E3`zXwMm#Iu{>mB_`tUCLi%BLhPVf8O55vyKTq0J zUct06ok4*0_x0AWf>QQtEM5PPGgUq>XE5MqY!gUhYvELgy1lP<7ELm==&SGjmM14G)>Yb-4v*w!3xXK>(VP^e^f zWXt{0ZN8lMyhD9B2g6l$R^M&RtJ#@m2rwTuV60)_N)urIuO<)?(YsDVU_%7EHV2b@ z1B?6zM&Ad_OBy&A3Y0S`a-Lk$*CH0iV8DM}gJHr2?g`&{m;$*O1UL>|U{)+(+E&1R z>qh^7j}E4bUDscfvvM-TGcff#v@!fo$o6)~^n1V^Q&7r(kxOi4Qlw~C@^qeO3=B&g z1dcm!@L8~3y zmQw=0wJ|8L`ZVz7H{^CT)GrY}uzNke$FXT~mNPEn6*t$sn!$K|$y2nF(__8Lk{) ze`GEYGa+>)JHyfqtZD6Ku5FbJ0^AG>xcvWrVA;Q5O43i3MG73*7n)CGmN8G{i+jL& z`2v?sd-Guj0pSB&?-c|T1gi52*r$35oX`~bl@NdSX2RU%l`MfgM+G<<6BaDB%wbXF zV}8hQ!@%UMkd(3@cW+xsm$?9IL*3rU*$f|;d;^jf3h=xw;9tbR#nc$Tg@eIMfQx5U zJHrJ=S%&P|XUuEM7VsR)f2S$HtR}F`P2k`ThBl4Ghp%NuSqLOM%vR76C<{wIu9?F; zF{w*IAZ|ydkU@gH0OuMvfyy=(#RisxKbq}sC2SL8lDx1iZx(aLt8^woCYc2#@(!5{ z7nYc7B}l6=9+c>D;$kpLSlZ~;&QX|HqPD!rN}%ljhvtSZLFcNZ%&gd{Czj>CT2`zk zpy80ju`$u$8e{#mC5>J!8folhVGMF&s~9FQ8XsH9^l%mPL`K_RNv%?%g;t6a4OY(E z;w7xe>^iHJn<1NXBSXoo)^*=j7q4o~Fc(nG$ePcVe8MYTLm?+mZAMj>fMUVwU9%GQ zMF})T3heX};J(1T;oDj+MP}}XHIJ&wj@?@8l9jGr!1N+(9oNFOx4Yup7jT^J5?r>d z^-!14Lob2-tJaApuK#{2_U?rBVOb(9r`NN;j(_W1m~607#CoGzK+Er`Gx@8V~o+OxI7!{W-C|k^!qb;Df+p<7Aan9uJqKpxa4|tdh8O(ocGfZG|lHPIs z>UQykYV3|Xqy!o2i#C5>#8ASzlPipo=fe((g_aBn5?R&)b6@Xd2@_p@T9D6Et`upe`FM@Qz_0i<|rfZ7GHZ zKcT|i?^Y-Dd&}Fa3OsTabaL4LeRjfTRRO*UE zTEH`ek!=B^xPlSeLqXjDN6th}B?rcR#V15qnMHHm@MGZ_vzi6}U8;f$;*<0R@2mcs^8OxkriE9p+9*#*X1-G_6nOWV zQ0Ou4jThM$%7^F*tWQ#&^O)h6;+2}ak=~P7s(l3xC<`ztG@6i`$IqT(^uy52EJk1F(>%SWov;oyduA=Z^@)G&YL5!zCl~c;cBshf|#zJ zsA1Gs#oKaE&#_HB!m{wJu;C4{g}V>+2J2?;TvjVERas#7CV>v^W5*hG&fX2ld9bzb z{~CduI?$wHUuU74QwdUTd zb^l&%kbAw!?)8?q*W2n|@0j;`*S^<#?!Dgk@AUz>H;3%r9Ep2#tnST;d2debdvoUA zn{)r(T#$Qv$?olyxVP8p-rkt^_SU|)ckaEt_wVfkxp$B3-aUzX_pI*Si+S%}?R)nI zbd%$|4|4B6*}eY~_x@Ym`ycb(|JwKd&%O8Tr&s@z`@m%XfhGO}Tm1))`5(CUf8e?Q zf$#qZ0r`(Y_8&#!KZ@0Vl$iffYX3)>`yb{0e^ikFq-6g|CH|9I{U?q2pS0G0y0H0^ z-v3Vq@}G_V+rJ8LViz+wFRp0D(YVd{yyVGA*Lf9L(jS=VPB66Pm+5q1Jt=g}onLYF z#)!vf1Q*=>GM|y9;j9RI;TgVzUuOAy-QOtTY%ExoBe3%I*ZPIFk8X2t6`YkV(q%Ga zcZ(N{slA-`URq+O05d~`M(p=Fjhgd~Z9fVMu5G>d^z8Rp9~Gm{s?CIHTTDy zi7|o`zcX$8KB4~SjQKxj?f*IF{?B>;e=d;!waEV0lK5ZC>VK`6Pr@dQ$0 z|DQAW|D5~(=Yss-OZI=S#Q(ik|M$lHzqj`Pz4QP6-+TZ6K9K+S$o}7x_Q2kNN+9?f?Jh{{Mgf|1&T;JaA}Y<&|?Gev@77 zz81;gXFjt`bMGCQ8T{ODo^9sY13-b8FlJv+~J zcG%mfZMk>%wMvJ-i`iBB_TJIi;qT-2)&Bj5w#lwn*1k<9@>9yGsk-sU=0tu@J2%(1 zo=rCDOU9+8zVqGYMt#k?wl;Qun{4#A|2em|=H5RxH~M?ty}h;n+2mr7H`$$?Yu_#x z`>W*D)wS`*=f(amdv|wlJ-d9|pNdaU&(3$BANRNF+uOVQ+vVf`)%^PU_Wtqt@&D`o zAvW1LF!Q?@II@bTY;a_kZ!vJ&lTF_G`&o>A43Dd9_Ax&1V(e>rJ!P}6`TZ7SKg;J!Hv3t>KVs}}`~AsgfBXL| zCIOD@s#^k_#ra)L0$s&Zw*6 z`t->z`sjoS6AUA7CL|;X2?=?7d#kCb{rdIm*|TTw-o2YVd9q>HO-DyZMMcFOJ9aEt zvgGrh|3*=FgQM$AOiX_M{F#@R7aktY#l>YFdEG4HqDAOF^N5=c5l0OpuWj78(JcJV zlP6CK3JNTuE?Yz#)(gE95?f~xdd|+y&cedt*s){FmoLxG&NfN7{q_HUr|9M7<>k|- zPv5d-i&5xx5fPEj&Q6=CYtNrQw}?7#lW@&8Vz+(Ff$r{Zi?Hi|{`~h%SmPFb!YuOc zw_pD+T>ax2xzj50=A%cC9=-XWnVC6l+BE;znK3aj2M-?fj9UBi|Nkpju1H8ooH=vK zDQc5Vn z3mO|6ckkZa+S=+Ixza4^_Js=<-v9bvUtjMQcfmSlw|UeJK|w*6*p*+u{`ZPowsh?U zqtJ^su@8Ks`T`;+*@qvn3%mXK=l_r2{yRlowhO!P```bB^2?5q_xA1E=M=uaXU;?C zm>urPS3JU(7{^>Qj(un!y3aFemUGmi17{y5mz}eUI$BavGI#FWsHmvm;9$r2Gq-Qw zPD@MMwr!h#L~DC{dv$g7ty{OwpFb}vEBpG-|Cb;B+r=MVarnPW)P$>7uO2z|{Pnm0 zyH5Sj%F60r@_+62dmhQ_tfEi2M(w@x>VN5^&)y09pFRI{NKx#akZw{H?kucVY6e)IqTgjpANAN^9*exq*MtKx>^ zQ>RX~2|i^UdLkgcFDUm$PWhCw`WH9_?KP2HYBRdGh|_2 z+x4KBw!+2-5s58R=KT$go@pMqJG%6ZM##0myoZ|)e)i9QK5^auu=vi(X+QkqH|^TB ztA5^puh`9L4R7APdqZ%psAA&O&Ng|WTLu-Ki%(A0(ALt}VYKx0bYWSB4Gf4g{^4^) zFWhEvNR=6$GSIv{YX_G_t=HC7DEk0}Vjg~Yd{B&SIg_cXSn}y@&fzZ_A!q!5es%Zs z_jJaVU^X_Vh!yJ}9u`fN6U=C4eRO<+viCfnotsj-as>()Hn1$b)wo*k{*;p+92_sP z2i{j*E5*QanN#b!;C%r1&i-B`(7ejzke@|NcEj4^{MYhk{CRllsc?6GPHuqX z$(eg0b4A~`>G=u&|Kbo}<;2J^=|AHJcg2=@;&HR?dN?Gk`N=<F?Uw*&a z0NDqiR>tIgFs0P=K&YD;E)fj3@=%xea>dcDh9l&Oi!_6QB7-W!0r$ze zOcPR_?Kz$tbICB>8Zc@0!5tI2QaoqQ>dV>o^4aWyYhP6ygYC9V@w*af^4!6OX~Thh zra6ZKS%vmG2}p@eG7p%l&od?6xl~U?jlp7yngEL>56dA3PX>WhM~f{xo;aknY)_xF zV%e%!tJb8M+=Qd)9?d7_0c}cd83e#MBA(2E!fdyNe z7+F;>yxMXlEc@+Nwz*Y70;eV#%ypQbwPdZ6>=&+yJ2?Z*)2F60e9-op{HQ5_!IRJM zLX62amS|0um)GYs2qkELIKU!)N1CO4mg0rEOq|{m4xM34P-J+qPvny4A48LM-u-L= z2akzqGPJl%mV08bP}uXpEM^^Jo;e4>b49t90`ZQXmSzEym?o-uySVEe6LNezlSP4{ zexuXOb9a~ygn2QVNCuu{W}P$P>VD4_`Li+QZ@*qIH#HBBdT1oFVUgd}sEOMhV#6=) z=JjRxbY9YA%R;L<~_TBg2&lk(# z`v8K!#6b1|L_ci=&lT1C>n7g$&jy++no#EU^B$x4i34o+_)_>ty?zriSA=~1CeI>) z|Lvf;qK_ROK8q-wD-z+b`gG#B9cUlGk_3CE%p*n{R&urYEK$l|%IXX1pOC9!c6 z)Rktp?`=0)#X~nbdtXXa+zViQ>%5&QD zfAeT4{N}t+KQDLz2dnaJ8K(=yzl;|OEKPR48F`^2N~BMCYPzfbsf(s*CW`!TS9qMa z2xJx5yg*TQrPt9L7beduQP7NC=`-=gh94HGT*=BF-m$mN%{cdExpPjMP{Wqs8T+m* zcko@s-@UW(rl_gy%Y|w|Q@yUrSoyf_Ids9j_te>y+g#H_d9%OqRn5y;7P3m(w&&-O zQ`c_KEiTeH{EXq;smpt2JhPQ&a>%%L>)JlPewLt#m(G`DUEA_$%9?mfKNgk=Qxt!G z-FSZYjE7vCuC~d3(>olwVlT@AuM<_%D)+8hlNviqd^v|O!-9~@>EYHk3J)E&1ggG` z^ zn)j#Ud7fQg@R!$s{eSkRzg#~K@TzR6;O%+9CLVB*F=<1y`W<_Y@7{+*&TaUsb0(Cx zx}rfw?rl5L8UNvD9*OP#anzu1V^3sitK{t;$1K8DsTG}hEcZKN{*oUbJVs z!UK9BqxjPketny!EdS%?CBVXL*uWvSW>czG_0R0sf175!HEM2NvOpnmS(p5=GtW*e zvHY)UCBVU^^Qpz`cBFpkzLPp^i`v@1%v7k~w|T+dqV}dY5!zZ3TNZ7c#Mib&@j`ds zmqsbu^u`s665=x*XDTu^H#RI%>SSwM;+`vNdf|Y=U4{c3Ngo;-r$};}OR$UY_`u=K zks{d5z`$P-&@9DqM0i!+R~wsy%(53A2s6BJQJ-}7jo%h2hPh@Z6j?s8G1y2mcnO?X z=6N=EKFco&h8v6wCJYQ3DVBULeTN;?0<*O`oE7d%bm+1e@i6R36k_shv}Ft8ixp;K zSR{6052FC9B*TJpK^h#gLPBrztYy^Ko@;Z+U}WIYICSfeK!+l$Q(vP86GMoEhZ@6z z?v{c^uD$;mSQzFNX2^3a;b3VzVk%Hr5YL@*OXYfnpx3_-^R6#>c)^ZCB{ zfHw01u0RbAwIIRgw%jU${Dw{zsJ|jKwx|F133fs z?V<(_B~w@55oF6`k$l9+ki>A{1^Y)=`A2#Jx+i{e-pM%bFprNxpJRyx1H(}<28E8M z70jQz&eyuFvlWnh!pv|=!DF4h-h@V6EY2k!KaOb@Zt(Xkw9P2=~~r zoIkeNE?tp3>cNr!q9y+Srm#Hz!7RDoVavu=2X!SLh7Mzfyaja(I}QshvFEtVsL&e1 z%y5~FvFd6YYq}bTR(KtUhoGqgi%Wul|AbVgi`=i+7+j_atSJ|;EfA3SkUk-R^|^w; z)&M?3gC_qEEVr%;ET7h(#leu%F5q$@Tk1IvTVgqnW5vgEfljp&Hb%}e@q$m~0{PpT zoOTE(GcbQ*U~pyNFg;ezT*$uVLnBKd>q7$%HpO~#2La0r0Ranv_5jw@4TXyv81>o( z94%VXG6eV+a1=6>F*VjPALL^=z|qUVpFLe5+CxCHLm*pC;1vVInGcl>91NNf0+C^D z=@lK!3%Mg7l(90_2mV*cTe+Z+X<-e6Lo-WZEAzy5=7-!2<^nAjSeP7{O*Zg(a4_6s zVA#yw(y^n9H;{KPJA)=e&X)jzDD`ya#!iL{rBWUO$sM3`(jFY(WWC6~#-inD3IF`# zWoy`3SwFJyFJP%jFFzYl7^NYwqk>~rg@9`SKf?p&J?sn<7BJ0Oz|Z2?!<5)@RHJ1| zL-CAfHB5~>31#$tvIJk1UQ8WXsCCa}%8AaH0xUmANg zuVN4D!Qzt}3!}r?E=SaxSqLba3q)!N%!v^AS0V6dTd8V!N_j*-!vr?2nH9g?1&%2Q z^dw}in+%>B{Uy%>Nb3m=)wwSn4+9Fi&Jkzb0VyGp9#g;AUEH_=+-vfV7YUth3Gdu6YO~KI`LjEMeO? zouQ$xNHTMhrGS*fOs0>`2foeVUYNPhLm-{4gv&8+>dNY=Wi!PSXWe=xz{@_1-?5D8 z;4B7(*~>k%+!%OLG6lC}rtxn~4VRe3VaP0LIh$o;X2^xv+jnN{Oki2Uz&tB+Hk)If z)B;Ac;{x@a0*5T;T$Y@C`enf)0WRzR0?emQ3O=nAx*aL-@~6P6pL1=+<~?4?c|3=AC`YVKF`wJ^*KSvK>lr}zs8-Vz4h%LNNKtavXJ2y#m;;Hwgddr-x1wa{Q9 z1E&J-S3`mSANWOXE&TFup~5b~?~>sAH>(zD%tF0?(`vCv)MB%$#TK&`Tip`ZcqE{_ zaj}D!V4vs`i(^(UUJLgXFX6MYj4@o|wJXJWftkcahFT|qW>LYFtPH#X0vQatJDFH6 zeOh8J#o~E_C{7gduOI%0VW2A<;;o86_f<-sV=+g#&A?f&}Nc| zeu4&5qG|T2<;`VrIaxw)|0^l81j?8F5|`{+VQ98eD$ug7NGLu?pl#E#4K6DU(pE|+ zu4-Q;IMqpDKG!NkGt0zXf<*%rol4qREXo?7!@FT= zv=$r329@2nRwsw8s^?MCUhO9owG#Z>~o3zqNNDEFI)>o@;bZ=Uef$U-`k z_W@f(sTIS7C2ovf61z8l-zw4gftl%xi045rwhvp}qT}iXSzNsZ9_$kKUbH!|J4S0=OB{wFTGCTA11`;BUP><9G0~ zW`XPv(u|i`|3(Se&k|s{uy{t+_L*4%)3TU(s$-cRL{GWAUF#^9XW|m3jSLdpy8f5+ zSOd4&Y}Qc!u$t%N>Sc!wK3Dp3+w4+{Qr0F zY~9ST_jhcPfDD5J!w!R8H=Q&YHfXkJ?G+bYwje~wXM<_BR79n=!0*#BJc28_e_6ON zF(e0U7c_|EU{v0$z5me^2HPxw)M9}xT)KN07+MS09oQ}K@U(KM))qEF7P%azPm_Fj z&IDd4+QC}5MbqjoK|~t#@w5;_THRx_vXC6 zHy6m>T4Z}`N$jmY^bNAM|zqdBX-loDnfd3@!16Xsz@}DepA3#6vNvV&5 zhjIkgXtT-#pnhd$gGX4~iQLUeH$Lje9udBfIdY!(tmBDmXEoc2ZYb z5UVgxeASv$k((dzBiDSZHO|ClMTA?tPj;P~jol!Cgs*1U`Iy zT+L|YJx}WN(I?X#g(FuT_4vFj-&%0$(K8ctYbLL!jR?&|J~K zxj}cH6%aF5^mM4r75)47oXzWn*`9Cgkr;*4F?QSVITF1%B`SIgNujr}fkynkPZr!?d%RXYy#HIfeN-u@POxw8q_Lrak zJz^F+#9#aP|Nq39*PW6td&X?aZF*=Gz0W&gokiI0zL{qnB36}lz3=GgD4YD}`h)+L zvA3qL{qGw(*Er_>iy!}U3YIs```_NP$tCjC{)_*eqfb>d?0fY5uUpKXjM9T4QLD8> zL5KLn*F602{r|fk|4&~1KWYAh`Sa(S$DVUcI=XhObmoyk_#Kn*V+kd< z9=`d1>cUsI@U7OtN0#jPZytKfEnA-z{WSQr`ASvp1DCY`Jvf)9KR}uD<=BRJdZw+)by>y$lFj z-aP03_WkeA-uhoueY~vyuYb^l8*l!n0@_)-B&`nQEmoANnh*-OJ?THg7&YwT;nyR6pv3Kv@ty{PL z`0?ZE)2Dy_{&#S25EB#A($Wf!srT^kSh;fL#EBDaZEa0VOo9sU?K%2;&XOw*5%=b< zy}0Yl|B~i|3)lTww&m^my*JLBx=MKDTTu3Rzk+iY{@ZQgBi}17f^WAywdJL6gdfW7 zwvZEWx@5hPZnwR?y#R3nP8%!xf;sp0H$ZQ?$HQjR&xi?-dW4c+6fvcS(qZWjt(^NL%r+O{VO{!*+!>jYl0S(=r})YAjpv zs0(@(k;dbmom1T*C*btie0%Y@-+@i@$pja%%qO(J-8Spx(iv&s+ihRHEaI&}x!rcn zHpmG$TCdk^xt8^M?T%-wUa#Bp?bYk`2iUaVY&as8{bu6{wbgGxC*Xi~Noc=?jC|in zTm5$1owC<&w?BYfMU?$+=Zh|Hhh1;7cINH=5cV@~&le}l_wm=Su3n$<{oU*J6aW4L zk9_BRILM*C=EET#Woh@r0`58=kC^%8d^{?Vz6Nvx&YO?N720(^olu#c^Xa6<@-?4M z>1==V=`?uc+vIxA=d%{i*L*%_^Zm`|^A69qcwTT3f2$(rrtUja$BX|955KSb-|Gxa z9=TuRnL=v6UIUMOC$#H+yJ6~BAi$oo{B0<2Sr(=wxkCa)6QZV4{Fbeutv~>sIyo6K^u{ z`d;AUU|7Jwu$wu+iBn@iLI5v|CgTAmh640iK8E3|kKITNOAs$|wr3#WYJZoN&@- zIKaTR=KwoHLc9?}0~bRGGlSHE1}>IKt%oNzDR3A_vw4{dXfP-UGVPT4!tlaOfa3`h zw*r&G|1gdQ79nQ^!-z%}6$Xa1JxZ(xem9x2JnC#ZvOsu$29q`e!=a0uPehn^wmLY3 z3+P5LGDy5&a1>Jz(Bf&SwF!}C@=!R~D8kr!cLftepMVzVtd?m4C!|>xu{T}Vpb%8i zD8G@BL0KS$%Y}hKm1PqX!PNtOQP?-GibGCSisGYz#{D)$m8IX zr!ZH5=?PmK)JmeS(yctvuDheHFHD+L7iwP2DXi0Eck#*9hDJDrl=t7&roeL};JWD1q zX{wtX75mT9gQ9Cp+@;F7Y(NkL)7Vuz9d z&J?Bt5=;{pFzT`IN_rQZ!^F`fl*7Rg=<#?8TV;ci>>>sck0$n%DJ$fhOgpT11u6t8 zoN!&dfr~Atk(Gf%R6&8^kP=e^*G`lBo`=J>tGf6poDlXfes-bD)XZfTQ=qbwQ8~Ms z7Bj=b6R()t1O(fyjx+zC{c1_mgoZyTCh{w#LKgDH#(-lyu` zZd@YE#K@@7)AHY^Nio@hBZ-~8IhSdHAVYwwy!FL)fh`9VeF}0f?^`)Rlp$H6O6P63L%C^86eFq~ju z2)&%F=R0e{Tcs3%w^xoh=zL%fk$SR5 z?3QJ?V%_Za{~`aEvx?E&O*U3MDN>>-4t(;~Y=#|f%!LEgFr9`KSOxf8V8$zt&CR~Si}lg zx$4v>2)Y~)z4DKdVN3hHTz-~{gai!+hrLk@5(gN{SPyLEEMks%-*bUgFpgD3sd?AU za7HeJR!tKJ0X~~(MfME`973uaUfe9d$ELW=af@5d7S5EackgB%c$Jz-mIAatp|6e!j`x5iLYp$-XVs31{R>p2K>Gp93!S>7386UJT zmsBe<2mEk&;5DI`c|rY6?~c8!Mh#pQ2@J{-4l(RaABy`A+!CBowZid-{o3a?X}kWJ zxpw5`HBGqtMu0#5P(NS8f@+4x%$err*o7G1vew>Y>O8=gSNm=K@gAN@y$ui8?I$kK zzVljs=I$zi_up+9?LIV%+w@4>|6wz6p$PLy1IJ_G%E^|s)vh@}7jIN`tV)AaLyo>~9@ zd7*#bm*xI{Uq%1_bz{G1#isLr-&Ozr{ea*8|IRj@e=8i1s^n_y|8+foQ`g4-e?Ro^ z|MT4c|F7Hij_>}T{VOWQKY2pE%HQqvnUCw3P8cyt2u&*FW8Gogx3PimM}vSwqmV@- z@weLsi!wZXz{eaYx0AhDEm)r60N)2jdDg;ai-&?19D2420#`N)yIZteOJaJoLGqaZ zJ0nAjSB24kb^ag^fxbY7|K+X0FAT$1u-zBn&kATsJ0OyIq4fZhPI;oSd@0%nKA zSqs>DZgfZ%x4um8d@`w%cVWF4BljE)fm{PVrirq%R_Oe{F5D0y&|J|a7|g)>ppz?+ zE$czo-J*tV8ip%57&gs7z1?<)h)Kl|x!v|Z+U>TMQ(PjUx7&K{oZ@qHir>#E0g_XL zET@JoL;qaddC*a(ibMEJy3zBm$StgM$W zUk(ckyL$C%VPWCfvuBqqS@QVt<7dyFJ$m%$)~#EoPMzAYVZ-$4({JCt{qNtunKNgu zSh3>8ix+u$d3WyIxqtuu^XJc(FJHcX{rcUzcON@;Z2tWD*RNkcbm-872M@ToxVCTK zo|To=)YN2eZ{OS73)(;*67uQOrwbP@Y}~l<#EBDo_wJoCWy^ z^Z#4V{!d=|t7G=PBUk>f-g58IsizE71?>MD7@C?}THD$?I=i}idi(k(Oq?`%%G7Do zXUv>6dxq|u`3n{J0^+k+_QJz{sRXO9X@jO z*zpr5Pn}*h?`X)GsX`aG>0h~iOq!XsNJMqXc?aJWl$b*@IFZ~XaHv8T7Ky&abM|338O)kTjUfp_P} zM@CA9ls;zPB%y!uZ|s>J8y~|~TtTkD1?|oU_d6jcuLiG}5&=KTiXLGE2zMCsTdhET1Zc3N<{P?t0GP z07FO==d+m(U7l*w(-ysa)|WNy<ZtP+8a(VY2<7?!c>s6>B771Im=>;9_XyN znAUxN%k{Y5&o|#{)4soDdtLY19WVB|uUq?ao3#ASJz`D_?Av!`>sNgc)8^Rm{hRc> z4fl**uieiweY=k0uTRk*4qX>yDA@Vg?DU5tcM7%F|KBH)erLl`j^s5TkDo8SnmP5$ zJL&a@6qeiEIdNuI^!if<>uuCdGV#lNK6_-ZRQ_@O$8R?0ZPluJci!c;n8}jQVrxtC z+@+g7T?$xz?aNVH_uSH~;PRZeS7SC$`>Nnyu3MHKKRf2@jf~>3ZD%vVC$ApY{eGw9 zdM@PT)q6GH!3(ZH2d|3f{dm}+z7BNo>boD0Cx8!L4bS`ew70nNC-mUecD-LOmQ2sH z%8Qz_Zdc68_3w5WB<%rh&R=ip20D0kcUIz?ch`Ro-o6BM@M@kCqnLKP zlaoto_cCE6iQ^u}jAni8$?#b$bscu_>SCGa9>=Y2eeA0^vsmtX$5OEg2bdWx92nR< zPcQ@|v8X6GCa@GTNvAbUn53a1&n((#$g04|X5hfeH-UkhnBl;v zQ}9Gpg_9vb>(GQXbC%50;$&d%QJ5@x!jUiJ0E36qA*SS0iVRve8PeAnP3v=5rgQ(w zo1Y+~Yd zIKaUPbRiZ;X11OL#yLCGRL*st)6RX!Ch_9rEG?xbMiT|CnK2ED`~@A= zObYWk1k@PZ7#JGFl2}X_RGI7*IGn4d2#A=rxUxI?#fyFMVX|m+Vohw6T9M%6rqIN! zwV{DoBw!AoK_j161B>97k_k-$OU)P^E{a}R!1ndb5(T>iMwt`_ZvX!c4KBeuzshj9UOyIBGQSB3*~h6RWCov-V4DjGTX z9By>81q-k>uyN~6XmF59U^Sf4v{Xu=LubL(>Fg^Q83Y2D1m7%}o08SQowMWG_Gw$T ztZ3Dqd@VAFVZj1Mt_>n_>Ob=Mx1zLpD7?^MHE#MIKU{If$CA4mlgR=OF=S(gN z%l4dlz&J(LK{)Hed6pTiTt*TM!g35Ojyw!(iW2Hs6RU206bjku5VXRSSAZ#V(j)=- zh$f~v3!1rV4lrmM9GbD>z*QE3@Cj@W7~>>g2g~y`uv*^mWU~8ki*bj8z_qg{{);qy z5SCJTz@#@pi0j^}u=r)$*6O*wpOE2sf<@#&(0kUWoH|n*StSlE7Hv4l(DcBQ?N9g| zrZ5La28LGAJE0uh70U{EKQyszSioRi*f1rcfklep3o~OwgD@LI%Y;eW_e?O+^**ni zB)74cp>1+q^auL=ScwuPH{)My>*n$jzq*|PTy;@Y@40}OS0Zax9pn{UHc>$Y&za@xd|{l zDidL_acE#V660N1w?Jv@nI)Ve3m9ZLk}fbiII?Cm++cNJWUUZwjF#S;>XBV}$$r(6 zfaA#;0NN`|P({SXRrQoYF zq2vOW#zBsttOgc`gUoqy>%A1;W~40NeyKU(8^Z}1hIvw#m{cMT#b)}xHq4y8!AmvO zzn`1om{lc)>7-bD&SU5kt*NCrS5IIuD%*jzS@#`uU#Xkz1avg_e_OM>9sRSG{h_Q>NEG*Ug-P@c^q}lc8(t1fGP0`SzY25%wP*4_p}oh;+qMiwEDU`n9_zN(GALA=HPkW+)G-^> zeP2@jguU#AyK?N7Fy97-a0iwNPb!%=Fbg>_iWM+hA7GL+W6*90Nj_B1_@F+wwVYuA zi`E7v(FY7|flV9A8WAyW|cyW)m2~0u^jI#@JW@czSDoJI!+U0sVafU|s zW{H+Em%{O@}b z(f6#P@2-U#Qv>6R8-4G7^nH-%|76ksC8D2Ef#G0>>yM27KR5dS{pe?qoWK;>`(uae zZ;J^WGbeEEoWOH)!mWr2zcd*5EGLRYP86%0$jCV{ykvsJ&53e9Cn`uzy0Btm*pZ1! zm6J4PPST2;sAB2*!=kun+ax2)$tIDLpWm1i(9(Z0eX`BX$#y>{pYNFL`(=^?q}!=E z#p}pKkq<0(3{1uknDj3&{k-0<&cJv&qNA&2O3clv_A95jZ|P@S!0f)Em9Lytjv@8y z3}*Ic45uO(e?6I6WI0`%bDGZkx_kclNfdt zw3y=+!#_(8&J7F99x&QEu*?YYxOs)~(z5x|QS(%y7Tv3uXRE@%x`X-T^Vz#JtG7&N z@ljAsR${J<_#b7lfhDbyRV82{;{?X!M+`y>Sdx{Z4Gr?wdbTkOFtvVRG1ySZY{2}+ z!{gX;M)?oSvz`~|U1(OjwKVQlkH#wJxe+s&9hjPrFg*O$Wp~tb`V)prAxyb#489*2 zBCS|ke|oYvuwH6ma1>y5XNWQk@NlqVurgTeYrwKsG+O^c#EdD)hte2$8uFP9SOp(2 zOO+?6U5HqC-A`&k?d_?t9XoR4tyV3G>Pf6}W>R3ZZ3yQIU{zCKGGUneO=YHF8$(b! zi{=M^(FM#p4aFsH5t;#u)fK|H6&TN!GCxdXXgTLJF^7P}8D zncEnaTnoOYs>*v{QIkp@dqa6q$C3kP45ky-Ob=n^xWHg|!JFG)h5LaeEuwj94AJ%i zGp=?qG>bBLd}!?}Wl(Nl=DRxok(Ju?pIyoeR2RKkXYhOJhg(iRR-~B=FmBma$Q8h1 z@gb>MCBs#U$@6)VVkv{a!b9tm@|i=;6B-WGX*!Bt?jy_K5zgKgKgFgRaeFnUnV zu29Q0frg^Vo+O9 z+u}CcVKswP!?H%s1SW?W*M52mEMW4uz-*Uc`J>dpGw4rd4K) zvQ>=s0<-xon zWWSNzuc0&R^K7TrH_97ldVWpwW-MT;{QAGn!F$Dj=|HA63@m#XBt9&!dBtQmfjLBB zrE`HNd&AyYuY6%1A|TibM9^L$OR1UIx${89@&2)18O`) z*Q}gAg+VNhQA>c?xQju}AtE%&gJB!vG@)b3dro@J?3cD=VSd0e+a*HqR4#J>Yk>{( zqfq}w6UJ#xjO+@GL5J$CS1t}L@MKJ2p7v;3wCe6RD$Hx6*Lv?d*1RQjSLH6Q2h8Wp z3*zUTob%_5d*m@y6$X8V&c3UsAEj(M%zm6>0n;q6|0T*3V%;xzo3}EQ^BfM9iQfJu zc$W=Bgr(oNDeH^`YNs7q(kaTUp%B<3Hd{f#ui)gFrL4y;*j$Kzc~bQ!%dB!%+uxqo zBAKmLF}$fb{GDrIqe*_wO5a}9>Qg##A^|Kxo6fOKV4U{p+&j(l*PfhWJ}`^zK_$n7 zY4)e%l7&{xDw)B!cOFaaWi!pQDk_W;3JKF5F{w5%CbTjeE~w-ZSW%F};={nATfnHK z!1(KH?Cc{9JPXt;CoqXlnD52F;!<_`k;)}zh50)r8Ps(BH1;w!ElJ^EVDWI6&G70X z^MXd!>p9t}3{1V3D`Ka!*}7I#GpHP3l4g&R6=!}NvPZRnwS4LSgB>p}HLEZh-zuCY z#3D3-mBWC=VC9icZ9nz^PlpBP|EV+WvRtvT^}ye3U-@50&E{TTRXfS*uVaO_pXLYV zH*SkJ{bUkK@c(n0fpY~@khxl8>OuQz20jL+CS4X*0fy$ty^ln;C&otc1YBcRIHR~> z8M_0E+W{ua(@d7BzU&T+Th!*2_MT*3aB_9*J&BvQ`AP6D7WvH;$2QL6Fp(fKuxq>lW5bmYcE zgSy8_I*%n?9;bOQ+D>4M=zQ$Nx8JJI(Z=qHhusC&I>#R~m{>nN36OglG><9d-IJiY zrxEazS8?yoPu=%Ktfl`|OFw9L{yIOGfaevMyYsOvxa!&G`e@pdS@W)QAILuR<0UOO z=l>^pcRpz=uCVUT-~UPHK5Tcs{b!T-&t~VcZ`gTuV250 z3~ncg?IdkUp>C-=b`gHc}*=5U??b@~L z&Ye5kw{JI(ynFuq`D@p%flhe!_O=Ya+27x`=X+v?Ck8cw6uQz z{{8jqSD%P=juE?^qAuD-p0*CXXcKuQDJjX{-@l@wqN}SbEiElPJpAOzlZL_Pd=uAs zM=pQ;+0%Oty<+D(Rb_hf9v>b&e5kjIy&6k z+<19;!;>3aTwLrT?!El`|J>C-k6!|?WtadkS0b zxrZ&Cy7u?s6ED&#jxOH)f8x^r_;;{@$*!48)(bSg?=e{` z_SBY@mzM`DhK%p8j@X=a_te(a*Oxd5w*B=&URE|y2{yc60oqVKU3J1f=(4hhi<6Ja zwXI0p2p!(Psi0`oY57ZtgKLAqyqU_s0%CSmqe6I98p`ng!tz5qEFr`D|NV7i5`P}vdVF>K`F*z0PmTT` zn{&`^-EYXUvX3_Z|1(g!tjxs8aS$vkTfU%8>(z=S)3RQzglwpWE-PD=k-X^|Y+2b3 zwL`DhABcLAz2S)1=?l!q)K=>_p3r-pv+=B*w(k0ie%Wu=UX5F=yXI!z>$j`!)@iR> z`LGYPtZdopce~!a+HrTo+hf}A_k6jQ{eJHc@WpE1UccYZz^-G^%*+E{R%ZU@17um5 zNO;c1H8U@AHPnlj%Pc-7hq|mx_?z&$=hwpy9 z8j-#hw5)9H8p$}&va*!v;EUDPe!Gi{B_dqCqD#Q_PF$#lpJ-K#NcrL z(+zc&GOw%hC44S3CM#XAzo{S3?R-~W#maq#xrx`$0&d0w`nlDT5# zWc#DV@g4jA9Vht}w_Bh1Ec1z@^NwC4e`Gx4Wiht1swx%YjBQSz0tI-O63Qb2I(XDP z4z*=`P_Pm3&=yj1Z0QM52-A3YXAR@z6DL2kF*&;ai}|#xX^LX41y7Rq|Co&v#JL1> z_h%cYECep|9$^+bsG`RDiQR2kZk2oG69*v;&*p};tfn`Y z##4f(?YPpZtGelQOdPL}=9LcJ{FkTi?A$oxgh_|)q?0~PXP6mwW~3P(Rrk%Dw0PEy zC$sD}MT(Rbe4hP)XSv03&vQkyKF@jKv)tS*K7WFX;{Ug`NAPXVS)}%%PQ#x9hV8LjguPA ztea)~+HsphbbV>ls_6pnyci3j4#}}FtqkoDlUNnW;Gt-CEjMpJpZ5fT7mN&h-ex%! z+`fJ+KuM`d^+fgxg?kmL*A?^=7#S9MO^|0`U=$2=l;S(ob!^ST_3{EIBrUve*sWk< zTDn$$|Beq6ejBxjGI<&>EPKGvJV%V_)5HyX4rvPrR48ua+ql6ohMViZoZn>|<@nV;9Q4$)R$F*>a0hl$F3UriMLPbzk=w ztWNSPPPurV@_c(*~w(9QsrFbGEd%gw(7Jv8*^^zV&)9bI!%PPaVn|8#1pKg(<%IU-sSMovncA z`acR?I~W<{q69+tSuEu2MRqG5`qXs9;c3N~N}A*MlW1cEaH> zCxyj{CobKsEo+=0$#9#o^%#3oj=pRY#@E4IX@R^Vxd}LSZbStMB*)N-Z+)xN&aCprxB+ap7_7|Sa>KA{fMETiF zSBS1NWJs$PkVbPB~}A#_;BP-9#br zkL3c)Y2hjj0=L=)em@rw*}yh!dl{=?1IrKfQ{sZ`7J`;+f=k&1E6od-DjJ)LDtIrZ zW?jo-Zmi^VEP3cIu;FVX+eQ|b2lY&X)jQpqCQeGOUYgdrp>Cq8fSbDjYj_pAVDq1L zfobLyRx8wH&1)<+gs(AZ5nhqFDxgf_gZL^ohG>PDa`PtUkInWg>X#f7;4v3qJ>KHG zLVeG%24N0{gVQ9UA2hKP7D`?$zt<{Yw!N+X6O-|UB$mK>w+NwLHzqX?0Uh&ffrk}b zg5}KrA9n0N+TOM(!jX-EN3?d5gw&S#q%=UC{?`_Z|`qRZN`cu7UqiWyz2c62>& zsaf-*YlB4hCX4PZ5#8G=x_8Xz-nFB9&kfXNWq8N;Z|&&4gBah34)4F1(f4Xc-y787 z{cjchKW6m*+JQ8@Z#jV_aspc=VtAkL=L7-Ci9)d9eTkV9rFKq~fer5~Sx!=koTLUB z-rqS%=jJ56pOXwECqst!%_=8b92^SE$}-qf)dU$QWXxKTShwb+i0hA84?#YuU z*RNkcfByVw)22wryKLK!CfuyN{2Lot@o@ z6DJ_Ycr9AAC@Lzdw6ruaF)=GE>(8G*_wV1=*47pg5!ttIUwwVOg@wi3xpTK{*>d>s zVM9a1pFe-jnKQ@9$?5CYua%XRZEbC-c?(3=FXeHV1e$!B@;B3VyxQQxobE2s;x6;&z-+;@zUih zSFa(h+IsZ($4ip+zKZ#XwkuBC@t{Lu)(WM1jd$B0 zb$|UEaFiLmYKzOI_yDuqfftWc)Ey=`vN1U*9GK{#rrGeH^&S6b5Ie z2&K-a(<0midRg3^G@s7s44iO?C8U6nLEMvLf&=@F2F->UDc3x2)PC5i$uQ^o3D4zo z8~(MX*HwMW?494J_Ud|VOu@$cEUiLCN0)TQ2p$t{3P^mZplb1FHr-KDq~L|wCTPB6dg<37M=kW$bvThhQ_ z{X{VXZx3e9GqW3yxM;885S2(_aAXooU^uvk^M>|`{UO{1sTcF&B46(jJP_T%p(Nno zAtV}J*?1&c{=zyg5&ND(CM)hw4HNUC3LGyRtgt=7C=esd!Ypw>;Q$-=7axy(oE)5` zQ?(ASskAdX?f!XQYlH#=+oC)MX6Ai;1*KO-IX10hb({D47gKn2Lza+ejKG#l9d8UO zm_rP_TUp$yW}eu;O8r8^B~JnSj|$D*1%--C9SM6B{L&H{uP_J{G;&DBG;IH`ApN3N ze_CyPp$c;zchYtSaSa`t>-;JU)kI&edZ6}QRAMLNL539#yNwR)J}W68H~04W=Q&~y zcT@X<6{KC*g{C(c{5Vy*sQKXA9uqsK1wIU$tX+ielj++tV?&R#k;Jt2E zxPSx)!$HS}gb)QGHYd?GWyb~0PnGZf{9(qynZVi5q~SP`=X%3x%LM|S8H;usO?T!n z$V_&Bb(?Yfi9VKfFQc0^rZZHzaLh|p;7RflXL0iAVBT?>`J3D>0lZZ)9o{WV1gLt-%?nr=-;sDYjv;Lf8YfOsORH z-^%g&{0|$H88=V;aOIfx!3vA=Us^mj&P-%sPhZcQ<16sX`#^7&ixJ0yNim5E4NNi* z7}u%>w-y^6S>hGIn9})f;cv^tXMO=4>?ID91P@CoO)}8;&NJ?rDZ{dPl0z%Ahy$Y> z!(+$#;531O!Rz)L zHlaqR-FzGKRUH(0j%;UEH95c>G3y@Fv#U`I3*JnbC3-vE{&fte%#@7}THBHx(>n}! z@?t^`sA*j`UA}^kscfdNQ=z8dPVSrq@$3uqT#kk?aIiew*D4_uEj+Qw@rxKkSkzJu z?^&m2IvFk%v`+b-kZ5kpB#^n9d-a?vtF9gVP*oxQc+U@J&aFqTevW|SSL61`Gu(8F;q-YwbGWK zI=x6v^L?8bOFEMRr&dG51l1Q7(;ctRcJ^ja=M-#Ey1Vh*4xs`jqi_Zt-B}kG9o@8S zy5OV4ovSa3njB%#jpg{fOFK%bLSmhYS-7~`y7;N+iIye6K80Cf! z_HKJww0co-R@0SuOxIpjbD7QHR=}XuvT*Lxlr5L#3Rp8m8yKTMCo3kM-S?oi zF|o<}z`EHLjQ{vHupEqT%w*QxvN(@{S<$EI(uvB(*}E?KdMP+8SNh;QiPt=Mmv95i zuUb}NakG{U(aHN)Ixz5bIFu}8DPd}wz{tL)fkDpV2@C6o159tME5ZXDj;q;n%;UV> zlD8;$>dD-9tK>UYdMc1cH`KaJl(75GW?LGPFQlboYO#gTEO=jc?$PrSSZm~MHlhLx};7QiTO$T#N zE_40$i>oAEWm|dztC)qXx$=Y}C00jqOg-;4lhIh(nx`KRlBa1 z&*##2I_0rNJoJ9BM%Ko^GZX!qWt6-EHg4JXa&F6n@M%UDb}=uB+SvAiLFwfbmY3`E zRzEq?aGs5yu~==XzDcM}Jn2Ez?^jv1wV;R;bq>bdSknF~HJY*lsg{@#+}!4o)x zL;HfEdTMK45uZw^s)K23RXCU5c4k%=)?eRCQ+KrQEofsDV+=T4GW}}X^ACk$#!Oxt zm|0aB%tN_;Jyw%ehv=!WSH{337&t@oSeG|a+c9FioW-gz{&aOo&2g^HG zWpK}waMRz~+7`gXWsvhcfJtZrv)~0rp#z-@6|{K`m;@KFEZEd_q=I{GM9&Ee@#8ak z&b$yieWT}sMDHbw-YXHk*D88%%;-h!)xlP6QK4IxDVrQHQDP;(_{@o*Zk?pC^v{XV zZXKssYQZF}l{}g|F}ih-UY%vH;?2npl2e>;Z5EOg?6sKc6*)DG+|5F}0u$=cHVbKT z{9yRc-SCs+WdcX!h8cV(S*DP;Td0#)=ECfKKWFb3)&~0wz0l&MTH2*M4$}GAP`+ zIkzil?vc*yJsBJ?Bg0<5{p~*^!v%)JCq3mZu&5kh^4-8_SIofpz|8rOx}X7z4g-U80Ru}zBI5=I z?f?eu4GfL~tU3bB6GIrZUd?N|z$kx!$)>lFJOKDk=b{H_NPzG-wjy~ z-(+B5Vqr^QN)cgnV^FY6SSS5y5rY6z&gM->qA28@8FoZo|;K7&fr%31Vb)Si*II!N-6h&S42tH-nx+ z&#{@xh6W5A0!)3s7#R*RU(ovRDa*z1uZuyjVEem|EE`uazH3~ZVy$?FlOcWf>a#1i z@jYOWTrk(>z-Hg=d?pum)W2Hd=fD{3u$5I{tNsUh4-F$;IIO z(g3*vc}s-?RRtynp*b^eD`-eFb$s7*K3i*&$u4FGro)~~ST8JNc3_NJz^Ep`YVXCQ z;=s7;7sFxCHIrX1Vc*3N`&7=fK*z#?Q9XcxdjW&OQ?tW6m+?PX+IE5Adm__mZAA@k z2llE3JGOi>vc-EJ!-Lfey!Htd?5ldcg*9jYG*cFR*EMb*mWW6#`jyQf zvSD-U1_rSOa~Wg~@HB0jqp~!pD){h8hWC#DnYd$?NH-`LUtl$MU=Cnlb-8djl!0N7 z6GP)GR*9MgTmeiH5BBYGTBDJ$f6I*hhgUM($~+Xrs-S)55L?rxmVg6!#jIMFLz@x~ zw_I4p5x}ajb=|2)##{l64OItUb?=vaASdI);F`c-dtqVM)8%{%_TRd>pnCbym^F&u zB^QYsGe{+H1T!#12W-D4%Frvl=!oYQON05%3JeUN7!S{6eRpw7=m`@hQ3kmK`&%zC zw#1weDLRol^+fldqnA&y)J&R};J|DYaFV&;Wax^M%m+>~USMHxV%h4=VYOhcXw0cU zl^iQ<7^2sl;yrZgGz&wQO@V;|hns-W5l@C728Gy$)4O{9*UsW$m=nXm|A3kK0h541 zj=_ZO{V@zDbWX(2I(1G*agB|w)P_|i3=C`vEb;=3ybX*-4_1aPSnNFe^lGory*YCf zKgj7RFuzM@R1;WXwt(sI&vU1A&VN3mV5r3*@j>pp%wo|COy_UT32R`?*4nW1%<(HH zPw&&=ut}JCo>ReFfaOT$#pf*-C36*|_xjxWdGYhi{iYL+|1e|?DA1c!vtU}yh1oHS zQdOD!9<02T$*jwue&i>^0;)SR!5IuwPlPJ=aPT`AX+3C-A^w=G zUctjR|1(NWV0FL1tUiHR=0f6*fNQ-UuC}k0VN_t88^!T1aLq?|?rFZ)rqtd%A;=)6 zAn=ZnCHexB6-;^sdt@R(tA@`U?p<_lcU2T({|Rty=@yEZg)7`+0HA& zw1C0GVbinlF#W4c?+RJ++j)+7b|3eZVQN^+rf|1CVL#UgrrCRVZr0pAp~xU(${-$a z=P)PZyF`{5H4C%?m}MN8f*z!cI#^k~V*F$q!+XG@`xk@r0@gqUrfWMH0}n8o8pNo_ za&R7C)>*))n6Phd3#0!Q27`vBrXOxTSu5?Uz;Wp$hoZnEds)U_P6aatw#&Th83b6x z9d@!EI4Q-T!1LihWAC4pegOx0AF#apxKcM^pU5qiXFeQe2N<`jbF9CkXZs;c_re|N zK52*7J0#4`Fg~&CUJ~G6&FJu8by5R!n8UuNuAJDfb6o^hiX33+%G$|%fz|ajbK+|` zjSCEyPO>;X*!aDXl`mm=*(z4{Z7i+@Ynv`GnTs+v9blSf$?7Vwx@iKl>%AvC9GUmJ zUUuaQVtQ`YZ8b;x0mH}BEKv%K1vX5_tr(0RFmPYk$M%86LV$&LgSK|VGra~TX#obV z4UDI48Qdl?B|KnM5@&hj#i)2;vtY5jeZr2#^B65Y$SH1E*2KqPeu3Fwfj=h$OVflo zJ$=#!57sgtV35;Vw1 zDF;U80G4j6rK}ei8od}}7chK~W4k@)Szr}I?1gA0gPfdh1}lSCj1%4jAIN+3XRg(P z1()Tdt?J$$TJ@IY0fT(NF4GT;4}LTHJ}Bn9@HC>}<*y|S+6t^ERxu`C*vEV!`Ed}_ z;&qJsPBDAkvC~grFrUD9L2Hfw>t&H2HZd?TGF)I;ypG|coI{uagGa#2lX}eU8~8jN zK8pUAieyk&E%MTJ7lStgg9yW_6IKl73QX)9E-(i$vut2mTEY;Q&#;)`v&;j=JQ;?- z0(r>?TjXY?`EA&ndF;5Q5i3Un>z`Y;hduu@EcUC^E@09uV3|4jjpKtYtqLq6ADF}H zzpf2D!?qydRV1VL1ST8)Ukhe22?{VcANZ_(fN9nKUn&O}pLFxTkz?lZpJQ0}HfGoN zOI!!9U0rA?v@(L>b)E6yAOn_&ET)#<4;d!BDNl**>0B|r|L3ZSj4licQ4Jg=(rZi@ z6s)9JH?Nv&F7R!^tvT!N?mH>Jc(s4RQZpB(8cYyPv+!VWc(9>hg0aB^L4o9i1{3C>|EA2WPA*HForMGrFeC^V z&#hg`cqU*$fC0yXW`hj@4RH<}CL2N>0wx%+?)fswmHDV+go{NELjbQJ7lYlAy;dCt z3lFvONL$r#7%n=}DWV;EDJP55k-IE2PH;FjOYE-t%VoCa z#>SM>vuwM~-Y)0iiI}puFoAUuQ=z?qq=NE+MxFy6F`Nn94i>w3H(lLRrhVYtyaz}A zNA;aO6$k5>u#vroMOXGp!+NLYB?0T)XzPh?5dUqYKwAlY1_AoYu6^b`5 zbQx%?{E<*#%V=eP)5owv!JMIyRk`HF4~JrgM|D<9tFwJxd~7a$agFzYlfr>^M$N1O z)`W$3(w)L}Q&7sWkV{xAySLTu)p{)+W!75BWjFBb*ih+qT9}WnLNKA6_R`=L&$eJ-TAknPr?4`7> z0=|FXYG9IOP+;Ye?#T9NReiF_i8awA zp^;0xM?qZa6l=l*2z)bCq%Gi`pY=Z%c@XUlHq?cclQR>67S^1EgCd&}=t zy+2!iKYlk?#e*h(zlw)#@_iMLy7bRgJnpmSt9&xa->>rNwD`WtXS3Mfl|P@idRyg- zMg4wNFPF{lt9rF+{kdNz^Y`;vM>25;RKFEJpI7~Em%T~#>wW+EYCas|_pkYQjJ@Ia zyHon_z1|B>ooQAHQ#PcezfQ7y?Xw-ACLO?TYkGezki?F-O1~|!{Q75EIxuPpG|4YGz|5_&MBV=7NoTd9Df!Kf z4C_vKoIW#=iLK%Eqa7Ze0uD=AxC zVZr3C=BIKCh4`ZP6->YKf6X$^>Yt}``f?|>oNN$T(%i~zkidMC;UZhs0VW}ng$Ab@ zPcbG%sxp}jeh8ztB=FJxx zgnAxan(o%H(B|#S_cB};7lipPGMW(JetP1?a*hM62NIb0ZZPsF+Azo{-+gStr@+jt zz_9f44M%>fU(M?;DKGnPM z!w}wh-@uXCh0}p$14ECVg$BdMKMDU^1Pq#HvM6w0n#pJ_&(In<=YYZH9gVzfB7M9C zBKn28YcuuDukTuAmbv+~w(``)4ZKs5*(S|(<2bkFD7#K77r%p&&Ed~CT0%=1;yCUk zpYiDJ%UhAb+QAUaU3BY(*Y?7dv1?27)fuj*1u_cG$jxO=Xq3A0fboBcsJGyP7NI@G z{ZT4Sxn=@=Y#ruIoPX1K8w8tP>?x6|C}A>CF}TaXJ)_|2-gS*DuSV^SN@L%A^r={^ zYBOWN0>($bbQ$mL4rTv*ecOSIrn*iA=kS>&49XH4I{jlFFt7d*$yxW--rb;EGGhmW zbi)CGEC(iok}ZttlNk(tbhz+b-adzM#`9j&{|6Y$Boa7&9c^2E=pbXln=eN~=H+#T z_oR9h8r!hGaOhclGM<0N0rr`O4J}5=(prKCnCn6vCgfgb{Acxm*DIS<)5>FS)gD6$I`S<^X9%;CCU(Wp=DjEKX31g80OB|MsFAlG9GBL2Z%B9 ztO~N)b-=5vsETb~*?Pt@fd=g!cQ5IHeC1|^xe6wh1)H|$zUS@#1Fn?}_xZLTEVg`Cq+OGV** zA7&h1_VE1-3xlEy=kg7g}U~DEK31&7Kcy>>ocA=C9tOBEjer!oV@(m%h39|DCMm6DJ6K z;%=Q5(7Ev_!$Et_1g3-|KV`We91u=3WY9jcfZ>MR0f7lO7M{NT=loHQ(%1Xz4_`lC z_a}K~Y;ux@vsfwvlVHXf6PbiYo+&$=9xF{&_58utV?8IHYl8!mgn{sv>AW9Ve4|4A z-Yd8~Sl*zjQupL}L)=D3g-L23Lrh}I3RS1q9p7GS>62C*he}$Fi42zT#t?4K1<2e4e zW&hw3Xlcuj$j&;^R=k2MkE6Z3BPrayy;{RMvAw(;ug@ zJ;-48{6F!7Mju<}#3>341{1=W8{A!;1KBpP&ODrPAZ((#r4{SUiP<|QR=P6&eG&CR zR9t%llXZmRytF2xEezI`jdO(r%7gRVu}y{ z2L{iBF-^{`q7~jB9GteP=;bYAc<>=sMuK6Ric_JZ@q>isw;hwVmrc~>oWAtLM4@Z_ zE(vLz0#3%241x!kEsrq^Ciwg}k+62~ubRl9wt!Lg00To4Lu3P^zy(H6MMk9wjC=>C z%nM85X<&S7qA!}jD9^xV6EM?b3nR~lVAGw9N)LJ)jDwXJa@Wjcuu))E5ny2{U}gQF z@HWL$PJvZr!GG4jF3z3{84?|gr3F|M7BDI*Fm7{6$(4-NlAP{yW74+9sf-3J2M(m1 z4rEl`!1~0IQP+_%LV!`?(G<}StQl7stR_g>8zkwuGBN}+C>Ag?A7Hl4$UhKJ>~V#` zZvvB8D4&}Eqfh~}<^d)ZL5A=Y)+mocwh7|vF0o{nrg>jr;hLajym4}90<&Hzv)cy7 zC#({CE;4qw${k2xR@uP7e`wmdodFjl=jvI^kpnJf%g z-MUz13mCL6_G_IA(7CmUZ^uLnQwIOGLdF9V3?3+0H)wMxFkf(E@N!^I`^K!em5FP? zyrc)rx&}%~)8)1VOnVW)BwZS&^&2v; zY~q_XWtD<~gzv8<7B4ehP5(2vY-I8^;Err)s#?f!$3ZUi0yk@c>yfBs2PTNWKM-iP zfth=P*4_k0?*)3Y!VC`W3?V^^TV0qr3Yg^z82A{Ngbp!>8|W#vsPalOa-LW>@yE3H zyH-fwER*lx<0@dB6vn*r5rh8%y%_P8>0T#9oOvglowZX$4nhRJT zY+xvlUZY~oE26r?#Zz4M!4xKiMAHqM1*b6?E9gyslE$@D+*CD-*<;G*3ry3ycWTet zGFy83TW?aC%E9wBFau0*c1{t9Q*2G85E)0xv z4T_bX3_$^W`V4Fd4oor+X4~3uM?cv2UOVrj_I~Y~D}<6*zyDyd`@p2ez1+CYStCUm zoxRH5QH&oX)=UXj_F^<~V9+jLm7JiO-o~QxfZ>=6L-rvNjtP=tq5J#pFuUAY=T>t> z!g8+MP4~QQ45y+Qf<;e++AxSW9Gwx#WRM{3YoND;?U?`U4LxZ!P8G+te>^bl;4z^B z1_5&h9fiWTE(|4m4n8b6uHdt`>P@)I1|Aa!mQV(!>1xbD419?qOeO}E6LOe?CTJN> zkaSOAI&t8Pf&p{r1lG_4Ov#=nXJ(w7uG2rWhBaWP%y$*1lE8Ad0(bTTqo^%HvTXd3 z4vc03!ko7mo(i0HH9q|;aNp@b1}g(@2DgLE35ANw{!h5k#vpS*|8Up#qdZIp7O+_F z-fVb9K}3o{`vXI3)_J*LX14`v{1X_t8xAuoFz7VN>~UPkRiOH;=G@gKJ74W7kgjxP z4wyWH)8az_lhy=DD~I}rh4nS=jAA}n|7xa`Y-C=_#I(@LSScY;#X+QZ;kvt?+Rl;E zwjac0J;b>KScRM}7B)usB%D(UI3x4A*RfiWMS(H!;&xRDKI`2~$}u~+4_xCoaQdqh z-zjb9X(g9u&OT@5+iSziW1rg)nBnc(z~JCuVsd#3uK~Y%!oi4m+6BQVLR$P;FD7!bE_vG~Bf&%}OcY8N+Z(zKzVY&4M zCaVL?U1x48IWU?lFl&93es@e-sg@!95vxf-ZR^|>?Y%cnuDD^xyC<;1^YrTz49d+D zKXU&)EgRXuFxyw;WdTE=FJp3$;+dDFW&)8BHLO+-<|~FWi8rV?Y*=3Vgi+&y5c2`X zS6lb&pQiSH6U$K_hQ3{jiX}#(1+Lx(Q`ip(I(%R#zw2q!usPrtgIWNe(Fca`gk8J| zOlP$jG_&qDPq}<^ZT6QFH-cvr@)a<>`Nrfd!00uBp`(>SKVaGi1(AO;!isMhxc9Me zeC6XSV2w|Zc2{7PGhlMuz$(JP^7H{?Ng+e11Al-3i{b(1_*Pc2(rYXQ|JT=<21q+F z1v7*mmtvGW#S$yPB6NY#w}E+S5UaUlYEJmf1)mtVGO}D+#lRoH!uDaF;{^sU1%^n2 z`Tf>MwDU^!?Dj8b;pyC5>Bdm2%gW>SAnfu7ZoLOR0+#~K0%9&JyqJD3$jaal+lH5m zUIks4&Ma-ft@c36x4iGG#)0EqHUX)xm>rn6E@jYRt-a;N&nb{3TflT7{gpmLLSNsx z34GHzc3N;RVBLQ)(5_*f|1;JM)s}TZjN8>^C8zSrIWRBJWe8iqxQ(4hZo&iK4@?)z zS-#%9kicLORKPO*9gEYyW z|GB;+bw4c5PGt~xh`+ogu~k@(U%`a+JA;@4181`Z|Ag{Cp|yWH+?6LVNHQb{TQuCf zpv0-bbb4Q(!Xg%>2@F~r)=iL#W-4GT{FcDC-&>dOW5hPc*FU@hPPnRknb>69?5Jzu z>%eTXfTd|N^X3nW+Yh@$=ePMBas6AdqFw8Ye*0Zl|E?n%Hm;Ky4iqq*Fy*~#$E{y* zFuA|OCI1_H+qZ+tjjL;{_ov=2Wb`#Rdzm8D-R3(NEgt=PtoG zA+eWQcnSX#h1c*C5`P!uN~5l|z5c%- zG$T==wNc%##DcNNIYx|?!FsO5cgCshg$fp}uq~A5gg7=XJ3HH=_|=`0o0t3NNqQ)F zTy#Fg$0WL^c7su$YeV3iCrg7Oxw06TLZn+aG(BomUOCl|Z-cnzsxzB2F0YC`y-noo zeE7-yw^&#hjS@UrnAn*@ECehLO=1kT33xPRtMHA8e$7tR-7D8VJw3xXd*64l^^lYK zeRoOqNI93vB*Y{g;$ar) zu!(4xdSC@JcSr$4^TLVDY&=p0K|#&ToeH8_oDU8S8fP+ za$?+TSPtu%M?q1Pv*~)Xc2k5N8kY0M~wtg z6`r2Ojm)72hJB38KLnao!+?*O^NRsPkHNNp`O0cNmk$Q}Up*k+ z$NYeyIb?FE!(m>1zJ?NCg$--xUhl52q3ABY$WYWrKkc0V;IViaDib;N8;uQL?k+7(9;u49c3~mty zUFiOKN9N1&bx~#9pppQ==>eaf_Y&?l!48A;)M^-rV9cVmuPt?$l znE|wg@;^t-2hbME5`QKi&jyi*Da>~*G-U!0GxJ#(bZr!IIgrfIyywFkW^E4vCthC> z2i8s>JI8~9Tx*UUwvZ7iXkZGoOmLo3HQ%~VC}QC>Ct>y}3DS(b|4kHK*=&>prav-5(-LdbC+7<;ZjP45l2ktT_Y>0ZmvPQv#uZ7djfu*I@fsc!CP1)5~N4lmm zZ|rZmV8F>2!T#&_hvV{{FP2}=|Nr;LZzTt&ma8kjGb;aR5YBU8)J;7TVYI?QVqZ~% zHcKLd$OVT_VGa_UDGm(IKNvW7IWV$tFjg{h++$!#kXTiScKv{v zJXseQ9WC-B^@C&b3>p}iH!QGgoH$>gy~E_!)Ayh&X%Bu=U#D>FupQ_B4Hp?0L>olz zHn0dt-489ha8U0+I=e|l6Qh*b6zSRxEC-a?nY}EO@?UVX`(!DGi3K$3PGM%0{o*LP z<9WyAI}IHDiViHtGMYYEPVDILNm<>q;)t8or-?GR;_oUP;gtTS$H8kIDcXL7iOHhD zz40aki)BFrQ%nM9#hgQ&Q4Y;o0*r3*JPaQaRE+$l6ftT@IPgy}>65*(oJDlUA+}uw zEpmN^R$7*vtPUS$F!dzJsCjfv7x6rsmDe_L!kJ}e+c~8qR2JkN3G&pef8Jm?Z-JoL zWybe4<*h6eoSRrZM1{9}U^ukEm(hKJgCLVLtIz=sIVtIMz4DtJ-nk1H)@UF69~_o2 zTVTrpSMv;}^V1|xq)Q!ODVVj))cn-NEeVrnEAX!LC{=1m+Vz03X7?#!eusX>ImMIN zG?;!#InL0Upv=K_;(*1ff>zNf4Gi1{fp2EHo7M9*Fn(g_$z?lrn(+-orM84mfVjg9 zp%w?3xEUH87VZq)NhaO0ysINFe!4hu*4H%|x*ZIA7A*RxxoQeaz+OtaM7)J?%ea0(3k0Xs@Cl**W6`U1eYha4h zDqcO|#j6QE2}-?vU$?9{>mGUe)U9i~wn;MmXxN-{p=C*gyDYna<0=gW))GEWM%#=7 zy5IksF-tTm+A=L@VB8eY$fYrbf#2bfh0tn?V@|FsSx=;=G{C+gOfUElXIo;;fU-2477Gi64D367R*ADSds7(L`O8YPZRWW6(ynOpBe zBb(9!CdP!usJO*^^VtlVc{LgtRSq}`)->EOGn!_2<7!^8wZL+Lgp*vk*?K%%TpO9! zHprcRqE&s6>%P=&39;2%*Y}n8T+5r0a3J7NplitkhSoeG#sKCh!zyYH(ww{_jwTfNH_ zRGE|}FtLO<%ndwnay#<{2L`zh45~2?n1p_)gc*J7;4NWTI*Fk>q(r%MjfVq^z=i|N zIl?<$PLw{k&2Rgz*Lz-Fh~;&(7nPe6`ahd)48Oed&8dKYcJdW_vETb@rTVJoP(H zh375nh;Dj(BCKqq2?xf;QG3*T2{?v{jM9w^`@`>{^xau|8Dz3e&4q3mQ_zv zXN|k+_kGv;=C}Fhci$5gD&PJ4@B8fOzwWX7|Cswl_Ctq%jqZoIAIGfaq}s#xJW=1z zbHl|uwfwIe@s{sb zpRZjQZ~yy2efcH%fM&5h4D22snD{%??Bxm;y!@|olK;={^*`RX|Npo1SSyo^LzCu# z42|?QzB!+@E(b^bPnPv)U?{mPlr}lyi+bg^_IjZm$yMK2H$7%{`@kA;K-~6=;N@^d zt%HoA7d*8XB{+99=rpphDX?TDrtn+12wF56S;SX8^ym1%>|CHya)jB*h{127^p6jX zQ#RC0ZgA6XU}j5Tl`Ut`(qJh~;&iFt^3C9CP*l95)}sGH$k3uWW=0s308@=2tI`CE za7LlE#S)#4c`3}?s^MN!6Kf`X2>x`9D`KIp-2{!6#3sY9EmJ3iZ26$6(^2}Um@DL> z#N}|y^#w`=8J3ZO#gRXRqHnZL(g+fGV8ncZ>4md;$)f)Z8x5WM1I$%Ec^-e9-|Nt} zUQy!hV+M^-rnD7&Ya+~3oEhw0l~xN%v`h>yHmZI1Su`=Bd%v)R5L--cNVkUrqf>(@ zs{otm1#8BJj@|aB*-Am2wVEd0`Vfxp*LAFPW0;-w=wp`55i!k35!Ib!*<65BCjfw3CER^9No4`+wM8L}7Z{x# zm~0f7t}+X~Vi3Bzn8jCs+2sQx?}hG@;hZcAj6n-ne;t&6m+{}9M}fg^0+aoRoaBtA zT`rEi1}ugTq)4e1Yz2?ETQ9((>bWJ>8^lzgC9^MX-Hfk{M| zAu)i7|H34l4f0nWb|^bBOqFC-F<|kUV4=K#DS1Ui_2;B%D<@x0p0G-_g6rq3_tRJy z6c{X%88jXg3*Kz=D~b?sVe~)1T)3%II)KkGfw8*P-MoNBn!(5D088kyIsck%_zjr% z{8Z8n@P8@6DH_0=c1enO$^U2akwNf^DbTx79bQ^$RPh=zQrRZ(+3Q1 z4H$$rFx3dNaTTcUXH||9uvl|aavkSvk6GE9W-=&VP~&i5(kji{zK}upf*?l%v;Bj5 z{a{9}07jMr49<$oVG~*`64JD;Fvb-y-~Yt?>;kj3LLcJ=2KR<6TZ2T724>zUPN4-& zk2k0%F(~UX%wa#^oSeed@e*QPiB-k!Q!Ogs`-G$KjOcU-47ME z1I&{g7W50S=ov92H87i9GH}1Zz_lR2+ngbwfm!4M(~2Mmjt9)V45F+Hm~yPFtBaBn zx)`DgMAWz6*X1oYL>!62Bi=drVZw*6LcR5uv(hy zaujF@C@?ZUV6ZxnCbf&zOF>6Tz**sx74H*PgF_3{P1dp{u?eZ zqM&jhs_k*WqDVuQ+lzz(75Gj%DX|E!)+aM}1=qmD$jmlWARsU z_6rPVsSMEttc`{1UhFD(b!y#|==iEYhF_)1#fzB(H!v%OGpH6ONC^zaf8BAy2u$E0Bu!WKJsRC=nM2nJ14SEhHEDekXNz8%{ z|CQL)IU81NRZV7)N|0@GWtE+NwOtH06D)3SX7q7jv~zH0{J_Y%h4tHvb}0ou zyAn~p3ywLzIr6L-6c-37e`IbtYCYvJ(~|?t*F6|CyBQ=Ib`||#_^HC@{wX|Ez{Osa zEg(Q|;_iyc(L2rVM6KK`rI^4H7VIE0!8Gtdj_3p%JEpbl3DK*g7z(2^mR?z<8_-%9 z#4sy}SyFY8Xaf`51Ez+Jduu;>rd*a{f32kZV0!-q=Eonzk30%yT)_N%C!;avYTJOl z^EcUEst|2ub@ZPj;*-cCUMZ?A!15@7xzSK}`VSFSNzMk1J|zKGn+J@ALUwC5uhk6j zkFSbQZ}{()UBQrOuvK%xD%J+p3m5lEunQ@FJTOn?V0Xm9MHe_sKQNZFcGnnt#Qhc# z|6mlNu;!2z%cf!#s|m_&d(8b8G9+!t*kp2eQ^N%FIcL~6+m|ddU&m~{>2O+fQNPU@ zmKY=TdjbqX1_>GmIK?hFS8nbJJ;9vJ!uV)WkY7QB@&*RJ2Ww0m{0>#KHeB53eV~0_ zLYk72g6ag8d(MnYj&$7;IxdmEmo0(W?z(+@BWte$lPrryqvH9}#|*QlvYvP*qBvcn zm$9QjHR91!xu|H?W^ai_DAxkUWS1r`2R`999IIps ze!FjPbkwSLW_di}KSTJ2jR#{GCmAvDEeJ4kVAO4};VNL|*t&{;8w+#BnKcb(PR+S0 zaNPdDACVS8M)?L-*@;XZ1%?tM_FJ zKB>{fyE818Gh*%47q;5Jga6-dSK${pAToEBh0d+B=8rj)KeAM9W=s~jE`E~vROt10 zhdC>3848$|Jx(ya@=K}WNL|?@;|UWiR;-PQFSyJ2_l9yH%Q=gEq7ydlE@p6YAE$j8pz$?2w>fIaid3VulCWSO?$Trlst%JQsp@C;OSki=X3AH-7C6p;-__0 z>iP}_(LJmuKAV5ZJ>kQ2llcS7Qj;x)3}Rdl?z1sG2s3=3aB#kD2y5sC)&@S-rgh9l z4lK>zI9hU;`1eV1CkVzr*yp5l;ql>?K%@URC;KrtU4D4*uuZJOizYqh)^*IG2~6?H zkERLisJOx4vMyI@Kj0^5C zE?_;z!s2#;$vA-Zekw!C!7z{Bp2o=<@dkX&hD`s}ndkAnSQz($&*50~ymj$$?{2Gj zRu?O6Pm!&-a*eg%S|+dJrwhznCpbS_KQH=wUs7D6YTemK4our`sCF68oOFR9TRQ5C zrL~KI=)}0am##9481K_QATl@fjQ|U?{nSFQqxoOWZcW@^<1|4-)nOxt0W<%DOKMD) z*4K(|oj141=(T;P`;?8G>xfeEZfu`UE4w+}nH60g^mVWNBRjHcq z%BtXG?8G2ct?R5Yu{s)4`U(H{tz){~Sf@4L>D(@4Il?$KY3*=YIw@2WCD?PGbW; zg9X>P63omMX1~?cW*wWk)wIadE*+t;2m4AGGegFLR`_JEh z|DV5LJ_92Imy`|WTH6l8#m9POtgHTT7%e$5QN=q*?HplC0 z`MlMP8{}4QNm}S)!!EaBiqr@0tJ8v<1J*tkEOp=rkXrOff#KBbR`n~_o_4S-YG7vP z=W8jLn8d)u$;IU$o3O+@f=RLJBnOA>t}idItd9O}eqqVCw|90||L3#Y^W)=_)3e2A zGPLzDiaa{ja6sW;yI7LaOARv<4;5(_35}ZxO}v4e3l1o_Zfv^3;MI6^N^m=i12fai z8UaUU9tXiW{QOsf83ZSO5je`mt8(EAgTtIjGsKs=IC7}w?EEjv5ThTk>44zU1jfUB zyet!)L)=u#6zrM;FE#Z`dR$;&(YVv#qS?=yc`{`xD}!r@_Xzw+s6Tg1m3rIY-;GM7$sn|`-)R^F-1<@4&evQ{kWtD3~XIwK%nWtE%IR6gz#!Ux#( z*8G~u+Z({7sv0<@sZqI-H6SU;=BWVRT8D@L1zQ%42WM98Rrt`%vCnEzyk?Tk!gJmG zXI*P%G!ELtthQ!T76X@1K$Bz2cY%T?#$3xw2l(eM5#!{H_4qMW%P``9kVov4gJNpQ z%pMY=tZ_L4oZOYNACB%=DSPm+(UgpZS;=e<5*YK^M4B7?EGS3*D_c1P=IjO7ooYng?#pmt*$6RvQ^zsACUS^$%&H{;QuTL=XJUQT! z<&%=gXv7#YVIyP1%Uf|*_Z_-6h0#FX;Q+g9k2R~H^fTj@9TR;F5AWm;I^=wD;*(Mq zCf6yUo{Sb1yRR@OoG|&oVDFO1F=1&=?D_6jCKsF%C&~!2Fut~Y=5dU}z^{XI?*S$s zM&CIC=QwRd1RO)uWDfk|;>uuj$uevBa6mxldkAw3^KOG?cA*Dsy~;ukj?%2&0sq%J zbn=UENHdypOq|6S?65I0$uz#d_S-G%BI66t#kT%-9?XqR9Zb?O0!%DgIsqO@ty5f2 zFn=_B;23%B@#g=BUdV6SFPoykD0sm2(VLI^*-{wT#41FaD}op{CGy&x)DlqqCeHQq zD4Ut!js^xRhRr*FHmg5baD-WBLZhIIf&TtOM^|s#Dk7+MjM4f9uhJ~z2L1`UO??6L z84Mb@LqwX@H!ym$2q`eJKS`}Gj$|-DXTrxc!!am;{i zN%d3h#gd@4wyQ4MI0+}JGF;oTPuE?}pk<+IQuFk@Km2J27PO21mFNXVL$k ze;ixj@=Hs~+hqyQ$3Q37bN#LRPjQ?7>zK}7o4{rgaAT$ya+Vp- zww#dcRXodB*g?fFV5_W^gKxv>B}+IGShxZjSot`dC4?9mcPJ>ZY*@6+`o87a6uaVi zU)C(QeZO;M#-ZZ*e^@$rq>5Yg&m7?1V-Uy^k*;}VV`qR##zD>|XGQ^*jq^p;W}JP} zdA=vBWUru-}*ISA@FrDJMae%9A z!vo2VME>p@N3_Z|_T;Wfmgl~C!mDi4l(lP8^{oXY7_^vYywyoEW{5i9Rkme`?%GWM z?px=C%C@e_U7PJawc*C8vTYlE*XHJT-@daF0=o!LX3=9l93=A6>B3PaO^f$`lU|kC2d%xpU{PTer?U^2XP%UoTv^@c8lL z?(XhizkZpA-`KcuXlUr?=a-a}6c`xz;K75El9I3g|2sw>yK?2qgb5Q4 z9XhmN!Gaw-b}U=AtfHdA*4EbB+uJ1amSxoO*|TRaUcC6lj(W6J*qt{qO-d(tGVNp>L7Z+DvUY?eg z*2IYu!@|N$qwXdoB>evUJ0l}w^XARg5hp(U{U29x^XAQ))2B~&jM`xyasJ1T9~(Ao zaC380P*C9IAU>pQWYc+O=za64qNrUj6g`|MLC+>+0&P6Ytwc?6r=(6&)Sz z5wl5FR`%Q9|1K^rCMG7q!NHC(7e4>}9}y8@6?)hz`ktvkpD(l(4^d#_?N^{=9$l;rxxCj!Bm{pZp&Y(>QrvE;C?*IL_|8rUf`%o_;mCzV&k790!6Ieq5z zrI+vCMirf}s9%^_dGy2UPmR6XY9`zZjjktnhH%D3CI$&Pexm~m19%&BWMF3qi<@$6 zVcLwC06#z90epsVhNB}lH;+r>20;dPEsnU4KN$`*Il1LeJ8{Z%AumJFF667}uf36D zm@gv5Ai%Uxf}wmL*PP!A)j1liZYAB(ve0O1^imN;95!`l>-s|~>8u`xE|H0C=PVm} zw(#r%pCP=C7+s~zQk)!x85(39mmZ0@5Z2wZ;y(0h`fV+9n3V*MFr=vqTzTxmX7Ru&gw62) zC&Md71usYK1Qn;rEWLrkW$Y7w3J3~vTw&l;wAj{}knyhr}KJrK;w`#H_QWrm8N4BJ+Z3G87zpEP-hHQt=i!KQnwS)RKwlhdul zWXo;GZl(`e1xr{R1QZ!Mb_&dA(mn8U$CGKRNxZ;b z&d}gKUHl`r!xm9p!y}IK|5{(Dzby3Su!CyN(zbp2i&lfLrZ)~~hQr-Ak9!* zrStUCI+Y7&Sk~^ycG|^NqU^@1Z7IORWLY{nzv?5y!(!vG=nL_zAKL@Yv8=4!w1u@Y zH^3uJz(jllk72=eK6Z)!CC?8W`KR;aL5p~vMG2d0^@2NF-Wg1gQe4jA(7Tw?fSF+x zoBD;u6dw@-$MSWFkG-mFt1qn9@J~4&t|$FucENnR_Jx<3j%L1eQP7+9%UdkV&;9vP z*X3<&Y0@p<9-dHN|L2pv(SdCa8V%MLo^MbJIp(tDrkyDt zQfOv2bl_$Gq|xS4sH8JvA^48KS1eAKUNbFDDcH-db|yEPsh^eHBLo{qZpY1)pI?)60{PsjcGH2uJqlk7sC z0$Qw}XPod^W)y$v#Fm)#20aQVIMNO@*|}_16o^=6w*BPUJg2q}x5xubn_iv;ogsX1 z&Rq@Wj&o(ZKF|G-6X)b23OPgg%yPT$pfiNqgxdMPEO%h{y3q8@Wp3Z<#{ugyFSJ>G zS-5`-Bjc(DRZGV&izLpjaAP$(*jx2wF=ztZ-Rsh%SznfD_^$K{KXqx^t}jash&n^~ z)RkpcUsne7t_oT1b#+zL*HsZ`SA}gqb#-0U*VPHUt0RtkUE2hj0QX%Tb^X+}ZM(j% zE$Cex^W5wDu3KN%Rh(TN_x;rMnn`Z*%s1N;zF)k4Na|X_wF9gSGKDveS$#|2`r}x# zy7$du&20)3R;)=gk5#mvirEYTcO4uq1m2ShU$yMU&5A=BddyE=?YOWstElqX>`dR+TP~hm zS5|##x@&6Q?gzZpDb6%kzdIw~D9-c~CZmFjDJabm$L%#hYljZmf z(;aml3CUk`W>PG4kgVYWv*}&G&!mWk zJUzx5sLHTx%`+$IC0g!m2RJtUY`!O=(inDa>R*l`%Vv!Q)v*B%vxO(6c6BVca?|rJ z%asR;Qv$OTc+P#|aG(1k?)vi++-4oSG{Oa#9Hg!@2OgdwKPi*dLE#kl$t^8~zHb_R zBK1wnJXUKm5VcrO8X?6_S`)q(Bb{(*-y{y4go#A)A&=Kv7Y?2 zR*UYZk}FzCZM5&c}secbdwTjXQR{@QUmBrIe(&K-x}8z`)Mwim>#3k3-Qcl1z7U z4RTveiVkk=uXCL8--Po(?e_=qz5kzN3Ve8I|Kz;@W8ov&L$zwm3BukAOpI~r0#zH0 ze;i$Bz3N${K-*u1Euj;u*&FK~hBxfFF0etZfnfpDvvdLe2?eYlndgcL9{5`uQd<-2 z!=&)?d^7guBngqd%LN__w=ozbpJZd;xKP5e&`&*C$bN$F+vm9t+Ke^_GqEpVD~hOK zRA+2CuE1cxuxWcOvmygyu=)ZsN8XAi&HvM^!rf(J9VEn*n`SCAr*beb3L7#`Zc6^q zX?C$}^Ku3s4u()i_K+936WWqWI|K?Yus#sWsa#gc?r6!mIPvK=4xs=>ML}7m07hML zS)MWtvkgX(*UaxcZ*jO$|I1xKT!E3ttcSsYb?@U8WAn7T&9Mu1^jZXpJ`T?3UFeoo zkjgcoiVM(B{#WEh^A2dA+qH zAZFi3%d91}EEmPKF9#a4)vVtxU~JHQCt{+mVAOB-RN1Qq>=QegA1dBRXyU$TWojm` z#wep^sHC1L(Cr|%>yX)bMn%hlsH%(ATGN_B{}<;x$e3u;=`F+|67rzQ)^f_Ba^s}G#>x<}yPh*(ZLB!ScnE{&$`pb7te?Db; z&Clt#RM;E9SJS^YjcuEWw3m7S5a|IqPmCE5igP=7TJp4`=E# z&JszSwdm)po`kDSvwk(0%d(^`?e z`Gde&OMx?)b1t0}y(Y+#`;q_h%(+erdDs+ZuuP1+B{|Re|Dm~T3uj3jWbv86q}jkI z!NBlVQ((WRK!SllCj-M-1A%p!^F$ZUe{^%cts?hF1%bJo91RCpBpetg8*qy-a70XC z_c7qiFyM?RU|uM|B{GYBssOWy1D8zHLWTn@n>TRP9AIx&SU7Vg`{V-)Dh;?91h@`x zGWaquOeo-H_`u54$o6XI!UhMfe>WFf8geojvPL!V8Qhw=gn^@Z0uO@&|HJ~GOAokn z7jW=-%{tG(@OA^&^#-2f4m`&h81`LYSsTEaQNYabf#>`KK86n*l>%H120ToTJQEH0 zzb#;Q+Q7qbVDTCQfn^i;nH85WzcAZQYK18y+iC`eJOP%@kihJ*s1mk-z&1o+yt1m?N&-JQU(cLICy2d>=>bKSVDWVWc5{LGO|#Z$F65ZYz&9^p?vw=_<_$cD zxfnVa7%FFSMjhb#EwI*HfHSyZ4pSqC2^YhoR~%CeIGR6j&1B%b^?=JaV8w2M)dvo6 zUCW%ybdja%0M`Tu?lTWKug#i1Zvm@g0#7^x*V=|Pr*>@+J2=mL0mn5dmRAf6doS>9 zYT!6=lXryz`@aAIrv)5O88*l}EZ*^eqfdZuI|FA_0?#rB&bT>HT4yMaf?i_?jVVX=Wg`>%CXA9(T_IQDGV=*z%S%)pf)%{To3duPBp zh6e5p3|z$@IPzBQJoJFer+deV*8C{keApuoOdfhG3>=iCGAZPu*8A9$yK z*g7klXUG2q?58&@%V6NT$iT4u1HTy;!>rZ33=7zQPT&hx;J)&JtH@wibHIG2i`<

, } -impl State { +impl State

{ /// Creates a new [`State`] for a [`PickList`]. - pub fn new() -> Self { + fn new() -> Self { Self { menu: menu::State::default(), keyboard_modifiers: keyboard::Modifiers::default(), is_open: bool::default(), hovered_option: Option::default(), + option_paragraphs: RefCell::new(Vec::new()), + placeholder_paragraph: RefCell::new(Default::default()), } } } -impl Default for State { +impl Default for State

{ fn default() -> Self { Self::new() } @@ -330,7 +337,7 @@ pub enum Handle { /// This is the default. Arrow { /// Font size of the content. - size: Option, + size: Option, }, /// A custom static handle. Static(Icon), @@ -359,7 +366,7 @@ pub struct Icon { /// The unicode code point that will be used as the icon. pub code_point: char, /// Font size of the content. - pub size: Option, + pub size: Option, /// Line height of the content. pub line_height: text::LineHeight, /// The shaping strategy of the icon. @@ -368,11 +375,12 @@ pub struct Icon { /// Computes the layout of a [`PickList`]. pub fn layout( + state: &State, renderer: &Renderer, limits: &layout::Limits, width: Length, padding: Padding, - text_size: Option, + text_size: Option, text_line_height: text::LineHeight, text_shaping: text::Shaping, font: Option, @@ -386,38 +394,70 @@ where use std::f32; let limits = limits.width(width).height(Length::Shrink).pad(padding); + let font = font.unwrap_or_else(|| renderer.default_font()); let text_size = text_size.unwrap_or_else(|| renderer.default_size()); + let mut paragraphs = state.option_paragraphs.borrow_mut(); + + paragraphs.resize_with(options.len(), Default::default); + + let option_text = Text { + content: "", + bounds: Size::new( + f32::INFINITY, + text_line_height.to_absolute(text_size).into(), + ), + size: text_size, + line_height: text_line_height, + font, + horizontal_alignment: alignment::Horizontal::Left, + vertical_alignment: alignment::Vertical::Center, + shaping: text_shaping, + }; + + for (option, paragraph) in options.iter().zip(paragraphs.iter_mut()) { + let label = option.to_string(); + + renderer.update_paragraph( + paragraph, + Text { + content: &label, + ..option_text + }, + ); + } + + if let Some(placeholder) = placeholder { + let mut paragraph = state.placeholder_paragraph.borrow_mut(); + renderer.update_paragraph( + &mut paragraph, + Text { + content: placeholder, + ..option_text + }, + ); + } + let max_width = match width { Length::Shrink => { - let measure = |label: &str| -> f32 { - let width = renderer.measure_width( - label, - text_size, - font.unwrap_or_else(|| renderer.default_font()), - text_shaping, - ); + let labels_width = + paragraphs.iter().fold(0.0, |width, paragraph| { + f32::max(width, paragraph.min_width()) + }); - width.round() - }; - - let labels = options.iter().map(ToString::to_string); - - let labels_width = labels - .map(|label| measure(&label)) - .fold(100.0, |candidate, current| current.max(candidate)); - - let placeholder_width = placeholder.map(measure).unwrap_or(100.0); - - labels_width.max(placeholder_width) + labels_width.max( + placeholder + .map(|_| state.placeholder_paragraph.borrow().min_width()) + .unwrap_or(0.0), + ) } _ => 0.0, }; let size = { let intrinsic = Size::new( - max_width + text_size + padding.left, - f32::from(text_line_height.to_absolute(Pixels(text_size))), + max_width + text_size.0 + padding.left, + f32::from(text_line_height.to_absolute(text_size)), ); limits.resolve(intrinsic).pad(padding) @@ -428,7 +468,7 @@ where /// Processes an [`Event`] and updates the [`State`] of a [`PickList`] /// accordingly. -pub fn update<'a, T, Message>( +pub fn update<'a, T, P, Message>( event: Event, layout: Layout<'_>, cursor: mouse::Cursor, @@ -436,10 +476,11 @@ pub fn update<'a, T, Message>( on_selected: &dyn Fn(T) -> Message, selected: Option<&T>, options: &[T], - state: impl FnOnce() -> &'a mut State, + state: impl FnOnce() -> &'a mut State

, ) -> event::Status where T: PartialEq + Clone + 'a, + P: text::Paragraph + 'a, { match event { Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) @@ -534,9 +575,9 @@ pub fn mouse_interaction( /// Returns the current overlay of a [`PickList`]. pub fn overlay<'a, T, Message, Renderer>( layout: Layout<'_>, - state: &'a mut State, + state: &'a mut State, padding: Padding, - text_size: Option, + text_size: Option, text_shaping: text::Shaping, font: Renderer::Font, options: &'a [T], @@ -591,7 +632,7 @@ pub fn draw<'a, T, Renderer>( layout: Layout<'_>, cursor: mouse::Cursor, padding: Padding, - text_size: Option, + text_size: Option, text_line_height: text::LineHeight, text_shaping: text::Shaping, font: Renderer::Font, @@ -599,7 +640,7 @@ pub fn draw<'a, T, Renderer>( selected: Option<&T>, handle: &Handle, style: &::Style, - state: impl FnOnce() -> &'a State, + state: impl FnOnce() -> &'a State, ) where Renderer: text::Renderer, Renderer::Theme: StyleSheet, @@ -665,22 +706,26 @@ pub fn draw<'a, T, Renderer>( if let Some((font, code_point, size, line_height, shaping)) = handle { let size = size.unwrap_or_else(|| renderer.default_size()); - renderer.fill_text(Text { - content: &code_point.to_string(), - size, - line_height, - font, - color: style.handle_color, - bounds: Rectangle { - x: bounds.x + bounds.width - padding.horizontal(), - y: bounds.center_y(), - height: f32::from(line_height.to_absolute(Pixels(size))), - ..bounds + renderer.fill_text( + Text { + content: &code_point.to_string(), + size, + line_height, + font, + bounds: Size::new( + bounds.width, + f32::from(line_height.to_absolute(size)), + ), + horizontal_alignment: alignment::Horizontal::Right, + vertical_alignment: alignment::Vertical::Center, + shaping, }, - horizontal_alignment: alignment::Horizontal::Right, - vertical_alignment: alignment::Vertical::Center, - shaping, - }); + Point::new( + bounds.x + bounds.width - padding.horizontal(), + bounds.center_y(), + ), + style.handle_color, + ); } let label = selected.map(ToString::to_string); @@ -688,27 +733,26 @@ pub fn draw<'a, T, Renderer>( if let Some(label) = label.as_deref().or(placeholder) { let text_size = text_size.unwrap_or_else(|| renderer.default_size()); - renderer.fill_text(Text { - content: label, - size: text_size, - line_height: text_line_height, - font, - color: if is_selected { + renderer.fill_text( + Text { + content: label, + size: text_size, + line_height: text_line_height, + font, + bounds: Size::new( + bounds.width - padding.horizontal(), + f32::from(text_line_height.to_absolute(text_size)), + ), + horizontal_alignment: alignment::Horizontal::Left, + vertical_alignment: alignment::Vertical::Center, + shaping: text_shaping, + }, + Point::new(bounds.x + padding.left, bounds.center_y()), + if is_selected { style.text_color } else { style.placeholder_color }, - bounds: Rectangle { - x: bounds.x + padding.left, - y: bounds.center_y(), - width: bounds.width - padding.horizontal(), - height: f32::from( - text_line_height.to_absolute(Pixels(text_size)), - ), - }, - horizontal_alignment: alignment::Horizontal::Left, - vertical_alignment: alignment::Vertical::Center, - shaping: text_shaping, - }); + ); } } diff --git a/widget/src/progress_bar.rs b/widget/src/progress_bar.rs index 37c6bc72..8b1490af 100644 --- a/widget/src/progress_bar.rs +++ b/widget/src/progress_bar.rs @@ -95,6 +95,7 @@ where fn layout( &self, + _tree: &Tree, _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/qr_code.rs b/widget/src/qr_code.rs index 51a541fd..589704a5 100644 --- a/widget/src/qr_code.rs +++ b/widget/src/qr_code.rs @@ -60,6 +60,7 @@ impl<'a, Message, Theme> Widget> for QRCode<'a> { fn layout( &self, + _tree: &Tree, _renderer: &Renderer, _limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/radio.rs b/widget/src/radio.rs index 65d71ec2..cb908ec4 100644 --- a/widget/src/radio.rs +++ b/widget/src/radio.rs @@ -6,12 +6,12 @@ use crate::core::mouse; use crate::core::renderer; use crate::core::text; use crate::core::touch; -use crate::core::widget::Tree; +use crate::core::widget; +use crate::core::widget::tree::{self, Tree}; use crate::core::{ - Alignment, Clipboard, Color, Element, Layout, Length, Pixels, Rectangle, - Shell, Widget, + Clipboard, Color, Element, Layout, Length, Pixels, Rectangle, Shell, Size, + Widget, }; -use crate::{Row, Text}; pub use iced_style::radio::{Appearance, StyleSheet}; @@ -80,7 +80,7 @@ where width: Length, size: f32, spacing: f32, - text_size: Option, + text_size: Option, text_line_height: text::LineHeight, text_shaping: text::Shaping, font: Option, @@ -152,7 +152,7 @@ where /// Sets the text size of the [`Radio`] button. pub fn text_size(mut self, text_size: impl Into) -> Self { - self.text_size = Some(text_size.into().0); + self.text_size = Some(text_size.into()); self } @@ -193,6 +193,14 @@ where Renderer: text::Renderer, Renderer::Theme: StyleSheet + crate::text::StyleSheet, { + fn tag(&self) -> tree::Tag { + tree::Tag::of::>() + } + + fn state(&self) -> tree::State { + tree::State::new(widget::text::State::::default()) + } + fn width(&self) -> Length { self.width } @@ -203,25 +211,35 @@ where fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - Row::<(), Renderer>::new() - .width(self.width) - .spacing(self.spacing) - .align_items(Alignment::Center) - .push(Row::new().width(self.size).height(self.size)) - .push( - Text::new(&self.label) - .width(self.width) - .size( - self.text_size - .unwrap_or_else(|| renderer.default_size()), - ) - .line_height(self.text_line_height) - .shaping(self.text_shaping), - ) - .layout(renderer, limits) + layout::next_to_each_other( + &limits.width(self.width), + self.spacing, + |_| layout::Node::new(Size::new(self.size, self.size)), + |limits| { + let state = tree + .state + .downcast_ref::>(); + + widget::text::layout( + state, + renderer, + limits, + self.width, + Length::Shrink, + &self.label, + self.text_line_height, + self.text_size, + self.font, + alignment::Horizontal::Left, + alignment::Vertical::Top, + self.text_shaping, + ) + }, + ) } fn on_event( @@ -267,7 +285,7 @@ where fn draw( &self, - _state: &Tree, + tree: &Tree, renderer: &mut Renderer, theme: &Renderer::Theme, style: &renderer::Style, @@ -327,16 +345,10 @@ where renderer, style, label_layout, - &self.label, - self.text_size, - self.text_line_height, - self.font, + tree.state.downcast_ref(), crate::text::Appearance { color: custom_style.text_color, }, - alignment::Horizontal::Left, - alignment::Vertical::Center, - self.text_shaping, ); } } diff --git a/widget/src/row.rs b/widget/src/row.rs index 99b2a0bf..17c49e67 100644 --- a/widget/src/row.rs +++ b/widget/src/row.rs @@ -114,6 +114,7 @@ where fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -127,6 +128,7 @@ where self.spacing, self.align_items, &self.children, + &tree.children, ) } diff --git a/widget/src/rule.rs b/widget/src/rule.rs index d703e6ae..032ff860 100644 --- a/widget/src/rule.rs +++ b/widget/src/rule.rs @@ -72,6 +72,7 @@ where fn layout( &self, + _tree: &Tree, _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index a83ed985..ce96883d 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -230,6 +230,7 @@ where fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -240,7 +241,11 @@ where self.height, &self.direction, |renderer, limits| { - self.content.as_widget().layout(renderer, limits) + self.content.as_widget().layout( + &tree.children[0], + renderer, + limits, + ) }, ) } diff --git a/widget/src/slider.rs b/widget/src/slider.rs index e41be7c9..b4c9198a 100644 --- a/widget/src/slider.rs +++ b/widget/src/slider.rs @@ -169,6 +169,7 @@ where fn layout( &self, + _tree: &Tree, _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/space.rs b/widget/src/space.rs index 9a5385e8..84331870 100644 --- a/widget/src/space.rs +++ b/widget/src/space.rs @@ -55,6 +55,7 @@ where fn layout( &self, + _tree: &Tree, _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/svg.rs b/widget/src/svg.rs index 1ccc5d62..f61a4ce2 100644 --- a/widget/src/svg.rs +++ b/widget/src/svg.rs @@ -106,6 +106,7 @@ where fn layout( &self, + _tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index 61fc0055..209ef968 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -17,7 +17,7 @@ use crate::core::keyboard; use crate::core::layout; use crate::core::mouse::{self, click}; use crate::core::renderer; -use crate::core::text::{self, Text}; +use crate::core::text::{self, Paragraph as _, Text}; use crate::core::time::{Duration, Instant}; use crate::core::touch; use crate::core::widget; @@ -30,6 +30,8 @@ use crate::core::{ }; use crate::runtime::Command; +use std::cell::RefCell; + pub use iced_style::text_input::{Appearance, StyleSheet}; /// A field that can be filled with text. @@ -67,7 +69,7 @@ where font: Option, width: Length, padding: Padding, - size: Option, + size: Option, line_height: text::LineHeight, on_input: Option Message + 'a>>, on_paste: Option Message + 'a>>, @@ -178,7 +180,7 @@ where /// Sets the text size of the [`TextInput`]. pub fn size(mut self, size: impl Into) -> Self { - self.size = Some(size.into().0); + self.size = Some(size.into()); self } @@ -218,12 +220,8 @@ where theme, layout, cursor, - tree.state.downcast_ref::(), + tree.state.downcast_ref::>(), value.unwrap_or(&self.value), - &self.placeholder, - self.size, - self.line_height, - self.font, self.on_input.is_none(), self.is_secure, self.icon.as_ref(), @@ -240,15 +238,15 @@ where Renderer::Theme: StyleSheet, { fn tag(&self) -> tree::Tag { - tree::Tag::of::() + tree::Tag::of::>() } fn state(&self) -> tree::State { - tree::State::new(State::new()) + tree::State::new(State::::new()) } fn diff(&self, tree: &mut Tree) { - let state = tree.state.downcast_mut::(); + let state = tree.state.downcast_mut::>(); // Unfocus text input if it becomes disabled if self.on_input.is_none() { @@ -269,6 +267,7 @@ where fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -278,8 +277,13 @@ where self.width, self.padding, self.size, + self.font, self.line_height, self.icon.as_ref(), + tree.state.downcast_ref::>(), + &self.value, + &self.placeholder, + self.is_secure, ) } @@ -290,7 +294,7 @@ where _renderer: &Renderer, operation: &mut dyn Operation, ) { - let state = tree.state.downcast_mut::(); + let state = tree.state.downcast_mut::>(); operation.focusable(state, self.id.as_ref().map(|id| &id.0)); operation.text_input(state, self.id.as_ref().map(|id| &id.0)); @@ -322,7 +326,7 @@ where self.on_input.as_deref(), self.on_paste.as_deref(), &self.on_submit, - || tree.state.downcast_mut::(), + || tree.state.downcast_mut::>(), ) } @@ -341,12 +345,8 @@ where theme, layout, cursor, - tree.state.downcast_ref::(), + tree.state.downcast_ref::>(), &self.value, - &self.placeholder, - self.size, - self.line_height, - self.font, self.on_input.is_none(), self.is_secure, self.icon.as_ref(), @@ -388,7 +388,7 @@ pub struct Icon { /// The unicode code point that will be used as the icon. pub code_point: char, /// The font size of the content. - pub size: Option, + pub size: Option, /// The spacing between the [`Icon`] and the text in a [`TextInput`]. pub spacing: f32, /// The side of a [`TextInput`] where to display the [`Icon`]. @@ -465,29 +465,65 @@ pub fn layout( limits: &layout::Limits, width: Length, padding: Padding, - size: Option, + size: Option, + font: Option, line_height: text::LineHeight, icon: Option<&Icon>, + state: &State, + value: &Value, + placeholder: &str, + is_secure: bool, ) -> layout::Node where Renderer: text::Renderer, { + let font = font.unwrap_or_else(|| renderer.default_font()); let text_size = size.unwrap_or_else(|| renderer.default_size()); + let padding = padding.fit(Size::ZERO, limits.max()); let limits = limits .width(width) .pad(padding) - .height(line_height.to_absolute(Pixels(text_size))); + .height(line_height.to_absolute(text_size)); let text_bounds = limits.resolve(Size::ZERO); - if let Some(icon) = icon { - let icon_width = renderer.measure_width( - &icon.code_point.to_string(), - icon.size.unwrap_or_else(|| renderer.default_size()), - icon.font, - text::Shaping::Advanced, + let placeholder_text = Text { + font, + line_height, + content: placeholder, + bounds: Size::new(f32::INFINITY, text_bounds.height), + size: text_size, + horizontal_alignment: alignment::Horizontal::Left, + vertical_alignment: alignment::Vertical::Center, + shaping: text::Shaping::Advanced, + }; + + renderer.update_paragraph( + &mut state.placeholder_paragraph.borrow_mut(), + placeholder_text, + ); + + if is_secure { + renderer.update_paragraph( + &mut state.paragraph.borrow_mut(), + Text { + content: &value.secure().to_string(), + ..placeholder_text + }, ); + } else { + renderer.update_paragraph( + &mut state.paragraph.borrow_mut(), + Text { + content: &value.to_string(), + ..placeholder_text + }, + ); + } + + if let Some(icon) = icon { + let icon_width = 0.0; // TODO let mut text_node = layout::Node::new( text_bounds - Size::new(icon_width + icon.spacing, 0.0), @@ -537,19 +573,31 @@ pub fn update<'a, Message, Renderer>( clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, value: &mut Value, - size: Option, + size: Option, line_height: text::LineHeight, font: Option, is_secure: bool, on_input: Option<&dyn Fn(String) -> Message>, on_paste: Option<&dyn Fn(String) -> Message>, on_submit: &Option, - state: impl FnOnce() -> &'a mut State, + state: impl FnOnce() -> &'a mut State, ) -> event::Status where Message: Clone, Renderer: text::Renderer, { + let update_cache = |state, value| { + replace_paragraph( + renderer, + state, + layout, + value, + font, + size, + line_height, + ) + }; + match event { Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) | Event::Touch(touch::Event::FingerPressed { .. }) => { @@ -592,11 +640,7 @@ where }; find_cursor_position( - renderer, text_layout.bounds(), - font, - size, - line_height, &value, state, target, @@ -621,11 +665,7 @@ where state.cursor.select_all(value); } else { let position = find_cursor_position( - renderer, text_layout.bounds(), - font, - size, - line_height, value, state, target, @@ -671,11 +711,7 @@ where }; let position = find_cursor_position( - renderer, text_layout.bounds(), - font, - size, - line_height, &value, state, target, @@ -710,6 +746,8 @@ where focus.updated_at = Instant::now(); + update_cache(state, value); + return event::Status::Captured; } } @@ -749,6 +787,8 @@ where let message = (on_input)(editor.contents()); shell.publish(message); + + update_cache(state, value); } keyboard::KeyCode::Delete => { if platform::is_jump_modifier_pressed(modifiers) @@ -769,6 +809,8 @@ where let message = (on_input)(editor.contents()); shell.publish(message); + + update_cache(state, value); } keyboard::KeyCode::Left => { if platform::is_jump_modifier_pressed(modifiers) @@ -844,6 +886,8 @@ where let message = (on_input)(editor.contents()); shell.publish(message); + + update_cache(state, value); } keyboard::KeyCode::V => { if state.keyboard_modifiers.command() @@ -876,6 +920,8 @@ where shell.publish(message); state.is_pasting = Some(content); + + update_cache(state, value); } else { state.is_pasting = None; } @@ -979,12 +1025,8 @@ pub fn draw( theme: &Renderer::Theme, layout: Layout<'_>, cursor: mouse::Cursor, - state: &State, + state: &State, value: &Value, - placeholder: &str, - size: Option, - line_height: text::LineHeight, - font: Option, is_disabled: bool, is_secure: bool, icon: Option<&Icon>, @@ -1023,28 +1065,14 @@ pub fn draw( appearance.background, ); - if let Some(icon) = icon { - let icon_layout = children_layout.next().unwrap(); + if let Some(_icon) = icon { + let _icon_layout = children_layout.next().unwrap(); - renderer.fill_text(Text { - content: &icon.code_point.to_string(), - size: icon.size.unwrap_or_else(|| renderer.default_size()), - line_height: text::LineHeight::default(), - font: icon.font, - color: appearance.icon_color, - bounds: Rectangle { - y: text_bounds.center_y(), - ..icon_layout.bounds() - }, - horizontal_alignment: alignment::Horizontal::Left, - vertical_alignment: alignment::Vertical::Center, - shaping: text::Shaping::Advanced, - }); + // TODO } let text = value.to_string(); - let font = font.unwrap_or_else(|| renderer.default_font()); - let size = size.unwrap_or_else(|| renderer.default_size()); + let paragraph = &state.paragraph.borrow() as &Renderer::Paragraph; let (cursor, offset) = if let Some(focus) = state .is_focused @@ -1055,12 +1083,9 @@ pub fn draw( cursor::State::Index(position) => { let (text_value_width, offset) = measure_cursor_and_scroll_offset( - renderer, + paragraph, text_bounds, - value, - size, position, - font, ); let is_cursor_visible = ((focus.now - focus.updated_at) @@ -1096,22 +1121,16 @@ pub fn draw( let (left_position, left_offset) = measure_cursor_and_scroll_offset( - renderer, + paragraph, text_bounds, - value, - size, left, - font, ); let (right_position, right_offset) = measure_cursor_and_scroll_offset( - renderer, + paragraph, text_bounds, - value, - size, right, - font, ); let width = right_position - left_position; @@ -1143,12 +1162,7 @@ pub fn draw( (None, 0.0) }; - let text_width = renderer.measure_width( - if text.is_empty() { placeholder } else { &text }, - size, - font, - text::Shaping::Advanced, - ); + let text_width = paragraph.min_width(); let render = |renderer: &mut Renderer| { if let Some((cursor, color)) = cursor { @@ -1157,27 +1171,23 @@ pub fn draw( renderer.with_translation(Vector::ZERO, |_| {}); } - renderer.fill_text(Text { - content: if text.is_empty() { placeholder } else { &text }, - color: if text.is_empty() { + let placeholder_paragraph = state.placeholder_paragraph.borrow(); + + renderer.fill_paragraph( + if text.is_empty() { + &placeholder_paragraph + } else { + paragraph + }, + Point::new(text_bounds.x, text_bounds.center_y()), + if text.is_empty() { theme.placeholder_color(style) } else if is_disabled { theme.disabled_color(style) } else { theme.value_color(style) }, - font, - bounds: Rectangle { - y: text_bounds.center_y(), - width: f32::INFINITY, - ..text_bounds - }, - size, - line_height, - horizontal_alignment: alignment::Horizontal::Left, - vertical_alignment: alignment::Vertical::Center, - shaping: text::Shaping::Advanced, - }); + ); }; if text_width > text_bounds.width { @@ -1208,7 +1218,9 @@ pub fn mouse_interaction( /// The state of a [`TextInput`]. #[derive(Debug, Default, Clone)] -pub struct State { +pub struct State { + paragraph: RefCell

, + placeholder_paragraph: RefCell

, is_focused: Option, is_dragging: bool, is_pasting: Option, @@ -1225,7 +1237,7 @@ struct Focus { is_window_focused: bool, } -impl State { +impl State

{ /// Creates a new [`State`], representing an unfocused [`TextInput`]. pub fn new() -> Self { Self::default() @@ -1234,6 +1246,8 @@ impl State { /// Creates a new [`State`], representing a focused [`TextInput`]. pub fn focused() -> Self { Self { + paragraph: RefCell::new(P::default()), + placeholder_paragraph: RefCell::new(P::default()), is_focused: None, is_dragging: false, is_pasting: None, @@ -1292,7 +1306,7 @@ impl State { } } -impl operation::Focusable for State { +impl operation::Focusable for State

{ fn is_focused(&self) -> bool { State::is_focused(self) } @@ -1306,7 +1320,7 @@ impl operation::Focusable for State { } } -impl operation::TextInput for State { +impl operation::TextInput for State

{ fn move_cursor_to_front(&mut self) { State::move_cursor_to_front(self) } @@ -1336,17 +1350,11 @@ mod platform { } } -fn offset( - renderer: &Renderer, +fn offset( text_bounds: Rectangle, - font: Renderer::Font, - size: f32, value: &Value, - state: &State, -) -> f32 -where - Renderer: text::Renderer, -{ + state: &State

, +) -> f32 { if state.is_focused() { let cursor = state.cursor(); @@ -1356,12 +1364,9 @@ where }; let (_, offset) = measure_cursor_and_scroll_offset( - renderer, + &state.paragraph.borrow() as &P, text_bounds, - value, - size, focus_position, - font, ); offset @@ -1370,63 +1375,35 @@ where } } -fn measure_cursor_and_scroll_offset( - renderer: &Renderer, +fn measure_cursor_and_scroll_offset( + paragraph: &impl text::Paragraph, text_bounds: Rectangle, - value: &Value, - size: f32, cursor_index: usize, - font: Renderer::Font, -) -> (f32, f32) -where - Renderer: text::Renderer, -{ - let text_before_cursor = value.until(cursor_index).to_string(); +) -> (f32, f32) { + let grapheme_position = paragraph + .grapheme_position(0, cursor_index) + .unwrap_or(Point::ORIGIN); - let text_value_width = renderer.measure_width( - &text_before_cursor, - size, - font, - text::Shaping::Advanced, - ); + let offset = ((grapheme_position.x + 5.0) - text_bounds.width).max(0.0); - let offset = ((text_value_width + 5.0) - text_bounds.width).max(0.0); - - (text_value_width, offset) + (grapheme_position.x, offset) } /// Computes the position of the text cursor at the given X coordinate of /// a [`TextInput`]. -fn find_cursor_position( - renderer: &Renderer, +fn find_cursor_position( text_bounds: Rectangle, - font: Option, - size: Option, - line_height: text::LineHeight, value: &Value, - state: &State, + state: &State

, x: f32, -) -> Option -where - Renderer: text::Renderer, -{ - let font = font.unwrap_or_else(|| renderer.default_font()); - let size = size.unwrap_or_else(|| renderer.default_size()); - - let offset = offset(renderer, text_bounds, font, size, value, state); +) -> Option { + let offset = offset(text_bounds, value, state); let value = value.to_string(); - let char_offset = renderer - .hit_test( - &value, - size, - line_height, - font, - Size::INFINITY, - text::Shaping::Advanced, - Point::new(x + offset, text_bounds.height / 2.0), - true, - ) + let char_offset = state + .paragraph + .borrow() + .hit_test(Point::new(x + offset, text_bounds.height / 2.0)) .map(text::Hit::cursor)?; Some( @@ -1438,4 +1415,33 @@ where ) } +fn replace_paragraph( + renderer: &Renderer, + state: &mut State, + layout: Layout<'_>, + value: &Value, + font: Option, + text_size: Option, + line_height: text::LineHeight, +) where + Renderer: text::Renderer, +{ + let font = font.unwrap_or_else(|| renderer.default_font()); + let text_size = text_size.unwrap_or_else(|| renderer.default_size()); + + let mut children_layout = layout.children(); + let text_bounds = children_layout.next().unwrap().bounds(); + + *state.paragraph.get_mut() = renderer.create_paragraph(Text { + font, + line_height, + content: &value.to_string(), + bounds: Size::new(f32::INFINITY, text_bounds.height), + size: text_size, + horizontal_alignment: alignment::Horizontal::Left, + vertical_alignment: alignment::Vertical::Top, + shaping: text::Shaping::Advanced, + }); +} + const CURSOR_BLINK_INTERVAL_MILLIS: u128 = 500; diff --git a/widget/src/toggler.rs b/widget/src/toggler.rs index c8187181..4ddc8db6 100644 --- a/widget/src/toggler.rs +++ b/widget/src/toggler.rs @@ -6,12 +6,12 @@ use crate::core::mouse; use crate::core::renderer; use crate::core::text; use crate::core::touch; -use crate::core::widget::Tree; +use crate::core::widget; +use crate::core::widget::tree::{self, Tree}; use crate::core::{ - Alignment, Clipboard, Element, Event, Layout, Length, Pixels, Rectangle, - Shell, Widget, + Clipboard, Element, Event, Layout, Length, Pixels, Rectangle, Shell, Size, + Widget, }; -use crate::{Row, Text}; pub use crate::style::toggler::{Appearance, StyleSheet}; @@ -42,7 +42,7 @@ where label: Option, width: Length, size: f32, - text_size: Option, + text_size: Option, text_line_height: text::LineHeight, text_alignment: alignment::Horizontal, text_shaping: text::Shaping, @@ -105,7 +105,7 @@ where /// Sets the text size o the [`Toggler`]. pub fn text_size(mut self, text_size: impl Into) -> Self { - self.text_size = Some(text_size.into().0); + self.text_size = Some(text_size.into()); self } @@ -160,6 +160,14 @@ where Renderer: text::Renderer, Renderer::Theme: StyleSheet + crate::text::StyleSheet, { + fn tag(&self) -> tree::Tag { + tree::Tag::of::>() + } + + fn state(&self) -> tree::State { + tree::State::new(widget::text::State::::default()) + } + fn width(&self) -> Length { self.width } @@ -170,32 +178,41 @@ where fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - let mut row = Row::<(), Renderer>::new() - .width(self.width) - .spacing(self.spacing) - .align_items(Alignment::Center); + let limits = limits.width(self.width); - if let Some(label) = &self.label { - row = row.push( - Text::new(label) - .horizontal_alignment(self.text_alignment) - .font(self.font.unwrap_or_else(|| renderer.default_font())) - .width(self.width) - .size( - self.text_size - .unwrap_or_else(|| renderer.default_size()), + layout::next_to_each_other( + &limits, + self.spacing, + |_| layout::Node::new(Size::new(2.0 * self.size, self.size)), + |limits| { + if let Some(label) = self.label.as_deref() { + let state = tree + .state + .downcast_ref::>(); + + widget::text::layout( + state, + renderer, + limits, + self.width, + Length::Shrink, + label, + self.text_line_height, + self.text_size, + self.font, + self.text_alignment, + alignment::Vertical::Top, + self.text_shaping, ) - .line_height(self.text_line_height) - .shaping(self.text_shaping), - ); - } - - row = row.push(Row::new().width(2.0 * self.size).height(self.size)); - - row.layout(renderer, limits) + } else { + layout::Node::new(Size::ZERO) + } + }, + ) } fn on_event( @@ -243,7 +260,7 @@ where fn draw( &self, - _state: &Tree, + tree: &Tree, renderer: &mut Renderer, theme: &Renderer::Theme, style: &renderer::Style, @@ -259,28 +276,21 @@ where const SPACE_RATIO: f32 = 0.05; let mut children = layout.children(); + let toggler_layout = children.next().unwrap(); - if let Some(label) = &self.label { + if self.label.is_some() { let label_layout = children.next().unwrap(); crate::text::draw( renderer, style, label_layout, - label, - self.text_size, - self.text_line_height, - self.font, + tree.state.downcast_ref(), Default::default(), - self.text_alignment, - alignment::Vertical::Center, - self.text_shaping, ); } - let toggler_layout = children.next().unwrap(); let bounds = toggler_layout.bounds(); - let is_mouse_over = cursor.is_over(layout.bounds()); let style = if is_mouse_over { diff --git a/widget/src/tooltip.rs b/widget/src/tooltip.rs index faa3f3e1..0444850e 100644 --- a/widget/src/tooltip.rs +++ b/widget/src/tooltip.rs @@ -107,11 +107,14 @@ where Renderer::Theme: container::StyleSheet + crate::text::StyleSheet, { fn children(&self) -> Vec { - vec![widget::Tree::new(&self.content)] + vec![ + widget::Tree::new(&self.content), + widget::Tree::new(&self.tooltip as &dyn Widget), + ] } fn diff(&self, tree: &mut widget::Tree) { - tree.diff_children(std::slice::from_ref(&self.content)) + tree.diff_children(&[self.content.as_widget(), &self.tooltip]) } fn state(&self) -> widget::tree::State { @@ -132,10 +135,11 @@ where fn layout( &self, + tree: &widget::Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - self.content.as_widget().layout(renderer, limits) + self.content.as_widget().layout(tree, renderer, limits) } fn on_event( @@ -214,8 +218,10 @@ where ) -> Option> { let state = tree.state.downcast_ref::(); + let mut children = tree.children.iter_mut(); + let content = self.content.as_widget_mut().overlay( - &mut tree.children[0], + children.next().unwrap(), layout, renderer, ); @@ -225,6 +231,7 @@ where layout.position(), Box::new(Overlay { tooltip: &self.tooltip, + state: children.next().unwrap(), cursor_position, content_bounds: layout.bounds(), snap_within_viewport: self.snap_within_viewport, @@ -295,6 +302,7 @@ where Renderer::Theme: container::StyleSheet + widget::text::StyleSheet, { tooltip: &'b Text<'a, Renderer>, + state: &'b widget::Tree, cursor_position: Point, content_bounds: Rectangle, snap_within_viewport: bool, @@ -320,6 +328,7 @@ where let text_layout = Widget::<(), Renderer>::layout( self.tooltip, + self.state, renderer, &layout::Limits::new( Size::ZERO, diff --git a/widget/src/vertical_slider.rs b/widget/src/vertical_slider.rs index efca302a..a11fec75 100644 --- a/widget/src/vertical_slider.rs +++ b/widget/src/vertical_slider.rs @@ -166,6 +166,7 @@ where fn layout( &self, + _tree: &Tree, _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { From 89acf0217e0acd92a82bff1fd516cd4266c0878a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 30 Aug 2023 05:06:08 +0200 Subject: [PATCH 086/321] Use `min_bounds` for cached text --- graphics/src/text/cache.rs | 17 +++++++++++++---- tiny_skia/src/text.rs | 8 ++++---- wgpu/src/text.rs | 17 ++++++++++------- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/graphics/src/text/cache.rs b/graphics/src/text/cache.rs index 8aea6715..9e4fbf65 100644 --- a/graphics/src/text/cache.rs +++ b/graphics/src/text/cache.rs @@ -8,7 +8,7 @@ use std::hash::{BuildHasher, Hash, Hasher}; #[allow(missing_debug_implementations)] #[derive(Default)] pub struct Cache { - entries: FxHashMap, + entries: FxHashMap, aliases: FxHashMap, recently_used: FxHashSet, hasher: HashBuilder, @@ -25,7 +25,7 @@ impl Cache { Self::default() } - pub fn get(&self, key: &KeyHash) -> Option<&cosmic_text::Buffer> { + pub fn get(&self, key: &KeyHash) -> Option<&Entry> { self.entries.get(key) } @@ -33,7 +33,7 @@ impl Cache { &mut self, font_system: &mut cosmic_text::FontSystem, key: Key<'_>, - ) -> (KeyHash, &mut cosmic_text::Buffer) { + ) -> (KeyHash, &mut Entry) { let hash = key.hash(self.hasher.build_hasher()); if let Some(hash) = self.aliases.get(&hash) { @@ -59,7 +59,10 @@ impl Cache { ); let bounds = text::measure(&buffer); - let _ = entry.insert(buffer); + let _ = entry.insert(Entry { + buffer, + min_bounds: bounds, + }); for bounds in [ bounds, @@ -118,3 +121,9 @@ impl Key<'_> { } pub type KeyHash = u64; + +#[allow(missing_debug_implementations)] +pub struct Entry { + pub buffer: cosmic_text::Buffer, + pub min_bounds: Size, +} diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index e4c5ad9b..6047a826 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -77,10 +77,10 @@ impl Pipeline { shaping, }; - let (_, buffer) = self.cache.get_mut().allocate(font_system, key); + let (_, entry) = self.cache.get_mut().allocate(font_system, key); - let max_width = bounds.width * scale_factor; - let total_height = bounds.height * scale_factor; + let max_width = entry.min_bounds.width * scale_factor; + let total_height = entry.min_bounds.height * scale_factor; let bounds = bounds * scale_factor; @@ -98,7 +98,7 @@ impl Pipeline { let mut swash = cosmic_text::SwashCache::new(); - for run in buffer.layout_runs() { + for run in entry.buffer.layout_runs() { for glyph in run.glyphs { let physical_glyph = glyph.physical((x, y), scale_factor); diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index da2062fe..ee352368 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -59,7 +59,7 @@ impl Pipeline { device: &wgpu::Device, queue: &wgpu::Queue, sections: &[Text<'_>], - bounds: Rectangle, + layer_bounds: Rectangle, scale_factor: f32, target_size: Size, ) { @@ -98,8 +98,8 @@ impl Pipeline { ), font: text.font, bounds: Size { - width: bounds.width, - height: bounds.height, + width: text.bounds.width, + height: text.bounds.height, }, shaping: text.shaping, }, @@ -110,7 +110,7 @@ impl Pipeline { }) .collect(); - let layer_bounds = bounds * scale_factor; + let layer_bounds = layer_bounds * scale_factor; let text_areas = sections.iter().zip(allocations.iter()).filter_map( |(section, allocation)| { @@ -144,11 +144,14 @@ impl Pipeline { return None; }; - let buffer = cache.get(key).expect("Get cached buffer"); + let entry = cache.get(key).expect("Get cached buffer"); ( - buffer, - text.bounds, + &entry.buffer, + Rectangle::new( + text.bounds.position(), + entry.min_bounds, + ), text.horizontal_alignment, text.vertical_alignment, text.color, From c44611cc7d43b5d8336509030e1181d1ec04ff64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 30 Aug 2023 05:33:39 +0200 Subject: [PATCH 087/321] Fix vertical alignment in `layout::next_to_each_other` --- core/src/layout.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/core/src/layout.rs b/core/src/layout.rs index 50ccf1f4..caf315b6 100644 --- a/core/src/layout.rs +++ b/core/src/layout.rs @@ -71,7 +71,7 @@ pub fn next_to_each_other( left: impl FnOnce(&Limits) -> Node, right: impl FnOnce(&Limits) -> Node, ) -> Node { - let left_node = left(limits); + let mut left_node = left(limits); let left_size = left_node.size(); let right_limits = limits.shrink(Size::new(left_size.width + spacing, 0.0)); @@ -79,7 +79,14 @@ pub fn next_to_each_other( let mut right_node = right(&right_limits); let right_size = right_node.size(); - right_node.move_to(Point::new(left_size.width + spacing, 0.0)); + let (left_y, right_y) = if left_size.height > right_size.height { + (0.0, (left_size.height - right_size.height) / 2.0) + } else { + ((right_size.height - left_size.height) / 2.0, 0.0) + }; + + left_node.move_to(Point::new(0.0, left_y)); + right_node.move_to(Point::new(left_size.width + spacing, right_y)); Node::with_children( Size::new( From ffd0f4df4521a34edf7b1d3aa22cf47d0b64edfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 30 Aug 2023 05:34:01 +0200 Subject: [PATCH 088/321] Add some default spacing for `Toggler` --- widget/src/toggler.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget/src/toggler.rs b/widget/src/toggler.rs index 4ddc8db6..89e6b5d3 100644 --- a/widget/src/toggler.rs +++ b/widget/src/toggler.rs @@ -85,7 +85,7 @@ where text_line_height: text::LineHeight::default(), text_alignment: alignment::Horizontal::Left, text_shaping: text::Shaping::Basic, - spacing: 0.0, + spacing: Self::DEFAULT_SIZE / 2.0, font: None, style: Default::default(), } From 301e6e5fdc40f36f98bd8fef0fa923745533ad27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 30 Aug 2023 05:34:17 +0200 Subject: [PATCH 089/321] Reduce default spacing of `Checkbox` --- widget/src/checkbox.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget/src/checkbox.rs b/widget/src/checkbox.rs index a66ce3ff..0158f15c 100644 --- a/widget/src/checkbox.rs +++ b/widget/src/checkbox.rs @@ -61,7 +61,7 @@ where const DEFAULT_SIZE: f32 = 20.0; /// The default spacing of a [`Checkbox`]. - const DEFAULT_SPACING: f32 = 15.0; + const DEFAULT_SPACING: f32 = 10.0; /// Creates a new [`Checkbox`]. /// From a026e917d3364e58fd827995261158d8cb356ce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 30 Aug 2023 06:36:24 +0200 Subject: [PATCH 090/321] Make `widget::Tree` mutable in `Widget::layout` --- core/src/element.rs | 4 +- core/src/layout/flex.rs | 4 +- core/src/overlay.rs | 2 +- core/src/overlay/element.rs | 4 +- core/src/overlay/group.rs | 4 +- core/src/widget.rs | 2 +- core/src/widget/text.rs | 19 +++++----- examples/custom_quad/src/main.rs | 2 +- examples/custom_widget/src/main.rs | 2 +- examples/geometry/src/main.rs | 2 +- examples/loading_spinners/src/circular.rs | 2 +- examples/loading_spinners/src/linear.rs | 2 +- examples/modal/src/main.rs | 12 +++--- examples/toast/src/main.rs | 12 +++--- runtime/src/user_interface.rs | 6 +-- widget/src/button.rs | 10 +++-- widget/src/canvas.rs | 2 +- widget/src/checkbox.rs | 4 +- widget/src/column.rs | 4 +- widget/src/combo_box.rs | 2 +- widget/src/container.rs | 2 +- widget/src/image.rs | 2 +- widget/src/image/viewer.rs | 2 +- widget/src/lazy.rs | 4 +- widget/src/lazy/component.rs | 4 +- widget/src/lazy/responsive.rs | 6 +-- widget/src/mouse_area.rs | 2 +- widget/src/overlay/menu.rs | 4 +- widget/src/pane_grid.rs | 13 +++++-- widget/src/pane_grid/content.rs | 14 ++++--- widget/src/pane_grid/title_bar.rs | 6 +-- widget/src/pick_list.rs | 28 ++++++-------- widget/src/progress_bar.rs | 2 +- widget/src/qr_code.rs | 2 +- widget/src/radio.rs | 4 +- widget/src/row.rs | 4 +- widget/src/rule.rs | 2 +- widget/src/scrollable.rs | 4 +- widget/src/slider.rs | 2 +- widget/src/space.rs | 2 +- widget/src/svg.rs | 2 +- widget/src/text_input.rs | 46 ++++++++++------------- widget/src/toggler.rs | 4 +- widget/src/tooltip.rs | 6 +-- widget/src/vertical_slider.rs | 2 +- 45 files changed, 135 insertions(+), 135 deletions(-) diff --git a/core/src/element.rs b/core/src/element.rs index 0d23a9e7..02f16bcb 100644 --- a/core/src/element.rs +++ b/core/src/element.rs @@ -306,7 +306,7 @@ where fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -492,7 +492,7 @@ where fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/core/src/layout/flex.rs b/core/src/layout/flex.rs index 86b1a45b..c02b63d8 100644 --- a/core/src/layout/flex.rs +++ b/core/src/layout/flex.rs @@ -67,7 +67,7 @@ pub fn resolve( spacing: f32, align_items: Alignment, items: &[Element<'_, Message, Renderer>], - trees: &[widget::Tree], + trees: &mut [widget::Tree], ) -> Node where Renderer: crate::Renderer, @@ -83,7 +83,7 @@ where let mut nodes: Vec = Vec::with_capacity(items.len()); nodes.resize(items.len(), Node::default()); - for (i, (child, tree)) in items.iter().zip(trees).enumerate() { + for (i, (child, tree)) in items.iter().zip(trees.iter_mut()).enumerate() { let fill_factor = match axis { Axis::Horizontal => child.as_widget().width(), Axis::Vertical => child.as_widget().height(), diff --git a/core/src/overlay.rs b/core/src/overlay.rs index 2e05db93..f71f25f7 100644 --- a/core/src/overlay.rs +++ b/core/src/overlay.rs @@ -25,7 +25,7 @@ where /// /// [`Node`]: layout::Node fn layout( - &self, + &mut self, renderer: &Renderer, bounds: Size, position: Point, diff --git a/core/src/overlay/element.rs b/core/src/overlay/element.rs index 29b404b8..689e69be 100644 --- a/core/src/overlay/element.rs +++ b/core/src/overlay/element.rs @@ -54,7 +54,7 @@ where /// Computes the layout of the [`Element`] in the given bounds. pub fn layout( - &self, + &mut self, renderer: &Renderer, bounds: Size, translation: Vector, @@ -150,7 +150,7 @@ where Renderer: crate::Renderer, { fn layout( - &self, + &mut self, renderer: &Renderer, bounds: Size, position: Point, diff --git a/core/src/overlay/group.rs b/core/src/overlay/group.rs index 691686cd..a0bae6bb 100644 --- a/core/src/overlay/group.rs +++ b/core/src/overlay/group.rs @@ -61,7 +61,7 @@ where Renderer: crate::Renderer, { fn layout( - &self, + &mut self, renderer: &Renderer, bounds: Size, position: Point, @@ -71,7 +71,7 @@ where layout::Node::with_children( bounds, self.children - .iter() + .iter_mut() .map(|child| child.layout(renderer, bounds, translation)) .collect(), ) diff --git a/core/src/widget.rs b/core/src/widget.rs index 70328ff7..294d5984 100644 --- a/core/src/widget.rs +++ b/core/src/widget.rs @@ -55,7 +55,7 @@ where /// user interface. fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node; diff --git a/core/src/widget/text.rs b/core/src/widget/text.rs index 0405537b..b349399b 100644 --- a/core/src/widget/text.rs +++ b/core/src/widget/text.rs @@ -3,12 +3,11 @@ use crate::alignment; use crate::layout; use crate::mouse; use crate::renderer; -use crate::text::{self, Paragraph as _}; +use crate::text::{self, Paragraph}; use crate::widget::tree::{self, Tree}; use crate::{Color, Element, Layout, Length, Pixels, Point, Rectangle, Widget}; use std::borrow::Cow; -use std::cell::RefCell; pub use text::{LineHeight, Shaping}; @@ -120,7 +119,7 @@ where /// The internal state of a [`Text`] widget. #[derive(Debug, Default)] -pub struct State(RefCell); +pub struct State(P); impl<'a, Message, Renderer> Widget for Text<'a, Renderer> where @@ -132,7 +131,7 @@ where } fn state(&self) -> tree::State { - tree::State::new(State(RefCell::new(Renderer::Paragraph::default()))) + tree::State::new(State(Renderer::Paragraph::default())) } fn width(&self) -> Length { @@ -145,12 +144,12 @@ where fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { layout( - tree.state.downcast_ref::>(), + tree.state.downcast_mut::>(), renderer, limits, self.width, @@ -189,7 +188,7 @@ where /// Produces the [`layout::Node`] of a [`Text`] widget. pub fn layout( - state: &State, + state: &mut State, renderer: &Renderer, limits: &layout::Limits, width: Length, @@ -211,10 +210,10 @@ where let size = size.unwrap_or_else(|| renderer.default_size()); let font = font.unwrap_or_else(|| renderer.default_font()); - let mut paragraph = state.0.borrow_mut(); + let State(ref mut paragraph) = state; renderer.update_paragraph( - &mut paragraph, + paragraph, text::Text { content, bounds, @@ -251,7 +250,7 @@ pub fn draw( ) where Renderer: text::Renderer, { - let paragraph = state.0.borrow(); + let State(ref paragraph) = state; let bounds = layout.bounds(); let x = match paragraph.horizontal_alignment() { diff --git a/examples/custom_quad/src/main.rs b/examples/custom_quad/src/main.rs index 91401f73..13b08250 100644 --- a/examples/custom_quad/src/main.rs +++ b/examples/custom_quad/src/main.rs @@ -36,7 +36,7 @@ mod quad { fn layout( &self, - _tree: &widget::Tree, + _tree: &mut widget::Tree, _renderer: &Renderer, _limits: &layout::Limits, ) -> layout::Node { diff --git a/examples/custom_widget/src/main.rs b/examples/custom_widget/src/main.rs index e0a23541..32a14cbe 100644 --- a/examples/custom_widget/src/main.rs +++ b/examples/custom_widget/src/main.rs @@ -43,7 +43,7 @@ mod circle { fn layout( &self, - _tree: &widget::Tree, + _tree: &mut widget::Tree, _renderer: &Renderer, _limits: &layout::Limits, ) -> layout::Node { diff --git a/examples/geometry/src/main.rs b/examples/geometry/src/main.rs index a0d505b8..8ab3b493 100644 --- a/examples/geometry/src/main.rs +++ b/examples/geometry/src/main.rs @@ -26,7 +26,7 @@ mod rainbow { fn layout( &self, - _tree: &widget::Tree, + _tree: &mut widget::Tree, _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/examples/loading_spinners/src/circular.rs b/examples/loading_spinners/src/circular.rs index 6bcfd507..bf01c3b4 100644 --- a/examples/loading_spinners/src/circular.rs +++ b/examples/loading_spinners/src/circular.rs @@ -254,7 +254,7 @@ where fn layout( &self, - _tree: &Tree, + _tree: &mut Tree, _renderer: &iced::Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/examples/loading_spinners/src/linear.rs b/examples/loading_spinners/src/linear.rs index 3addd7bb..c5bb4791 100644 --- a/examples/loading_spinners/src/linear.rs +++ b/examples/loading_spinners/src/linear.rs @@ -175,7 +175,7 @@ where fn layout( &self, - _tree: &Tree, + _tree: &mut Tree, _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/examples/modal/src/main.rs b/examples/modal/src/main.rs index 5d47f02c..aa9107d0 100644 --- a/examples/modal/src/main.rs +++ b/examples/modal/src/main.rs @@ -285,13 +285,15 @@ mod modal { fn layout( &self, - tree: &widget::Tree, + tree: &mut widget::Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - self.base - .as_widget() - .layout(&tree.children[0], renderer, limits) + self.base.as_widget().layout( + &mut tree.children[0], + renderer, + limits, + ) } fn on_event( @@ -402,7 +404,7 @@ mod modal { Message: Clone, { fn layout( - &self, + &mut self, renderer: &Renderer, _bounds: Size, position: Point, diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs index 01eea3cc..50fa885a 100644 --- a/examples/toast/src/main.rs +++ b/examples/toast/src/main.rs @@ -326,13 +326,15 @@ mod toast { fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - self.content - .as_widget() - .layout(&tree.children[0], renderer, limits) + self.content.as_widget().layout( + &mut tree.children[0], + renderer, + limits, + ) } fn tag(&self) -> widget::tree::Tag { @@ -503,7 +505,7 @@ mod toast { for Overlay<'a, 'b, Message> { fn layout( - &self, + &mut self, renderer: &Renderer, bounds: Size, position: Point, diff --git a/runtime/src/user_interface.rs b/runtime/src/user_interface.rs index a730102c..b684fbde 100644 --- a/runtime/src/user_interface.rs +++ b/runtime/src/user_interface.rs @@ -96,7 +96,7 @@ where state.diff(root.as_widget()); let base = root.as_widget().layout( - &state, + &mut state, renderer, &layout::Limits::new(Size::ZERO, bounds), ); @@ -230,7 +230,7 @@ where let _ = ManuallyDrop::into_inner(manual_overlay); self.base = self.root.as_widget().layout( - &self.state, + &mut self.state, renderer, &layout::Limits::new(Size::ZERO, self.bounds), ); @@ -330,7 +330,7 @@ where shell.revalidate_layout(|| { self.base = self.root.as_widget().layout( - &self.state, + &mut self.state, renderer, &layout::Limits::new(Size::ZERO, self.bounds), ); diff --git a/widget/src/button.rs b/widget/src/button.rs index 1788b6c4..8ca4a542 100644 --- a/widget/src/button.rs +++ b/widget/src/button.rs @@ -159,14 +159,16 @@ where fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { layout(limits, self.width, self.height, self.padding, |limits| { - self.content - .as_widget() - .layout(&tree.children[0], renderer, limits) + self.content.as_widget().layout( + &mut tree.children[0], + renderer, + limits, + ) }) } diff --git a/widget/src/canvas.rs b/widget/src/canvas.rs index d749355b..390f4d92 100644 --- a/widget/src/canvas.rs +++ b/widget/src/canvas.rs @@ -129,7 +129,7 @@ where fn layout( &self, - _tree: &Tree, + _tree: &mut Tree, _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/checkbox.rs b/widget/src/checkbox.rs index 0158f15c..2860d496 100644 --- a/widget/src/checkbox.rs +++ b/widget/src/checkbox.rs @@ -184,7 +184,7 @@ where fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -195,7 +195,7 @@ where |limits| { let state = tree .state - .downcast_ref::>(); + .downcast_mut::>(); widget::text::layout( state, diff --git a/widget/src/column.rs b/widget/src/column.rs index 107c3475..f2347cc9 100644 --- a/widget/src/column.rs +++ b/widget/src/column.rs @@ -122,7 +122,7 @@ where fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -139,7 +139,7 @@ where self.spacing, self.align_items, &self.children, - &tree.children, + &mut tree.children, ) } diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs index 8c20ae8e..650954ef 100644 --- a/widget/src/combo_box.rs +++ b/widget/src/combo_box.rs @@ -305,7 +305,7 @@ where fn layout( &self, - tree: &widget::Tree, + tree: &mut widget::Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/container.rs b/widget/src/container.rs index c16c1117..ee7a4965 100644 --- a/widget/src/container.rs +++ b/widget/src/container.rs @@ -162,7 +162,7 @@ where fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/image.rs b/widget/src/image.rs index f73ee5d7..3c83c87b 100644 --- a/widget/src/image.rs +++ b/widget/src/image.rs @@ -167,7 +167,7 @@ where fn layout( &self, - _tree: &Tree, + _tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/image/viewer.rs b/widget/src/image/viewer.rs index 1f52bf2f..724d121e 100644 --- a/widget/src/image/viewer.rs +++ b/widget/src/image/viewer.rs @@ -105,7 +105,7 @@ where fn layout( &self, - _tree: &Tree, + _tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/lazy.rs b/widget/src/lazy.rs index 412254f5..d980a934 100644 --- a/widget/src/lazy.rs +++ b/widget/src/lazy.rs @@ -152,7 +152,7 @@ where fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -327,7 +327,7 @@ where Renderer: core::Renderer, { fn layout( - &self, + &mut self, renderer: &Renderer, bounds: Size, position: Point, diff --git a/widget/src/lazy/component.rs b/widget/src/lazy/component.rs index 9b3b13b2..fba057ee 100644 --- a/widget/src/lazy/component.rs +++ b/widget/src/lazy/component.rs @@ -254,7 +254,7 @@ where fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -567,7 +567,7 @@ where S: 'static + Default, { fn layout( - &self, + &mut self, renderer: &Renderer, bounds: Size, position: Point, diff --git a/widget/src/lazy/responsive.rs b/widget/src/lazy/responsive.rs index 5ab8ed1a..0b819455 100644 --- a/widget/src/lazy/responsive.rs +++ b/widget/src/lazy/responsive.rs @@ -60,7 +60,7 @@ impl<'a, Message, Renderer> Content<'a, Message, Renderer> where Renderer: core::Renderer, { - fn layout(&mut self, tree: &Tree, renderer: &Renderer) { + fn layout(&mut self, tree: &mut Tree, renderer: &Renderer) { if self.layout.is_none() { self.layout = Some(self.element.as_widget().layout( tree, @@ -144,7 +144,7 @@ where fn layout( &self, - _tree: &Tree, + _tree: &mut Tree, _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -363,7 +363,7 @@ where Renderer: core::Renderer, { fn layout( - &self, + &mut self, renderer: &Renderer, bounds: Size, position: Point, diff --git a/widget/src/mouse_area.rs b/widget/src/mouse_area.rs index 95b45b02..65d44dd5 100644 --- a/widget/src/mouse_area.rs +++ b/widget/src/mouse_area.rs @@ -120,7 +120,7 @@ where fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/overlay/menu.rs b/widget/src/overlay/menu.rs index 71703e71..5a2e1bf0 100644 --- a/widget/src/overlay/menu.rs +++ b/widget/src/overlay/menu.rs @@ -232,7 +232,7 @@ where Renderer::Theme: StyleSheet + container::StyleSheet, { fn layout( - &self, + &mut self, renderer: &Renderer, bounds: Size, position: Point, @@ -352,7 +352,7 @@ where fn layout( &self, - _tree: &Tree, + _tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs index 366d9a66..6e2b39a4 100644 --- a/widget/src/pane_grid.rs +++ b/widget/src/pane_grid.rs @@ -275,7 +275,7 @@ where fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -475,7 +475,7 @@ where /// Calculates the [`Layout`] of a [`PaneGrid`]. pub fn layout( - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, node: &Node, @@ -483,14 +483,19 @@ pub fn layout( height: Length, spacing: f32, contents: impl Iterator, - layout_content: impl Fn(T, &Tree, &Renderer, &layout::Limits) -> layout::Node, + layout_content: impl Fn( + T, + &mut Tree, + &Renderer, + &layout::Limits, + ) -> layout::Node, ) -> layout::Node { let limits = limits.width(width).height(height); let size = limits.resolve(Size::ZERO); let regions = node.pane_regions(spacing, size); let children = contents - .zip(tree.children.iter()) + .zip(tree.children.iter_mut()) .filter_map(|((pane, content), tree)| { let region = regions.get(&pane)?; let size = Size::new(region.width, region.height); diff --git a/widget/src/pane_grid/content.rs b/widget/src/pane_grid/content.rs index 8a74b4b9..5dbc5496 100644 --- a/widget/src/pane_grid/content.rs +++ b/widget/src/pane_grid/content.rs @@ -150,7 +150,7 @@ where pub(crate) fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -158,7 +158,7 @@ where let max_size = limits.max(); let title_bar_layout = title_bar.layout( - &tree.children[1], + &mut tree.children[1], renderer, &layout::Limits::new(Size::ZERO, max_size), ); @@ -166,7 +166,7 @@ where let title_bar_size = title_bar_layout.size(); let mut body_layout = self.body.as_widget().layout( - &tree.children[0], + &mut tree.children[0], renderer, &layout::Limits::new( Size::ZERO, @@ -184,9 +184,11 @@ where vec![title_bar_layout, body_layout], ) } else { - self.body - .as_widget() - .layout(&tree.children[0], renderer, limits) + self.body.as_widget().layout( + &mut tree.children[0], + renderer, + limits, + ) } } diff --git a/widget/src/pane_grid/title_bar.rs b/widget/src/pane_grid/title_bar.rs index c0fb9936..8a4523e8 100644 --- a/widget/src/pane_grid/title_bar.rs +++ b/widget/src/pane_grid/title_bar.rs @@ -213,7 +213,7 @@ where pub(crate) fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -221,7 +221,7 @@ where let max_size = limits.max(); let title_layout = self.content.as_widget().layout( - &tree.children[0], + &mut tree.children[0], renderer, &layout::Limits::new(Size::ZERO, max_size), ); @@ -230,7 +230,7 @@ where let mut node = if let Some(controls) = &self.controls { let mut controls_layout = controls.as_widget().layout( - &tree.children[1], + &mut tree.children[1], renderer, &layout::Limits::new(Size::ZERO, max_size), ); diff --git a/widget/src/pick_list.rs b/widget/src/pick_list.rs index 719aa066..8feb1788 100644 --- a/widget/src/pick_list.rs +++ b/widget/src/pick_list.rs @@ -18,7 +18,6 @@ use crate::overlay::menu::{self, Menu}; use crate::scrollable; use std::borrow::Cow; -use std::cell::RefCell; pub use crate::style::pick_list::{Appearance, StyleSheet}; @@ -175,12 +174,12 @@ where fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { layout( - tree.state.downcast_ref::>(), + tree.state.downcast_mut::>(), renderer, limits, self.width, @@ -305,8 +304,8 @@ pub struct State { keyboard_modifiers: keyboard::Modifiers, is_open: bool, hovered_option: Option, - option_paragraphs: RefCell>, - placeholder_paragraph: RefCell

, + options: Vec

, + placeholder: P, } impl State

{ @@ -317,8 +316,8 @@ impl State

{ keyboard_modifiers: keyboard::Modifiers::default(), is_open: bool::default(), hovered_option: Option::default(), - option_paragraphs: RefCell::new(Vec::new()), - placeholder_paragraph: RefCell::new(Default::default()), + options: Vec::new(), + placeholder: P::default(), } } } @@ -375,7 +374,7 @@ pub struct Icon { /// Computes the layout of a [`PickList`]. pub fn layout( - state: &State, + state: &mut State, renderer: &Renderer, limits: &layout::Limits, width: Length, @@ -397,9 +396,7 @@ where let font = font.unwrap_or_else(|| renderer.default_font()); let text_size = text_size.unwrap_or_else(|| renderer.default_size()); - let mut paragraphs = state.option_paragraphs.borrow_mut(); - - paragraphs.resize_with(options.len(), Default::default); + state.options.resize_with(options.len(), Default::default); let option_text = Text { content: "", @@ -415,7 +412,7 @@ where shaping: text_shaping, }; - for (option, paragraph) in options.iter().zip(paragraphs.iter_mut()) { + for (option, paragraph) in options.iter().zip(state.options.iter_mut()) { let label = option.to_string(); renderer.update_paragraph( @@ -428,9 +425,8 @@ where } if let Some(placeholder) = placeholder { - let mut paragraph = state.placeholder_paragraph.borrow_mut(); renderer.update_paragraph( - &mut paragraph, + &mut state.placeholder, Text { content: placeholder, ..option_text @@ -441,13 +437,13 @@ where let max_width = match width { Length::Shrink => { let labels_width = - paragraphs.iter().fold(0.0, |width, paragraph| { + state.options.iter().fold(0.0, |width, paragraph| { f32::max(width, paragraph.min_width()) }); labels_width.max( placeholder - .map(|_| state.placeholder_paragraph.borrow().min_width()) + .map(|_| state.placeholder.min_width()) .unwrap_or(0.0), ) } diff --git a/widget/src/progress_bar.rs b/widget/src/progress_bar.rs index 8b1490af..07de72d5 100644 --- a/widget/src/progress_bar.rs +++ b/widget/src/progress_bar.rs @@ -95,7 +95,7 @@ where fn layout( &self, - _tree: &Tree, + _tree: &mut Tree, _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/qr_code.rs b/widget/src/qr_code.rs index 589704a5..d176021d 100644 --- a/widget/src/qr_code.rs +++ b/widget/src/qr_code.rs @@ -60,7 +60,7 @@ impl<'a, Message, Theme> Widget> for QRCode<'a> { fn layout( &self, - _tree: &Tree, + _tree: &mut Tree, _renderer: &Renderer, _limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/radio.rs b/widget/src/radio.rs index cb908ec4..a85dad63 100644 --- a/widget/src/radio.rs +++ b/widget/src/radio.rs @@ -211,7 +211,7 @@ where fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -222,7 +222,7 @@ where |limits| { let state = tree .state - .downcast_ref::>(); + .downcast_mut::>(); widget::text::layout( state, diff --git a/widget/src/row.rs b/widget/src/row.rs index 17c49e67..71cf0509 100644 --- a/widget/src/row.rs +++ b/widget/src/row.rs @@ -114,7 +114,7 @@ where fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -128,7 +128,7 @@ where self.spacing, self.align_items, &self.children, - &tree.children, + &mut tree.children, ) } diff --git a/widget/src/rule.rs b/widget/src/rule.rs index 032ff860..b5c5fa55 100644 --- a/widget/src/rule.rs +++ b/widget/src/rule.rs @@ -72,7 +72,7 @@ where fn layout( &self, - _tree: &Tree, + _tree: &mut Tree, _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index ce96883d..5decfd9d 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -230,7 +230,7 @@ where fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -242,7 +242,7 @@ where &self.direction, |renderer, limits| { self.content.as_widget().layout( - &tree.children[0], + &mut tree.children[0], renderer, limits, ) diff --git a/widget/src/slider.rs b/widget/src/slider.rs index b4c9198a..a9727aa3 100644 --- a/widget/src/slider.rs +++ b/widget/src/slider.rs @@ -169,7 +169,7 @@ where fn layout( &self, - _tree: &Tree, + _tree: &mut Tree, _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/space.rs b/widget/src/space.rs index 84331870..e5a8f169 100644 --- a/widget/src/space.rs +++ b/widget/src/space.rs @@ -55,7 +55,7 @@ where fn layout( &self, - _tree: &Tree, + _tree: &mut Tree, _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/svg.rs b/widget/src/svg.rs index f61a4ce2..2d01d1ab 100644 --- a/widget/src/svg.rs +++ b/widget/src/svg.rs @@ -106,7 +106,7 @@ where fn layout( &self, - _tree: &Tree, + _tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index 209ef968..75800a34 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -30,8 +30,6 @@ use crate::core::{ }; use crate::runtime::Command; -use std::cell::RefCell; - pub use iced_style::text_input::{Appearance, StyleSheet}; /// A field that can be filled with text. @@ -267,7 +265,7 @@ where fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -280,7 +278,7 @@ where self.font, self.line_height, self.icon.as_ref(), - tree.state.downcast_ref::>(), + tree.state.downcast_mut::>(), &self.value, &self.placeholder, self.is_secure, @@ -469,7 +467,7 @@ pub fn layout( font: Option, line_height: text::LineHeight, icon: Option<&Icon>, - state: &State, + state: &mut State, value: &Value, placeholder: &str, is_secure: bool, @@ -499,14 +497,12 @@ where shaping: text::Shaping::Advanced, }; - renderer.update_paragraph( - &mut state.placeholder_paragraph.borrow_mut(), - placeholder_text, - ); + renderer + .update_paragraph(&mut state.placeholder_paragraph, placeholder_text); if is_secure { renderer.update_paragraph( - &mut state.paragraph.borrow_mut(), + &mut state.paragraph, Text { content: &value.secure().to_string(), ..placeholder_text @@ -514,7 +510,7 @@ where ); } else { renderer.update_paragraph( - &mut state.paragraph.borrow_mut(), + &mut state.paragraph, Text { content: &value.to_string(), ..placeholder_text @@ -1072,7 +1068,6 @@ pub fn draw( } let text = value.to_string(); - let paragraph = &state.paragraph.borrow() as &Renderer::Paragraph; let (cursor, offset) = if let Some(focus) = state .is_focused @@ -1083,7 +1078,7 @@ pub fn draw( cursor::State::Index(position) => { let (text_value_width, offset) = measure_cursor_and_scroll_offset( - paragraph, + &state.paragraph, text_bounds, position, ); @@ -1121,14 +1116,14 @@ pub fn draw( let (left_position, left_offset) = measure_cursor_and_scroll_offset( - paragraph, + &state.paragraph, text_bounds, left, ); let (right_position, right_offset) = measure_cursor_and_scroll_offset( - paragraph, + &state.paragraph, text_bounds, right, ); @@ -1162,7 +1157,7 @@ pub fn draw( (None, 0.0) }; - let text_width = paragraph.min_width(); + let text_width = state.paragraph.min_width(); let render = |renderer: &mut Renderer| { if let Some((cursor, color)) = cursor { @@ -1171,13 +1166,11 @@ pub fn draw( renderer.with_translation(Vector::ZERO, |_| {}); } - let placeholder_paragraph = state.placeholder_paragraph.borrow(); - renderer.fill_paragraph( if text.is_empty() { - &placeholder_paragraph + &state.placeholder_paragraph } else { - paragraph + &state.paragraph }, Point::new(text_bounds.x, text_bounds.center_y()), if text.is_empty() { @@ -1219,8 +1212,8 @@ pub fn mouse_interaction( /// The state of a [`TextInput`]. #[derive(Debug, Default, Clone)] pub struct State { - paragraph: RefCell

, - placeholder_paragraph: RefCell

, + paragraph: P, + placeholder_paragraph: P, is_focused: Option, is_dragging: bool, is_pasting: Option, @@ -1246,8 +1239,8 @@ impl State

{ /// Creates a new [`State`], representing a focused [`TextInput`]. pub fn focused() -> Self { Self { - paragraph: RefCell::new(P::default()), - placeholder_paragraph: RefCell::new(P::default()), + paragraph: P::default(), + placeholder_paragraph: P::default(), is_focused: None, is_dragging: false, is_pasting: None, @@ -1364,7 +1357,7 @@ fn offset( }; let (_, offset) = measure_cursor_and_scroll_offset( - &state.paragraph.borrow() as &P, + &state.paragraph, text_bounds, focus_position, ); @@ -1402,7 +1395,6 @@ fn find_cursor_position( let char_offset = state .paragraph - .borrow() .hit_test(Point::new(x + offset, text_bounds.height / 2.0)) .map(text::Hit::cursor)?; @@ -1432,7 +1424,7 @@ fn replace_paragraph( let mut children_layout = layout.children(); let text_bounds = children_layout.next().unwrap().bounds(); - *state.paragraph.get_mut() = renderer.create_paragraph(Text { + state.paragraph = renderer.create_paragraph(Text { font, line_height, content: &value.to_string(), diff --git a/widget/src/toggler.rs b/widget/src/toggler.rs index 89e6b5d3..acb9b25d 100644 --- a/widget/src/toggler.rs +++ b/widget/src/toggler.rs @@ -178,7 +178,7 @@ where fn layout( &self, - tree: &Tree, + tree: &mut Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -192,7 +192,7 @@ where if let Some(label) = self.label.as_deref() { let state = tree .state - .downcast_ref::>(); + .downcast_mut::>(); widget::text::layout( state, diff --git a/widget/src/tooltip.rs b/widget/src/tooltip.rs index 0444850e..534d901a 100644 --- a/widget/src/tooltip.rs +++ b/widget/src/tooltip.rs @@ -135,7 +135,7 @@ where fn layout( &self, - tree: &widget::Tree, + tree: &mut widget::Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -302,7 +302,7 @@ where Renderer::Theme: container::StyleSheet + widget::text::StyleSheet, { tooltip: &'b Text<'a, Renderer>, - state: &'b widget::Tree, + state: &'b mut widget::Tree, cursor_position: Point, content_bounds: Rectangle, snap_within_viewport: bool, @@ -319,7 +319,7 @@ where Renderer::Theme: container::StyleSheet + widget::text::StyleSheet, { fn layout( - &self, + &mut self, renderer: &Renderer, bounds: Size, position: Point, diff --git a/widget/src/vertical_slider.rs b/widget/src/vertical_slider.rs index a11fec75..1efcd63b 100644 --- a/widget/src/vertical_slider.rs +++ b/widget/src/vertical_slider.rs @@ -166,7 +166,7 @@ where fn layout( &self, - _tree: &Tree, + _tree: &mut Tree, _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { From bcd9fdb521ce4cf21e9d1ee28157ed068ae1428c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 30 Aug 2023 06:43:45 +0200 Subject: [PATCH 091/321] Simplify new logic in `TextInput` --- widget/src/text_input.rs | 56 +++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index 75800a34..f36b5616 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -497,26 +497,18 @@ where shaping: text::Shaping::Advanced, }; - renderer - .update_paragraph(&mut state.placeholder_paragraph, placeholder_text); + renderer.update_paragraph(&mut state.placeholder, placeholder_text); - if is_secure { - renderer.update_paragraph( - &mut state.paragraph, - Text { - content: &value.secure().to_string(), - ..placeholder_text - }, - ); - } else { - renderer.update_paragraph( - &mut state.paragraph, - Text { - content: &value.to_string(), - ..placeholder_text - }, - ); - } + let secure_value = is_secure.then(|| value.secure()); + let value = secure_value.as_ref().unwrap_or(value); + + renderer.update_paragraph( + &mut state.value, + Text { + content: &value.to_string(), + ..placeholder_text + }, + ); if let Some(icon) = icon { let icon_width = 0.0; // TODO @@ -1078,7 +1070,7 @@ pub fn draw( cursor::State::Index(position) => { let (text_value_width, offset) = measure_cursor_and_scroll_offset( - &state.paragraph, + &state.value, text_bounds, position, ); @@ -1116,14 +1108,14 @@ pub fn draw( let (left_position, left_offset) = measure_cursor_and_scroll_offset( - &state.paragraph, + &state.value, text_bounds, left, ); let (right_position, right_offset) = measure_cursor_and_scroll_offset( - &state.paragraph, + &state.value, text_bounds, right, ); @@ -1157,7 +1149,7 @@ pub fn draw( (None, 0.0) }; - let text_width = state.paragraph.min_width(); + let text_width = state.value.min_width(); let render = |renderer: &mut Renderer| { if let Some((cursor, color)) = cursor { @@ -1168,9 +1160,9 @@ pub fn draw( renderer.fill_paragraph( if text.is_empty() { - &state.placeholder_paragraph + &state.placeholder } else { - &state.paragraph + &state.value }, Point::new(text_bounds.x, text_bounds.center_y()), if text.is_empty() { @@ -1212,8 +1204,8 @@ pub fn mouse_interaction( /// The state of a [`TextInput`]. #[derive(Debug, Default, Clone)] pub struct State { - paragraph: P, - placeholder_paragraph: P, + value: P, + placeholder: P, is_focused: Option, is_dragging: bool, is_pasting: Option, @@ -1239,8 +1231,8 @@ impl State

{ /// Creates a new [`State`], representing a focused [`TextInput`]. pub fn focused() -> Self { Self { - paragraph: P::default(), - placeholder_paragraph: P::default(), + value: P::default(), + placeholder: P::default(), is_focused: None, is_dragging: false, is_pasting: None, @@ -1357,7 +1349,7 @@ fn offset( }; let (_, offset) = measure_cursor_and_scroll_offset( - &state.paragraph, + &state.value, text_bounds, focus_position, ); @@ -1394,7 +1386,7 @@ fn find_cursor_position( let value = value.to_string(); let char_offset = state - .paragraph + .value .hit_test(Point::new(x + offset, text_bounds.height / 2.0)) .map(text::Hit::cursor)?; @@ -1424,7 +1416,7 @@ fn replace_paragraph( let mut children_layout = layout.children(); let text_bounds = children_layout.next().unwrap().bounds(); - state.paragraph = renderer.create_paragraph(Text { + state.value = renderer.create_paragraph(Text { font, line_height, content: &value.to_string(), From b51ffe53ed540d27022157dfb202364825806699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 30 Aug 2023 06:44:40 +0200 Subject: [PATCH 092/321] Fix unnecessary dereference in `widget::text` --- core/src/widget/text.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/widget/text.rs b/core/src/widget/text.rs index b349399b..53ed463e 100644 --- a/core/src/widget/text.rs +++ b/core/src/widget/text.rs @@ -266,7 +266,7 @@ pub fn draw( }; renderer.fill_paragraph( - ¶graph, + paragraph, Point::new(x, y), appearance.color.unwrap_or(style.text_color), ); From 252a05c7f4013991f94ab1b60f138a4c49fdcbfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 30 Aug 2023 07:26:48 +0200 Subject: [PATCH 093/321] Update `CHANGELOG` --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e69b26eb..d80dc5e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added +- Explicit text caching. [#2058](https://github.com/iced-rs/iced/pull/2058) + +Many thanks to... + +- Add your name here + ## [0.10.0] - 2023-07-28 ### Added - Text shaping, font fallback, and `iced_wgpu` overhaul. [#1697](https://github.com/iced-rs/iced/pull/1697) From ce22d661fa2f4b50d2e7d9ba6bd07e625ec6789e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 1 Sep 2023 03:25:29 +0200 Subject: [PATCH 094/321] Remove `Clone` implementation for `Paragraph` --- graphics/src/text/paragraph.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphics/src/text/paragraph.rs b/graphics/src/text/paragraph.rs index 7b70376a..f04b1e69 100644 --- a/graphics/src/text/paragraph.rs +++ b/graphics/src/text/paragraph.rs @@ -7,7 +7,7 @@ use crate::text::{self, FontSystem}; use std::fmt; use std::sync::{self, Arc}; -#[derive(Clone, PartialEq, Default)] +#[derive(PartialEq, Default)] pub struct Paragraph(Arc); struct Internal { From 935c722a278071d3bcd0bf499a0ef8f687ed51ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 1 Sep 2023 03:59:57 +0200 Subject: [PATCH 095/321] Use `Arc::try_unwrap` in `Paragraph` We use `MaybeUninit` here instead of `Option` to save some cycles, but I will most likely change it for an `Option` since unsafe code is quite scary. --- graphics/src/text/paragraph.rs | 150 ++++++++++++++++++++------------- 1 file changed, 93 insertions(+), 57 deletions(-) diff --git a/graphics/src/text/paragraph.rs b/graphics/src/text/paragraph.rs index f04b1e69..c6921005 100644 --- a/graphics/src/text/paragraph.rs +++ b/graphics/src/text/paragraph.rs @@ -5,10 +5,10 @@ use crate::core::{Font, Pixels, Point, Size}; use crate::text::{self, FontSystem}; use std::fmt; +use std::mem::MaybeUninit; use std::sync::{self, Arc}; -#[derive(PartialEq, Default)] -pub struct Paragraph(Arc); +pub struct Paragraph(MaybeUninit>); struct Internal { buffer: cosmic_text::Buffer, @@ -21,6 +21,12 @@ struct Internal { min_bounds: Size, } +impl Default for Paragraph { + fn default() -> Self { + Self(MaybeUninit::new(Arc::new(Internal::default()))) + } +} + impl Paragraph { pub fn new() -> Self { Self::default() @@ -52,7 +58,7 @@ impl Paragraph { let min_bounds = text::measure(&buffer); - Self(Arc::new(Internal { + Self(MaybeUninit::new(Arc::new(Internal { buffer, content: text.content.to_owned(), font: text.font, @@ -61,54 +67,80 @@ impl Paragraph { shaping: text.shaping, bounds: text.bounds, min_bounds, - })) + }))) } pub fn buffer(&self) -> &cosmic_text::Buffer { - &self.0.buffer + #[allow(unsafe_code)] + &unsafe { self.0.assume_init_ref() }.buffer } pub fn downgrade(&self) -> Weak { + #[allow(unsafe_code)] + let paragraph = unsafe { self.0.assume_init_ref() }; + Weak { - raw: Arc::downgrade(&self.0), - min_bounds: self.0.min_bounds, - horizontal_alignment: self.0.horizontal_alignment, - vertical_alignment: self.0.vertical_alignment, + raw: Arc::downgrade(paragraph), + min_bounds: paragraph.min_bounds, + horizontal_alignment: paragraph.horizontal_alignment, + vertical_alignment: paragraph.vertical_alignment, } } pub fn resize(&mut self, new_bounds: Size, font_system: &FontSystem) { - if let Some(internal) = Arc::get_mut(&mut self.0) { - // If there is no strong reference holding on to the paragraph, we - // resize the buffer in-place - internal.buffer.set_size( - &mut font_system.write(), - new_bounds.width, - new_bounds.height, - ); + // Place uninit for now, we always write to `self.0` in the end + let paragraph = std::mem::replace(&mut self.0, MaybeUninit::uninit()); - internal.bounds = new_bounds; - internal.min_bounds = text::measure(&internal.buffer); - } else { - let metrics = self.0.buffer.metrics(); + // Mutable self guarantees unique access and `uninit` call only happens + // in this method. + #[allow(unsafe_code)] + let paragraph = unsafe { paragraph.assume_init() }; - // If there is a strong reference somewhere, we recompute the buffer - // from scratch - *self = Self::with_text( - Text { - content: &self.0.content, - bounds: self.0.bounds, - size: Pixels(metrics.font_size), - line_height: LineHeight::Absolute(Pixels( - metrics.line_height, - )), - font: self.0.font, - horizontal_alignment: self.0.horizontal_alignment, - vertical_alignment: self.0.vertical_alignment, - shaping: self.0.shaping, - }, - font_system, - ); + match Arc::try_unwrap(paragraph) { + Ok(mut internal) => { + internal.buffer.set_size( + &mut font_system.write(), + new_bounds.width, + new_bounds.height, + ); + + internal.bounds = new_bounds; + internal.min_bounds = text::measure(&internal.buffer); + + let _ = self.0.write(Arc::new(internal)); + } + Err(internal) => { + let metrics = internal.buffer.metrics(); + + // If there is a strong reference somewhere, we recompute the + // buffer from scratch + let new_paragraph = Self::with_text( + Text { + content: &internal.content, + bounds: internal.bounds, + size: Pixels(metrics.font_size), + line_height: LineHeight::Absolute(Pixels( + metrics.line_height, + )), + font: internal.font, + horizontal_alignment: internal.horizontal_alignment, + vertical_alignment: internal.vertical_alignment, + shaping: internal.shaping, + }, + font_system, + ); + + // New paragraph should always be initialized + #[allow(unsafe_code)] + let _ = self.0.write(unsafe { new_paragraph.0.assume_init() }); + } + } + } + + fn internal_ref(&self) -> &Internal { + #[allow(unsafe_code)] + unsafe { + self.0.assume_init_ref() } } } @@ -117,49 +149,51 @@ impl core::text::Paragraph for Paragraph { type Font = Font; fn content(&self) -> &str { - &self.0.content + &self.internal_ref().content } fn text_size(&self) -> Pixels { - Pixels(self.0.buffer.metrics().font_size) + Pixels(self.internal_ref().buffer.metrics().font_size) } fn line_height(&self) -> LineHeight { - LineHeight::Absolute(Pixels(self.0.buffer.metrics().line_height)) + LineHeight::Absolute(Pixels( + self.internal_ref().buffer.metrics().line_height, + )) } fn font(&self) -> Font { - self.0.font + self.internal_ref().font } fn shaping(&self) -> Shaping { - self.0.shaping + self.internal_ref().shaping } fn horizontal_alignment(&self) -> alignment::Horizontal { - self.0.horizontal_alignment + self.internal_ref().horizontal_alignment } fn vertical_alignment(&self) -> alignment::Vertical { - self.0.vertical_alignment + self.internal_ref().vertical_alignment } fn bounds(&self) -> Size { - self.0.bounds + self.internal_ref().bounds } fn min_bounds(&self) -> Size { - self.0.min_bounds + self.internal_ref().min_bounds } fn hit_test(&self, point: Point) -> Option { - let cursor = self.0.buffer.hit(point.x, point.y)?; + let cursor = self.internal_ref().buffer.hit(point.x, point.y)?; Some(Hit::CharOffset(cursor.index)) } fn grapheme_position(&self, line: usize, index: usize) -> Option { - let run = self.0.buffer.layout_runs().nth(line)?; + let run = self.internal_ref().buffer.layout_runs().nth(line)?; // TODO: Index represents a grapheme, not a glyph let glyph = run.glyphs.get(index).or_else(|| run.glyphs.last())?; @@ -210,14 +244,16 @@ impl Default for Internal { impl fmt::Debug for Paragraph { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let paragraph = self.internal_ref(); + f.debug_struct("Paragraph") - .field("content", &self.0.content) - .field("font", &self.0.font) - .field("shaping", &self.0.shaping) - .field("horizontal_alignment", &self.0.horizontal_alignment) - .field("vertical_alignment", &self.0.vertical_alignment) - .field("bounds", &self.0.bounds) - .field("min_bounds", &self.0.min_bounds) + .field("content", ¶graph.content) + .field("font", ¶graph.font) + .field("shaping", ¶graph.shaping) + .field("horizontal_alignment", ¶graph.horizontal_alignment) + .field("vertical_alignment", ¶graph.vertical_alignment) + .field("bounds", ¶graph.bounds) + .field("min_bounds", ¶graph.min_bounds) .finish() } } @@ -232,7 +268,7 @@ pub struct Weak { impl Weak { pub fn upgrade(&self) -> Option { - self.raw.upgrade().map(Paragraph) + self.raw.upgrade().map(MaybeUninit::new).map(Paragraph) } } From 51e69d7040c943aad8453bc03031c75b4cb302bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 1 Sep 2023 04:04:15 +0200 Subject: [PATCH 096/321] Replace `MaybeUninit` with `Option` in `paragraph` --- graphics/src/text/paragraph.rs | 72 +++++++++++++--------------------- 1 file changed, 28 insertions(+), 44 deletions(-) diff --git a/graphics/src/text/paragraph.rs b/graphics/src/text/paragraph.rs index c6921005..8e8907f9 100644 --- a/graphics/src/text/paragraph.rs +++ b/graphics/src/text/paragraph.rs @@ -5,10 +5,10 @@ use crate::core::{Font, Pixels, Point, Size}; use crate::text::{self, FontSystem}; use std::fmt; -use std::mem::MaybeUninit; use std::sync::{self, Arc}; -pub struct Paragraph(MaybeUninit>); +#[derive(Clone, PartialEq, Default)] +pub struct Paragraph(Option>); struct Internal { buffer: cosmic_text::Buffer, @@ -21,12 +21,6 @@ struct Internal { min_bounds: Size, } -impl Default for Paragraph { - fn default() -> Self { - Self(MaybeUninit::new(Arc::new(Internal::default()))) - } -} - impl Paragraph { pub fn new() -> Self { Self::default() @@ -58,7 +52,7 @@ impl Paragraph { let min_bounds = text::measure(&buffer); - Self(MaybeUninit::new(Arc::new(Internal { + Self(Some(Arc::new(Internal { buffer, content: text.content.to_owned(), font: text.font, @@ -71,13 +65,11 @@ impl Paragraph { } pub fn buffer(&self) -> &cosmic_text::Buffer { - #[allow(unsafe_code)] - &unsafe { self.0.assume_init_ref() }.buffer + &self.internal().buffer } pub fn downgrade(&self) -> Weak { - #[allow(unsafe_code)] - let paragraph = unsafe { self.0.assume_init_ref() }; + let paragraph = self.internal(); Weak { raw: Arc::downgrade(paragraph), @@ -88,13 +80,10 @@ impl Paragraph { } pub fn resize(&mut self, new_bounds: Size, font_system: &FontSystem) { - // Place uninit for now, we always write to `self.0` in the end - let paragraph = std::mem::replace(&mut self.0, MaybeUninit::uninit()); - - // Mutable self guarantees unique access and `uninit` call only happens - // in this method. - #[allow(unsafe_code)] - let paragraph = unsafe { paragraph.assume_init() }; + let paragraph = self + .0 + .take() + .expect("paragraph should always be initialized"); match Arc::try_unwrap(paragraph) { Ok(mut internal) => { @@ -107,14 +96,14 @@ impl Paragraph { internal.bounds = new_bounds; internal.min_bounds = text::measure(&internal.buffer); - let _ = self.0.write(Arc::new(internal)); + self.0 = Some(Arc::new(internal)); } Err(internal) => { let metrics = internal.buffer.metrics(); // If there is a strong reference somewhere, we recompute the // buffer from scratch - let new_paragraph = Self::with_text( + *self = Self::with_text( Text { content: &internal.content, bounds: internal.bounds, @@ -129,19 +118,14 @@ impl Paragraph { }, font_system, ); - - // New paragraph should always be initialized - #[allow(unsafe_code)] - let _ = self.0.write(unsafe { new_paragraph.0.assume_init() }); } } } - fn internal_ref(&self) -> &Internal { - #[allow(unsafe_code)] - unsafe { - self.0.assume_init_ref() - } + fn internal(&self) -> &Arc { + self.0 + .as_ref() + .expect("paragraph should always be initialized") } } @@ -149,51 +133,51 @@ impl core::text::Paragraph for Paragraph { type Font = Font; fn content(&self) -> &str { - &self.internal_ref().content + &self.internal().content } fn text_size(&self) -> Pixels { - Pixels(self.internal_ref().buffer.metrics().font_size) + Pixels(self.internal().buffer.metrics().font_size) } fn line_height(&self) -> LineHeight { LineHeight::Absolute(Pixels( - self.internal_ref().buffer.metrics().line_height, + self.internal().buffer.metrics().line_height, )) } fn font(&self) -> Font { - self.internal_ref().font + self.internal().font } fn shaping(&self) -> Shaping { - self.internal_ref().shaping + self.internal().shaping } fn horizontal_alignment(&self) -> alignment::Horizontal { - self.internal_ref().horizontal_alignment + self.internal().horizontal_alignment } fn vertical_alignment(&self) -> alignment::Vertical { - self.internal_ref().vertical_alignment + self.internal().vertical_alignment } fn bounds(&self) -> Size { - self.internal_ref().bounds + self.internal().bounds } fn min_bounds(&self) -> Size { - self.internal_ref().min_bounds + self.internal().min_bounds } fn hit_test(&self, point: Point) -> Option { - let cursor = self.internal_ref().buffer.hit(point.x, point.y)?; + let cursor = self.internal().buffer.hit(point.x, point.y)?; Some(Hit::CharOffset(cursor.index)) } fn grapheme_position(&self, line: usize, index: usize) -> Option { - let run = self.internal_ref().buffer.layout_runs().nth(line)?; + let run = self.internal().buffer.layout_runs().nth(line)?; // TODO: Index represents a grapheme, not a glyph let glyph = run.glyphs.get(index).or_else(|| run.glyphs.last())?; @@ -244,7 +228,7 @@ impl Default for Internal { impl fmt::Debug for Paragraph { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let paragraph = self.internal_ref(); + let paragraph = self.internal(); f.debug_struct("Paragraph") .field("content", ¶graph.content) @@ -268,7 +252,7 @@ pub struct Weak { impl Weak { pub fn upgrade(&self) -> Option { - self.raw.upgrade().map(MaybeUninit::new).map(Paragraph) + self.raw.upgrade().map(Some).map(Paragraph) } } From 6758de2b4348d8990205721027524cf87a9db128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 1 Sep 2023 04:14:06 +0200 Subject: [PATCH 097/321] Fix `Default` implementation for `Paragraph` --- graphics/src/text/paragraph.rs | 40 +++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/graphics/src/text/paragraph.rs b/graphics/src/text/paragraph.rs index 8e8907f9..d99b8412 100644 --- a/graphics/src/text/paragraph.rs +++ b/graphics/src/text/paragraph.rs @@ -7,7 +7,7 @@ use crate::text::{self, FontSystem}; use std::fmt; use std::sync::{self, Arc}; -#[derive(Clone, PartialEq, Default)] +#[derive(Clone, PartialEq)] pub struct Paragraph(Option>); struct Internal { @@ -195,6 +195,28 @@ impl core::text::Paragraph for Paragraph { } } +impl Default for Paragraph { + fn default() -> Self { + Self(Some(Arc::new(Internal::default()))) + } +} + +impl fmt::Debug for Paragraph { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let paragraph = self.internal(); + + f.debug_struct("Paragraph") + .field("content", ¶graph.content) + .field("font", ¶graph.font) + .field("shaping", ¶graph.shaping) + .field("horizontal_alignment", ¶graph.horizontal_alignment) + .field("vertical_alignment", ¶graph.vertical_alignment) + .field("bounds", ¶graph.bounds) + .field("min_bounds", ¶graph.min_bounds) + .finish() + } +} + impl PartialEq for Internal { fn eq(&self, other: &Self) -> bool { self.content == other.content @@ -226,22 +248,6 @@ impl Default for Internal { } } -impl fmt::Debug for Paragraph { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let paragraph = self.internal(); - - f.debug_struct("Paragraph") - .field("content", ¶graph.content) - .field("font", ¶graph.font) - .field("shaping", ¶graph.shaping) - .field("horizontal_alignment", ¶graph.horizontal_alignment) - .field("vertical_alignment", ¶graph.vertical_alignment) - .field("bounds", ¶graph.bounds) - .field("min_bounds", ¶graph.min_bounds) - .finish() - } -} - #[derive(Debug, Clone)] pub struct Weak { raw: sync::Weak, From 548b9d0294cb18a79e1adb9629912e16a4fc353e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 1 Sep 2023 04:15:09 +0200 Subject: [PATCH 098/321] Fix `Widget::layout` for `Component` --- widget/src/lazy/component.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/widget/src/lazy/component.rs b/widget/src/lazy/component.rs index fba057ee..fe99a7f2 100644 --- a/widget/src/lazy/component.rs +++ b/widget/src/lazy/component.rs @@ -258,8 +258,14 @@ where renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { + let t = tree.state.downcast_mut::>>>(); + self.with_element(|element| { - element.as_widget().layout(tree, renderer, limits) + element.as_widget().layout( + &mut t.borrow_mut().as_mut().unwrap().children[0], + renderer, + limits, + ) }) } From 601e5563d101788cbaa6febbe15cdf52e9f3ae9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 1 Sep 2023 04:15:59 +0200 Subject: [PATCH 099/321] Fix `Widget::layout` for `Lazy` --- widget/src/lazy.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/widget/src/lazy.rs b/widget/src/lazy.rs index d980a934..bf695a57 100644 --- a/widget/src/lazy.rs +++ b/widget/src/lazy.rs @@ -157,7 +157,9 @@ where limits: &layout::Limits, ) -> layout::Node { self.with_element(|element| { - element.as_widget().layout(tree, renderer, limits) + element + .as_widget() + .layout(&mut tree.children[0], renderer, limits) }) } From 6cc354fdc4eec6576e0591cd3a2ce37155cbfa09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 3 Sep 2023 00:21:04 +0200 Subject: [PATCH 100/321] Update `wgpu` to `0.17` --- examples/integration/src/main.rs | 1 - wgpu/Cargo.toml | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/integration/src/main.rs b/examples/integration/src/main.rs index 342d4c69..98b58f16 100644 --- a/examples/integration/src/main.rs +++ b/examples/integration/src/main.rs @@ -82,7 +82,6 @@ pub fn main() -> Result<(), Box> { futures::futures::executor::block_on(async { let adapter = wgpu::util::initialize_adapter_from_env_or_default( &instance, - backend, Some(&surface), ) .await diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 69568099..2fade559 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -14,8 +14,8 @@ svg = ["resvg"] web-colors = ["iced_graphics/web-colors"] [dependencies] -wgpu = "0.16" -glyphon = "0.3" +wgpu = "0.17" +glyphon = { git = "https://github.com/grovesNL/glyphon.git", rev = "20f0f8fa80e0d0df4c63634ce9176fa489546ca9" } raw-window-handle = "0.5" guillotiere = "0.6" futures = "0.3" From d4f5dd7c95e5a17df08ef2454954fb9c0e05a834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 3 Sep 2023 00:24:09 +0200 Subject: [PATCH 101/321] Update `CHANGELOG` --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e69b26eb..9d02ef4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed +- Updated `wgpu` to `0.17`. [#2065](https://github.com/iced-rs/iced/pull/2065) + +Many thanks to... + +- Add your here ## [0.10.0] - 2023-07-28 ### Added From d518e7d423f7069ed72d84e39a08e69ac07680fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 3 Sep 2023 00:28:05 +0200 Subject: [PATCH 102/321] Update `wgpu` for Wasm --- wgpu/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 2fade559..b0f70220 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -25,7 +25,7 @@ rustc-hash = "1.1" log = "0.4" [target.'cfg(target_arch = "wasm32")'.dependencies] -wgpu = { version = "0.16", features = ["webgl"] } +wgpu = { version = "0.17", features = ["webgl"] } [dependencies.twox-hash] version = "1.6" From 020fb3c37794fcfa2670c3c0ada949aee95855a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 3 Sep 2023 01:01:33 +0200 Subject: [PATCH 103/321] Fix `iced_wgpu` device selection on Wasm --- core/src/window/redraw_request.rs | 2 +- wgpu/src/window/compositor.rs | 33 ++++++++++++++++++------------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/core/src/window/redraw_request.rs b/core/src/window/redraw_request.rs index 3b4f0fd3..8a59e83c 100644 --- a/core/src/window/redraw_request.rs +++ b/core/src/window/redraw_request.rs @@ -13,7 +13,7 @@ pub enum RedrawRequest { #[cfg(test)] mod tests { use super::*; - use std::time::{Duration, Instant}; + use crate::time::{Duration, Instant}; #[test] fn ordering() { diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index cd5b20cc..5202c7ef 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -6,8 +6,6 @@ use crate::graphics::compositor; use crate::graphics::{Error, Viewport}; use crate::{Backend, Primitive, Renderer, Settings}; -use futures::stream::{self, StreamExt}; - use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle}; use std::marker::PhantomData; @@ -95,14 +93,17 @@ impl Compositor { let limits = [wgpu::Limits::default(), wgpu::Limits::downlevel_defaults()]; - let limits = limits.into_iter().map(|limits| wgpu::Limits { - max_bind_groups: 2, - ..limits - }); + let mut limits = limits + .into_iter() + .map(|limits| wgpu::Limits { + max_bind_groups: 2, + ..limits + }) + .into_iter(); - let (device, queue) = stream::iter(limits) - .filter_map(|limits| async { - adapter.request_device( + let (device, queue) = loop { + if let Some(limits) = limits.next() { + let device = adapter.request_device( &wgpu::DeviceDescriptor { label: Some( "iced_wgpu::window::compositor device descriptor", @@ -111,11 +112,15 @@ impl Compositor { limits, }, None, - ).await.ok() - }) - .boxed() - .next() - .await?; + ).await.ok(); + + if let Some(device) = device { + break Some(device); + } + } + + break None; + }?; Some(Compositor { instance, From 0b28080d3ebda4dda24c9ac9c38e3195d3499be7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 3 Sep 2023 01:05:17 +0200 Subject: [PATCH 104/321] Remove redundant `into_iter` call in `iced_wgpu` --- wgpu/src/window/compositor.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index 5202c7ef..cacfeef2 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -93,13 +93,10 @@ impl Compositor { let limits = [wgpu::Limits::default(), wgpu::Limits::downlevel_defaults()]; - let mut limits = limits - .into_iter() - .map(|limits| wgpu::Limits { - max_bind_groups: 2, - ..limits - }) - .into_iter(); + let mut limits = limits.into_iter().map(|limits| wgpu::Limits { + max_bind_groups: 2, + ..limits + }); let (device, queue) = loop { if let Some(limits) = limits.next() { From 9b9b37e6f83b5e5a8811feb17b484c6b11fa3b8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 3 Sep 2023 01:14:22 +0200 Subject: [PATCH 105/321] Fix adapter selection loop in `iced_wgpu` --- wgpu/src/window/compositor.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index cacfeef2..9e9c63db 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -98,8 +98,9 @@ impl Compositor { ..limits }); - let (device, queue) = loop { - if let Some(limits) = limits.next() { + let (device, queue) = + loop { + let limits = limits.next()?; let device = adapter.request_device( &wgpu::DeviceDescriptor { label: Some( @@ -114,10 +115,7 @@ impl Compositor { if let Some(device) = device { break Some(device); } - } - - break None; - }?; + }?; Some(Compositor { instance, From 832d9f1b01de5a1128f5adcd128f405718c72736 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 3 Sep 2023 01:32:47 +0200 Subject: [PATCH 106/321] Introduce `theme::Custom::with_fn` to generate completely custom themes --- style/src/theme.rs | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/style/src/theme.rs b/style/src/theme.rs index 64497181..893d7202 100644 --- a/style/src/theme.rs +++ b/style/src/theme.rs @@ -1,8 +1,7 @@ //! Use the built-in theme and styles. pub mod palette; -use self::palette::Extended; -pub use self::palette::Palette; +pub use palette::Palette; use crate::application; use crate::button; @@ -40,7 +39,16 @@ pub enum Theme { impl Theme { /// Creates a new custom [`Theme`] from the given [`Palette`]. pub fn custom(palette: Palette) -> Self { - Self::Custom(Box::new(Custom::new(palette))) + Self::custom_with_fn(palette, palette::Extended::generate) + } + + /// Creates a new custom [`Theme`] from the given [`Palette`], with + /// a custom generator of a [`palette::Extended`]. + pub fn custom_with_fn( + palette: Palette, + generate: impl FnOnce(Palette) -> palette::Extended, + ) -> Self { + Self::Custom(Box::new(Custom::with_fn(palette, generate))) } /// Returns the [`Palette`] of the [`Theme`]. @@ -66,15 +74,24 @@ impl Theme { #[derive(Debug, Clone, Copy, PartialEq)] pub struct Custom { palette: Palette, - extended: Extended, + extended: palette::Extended, } impl Custom { /// Creates a [`Custom`] theme from the given [`Palette`]. pub fn new(palette: Palette) -> Self { + Self::with_fn(palette, palette::Extended::generate) + } + + /// Creates a [`Custom`] theme from the given [`Palette`] with + /// a custom generator of a [`palette::Extended`]. + pub fn with_fn( + palette: Palette, + generate: impl FnOnce(Palette) -> palette::Extended, + ) -> Self { Self { palette, - extended: Extended::generate(palette), + extended: generate(palette), } } } From 624d5c2c64a174ccdb5236c65ca49556ac3e13ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 3 Sep 2023 02:28:02 +0200 Subject: [PATCH 107/321] Update `CHANGELOG` --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d02ef4b..a53c81cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- `Theme::Custom::with_fn` for custom extended palette generation. [#2067](https://github.com/iced-rs/iced/pull/2067) + ### Changed - Updated `wgpu` to `0.17`. [#2065](https://github.com/iced-rs/iced/pull/2065) From 8129e2c208d9b13dbd32a309058b0547c723dede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 3 Sep 2023 08:08:27 +0200 Subject: [PATCH 108/321] Implement `draw_paragraph` in `iced_tiny_skia` --- tiny_skia/src/backend.rs | 2 +- tiny_skia/src/text.rs | 156 +++++++++++++++++++++++++-------------- wgpu/src/text.rs | 25 +++---- 3 files changed, 115 insertions(+), 68 deletions(-) diff --git a/tiny_skia/src/backend.rs b/tiny_skia/src/backend.rs index ef587bac..c721d96e 100644 --- a/tiny_skia/src/backend.rs +++ b/tiny_skia/src/backend.rs @@ -405,7 +405,7 @@ impl Backend { let clip_mask = (!physical_bounds.is_within(&clip_bounds)) .then_some(clip_mask as &_); - self.text_pipeline.draw( + self.text_pipeline.draw_cached( content, *bounds + translation, *color, diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index 6047a826..3f57f9b1 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -41,16 +41,34 @@ impl Pipeline { pub fn draw_paragraph( &mut self, - _paragraph: ¶graph::Weak, - _position: Point, - _color: Color, - _scale_factor: f32, - _pixels: &mut tiny_skia::PixmapMut<'_>, - _clip_mask: Option<&tiny_skia::Mask>, + paragraph: ¶graph::Weak, + position: Point, + color: Color, + scale_factor: f32, + pixels: &mut tiny_skia::PixmapMut<'_>, + clip_mask: Option<&tiny_skia::Mask>, ) { + use crate::core::text::Paragraph as _; + + let Some(paragraph) = paragraph.upgrade() else { + return; + }; + + draw( + &mut self.font_system.get_mut(), + &mut self.glyph_cache, + paragraph.buffer(), + Rectangle::new(position, paragraph.min_bounds()), + color, + paragraph.horizontal_alignment(), + paragraph.vertical_alignment(), + scale_factor, + pixels, + clip_mask, + ); } - pub fn draw( + pub fn draw_cached( &mut self, content: &str, bounds: Rectangle, @@ -79,54 +97,25 @@ impl Pipeline { let (_, entry) = self.cache.get_mut().allocate(font_system, key); - let max_width = entry.min_bounds.width * scale_factor; - let total_height = entry.min_bounds.height * scale_factor; + let width = entry.min_bounds.width; + let height = entry.min_bounds.height; - let bounds = bounds * scale_factor; - - let x = match horizontal_alignment { - alignment::Horizontal::Left => bounds.x, - alignment::Horizontal::Center => bounds.x - max_width / 2.0, - alignment::Horizontal::Right => bounds.x - max_width, - }; - - let y = match vertical_alignment { - alignment::Vertical::Top => bounds.y, - alignment::Vertical::Center => bounds.y - total_height / 2.0, - alignment::Vertical::Bottom => bounds.y - total_height, - }; - - let mut swash = cosmic_text::SwashCache::new(); - - for run in entry.buffer.layout_runs() { - for glyph in run.glyphs { - let physical_glyph = glyph.physical((x, y), scale_factor); - - if let Some((buffer, placement)) = self.glyph_cache.allocate( - physical_glyph.cache_key, - color, - font_system, - &mut swash, - ) { - let pixmap = tiny_skia::PixmapRef::from_bytes( - buffer, - placement.width, - placement.height, - ) - .expect("Create glyph pixel map"); - - pixels.draw_pixmap( - physical_glyph.x + placement.left, - physical_glyph.y - placement.top - + (run.line_y * scale_factor).round() as i32, - pixmap, - &tiny_skia::PixmapPaint::default(), - tiny_skia::Transform::identity(), - clip_mask, - ); - } - } - } + draw( + font_system, + &mut self.glyph_cache, + &entry.buffer, + Rectangle { + width, + height, + ..bounds + }, + color, + horizontal_alignment, + vertical_alignment, + scale_factor, + pixels, + clip_mask, + ); } pub fn trim_cache(&mut self) { @@ -135,6 +124,65 @@ impl Pipeline { } } +fn draw( + font_system: &mut cosmic_text::FontSystem, + glyph_cache: &mut GlyphCache, + buffer: &cosmic_text::Buffer, + bounds: Rectangle, + color: Color, + horizontal_alignment: alignment::Horizontal, + vertical_alignment: alignment::Vertical, + scale_factor: f32, + pixels: &mut tiny_skia::PixmapMut<'_>, + clip_mask: Option<&tiny_skia::Mask>, +) { + let bounds = bounds * scale_factor; + + let x = match horizontal_alignment { + alignment::Horizontal::Left => bounds.x, + alignment::Horizontal::Center => bounds.x - bounds.width / 2.0, + alignment::Horizontal::Right => bounds.x - bounds.width, + }; + + let y = match vertical_alignment { + alignment::Vertical::Top => bounds.y, + alignment::Vertical::Center => bounds.y - bounds.height / 2.0, + alignment::Vertical::Bottom => bounds.y - bounds.height, + }; + + let mut swash = cosmic_text::SwashCache::new(); + + for run in buffer.layout_runs() { + for glyph in run.glyphs { + let physical_glyph = glyph.physical((x, y), scale_factor); + + if let Some((buffer, placement)) = glyph_cache.allocate( + physical_glyph.cache_key, + color, + font_system, + &mut swash, + ) { + let pixmap = tiny_skia::PixmapRef::from_bytes( + buffer, + placement.width, + placement.height, + ) + .expect("Create glyph pixel map"); + + pixels.draw_pixmap( + physical_glyph.x + placement.left, + physical_glyph.y - placement.top + + (run.line_y * scale_factor).round() as i32, + pixmap, + &tiny_skia::PixmapPaint::default(), + tiny_skia::Transform::identity(), + clip_mask, + ); + } + } + } +} + #[derive(Debug, Clone, Default)] struct GlyphCache { entries: FxHashMap< diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index ee352368..a1ec511b 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -159,29 +159,28 @@ impl Pipeline { } }; - let x = bounds.x * scale_factor; - let y = bounds.y * scale_factor; - - let max_width = bounds.width * scale_factor; - let total_height = bounds.height * scale_factor; + let bounds = bounds * scale_factor; let left = match horizontal_alignment { - alignment::Horizontal::Left => x, - alignment::Horizontal::Center => x - max_width / 2.0, - alignment::Horizontal::Right => x - max_width, + alignment::Horizontal::Left => bounds.x, + alignment::Horizontal::Center => { + bounds.x - bounds.width / 2.0 + } + alignment::Horizontal::Right => bounds.x - bounds.width, }; let top = match vertical_alignment { - alignment::Vertical::Top => y, - alignment::Vertical::Center => y - total_height / 2.0, - alignment::Vertical::Bottom => y - total_height, + alignment::Vertical::Top => bounds.y, + alignment::Vertical::Center => { + bounds.y - bounds.height / 2.0 + } + alignment::Vertical::Bottom => bounds.y - bounds.height, }; let section_bounds = Rectangle { x: left, y: top, - width: max_width, - height: total_height, + ..bounds }; let clip_bounds = layer_bounds.intersection(§ion_bounds)?; From 1a1da6a1f0ee58d5cdc7365681e0ad5edd0117af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 3 Sep 2023 08:11:36 +0200 Subject: [PATCH 109/321] Remove unnecessary mutable reference in `iced_tiny_skia` --- tiny_skia/src/text.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index 3f57f9b1..2bf35e76 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -55,7 +55,7 @@ impl Pipeline { }; draw( - &mut self.font_system.get_mut(), + self.font_system.get_mut(), &mut self.glyph_cache, paragraph.buffer(), Rectangle::new(position, paragraph.min_bounds()), From 3a44ad3c737cf6cff6f04e03a7778d75fcc0c719 Mon Sep 17 00:00:00 2001 From: Akshay Raina <104209297+akshayr-mecha@users.noreply.github.com> Date: Sat, 2 Sep 2023 02:03:39 +0530 Subject: [PATCH 110/321] fix(examples-styling): fixed checkbox and toggler getting hidden behind scrollbar Column inside scrollable is having Length::Fill so it is taking entire width thus hiding check box and toggler. Added fixed width to scrollable so Lenth::Fill will be relative to fixed width --- examples/styling/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/styling/src/main.rs b/examples/styling/src/main.rs index f8a4c80a..b457df25 100644 --- a/examples/styling/src/main.rs +++ b/examples/styling/src/main.rs @@ -108,6 +108,7 @@ impl Sandbox for Styling { column!["Scroll me!", vertical_space(800), "You did it!"] .width(Length::Fill), ) + .width(300) .height(100); let checkbox = checkbox( From 20bf01a551b967f6f8be4c38ef01d14a690d8835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n?= Date: Sun, 3 Sep 2023 08:28:03 +0200 Subject: [PATCH 111/321] Use `Length::Fill` instead of fixed length in `styling` example --- examples/styling/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/styling/src/main.rs b/examples/styling/src/main.rs index b457df25..51538ec2 100644 --- a/examples/styling/src/main.rs +++ b/examples/styling/src/main.rs @@ -108,7 +108,7 @@ impl Sandbox for Styling { column!["Scroll me!", vertical_space(800), "You did it!"] .width(Length::Fill), ) - .width(300) + .width(Length::Fill) .height(100); let checkbox = checkbox( From aed06ac208d1e80b13c5952adbff78dd7d02c025 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 21 Aug 2023 13:32:44 -0400 Subject: [PATCH 112/321] Support automatic style type casting for Buttons. Changes the signature of Button::style to use `impl Into<...>` instead of taking the style sheet itself. (Matches other widgets). --- widget/src/button.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/widget/src/button.rs b/widget/src/button.rs index 5727c631..18a95c9e 100644 --- a/widget/src/button.rs +++ b/widget/src/button.rs @@ -119,9 +119,9 @@ where /// Sets the style variant of this [`Button`]. pub fn style( mut self, - style: ::Style, + style: impl Into<::Style>, ) -> Self { - self.style = style; + self.style = style.into(); self } } From 28252e64086ad99897e881aa5e27e64654e9bafb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 3 Sep 2023 08:41:08 +0200 Subject: [PATCH 113/321] Update `CHANGELOG` --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a53c81cb..8be92a28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,10 +10,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Updated `wgpu` to `0.17`. [#2065](https://github.com/iced-rs/iced/pull/2065) +- Changed `Button::style` to take an `impl Into<...>` for consistency. [#2046](https://github.com/iced-rs/iced/pull/2046) Many thanks to... -- Add your here +- @dtzxporter ## [0.10.0] - 2023-07-28 ### Added From 89d31913db5d1e46b19b265bf48faccfc9869066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 3 Sep 2023 08:33:46 +0200 Subject: [PATCH 114/321] Update `CHANGELOG` --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a53c81cb..68713158 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,9 +11,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Updated `wgpu` to `0.17`. [#2065](https://github.com/iced-rs/iced/pull/2065) +### Fixed +- Missing `width` attribute in `styling` example. [#2062](https://github.com/iced-rs/iced/pull/2062) + Many thanks to... -- Add your here +- @akshayr-mecha ## [0.10.0] - 2023-07-28 ### Added From 982ea578be1e0b934e75b41cb8d65d2ffe05558a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 3 Sep 2023 08:43:58 +0200 Subject: [PATCH 115/321] Stop verifying the `CHANGELOG` on every PR It's a real pain to keep it up-to-date. Way easier to generate it with a script before release. --- .github/workflows/verify.yml | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 .github/workflows/verify.yml diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml deleted file mode 100644 index 089dd5c9..00000000 --- a/.github/workflows/verify.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Verify -on: - pull_request: - branches: - - master -jobs: - changelog: - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: Check `CHANGELOG.md` has changes - run: | - ! git diff --exit-code origin/master HEAD -- CHANGELOG.md - - name: Check `CHANGELOG.md` thanks the PR author - if: ${{ github.event.pull_request.user.login != 'hecrj' }} - run: | - sed -n '/## \[Unreleased\]/,/^## /p' CHANGELOG.md | sed -n '/Many thanks to.../,//p' | grep '@${{ github.event.pull_request.user.login }}' From 76cec1b1fd533dda37aa53c40ef7665ed3b406b6 Mon Sep 17 00:00:00 2001 From: David Huculak Date: Sun, 3 Sep 2023 19:32:38 -0400 Subject: [PATCH 116/321] use @interpolate(flat) attribute as per the WebGPU spec: User-defined vertex outputs and fragment inputs of scalar or vector integer type must always be specified as @interpolate(flat) https://www.w3.org/TR/WGSL/#interpolation --- wgpu/src/shader/quad.wgsl | 22 +++++++++++----------- wgpu/src/shader/triangle.wgsl | 20 ++++++++++---------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/wgpu/src/shader/quad.wgsl b/wgpu/src/shader/quad.wgsl index fb402158..87055339 100644 --- a/wgpu/src/shader/quad.wgsl +++ b/wgpu/src/shader/quad.wgsl @@ -147,12 +147,12 @@ fn solid_fs_main( struct GradientVertexInput { @location(0) v_pos: vec2, - @location(1) colors_1: vec4, - @location(2) colors_2: vec4, - @location(3) colors_3: vec4, - @location(4) colors_4: vec4, - @location(5) offsets: vec4, - @location(6) direction: vec4, + @location(1) @interpolate(flat) colors_1: vec4, + @location(2) @interpolate(flat) colors_2: vec4, + @location(3) @interpolate(flat) colors_3: vec4, + @location(4) @interpolate(flat) colors_4: vec4, + @location(5) @interpolate(flat) offsets: vec4, + @location(6) @interpolate(flat) direction: vec4, @location(7) position_and_scale: vec4, @location(8) border_color: vec4, @location(9) border_radius: vec4, @@ -161,11 +161,11 @@ struct GradientVertexInput { struct GradientVertexOutput { @builtin(position) position: vec4, - @location(1) colors_1: vec4, - @location(2) colors_2: vec4, - @location(3) colors_3: vec4, - @location(4) colors_4: vec4, - @location(5) offsets: vec4, + @location(1) @interpolate(flat) colors_1: vec4, + @location(2) @interpolate(flat) colors_2: vec4, + @location(3) @interpolate(flat) colors_3: vec4, + @location(4) @interpolate(flat) colors_4: vec4, + @location(5) @interpolate(flat) offsets: vec4, @location(6) direction: vec4, @location(7) position_and_scale: vec4, @location(8) border_color: vec4, diff --git a/wgpu/src/shader/triangle.wgsl b/wgpu/src/shader/triangle.wgsl index 9f512d14..3a2b9845 100644 --- a/wgpu/src/shader/triangle.wgsl +++ b/wgpu/src/shader/triangle.wgsl @@ -38,22 +38,22 @@ fn solid_fs_main(input: SolidVertexOutput) -> @location(0) vec4 { struct GradientVertexInput { @location(0) v_pos: vec2, - @location(1) colors_1: vec4, - @location(2) colors_2: vec4, - @location(3) colors_3: vec4, - @location(4) colors_4: vec4, - @location(5) offsets: vec4, + @location(1) @interpolate(flat) colors_1: vec4, + @location(2) @interpolate(flat) colors_2: vec4, + @location(3) @interpolate(flat) colors_3: vec4, + @location(4) @interpolate(flat) colors_4: vec4, + @location(5) @interpolate(flat) offsets: vec4, @location(6) direction: vec4, } struct GradientVertexOutput { @builtin(position) position: vec4, @location(0) raw_position: vec2, - @location(1) colors_1: vec4, - @location(2) colors_2: vec4, - @location(3) colors_3: vec4, - @location(4) colors_4: vec4, - @location(5) offsets: vec4, + @location(1) @interpolate(flat) colors_1: vec4, + @location(2) @interpolate(flat) colors_2: vec4, + @location(3) @interpolate(flat) colors_3: vec4, + @location(4) @interpolate(flat) colors_4: vec4, + @location(5) @interpolate(flat) offsets: vec4, @location(6) direction: vec4, } From 34495bba1c1ffaa4ea2bab46103b5d66e333c51e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 4 Sep 2023 02:55:09 +0200 Subject: [PATCH 117/321] Introduce `keyed::Column` widget --- core/src/widget/tree.rs | 82 +++++++++ examples/todos/Cargo.toml | 4 +- examples/todos/src/main.rs | 24 ++- graphics/src/text/paragraph.rs | 2 + widget/src/helpers.rs | 13 +- widget/src/keyed.rs | 55 ++++++ widget/src/keyed/column.rs | 320 +++++++++++++++++++++++++++++++++ widget/src/lib.rs | 1 + 8 files changed, 490 insertions(+), 11 deletions(-) create mode 100644 widget/src/keyed.rs create mode 100644 widget/src/keyed/column.rs diff --git a/core/src/widget/tree.rs b/core/src/widget/tree.rs index 0af40c33..202cca9a 100644 --- a/core/src/widget/tree.rs +++ b/core/src/widget/tree.rs @@ -107,6 +107,88 @@ impl Tree { } } +/// Reconciliates the `current_children` with the provided list of widgets using +/// custom logic both for diffing and creating new widget state. +/// +/// The algorithm will try to minimize the impact of diffing by querying the +/// `maybe_changed` closure. +pub fn diff_children_custom_with_search( + current_children: &mut Vec, + new_children: &[T], + diff: impl Fn(&mut Tree, &T), + maybe_changed: impl Fn(usize) -> bool, + new_state: impl Fn(&T) -> Tree, +) { + if new_children.is_empty() { + current_children.clear(); + return; + } + + if current_children.is_empty() { + current_children.extend(new_children.iter().map(new_state)); + return; + } + + let first_maybe_changed = maybe_changed(0); + let last_maybe_changed = maybe_changed(current_children.len() - 1); + + if current_children.len() > new_children.len() { + if !first_maybe_changed && last_maybe_changed { + current_children.truncate(new_children.len()); + } else { + let difference_index = if first_maybe_changed { + 0 + } else { + (1..current_children.len()) + .find(|&i| maybe_changed(i)) + .unwrap_or(0) + }; + + let _ = current_children.splice( + difference_index + ..difference_index + + (current_children.len() - new_children.len()), + std::iter::empty(), + ); + } + } + + if current_children.len() < new_children.len() { + let first_maybe_changed = maybe_changed(0); + let last_maybe_changed = maybe_changed(current_children.len() - 1); + + if !first_maybe_changed && last_maybe_changed { + current_children.extend( + new_children[current_children.len()..].iter().map(new_state), + ); + } else { + let difference_index = if first_maybe_changed { + 0 + } else { + (1..current_children.len()) + .find(|&i| maybe_changed(i)) + .unwrap_or(0) + }; + + let _ = current_children.splice( + difference_index..difference_index, + new_children[difference_index + ..difference_index + + (new_children.len() - current_children.len())] + .iter() + .map(new_state), + ); + } + } + + // TODO: Merge loop with extend logic (?) + for (child_state, new) in + current_children.iter_mut().zip(new_children.iter()) + { + diff(child_state, new); + } +} + /// The identifier of some widget state. #[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)] pub struct Tag(any::TypeId); diff --git a/examples/todos/Cargo.toml b/examples/todos/Cargo.toml index 7ad4d558..4a35cfe6 100644 --- a/examples/todos/Cargo.toml +++ b/examples/todos/Cargo.toml @@ -7,9 +7,11 @@ publish = false [dependencies] iced = { path = "../..", features = ["async-std", "debug"] } +uuid = { version = "1.0", features = ["v4", "fast-rng", "serde"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -once_cell = "1.15" +once_cell = "1.0" +tracing-subscriber = "0.3" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] async-std = "1.0" diff --git a/examples/todos/src/main.rs b/examples/todos/src/main.rs index 6ad7b4fb..1dd8a307 100644 --- a/examples/todos/src/main.rs +++ b/examples/todos/src/main.rs @@ -5,8 +5,8 @@ use iced::keyboard::{self, KeyCode, Modifiers}; use iced::subscription; use iced::theme::{self, Theme}; use iced::widget::{ - self, button, checkbox, column, container, row, scrollable, text, - text_input, Text, + self, button, checkbox, column, container, keyed_column, row, scrollable, + text, text_input, Text, }; use iced::window; use iced::{Application, Element}; @@ -14,10 +14,13 @@ use iced::{Color, Command, Length, Settings, Subscription}; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; +use uuid::Uuid; static INPUT_ID: Lazy = Lazy::new(text_input::Id::unique); pub fn main() -> iced::Result { + tracing_subscriber::fmt::init(); + Todos::run(Settings { window: window::Settings { size: (500, 800), @@ -222,17 +225,19 @@ impl Application for Todos { tasks.iter().filter(|task| filter.matches(task)); let tasks: Element<_> = if filtered_tasks.count() > 0 { - column( + keyed_column( tasks .iter() .enumerate() .filter(|(_, task)| filter.matches(task)) .map(|(i, task)| { - task.view(i).map(move |message| { - Message::TaskMessage(i, message) - }) - }) - .collect(), + ( + task.id, + task.view(i).map(move |message| { + Message::TaskMessage(i, message) + }), + ) + }), ) .spacing(10) .into() @@ -295,6 +300,8 @@ impl Application for Todos { #[derive(Debug, Clone, Serialize, Deserialize)] struct Task { + #[serde(default = "Uuid::new_v4")] + id: Uuid, description: String, completed: bool, @@ -330,6 +337,7 @@ impl Task { fn new(description: String) -> Self { Task { + id: Uuid::new_v4(), description, completed: false, state: TaskState::Idle, diff --git a/graphics/src/text/paragraph.rs b/graphics/src/text/paragraph.rs index d99b8412..ee7c04c8 100644 --- a/graphics/src/text/paragraph.rs +++ b/graphics/src/text/paragraph.rs @@ -27,6 +27,8 @@ impl Paragraph { } pub fn with_text(text: Text<'_, Font>, font_system: &FontSystem) -> Self { + log::trace!("\nAllocating paragraph: {}", text.content); + let mut font_system = font_system.write(); let mut buffer = cosmic_text::Buffer::new( diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs index 9c3c83a9..c885d724 100644 --- a/widget/src/helpers.rs +++ b/widget/src/helpers.rs @@ -6,6 +6,7 @@ use crate::container::{self, Container}; use crate::core; use crate::core::widget::operation; use crate::core::{Element, Length, Pixels}; +use crate::keyed; use crate::overlay; use crate::pick_list::{self, PickList}; use crate::progress_bar::{self, ProgressBar}; @@ -63,14 +64,22 @@ where } /// Creates a new [`Column`] with the given children. -/// -/// [`Column`]: widget::Column pub fn column( children: Vec>, ) -> Column<'_, Message, Renderer> { Column::with_children(children) } +/// Creates a new [`keyed::Column`] with the given children. +pub fn keyed_column<'a, Key, Message, Renderer>( + children: impl IntoIterator)>, +) -> keyed::Column<'a, Key, Message, Renderer> +where + Key: Copy + PartialEq, +{ + keyed::Column::with_children(children) +} + /// Creates a new [`Row`] with the given children. /// /// [`Row`]: widget::Row diff --git a/widget/src/keyed.rs b/widget/src/keyed.rs new file mode 100644 index 00000000..55019535 --- /dev/null +++ b/widget/src/keyed.rs @@ -0,0 +1,55 @@ +//! Use widgets that can provide hints to ensure continuity. +//! +//! # What is continuity? +//! Continuity is the feeling of persistence of state. +//! +//! In a graphical user interface, users expect widgets to have a +//! certain degree of continuous state. For instance, a text input +//! that is focused should stay focused even if the widget tree +//! changes slightly. +//! +//! Continuity is tricky in `iced` and the Elm Architecture because +//! the whole widget tree is rebuilt during every `view` call. This is +//! very convenient from a developer perspective because you can build +//! extremely dynamic interfaces without worrying about changing state. +//! +//! However, the tradeoff is that determining what changed becomes hard +//! for `iced`. If you have a list of things, adding an element at the +//! top may cause a loss of continuity on every element on the list! +//! +//! # How can we keep continuity? +//! The good news is that user interfaces generally have a static widget +//! structure. This structure can be relied on to ensure some degree of +//! continuity. `iced` already does this. +//! +//! However, sometimes you have a certain part of your interface that is +//! quite dynamic. For instance, a list of things where items may be added +//! or removed at any place. +//! +//! There are different ways to mitigate this during the reconciliation +//! stage, but they involve comparing trees at certain depths and +//! backtracking... Quite computationally expensive. +//! +//! One approach that is cheaper consists in letting the user provide some hints +//! about the identities of the different widgets so that they can be compared +//! directly without going deeper. +//! +//! The widgets in this module will all ask for a "hint" of some sort. In order +//! to help them keep continuity, you need to make sure the hint stays the same +//! for the same items in your user interface between `view` calls. +pub mod column; + +pub use column::Column; + +/// Creates a [`Column`] with the given children. +/// +/// [`Column`]: widget::Column +#[macro_export] +macro_rules! keyed_column { + () => ( + $crate::Column::new() + ); + ($($x:expr),+ $(,)?) => ( + $crate::keyed::Column::with_children(vec![$($crate::core::Element::from($x)),+]) + ); +} diff --git a/widget/src/keyed/column.rs b/widget/src/keyed/column.rs new file mode 100644 index 00000000..19016679 --- /dev/null +++ b/widget/src/keyed/column.rs @@ -0,0 +1,320 @@ +//! Distribute content vertically. +use crate::core::event::{self, Event}; +use crate::core::layout; +use crate::core::mouse; +use crate::core::overlay; +use crate::core::renderer; +use crate::core::widget::tree::{self, Tree}; +use crate::core::widget::Operation; +use crate::core::{ + Alignment, Clipboard, Element, Layout, Length, Padding, Pixels, Rectangle, + Shell, Widget, +}; + +/// A container that distributes its contents vertically. +#[allow(missing_debug_implementations)] +pub struct Column<'a, Key, Message, Renderer = crate::Renderer> +where + Key: Copy + PartialEq, +{ + spacing: f32, + padding: Padding, + width: Length, + height: Length, + max_width: f32, + align_items: Alignment, + keys: Vec, + children: Vec>, +} + +impl<'a, Key, Message, Renderer> Column<'a, Key, Message, Renderer> +where + Key: Copy + PartialEq, +{ + /// Creates an empty [`Column`]. + pub fn new() -> Self { + Self::with_children(Vec::new()) + } + + /// Creates a [`Column`] with the given elements. + pub fn with_children( + children: impl IntoIterator)>, + ) -> Self { + let (keys, children) = children.into_iter().fold( + (Vec::new(), Vec::new()), + |(mut keys, mut children), (key, child)| { + keys.push(key); + children.push(child); + + (keys, children) + }, + ); + + Column { + spacing: 0.0, + padding: Padding::ZERO, + width: Length::Shrink, + height: Length::Shrink, + max_width: f32::INFINITY, + align_items: Alignment::Start, + keys, + children, + } + } + + /// Sets the vertical spacing _between_ elements. + /// + /// Custom margins per element do not exist in iced. You should use this + /// method instead! While less flexible, it helps you keep spacing between + /// elements consistent. + pub fn spacing(mut self, amount: impl Into) -> Self { + self.spacing = amount.into().0; + self + } + + /// Sets the [`Padding`] of the [`Column`]. + pub fn padding>(mut self, padding: P) -> Self { + self.padding = padding.into(); + self + } + + /// Sets the width of the [`Column`]. + pub fn width(mut self, width: impl Into) -> Self { + self.width = width.into(); + self + } + + /// Sets the height of the [`Column`]. + pub fn height(mut self, height: impl Into) -> Self { + self.height = height.into(); + self + } + + /// Sets the maximum width of the [`Column`]. + pub fn max_width(mut self, max_width: impl Into) -> Self { + self.max_width = max_width.into().0; + self + } + + /// Sets the horizontal alignment of the contents of the [`Column`] . + pub fn align_items(mut self, align: Alignment) -> Self { + self.align_items = align; + self + } + + /// Adds an element to the [`Column`]. + pub fn push( + mut self, + key: Key, + child: impl Into>, + ) -> Self { + self.keys.push(key); + self.children.push(child.into()); + self + } +} + +impl<'a, Key, Message, Renderer> Default for Column<'a, Key, Message, Renderer> +where + Key: Copy + PartialEq, +{ + fn default() -> Self { + Self::new() + } +} + +struct State +where + Key: Copy + PartialEq, +{ + keys: Vec, +} + +impl<'a, Key, Message, Renderer> Widget + for Column<'a, Key, Message, Renderer> +where + Renderer: crate::core::Renderer, + Key: Copy + PartialEq + 'static, +{ + fn tag(&self) -> tree::Tag { + tree::Tag::of::>() + } + + fn state(&self) -> tree::State { + tree::State::new(State { + keys: self.keys.clone(), + }) + } + + fn children(&self) -> Vec { + self.children.iter().map(Tree::new).collect() + } + + fn diff(&self, tree: &mut Tree) { + let Tree { + state, children, .. + } = tree; + + let state = state.downcast_mut::>(); + + tree::diff_children_custom_with_search( + children, + &self.children, + |tree, child| child.as_widget().diff(tree), + |index| { + self.keys.get(index).or_else(|| self.keys.last()).copied() + != Some(state.keys[index]) + }, + |child| Tree::new(child.as_widget()), + ); + + if state.keys != self.keys { + state.keys = self.keys.clone(); + } + } + + fn width(&self) -> Length { + self.width + } + + fn height(&self) -> Length { + self.height + } + + fn layout( + &self, + tree: &mut Tree, + renderer: &Renderer, + limits: &layout::Limits, + ) -> layout::Node { + let limits = limits + .max_width(self.max_width) + .width(self.width) + .height(self.height); + + layout::flex::resolve( + layout::flex::Axis::Vertical, + renderer, + &limits, + self.padding, + self.spacing, + self.align_items, + &self.children, + &mut tree.children, + ) + } + + fn operate( + &self, + tree: &mut Tree, + layout: Layout<'_>, + renderer: &Renderer, + operation: &mut dyn Operation, + ) { + operation.container(None, layout.bounds(), &mut |operation| { + self.children + .iter() + .zip(&mut tree.children) + .zip(layout.children()) + .for_each(|((child, state), layout)| { + child + .as_widget() + .operate(state, layout, renderer, operation); + }) + }); + } + + fn on_event( + &mut self, + tree: &mut Tree, + event: Event, + layout: Layout<'_>, + cursor: mouse::Cursor, + renderer: &Renderer, + clipboard: &mut dyn Clipboard, + shell: &mut Shell<'_, Message>, + viewport: &Rectangle, + ) -> event::Status { + self.children + .iter_mut() + .zip(&mut tree.children) + .zip(layout.children()) + .map(|((child, state), layout)| { + child.as_widget_mut().on_event( + state, + event.clone(), + layout, + cursor, + renderer, + clipboard, + shell, + viewport, + ) + }) + .fold(event::Status::Ignored, event::Status::merge) + } + + fn mouse_interaction( + &self, + tree: &Tree, + layout: Layout<'_>, + cursor: mouse::Cursor, + viewport: &Rectangle, + renderer: &Renderer, + ) -> mouse::Interaction { + self.children + .iter() + .zip(&tree.children) + .zip(layout.children()) + .map(|((child, state), layout)| { + child.as_widget().mouse_interaction( + state, layout, cursor, viewport, renderer, + ) + }) + .max() + .unwrap_or_default() + } + + fn draw( + &self, + tree: &Tree, + renderer: &mut Renderer, + theme: &Renderer::Theme, + style: &renderer::Style, + layout: Layout<'_>, + cursor: mouse::Cursor, + viewport: &Rectangle, + ) { + for ((child, state), layout) in self + .children + .iter() + .zip(&tree.children) + .zip(layout.children()) + { + child + .as_widget() + .draw(state, renderer, theme, style, layout, cursor, viewport); + } + } + + fn overlay<'b>( + &'b mut self, + tree: &'b mut Tree, + layout: Layout<'_>, + renderer: &Renderer, + ) -> Option> { + overlay::from_children(&mut self.children, tree, layout, renderer) + } +} + +impl<'a, Key, Message, Renderer> From> + for Element<'a, Message, Renderer> +where + Key: Copy + PartialEq + 'static, + Message: 'a, + Renderer: crate::core::Renderer + 'a, +{ + fn from(column: Column<'a, Key, Message, Renderer>) -> Self { + Self::new(column) + } +} diff --git a/widget/src/lib.rs b/widget/src/lib.rs index 316e8829..707fec04 100644 --- a/widget/src/lib.rs +++ b/widget/src/lib.rs @@ -29,6 +29,7 @@ pub mod button; pub mod checkbox; pub mod combo_box; pub mod container; +pub mod keyed; pub mod overlay; pub mod pane_grid; pub mod pick_list; From 837529bc995a728300c61fc102474cc31f7a6500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 4 Sep 2023 03:02:46 +0200 Subject: [PATCH 118/321] Fix Wasm build of `todos` example --- examples/todos/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/todos/Cargo.toml b/examples/todos/Cargo.toml index 4a35cfe6..7292f665 100644 --- a/examples/todos/Cargo.toml +++ b/examples/todos/Cargo.toml @@ -18,6 +18,7 @@ async-std = "1.0" directories-next = "2.0" [target.'cfg(target_arch = "wasm32")'.dependencies] +uuid = { version = "1.0", features = ["js"] } web-sys = { version = "0.3", features = ["Window", "Storage"] } wasm-timer = "0.2" From bb49a22996f39e32c3ced0c2d80c2137aed7a0ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 4 Sep 2023 03:28:45 +0200 Subject: [PATCH 119/321] Enable WebGPU backend in `wgpu` by default instead of WebGL Instead, we expose a new `webgl` feature. --- Cargo.toml | 2 ++ renderer/Cargo.toml | 1 + wgpu/Cargo.toml | 4 +--- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 71484b7a..3b2ef547 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,6 +39,8 @@ palette = ["iced_core/palette"] system = ["iced_winit/system"] # Enables broken "sRGB linear" blending to reproduce color management of the Web web-colors = ["iced_renderer/web-colors"] +# Enables the WebGL backend, replacing WebGPU +webgl = ["iced_renderer/webgl"] # Enables the advanced module advanced = [] diff --git a/renderer/Cargo.toml b/renderer/Cargo.toml index 89326d73..2c88cf31 100644 --- a/renderer/Cargo.toml +++ b/renderer/Cargo.toml @@ -17,6 +17,7 @@ svg = ["iced_tiny_skia/svg", "iced_wgpu?/svg"] geometry = ["iced_graphics/geometry", "iced_tiny_skia/geometry", "iced_wgpu?/geometry"] tracing = ["iced_wgpu?/tracing"] web-colors = ["iced_wgpu?/web-colors"] +webgl = ["iced_wgpu?/webgl"] [dependencies] raw-window-handle = "0.5" diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index b0f70220..49c62673 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -12,6 +12,7 @@ geometry = ["iced_graphics/geometry", "lyon"] image = ["iced_graphics/image"] svg = ["resvg"] web-colors = ["iced_graphics/web-colors"] +webgl = ["wgpu/webgl"] [dependencies] wgpu = "0.17" @@ -24,9 +25,6 @@ once_cell = "1.0" rustc-hash = "1.1" log = "0.4" -[target.'cfg(target_arch = "wasm32")'.dependencies] -wgpu = { version = "0.17", features = ["webgl"] } - [dependencies.twox-hash] version = "1.6" default-features = false From 685e44587c8c89be455838d6b96f3b762da836f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 4 Sep 2023 03:46:41 +0200 Subject: [PATCH 120/321] Enable unstable `web-sys` APIs on CI --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a9a9b3f9..ac8d27f9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,6 +25,8 @@ jobs: web: runs-on: ubuntu-latest + env: + RUSTFLAGS: --cfg=web_sys_unstable_apis steps: - uses: hecrj/setup-rust-action@v1 with: From ef429fbea6e39efcfdc58fdd8a2fe365fd5314d9 Mon Sep 17 00:00:00 2001 From: Josh Megnauth Date: Mon, 4 Sep 2023 02:58:54 -0400 Subject: [PATCH 121/321] Ensure LineHeight > 0.0 for the WGPU renderer --- wgpu/src/text.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index fb13545d..08a32b5e 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -96,7 +96,8 @@ impl Pipeline { section .line_height .to_absolute(Pixels(section.size)), - ), + ) + .max(f32::MIN_POSITIVE), font: section.font, bounds: Size { width: section.bounds.width, @@ -238,7 +239,8 @@ impl Pipeline { ) -> Size { let mut cache = self.cache.borrow_mut(); - let line_height = f32::from(line_height.to_absolute(Pixels(size))); + let line_height = f32::from(line_height.to_absolute(Pixels(size))) + .max(f32::MIN_POSITIVE); let (_, entry) = cache.allocate( &mut self.font_system.borrow_mut(), @@ -269,7 +271,8 @@ impl Pipeline { ) -> Option { let mut cache = self.cache.borrow_mut(); - let line_height = f32::from(line_height.to_absolute(Pixels(size))); + let line_height = f32::from(line_height.to_absolute(Pixels(size))) + .max(f32::MIN_POSITIVE); let (_, entry) = cache.allocate( &mut self.font_system.borrow_mut(), From f468e25d0c67a01ee79d892f6e8ba9be019f06c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 4 Sep 2023 12:58:41 +0200 Subject: [PATCH 122/321] Use workspace dependencies and package inheritance We are also taking this as a chance to synchronize the versions of all the crates! Because of this, we will skip the `0.11` version. --- Cargo.toml | 135 +++++++++++++++++------- core/Cargo.toml | 30 +++--- examples/arc/Cargo.toml | 3 +- examples/bezier_tool/Cargo.toml | 3 +- examples/checkbox/Cargo.toml | 2 +- examples/clock/Cargo.toml | 6 +- examples/color_palette/Cargo.toml | 6 +- examples/combo_box/Cargo.toml | 3 +- examples/component/Cargo.toml | 3 +- examples/counter/Cargo.toml | 2 +- examples/custom_quad/Cargo.toml | 3 +- examples/custom_widget/Cargo.toml | 3 +- examples/download_progress/Cargo.toml | 3 +- examples/events/Cargo.toml | 3 +- examples/exit/Cargo.toml | 2 +- examples/game_of_life/Cargo.toml | 10 +- examples/game_of_life/src/main.rs | 2 +- examples/geometry/Cargo.toml | 3 +- examples/integration/Cargo.toml | 13 +-- examples/integration/src/main.rs | 2 +- examples/lazy/Cargo.toml | 3 +- examples/loading_spinners/Cargo.toml | 8 +- examples/modal/Cargo.toml | 3 +- examples/multitouch/Cargo.toml | 7 +- examples/multitouch/src/main.rs | 2 +- examples/pane_grid/Cargo.toml | 3 +- examples/pick_list/Cargo.toml | 3 +- examples/pokedex/Cargo.toml | 4 +- examples/progress_bar/Cargo.toml | 2 +- examples/qr_code/Cargo.toml | 3 +- examples/screenshot/Cargo.toml | 8 +- examples/screenshot/src/main.rs | 2 +- examples/scrollable/Cargo.toml | 6 +- examples/sierpinski_triangle/Cargo.toml | 6 +- examples/slider/Cargo.toml | 2 +- examples/solar_system/Cargo.toml | 6 +- examples/solar_system/src/main.rs | 2 +- examples/stopwatch/Cargo.toml | 3 +- examples/styling/Cargo.toml | 2 +- examples/svg/Cargo.toml | 3 +- examples/system_information/Cargo.toml | 6 +- examples/toast/Cargo.toml | 3 +- examples/todos/Cargo.toml | 12 ++- examples/tooltip/Cargo.toml | 3 +- examples/tour/Cargo.toml | 6 +- examples/tour/src/main.rs | 2 +- examples/url_handler/Cargo.toml | 2 +- examples/visible_bounds/Cargo.toml | 6 +- examples/websocket/Cargo.toml | 12 +-- futures/Cargo.toml | 61 +++++------ graphics/Cargo.toml | 62 +++++------ renderer/Cargo.toml | 39 +++---- runtime/Cargo.toml | 28 +++-- src/window/icon.rs | 9 +- style/Cargo.toml | 30 +++--- tiny_skia/Cargo.toml | 54 +++++----- wgpu/Cargo.toml | 80 ++++++-------- widget/Cargo.toml | 57 ++++------ winit/Cargo.toml | 83 +++++---------- 59 files changed, 447 insertions(+), 423 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3b2ef547..af74a3cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,22 +1,28 @@ [package] name = "iced" -version = "0.10.0" -authors = ["HĂ©ctor RamĂłn JimĂ©nez "] -edition = "2021" description = "A cross-platform GUI library inspired by Elm" -license = "MIT" -repository = "https://github.com/iced-rs/iced" -documentation = "https://docs.rs/iced" -readme = "README.md" -keywords = ["gui", "ui", "graphics", "interface", "widgets"] -categories = ["gui"] +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true +categories.workspace = true +keywords.workspace = true + +[package.metadata.docs.rs] +rustdoc-args = ["--cfg", "docsrs"] +all-features = true + +[badges] +maintenance = { status = "actively-developed" } [features] default = ["wgpu"] # Enable the `wgpu` GPU-accelerated renderer backend wgpu = ["iced_renderer/wgpu"] # Enables the `Image` widget -image = ["iced_widget/image", "image_rs"] +image = ["iced_widget/image", "dep:image"] # Enables the `Svg` widget svg = ["iced_widget/svg"] # Enables the `Canvas` widget @@ -44,8 +50,28 @@ webgl = ["iced_renderer/webgl"] # Enables the advanced module advanced = [] -[badges] -maintenance = { status = "actively-developed" } +[dependencies] +iced_core.workspace = true +iced_futures.workspace = true +iced_renderer.workspace = true +iced_widget.workspace = true +iced_winit.features = ["application"] +iced_winit.workspace = true + +thiserror.workspace = true + +image.workspace = true +image.optional = true + +[profile.release-opt] +inherits = "release" +codegen-units = 1 +debug = false +lto = true +incremental = false +opt-level = 3 +overflow-checks = false +strip = "debuginfo" [workspace] members = [ @@ -62,29 +88,66 @@ members = [ "examples/*", ] -[dependencies] -iced_core = { version = "0.10", path = "core" } -iced_futures = { version = "0.7", path = "futures" } -iced_renderer = { version = "0.1", path = "renderer" } -iced_widget = { version = "0.1", path = "widget" } -iced_winit = { version = "0.10", path = "winit", features = ["application"] } -thiserror = "1" +[workspace.package] +version = "0.12.0" +authors = ["HĂ©ctor RamĂłn JimĂ©nez "] +edition = "2021" +license = "MIT" +repository = "https://github.com/iced-rs/iced" +homepage = "https://iced.rs" +categories = ["gui"] +keywords = ["gui", "ui", "graphics", "interface", "widgets"] -[dependencies.image_rs] -version = "0.24" -package = "image" -optional = true +[workspace.dependencies] +iced = { version = "0.12", path = "." } +iced_core = { version = "0.12", path = "core" } +iced_futures = { version = "0.12", path = "futures" } +iced_graphics = { version = "0.12", path = "graphics" } +iced_renderer = { version = "0.12", path = "renderer" } +iced_runtime = { version = "0.12", path = "runtime" } +iced_style = { version = "0.12", path = "style" } +iced_tiny_skia = { version = "0.12", path = "tiny_skia" } +iced_wgpu = { version = "0.12", path = "wgpu" } +iced_widget = { version = "0.12", path = "widget" } +iced_winit = { version = "0.12", path = "winit" } -[package.metadata.docs.rs] -rustdoc-args = ["--cfg", "docsrs"] -all-features = true - -[profile.release-opt] -inherits = "release" -codegen-units = 1 -debug = false -lto = true -incremental = false -opt-level = 3 -overflow-checks = false -strip = "debuginfo" +async-std = "1.0" +bitflags = "1.0" +bytemuck = { version = "1.0", features = ["derive"] } +cosmic-text = "0.9" +futures = "0.3" +glam = "0.24" +glyphon = { git = "https://github.com/grovesNL/glyphon.git", rev = "20f0f8fa80e0d0df4c63634ce9176fa489546ca9" } +guillotiere = "0.6" +half = "2.2" +image = "0.24" +instant = "0.1" +kamadak-exif = "0.5" +kurbo = "0.9" +log = "0.4" +lyon = "1.0" +lyon_path = "1.0" +num-traits = "0.2" +once_cell = "1.0" +ouroboros = "0.17" +palette = "0.7" +qrcode = { version = "0.12", default-features = false } +raw-window-handle = "0.5" +resvg = "0.35" +rustc-hash = "1.0" +smol = "1.0" +softbuffer = "0.2" +sysinfo = "0.28" +thiserror = "1.0" +tiny-skia = "0.10" +tokio = "1.0" +tracing = "0.1" +twox-hash = { version = "1.0", default-features = false } +unicode-segmentation = "1.0" +wasm-bindgen-futures = "0.4" +wasm-timer = "0.2" +web-sys = "0.3" +wgpu = "0.17" +winapi = "0.3" +window_clipboard = "0.3" +winit = { git = "https://github.com/iced-rs/winit.git", rev = "c52db2045d0a2f1b8d9923870de1d4ab1994146e", default-features = false } diff --git a/core/Cargo.toml b/core/Cargo.toml index 8bb37309..8859e91e 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -1,24 +1,26 @@ [package] name = "iced_core" -version = "0.10.0" -authors = ["HĂ©ctor RamĂłn JimĂ©nez "] -edition = "2021" -description = "The essential concepts of Iced" -license = "MIT" -repository = "https://github.com/iced-rs/iced" +description = "The essential ideas of iced" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true +categories.workspace = true +keywords.workspace = true [dependencies] -bitflags = "1.2" -thiserror = "1" -log = "0.4.17" -twox-hash = { version = "1.5", default-features = false } +bitflags.workspace = true +log.workspace = true +thiserror.workspace = true +twox-hash.workspace = true -[dependencies.palette] -version = "0.7" -optional = true +palette.workspace = true +palette.optional = true [target.'cfg(target_arch = "wasm32")'.dependencies] -instant = "0.1" +instant.workspace = true [dev-dependencies] approx = "0.5" diff --git a/examples/arc/Cargo.toml b/examples/arc/Cargo.toml index e6e74363..5012ff82 100644 --- a/examples/arc/Cargo.toml +++ b/examples/arc/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["canvas", "tokio", "debug"] } +iced.workspace = true +iced.features = ["canvas", "tokio", "debug"] diff --git a/examples/bezier_tool/Cargo.toml b/examples/bezier_tool/Cargo.toml index 890e3027..b2547ff1 100644 --- a/examples/bezier_tool/Cargo.toml +++ b/examples/bezier_tool/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["canvas"] } +iced.workspace = true +iced.features = ["canvas"] diff --git a/examples/checkbox/Cargo.toml b/examples/checkbox/Cargo.toml index dde8f910..1e027c4c 100644 --- a/examples/checkbox/Cargo.toml +++ b/examples/checkbox/Cargo.toml @@ -6,4 +6,4 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../.." } +iced.workspace = true diff --git a/examples/clock/Cargo.toml b/examples/clock/Cargo.toml index 5e869eb5..2d3d5908 100644 --- a/examples/clock/Cargo.toml +++ b/examples/clock/Cargo.toml @@ -6,5 +6,7 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["canvas", "tokio", "debug"] } -time = { version = "0.3.5", features = ["local-offset"] } +iced.workspace = true +iced.features = ["canvas", "tokio", "debug"] + +time = { version = "0.3", features = ["local-offset"] } diff --git a/examples/color_palette/Cargo.toml b/examples/color_palette/Cargo.toml index 3be732bb..2da6c6ed 100644 --- a/examples/color_palette/Cargo.toml +++ b/examples/color_palette/Cargo.toml @@ -6,5 +6,7 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["canvas", "palette"] } -palette = "0.7.0" +iced.workspace = true +iced.features = ["canvas", "palette"] + +palette.workspace = true diff --git a/examples/combo_box/Cargo.toml b/examples/combo_box/Cargo.toml index be1b5e32..0f5ecf2a 100644 --- a/examples/combo_box/Cargo.toml +++ b/examples/combo_box/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["debug"] } +iced.workspace = true +iced.features = ["debug"] diff --git a/examples/component/Cargo.toml b/examples/component/Cargo.toml index 9db1e6b4..83b7b8a4 100644 --- a/examples/component/Cargo.toml +++ b/examples/component/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["debug", "lazy"] } +iced.workspace = true +iced.features = ["debug", "lazy"] diff --git a/examples/counter/Cargo.toml b/examples/counter/Cargo.toml index e31f440f..1e9bba6b 100644 --- a/examples/counter/Cargo.toml +++ b/examples/counter/Cargo.toml @@ -6,4 +6,4 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../.." } +iced.workspace = true diff --git a/examples/custom_quad/Cargo.toml b/examples/custom_quad/Cargo.toml index f097c2dd..31b5055d 100644 --- a/examples/custom_quad/Cargo.toml +++ b/examples/custom_quad/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["advanced"] } +iced.workspace = true +iced.features = ["advanced"] diff --git a/examples/custom_widget/Cargo.toml b/examples/custom_widget/Cargo.toml index dda0efe8..1e94bc52 100644 --- a/examples/custom_widget/Cargo.toml +++ b/examples/custom_widget/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["advanced"] } +iced.workspace = true +iced.features = ["advanced"] diff --git a/examples/download_progress/Cargo.toml b/examples/download_progress/Cargo.toml index 212832f4..18a49f66 100644 --- a/examples/download_progress/Cargo.toml +++ b/examples/download_progress/Cargo.toml @@ -6,7 +6,8 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["tokio"] } +iced.workspace = true +iced.features = ["tokio"] [dependencies.reqwest] version = "0.11" diff --git a/examples/events/Cargo.toml b/examples/events/Cargo.toml index 15ffc0af..87315a10 100644 --- a/examples/events/Cargo.toml +++ b/examples/events/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["debug"] } +iced.workspace = true +iced.features = ["debug"] diff --git a/examples/exit/Cargo.toml b/examples/exit/Cargo.toml index 34d0789a..b06fbadc 100644 --- a/examples/exit/Cargo.toml +++ b/examples/exit/Cargo.toml @@ -5,4 +5,4 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../.." } +iced.workspace = true diff --git a/examples/game_of_life/Cargo.toml b/examples/game_of_life/Cargo.toml index 6de45db6..f8d21c65 100644 --- a/examples/game_of_life/Cargo.toml +++ b/examples/game_of_life/Cargo.toml @@ -6,8 +6,10 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["canvas", "tokio", "debug"] } -tokio = { version = "1.0", features = ["sync"] } +iced.workspace = true +iced.features = ["debug", "canvas", "tokio"] + itertools = "0.9" -rustc-hash = "1.1" -env_logger = "0.10" +rustc-hash.workspace = true +tokio = { workspace = true, features = ["sync"] } +tracing-subscriber = "0.3" diff --git a/examples/game_of_life/src/main.rs b/examples/game_of_life/src/main.rs index e951d734..a2038f12 100644 --- a/examples/game_of_life/src/main.rs +++ b/examples/game_of_life/src/main.rs @@ -18,7 +18,7 @@ use iced::{ use std::time::{Duration, Instant}; pub fn main() -> iced::Result { - env_logger::builder().format_timestamp(None).init(); + tracing_subscriber::fmt::init(); GameOfLife::run(Settings { antialiasing: true, diff --git a/examples/geometry/Cargo.toml b/examples/geometry/Cargo.toml index 6068d651..9606dcb3 100644 --- a/examples/geometry/Cargo.toml +++ b/examples/geometry/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["advanced"] } +iced.workspace = true +iced.features = ["advanced"] diff --git a/examples/integration/Cargo.toml b/examples/integration/Cargo.toml index 22914742..4c55daa7 100644 --- a/examples/integration/Cargo.toml +++ b/examples/integration/Cargo.toml @@ -6,18 +6,19 @@ edition = "2021" publish = false [dependencies] -iced_winit = { path = "../../winit" } -iced_wgpu = { path = "../../wgpu" } -iced_widget = { path = "../../widget" } -iced_renderer = { path = "../../renderer", features = ["wgpu"] } -env_logger = "0.10" +iced_winit.workspace = true +iced_wgpu.workspace = true +iced_widget.workspace = true + +tracing-subscriber = "0.3" [target.'cfg(target_arch = "wasm32")'.dependencies] console_error_panic_hook = "0.1.7" console_log = "0.2.0" -log = "0.4" +log.workspace = true wasm-bindgen = "0.2" web-sys = { version = "0.3", features = ["Element", "HtmlCanvasElement", "Window", "Document"] } + # This dependency a little bit quirky, it is deep in the tree and without `js` feature it # refuses to work with `wasm32-unknown-unknown target`. Unfortunately, we need this patch # to make it work diff --git a/examples/integration/src/main.rs b/examples/integration/src/main.rs index 98b58f16..af48af5f 100644 --- a/examples/integration/src/main.rs +++ b/examples/integration/src/main.rs @@ -41,7 +41,7 @@ pub fn main() -> Result<(), Box> { }; #[cfg(not(target_arch = "wasm32"))] - env_logger::init(); + tracing_subscriber::fmt::init(); // Initialize winit let event_loop = EventLoop::new(); diff --git a/examples/lazy/Cargo.toml b/examples/lazy/Cargo.toml index e03e89a9..4ccb9584 100644 --- a/examples/lazy/Cargo.toml +++ b/examples/lazy/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["debug", "lazy"] } +iced.workspace = true +iced.features = ["debug", "lazy"] diff --git a/examples/loading_spinners/Cargo.toml b/examples/loading_spinners/Cargo.toml index ee9a48aa..a32da386 100644 --- a/examples/loading_spinners/Cargo.toml +++ b/examples/loading_spinners/Cargo.toml @@ -6,6 +6,8 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["advanced", "canvas"] } -lyon_algorithms = "1" -once_cell = "1" +iced.workspace = true +iced.features = ["advanced", "canvas"] + +lyon_algorithms = "1.0" +once_cell.workspace = true \ No newline at end of file diff --git a/examples/modal/Cargo.toml b/examples/modal/Cargo.toml index 3ac61e6a..009d9653 100644 --- a/examples/modal/Cargo.toml +++ b/examples/modal/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["advanced"] } +iced.workspace = true +iced.features = ["advanced"] diff --git a/examples/multitouch/Cargo.toml b/examples/multitouch/Cargo.toml index 867312f8..e0d14f58 100644 --- a/examples/multitouch/Cargo.toml +++ b/examples/multitouch/Cargo.toml @@ -6,7 +6,8 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["canvas", "tokio", "debug"] } -tokio = { version = "1.0", features = ["sync"] } -env_logger = "0.10" +iced.workspace = true +iced.features = ["debug", "canvas", "tokio"] + +tracing-subscriber = "0.3" voronator = "0.2" diff --git a/examples/multitouch/src/main.rs b/examples/multitouch/src/main.rs index 2830b78d..ba8df7aa 100644 --- a/examples/multitouch/src/main.rs +++ b/examples/multitouch/src/main.rs @@ -13,7 +13,7 @@ use iced::{ use std::collections::HashMap; pub fn main() -> iced::Result { - env_logger::builder().format_timestamp(None).init(); + tracing_subscriber::fmt::init(); Multitouch::run(Settings { antialiasing: true, diff --git a/examples/pane_grid/Cargo.toml b/examples/pane_grid/Cargo.toml index 4c0bf072..095ecd10 100644 --- a/examples/pane_grid/Cargo.toml +++ b/examples/pane_grid/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["debug", "lazy"] } +iced.workspace = true +iced.features = ["debug", "lazy"] diff --git a/examples/pick_list/Cargo.toml b/examples/pick_list/Cargo.toml index 4aa4603a..030558e7 100644 --- a/examples/pick_list/Cargo.toml +++ b/examples/pick_list/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["debug"] } +iced.workspace = true +iced.features = ["debug"] diff --git a/examples/pokedex/Cargo.toml b/examples/pokedex/Cargo.toml index e99fc0c3..de8a5c17 100644 --- a/examples/pokedex/Cargo.toml +++ b/examples/pokedex/Cargo.toml @@ -6,7 +6,9 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["image", "debug", "tokio"] } +iced.workspace = true +iced.features = ["image", "debug", "tokio"] + serde_json = "1.0" [dependencies.serde] diff --git a/examples/progress_bar/Cargo.toml b/examples/progress_bar/Cargo.toml index 383a9bdd..6624ae15 100644 --- a/examples/progress_bar/Cargo.toml +++ b/examples/progress_bar/Cargo.toml @@ -6,4 +6,4 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../.." } +iced.workspace = true diff --git a/examples/qr_code/Cargo.toml b/examples/qr_code/Cargo.toml index 2f164df6..8f33ea8c 100644 --- a/examples/qr_code/Cargo.toml +++ b/examples/qr_code/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["qr_code"] } +iced.workspace = true +iced.features = ["qr_code"] diff --git a/examples/screenshot/Cargo.toml b/examples/screenshot/Cargo.toml index b79300b7..dcd77439 100644 --- a/examples/screenshot/Cargo.toml +++ b/examples/screenshot/Cargo.toml @@ -6,6 +6,8 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["debug", "image", "advanced"] } -image = { version = "0.24.6", features = ["png"]} -env_logger = "0.10.0" +iced.workspace = true +iced.features = ["debug", "image", "advanced"] + +image = { workspace = true, features = ["png"]} +tracing-subscriber = "0.3" \ No newline at end of file diff --git a/examples/screenshot/src/main.rs b/examples/screenshot/src/main.rs index 83824535..1d8eaa44 100644 --- a/examples/screenshot/src/main.rs +++ b/examples/screenshot/src/main.rs @@ -13,7 +13,7 @@ use ::image as img; use ::image::ColorType; fn main() -> iced::Result { - env_logger::builder().format_timestamp(None).init(); + tracing_subscriber::fmt::init(); Example::run(iced::Settings::default()) } diff --git a/examples/scrollable/Cargo.toml b/examples/scrollable/Cargo.toml index e6411e26..f8c735c0 100644 --- a/examples/scrollable/Cargo.toml +++ b/examples/scrollable/Cargo.toml @@ -6,5 +6,7 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["debug"] } -once_cell = "1.16.0" +iced.workspace = true +iced.features = ["debug"] + +once_cell.workspace = true diff --git a/examples/sierpinski_triangle/Cargo.toml b/examples/sierpinski_triangle/Cargo.toml index 39d45f64..600a9e06 100644 --- a/examples/sierpinski_triangle/Cargo.toml +++ b/examples/sierpinski_triangle/Cargo.toml @@ -6,5 +6,7 @@ edition = "2018" publish = false [dependencies] -iced = { path = "../..", features = ["canvas", "debug"] } -rand = "0.8.4" +iced.workspace = true +iced.features = ["debug", "canvas"] + +rand = "0.8" diff --git a/examples/slider/Cargo.toml b/examples/slider/Cargo.toml index 112d7cff..fad8916e 100644 --- a/examples/slider/Cargo.toml +++ b/examples/slider/Cargo.toml @@ -6,4 +6,4 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../.." } +iced.workspace = true diff --git a/examples/solar_system/Cargo.toml b/examples/solar_system/Cargo.toml index 1a98a87e..ca64da14 100644 --- a/examples/solar_system/Cargo.toml +++ b/examples/solar_system/Cargo.toml @@ -6,6 +6,8 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["canvas", "tokio", "debug"] } -env_logger = "0.10.0" +iced.workspace = true +iced.features = ["debug", "canvas", "tokio"] + rand = "0.8.3" +tracing-subscriber = "0.3" diff --git a/examples/solar_system/src/main.rs b/examples/solar_system/src/main.rs index 58d06206..8fa8946e 100644 --- a/examples/solar_system/src/main.rs +++ b/examples/solar_system/src/main.rs @@ -23,7 +23,7 @@ use iced::{ use std::time::Instant; pub fn main() -> iced::Result { - env_logger::builder().format_timestamp(None).init(); + tracing_subscriber::fmt::init(); SolarSystem::run(Settings { antialiasing: true, diff --git a/examples/stopwatch/Cargo.toml b/examples/stopwatch/Cargo.toml index f623feb9..6b1419f6 100644 --- a/examples/stopwatch/Cargo.toml +++ b/examples/stopwatch/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["smol"] } +iced.workspace = true +iced.features = ["smol"] diff --git a/examples/styling/Cargo.toml b/examples/styling/Cargo.toml index f771708c..c8a90258 100644 --- a/examples/styling/Cargo.toml +++ b/examples/styling/Cargo.toml @@ -6,4 +6,4 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../.." } +iced.workspace = true diff --git a/examples/svg/Cargo.toml b/examples/svg/Cargo.toml index f5a6eaa2..78208fb0 100644 --- a/examples/svg/Cargo.toml +++ b/examples/svg/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["svg"] } +iced.workspace = true +iced.features = ["svg"] diff --git a/examples/system_information/Cargo.toml b/examples/system_information/Cargo.toml index 7d1e4b94..41903122 100644 --- a/examples/system_information/Cargo.toml +++ b/examples/system_information/Cargo.toml @@ -6,5 +6,7 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["system"] } -bytesize = { version = "1.1.0" } +iced.workspace = true +iced.features = ["system"] + +bytesize = "1.1" diff --git a/examples/toast/Cargo.toml b/examples/toast/Cargo.toml index f703572c..113313e2 100644 --- a/examples/toast/Cargo.toml +++ b/examples/toast/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["advanced"] } +iced.workspace = true +iced.features = ["advanced"] diff --git a/examples/todos/Cargo.toml b/examples/todos/Cargo.toml index 7ad4d558..fea20375 100644 --- a/examples/todos/Cargo.toml +++ b/examples/todos/Cargo.toml @@ -6,18 +6,20 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["async-std", "debug"] } +iced.workspace = true +iced.features = ["async-std", "debug"] + serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -once_cell = "1.15" +once_cell.workspace = true [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -async-std = "1.0" +async-std.workspace = true directories-next = "2.0" [target.'cfg(target_arch = "wasm32")'.dependencies] -web-sys = { version = "0.3", features = ["Window", "Storage"] } -wasm-timer = "0.2" +web-sys = { workspace = true, features = ["Window", "Storage"] } +wasm-timer.workspace = true [package.metadata.deb] assets = [ diff --git a/examples/tooltip/Cargo.toml b/examples/tooltip/Cargo.toml index 25840fb4..57bb0dcb 100644 --- a/examples/tooltip/Cargo.toml +++ b/examples/tooltip/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["debug"] } +iced.workspace = true +iced.features = ["debug"] diff --git a/examples/tour/Cargo.toml b/examples/tour/Cargo.toml index 48471f2d..21206ecb 100644 --- a/examples/tour/Cargo.toml +++ b/examples/tour/Cargo.toml @@ -6,5 +6,7 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["image", "debug"] } -env_logger = "0.10.0" +iced.workspace = true +iced.features = ["image", "debug"] + +tracing-subscriber = "0.3" diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs index 13bcd5ff..af508206 100644 --- a/examples/tour/src/main.rs +++ b/examples/tour/src/main.rs @@ -8,7 +8,7 @@ use iced::widget::{Button, Column, Container, Slider}; use iced::{Color, Element, Font, Length, Renderer, Sandbox, Settings}; pub fn main() -> iced::Result { - env_logger::init(); + tracing_subscriber::fmt::init(); Tour::run(Settings::default()) } diff --git a/examples/url_handler/Cargo.toml b/examples/url_handler/Cargo.toml index 4dcff92d..7bb9914b 100644 --- a/examples/url_handler/Cargo.toml +++ b/examples/url_handler/Cargo.toml @@ -6,4 +6,4 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../.." } +iced.workspace = true diff --git a/examples/visible_bounds/Cargo.toml b/examples/visible_bounds/Cargo.toml index cfa56dd2..37594b84 100644 --- a/examples/visible_bounds/Cargo.toml +++ b/examples/visible_bounds/Cargo.toml @@ -6,5 +6,7 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["debug"] } -once_cell = "1" +iced.workspace = true +iced.features = ["debug"] + +once_cell.workspace = true diff --git a/examples/websocket/Cargo.toml b/examples/websocket/Cargo.toml index 12af9658..2756e8e0 100644 --- a/examples/websocket/Cargo.toml +++ b/examples/websocket/Cargo.toml @@ -6,16 +6,16 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["tokio", "debug"] } -once_cell = "1.15" +iced.workspace = true +iced.features = ["debug", "tokio"] + +once_cell.workspace = true +warp = "0.3" [dependencies.async-tungstenite] version = "0.23" features = ["tokio-rustls-webpki-roots"] [dependencies.tokio] -version = "1" +workspace = true features = ["time"] - -[dependencies.warp] -version = "0.3" diff --git a/futures/Cargo.toml b/futures/Cargo.toml index 044827c2..69a915e4 100644 --- a/futures/Cargo.toml +++ b/futures/Cargo.toml @@ -1,47 +1,40 @@ [package] name = "iced_futures" -version = "0.7.0" -authors = ["HĂ©ctor RamĂłn JimĂ©nez "] -edition = "2021" -description = "Commands, subscriptions, and runtimes for Iced" -license = "MIT" -repository = "https://github.com/iced-rs/iced" -documentation = "https://docs.rs/iced_futures" -keywords = ["gui", "ui", "graphics", "interface", "futures"] -categories = ["gui"] +description = "Commands, subscriptions, and future executors for iced" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true +categories.workspace = true +keywords.workspace = true + +[package.metadata.docs.rs] +rustdoc-args = ["--cfg", "docsrs"] +all-features = true [features] thread-pool = ["futures/thread-pool"] [dependencies] -log = "0.4" +iced_core.workspace = true -[dependencies.iced_core] -version = "0.10" -path = "../core" +futures.workspace = true +log.workspace = true -[dependencies.futures] -version = "0.3" +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +async-std.workspace = true +async-std.optional = true +async-std.features = ["unstable"] -[target.'cfg(not(target_arch = "wasm32"))'.dependencies.tokio] -package = "tokio" -version = "1.0" -optional = true -features = ["rt", "rt-multi-thread", "time"] +smol.workspace = true +smol.optional = true -[target.'cfg(not(target_arch = "wasm32"))'.dependencies.async-std] -version = "1.0" -optional = true -features = ["unstable"] - -[target.'cfg(not(target_arch = "wasm32"))'.dependencies.smol] -version = "1.2" -optional = true +tokio.workspace = true +tokio.optional = true +tokio.features = ["rt", "rt-multi-thread", "time"] [target.'cfg(target_arch = "wasm32")'.dependencies] -wasm-bindgen-futures = "0.4" -wasm-timer = "0.2" - -[package.metadata.docs.rs] -rustdoc-args = ["--cfg", "docsrs"] -all-features = true +wasm-bindgen-futures.workspace = true +wasm-timer.workspace = true diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml index ca7bf61a..23a19845 100644 --- a/graphics/Cargo.toml +++ b/graphics/Cargo.toml @@ -1,14 +1,18 @@ [package] name = "iced_graphics" -version = "0.9.0" -authors = ["HĂ©ctor RamĂłn JimĂ©nez "] -edition = "2021" -description = "A bunch of backend-agnostic types that can be leveraged to build a renderer for Iced" -license = "MIT" -repository = "https://github.com/iced-rs/iced" -documentation = "https://docs.rs/iced_graphics" -keywords = ["gui", "ui", "graphics", "interface", "widgets"] -categories = ["gui"] +description = "A bunch of backend-agnostic types that can be leveraged to build a renderer for iced" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true +categories.workspace = true +keywords.workspace = true + +[package.metadata.docs.rs] +rustdoc-args = ["--cfg", "docsrs"] +all-features = true [features] geometry = ["lyon_path"] @@ -17,33 +21,21 @@ image = ["dep:image", "kamadak-exif"] web-colors = [] [dependencies] -glam = "0.24" -half = "2.2.1" -log = "0.4" -raw-window-handle = "0.5" -thiserror = "1.0" -bitflags = "1.2" +iced_core.workspace = true -[dependencies.bytemuck] -version = "1.4" -features = ["derive"] +bitflags.workspace = true +bytemuck.workspace = true +glam.workspace = true +half.workspace = true +log.workspace = true +raw-window-handle.workspace = true +thiserror.workspace = true -[dependencies.iced_core] -version = "0.10" -path = "../core" +lyon_path.workspace = true +lyon_path.optional = true -[dependencies.image] -version = "0.24" -optional = true +image.workspace = true +image.optional = true -[dependencies.kamadak-exif] -version = "0.5" -optional = true - -[dependencies.lyon_path] -version = "1" -optional = true - -[package.metadata.docs.rs] -rustdoc-args = ["--cfg", "docsrs"] -all-features = true +kamadak-exif.workspace = true +kamadak-exif.optional = true diff --git a/renderer/Cargo.toml b/renderer/Cargo.toml index 2c88cf31..56e17209 100644 --- a/renderer/Cargo.toml +++ b/renderer/Cargo.toml @@ -1,14 +1,14 @@ [package] name = "iced_renderer" -version = "0.1.0" -authors = ["HĂ©ctor RamĂłn JimĂ©nez "] -edition = "2021" -description = "The official renderer for Iced" -license = "MIT" -repository = "https://github.com/iced-rs/iced" -documentation = "https://docs.rs/iced_renderer" -keywords = ["gui", "ui", "graphics", "interface", "widgets"] -categories = ["gui"] +description = "The official renderer for iced" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true +categories.workspace = true +keywords.workspace = true [features] wgpu = ["iced_wgpu"] @@ -20,19 +20,12 @@ web-colors = ["iced_wgpu?/web-colors"] webgl = ["iced_wgpu?/webgl"] [dependencies] -raw-window-handle = "0.5" -thiserror = "1" -log = "0.4" +iced_graphics.workspace = true +iced_tiny_skia.workspace = true -[dependencies.iced_graphics] -version = "0.9" -path = "../graphics" +iced_wgpu.workspace = true +iced_wgpu.optional = true -[dependencies.iced_tiny_skia] -version = "0.1" -path = "../tiny_skia" - -[dependencies.iced_wgpu] -version = "0.11" -path = "../wgpu" -optional = true +log.workspace = true +raw-window-handle.workspace = true +thiserror.workspace = true diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 9fbe4be7..d19aedd3 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -1,23 +1,21 @@ [package] name = "iced_runtime" -version = "0.1.1" -authors = ["HĂ©ctor RamĂłn JimĂ©nez "] -edition = "2021" -description = "A renderer-agnostic runtime for Iced" -license = "MIT" -repository = "https://github.com/iced-rs/iced" +description = "A renderer-agnostic runtime for iced" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true +categories.workspace = true +keywords.workspace = true [features] debug = [] [dependencies] -thiserror = "1" +iced_core.workspace = true +iced_futures.workspace = true +iced_futures.features = ["thread-pool"] -[dependencies.iced_core] -version = "0.10" -path = "../core" - -[dependencies.iced_futures] -version = "0.7" -path = "../futures" -features = ["thread-pool"] +thiserror.workspace = true diff --git a/src/window/icon.rs b/src/window/icon.rs index 0fe010ca..0cb206b3 100644 --- a/src/window/icon.rs +++ b/src/window/icon.rs @@ -13,7 +13,7 @@ use std::path::Path; /// This will return an error in case the file is missing at run-time. You may prefer [`Self::from_file_data`] instead. #[cfg(feature = "image")] pub fn from_file>(icon_path: P) -> Result { - let icon = image_rs::io::Reader::open(icon_path)?.decode()?.to_rgba8(); + let icon = image::io::Reader::open(icon_path)?.decode()?.to_rgba8(); Ok(icon::from_rgba(icon.to_vec(), icon.width(), icon.height())?) } @@ -25,9 +25,10 @@ pub fn from_file>(icon_path: P) -> Result { #[cfg(feature = "image")] pub fn from_file_data( data: &[u8], - explicit_format: Option, + explicit_format: Option, ) -> Result { - let mut icon = image_rs::io::Reader::new(std::io::Cursor::new(data)); + let mut icon = image::io::Reader::new(std::io::Cursor::new(data)); + let icon_with_format = match explicit_format { Some(format) => { icon.set_format(format); @@ -59,5 +60,5 @@ pub enum Error { /// The `image` crate reported an error. #[cfg(feature = "image")] #[error("Unable to create icon from a file: {0}")] - ImageError(#[from] image_rs::error::ImageError), + ImageError(#[from] image::error::ImageError), } diff --git a/style/Cargo.toml b/style/Cargo.toml index 689cf978..3f00e787 100644 --- a/style/Cargo.toml +++ b/style/Cargo.toml @@ -1,22 +1,18 @@ [package] name = "iced_style" -version = "0.9.0" -authors = ["HĂ©ctor RamĂłn JimĂ©nez "] -edition = "2021" description = "The default set of styles of Iced" -license = "MIT" -repository = "https://github.com/iced-rs/iced" -documentation = "https://docs.rs/iced_style" -keywords = ["gui", "ui", "graphics", "interface", "widgets"] -categories = ["gui"] +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true +categories.workspace = true +keywords.workspace = true -[dependencies.iced_core] -version = "0.10" -path = "../core" -features = ["palette"] +[dependencies] +iced_core.workspace = true +iced_core.features = ["palette"] -[dependencies.palette] -version = "0.7" - -[dependencies.once_cell] -version = "1.15" +palette.workspace = true +once_cell.workspace = true diff --git a/tiny_skia/Cargo.toml b/tiny_skia/Cargo.toml index 9aa63a4f..15a6928a 100644 --- a/tiny_skia/Cargo.toml +++ b/tiny_skia/Cargo.toml @@ -1,14 +1,14 @@ [package] name = "iced_tiny_skia" -version = "0.1.0" -authors = ["HĂ©ctor RamĂłn JimĂ©nez "] -edition = "2021" -description = "A software renderer for Iced" -license = "MIT" -repository = "https://github.com/iced-rs/iced" -documentation = "https://docs.rs/iced_tiny_skia" -keywords = ["gui", "ui", "graphics", "interface", "widgets"] -categories = ["gui"] +description = "A software renderer for iced on top of tiny-skia" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true +categories.workspace = true +keywords.workspace = true [features] image = ["iced_graphics/image"] @@ -16,27 +16,21 @@ svg = ["resvg"] geometry = ["iced_graphics/geometry"] [dependencies] -raw-window-handle = "0.5" -softbuffer = "0.2" -tiny-skia = "0.10" -cosmic-text = "0.9" -bytemuck = "1" -rustc-hash = "1.1" -kurbo = "0.9" -log = "0.4" +iced_graphics.workspace = true -[dependencies.iced_graphics] -version = "0.9" -path = "../graphics" +bytemuck.workspace = true +cosmic-text.workspace = true +kurbo.workspace = true +log.workspace = true +raw-window-handle.workspace = true +rustc-hash.workspace = true +softbuffer.workspace = true +tiny-skia.workspace = true +twox-hash.workspace = true -[dependencies.twox-hash] -version = "1.6" -default-features = false +resvg.workspace = true +resvg.optional = true -[target.'cfg(not(target_arch = "wasm32"))'.dependencies.twox-hash] -version = "1.6.1" -features = ["std"] - -[dependencies.resvg] -version = "0.35" -optional = true +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +twox-hash.workspace = true +twox-hash.features = ["std"] diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 49c62673..97594f1a 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -1,11 +1,18 @@ [package] name = "iced_wgpu" -version = "0.11.1" -authors = ["HĂ©ctor RamĂłn JimĂ©nez "] -edition = "2021" -description = "A wgpu renderer for Iced" -license = "MIT AND OFL-1.1" -repository = "https://github.com/iced-rs/iced" +description = "A renderer for iced on top of wgpu" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true +categories.workspace = true +keywords.workspace = true + +[package.metadata.docs.rs] +rustdoc-args = ["--cfg", "docsrs"] +all-features = true [features] geometry = ["iced_graphics/geometry", "lyon"] @@ -15,47 +22,30 @@ web-colors = ["iced_graphics/web-colors"] webgl = ["wgpu/webgl"] [dependencies] -wgpu = "0.17" -glyphon = { git = "https://github.com/grovesNL/glyphon.git", rev = "20f0f8fa80e0d0df4c63634ce9176fa489546ca9" } -raw-window-handle = "0.5" -guillotiere = "0.6" -futures = "0.3" -bitflags = "1.2" -once_cell = "1.0" -rustc-hash = "1.1" -log = "0.4" +iced_graphics.workspace = true -[dependencies.twox-hash] -version = "1.6" -default-features = false +bitflags.workspace = true +bytemuck.workspace = true +futures.workspace = true +glam.workspace = true +glyphon.workspace = true +guillotiere.workspace = true +log.workspace = true +once_cell.workspace = true +raw-window-handle.workspace = true +rustc-hash.workspace = true +twox-hash.workspace = true +wgpu.workspace = true -[target.'cfg(not(target_arch = "wasm32"))'.dependencies.twox-hash] -version = "1.6.1" -features = ["std"] +lyon.workspace = true +lyon.optional = true -[dependencies.bytemuck] -version = "1.9" -features = ["derive"] +resvg.workspace = true +resvg.optional = true -[dependencies.iced_graphics] -version = "0.9" -path = "../graphics" +tracing.workspace = true +tracing.optional = true -[dependencies.glam] -version = "0.24" - -[dependencies.lyon] -version = "1.0" -optional = true - -[dependencies.resvg] -version = "0.35" -optional = true - -[dependencies.tracing] -version = "0.1.6" -optional = true - -[package.metadata.docs.rs] -rustdoc-args = ["--cfg", "docsrs"] -all-features = true +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +twox-hash.workspace = true +twox-hash.features = ["std"] diff --git a/widget/Cargo.toml b/widget/Cargo.toml index 128a7c38..6d62c181 100644 --- a/widget/Cargo.toml +++ b/widget/Cargo.toml @@ -1,14 +1,18 @@ [package] name = "iced_widget" -version = "0.1.3" -authors = ["HĂ©ctor RamĂłn JimĂ©nez "] -edition = "2021" -description = "The built-in widgets for Iced" -license = "MIT" -repository = "https://github.com/iced-rs/iced" -documentation = "https://docs.rs/iced_widget" -keywords = ["gui", "ui", "graphics", "interface", "widgets"] -categories = ["gui"] +description = "The built-in widgets for iced" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true +categories.workspace = true +keywords.workspace = true + +[package.metadata.docs.rs] +rustdoc-args = ["--cfg", "docsrs"] +all-features = true [features] lazy = ["ouroboros"] @@ -18,31 +22,16 @@ canvas = ["iced_renderer/geometry"] qr_code = ["canvas", "qrcode"] [dependencies] -unicode-segmentation = "1.6" -num-traits = "0.2" -thiserror = "1" +iced_renderer.workspace = true +iced_runtime.workspace = true +iced_style.workspace = true -[dependencies.iced_runtime] -version = "0.1" -path = "../runtime" +num-traits.workspace = true +thiserror.workspace = true +unicode-segmentation.workspace = true -[dependencies.iced_renderer] -version = "0.1" -path = "../renderer" +ouroboros.workspace = true +ouroboros.optional = true -[dependencies.iced_style] -version = "0.9" -path = "../style" - -[dependencies.ouroboros] -version = "0.17" -optional = true - -[dependencies.qrcode] -version = "0.12" -optional = true -default-features = false - -[package.metadata.docs.rs] -rustdoc-args = ["--cfg", "docsrs"] -all-features = true +qrcode.workspace = true +qrcode.optional = true diff --git a/winit/Cargo.toml b/winit/Cargo.toml index 67216147..674a66d3 100644 --- a/winit/Cargo.toml +++ b/winit/Cargo.toml @@ -1,19 +1,17 @@ [package] name = "iced_winit" -version = "0.10.0" -authors = ["HĂ©ctor RamĂłn JimĂ©nez "] -edition = "2021" -description = "A winit runtime for Iced" -license = "MIT" -repository = "https://github.com/iced-rs/iced" -documentation = "https://docs.rs/iced_winit" -keywords = ["gui", "ui", "graphics", "interface", "widgets"] -categories = ["gui"] +description = "A runtime for iced on top of winit" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true +categories.workspace = true +keywords.workspace = true [features] default = ["x11", "wayland", "wayland-dlopen", "wayland-csd-adwaita"] -trace = ["tracing", "tracing-core", "tracing-subscriber"] -chrome-trace = ["trace", "tracing-chrome"] debug = ["iced_runtime/debug"] system = ["sysinfo"] application = [] @@ -23,54 +21,23 @@ wayland-dlopen = ["winit/wayland-dlopen"] wayland-csd-adwaita = ["winit/wayland-csd-adwaita"] [dependencies] -window_clipboard = "0.3" -log = "0.4" -thiserror = "1.0" -raw-window-handle = "0.5" +iced_graphics.workspace = true +iced_runtime.workspace = true +iced_style.workspace = true -[dependencies.winit] -version = "0.28" -git = "https://github.com/iced-rs/winit.git" -rev = "c52db2045d0a2f1b8d9923870de1d4ab1994146e" -default-features = false +log.workspace = true +raw-window-handle.workspace = true +thiserror.workspace = true +tracing.workspace = true +window_clipboard.workspace = true +winit.workspace = true -[dependencies.iced_runtime] -version = "0.1" -path = "../runtime" +sysinfo.workspace = true +sysinfo.optional = true -[dependencies.iced_graphics] -version = "0.9" -path = "../graphics" +[target.'cfg(target_os = "windows")'.dependencies] +winapi.workspace = true -[dependencies.iced_style] -version = "0.9" -path = "../style" - -[dependencies.tracing] -version = "0.1.37" -optional = true -features = ["std"] - -[dependencies.tracing-core] -version = "0.1.30" -optional = true - -[dependencies.tracing-subscriber] -version = "0.3.16" -optional = true -features = ["registry"] - -[dependencies.tracing-chrome] -version = "0.7.0" -optional = true - -[target.'cfg(target_os = "windows")'.dependencies.winapi] -version = "0.3.6" - -[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys] -version = "0.3" -features = ["Document", "Window"] - -[dependencies.sysinfo] -version = "0.28" -optional = true +[target.'cfg(target_arch = "wasm32")'.dependencies] +web-sys.workspace = true +web-sys.features = ["Document", "Window"] From 34876aea5ea698f342220e7b7c0bed33a42859d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 4 Sep 2023 13:32:27 +0200 Subject: [PATCH 123/321] Add GitHub CI workflow to detect outdated dependencies --- .github/workflows/detect.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .github/workflows/detect.yml diff --git a/.github/workflows/detect.yml b/.github/workflows/detect.yml new file mode 100644 index 00000000..c4b7413d --- /dev/null +++ b/.github/workflows/detect.yml @@ -0,0 +1,16 @@ +name: Detect +on: + push: {} + pull_request: {} + schedule: + - cron: '0 0 * * *' +jobs: + outdated_dependencies: + runs-on: ubuntu-latest + steps: + - uses: hecrj/setup-rust-action@v1 + - name: Install cargo-outdated + run: cargo install cargo-outdated + - uses: actions/checkout@master + - name: Detect outdated dependencies + run: cargo outdated --exit-code 1 From 20681b4777a1954e6b7f659d5bc1817f7924f40d Mon Sep 17 00:00:00 2001 From: Josh Megnauth Date: Mon, 4 Sep 2023 21:03:16 -0400 Subject: [PATCH 124/321] Ensure LineHeight is always > 0.0 for tiny skia. --- tiny_skia/src/text.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index 08fde4bf..9b949218 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -54,7 +54,8 @@ impl Pipeline { pixels: &mut tiny_skia::PixmapMut<'_>, clip_mask: Option<&tiny_skia::Mask>, ) { - let line_height = f32::from(line_height.to_absolute(Pixels(size))); + let line_height = f32::from(line_height.to_absolute(Pixels(size))) + .max(f32::MIN_POSITIVE); let font_system = self.font_system.get_mut(); let key = Key { @@ -134,7 +135,8 @@ impl Pipeline { ) -> Size { let mut measurement_cache = self.cache.borrow_mut(); - let line_height = f32::from(line_height.to_absolute(Pixels(size))); + let line_height = f32::from(line_height.to_absolute(Pixels(size))) + .max(f32::MIN_POSITIVE); let (_, entry) = measurement_cache.allocate( &mut self.font_system.borrow_mut(), @@ -164,7 +166,8 @@ impl Pipeline { ) -> Option { let mut measurement_cache = self.cache.borrow_mut(); - let line_height = f32::from(line_height.to_absolute(Pixels(size))); + let line_height = f32::from(line_height.to_absolute(Pixels(size))) + .max(f32::MIN_POSITIVE); let (_, entry) = measurement_cache.allocate( &mut self.font_system.borrow_mut(), @@ -405,7 +408,10 @@ impl Cache { } if let hash_map::Entry::Vacant(entry) = self.entries.entry(hash) { - let metrics = cosmic_text::Metrics::new(key.size, key.size * 1.2); + let metrics = cosmic_text::Metrics::new( + key.size, + (key.size * 1.2).max(f32::MIN_POSITIVE), + ); let mut buffer = cosmic_text::Buffer::new(font_system, metrics); buffer.set_size( From bdf18554feadb631fdae5b427ac7a92a5546ade1 Mon Sep 17 00:00:00 2001 From: Josh Megnauth Date: Mon, 4 Sep 2023 23:47:44 -0400 Subject: [PATCH 125/321] Check LineHeight > 0.0 before allocating text --- tiny_skia/src/text.rs | 13 +++++-------- wgpu/src/text.rs | 14 +++++++------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index 9b949218..24b17662 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -54,8 +54,7 @@ impl Pipeline { pixels: &mut tiny_skia::PixmapMut<'_>, clip_mask: Option<&tiny_skia::Mask>, ) { - let line_height = f32::from(line_height.to_absolute(Pixels(size))) - .max(f32::MIN_POSITIVE); + let line_height = f32::from(line_height.to_absolute(Pixels(size))); let font_system = self.font_system.get_mut(); let key = Key { @@ -135,8 +134,7 @@ impl Pipeline { ) -> Size { let mut measurement_cache = self.cache.borrow_mut(); - let line_height = f32::from(line_height.to_absolute(Pixels(size))) - .max(f32::MIN_POSITIVE); + let line_height = f32::from(line_height.to_absolute(Pixels(size))); let (_, entry) = measurement_cache.allocate( &mut self.font_system.borrow_mut(), @@ -166,8 +164,7 @@ impl Pipeline { ) -> Option { let mut measurement_cache = self.cache.borrow_mut(); - let line_height = f32::from(line_height.to_absolute(Pixels(size))) - .max(f32::MIN_POSITIVE); + let line_height = f32::from(line_height.to_absolute(Pixels(size))); let (_, entry) = measurement_cache.allocate( &mut self.font_system.borrow_mut(), @@ -409,8 +406,8 @@ impl Cache { if let hash_map::Entry::Vacant(entry) = self.entries.entry(hash) { let metrics = cosmic_text::Metrics::new( - key.size, - (key.size * 1.2).max(f32::MIN_POSITIVE), + key.line_height, + (key.line_height * 1.2).max(f32::MIN_POSITIVE), ); let mut buffer = cosmic_text::Buffer::new(font_system, metrics); diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index 08a32b5e..9c42be0e 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -96,8 +96,7 @@ impl Pipeline { section .line_height .to_absolute(Pixels(section.size)), - ) - .max(f32::MIN_POSITIVE), + ), font: section.font, bounds: Size { width: section.bounds.width, @@ -239,8 +238,7 @@ impl Pipeline { ) -> Size { let mut cache = self.cache.borrow_mut(); - let line_height = f32::from(line_height.to_absolute(Pixels(size))) - .max(f32::MIN_POSITIVE); + let line_height = f32::from(line_height.to_absolute(Pixels(size))); let (_, entry) = cache.allocate( &mut self.font_system.borrow_mut(), @@ -271,8 +269,7 @@ impl Pipeline { ) -> Option { let mut cache = self.cache.borrow_mut(); - let line_height = f32::from(line_height.to_absolute(Pixels(size))) - .max(f32::MIN_POSITIVE); + let line_height = f32::from(line_height.to_absolute(Pixels(size))); let (_, entry) = cache.allocate( &mut self.font_system.borrow_mut(), @@ -417,7 +414,10 @@ impl Cache { } if let hash_map::Entry::Vacant(entry) = self.entries.entry(hash) { - let metrics = glyphon::Metrics::new(key.size, key.line_height); + let metrics = glyphon::Metrics::new( + key.size, + key.line_height.max(f32::MIN_POSITIVE), + ); let mut buffer = glyphon::Buffer::new(font_system, metrics); buffer.set_size( From 5371fae21a4c1110a37e7183e794cba234598d9c Mon Sep 17 00:00:00 2001 From: ripytide Date: Tue, 5 Sep 2023 10:49:50 +0100 Subject: [PATCH 126/321] added a Frame::scale_nonuniform method --- renderer/src/geometry.rs | 8 +++++++- tiny_skia/src/geometry.rs | 4 ++++ wgpu/src/geometry.rs | 10 +++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/renderer/src/geometry.rs b/renderer/src/geometry.rs index 04b5d9e6..0e524169 100644 --- a/renderer/src/geometry.rs +++ b/renderer/src/geometry.rs @@ -168,12 +168,18 @@ impl Frame { delegate!(self, frame, frame.rotate(angle)); } - /// Applies a scaling to the current transform of the [`Frame`]. + /// Applies a uniform scaling to the current transform of the [`Frame`]. #[inline] pub fn scale(&mut self, scale: f32) { delegate!(self, frame, frame.scale(scale)); } + /// Applies a non-uniform scaling to the current transform of the [`Frame`]. + #[inline] + pub fn scale_nonuniform(&mut self, scale: Vector) { + delegate!(self, frame, frame.scale_nonuniform(scale)); + } + pub fn into_geometry(self) -> Geometry { match self { Self::TinySkia(frame) => Geometry::TinySkia(frame.into_primitive()), diff --git a/tiny_skia/src/geometry.rs b/tiny_skia/src/geometry.rs index 0fae7364..a416020f 100644 --- a/tiny_skia/src/geometry.rs +++ b/tiny_skia/src/geometry.rs @@ -158,6 +158,10 @@ impl Frame { self.transform = self.transform.pre_scale(scale, scale); } + pub fn scale_nonuniform(&mut self, scale: Vector) { + self.transform = self.transform.pre_scale(scale.x, scale.y); + } + pub fn into_primitive(self) -> Primitive { Primitive::Clip { bounds: Rectangle::new(Point::ORIGIN, self.size), diff --git a/wgpu/src/geometry.rs b/wgpu/src/geometry.rs index e421e0b0..2cd07a27 100644 --- a/wgpu/src/geometry.rs +++ b/wgpu/src/geometry.rs @@ -444,7 +444,7 @@ impl Frame { self.transforms.current.is_identity = false; } - /// Applies a scaling to the current transform of the [`Frame`]. + /// Applies a uniform scaling to the current transform of the [`Frame`]. #[inline] pub fn scale(&mut self, scale: f32) { self.transforms.current.raw = @@ -452,6 +452,14 @@ impl Frame { self.transforms.current.is_identity = false; } + /// Applies a non-uniform scaling to the current transform of the [`Frame`]. + #[inline] + pub fn scale_nonuniform(&mut self, scale: Vector) { + self.transforms.current.raw = + self.transforms.current.raw.pre_scale(scale.x, scale.y); + self.transforms.current.is_identity = false; + } + /// Produces the [`Primitive`] representing everything drawn on the [`Frame`]. pub fn into_primitive(self) -> Primitive { Primitive::Group { From cee0ed64694e06eb3061acc1abd76deded3e0648 Mon Sep 17 00:00:00 2001 From: Josh Megnauth Date: Tue, 5 Sep 2023 20:45:27 -0400 Subject: [PATCH 127/321] Use the correct text size and height in tiny_skia --- tiny_skia/src/text.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index 24b17662..306b400a 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -406,8 +406,8 @@ impl Cache { if let hash_map::Entry::Vacant(entry) = self.entries.entry(hash) { let metrics = cosmic_text::Metrics::new( - key.line_height, - (key.line_height * 1.2).max(f32::MIN_POSITIVE), + key.size, + key.line_height.max(f32::MIN_POSITIVE), ); let mut buffer = cosmic_text::Buffer::new(font_system, metrics); From 08a031cbe5913c249efa7fc82556d5d95f981c4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 7 Sep 2023 02:45:15 +0200 Subject: [PATCH 128/321] Introduce `keyboard::on_key_press` and `on_key_release` Also rename `subscription::events*` to `event::listen*`. --- examples/events/src/main.rs | 5 +- examples/modal/src/main.rs | 8 ++- examples/pane_grid/src/main.rs | 14 +---- examples/screenshot/src/main.rs | 7 +-- examples/toast/src/main.rs | 8 ++- examples/todos/src/main.rs | 40 ++++--------- examples/url_handler/src/main.rs | 13 +++-- examples/visible_bounds/src/main.rs | 8 +-- futures/src/event.rs | 59 +++++++++++++++++++ futures/src/keyboard.rs | 61 +++++++++++++++++++ futures/src/lib.rs | 2 + futures/src/subscription.rs | 91 ++++++----------------------- runtime/src/window.rs | 5 +- src/lib.rs | 10 +++- 14 files changed, 193 insertions(+), 138 deletions(-) create mode 100644 futures/src/event.rs create mode 100644 futures/src/keyboard.rs diff --git a/examples/events/src/main.rs b/examples/events/src/main.rs index 7f3a5e1d..32d0da2c 100644 --- a/examples/events/src/main.rs +++ b/examples/events/src/main.rs @@ -1,9 +1,8 @@ use iced::alignment; +use iced::event::{self, Event}; use iced::executor; -use iced::subscription; use iced::widget::{button, checkbox, container, text, Column}; use iced::window; -use iced::Event; use iced::{ Alignment, Application, Command, Element, Length, Settings, Subscription, Theme, @@ -71,7 +70,7 @@ impl Application for Events { } fn subscription(&self) -> Subscription { - subscription::events().map(Message::EventOccurred) + event::listen().map(Message::EventOccurred) } fn view(&self) -> Element { diff --git a/examples/modal/src/main.rs b/examples/modal/src/main.rs index 8a48f830..4aa70886 100644 --- a/examples/modal/src/main.rs +++ b/examples/modal/src/main.rs @@ -1,12 +1,14 @@ +use iced::event::{self, Event}; use iced::executor; use iced::keyboard; -use iced::subscription::{self, Subscription}; use iced::theme; use iced::widget::{ self, button, column, container, horizontal_space, pick_list, row, text, text_input, }; -use iced::{Alignment, Application, Command, Element, Event, Length, Settings}; +use iced::{ + Alignment, Application, Command, Element, Length, Settings, Subscription, +}; use modal::Modal; use std::fmt; @@ -49,7 +51,7 @@ impl Application for App { } fn subscription(&self) -> Subscription { - subscription::events().map(Message::Event) + event::listen().map(Message::Event) } fn update(&mut self, message: Message) -> Command { diff --git a/examples/pane_grid/src/main.rs b/examples/pane_grid/src/main.rs index 04896e20..af87e2c0 100644 --- a/examples/pane_grid/src/main.rs +++ b/examples/pane_grid/src/main.rs @@ -1,8 +1,6 @@ use iced::alignment::{self, Alignment}; -use iced::event::{self, Event}; use iced::executor; use iced::keyboard; -use iced::subscription; use iced::theme::{self, Theme}; use iced::widget::pane_grid::{self, PaneGrid}; use iced::widget::{ @@ -146,18 +144,12 @@ impl Application for Example { } fn subscription(&self) -> Subscription { - subscription::events_with(|event, status| { - if let event::Status::Captured = status { + keyboard::on_key_press(|key_code, modifiers| { + if !modifiers.command() { return None; } - match event { - Event::Keyboard(keyboard::Event::KeyPressed { - modifiers, - key_code, - }) if modifiers.command() => handle_hotkey(key_code), - _ => None, - } + handle_hotkey(key_code) }) } diff --git a/examples/screenshot/src/main.rs b/examples/screenshot/src/main.rs index 83824535..54446724 100644 --- a/examples/screenshot/src/main.rs +++ b/examples/screenshot/src/main.rs @@ -4,9 +4,8 @@ use iced::theme::{Button, Container}; use iced::widget::{button, column, container, image, row, text, text_input}; use iced::window::screenshot::{self, Screenshot}; use iced::{ - event, executor, keyboard, subscription, Alignment, Application, Command, - ContentFit, Element, Event, Length, Rectangle, Renderer, Subscription, - Theme, + event, executor, keyboard, Alignment, Application, Command, ContentFit, + Element, Event, Length, Rectangle, Renderer, Subscription, Theme, }; use ::image as img; @@ -254,7 +253,7 @@ impl Application for Example { } fn subscription(&self) -> Subscription { - subscription::events_with(|event, status| { + event::listen_with(|event, status| { if let event::Status::Captured = status { return None; } diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs index 42f6c348..47b272a9 100644 --- a/examples/toast/src/main.rs +++ b/examples/toast/src/main.rs @@ -1,10 +1,12 @@ +use iced::event::{self, Event}; use iced::executor; use iced::keyboard; -use iced::subscription::{self, Subscription}; use iced::widget::{ self, button, column, container, pick_list, row, slider, text, text_input, }; -use iced::{Alignment, Application, Command, Element, Event, Length, Settings}; +use iced::{ + Alignment, Application, Command, Element, Length, Settings, Subscription, +}; use toast::{Status, Toast}; @@ -57,7 +59,7 @@ impl Application for App { } fn subscription(&self) -> Subscription { - subscription::events().map(Message::Event) + event::listen().map(Message::Event) } fn update(&mut self, message: Message) -> Command { diff --git a/examples/todos/src/main.rs b/examples/todos/src/main.rs index 6ad7b4fb..62c17926 100644 --- a/examples/todos/src/main.rs +++ b/examples/todos/src/main.rs @@ -1,8 +1,6 @@ use iced::alignment::{self, Alignment}; -use iced::event::{self, Event}; use iced::font::{self, Font}; -use iced::keyboard::{self, KeyCode, Modifiers}; -use iced::subscription; +use iced::keyboard; use iced::theme::{self, Theme}; use iced::widget::{ self, button, checkbox, column, container, row, scrollable, text, @@ -52,7 +50,7 @@ enum Message { FilterChanged(Filter), TaskMessage(usize, TaskMessage), TabPressed { shift: bool }, - ToggleFullscreen(window::Mode), + ChangeWindowMode(window::Mode), } impl Application for Todos { @@ -163,7 +161,7 @@ impl Application for Todos { widget::focus_next() } } - Message::ToggleFullscreen(mode) => { + Message::ChangeWindowMode(mode) => { window::change_mode(mode) } _ => Command::none(), @@ -262,33 +260,19 @@ impl Application for Todos { } fn subscription(&self) -> Subscription { - subscription::events_with(|event, status| match (event, status) { - ( - Event::Keyboard(keyboard::Event::KeyPressed { - key_code: keyboard::KeyCode::Tab, - modifiers, - .. + keyboard::on_key_press(|key_code, modifiers| { + match (key_code, modifiers) { + (keyboard::KeyCode::Tab, _) => Some(Message::TabPressed { + shift: modifiers.shift(), }), - event::Status::Ignored, - ) => Some(Message::TabPressed { - shift: modifiers.shift(), - }), - ( - Event::Keyboard(keyboard::Event::KeyPressed { - key_code, - modifiers: Modifiers::SHIFT, - }), - event::Status::Ignored, - ) => match key_code { - KeyCode::Up => { - Some(Message::ToggleFullscreen(window::Mode::Fullscreen)) + (keyboard::KeyCode::Up, keyboard::Modifiers::SHIFT) => { + Some(Message::ChangeWindowMode(window::Mode::Fullscreen)) } - KeyCode::Down => { - Some(Message::ToggleFullscreen(window::Mode::Windowed)) + (keyboard::KeyCode::Down, keyboard::Modifiers::SHIFT) => { + Some(Message::ChangeWindowMode(window::Mode::Windowed)) } _ => None, - }, - _ => None, + } }) } } diff --git a/examples/url_handler/src/main.rs b/examples/url_handler/src/main.rs index f63fa06a..bf570123 100644 --- a/examples/url_handler/src/main.rs +++ b/examples/url_handler/src/main.rs @@ -1,6 +1,5 @@ -use iced::event::{Event, MacOS, PlatformSpecific}; +use iced::event::{self, Event}; use iced::executor; -use iced::subscription; use iced::widget::{container, text}; use iced::{ Application, Command, Element, Length, Settings, Subscription, Theme, @@ -37,9 +36,11 @@ impl Application for App { fn update(&mut self, message: Message) -> Command { match message { Message::EventOccurred(event) => { - if let Event::PlatformSpecific(PlatformSpecific::MacOS( - MacOS::ReceivedUrl(url), - )) = event + if let Event::PlatformSpecific( + event::PlatformSpecific::MacOS(event::MacOS::ReceivedUrl( + url, + )), + ) = event { self.url = Some(url); } @@ -50,7 +51,7 @@ impl Application for App { } fn subscription(&self) -> Subscription { - subscription::events().map(Message::EventOccurred) + event::listen().map(Message::EventOccurred) } fn view(&self) -> Element { diff --git a/examples/visible_bounds/src/main.rs b/examples/visible_bounds/src/main.rs index 8b684514..42dfc24c 100644 --- a/examples/visible_bounds/src/main.rs +++ b/examples/visible_bounds/src/main.rs @@ -1,14 +1,14 @@ +use iced::event::{self, Event}; use iced::executor; use iced::mouse; -use iced::subscription::{self, Subscription}; use iced::theme::{self, Theme}; use iced::widget::{ column, container, horizontal_space, row, scrollable, text, vertical_space, }; use iced::window; use iced::{ - Alignment, Application, Color, Command, Element, Event, Font, Length, - Point, Rectangle, Settings, + Alignment, Application, Color, Command, Element, Font, Length, Point, + Rectangle, Settings, Subscription, }; pub fn main() -> iced::Result { @@ -163,7 +163,7 @@ impl Application for Example { } fn subscription(&self) -> Subscription { - subscription::events_with(|event, _| match event { + event::listen_with(|event, _| match event { Event::Mouse(mouse::Event::CursorMoved { position }) => { Some(Message::MouseMoved(position)) } diff --git a/futures/src/event.rs b/futures/src/event.rs new file mode 100644 index 00000000..214d2d40 --- /dev/null +++ b/futures/src/event.rs @@ -0,0 +1,59 @@ +//! Listen to runtime events. +use crate::core::event::{self, Event}; +use crate::core::window; +use crate::subscription::{self, Subscription}; +use crate::MaybeSend; + +/// Returns a [`Subscription`] to all the ignored runtime events. +/// +/// This subscription will notify your application of any [`Event`] that was +/// not captured by any widget. +pub fn listen() -> Subscription { + listen_with(|event, status| match status { + event::Status::Ignored => Some(event), + event::Status::Captured => None, + }) +} + +/// Creates a [`Subscription`] that listens and filters all the runtime events +/// with the provided function, producing messages accordingly. +/// +/// This subscription will call the provided function for every [`Event`] +/// handled by the runtime. If the function: +/// +/// - Returns `None`, the [`Event`] will be discarded. +/// - Returns `Some` message, the `Message` will be produced. +pub fn listen_with( + f: fn(Event, event::Status) -> Option, +) -> Subscription +where + Message: 'static + MaybeSend, +{ + #[derive(Hash)] + struct EventsWith; + + subscription::filter_map( + (EventsWith, f), + move |event, status| match event { + Event::Window(window::Event::RedrawRequested(_)) => None, + _ => f(event, status), + }, + ) +} + +/// Creates a [`Subscription`] that produces a message for every runtime event, +/// including the redraw request events. +/// +/// **Warning:** This [`Subscription`], if unfiltered, may produce messages in +/// an infinite loop. +pub fn listen_raw( + f: fn(Event, event::Status) -> Option, +) -> Subscription +where + Message: 'static + MaybeSend, +{ + #[derive(Hash)] + struct RawEvents; + + subscription::filter_map((RawEvents, f), f) +} diff --git a/futures/src/keyboard.rs b/futures/src/keyboard.rs new file mode 100644 index 00000000..1ddca0bb --- /dev/null +++ b/futures/src/keyboard.rs @@ -0,0 +1,61 @@ +//! Listen to keyboard events. +use crate::core; +use crate::core::keyboard::{Event, KeyCode, Modifiers}; +use crate::subscription::{self, Subscription}; +use crate::MaybeSend; + +/// Listens to keyboard key presses and calls the given function +/// map them into actual messages. +/// +/// If the function returns `None`, the key press will be simply +/// ignored. +pub fn on_key_press( + f: fn(KeyCode, Modifiers) -> Option, +) -> Subscription +where + Message: MaybeSend + 'static, +{ + #[derive(Hash)] + struct OnKeyPress; + + subscription::filter_map((OnKeyPress, f), move |event, status| { + match (event, status) { + ( + core::Event::Keyboard(Event::KeyPressed { + key_code, + modifiers, + }), + core::event::Status::Ignored, + ) => f(key_code, modifiers), + _ => None, + } + }) +} + +/// Listens to keyboard key releases and calls the given function +/// map them into actual messages. +/// +/// If the function returns `None`, the key release will be simply +/// ignored. +pub fn on_key_release( + f: fn(KeyCode, Modifiers) -> Option, +) -> Subscription +where + Message: MaybeSend + 'static, +{ + #[derive(Hash)] + struct OnKeyPress; + + subscription::filter_map((OnKeyPress, f), move |event, status| { + match (event, status) { + ( + core::Event::Keyboard(Event::KeyReleased { + key_code, + modifiers, + }), + core::event::Status::Ignored, + ) => f(key_code, modifiers), + _ => None, + } + }) +} diff --git a/futures/src/lib.rs b/futures/src/lib.rs index 34d81e1e..8e75331f 100644 --- a/futures/src/lib.rs +++ b/futures/src/lib.rs @@ -24,7 +24,9 @@ mod maybe_send; mod runtime; pub mod backend; +pub mod event; pub mod executor; +pub mod keyboard; pub mod subscription; pub use executor::Executor; diff --git a/futures/src/subscription.rs b/futures/src/subscription.rs index 8f78ce3a..759dd223 100644 --- a/futures/src/subscription.rs +++ b/futures/src/subscription.rs @@ -4,7 +4,6 @@ mod tracker; pub use tracker::Tracker; use crate::core::event::{self, Event}; -use crate::core::window; use crate::core::Hasher; use crate::futures::{Future, Stream}; use crate::{BoxStream, MaybeSend}; @@ -215,77 +214,6 @@ where } } -/// Returns a [`Subscription`] to all the ignored runtime events. -/// -/// This subscription will notify your application of any [`Event`] that was -/// not captured by any widget. -pub fn events() -> Subscription { - events_with(|event, status| match status { - event::Status::Ignored => Some(event), - event::Status::Captured => None, - }) -} - -/// Returns a [`Subscription`] that filters all the runtime events with the -/// provided function, producing messages accordingly. -/// -/// This subscription will call the provided function for every [`Event`] -/// handled by the runtime. If the function: -/// -/// - Returns `None`, the [`Event`] will be discarded. -/// - Returns `Some` message, the `Message` will be produced. -pub fn events_with( - f: fn(Event, event::Status) -> Option, -) -> Subscription -where - Message: 'static + MaybeSend, -{ - #[derive(Hash)] - struct EventsWith; - - Subscription::from_recipe(Runner { - id: (EventsWith, f), - spawn: move |events| { - use futures::future; - use futures::stream::StreamExt; - - events.filter_map(move |(event, status)| { - future::ready(match event { - Event::Window(window::Event::RedrawRequested(_)) => None, - _ => f(event, status), - }) - }) - }, - }) -} - -/// Returns a [`Subscription`] that produces a message for every runtime event, -/// including the redraw request events. -/// -/// **Warning:** This [`Subscription`], if unfiltered, may produce messages in -/// an infinite loop. -pub fn raw_events( - f: fn(Event, event::Status) -> Option, -) -> Subscription -where - Message: 'static + MaybeSend, -{ - #[derive(Hash)] - struct RawEvents; - - Subscription::from_recipe(Runner { - id: (RawEvents, f), - spawn: move |events| { - use futures::future; - use futures::stream::StreamExt; - - events.filter_map(move |(event, status)| { - future::ready(f(event, status)) - }) - }, - }) -} - /// Returns a [`Subscription`] that will call the given function to create and /// asynchronously run the given [`Stream`]. pub fn run(builder: fn() -> S) -> Subscription @@ -338,6 +266,25 @@ where ) } +pub(crate) fn filter_map(id: I, f: F) -> Subscription +where + I: Hash + 'static, + F: Fn(Event, event::Status) -> Option + MaybeSend + 'static, + Message: 'static + MaybeSend, +{ + Subscription::from_recipe(Runner { + id, + spawn: |events| { + use futures::future; + use futures::stream::StreamExt; + + events.filter_map(move |(event, status)| { + future::ready(f(event, status)) + }) + }, + }) +} + /// Creates a [`Subscription`] that publishes the events sent from a [`Future`] /// to an [`mpsc::Sender`] with the given bounds. /// diff --git a/runtime/src/window.rs b/runtime/src/window.rs index 5219fbfd..41816967 100644 --- a/runtime/src/window.rs +++ b/runtime/src/window.rs @@ -10,7 +10,8 @@ use crate::command::{self, Command}; use crate::core::time::Instant; use crate::core::window::{Event, Icon, Level, Mode, UserAttention}; use crate::core::Size; -use crate::futures::subscription::{self, Subscription}; +use crate::futures::event; +use crate::futures::Subscription; /// Subscribes to the frames of the window of the running application. /// @@ -21,7 +22,7 @@ use crate::futures::subscription::{self, Subscription}; /// In any case, this [`Subscription`] is useful to smoothly draw application-driven /// animations without missing any frames. pub fn frames() -> Subscription { - subscription::raw_events(|event, _status| match event { + event::listen_raw(|event, _status| match event { iced_core::Event::Window(Event::RedrawRequested(at)) => Some(at), _ => None, }) diff --git a/src/lib.rs b/src/lib.rs index 36f48ba2..840802cc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -187,7 +187,6 @@ pub mod advanced; pub use style::theme; pub use crate::core::alignment; -pub use crate::core::event; pub use crate::core::gradient; pub use crate::core::{ color, Alignment, Background, BorderRadius, Color, ContentFit, Degrees, @@ -223,9 +222,16 @@ pub mod font { pub use crate::runtime::font::*; } +pub mod event { + //! Handle events of a user interface. + pub use crate::core::event::{Event, MacOS, PlatformSpecific, Status}; + pub use iced_futures::event::{listen, listen_raw, listen_with}; +} + pub mod keyboard { //! Listen and react to keyboard events. pub use crate::core::keyboard::{Event, KeyCode, Modifiers}; + pub use iced_futures::keyboard::{on_key_press, on_key_release}; } pub mod mouse { @@ -238,7 +244,7 @@ pub mod mouse { pub mod subscription { //! Listen to external events in your application. pub use iced_futures::subscription::{ - channel, events, events_with, run, run_with_id, unfold, Subscription, + channel, run, run_with_id, unfold, Subscription, }; } From d21f0698b505d699c44e9414f902dbeca9474e39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 7 Sep 2023 02:46:19 +0200 Subject: [PATCH 129/321] Add hotkey support for `stopwatch` example --- examples/stopwatch/src/main.rs | 16 +++++++++++++++- futures/src/keyboard.rs | 4 ++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/examples/stopwatch/src/main.rs b/examples/stopwatch/src/main.rs index 842ba3d4..0b0f0607 100644 --- a/examples/stopwatch/src/main.rs +++ b/examples/stopwatch/src/main.rs @@ -1,5 +1,6 @@ use iced::alignment; use iced::executor; +use iced::keyboard; use iced::theme::{self, Theme}; use iced::time; use iced::widget::{button, column, container, row, text}; @@ -77,12 +78,25 @@ impl Application for Stopwatch { } fn subscription(&self) -> Subscription { - match self.state { + let tick = match self.state { State::Idle => Subscription::none(), State::Ticking { .. } => { time::every(Duration::from_millis(10)).map(Message::Tick) } + }; + + fn handle_hotkey( + key_code: keyboard::KeyCode, + _modifiers: keyboard::Modifiers, + ) -> Option { + match key_code { + keyboard::KeyCode::Space => Some(Message::Toggle), + keyboard::KeyCode::R => Some(Message::Reset), + _ => None, + } } + + Subscription::batch(vec![tick, keyboard::on_key_press(handle_hotkey)]) } fn view(&self) -> Element { diff --git a/futures/src/keyboard.rs b/futures/src/keyboard.rs index 1ddca0bb..af68e1f2 100644 --- a/futures/src/keyboard.rs +++ b/futures/src/keyboard.rs @@ -44,9 +44,9 @@ where Message: MaybeSend + 'static, { #[derive(Hash)] - struct OnKeyPress; + struct OnKeyRelease; - subscription::filter_map((OnKeyPress, f), move |event, status| { + subscription::filter_map((OnKeyRelease, f), move |event, status| { match (event, status) { ( core::Event::Keyboard(Event::KeyReleased { From 8cfad86ec1bb8d6f65eeec051e59b3ade982ef36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 7 Sep 2023 03:02:06 +0200 Subject: [PATCH 130/321] Unify `audit` and `detect` workflows --- .github/workflows/audit.yml | 20 +++++++++++++++++--- .github/workflows/detect.yml | 16 ---------------- 2 files changed, 17 insertions(+), 19 deletions(-) delete mode 100644 .github/workflows/detect.yml diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index ba5dc190..e9f4b0c5 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -1,12 +1,26 @@ name: Audit -on: [push] +on: + push: {} + pull_request: {} + schedule: + - cron: '0 0 * * *' jobs: - dependencies: + vulnerabilities: runs-on: ubuntu-latest steps: - uses: hecrj/setup-rust-action@v1 - name: Install cargo-audit run: cargo install cargo-audit - uses: actions/checkout@master - - name: Audit dependencies + - name: Audit vulnerabilities run: cargo audit + + artifacts: + runs-on: ubuntu-latest + steps: + - uses: hecrj/setup-rust-action@v1 + - name: Install cargo-outdated + run: cargo install cargo-outdated + - uses: actions/checkout@master + - name: Find outdated dependencies + run: cargo outdated --workspace --exit-code 1 diff --git a/.github/workflows/detect.yml b/.github/workflows/detect.yml deleted file mode 100644 index c4b7413d..00000000 --- a/.github/workflows/detect.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: Detect -on: - push: {} - pull_request: {} - schedule: - - cron: '0 0 * * *' -jobs: - outdated_dependencies: - runs-on: ubuntu-latest - steps: - - uses: hecrj/setup-rust-action@v1 - - name: Install cargo-outdated - run: cargo install cargo-outdated - - uses: actions/checkout@master - - name: Detect outdated dependencies - run: cargo outdated --exit-code 1 From d315e27451d46a815d18ed6037547d178413ede7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 7 Sep 2023 03:15:02 +0200 Subject: [PATCH 131/321] Update example dependencies --- examples/game_of_life/Cargo.toml | 2 +- examples/integration/Cargo.toml | 9 ++------- examples/pokedex/Cargo.toml | 7 +++++-- examples/pokedex/src/main.rs | 2 +- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/examples/game_of_life/Cargo.toml b/examples/game_of_life/Cargo.toml index f8d21c65..9b291de8 100644 --- a/examples/game_of_life/Cargo.toml +++ b/examples/game_of_life/Cargo.toml @@ -9,7 +9,7 @@ publish = false iced.workspace = true iced.features = ["debug", "canvas", "tokio"] -itertools = "0.9" +itertools = "0.11" rustc-hash.workspace = true tokio = { workspace = true, features = ["sync"] } tracing-subscriber = "0.3" diff --git a/examples/integration/Cargo.toml b/examples/integration/Cargo.toml index 4c55daa7..032cc75e 100644 --- a/examples/integration/Cargo.toml +++ b/examples/integration/Cargo.toml @@ -13,13 +13,8 @@ iced_widget.workspace = true tracing-subscriber = "0.3" [target.'cfg(target_arch = "wasm32")'.dependencies] -console_error_panic_hook = "0.1.7" -console_log = "0.2.0" +console_error_panic_hook = "0.1" +console_log = "1.0" log.workspace = true wasm-bindgen = "0.2" web-sys = { version = "0.3", features = ["Element", "HtmlCanvasElement", "Window", "Document"] } - -# This dependency a little bit quirky, it is deep in the tree and without `js` feature it -# refuses to work with `wasm32-unknown-unknown target`. Unfortunately, we need this patch -# to make it work -getrandom = { version = "0.2", features = ["js"] } diff --git a/examples/pokedex/Cargo.toml b/examples/pokedex/Cargo.toml index de8a5c17..bf7e1e35 100644 --- a/examples/pokedex/Cargo.toml +++ b/examples/pokedex/Cargo.toml @@ -21,5 +21,8 @@ default-features = false features = ["json", "rustls-tls"] [dependencies.rand] -version = "0.7" -features = ["wasm-bindgen"] +version = "0.8" + +[dependencies.getrandom] +version = "0.2" +features = ["js"] diff --git a/examples/pokedex/src/main.rs b/examples/pokedex/src/main.rs index 4482814c..8b71a269 100644 --- a/examples/pokedex/src/main.rs +++ b/examples/pokedex/src/main.rs @@ -153,7 +153,7 @@ impl Pokemon { let id = { let mut rng = rand::rngs::OsRng; - rng.gen_range(0, Pokemon::TOTAL) + rng.gen_range(0..Pokemon::TOTAL) }; let fetch_entry = async { From e5afaa08924cb0f34789b5a7de1720dc91978923 Mon Sep 17 00:00:00 2001 From: Nick Date: Wed, 6 Sep 2023 21:50:59 -0400 Subject: [PATCH 132/321] Add access to bounds/content bounds from a scrollable viewport. (#2072) * Add access to bounds/content bounds from a scrollable viewport in order to perform certain scrollable optimizations as a consumer. * Move bounds/content_bounds after relative_offset as per feedback. --- widget/src/scrollable.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index a83ed985..d0c77e6b 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -1146,6 +1146,16 @@ impl Viewport { RelativeOffset { x, y } } + + /// Returns the bounds of the current [`Viewport`]. + pub fn bounds(&self) -> Rectangle { + self.bounds + } + + /// Returns the content bounds of the current [`Viewport`]. + pub fn content_bounds(&self) -> Rectangle { + self.content_bounds + } } impl State { From 6fd2c1552735639d96d177550e98b314bd6f79a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 7 Sep 2023 05:05:43 +0200 Subject: [PATCH 133/321] Host GIFs and video examples in `iced.rs` RIP Gfycat --- README.md | 14 +++++++------- examples/README.md | 20 +++++++------------- examples/bezier_tool/README.md | 4 +--- examples/color_palette/README.md | 6 ++---- examples/counter/README.md | 4 +--- examples/custom_widget/README.md | 4 +--- examples/download_progress/README.md | 4 +--- examples/events/README.md | 6 ------ examples/game_of_life/README.md | 4 +--- examples/geometry/README.md | 4 +--- examples/integration/README.md | 4 +--- examples/loading_spinners/README.md | 6 ------ examples/pane_grid/README.md | 4 +--- examples/pokedex/README.md | 4 +--- examples/progress_bar/README.md | 4 +--- examples/qr_code/README.md | 4 +--- examples/sierpinski_triangle/README.md | 4 +--- examples/solar_system/README.md | 4 +--- examples/stopwatch/README.md | 4 +--- examples/styling/README.md | 4 +--- examples/todos/README.md | 4 ++-- examples/tour/README.md | 4 ++-- src/lib.rs | 6 +++--- widget/src/pane_grid.rs | 4 ++-- 24 files changed, 40 insertions(+), 90 deletions(-) diff --git a/README.md b/README.md index 431f14f9..825219aa 100644 --- a/README.md +++ b/README.md @@ -15,11 +15,11 @@ A cross-platform GUI library for Rust focused on simplicity and type-safety. Inspired by [Elm]. - - + + - - + + @@ -47,9 +47,9 @@ __Iced is currently experimental software.__ [Take a look at the roadmap], [Cross-platform support]: https://raw.githubusercontent.com/iced-rs/iced/master/docs/images/todos_desktop.jpg [the Web]: https://github.com/iced-rs/iced_web -[text inputs]: https://gfycat.com/alertcalmcrow-rust-gui -[scrollables]: https://gfycat.com/perkybaggybaboon-rust-gui -[Debug overlay with performance metrics]: https://gfycat.com/incredibledarlingbee +[text inputs]: https://iced.rs/examples/text_input.mp4 +[scrollables]: https://iced.rs/examples/scrollable.mp4 +[Debug overlay with performance metrics]: https://iced.rs/examples/debug.mp4 [Modular ecosystem]: ECOSYSTEM.md [renderer-agnostic native runtime]: runtime/ [`wgpu`]: https://github.com/gfx-rs/wgpu diff --git a/examples/README.md b/examples/README.md index 111e8910..71dad13e 100644 --- a/examples/README.md +++ b/examples/README.md @@ -10,8 +10,8 @@ A simple UI tour that can run both on native platforms and the web! It showcases The __[`main`](tour/src/main.rs)__ file contains all the code of the example! All the cross-platform GUI is defined in terms of __state__, __messages__, __update logic__ and __view logic__.

@@ -33,8 +33,8 @@ A todos tracker inspired by [TodoMVC]. It showcases dynamic layout, text input, The example code is located in the __[`main`](todos/src/main.rs)__ file. @@ -53,9 +53,7 @@ It runs a simulation in a background thread while allowing interaction with a `C The relevant code is located in the __[`main`](game_of_life/src/main.rs)__ file.
- - - +
You can run it with `cargo run`: @@ -72,9 +70,7 @@ An example showcasing custom styling with a light and dark theme. The example code is located in the __[`main`](styling/src/main.rs)__ file.
- - - +
You can run it with `cargo run`: @@ -120,9 +116,7 @@ Since [Iced was born in May 2019], it has been powering the user interfaces in
- - - +
[Iced was born in May 2019]: https://github.com/hecrj/coffee/pull/35 diff --git a/examples/bezier_tool/README.md b/examples/bezier_tool/README.md index ebbb12cc..6dc13785 100644 --- a/examples/bezier_tool/README.md +++ b/examples/bezier_tool/README.md @@ -5,9 +5,7 @@ A Paint-like tool for drawing Bézier curves using the `Canvas` widget. The __[`main`]__ file contains all the code of the example.
- - - +
You can run it with `cargo run`: diff --git a/examples/color_palette/README.md b/examples/color_palette/README.md index f90020b1..9c135937 100644 --- a/examples/color_palette/README.md +++ b/examples/color_palette/README.md @@ -3,13 +3,11 @@ A color palette generator, based on a user-defined root color.
- - - +
You can run it with `cargo run`: ``` -cargo run --package pure_color_palette +cargo run --package color_palette ``` diff --git a/examples/counter/README.md b/examples/counter/README.md index 4d9fc5b9..53243c24 100644 --- a/examples/counter/README.md +++ b/examples/counter/README.md @@ -5,9 +5,7 @@ The classic counter example explained in the [`README`](../../README.md). The __[`main`]__ file contains all the code of the example.
- - - +
You can run it with `cargo run`: diff --git a/examples/custom_widget/README.md b/examples/custom_widget/README.md index 3d6cf902..b80e898f 100644 --- a/examples/custom_widget/README.md +++ b/examples/custom_widget/README.md @@ -5,9 +5,7 @@ A demonstration of how to build a custom widget that draws a circle. The __[`main`]__ file contains all the code of the example.
- - - +
You can run it with `cargo run`: diff --git a/examples/download_progress/README.md b/examples/download_progress/README.md index 7999ce94..19cb2966 100644 --- a/examples/download_progress/README.md +++ b/examples/download_progress/README.md @@ -5,9 +5,7 @@ A basic application that asynchronously downloads multiple dummy files of 100 MB The example implements a custom `Subscription` in the __[`download`](src/download.rs)__ module. This subscription downloads and produces messages that can be used to keep track of its progress.
- - - +
You can run it with `cargo run`: diff --git a/examples/events/README.md b/examples/events/README.md index 3c9a1cab..fd7f9b47 100644 --- a/examples/events/README.md +++ b/examples/events/README.md @@ -4,12 +4,6 @@ A log of native events displayed using a conditional `Subscription`. The __[`main`]__ file contains all the code of the example. - - You can run it with `cargo run`: ``` cargo run --package events diff --git a/examples/game_of_life/README.md b/examples/game_of_life/README.md index aa39201c..60033c1a 100644 --- a/examples/game_of_life/README.md +++ b/examples/game_of_life/README.md @@ -7,9 +7,7 @@ It runs a simulation in a background thread while allowing interaction with a `C The __[`main`]__ file contains the relevant code of the example.
- - - +
You can run it with `cargo run`: diff --git a/examples/geometry/README.md b/examples/geometry/README.md index 4d5c81cb..16be8d19 100644 --- a/examples/geometry/README.md +++ b/examples/geometry/README.md @@ -5,9 +5,7 @@ A custom widget showcasing how to draw geometry with the `Mesh2D` primitive in [ The __[`main`]__ file contains all the code of the example.
- - - +
You can run it with `cargo run`: diff --git a/examples/integration/README.md b/examples/integration/README.md index ece9ba1e..996cdc17 100644 --- a/examples/integration/README.md +++ b/examples/integration/README.md @@ -5,9 +5,7 @@ A demonstration of how to integrate Iced in an existing [`wgpu`] application. The __[`main`]__ file contains all the code of the example.
- - - +
You can run it with `cargo run`: diff --git a/examples/loading_spinners/README.md b/examples/loading_spinners/README.md index 3573c6f6..75b88804 100644 --- a/examples/loading_spinners/README.md +++ b/examples/loading_spinners/README.md @@ -2,12 +2,6 @@ Example implementation of animated indeterminate loading spinners. - - You can run it with `cargo run`: ``` cargo run --package loading_spinners diff --git a/examples/pane_grid/README.md b/examples/pane_grid/README.md index a4cfcb7d..65357b23 100644 --- a/examples/pane_grid/README.md +++ b/examples/pane_grid/README.md @@ -15,9 +15,7 @@ This example showcases the `PaneGrid` widget, which features: The __[`main`]__ file contains all the code of the example.
- - - +
You can run it with `cargo run`: diff --git a/examples/pokedex/README.md b/examples/pokedex/README.md index 50720f57..8e8562ac 100644 --- a/examples/pokedex/README.md +++ b/examples/pokedex/README.md @@ -4,9 +4,7 @@ An application that loads a random Pokédex entry using the [PokéAPI]. All the example code can be found in the __[`main`](src/main.rs)__ file.
- - - +
You can run it on native platforms with `cargo run`: diff --git a/examples/progress_bar/README.md b/examples/progress_bar/README.md index 1e927b3c..1268ac6b 100644 --- a/examples/progress_bar/README.md +++ b/examples/progress_bar/README.md @@ -5,9 +5,7 @@ A simple progress bar that can be filled by using a slider. The __[`main`]__ file contains all the code of the example.
- - - +
You can run it with `cargo run`: diff --git a/examples/qr_code/README.md b/examples/qr_code/README.md index 2dd89c26..0d1abaa7 100644 --- a/examples/qr_code/README.md +++ b/examples/qr_code/README.md @@ -5,9 +5,7 @@ A basic QR code generator that showcases the `QRCode` widget. The __[`main`]__ file contains all the code of the example.
- - - +
You can run it with `cargo run`: diff --git a/examples/sierpinski_triangle/README.md b/examples/sierpinski_triangle/README.md index 9fd18257..8b7676d1 100644 --- a/examples/sierpinski_triangle/README.md +++ b/examples/sierpinski_triangle/README.md @@ -5,9 +5,7 @@ A simple [Sierpiński triangle](https://en.wikipedia.org/wiki/Sierpi%C5%84ski_tr Left-click add fixed point, right-click remove fixed point.
- - - +
You can run with cargo: diff --git a/examples/solar_system/README.md b/examples/solar_system/README.md index acfbc466..81ffd3a5 100644 --- a/examples/solar_system/README.md +++ b/examples/solar_system/README.md @@ -5,9 +5,7 @@ An animated solar system drawn using the `Canvas` widget and showcasing how to c The __[`main`]__ file contains all the code of the example.
- - - +
You can run it with `cargo run`: diff --git a/examples/stopwatch/README.md b/examples/stopwatch/README.md index 4cf4582e..1cf370bd 100644 --- a/examples/stopwatch/README.md +++ b/examples/stopwatch/README.md @@ -5,9 +5,7 @@ A watch with start/stop and reset buttons showcasing how to listen to time. The __[`main`]__ file contains all the code of the example.
- - - +
You can run it with `cargo run`: diff --git a/examples/styling/README.md b/examples/styling/README.md index 6c198a54..fd12300d 100644 --- a/examples/styling/README.md +++ b/examples/styling/README.md @@ -4,9 +4,7 @@ An example showcasing custom styling with a light and dark theme. All the example code is located in the __[`main`](src/main.rs)__ file.
- - - +
You can run it with `cargo run`: diff --git a/examples/todos/README.md b/examples/todos/README.md index 9c2598b9..852dd88d 100644 --- a/examples/todos/README.md +++ b/examples/todos/README.md @@ -5,8 +5,8 @@ A todos tracker inspired by [TodoMVC]. It showcases dynamic layout, text input, All the example code is located in the __[`main`]__ file. diff --git a/examples/tour/README.md b/examples/tour/README.md index 731e7e66..1c01236b 100644 --- a/examples/tour/README.md +++ b/examples/tour/README.md @@ -5,8 +5,8 @@ A simple UI tour that can run both on native platforms and the web! It showcases The __[`main`]__ file contains all the code of the example! All the cross-platform GUI is defined in terms of __state__, __messages__, __update logic__ and __view logic__. diff --git a/src/lib.rs b/src/lib.rs index 840802cc..91c78423 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,9 +20,9 @@ //! Check out the [repository] and the [examples] for more details! //! //! [Cross-platform support]: https://github.com/iced-rs/iced/blob/master/docs/images/todos_desktop.jpg?raw=true -//! [text inputs]: https://gfycat.com/alertcalmcrow-rust-gui -//! [scrollables]: https://gfycat.com/perkybaggybaboon-rust-gui -//! [Debug overlay with performance metrics]: https://gfycat.com/incredibledarlingbee +//! [text inputs]: https://iced.rs/examples/text_input.mp4 +//! [scrollables]: https://iced.rs/examples/scrollable.mp4 +//! [Debug overlay with performance metrics]: https://iced.rs/examples/debug.mp4 //! [Modular ecosystem]: https://github.com/iced-rs/iced/blob/master/ECOSYSTEM.md //! [renderer-agnostic native runtime]: https://github.com/iced-rs/iced/tree/0.10/runtime //! [`wgpu`]: https://github.com/gfx-rs/wgpu-rs diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs index d8c98858..40833622 100644 --- a/widget/src/pane_grid.rs +++ b/widget/src/pane_grid.rs @@ -1,6 +1,6 @@ //! Let your users split regions of your application and organize layout dynamically. //! -//! [![Pane grid - Iced](https://thumbs.gfycat.com/MixedFlatJellyfish-small.gif)](https://gfycat.com/mixedflatjellyfish) +//! ![Pane grid - Iced](https://iced.rs/examples/pane_grid.gif) //! //! # Example //! The [`pane_grid` example] showcases how to use a [`PaneGrid`] with resizing, @@ -49,7 +49,7 @@ use crate::core::{ /// A collection of panes distributed using either vertical or horizontal splits /// to completely fill the space available. /// -/// [![Pane grid - Iced](https://thumbs.gfycat.com/FrailFreshAiredaleterrier-small.gif)](https://gfycat.com/frailfreshairedaleterrier) +/// ![Pane grid - Iced](https://iced.rs/examples/pane_grid.gif) /// /// This distribution of space is common in tiling window managers (like /// [`awesome`](https://awesomewm.org/), [`i3`](https://i3wm.org/), or even From 87800095e27353557adb39ef42ee6f82a0075bc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 7 Sep 2023 05:43:03 +0200 Subject: [PATCH 134/321] Remove unnecessary `interpolate(flat)` in `quad.wgsl` --- wgpu/src/shader/quad.wgsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu/src/shader/quad.wgsl b/wgpu/src/shader/quad.wgsl index 87055339..023b5a6d 100644 --- a/wgpu/src/shader/quad.wgsl +++ b/wgpu/src/shader/quad.wgsl @@ -152,7 +152,7 @@ struct GradientVertexInput { @location(3) @interpolate(flat) colors_3: vec4, @location(4) @interpolate(flat) colors_4: vec4, @location(5) @interpolate(flat) offsets: vec4, - @location(6) @interpolate(flat) direction: vec4, + @location(6) direction: vec4, @location(7) position_and_scale: vec4, @location(8) border_color: vec4, @location(9) border_radius: vec4, From 1f263051b6c2d2f2a02633d8a6277c772ae8e7f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 7 Sep 2023 05:45:51 +0200 Subject: [PATCH 135/321] Implement `scale` in terms of `scale_nonuniform` --- tiny_skia/src/geometry.rs | 2 +- wgpu/src/geometry.rs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tiny_skia/src/geometry.rs b/tiny_skia/src/geometry.rs index a416020f..ced5b408 100644 --- a/tiny_skia/src/geometry.rs +++ b/tiny_skia/src/geometry.rs @@ -155,7 +155,7 @@ impl Frame { } pub fn scale(&mut self, scale: f32) { - self.transform = self.transform.pre_scale(scale, scale); + self.scale_nonuniform(Vector { x: scale, y: scale }); } pub fn scale_nonuniform(&mut self, scale: Vector) { diff --git a/wgpu/src/geometry.rs b/wgpu/src/geometry.rs index 2cd07a27..64b98469 100644 --- a/wgpu/src/geometry.rs +++ b/wgpu/src/geometry.rs @@ -447,9 +447,7 @@ impl Frame { /// Applies a uniform scaling to the current transform of the [`Frame`]. #[inline] pub fn scale(&mut self, scale: f32) { - self.transforms.current.raw = - self.transforms.current.raw.pre_scale(scale, scale); - self.transforms.current.is_identity = false; + self.scale_nonuniform(Vector { x: scale, y: scale }); } /// Applies a non-uniform scaling to the current transform of the [`Frame`]. From 09965b686ea6bf82e6c13ed5331bbeb059848e4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 7 Sep 2023 05:51:39 +0200 Subject: [PATCH 136/321] Make `scale` methods in `Frame` generic over `f32` and `Vector` --- examples/game_of_life/src/main.rs | 8 ++++---- renderer/src/geometry.rs | 4 ++-- tiny_skia/src/geometry.rs | 8 ++++++-- wgpu/src/geometry.rs | 8 ++++++-- widget/src/qr_code.rs | 2 +- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/examples/game_of_life/src/main.rs b/examples/game_of_life/src/main.rs index e951d734..1f266c8e 100644 --- a/examples/game_of_life/src/main.rs +++ b/examples/game_of_life/src/main.rs @@ -550,7 +550,7 @@ mod grid { frame.translate(center); frame.scale(self.scaling); frame.translate(self.translation); - frame.scale(Cell::SIZE as f32); + frame.scale(Cell::SIZE); let region = self.visible_region(frame.size()); @@ -576,7 +576,7 @@ mod grid { frame.translate(center); frame.scale(self.scaling); frame.translate(self.translation); - frame.scale(Cell::SIZE as f32); + frame.scale(Cell::SIZE); frame.fill_rectangle( Point::new(cell.j as f32, cell.i as f32), @@ -630,7 +630,7 @@ mod grid { frame.translate(center); frame.scale(self.scaling); frame.translate(self.translation); - frame.scale(Cell::SIZE as f32); + frame.scale(Cell::SIZE); let region = self.visible_region(frame.size()); let rows = region.rows(); @@ -834,7 +834,7 @@ mod grid { } impl Cell { - const SIZE: usize = 20; + const SIZE: u16 = 20; fn at(position: Point) -> Cell { let i = (position.y / Cell::SIZE as f32).ceil() as isize; diff --git a/renderer/src/geometry.rs b/renderer/src/geometry.rs index 0e524169..1a974b7f 100644 --- a/renderer/src/geometry.rs +++ b/renderer/src/geometry.rs @@ -170,13 +170,13 @@ impl Frame { /// Applies a uniform scaling to the current transform of the [`Frame`]. #[inline] - pub fn scale(&mut self, scale: f32) { + pub fn scale(&mut self, scale: impl Into) { delegate!(self, frame, frame.scale(scale)); } /// Applies a non-uniform scaling to the current transform of the [`Frame`]. #[inline] - pub fn scale_nonuniform(&mut self, scale: Vector) { + pub fn scale_nonuniform(&mut self, scale: impl Into) { delegate!(self, frame, frame.scale_nonuniform(scale)); } diff --git a/tiny_skia/src/geometry.rs b/tiny_skia/src/geometry.rs index ced5b408..1df5aa18 100644 --- a/tiny_skia/src/geometry.rs +++ b/tiny_skia/src/geometry.rs @@ -154,11 +154,15 @@ impl Frame { .pre_concat(tiny_skia::Transform::from_rotate(angle.to_degrees())); } - pub fn scale(&mut self, scale: f32) { + pub fn scale(&mut self, scale: impl Into) { + let scale = scale.into(); + self.scale_nonuniform(Vector { x: scale, y: scale }); } - pub fn scale_nonuniform(&mut self, scale: Vector) { + pub fn scale_nonuniform(&mut self, scale: impl Into) { + let scale = scale.into(); + self.transform = self.transform.pre_scale(scale.x, scale.y); } diff --git a/wgpu/src/geometry.rs b/wgpu/src/geometry.rs index 64b98469..c3e16f8c 100644 --- a/wgpu/src/geometry.rs +++ b/wgpu/src/geometry.rs @@ -446,13 +446,17 @@ impl Frame { /// Applies a uniform scaling to the current transform of the [`Frame`]. #[inline] - pub fn scale(&mut self, scale: f32) { + pub fn scale(&mut self, scale: impl Into) { + let scale = scale.into(); + self.scale_nonuniform(Vector { x: scale, y: scale }); } /// Applies a non-uniform scaling to the current transform of the [`Frame`]. #[inline] - pub fn scale_nonuniform(&mut self, scale: Vector) { + pub fn scale_nonuniform(&mut self, scale: impl Into) { + let scale = scale.into(); + self.transforms.current.raw = self.transforms.current.raw.pre_scale(scale.x, scale.y); self.transforms.current.is_identity = false; diff --git a/widget/src/qr_code.rs b/widget/src/qr_code.rs index 51a541fd..75409091 100644 --- a/widget/src/qr_code.rs +++ b/widget/src/qr_code.rs @@ -86,7 +86,7 @@ impl<'a, Message, Theme> Widget> for QRCode<'a> { let geometry = self.state.cache.draw(renderer, bounds.size(), |frame| { // Scale units to cell size - frame.scale(f32::from(self.cell_size)); + frame.scale(self.cell_size); // Draw background frame.fill_rectangle( From 181708a1c0f4920f7491df4516b0de3f61993391 Mon Sep 17 00:00:00 2001 From: Matthias Vogelgesang Date: Mon, 28 Aug 2023 22:56:47 +0200 Subject: [PATCH 137/321] Compute gradients in Oklab color space --- wgpu/src/shader/quad.wgsl | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/wgpu/src/shader/quad.wgsl b/wgpu/src/shader/quad.wgsl index 023b5a6d..cba7e5a4 100644 --- a/wgpu/src/shader/quad.wgsl +++ b/wgpu/src/shader/quad.wgsl @@ -230,6 +230,18 @@ fn gradient( let unit = normalize(v1); let coord_offset = dot(unit, v2) / length(v1); + let to_lms: mat3x4 = mat3x4( + vec4(0.4121656120, 0.2118591070, 0.0883097947, 0.0), + vec4(0.5362752080, 0.6807189584, 0.2818474174, 0.0), + vec4(0.0514575653, 0.1074065790, 0.6302613616, 0.0), + ); + + let to_rgb: mat3x4 = mat3x4( + vec4( 4.0767245293, -3.3072168827, 0.2307590544, 0.0), + vec4(-1.2681437731, 2.6093323231, -0.3411344290, 0.0), + vec4(-0.0041119885, -0.7034763098, 1.7068625689, 0.0), + ); + //need to store these as a var to use dynamic indexing in a loop //this is already added to wgsl spec but not in wgpu yet var colors_arr = colors; @@ -248,11 +260,15 @@ fn gradient( } if (curr_offset <= coord_offset && coord_offset <= next_offset) { - color = mix(colors_arr[i], colors_arr[i+1], smoothstep( - curr_offset, - next_offset, - coord_offset, - )); + // blend in OKLab + let factor = smoothstep(curr_offset, next_offset, coord_offset); + let lms_a = pow(colors_arr[i] * to_lms, vec3(1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0)); + let lms_b = pow(colors_arr[i+1] * to_lms, vec3(1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0)); + let mixed = mix(lms_a, lms_b, factor); + + // back to sRGB + color = to_rgb * (mixed * mixed * mixed); + color.a = mix(colors_arr[i].a, colors_arr[i+1].a, factor); } if (coord_offset >= offsets_arr[last_index]) { From 2b746c7b253573c9194844a02afba709839f5910 Mon Sep 17 00:00:00 2001 From: Matthias Vogelgesang Date: Sat, 2 Sep 2023 13:44:45 +0200 Subject: [PATCH 138/321] Add gradient picker example --- examples/gradients/Cargo.toml | 8 ++ examples/gradients/src/main.rs | 136 +++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 examples/gradients/Cargo.toml create mode 100644 examples/gradients/src/main.rs diff --git a/examples/gradients/Cargo.toml b/examples/gradients/Cargo.toml new file mode 100644 index 00000000..1bc65a9c --- /dev/null +++ b/examples/gradients/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "gradients" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] +iced = { path = "../.." } diff --git a/examples/gradients/src/main.rs b/examples/gradients/src/main.rs new file mode 100644 index 00000000..d8b7945e --- /dev/null +++ b/examples/gradients/src/main.rs @@ -0,0 +1,136 @@ +use iced::widget::{column, container, row, slider, text}; +use iced::{ + gradient, Alignment, Background, BorderRadius, Color, Element, Length, + Radians, Sandbox, Settings, +}; + +pub fn main() -> iced::Result { + Gradient::run(Settings::default()) +} + +struct Gradient { + first: Color, + second: Color, + angle: f32, +} + +#[derive(Debug, Clone, Copy)] +enum Message { + FirstChanged(Color), + SecondChanged(Color), + AngleChanged(f32), +} + +impl Sandbox for Gradient { + type Message = Message; + + fn new() -> Self { + let first = Color::new(0.2784314, 0.0627451, 0.4117647, 1.0); + let second = Color::new(0.1882353, 0.772549, 0.8235294, 1.0); + + Self { + first, + second, + angle: 0.0, + } + } + + fn title(&self) -> String { + String::from("Color gradient") + } + + fn update(&mut self, message: Message) { + match message { + Message::FirstChanged(color) => self.first = color, + Message::SecondChanged(color) => self.second = color, + Message::AngleChanged(angle) => self.angle = angle, + } + } + + fn view(&self) -> Element { + let first = self.first; + let second = self.second; + let angle = self.angle; + + let gradient_box = container(text("")) + .width(Length::Fill) + .height(Length::Fill) + .center_x() + .center_y() + .style(move |_: &_| { + let gradient = gradient::Linear::new(Radians(angle)) + .add_stop(0.0, first) + .add_stop(1.0, second) + .into(); + + container::Appearance { + text_color: None, + background: Some(Background::Gradient(gradient)), + border_radius: BorderRadius::default(), + border_width: 0.0, + border_color: Color::new(0.0, 0.0, 0.0, 0.0), + } + }); + + let range = 0.0..=1.0; + let l = self.first; + let r = self.second; + + let first_color_picker = row![ + text("First").width(64), + slider(range.clone(), l.r, move |v| { + Message::FirstChanged(Color::new(v, l.g, l.b, l.a)) + }) + .step(0.01), + slider(range.clone(), l.g, move |v| { + Message::FirstChanged(Color::new(l.r, v, l.b, l.a)) + }) + .step(0.01), + slider(range.clone(), l.b, move |v| { + Message::FirstChanged(Color::new(l.r, l.g, v, l.a)) + }) + .step(0.01), + ] + .spacing(8) + .padding(8) + .align_items(Alignment::Center); + + let second_color_picker = row![ + text("Second").width(64), + slider(range.clone(), r.r, move |v| { + Message::SecondChanged(Color::new(v, r.g, r.b, r.a)) + }) + .step(0.01), + slider(range.clone(), r.g, move |v| { + Message::SecondChanged(Color::new(r.r, v, r.b, r.a)) + }) + .step(0.01), + slider(range.clone(), r.b, move |v| { + Message::SecondChanged(Color::new(r.r, r.g, v, r.a)) + }) + .step(0.01), + ] + .spacing(8) + .padding(8) + .align_items(Alignment::Center); + + let angle_picker = row![ + text("Angle").width(64), + slider(0.0..=std::f32::consts::PI * 2.0, self.angle, move |v| { + Message::AngleChanged(v) + }) + .step(0.01) + ] + .spacing(8) + .padding(8) + .align_items(Alignment::Center); + + column![ + first_color_picker, + second_color_picker, + angle_picker, + gradient_box + ] + .into() + } +} From 10d0b257f929296b1991a440f62c87487c0076dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 7 Sep 2023 07:24:32 +0200 Subject: [PATCH 139/321] Use Oklab color interpolation only with `color::GAMMA_CORRECTION` --- wgpu/src/quad/gradient.rs | 19 +- wgpu/src/quad/solid.rs | 6 +- wgpu/src/shader/color/linear_rgb.wgsl | 3 + wgpu/src/shader/color/oklab.wgsl | 26 ++ wgpu/src/shader/quad.wgsl | 322 ------------------------- wgpu/src/shader/quad/gradient.wgsl | 205 ++++++++++++++++ wgpu/src/shader/quad/solid.wgsl | 99 ++++++++ wgpu/src/shader/triangle.wgsl | 160 ------------ wgpu/src/shader/triangle/gradient.wgsl | 134 ++++++++++ wgpu/src/shader/triangle/solid.wgsl | 24 ++ wgpu/src/triangle.rs | 35 ++- 11 files changed, 544 insertions(+), 489 deletions(-) create mode 100644 wgpu/src/shader/color/linear_rgb.wgsl create mode 100644 wgpu/src/shader/color/oklab.wgsl create mode 100644 wgpu/src/shader/quad/gradient.wgsl create mode 100644 wgpu/src/shader/quad/solid.wgsl create mode 100644 wgpu/src/shader/triangle/gradient.wgsl create mode 100644 wgpu/src/shader/triangle/solid.wgsl diff --git a/wgpu/src/quad/gradient.rs b/wgpu/src/quad/gradient.rs index 6db37252..a8e83d01 100644 --- a/wgpu/src/quad/gradient.rs +++ b/wgpu/src/quad/gradient.rs @@ -1,3 +1,4 @@ +use crate::graphics::color; use crate::graphics::gradient; use crate::quad::{self, Quad}; use crate::Buffer; @@ -78,7 +79,23 @@ impl Pipeline { device.create_shader_module(wgpu::ShaderModuleDescriptor { label: Some("iced_wgpu.quad.gradient.shader"), source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed( - include_str!("../shader/quad.wgsl"), + if color::GAMMA_CORRECTION { + concat!( + include_str!("../shader/quad.wgsl"), + "\n", + include_str!("../shader/quad/gradient.wgsl"), + "\n", + include_str!("../shader/color/oklab.wgsl") + ) + } else { + concat!( + include_str!("../shader/quad.wgsl"), + "\n", + include_str!("../shader/quad/gradient.wgsl"), + "\n", + include_str!("../shader/color/linear_rgb.wgsl") + ) + }, )), }); diff --git a/wgpu/src/quad/solid.rs b/wgpu/src/quad/solid.rs index f8f1e3a5..9bc6b466 100644 --- a/wgpu/src/quad/solid.rs +++ b/wgpu/src/quad/solid.rs @@ -72,7 +72,11 @@ impl Pipeline { device.create_shader_module(wgpu::ShaderModuleDescriptor { label: Some("iced_wgpu.quad.solid.shader"), source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed( - include_str!("../shader/quad.wgsl"), + concat!( + include_str!("../shader/quad.wgsl"), + "\n", + include_str!("../shader/quad/solid.wgsl"), + ), )), }); diff --git a/wgpu/src/shader/color/linear_rgb.wgsl b/wgpu/src/shader/color/linear_rgb.wgsl new file mode 100644 index 00000000..a5cf45d4 --- /dev/null +++ b/wgpu/src/shader/color/linear_rgb.wgsl @@ -0,0 +1,3 @@ +fn interpolate_color(from_: vec4, to_: vec4, factor: f32) -> vec4 { + return mix(from_, to_, factor); +} diff --git a/wgpu/src/shader/color/oklab.wgsl b/wgpu/src/shader/color/oklab.wgsl new file mode 100644 index 00000000..0dc37ba6 --- /dev/null +++ b/wgpu/src/shader/color/oklab.wgsl @@ -0,0 +1,26 @@ +const to_lms = mat3x4( + vec4(0.4121656120, 0.2118591070, 0.0883097947, 0.0), + vec4(0.5362752080, 0.6807189584, 0.2818474174, 0.0), + vec4(0.0514575653, 0.1074065790, 0.6302613616, 0.0), +); + +const to_rgb = mat3x4( + vec4( 4.0767245293, -3.3072168827, 0.2307590544, 0.0), + vec4(-1.2681437731, 2.6093323231, -0.3411344290, 0.0), + vec4(-0.0041119885, -0.7034763098, 1.7068625689, 0.0), +); + +fn interpolate_color(from_: vec4, to_: vec4, factor: f32) -> vec4 { + // To Oklab + let lms_a = pow(from_ * to_lms, vec3(1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0)); + let lms_b = pow(to_ * to_lms, vec3(1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0)); + let mixed = mix(lms_a, lms_b, factor); + + // Back to linear RGB + var color = to_rgb * (mixed * mixed * mixed); + + // Alpha interpolation + color.a = mix(from_.a, to_.a, factor); + + return color; +} diff --git a/wgpu/src/shader/quad.wgsl b/wgpu/src/shader/quad.wgsl index cba7e5a4..f919cfe2 100644 --- a/wgpu/src/shader/quad.wgsl +++ b/wgpu/src/shader/quad.wgsl @@ -37,325 +37,3 @@ fn select_border_radius(radi: vec4, position: vec2, center: vec2) rx = select(rx, ry, position.y > center.y); return rx; } - -fn unpack_u32(color: vec2) -> vec4 { - let rg: vec2 = unpack2x16float(color.x); - let ba: vec2 = unpack2x16float(color.y); - - return vec4(rg.y, rg.x, ba.y, ba.x); -} - -struct SolidVertexInput { - @location(0) v_pos: vec2, - @location(1) color: vec4, - @location(2) pos: vec2, - @location(3) scale: vec2, - @location(4) border_color: vec4, - @location(5) border_radius: vec4, - @location(6) border_width: f32, -} - -struct SolidVertexOutput { - @builtin(position) position: vec4, - @location(0) color: vec4, - @location(1) border_color: vec4, - @location(2) pos: vec2, - @location(3) scale: vec2, - @location(4) border_radius: vec4, - @location(5) border_width: f32, -} - -@vertex -fn solid_vs_main(input: SolidVertexInput) -> SolidVertexOutput { - var out: SolidVertexOutput; - - var pos: vec2 = input.pos * globals.scale; - var scale: vec2 = input.scale * globals.scale; - - var min_border_radius = min(input.scale.x, input.scale.y) * 0.5; - var border_radius: vec4 = vec4( - min(input.border_radius.x, min_border_radius), - min(input.border_radius.y, min_border_radius), - min(input.border_radius.z, min_border_radius), - min(input.border_radius.w, min_border_radius) - ); - - var transform: mat4x4 = mat4x4( - vec4(scale.x + 1.0, 0.0, 0.0, 0.0), - vec4(0.0, scale.y + 1.0, 0.0, 0.0), - vec4(0.0, 0.0, 1.0, 0.0), - vec4(pos - vec2(0.5, 0.5), 0.0, 1.0) - ); - - out.position = globals.transform * transform * vec4(input.v_pos, 0.0, 1.0); - out.color = input.color; - out.border_color = input.border_color; - out.pos = pos; - out.scale = scale; - out.border_radius = border_radius * globals.scale; - out.border_width = input.border_width * globals.scale; - - return out; -} - -@fragment -fn solid_fs_main( - input: SolidVertexOutput -) -> @location(0) vec4 { - var mixed_color: vec4 = input.color; - - var border_radius = select_border_radius( - input.border_radius, - input.position.xy, - (input.pos + input.scale * 0.5).xy - ); - - if (input.border_width > 0.0) { - var internal_border: f32 = max(border_radius - input.border_width, 0.0); - - var internal_distance: f32 = distance_alg( - input.position.xy, - input.pos + vec2(input.border_width, input.border_width), - input.scale - vec2(input.border_width * 2.0, input.border_width * 2.0), - internal_border - ); - - var border_mix: f32 = smoothstep( - max(internal_border - 0.5, 0.0), - internal_border + 0.5, - internal_distance - ); - - mixed_color = mix(input.color, input.border_color, vec4(border_mix, border_mix, border_mix, border_mix)); - } - - var dist: f32 = distance_alg( - vec2(input.position.x, input.position.y), - input.pos, - input.scale, - border_radius - ); - - var radius_alpha: f32 = 1.0 - smoothstep( - max(border_radius - 0.5, 0.0), - border_radius + 0.5, - dist - ); - - return vec4(mixed_color.x, mixed_color.y, mixed_color.z, mixed_color.w * radius_alpha); -} - -struct GradientVertexInput { - @location(0) v_pos: vec2, - @location(1) @interpolate(flat) colors_1: vec4, - @location(2) @interpolate(flat) colors_2: vec4, - @location(3) @interpolate(flat) colors_3: vec4, - @location(4) @interpolate(flat) colors_4: vec4, - @location(5) @interpolate(flat) offsets: vec4, - @location(6) direction: vec4, - @location(7) position_and_scale: vec4, - @location(8) border_color: vec4, - @location(9) border_radius: vec4, - @location(10) border_width: f32, -} - -struct GradientVertexOutput { - @builtin(position) position: vec4, - @location(1) @interpolate(flat) colors_1: vec4, - @location(2) @interpolate(flat) colors_2: vec4, - @location(3) @interpolate(flat) colors_3: vec4, - @location(4) @interpolate(flat) colors_4: vec4, - @location(5) @interpolate(flat) offsets: vec4, - @location(6) direction: vec4, - @location(7) position_and_scale: vec4, - @location(8) border_color: vec4, - @location(9) border_radius: vec4, - @location(10) border_width: f32, -} - -@vertex -fn gradient_vs_main(input: GradientVertexInput) -> GradientVertexOutput { - var out: GradientVertexOutput; - - var pos: vec2 = input.position_and_scale.xy * globals.scale; - var scale: vec2 = input.position_and_scale.zw * globals.scale; - - var min_border_radius = min(input.position_and_scale.z, input.position_and_scale.w) * 0.5; - var border_radius: vec4 = vec4( - min(input.border_radius.x, min_border_radius), - min(input.border_radius.y, min_border_radius), - min(input.border_radius.z, min_border_radius), - min(input.border_radius.w, min_border_radius) - ); - - var transform: mat4x4 = mat4x4( - vec4(scale.x + 1.0, 0.0, 0.0, 0.0), - vec4(0.0, scale.y + 1.0, 0.0, 0.0), - vec4(0.0, 0.0, 1.0, 0.0), - vec4(pos - vec2(0.5, 0.5), 0.0, 1.0) - ); - - out.position = globals.transform * transform * vec4(input.v_pos, 0.0, 1.0); - out.colors_1 = input.colors_1; - out.colors_2 = input.colors_2; - out.colors_3 = input.colors_3; - out.colors_4 = input.colors_4; - out.offsets = input.offsets; - out.direction = input.direction * globals.scale; - out.position_and_scale = vec4(pos, scale); - out.border_color = input.border_color; - out.border_radius = border_radius * globals.scale; - out.border_width = input.border_width * globals.scale; - - return out; -} - -fn random(coords: vec2) -> f32 { - return fract(sin(dot(coords, vec2(12.9898,78.233))) * 43758.5453); -} - -/// Returns the current interpolated color with a max 8-stop gradient -fn gradient( - raw_position: vec2, - direction: vec4, - colors: array, 8>, - offsets: array, - last_index: i32 -) -> vec4 { - let start = direction.xy; - let end = direction.zw; - - let v1 = end - start; - let v2 = raw_position - start; - let unit = normalize(v1); - let coord_offset = dot(unit, v2) / length(v1); - - let to_lms: mat3x4 = mat3x4( - vec4(0.4121656120, 0.2118591070, 0.0883097947, 0.0), - vec4(0.5362752080, 0.6807189584, 0.2818474174, 0.0), - vec4(0.0514575653, 0.1074065790, 0.6302613616, 0.0), - ); - - let to_rgb: mat3x4 = mat3x4( - vec4( 4.0767245293, -3.3072168827, 0.2307590544, 0.0), - vec4(-1.2681437731, 2.6093323231, -0.3411344290, 0.0), - vec4(-0.0041119885, -0.7034763098, 1.7068625689, 0.0), - ); - - //need to store these as a var to use dynamic indexing in a loop - //this is already added to wgsl spec but not in wgpu yet - var colors_arr = colors; - var offsets_arr = offsets; - - var color: vec4; - - let noise_granularity: f32 = 0.3/255.0; - - for (var i: i32 = 0; i < last_index; i++) { - let curr_offset = offsets_arr[i]; - let next_offset = offsets_arr[i+1]; - - if (coord_offset <= offsets_arr[0]) { - color = colors_arr[0]; - } - - if (curr_offset <= coord_offset && coord_offset <= next_offset) { - // blend in OKLab - let factor = smoothstep(curr_offset, next_offset, coord_offset); - let lms_a = pow(colors_arr[i] * to_lms, vec3(1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0)); - let lms_b = pow(colors_arr[i+1] * to_lms, vec3(1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0)); - let mixed = mix(lms_a, lms_b, factor); - - // back to sRGB - color = to_rgb * (mixed * mixed * mixed); - color.a = mix(colors_arr[i].a, colors_arr[i+1].a, factor); - } - - if (coord_offset >= offsets_arr[last_index]) { - color = colors_arr[last_index]; - } - } - - return color + mix(-noise_granularity, noise_granularity, random(raw_position)); -} - -@fragment -fn gradient_fs_main(input: GradientVertexOutput) -> @location(0) vec4 { - let colors = array, 8>( - unpack_u32(input.colors_1.xy), - unpack_u32(input.colors_1.zw), - unpack_u32(input.colors_2.xy), - unpack_u32(input.colors_2.zw), - unpack_u32(input.colors_3.xy), - unpack_u32(input.colors_3.zw), - unpack_u32(input.colors_4.xy), - unpack_u32(input.colors_4.zw), - ); - - let offsets_1: vec4 = unpack_u32(input.offsets.xy); - let offsets_2: vec4 = unpack_u32(input.offsets.zw); - - var offsets = array( - offsets_1.x, - offsets_1.y, - offsets_1.z, - offsets_1.w, - offsets_2.x, - offsets_2.y, - offsets_2.z, - offsets_2.w, - ); - - //TODO could just pass this in to the shader but is probably more performant to just check it here - var last_index = 7; - for (var i: i32 = 0; i <= 7; i++) { - if (offsets[i] > 1.0) { - last_index = i - 1; - break; - } - } - - var mixed_color: vec4 = gradient(input.position.xy, input.direction, colors, offsets, last_index); - - let pos = input.position_and_scale.xy; - let scale = input.position_and_scale.zw; - - var border_radius = select_border_radius( - input.border_radius, - input.position.xy, - (pos + scale * 0.5).xy - ); - - if (input.border_width > 0.0) { - var internal_border: f32 = max(border_radius - input.border_width, 0.0); - - var internal_distance: f32 = distance_alg( - input.position.xy, - pos + vec2(input.border_width, input.border_width), - scale - vec2(input.border_width * 2.0, input.border_width * 2.0), - internal_border - ); - - var border_mix: f32 = smoothstep( - max(internal_border - 0.5, 0.0), - internal_border + 0.5, - internal_distance - ); - - mixed_color = mix(mixed_color, input.border_color, vec4(border_mix, border_mix, border_mix, border_mix)); - } - - var dist: f32 = distance_alg( - input.position.xy, - pos, - scale, - border_radius - ); - - var radius_alpha: f32 = 1.0 - smoothstep( - max(border_radius - 0.5, 0.0), - border_radius + 0.5, - dist); - - return vec4(mixed_color.x, mixed_color.y, mixed_color.z, mixed_color.w * radius_alpha); -} diff --git a/wgpu/src/shader/quad/gradient.wgsl b/wgpu/src/shader/quad/gradient.wgsl new file mode 100644 index 00000000..0754e97f --- /dev/null +++ b/wgpu/src/shader/quad/gradient.wgsl @@ -0,0 +1,205 @@ +struct GradientVertexInput { + @location(0) v_pos: vec2, + @location(1) @interpolate(flat) colors_1: vec4, + @location(2) @interpolate(flat) colors_2: vec4, + @location(3) @interpolate(flat) colors_3: vec4, + @location(4) @interpolate(flat) colors_4: vec4, + @location(5) @interpolate(flat) offsets: vec4, + @location(6) direction: vec4, + @location(7) position_and_scale: vec4, + @location(8) border_color: vec4, + @location(9) border_radius: vec4, + @location(10) border_width: f32, +} + +struct GradientVertexOutput { + @builtin(position) position: vec4, + @location(1) @interpolate(flat) colors_1: vec4, + @location(2) @interpolate(flat) colors_2: vec4, + @location(3) @interpolate(flat) colors_3: vec4, + @location(4) @interpolate(flat) colors_4: vec4, + @location(5) @interpolate(flat) offsets: vec4, + @location(6) direction: vec4, + @location(7) position_and_scale: vec4, + @location(8) border_color: vec4, + @location(9) border_radius: vec4, + @location(10) border_width: f32, +} + +@vertex +fn gradient_vs_main(input: GradientVertexInput) -> GradientVertexOutput { + var out: GradientVertexOutput; + + var pos: vec2 = input.position_and_scale.xy * globals.scale; + var scale: vec2 = input.position_and_scale.zw * globals.scale; + + var min_border_radius = min(input.position_and_scale.z, input.position_and_scale.w) * 0.5; + var border_radius: vec4 = vec4( + min(input.border_radius.x, min_border_radius), + min(input.border_radius.y, min_border_radius), + min(input.border_radius.z, min_border_radius), + min(input.border_radius.w, min_border_radius) + ); + + var transform: mat4x4 = mat4x4( + vec4(scale.x + 1.0, 0.0, 0.0, 0.0), + vec4(0.0, scale.y + 1.0, 0.0, 0.0), + vec4(0.0, 0.0, 1.0, 0.0), + vec4(pos - vec2(0.5, 0.5), 0.0, 1.0) + ); + + out.position = globals.transform * transform * vec4(input.v_pos, 0.0, 1.0); + out.colors_1 = input.colors_1; + out.colors_2 = input.colors_2; + out.colors_3 = input.colors_3; + out.colors_4 = input.colors_4; + out.offsets = input.offsets; + out.direction = input.direction * globals.scale; + out.position_and_scale = vec4(pos, scale); + out.border_color = input.border_color; + out.border_radius = border_radius * globals.scale; + out.border_width = input.border_width * globals.scale; + + return out; +} + +fn random(coords: vec2) -> f32 { + return fract(sin(dot(coords, vec2(12.9898,78.233))) * 43758.5453); +} + +/// Returns the current interpolated color with a max 8-stop gradient +fn gradient( + raw_position: vec2, + direction: vec4, + colors: array, 8>, + offsets: array, + last_index: i32 +) -> vec4 { + let start = direction.xy; + let end = direction.zw; + + let v1 = end - start; + let v2 = raw_position - start; + let unit = normalize(v1); + let coord_offset = dot(unit, v2) / length(v1); + + //need to store these as a var to use dynamic indexing in a loop + //this is already added to wgsl spec but not in wgpu yet + var colors_arr = colors; + var offsets_arr = offsets; + + var color: vec4; + + let noise_granularity: f32 = 0.3/255.0; + + for (var i: i32 = 0; i < last_index; i++) { + let curr_offset = offsets_arr[i]; + let next_offset = offsets_arr[i+1]; + + if (coord_offset <= offsets_arr[0]) { + color = colors_arr[0]; + } + + if (curr_offset <= coord_offset && coord_offset <= next_offset) { + let from_ = colors_arr[i]; + let to_ = colors_arr[i+1]; + let factor = smoothstep(curr_offset, next_offset, coord_offset); + + color = interpolate_color(from_, to_, factor); + } + + if (coord_offset >= offsets_arr[last_index]) { + color = colors_arr[last_index]; + } + } + + return color + mix(-noise_granularity, noise_granularity, random(raw_position)); +} + +@fragment +fn gradient_fs_main(input: GradientVertexOutput) -> @location(0) vec4 { + let colors = array, 8>( + unpack_u32(input.colors_1.xy), + unpack_u32(input.colors_1.zw), + unpack_u32(input.colors_2.xy), + unpack_u32(input.colors_2.zw), + unpack_u32(input.colors_3.xy), + unpack_u32(input.colors_3.zw), + unpack_u32(input.colors_4.xy), + unpack_u32(input.colors_4.zw), + ); + + let offsets_1: vec4 = unpack_u32(input.offsets.xy); + let offsets_2: vec4 = unpack_u32(input.offsets.zw); + + var offsets = array( + offsets_1.x, + offsets_1.y, + offsets_1.z, + offsets_1.w, + offsets_2.x, + offsets_2.y, + offsets_2.z, + offsets_2.w, + ); + + //TODO could just pass this in to the shader but is probably more performant to just check it here + var last_index = 7; + for (var i: i32 = 0; i <= 7; i++) { + if (offsets[i] > 1.0) { + last_index = i - 1; + break; + } + } + + var mixed_color: vec4 = gradient(input.position.xy, input.direction, colors, offsets, last_index); + + let pos = input.position_and_scale.xy; + let scale = input.position_and_scale.zw; + + var border_radius = select_border_radius( + input.border_radius, + input.position.xy, + (pos + scale * 0.5).xy + ); + + if (input.border_width > 0.0) { + var internal_border: f32 = max(border_radius - input.border_width, 0.0); + + var internal_distance: f32 = distance_alg( + input.position.xy, + pos + vec2(input.border_width, input.border_width), + scale - vec2(input.border_width * 2.0, input.border_width * 2.0), + internal_border + ); + + var border_mix: f32 = smoothstep( + max(internal_border - 0.5, 0.0), + internal_border + 0.5, + internal_distance + ); + + mixed_color = mix(mixed_color, input.border_color, vec4(border_mix, border_mix, border_mix, border_mix)); + } + + var dist: f32 = distance_alg( + input.position.xy, + pos, + scale, + border_radius + ); + + var radius_alpha: f32 = 1.0 - smoothstep( + max(border_radius - 0.5, 0.0), + border_radius + 0.5, + dist); + + return vec4(mixed_color.x, mixed_color.y, mixed_color.z, mixed_color.w * radius_alpha); +} + +fn unpack_u32(color: vec2) -> vec4 { + let rg: vec2 = unpack2x16float(color.x); + let ba: vec2 = unpack2x16float(color.y); + + return vec4(rg.y, rg.x, ba.y, ba.x); +} diff --git a/wgpu/src/shader/quad/solid.wgsl b/wgpu/src/shader/quad/solid.wgsl new file mode 100644 index 00000000..ebd6d877 --- /dev/null +++ b/wgpu/src/shader/quad/solid.wgsl @@ -0,0 +1,99 @@ +struct SolidVertexInput { + @location(0) v_pos: vec2, + @location(1) color: vec4, + @location(2) pos: vec2, + @location(3) scale: vec2, + @location(4) border_color: vec4, + @location(5) border_radius: vec4, + @location(6) border_width: f32, +} + +struct SolidVertexOutput { + @builtin(position) position: vec4, + @location(0) color: vec4, + @location(1) border_color: vec4, + @location(2) pos: vec2, + @location(3) scale: vec2, + @location(4) border_radius: vec4, + @location(5) border_width: f32, +} + +@vertex +fn solid_vs_main(input: SolidVertexInput) -> SolidVertexOutput { + var out: SolidVertexOutput; + + var pos: vec2 = input.pos * globals.scale; + var scale: vec2 = input.scale * globals.scale; + + var min_border_radius = min(input.scale.x, input.scale.y) * 0.5; + var border_radius: vec4 = vec4( + min(input.border_radius.x, min_border_radius), + min(input.border_radius.y, min_border_radius), + min(input.border_radius.z, min_border_radius), + min(input.border_radius.w, min_border_radius) + ); + + var transform: mat4x4 = mat4x4( + vec4(scale.x + 1.0, 0.0, 0.0, 0.0), + vec4(0.0, scale.y + 1.0, 0.0, 0.0), + vec4(0.0, 0.0, 1.0, 0.0), + vec4(pos - vec2(0.5, 0.5), 0.0, 1.0) + ); + + out.position = globals.transform * transform * vec4(input.v_pos, 0.0, 1.0); + out.color = input.color; + out.border_color = input.border_color; + out.pos = pos; + out.scale = scale; + out.border_radius = border_radius * globals.scale; + out.border_width = input.border_width * globals.scale; + + return out; +} + +@fragment +fn solid_fs_main( + input: SolidVertexOutput +) -> @location(0) vec4 { + var mixed_color: vec4 = input.color; + + var border_radius = select_border_radius( + input.border_radius, + input.position.xy, + (input.pos + input.scale * 0.5).xy + ); + + if (input.border_width > 0.0) { + var internal_border: f32 = max(border_radius - input.border_width, 0.0); + + var internal_distance: f32 = distance_alg( + input.position.xy, + input.pos + vec2(input.border_width, input.border_width), + input.scale - vec2(input.border_width * 2.0, input.border_width * 2.0), + internal_border + ); + + var border_mix: f32 = smoothstep( + max(internal_border - 0.5, 0.0), + internal_border + 0.5, + internal_distance + ); + + mixed_color = mix(input.color, input.border_color, vec4(border_mix, border_mix, border_mix, border_mix)); + } + + var dist: f32 = distance_alg( + vec2(input.position.x, input.position.y), + input.pos, + input.scale, + border_radius + ); + + var radius_alpha: f32 = 1.0 - smoothstep( + max(border_radius - 0.5, 0.0), + border_radius + 0.5, + dist + ); + + return vec4(mixed_color.x, mixed_color.y, mixed_color.z, mixed_color.w * radius_alpha); +} diff --git a/wgpu/src/shader/triangle.wgsl b/wgpu/src/shader/triangle.wgsl index 3a2b9845..e4c19344 100644 --- a/wgpu/src/shader/triangle.wgsl +++ b/wgpu/src/shader/triangle.wgsl @@ -3,163 +3,3 @@ struct Globals { } @group(0) @binding(0) var globals: Globals; - -fn unpack_u32(color: vec2) -> vec4 { - let rg: vec2 = unpack2x16float(color.x); - let ba: vec2 = unpack2x16float(color.y); - - return vec4(rg.y, rg.x, ba.y, ba.x); -} - -struct SolidVertexInput { - @location(0) position: vec2, - @location(1) color: vec4, -} - -struct SolidVertexOutput { - @builtin(position) position: vec4, - @location(0) color: vec4, -} - -@vertex -fn solid_vs_main(input: SolidVertexInput) -> SolidVertexOutput { - var out: SolidVertexOutput; - - out.color = input.color; - out.position = globals.transform * vec4(input.position, 0.0, 1.0); - - return out; -} - -@fragment -fn solid_fs_main(input: SolidVertexOutput) -> @location(0) vec4 { - return input.color; -} - -struct GradientVertexInput { - @location(0) v_pos: vec2, - @location(1) @interpolate(flat) colors_1: vec4, - @location(2) @interpolate(flat) colors_2: vec4, - @location(3) @interpolate(flat) colors_3: vec4, - @location(4) @interpolate(flat) colors_4: vec4, - @location(5) @interpolate(flat) offsets: vec4, - @location(6) direction: vec4, -} - -struct GradientVertexOutput { - @builtin(position) position: vec4, - @location(0) raw_position: vec2, - @location(1) @interpolate(flat) colors_1: vec4, - @location(2) @interpolate(flat) colors_2: vec4, - @location(3) @interpolate(flat) colors_3: vec4, - @location(4) @interpolate(flat) colors_4: vec4, - @location(5) @interpolate(flat) offsets: vec4, - @location(6) direction: vec4, -} - -@vertex -fn gradient_vs_main(input: GradientVertexInput) -> GradientVertexOutput { - var output: GradientVertexOutput; - - output.position = globals.transform * vec4(input.v_pos, 0.0, 1.0); - output.raw_position = input.v_pos; - output.colors_1 = input.colors_1; - output.colors_2 = input.colors_2; - output.colors_3 = input.colors_3; - output.colors_4 = input.colors_4; - output.offsets = input.offsets; - output.direction = input.direction; - - return output; -} - -fn random(coords: vec2) -> f32 { - return fract(sin(dot(coords, vec2(12.9898,78.233))) * 43758.5453); -} - -/// Returns the current interpolated color with a max 8-stop gradient -fn gradient( - raw_position: vec2, - direction: vec4, - colors: array, 8>, - offsets: array, - last_index: i32 -) -> vec4 { - let start = direction.xy; - let end = direction.zw; - - let v1 = end - start; - let v2 = raw_position - start; - let unit = normalize(v1); - let coord_offset = dot(unit, v2) / length(v1); - - //need to store these as a var to use dynamic indexing in a loop - //this is already added to wgsl spec but not in wgpu yet - var colors_arr = colors; - var offsets_arr = offsets; - - var color: vec4; - - let noise_granularity: f32 = 0.3/255.0; - - for (var i: i32 = 0; i < last_index; i++) { - let curr_offset = offsets_arr[i]; - let next_offset = offsets_arr[i+1]; - - if (coord_offset <= offsets_arr[0]) { - color = colors_arr[0]; - } - - if (curr_offset <= coord_offset && coord_offset <= next_offset) { - color = mix(colors_arr[i], colors_arr[i+1], smoothstep( - curr_offset, - next_offset, - coord_offset, - )); - } - - if (coord_offset >= offsets_arr[last_index]) { - color = colors_arr[last_index]; - } - } - - return color + mix(-noise_granularity, noise_granularity, random(raw_position)); -} - -@fragment -fn gradient_fs_main(input: GradientVertexOutput) -> @location(0) vec4 { - let colors = array, 8>( - unpack_u32(input.colors_1.xy), - unpack_u32(input.colors_1.zw), - unpack_u32(input.colors_2.xy), - unpack_u32(input.colors_2.zw), - unpack_u32(input.colors_3.xy), - unpack_u32(input.colors_3.zw), - unpack_u32(input.colors_4.xy), - unpack_u32(input.colors_4.zw), - ); - - let offsets_1: vec4 = unpack_u32(input.offsets.xy); - let offsets_2: vec4 = unpack_u32(input.offsets.zw); - - var offsets = array( - offsets_1.x, - offsets_1.y, - offsets_1.z, - offsets_1.w, - offsets_2.x, - offsets_2.y, - offsets_2.z, - offsets_2.w, - ); - - var last_index = 7; - for (var i: i32 = 0; i <= 7; i++) { - if (offsets[i] >= 1.0) { - last_index = i; - break; - } - } - - return gradient(input.raw_position, input.direction, colors, offsets, last_index); -} diff --git a/wgpu/src/shader/triangle/gradient.wgsl b/wgpu/src/shader/triangle/gradient.wgsl new file mode 100644 index 00000000..1a8ae3b5 --- /dev/null +++ b/wgpu/src/shader/triangle/gradient.wgsl @@ -0,0 +1,134 @@ +struct GradientVertexInput { + @location(0) v_pos: vec2, + @location(1) @interpolate(flat) colors_1: vec4, + @location(2) @interpolate(flat) colors_2: vec4, + @location(3) @interpolate(flat) colors_3: vec4, + @location(4) @interpolate(flat) colors_4: vec4, + @location(5) @interpolate(flat) offsets: vec4, + @location(6) direction: vec4, +} + +struct GradientVertexOutput { + @builtin(position) position: vec4, + @location(0) raw_position: vec2, + @location(1) @interpolate(flat) colors_1: vec4, + @location(2) @interpolate(flat) colors_2: vec4, + @location(3) @interpolate(flat) colors_3: vec4, + @location(4) @interpolate(flat) colors_4: vec4, + @location(5) @interpolate(flat) offsets: vec4, + @location(6) direction: vec4, +} + +@vertex +fn gradient_vs_main(input: GradientVertexInput) -> GradientVertexOutput { + var output: GradientVertexOutput; + + output.position = globals.transform * vec4(input.v_pos, 0.0, 1.0); + output.raw_position = input.v_pos; + output.colors_1 = input.colors_1; + output.colors_2 = input.colors_2; + output.colors_3 = input.colors_3; + output.colors_4 = input.colors_4; + output.offsets = input.offsets; + output.direction = input.direction; + + return output; +} + +/// Returns the current interpolated color with a max 8-stop gradient +fn gradient( + raw_position: vec2, + direction: vec4, + colors: array, 8>, + offsets: array, + last_index: i32 +) -> vec4 { + let start = direction.xy; + let end = direction.zw; + + let v1 = end - start; + let v2 = raw_position - start; + let unit = normalize(v1); + let coord_offset = dot(unit, v2) / length(v1); + + //need to store these as a var to use dynamic indexing in a loop + //this is already added to wgsl spec but not in wgpu yet + var colors_arr = colors; + var offsets_arr = offsets; + + var color: vec4; + + let noise_granularity: f32 = 0.3/255.0; + + for (var i: i32 = 0; i < last_index; i++) { + let curr_offset = offsets_arr[i]; + let next_offset = offsets_arr[i+1]; + + if (coord_offset <= offsets_arr[0]) { + color = colors_arr[0]; + } + + if (curr_offset <= coord_offset && coord_offset <= next_offset) { + let from_ = colors_arr[i]; + let to_ = colors_arr[i+1]; + let factor = smoothstep(curr_offset, next_offset, coord_offset); + + color = interpolate_color(from_, to_, factor); + } + + if (coord_offset >= offsets_arr[last_index]) { + color = colors_arr[last_index]; + } + } + + return color + mix(-noise_granularity, noise_granularity, random(raw_position)); +} + +@fragment +fn gradient_fs_main(input: GradientVertexOutput) -> @location(0) vec4 { + let colors = array, 8>( + unpack_u32(input.colors_1.xy), + unpack_u32(input.colors_1.zw), + unpack_u32(input.colors_2.xy), + unpack_u32(input.colors_2.zw), + unpack_u32(input.colors_3.xy), + unpack_u32(input.colors_3.zw), + unpack_u32(input.colors_4.xy), + unpack_u32(input.colors_4.zw), + ); + + let offsets_1: vec4 = unpack_u32(input.offsets.xy); + let offsets_2: vec4 = unpack_u32(input.offsets.zw); + + var offsets = array( + offsets_1.x, + offsets_1.y, + offsets_1.z, + offsets_1.w, + offsets_2.x, + offsets_2.y, + offsets_2.z, + offsets_2.w, + ); + + var last_index = 7; + for (var i: i32 = 0; i <= 7; i++) { + if (offsets[i] >= 1.0) { + last_index = i; + break; + } + } + + return gradient(input.raw_position, input.direction, colors, offsets, last_index); +} + +fn unpack_u32(color: vec2) -> vec4 { + let rg: vec2 = unpack2x16float(color.x); + let ba: vec2 = unpack2x16float(color.y); + + return vec4(rg.y, rg.x, ba.y, ba.x); +} + +fn random(coords: vec2) -> f32 { + return fract(sin(dot(coords, vec2(12.9898,78.233))) * 43758.5453); +} diff --git a/wgpu/src/shader/triangle/solid.wgsl b/wgpu/src/shader/triangle/solid.wgsl new file mode 100644 index 00000000..9ef81982 --- /dev/null +++ b/wgpu/src/shader/triangle/solid.wgsl @@ -0,0 +1,24 @@ +struct SolidVertexInput { + @location(0) position: vec2, + @location(1) color: vec4, +} + +struct SolidVertexOutput { + @builtin(position) position: vec4, + @location(0) color: vec4, +} + +@vertex +fn solid_vs_main(input: SolidVertexInput) -> SolidVertexOutput { + var out: SolidVertexOutput; + + out.color = input.color; + out.position = globals.transform * vec4(input.position, 0.0, 1.0); + + return out; +} + +@fragment +fn solid_fs_main(input: SolidVertexOutput) -> @location(0) vec4 { + return input.color; +} diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs index d8b23dfe..d430e607 100644 --- a/wgpu/src/triangle.rs +++ b/wgpu/src/triangle.rs @@ -487,8 +487,10 @@ mod solid { device.create_shader_module(wgpu::ShaderModuleDescriptor { label: Some("iced_wgpu.triangle.solid.shader"), source: wgpu::ShaderSource::Wgsl( - std::borrow::Cow::Borrowed(include_str!( - "shader/triangle.wgsl" + std::borrow::Cow::Borrowed(concat!( + include_str!("shader/triangle.wgsl"), + "\n", + include_str!("shader/triangle/solid.wgsl"), )), ), }); @@ -537,6 +539,7 @@ mod solid { } mod gradient { + use crate::graphics::color; use crate::graphics::mesh; use crate::graphics::Antialiasing; use crate::triangle; @@ -633,9 +636,31 @@ mod gradient { device.create_shader_module(wgpu::ShaderModuleDescriptor { label: Some("iced_wgpu.triangle.gradient.shader"), source: wgpu::ShaderSource::Wgsl( - std::borrow::Cow::Borrowed(include_str!( - "shader/triangle.wgsl" - )), + std::borrow::Cow::Borrowed( + if color::GAMMA_CORRECTION { + concat!( + include_str!("shader/triangle.wgsl"), + "\n", + include_str!( + "shader/triangle/gradient.wgsl" + ), + "\n", + include_str!("shader/color/oklab.wgsl") + ) + } else { + concat!( + include_str!("shader/triangle.wgsl"), + "\n", + include_str!( + "shader/triangle/gradient.wgsl" + ), + "\n", + include_str!( + "shader/color/linear_rgb.wgsl" + ) + ) + }, + ), ), }); From adfcd8c727b896589b77322eae01f9710a86f7cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 7 Sep 2023 07:37:57 +0200 Subject: [PATCH 140/321] Simplify `gradients` example --- examples/gradients/src/main.rs | 99 +++++++++++++--------------------- 1 file changed, 37 insertions(+), 62 deletions(-) diff --git a/examples/gradients/src/main.rs b/examples/gradients/src/main.rs index d8b7945e..ad9bfe11 100644 --- a/examples/gradients/src/main.rs +++ b/examples/gradients/src/main.rs @@ -8,16 +8,17 @@ pub fn main() -> iced::Result { Gradient::run(Settings::default()) } +#[derive(Debug, Clone, Copy)] struct Gradient { - first: Color, - second: Color, + start: Color, + end: Color, angle: f32, } #[derive(Debug, Clone, Copy)] enum Message { - FirstChanged(Color), - SecondChanged(Color), + StartChanged(Color), + EndChanged(Color), AngleChanged(f32), } @@ -25,32 +26,30 @@ impl Sandbox for Gradient { type Message = Message; fn new() -> Self { - let first = Color::new(0.2784314, 0.0627451, 0.4117647, 1.0); - let second = Color::new(0.1882353, 0.772549, 0.8235294, 1.0); + let start = Color::new(1.0, 1.0, 1.0, 1.0); + let end = Color::new(0.0, 0.0, 1.0, 1.0); Self { - first, - second, + start, + end, angle: 0.0, } } fn title(&self) -> String { - String::from("Color gradient") + String::from("Gradient") } fn update(&mut self, message: Message) { match message { - Message::FirstChanged(color) => self.first = color, - Message::SecondChanged(color) => self.second = color, + Message::StartChanged(color) => self.start = color, + Message::EndChanged(color) => self.end = color, Message::AngleChanged(angle) => self.angle = angle, } } fn view(&self) -> Element { - let first = self.first; - let second = self.second; - let angle = self.angle; + let Self { start, end, angle } = *self; let gradient_box = container(text("")) .width(Length::Fill) @@ -58,10 +57,12 @@ impl Sandbox for Gradient { .center_x() .center_y() .style(move |_: &_| { - let gradient = gradient::Linear::new(Radians(angle)) - .add_stop(0.0, first) - .add_stop(1.0, second) - .into(); + let gradient = gradient::Linear::new(Radians( + angle + std::f32::consts::PI, + )) + .add_stop(0.0, start) + .add_stop(1.0, end) + .into(); container::Appearance { text_color: None, @@ -72,48 +73,6 @@ impl Sandbox for Gradient { } }); - let range = 0.0..=1.0; - let l = self.first; - let r = self.second; - - let first_color_picker = row![ - text("First").width(64), - slider(range.clone(), l.r, move |v| { - Message::FirstChanged(Color::new(v, l.g, l.b, l.a)) - }) - .step(0.01), - slider(range.clone(), l.g, move |v| { - Message::FirstChanged(Color::new(l.r, v, l.b, l.a)) - }) - .step(0.01), - slider(range.clone(), l.b, move |v| { - Message::FirstChanged(Color::new(l.r, l.g, v, l.a)) - }) - .step(0.01), - ] - .spacing(8) - .padding(8) - .align_items(Alignment::Center); - - let second_color_picker = row![ - text("Second").width(64), - slider(range.clone(), r.r, move |v| { - Message::SecondChanged(Color::new(v, r.g, r.b, r.a)) - }) - .step(0.01), - slider(range.clone(), r.g, move |v| { - Message::SecondChanged(Color::new(r.r, v, r.b, r.a)) - }) - .step(0.01), - slider(range.clone(), r.b, move |v| { - Message::SecondChanged(Color::new(r.r, r.g, v, r.a)) - }) - .step(0.01), - ] - .spacing(8) - .padding(8) - .align_items(Alignment::Center); - let angle_picker = row![ text("Angle").width(64), slider(0.0..=std::f32::consts::PI * 2.0, self.angle, move |v| { @@ -126,11 +85,27 @@ impl Sandbox for Gradient { .align_items(Alignment::Center); column![ - first_color_picker, - second_color_picker, + color_picker("Start", self.start).map(Message::StartChanged), + color_picker("End", self.end).map(Message::EndChanged), angle_picker, gradient_box ] .into() } } + +fn color_picker(label: &str, color: Color) -> Element<'_, Color> { + row![ + text(label).width(64), + slider(0.0..=1.0, color.r, move |r| { Color { r, ..color } }) + .step(0.01), + slider(0.0..=1.0, color.g, move |g| { Color { g, ..color } }) + .step(0.01), + slider(0.0..=1.0, color.b, move |b| { Color { b, ..color } }) + .step(0.01), + ] + .spacing(8) + .padding(8) + .align_items(Alignment::Center) + .into() +} From 21259ee745c17d0f257c7a6c356d8a491460f9d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 7 Sep 2023 07:38:51 +0200 Subject: [PATCH 141/321] Rename `gradients` example to `gradient` --- examples/{gradients => gradient}/Cargo.toml | 0 examples/{gradients => gradient}/src/main.rs | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename examples/{gradients => gradient}/Cargo.toml (100%) rename examples/{gradients => gradient}/src/main.rs (100%) diff --git a/examples/gradients/Cargo.toml b/examples/gradient/Cargo.toml similarity index 100% rename from examples/gradients/Cargo.toml rename to examples/gradient/Cargo.toml diff --git a/examples/gradients/src/main.rs b/examples/gradient/src/main.rs similarity index 100% rename from examples/gradients/src/main.rs rename to examples/gradient/src/main.rs From f83fb9b6cd221ecfc02d468df128dbb8b3751c3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 7 Sep 2023 07:40:27 +0200 Subject: [PATCH 142/321] Use `Color::WHITE` in `gradient` example --- examples/gradient/src/main.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/examples/gradient/src/main.rs b/examples/gradient/src/main.rs index ad9bfe11..dd50ebc9 100644 --- a/examples/gradient/src/main.rs +++ b/examples/gradient/src/main.rs @@ -26,12 +26,9 @@ impl Sandbox for Gradient { type Message = Message; fn new() -> Self { - let start = Color::new(1.0, 1.0, 1.0, 1.0); - let end = Color::new(0.0, 0.0, 1.0, 1.0); - Self { - start, - end, + start: Color::WHITE, + end: Color::new(0.0, 0.0, 1.0, 1.0), angle: 0.0, } } From d818deb4cdfcfeffa88e649e3e27aa477a336f4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 7 Sep 2023 07:50:59 +0200 Subject: [PATCH 143/321] Increase threshold of `enum-variant-names` lint --- clippy.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/clippy.toml b/clippy.toml index 0d4e02f0..02f00a06 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1 +1,2 @@ too-many-arguments-threshold = 20 +enum-variant-name-threshold = 10 From fc261a539b28dcd5f1898107a7c69c0719f3bbbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 7 Sep 2023 07:53:26 +0200 Subject: [PATCH 144/321] Fix name of `gradient` example package --- examples/gradient/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gradient/Cargo.toml b/examples/gradient/Cargo.toml index 1bc65a9c..2dea2c4f 100644 --- a/examples/gradient/Cargo.toml +++ b/examples/gradient/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "gradients" +name = "gradient" version = "0.1.0" edition = "2021" publish = false From 6ff2e48feb7c0c3f65a3e6d298fc1c73356dc740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 7 Sep 2023 07:53:34 +0200 Subject: [PATCH 145/321] Use `Default` for `container::Appearance` in `gradient` example --- examples/gradient/src/main.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/examples/gradient/src/main.rs b/examples/gradient/src/main.rs index dd50ebc9..91a65f1e 100644 --- a/examples/gradient/src/main.rs +++ b/examples/gradient/src/main.rs @@ -1,7 +1,7 @@ +use iced::gradient; use iced::widget::{column, container, row, slider, text}; use iced::{ - gradient, Alignment, Background, BorderRadius, Color, Element, Length, - Radians, Sandbox, Settings, + Alignment, Background, Color, Element, Length, Radians, Sandbox, Settings, }; pub fn main() -> iced::Result { @@ -62,11 +62,8 @@ impl Sandbox for Gradient { .into(); container::Appearance { - text_color: None, background: Some(Background::Gradient(gradient)), - border_radius: BorderRadius::default(), - border_width: 0.0, - border_color: Color::new(0.0, 0.0, 0.0, 0.0), + ..Default::default() } }); From d6be3ab68246b08ea3f8988833e3b266b524dd1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 7 Sep 2023 07:55:09 +0200 Subject: [PATCH 146/321] Use `horizontal_space` instead of empty `text` widget in `gradient` example --- examples/gradient/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/gradient/src/main.rs b/examples/gradient/src/main.rs index 91a65f1e..3ba08a06 100644 --- a/examples/gradient/src/main.rs +++ b/examples/gradient/src/main.rs @@ -1,5 +1,5 @@ use iced::gradient; -use iced::widget::{column, container, row, slider, text}; +use iced::widget::{column, container, horizontal_space, row, slider, text}; use iced::{ Alignment, Background, Color, Element, Length, Radians, Sandbox, Settings, }; @@ -48,7 +48,7 @@ impl Sandbox for Gradient { fn view(&self) -> Element { let Self { start, end, angle } = *self; - let gradient_box = container(text("")) + let gradient_box = container(horizontal_space(Length::Fill)) .width(Length::Fill) .height(Length::Fill) .center_x() From c1139898c50d22ac3b711801b1058aacef514030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 7 Sep 2023 07:55:54 +0200 Subject: [PATCH 147/321] Remove unnecessary centering in `gradient` example --- examples/gradient/src/main.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/gradient/src/main.rs b/examples/gradient/src/main.rs index 3ba08a06..0b32e73c 100644 --- a/examples/gradient/src/main.rs +++ b/examples/gradient/src/main.rs @@ -51,8 +51,6 @@ impl Sandbox for Gradient { let gradient_box = container(horizontal_space(Length::Fill)) .width(Length::Fill) .height(Length::Fill) - .center_x() - .center_y() .style(move |_: &_| { let gradient = gradient::Linear::new(Radians( angle + std::f32::consts::PI, From d2294737c2e28b3b3050d7bf820bbca09896b00e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 8 Sep 2023 01:58:52 +0200 Subject: [PATCH 148/321] Use `Radians` as a number directly in `gradient` example --- core/Cargo.toml | 1 + core/src/angle.rs | 47 ++++++++++++++++++++++++++++++++--- examples/gradient/src/main.rs | 22 +++++++--------- widget/src/slider.rs | 4 +-- 4 files changed, 55 insertions(+), 19 deletions(-) diff --git a/core/Cargo.toml b/core/Cargo.toml index 8859e91e..7acb7511 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -15,6 +15,7 @@ bitflags.workspace = true log.workspace = true thiserror.workspace = true twox-hash.workspace = true +num-traits.workspace = true palette.workspace = true palette.optional = true diff --git a/core/src/angle.rs b/core/src/angle.rs index 75a57c76..91fc2ba7 100644 --- a/core/src/angle.rs +++ b/core/src/angle.rs @@ -1,17 +1,56 @@ use crate::{Point, Rectangle, Vector}; -use std::f32::consts::PI; -#[derive(Debug, Copy, Clone, PartialEq)] +use std::f32::consts::PI; +use std::ops::RangeInclusive; + /// Degrees +#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)] pub struct Degrees(pub f32); -#[derive(Debug, Copy, Clone, PartialEq)] /// Radians +#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)] pub struct Radians(pub f32); +impl Radians { + /// The range of radians of a circle. + pub const RANGE: RangeInclusive = Radians(0.0)..=Radians(2.0 * PI); +} + impl From for Radians { fn from(degrees: Degrees) -> Self { - Radians(degrees.0 * PI / 180.0) + Self(degrees.0 * PI / 180.0) + } +} + +impl From for Radians { + fn from(radians: f32) -> Self { + Self(radians) + } +} + +impl From for Radians { + fn from(radians: u8) -> Self { + Self(f32::from(radians)) + } +} + +impl From for f64 { + fn from(radians: Radians) -> Self { + Self::from(radians.0) + } +} + +impl num_traits::FromPrimitive for Radians { + fn from_i64(n: i64) -> Option { + Some(Self(n as f32)) + } + + fn from_u64(n: u64) -> Option { + Some(Self(n as f32)) + } + + fn from_f64(n: f64) -> Option { + Some(Self(n as f32)) } } diff --git a/examples/gradient/src/main.rs b/examples/gradient/src/main.rs index 0b32e73c..1bf5822d 100644 --- a/examples/gradient/src/main.rs +++ b/examples/gradient/src/main.rs @@ -12,14 +12,14 @@ pub fn main() -> iced::Result { struct Gradient { start: Color, end: Color, - angle: f32, + angle: Radians, } #[derive(Debug, Clone, Copy)] enum Message { StartChanged(Color), EndChanged(Color), - AngleChanged(f32), + AngleChanged(Radians), } impl Sandbox for Gradient { @@ -29,7 +29,7 @@ impl Sandbox for Gradient { Self { start: Color::WHITE, end: Color::new(0.0, 0.0, 1.0, 1.0), - angle: 0.0, + angle: Radians(0.0), } } @@ -52,12 +52,10 @@ impl Sandbox for Gradient { .width(Length::Fill) .height(Length::Fill) .style(move |_: &_| { - let gradient = gradient::Linear::new(Radians( - angle + std::f32::consts::PI, - )) - .add_stop(0.0, start) - .add_stop(1.0, end) - .into(); + let gradient = gradient::Linear::new(angle) + .add_stop(0.0, start) + .add_stop(1.0, end) + .into(); container::Appearance { background: Some(Background::Gradient(gradient)), @@ -67,10 +65,8 @@ impl Sandbox for Gradient { let angle_picker = row![ text("Angle").width(64), - slider(0.0..=std::f32::consts::PI * 2.0, self.angle, move |v| { - Message::AngleChanged(v) - }) - .step(0.01) + slider(Radians::RANGE, self.angle, Message::AngleChanged) + .step(0.01) ] .spacing(8) .padding(8) diff --git a/widget/src/slider.rs b/widget/src/slider.rs index e41be7c9..bd73ea79 100644 --- a/widget/src/slider.rs +++ b/widget/src/slider.rs @@ -137,8 +137,8 @@ where } /// Sets the step size of the [`Slider`]. - pub fn step(mut self, step: T) -> Self { - self.step = step; + pub fn step(mut self, step: impl Into) -> Self { + self.step = step.into(); self } } From 90cbab18b95a2a90a6a527280a6ca461203ea1b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 8 Sep 2023 02:36:17 +0200 Subject: [PATCH 149/321] Fine-tune `Radians::to_distance` An angle of 0 radians will "point" to the top-center of a `Rectangle` and then increase clockwise. --- core/src/angle.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/core/src/angle.rs b/core/src/angle.rs index 91fc2ba7..c8f3f013 100644 --- a/core/src/angle.rs +++ b/core/src/angle.rs @@ -1,6 +1,6 @@ use crate::{Point, Rectangle, Vector}; -use std::f32::consts::PI; +use std::f32::consts::{FRAC_PI_2, PI}; use std::ops::RangeInclusive; /// Degrees @@ -57,15 +57,16 @@ impl num_traits::FromPrimitive for Radians { impl Radians { /// Calculates the line in which the [`Angle`] intercepts the `bounds`. pub fn to_distance(&self, bounds: &Rectangle) -> (Point, Point) { - let v1 = Vector::new(f32::cos(self.0), f32::sin(self.0)); + let angle = self.0 - FRAC_PI_2; + let r = Vector::new(f32::cos(angle), f32::sin(angle)); - let distance_to_rect = f32::min( - f32::abs((bounds.y - bounds.center().y) / v1.y), - f32::abs(((bounds.x + bounds.width) - bounds.center().x) / v1.x), + let distance_to_rect = f32::max( + f32::abs(r.x * bounds.width / 2.0), + f32::abs(r.y * bounds.height / 2.0), ); - let start = bounds.center() + v1 * distance_to_rect; - let end = bounds.center() - v1 * distance_to_rect; + let start = bounds.center() - r * distance_to_rect; + let end = bounds.center() + r * distance_to_rect; (start, end) } From 3450987355be7fe029db112474d06613929b54c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 9 Sep 2023 11:21:32 +0200 Subject: [PATCH 150/321] Invalidate existing paragraphs when new fonts are loaded --- core/src/text.rs | 68 ++++++++++++++++++++++++++++------ graphics/src/renderer.rs | 23 ++++++++++++ graphics/src/text.rs | 44 +++++++++++++++++----- graphics/src/text/paragraph.rs | 15 ++++++-- tiny_skia/src/text.rs | 5 +-- wgpu/src/text.rs | 5 +-- 6 files changed, 127 insertions(+), 33 deletions(-) diff --git a/core/src/text.rs b/core/src/text.rs index c59c683a..f5e9abc4 100644 --- a/core/src/text.rs +++ b/core/src/text.rs @@ -172,18 +172,14 @@ pub trait Renderer: crate::Renderer { paragraph: &mut Self::Paragraph, text: Text<'_, Self::Font>, ) { - if paragraph.content() != text.content - || paragraph.text_size() != text.size - || paragraph.line_height().to_absolute(text.size) - != text.line_height.to_absolute(text.size) - || paragraph.font() != text.font - || paragraph.shaping() != text.shaping - || paragraph.horizontal_alignment() != text.horizontal_alignment - || paragraph.vertical_alignment() != text.vertical_alignment - { - *paragraph = self.create_paragraph(text); - } else if paragraph.bounds() != text.bounds { - self.resize_paragraph(paragraph, text.bounds); + match compare(paragraph, text) { + Difference::None => {} + Difference::Bounds => { + self.resize_paragraph(paragraph, text.bounds); + } + Difference::Shape => { + *paragraph = self.create_paragraph(text); + } } } @@ -255,3 +251,51 @@ pub trait Paragraph: Default { self.min_bounds().height } } + +/// The difference detected in some text. +/// +/// You will obtain a [`Difference`] when you [`compare`] a [`Paragraph`] with some +/// [`Text`]. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Difference { + /// No difference. + /// + /// The text can be reused as it is! + None, + + /// A bounds difference. + /// + /// This normally means a relayout is necessary, but the shape of the text can + /// be reused. + Bounds, + + /// A shape difference. + /// + /// The contents, alignment, sizes, fonts, or any other essential attributes + /// of the shape of the text have changed. A complete reshape and relayout of + /// the text is necessary. + Shape, +} + +/// Compares a [`Paragraph`] with some desired [`Text`] and returns the +/// [`Difference`]. +pub fn compare( + paragraph: &impl Paragraph, + text: Text<'_, Font>, +) -> Difference { + if paragraph.content() != text.content + || paragraph.text_size() != text.size + || paragraph.line_height().to_absolute(text.size) + != text.line_height.to_absolute(text.size) + || paragraph.font() != text.font + || paragraph.shaping() != text.shaping + || paragraph.horizontal_alignment() != text.horizontal_alignment + || paragraph.vertical_alignment() != text.vertical_alignment + { + Difference::Shape + } else if paragraph.bounds() != text.bounds { + Difference::Bounds + } else { + Difference::None + } +} diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index f93f4a6d..d4df29a5 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -162,6 +162,29 @@ where text::Paragraph::with_text(text, self.backend.font_system()) } + fn update_paragraph( + &self, + paragraph: &mut Self::Paragraph, + text: Text<'_, Self::Font>, + ) { + let font_system = self.backend.font_system(); + + if paragraph.version() != font_system.version() { + // The font system has changed, paragraph fonts may be outdated + *paragraph = self.create_paragraph(text); + } else { + match core::text::compare(paragraph, text) { + core::text::Difference::None => {} + core::text::Difference::Bounds => { + self.resize_paragraph(paragraph, text.bounds); + } + core::text::Difference::Shape => { + *paragraph = self.create_paragraph(text); + } + } + } + } + fn resize_paragraph( &self, paragraph: &mut Self::Paragraph, diff --git a/graphics/src/text.rs b/graphics/src/text.rs index bbe9d7cb..bc06aa3c 100644 --- a/graphics/src/text.rs +++ b/graphics/src/text.rs @@ -10,30 +10,54 @@ use crate::core::font::{self, Font}; use crate::core::text::Shaping; use crate::core::Size; +use std::borrow::Cow; use std::sync::{self, Arc, RwLock}; #[allow(missing_debug_implementations)] -pub struct FontSystem(RwLock); +pub struct FontSystem { + raw: RwLock, + version: Version, +} impl FontSystem { pub fn new() -> Self { - FontSystem(RwLock::new(cosmic_text::FontSystem::new_with_fonts( - [cosmic_text::fontdb::Source::Binary(Arc::new( - include_bytes!("../fonts/Iced-Icons.ttf").as_slice(), - ))] - .into_iter(), - ))) + FontSystem { + raw: RwLock::new(cosmic_text::FontSystem::new_with_fonts( + [cosmic_text::fontdb::Source::Binary(Arc::new( + include_bytes!("../fonts/Iced-Icons.ttf").as_slice(), + ))] + .into_iter(), + )), + version: Version::default(), + } } pub fn get_mut(&mut self) -> &mut cosmic_text::FontSystem { - self.0.get_mut().expect("Lock font system") + self.raw.get_mut().expect("Lock font system") } - pub fn write(&self) -> sync::RwLockWriteGuard<'_, cosmic_text::FontSystem> { - self.0.write().expect("Write font system") + pub fn write( + &self, + ) -> (sync::RwLockWriteGuard<'_, cosmic_text::FontSystem>, Version) { + (self.raw.write().expect("Write font system"), self.version) + } + + pub fn load_font(&mut self, bytes: Cow<'static, [u8]>) { + let _ = self.get_mut().db_mut().load_font_source( + cosmic_text::fontdb::Source::Binary(Arc::new(bytes.into_owned())), + ); + + self.version = Version(self.version.0 + 1); + } + + pub fn version(&self) -> Version { + self.version } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +pub struct Version(u32); + impl Default for FontSystem { fn default() -> Self { Self::new() diff --git a/graphics/src/text/paragraph.rs b/graphics/src/text/paragraph.rs index ee7c04c8..cd12bc8f 100644 --- a/graphics/src/text/paragraph.rs +++ b/graphics/src/text/paragraph.rs @@ -19,6 +19,7 @@ struct Internal { vertical_alignment: alignment::Vertical, bounds: Size, min_bounds: Size, + version: text::Version, } impl Paragraph { @@ -27,9 +28,9 @@ impl Paragraph { } pub fn with_text(text: Text<'_, Font>, font_system: &FontSystem) -> Self { - log::trace!("\nAllocating paragraph: {}", text.content); + log::trace!("Allocating paragraph: {}", text.content); - let mut font_system = font_system.write(); + let (mut font_system, version) = font_system.write(); let mut buffer = cosmic_text::Buffer::new( &mut font_system, @@ -63,6 +64,7 @@ impl Paragraph { shaping: text.shaping, bounds: text.bounds, min_bounds, + version, }))) } @@ -70,6 +72,10 @@ impl Paragraph { &self.internal().buffer } + pub fn version(&self) -> text::Version { + self.internal().version + } + pub fn downgrade(&self) -> Weak { let paragraph = self.internal(); @@ -89,8 +95,10 @@ impl Paragraph { match Arc::try_unwrap(paragraph) { Ok(mut internal) => { + let (mut font_system, _) = font_system.write(); + internal.buffer.set_size( - &mut font_system.write(), + &mut font_system, new_bounds.width, new_bounds.height, ); @@ -246,6 +254,7 @@ impl Default for Internal { vertical_alignment: alignment::Vertical::Top, bounds: Size::ZERO, min_bounds: Size::ZERO, + version: text::Version::default(), } } } diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index 2bf35e76..820e7bd8 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -9,7 +9,6 @@ use rustc_hash::{FxHashMap, FxHashSet}; use std::borrow::Cow; use std::cell::RefCell; use std::collections::hash_map; -use std::sync::Arc; #[allow(missing_debug_implementations)] pub struct Pipeline { @@ -32,9 +31,7 @@ impl Pipeline { } pub fn load_font(&mut self, bytes: Cow<'static, [u8]>) { - self.font_system.get_mut().db_mut().load_font_source( - cosmic_text::fontdb::Source::Binary(Arc::new(bytes.into_owned())), - ); + self.font_system.load_font(bytes); self.cache = RefCell::new(Cache::new()); } diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index a1ec511b..bd4f3e06 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -7,7 +7,6 @@ use crate::layer::Text; use std::borrow::Cow; use std::cell::RefCell; -use std::sync::Arc; #[allow(missing_debug_implementations)] pub struct Pipeline { @@ -47,9 +46,7 @@ impl Pipeline { } pub fn load_font(&mut self, bytes: Cow<'static, [u8]>) { - let _ = self.font_system.get_mut().db_mut().load_font_source( - glyphon::fontdb::Source::Binary(Arc::new(bytes.into_owned())), - ); + self.font_system.load_font(bytes); self.cache = RefCell::new(Cache::new()); } From 3cc605b70f543313cb665465ac169d0c85c446ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 9 Sep 2023 12:36:00 +0200 Subject: [PATCH 151/321] Implement `Icon` support for `TextInput` --- widget/src/text_input.rs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index f36b5616..aa35b5e4 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -511,7 +511,20 @@ where ); if let Some(icon) = icon { - let icon_width = 0.0; // TODO + let icon_text = Text { + line_height, + content: &icon.code_point.to_string(), + font: icon.font, + size: icon.size.unwrap_or_else(|| renderer.default_size()), + bounds: Size::new(f32::INFINITY, text_bounds.height), + horizontal_alignment: alignment::Horizontal::Center, + vertical_alignment: alignment::Vertical::Center, + shaping: text::Shaping::Advanced, + }; + + renderer.update_paragraph(&mut state.icon, icon_text); + + let icon_width = state.icon.min_width(); let mut text_node = layout::Node::new( text_bounds - Size::new(icon_width + icon.spacing, 0.0), @@ -1053,10 +1066,14 @@ pub fn draw( appearance.background, ); - if let Some(_icon) = icon { - let _icon_layout = children_layout.next().unwrap(); + if icon.is_some() { + let icon_layout = children_layout.next().unwrap(); - // TODO + renderer.fill_paragraph( + &state.icon, + icon_layout.bounds().center(), + appearance.icon_color, + ); } let text = value.to_string(); @@ -1206,6 +1223,7 @@ pub fn mouse_interaction( pub struct State { value: P, placeholder: P, + icon: P, is_focused: Option, is_dragging: bool, is_pasting: Option, @@ -1233,6 +1251,7 @@ impl State

{ Self { value: P::default(), placeholder: P::default(), + icon: P::default(), is_focused: None, is_dragging: false, is_pasting: None, From 9c2ad457d80e8254955396ad034df0dd5f2b59b3 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sat, 9 Sep 2023 13:59:18 +0200 Subject: [PATCH 152/321] Add webgl feature for web examples --- examples/counter/Cargo.toml | 4 ++++ examples/integration/Cargo.toml | 3 +++ examples/todos/Cargo.toml | 3 +++ examples/tour/Cargo.toml | 4 ++++ 4 files changed, 14 insertions(+) diff --git a/examples/counter/Cargo.toml b/examples/counter/Cargo.toml index 1e9bba6b..22f86064 100644 --- a/examples/counter/Cargo.toml +++ b/examples/counter/Cargo.toml @@ -7,3 +7,7 @@ publish = false [dependencies] iced.workspace = true + +[target.'cfg(target_arch = "wasm32")'.dependencies] +iced.workspace = true +iced.features = ["webgl"] diff --git a/examples/integration/Cargo.toml b/examples/integration/Cargo.toml index 032cc75e..bf70a619 100644 --- a/examples/integration/Cargo.toml +++ b/examples/integration/Cargo.toml @@ -13,6 +13,9 @@ iced_widget.workspace = true tracing-subscriber = "0.3" [target.'cfg(target_arch = "wasm32")'.dependencies] +iced_wgpu.workspace = true +iced_wgpu.features = ["webgl"] + console_error_panic_hook = "0.1" console_log = "1.0" log.workspace = true diff --git a/examples/todos/Cargo.toml b/examples/todos/Cargo.toml index fea20375..3334d84f 100644 --- a/examples/todos/Cargo.toml +++ b/examples/todos/Cargo.toml @@ -18,6 +18,9 @@ async-std.workspace = true directories-next = "2.0" [target.'cfg(target_arch = "wasm32")'.dependencies] +iced.workspace = true +iced.features = ["debug", "webgl"] + web-sys = { workspace = true, features = ["Window", "Storage"] } wasm-timer.workspace = true diff --git a/examples/tour/Cargo.toml b/examples/tour/Cargo.toml index 21206ecb..9de017ce 100644 --- a/examples/tour/Cargo.toml +++ b/examples/tour/Cargo.toml @@ -10,3 +10,7 @@ iced.workspace = true iced.features = ["image", "debug"] tracing-subscriber = "0.3" + +[target.'cfg(target_arch = "wasm32")'.dependencies] +iced.workspace = true +iced.features = ["image", "debug", "webgl"] From e562544807b196dafac9195ea8137958698755e5 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sat, 9 Sep 2023 14:09:48 +0200 Subject: [PATCH 153/321] Add logging for web in tour example --- examples/tour/Cargo.toml | 5 +++++ examples/tour/src/main.rs | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/examples/tour/Cargo.toml b/examples/tour/Cargo.toml index 9de017ce..11920e0d 100644 --- a/examples/tour/Cargo.toml +++ b/examples/tour/Cargo.toml @@ -9,8 +9,13 @@ publish = false iced.workspace = true iced.features = ["image", "debug"] +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] tracing-subscriber = "0.3" [target.'cfg(target_arch = "wasm32")'.dependencies] iced.workspace = true iced.features = ["image", "debug", "webgl"] + +console_error_panic_hook = "0.1" +console_log = "1.0" +log.workspace = true diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs index af508206..f0e3c0cd 100644 --- a/examples/tour/src/main.rs +++ b/examples/tour/src/main.rs @@ -8,6 +8,13 @@ use iced::widget::{Button, Column, Container, Slider}; use iced::{Color, Element, Font, Length, Renderer, Sandbox, Settings}; pub fn main() -> iced::Result { + #[cfg(target_arch = "wasm32")] + { + console_log::init_with_level(log::Level::Debug).expect("Initialize logger"); + std::panic::set_hook(Box::new(console_error_panic_hook::hook)); + } + + #[cfg(not(target_arch = "wasm32"))] tracing_subscriber::fmt::init(); Tour::run(Settings::default()) From 52da89ac531cdf93b0e74afdd5bf6ad366551f82 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sat, 9 Sep 2023 14:11:40 +0200 Subject: [PATCH 154/321] Add instructions to run web examples --- examples/counter/README.md | 8 ++++++++ examples/todos/README.md | 9 ++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/examples/counter/README.md b/examples/counter/README.md index 53243c24..18761bba 100644 --- a/examples/counter/README.md +++ b/examples/counter/README.md @@ -13,4 +13,12 @@ You can run it with `cargo run`: cargo run --package counter ``` +The web version can be run with [`trunk`]: + +``` +cd examples/counter +trunk serve +``` + [`main`]: src/main.rs +[`trunk`]: https://trunkrs.dev/ diff --git a/examples/todos/README.md b/examples/todos/README.md index 852dd88d..5e42f166 100644 --- a/examples/todos/README.md +++ b/examples/todos/README.md @@ -14,7 +14,14 @@ You can run the native version with `cargo run`: ``` cargo run --package todos ``` -We have not yet implemented a `LocalStorage` version of the auto-save feature. Therefore, it does not work on web _yet_! + +The web version can be run with [`trunk`]: + +``` +cd examples/todos +trunk serve +``` [`main`]: src/main.rs [TodoMVC]: http://todomvc.com/ +[`trunk`]: https://trunkrs.dev/ From 052fe0edaeb0d6ce096375751eec02b953faf2a1 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sat, 9 Sep 2023 14:15:11 +0200 Subject: [PATCH 155/321] Dont use tracing-subscriber dependency on web --- examples/integration/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/integration/Cargo.toml b/examples/integration/Cargo.toml index bf70a619..6b9fcc57 100644 --- a/examples/integration/Cargo.toml +++ b/examples/integration/Cargo.toml @@ -10,6 +10,7 @@ iced_winit.workspace = true iced_wgpu.workspace = true iced_widget.workspace = true +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] tracing-subscriber = "0.3" [target.'cfg(target_arch = "wasm32")'.dependencies] From 89d9f1d7d2202029028a487df1dd11b0665a7517 Mon Sep 17 00:00:00 2001 From: Matthias Vogelgesang Date: Sat, 9 Sep 2023 12:24:47 +0200 Subject: [PATCH 156/321] Fix majority of unresolved documentation links --- core/src/angle.rs | 2 +- core/src/gradient.rs | 2 +- core/src/shell.rs | 4 +- core/src/window/icon.rs | 2 +- futures/src/runtime.rs | 5 ++- futures/src/subscription.rs | 6 +-- futures/src/subscription/tracker.rs | 3 ++ graphics/src/geometry.rs | 4 +- graphics/src/gradient.rs | 4 +- graphics/src/mesh.rs | 2 +- renderer/src/geometry.rs | 4 +- renderer/src/settings.rs | 4 +- runtime/src/lib.rs | 25 +------------ runtime/src/overlay/nested.rs | 4 +- runtime/src/program/state.rs | 2 +- runtime/src/user_interface.rs | 4 +- src/lib.rs | 6 +-- src/settings.rs | 2 +- src/window/icon.rs | 2 +- wgpu/src/geometry.rs | 4 +- widget/src/canvas/event.rs | 2 +- widget/src/canvas/program.rs | 11 +++--- widget/src/checkbox.rs | 6 +-- widget/src/combo_box.rs | 8 ++-- widget/src/helpers.rs | 54 ++++++++++++++------------- widget/src/overlay/menu.rs | 2 +- widget/src/pane_grid/configuration.rs | 4 +- widget/src/pane_grid/content.rs | 4 +- widget/src/pane_grid/node.rs | 2 +- widget/src/pane_grid/pane.rs | 2 +- widget/src/pane_grid/split.rs | 2 +- widget/src/pane_grid/state.rs | 40 ++++++++++---------- widget/src/pane_grid/title_bar.rs | 6 +-- widget/src/pick_list.rs | 2 +- widget/src/radio.rs | 2 +- widget/src/text_input.rs | 2 +- widget/src/text_input/value.rs | 2 +- widget/src/toggler.rs | 6 +-- winit/src/application/state.rs | 4 +- winit/src/conversion.rs | 2 +- 40 files changed, 117 insertions(+), 137 deletions(-) diff --git a/core/src/angle.rs b/core/src/angle.rs index c8f3f013..102b69cf 100644 --- a/core/src/angle.rs +++ b/core/src/angle.rs @@ -55,7 +55,7 @@ impl num_traits::FromPrimitive for Radians { } impl Radians { - /// Calculates the line in which the [`Angle`] intercepts the `bounds`. + /// Calculates the line in which the angle intercepts the `bounds`. pub fn to_distance(&self, bounds: &Rectangle) -> (Point, Point) { let angle = self.0 - FRAC_PI_2; let r = Vector::new(f32::cos(angle), f32::sin(angle)); diff --git a/core/src/gradient.rs b/core/src/gradient.rs index e19622fb..576c9e4d 100644 --- a/core/src/gradient.rs +++ b/core/src/gradient.rs @@ -9,7 +9,7 @@ use std::cmp::Ordering; /// /// For a gradient which can be used as a fill on a canvas, see [`iced_graphics::Gradient`]. pub enum Gradient { - /// A linear gradient interpolates colors along a direction at a specific [`Angle`]. + /// A linear gradient interpolates colors along a direction at a specific angle. Linear(Linear), } diff --git a/core/src/shell.rs b/core/src/shell.rs index 74a5c616..246c937a 100644 --- a/core/src/shell.rs +++ b/core/src/shell.rs @@ -35,7 +35,7 @@ impl<'a, Message> Shell<'a, Message> { self.messages.push(message); } - /// Requests a new frame to be drawn at the given [`Instant`]. + /// Requests a new frame to be drawn. pub fn request_redraw(&mut self, request: window::RedrawRequest) { match self.redraw_request { None => { @@ -48,7 +48,7 @@ impl<'a, Message> Shell<'a, Message> { } } - /// Returns the requested [`Instant`] a redraw should happen, if any. + /// Returns the request a redraw should happen, if any. pub fn redraw_request(&self) -> Option { self.redraw_request } diff --git a/core/src/window/icon.rs b/core/src/window/icon.rs index 31868ecf..2fc48e3b 100644 --- a/core/src/window/icon.rs +++ b/core/src/window/icon.rs @@ -49,7 +49,7 @@ impl Icon { } #[derive(Debug, thiserror::Error)] -/// An error produced when using [`Icon::from_rgba`] with invalid arguments. +/// An error produced when using [`from_rgba`] with invalid arguments. pub enum Error { /// Produced when the length of the `rgba` argument isn't divisible by 4, thus `rgba` can't be /// safely interpreted as 32bpp RGBA pixels. diff --git a/futures/src/runtime.rs b/futures/src/runtime.rs index 2241a494..16111b36 100644 --- a/futures/src/runtime.rs +++ b/futures/src/runtime.rs @@ -9,9 +9,9 @@ use std::marker::PhantomData; /// A batteries-included runtime of commands and subscriptions. /// /// If you have an [`Executor`], a [`Runtime`] can be leveraged to run any -/// [`Command`] or [`Subscription`] and get notified of the results! +/// `Command` or [`Subscription`] and get notified of the results! /// -/// [`Command`]: crate::Command +/// [`Subscription`]: crate::Subscription #[derive(Debug)] pub struct Runtime { executor: Executor, @@ -75,6 +75,7 @@ where /// [`Tracker::update`] to learn more about this! /// /// [`Tracker::update`]: subscription::Tracker::update + /// [`Subscription`]: crate::Subscription pub fn track( &mut self, recipes: impl IntoIterator< diff --git a/futures/src/subscription.rs b/futures/src/subscription.rs index 759dd223..d40125e3 100644 --- a/futures/src/subscription.rs +++ b/futures/src/subscription.rs @@ -19,16 +19,14 @@ pub type EventStream = BoxStream<(Event, event::Status)>; /// A request to listen to external events. /// -/// Besides performing async actions on demand with [`Command`], most +/// Besides performing async actions on demand with `Command`, most /// applications also need to listen to external events passively. /// -/// A [`Subscription`] is normally provided to some runtime, like a [`Command`], +/// A [`Subscription`] is normally provided to some runtime, like a `Command`, /// and it will generate events as long as the user keeps requesting it. /// /// For instance, you can use a [`Subscription`] to listen to a WebSocket /// connection, keyboard presses, mouse events, time ticks, etc. -/// -/// [`Command`]: crate::Command #[must_use = "`Subscription` must be returned to runtime to take effect"] pub struct Subscription { recipes: Vec>>, diff --git a/futures/src/subscription/tracker.rs b/futures/src/subscription/tracker.rs index ae71cd25..3a83da09 100644 --- a/futures/src/subscription/tracker.rs +++ b/futures/src/subscription/tracker.rs @@ -14,6 +14,8 @@ use std::hash::Hasher as _; /// If you have an application that continuously returns a [`Subscription`], /// you can use a [`Tracker`] to keep track of the different recipes and keep /// its executions alive. +/// +/// [`Subscription`]: crate::Subscription #[derive(Debug, Default)] pub struct Tracker { subscriptions: HashMap, @@ -51,6 +53,7 @@ impl Tracker { /// the [`Tracker`] changes. /// /// [`Recipe`]: crate::subscription::Recipe + /// [`Subscription`]: crate::Subscription pub fn update( &mut self, recipes: impl Iterator>>, diff --git a/graphics/src/geometry.rs b/graphics/src/geometry.rs index 7cd3dd3a..d7d6a0aa 100644 --- a/graphics/src/geometry.rs +++ b/graphics/src/geometry.rs @@ -14,11 +14,11 @@ pub use text::Text; pub use crate::gradient::{self, Gradient}; -/// A renderer capable of drawing some [`Geometry`]. +/// A renderer capable of drawing some [`Self::Geometry`]. pub trait Renderer: crate::core::Renderer { /// The kind of geometry this renderer can draw. type Geometry; - /// Draws the given layers of [`Geometry`]. + /// Draws the given layers of [`Self::Geometry`]. fn draw(&mut self, layers: Vec); } diff --git a/graphics/src/gradient.rs b/graphics/src/gradient.rs index 4db565d8..f5f5f8b4 100644 --- a/graphics/src/gradient.rs +++ b/graphics/src/gradient.rs @@ -1,4 +1,4 @@ -//! A gradient that can be used as a [`Fill`] for some geometry. +//! A gradient that can be used as a fill for some geometry. //! //! For a gradient that you can use as a background variant for a widget, see [`Gradient`]. //! @@ -53,7 +53,7 @@ pub struct Linear { } impl Linear { - /// Creates a new [`Builder`]. + /// Creates a new [`Linear`] builder. pub fn new(start: Point, end: Point) -> Self { Self { start, diff --git a/graphics/src/mesh.rs b/graphics/src/mesh.rs index cfb5a60f..041986cf 100644 --- a/graphics/src/mesh.rs +++ b/graphics/src/mesh.rs @@ -41,7 +41,7 @@ impl Damage for Mesh { } } -/// A set of [`Vertex2D`] and indices representing a list of triangles. +/// A set of vertices and indices representing a list of triangles. #[derive(Clone, Debug, PartialEq, Eq)] pub struct Indexed { /// The vertices of the mesh diff --git a/renderer/src/geometry.rs b/renderer/src/geometry.rs index 1a974b7f..1ecb0a43 100644 --- a/renderer/src/geometry.rs +++ b/renderer/src/geometry.rs @@ -96,13 +96,11 @@ impl Frame { /// resulting glyphs will not be rotated or scaled properly. /// /// Additionally, all text will be rendered on top of all the layers of - /// a [`Canvas`]. Therefore, it is currently only meant to be used for + /// a `Canvas`. Therefore, it is currently only meant to be used for /// overlays, which is the most common use case. /// /// Support for vectorial text is planned, and should address all these /// limitations. - /// - /// [`Canvas`]: crate::widget::Canvas pub fn fill_text(&mut self, text: impl Into) { delegate!(self, frame, frame.fill_text(text)); } diff --git a/renderer/src/settings.rs b/renderer/src/settings.rs index 2e51f339..318ae718 100644 --- a/renderer/src/settings.rs +++ b/renderer/src/settings.rs @@ -1,9 +1,7 @@ use crate::core::Font; use crate::graphics::Antialiasing; -/// The settings of a [`Backend`]. -/// -/// [`Backend`]: crate::Backend +/// The settings of a Backend. #[derive(Debug, Clone, Copy, PartialEq)] pub struct Settings { /// The default [`Font`] to use. diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 59c70ff7..dc631d47 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -2,32 +2,9 @@ //! //! ![The native path of the Iced ecosystem](https://github.com/iced-rs/iced/raw/improvement/update-ecosystem-and-roadmap/docs/graphs/native.png) //! -//! `iced_native` takes [`iced_core`] and builds a native runtime on top of it, -//! featuring: -//! -//! - A custom layout engine, greatly inspired by [`druid`] -//! - Event handling for all the built-in widgets -//! - A renderer-agnostic API -//! -//! To achieve this, it introduces a couple of reusable interfaces: -//! -//! - A [`Widget`] trait, which is used to implement new widgets: from layout -//! requirements to event and drawing logic. -//! - A bunch of `Renderer` traits, meant to keep the crate renderer-agnostic. -//! -//! # Usage -//! The strategy to use this crate depends on your particular use case. If you -//! want to: -//! - Implement a custom shell or integrate it in your own system, check out the -//! [`UserInterface`] type. -//! - Build a new renderer, see the [renderer] module. -//! - Build a custom widget, start at the [`Widget`] trait. +//! `iced_runtime` takes [`iced_core`] and builds a native runtime on top of it. //! //! [`iced_core`]: https://github.com/iced-rs/iced/tree/0.10/core -//! [`iced_winit`]: https://github.com/iced-rs/iced/tree/0.10/winit -//! [`druid`]: https://github.com/xi-editor/druid -//! [`raw-window-handle`]: https://github.com/rust-windowing/raw-window-handle -//! [renderer]: crate::renderer #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] diff --git a/runtime/src/overlay/nested.rs b/runtime/src/overlay/nested.rs index b729f769..21b6f7c1 100644 --- a/runtime/src/overlay/nested.rs +++ b/runtime/src/overlay/nested.rs @@ -6,7 +6,7 @@ use crate::core::renderer; use crate::core::widget; use crate::core::{Clipboard, Event, Layout, Point, Rectangle, Shell, Size}; -/// An [`Overlay`] container that displays nested overlays +/// An overlay container that displays nested overlays #[allow(missing_debug_implementations)] pub struct Nested<'a, Message, Renderer> { overlay: overlay::Element<'a, Message, Renderer>, @@ -27,6 +27,8 @@ where } /// Returns the layout [`Node`] of the [`Nested`] overlay. + /// + /// [`Node`]: layout::Node pub fn layout( &mut self, renderer: &Renderer, diff --git a/runtime/src/program/state.rs b/runtime/src/program/state.rs index 35df6078..9aa2d550 100644 --- a/runtime/src/program/state.rs +++ b/runtime/src/program/state.rs @@ -175,7 +175,7 @@ where (uncaptured_events, command) } - /// Applies [`widget::Operation`]s to the [`State`] + /// Applies [`Operation`]s to the [`State`] pub fn operate( &mut self, renderer: &mut P::Renderer, diff --git a/runtime/src/user_interface.rs b/runtime/src/user_interface.rs index e529c004..165a85ae 100644 --- a/runtime/src/user_interface.rs +++ b/runtime/src/user_interface.rs @@ -356,7 +356,7 @@ where /// It returns the current [`mouse::Interaction`]. You should update the /// icon of the mouse cursor accordingly in your system. /// - /// [`Renderer`]: crate::Renderer + /// [`Renderer`]: crate::core::Renderer /// /// # Example /// We can finally draw our [counter](index.html#usage) by @@ -619,7 +619,7 @@ pub enum State { /// The [`UserInterface`] is up-to-date and can be reused without /// rebuilding. Updated { - /// The [`Instant`] when a redraw should be performed. + /// The [`window::RedrawRequest`] when a redraw should be performed. redraw_request: Option, }, } diff --git a/src/lib.rs b/src/lib.rs index 91c78423..8780d276 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -258,11 +258,11 @@ pub mod system { pub mod overlay { //! Display interactive elements on top of other widgets. - /// A generic [`Overlay`]. + /// A generic overlay. /// - /// This is an alias of an `iced_native` element with a default `Renderer`. + /// This is an alias of an [`overlay::Element`] with a default `Renderer`. /// - /// [`Overlay`]: iced_native::Overlay + /// [`overlay::Element`]: crate::core::overlay::Element pub type Element<'a, Message, Renderer = crate::Renderer> = crate::core::overlay::Element<'a, Message, Renderer>; diff --git a/src/settings.rs b/src/settings.rs index 0dd46584..8659603c 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -23,7 +23,7 @@ pub struct Settings { /// The default [`Font`] to be used. /// - /// By default, it uses [`Font::SansSerif`]. + /// By default, it uses [`Family::SansSerif`](crate::font::Family::SansSerif). pub default_font: Font, /// The text size that will be used by default. diff --git a/src/window/icon.rs b/src/window/icon.rs index 0cb206b3..ef71c228 100644 --- a/src/window/icon.rs +++ b/src/window/icon.rs @@ -10,7 +10,7 @@ use std::path::Path; /// Creates an icon from an image file. /// -/// This will return an error in case the file is missing at run-time. You may prefer [`Self::from_file_data`] instead. +/// This will return an error in case the file is missing at run-time. You may prefer [`from_file_data`] instead. #[cfg(feature = "image")] pub fn from_file>(icon_path: P) -> Result { let icon = image::io::Reader::open(icon_path)?.decode()?.to_rgba8(); diff --git a/wgpu/src/geometry.rs b/wgpu/src/geometry.rs index c3e16f8c..63a59c05 100644 --- a/wgpu/src/geometry.rs +++ b/wgpu/src/geometry.rs @@ -310,13 +310,11 @@ impl Frame { /// resulting glyphs will not be rotated or scaled properly. /// /// Additionally, all text will be rendered on top of all the layers of - /// a [`Canvas`]. Therefore, it is currently only meant to be used for + /// a `Canvas`. Therefore, it is currently only meant to be used for /// overlays, which is the most common use case. /// /// Support for vectorial text is planned, and should address all these /// limitations. - /// - /// [`Canvas`]: crate::widget::Canvas pub fn fill_text(&mut self, text: impl Into) { let text = text.into(); diff --git a/widget/src/canvas/event.rs b/widget/src/canvas/event.rs index 4508c184..1288365f 100644 --- a/widget/src/canvas/event.rs +++ b/widget/src/canvas/event.rs @@ -7,7 +7,7 @@ pub use crate::core::event::Status; /// A [`Canvas`] event. /// -/// [`Canvas`]: crate::widget::Canvas +/// [`Canvas`]: crate::Canvas #[derive(Debug, Clone, Copy, PartialEq)] pub enum Event { /// A mouse event. diff --git a/widget/src/canvas/program.rs b/widget/src/canvas/program.rs index b3f6175e..2ac23061 100644 --- a/widget/src/canvas/program.rs +++ b/widget/src/canvas/program.rs @@ -8,7 +8,7 @@ use crate::graphics::geometry; /// A [`Program`] can mutate internal state and produce messages for an /// application. /// -/// [`Canvas`]: crate::widget::Canvas +/// [`Canvas`]: crate::Canvas pub trait Program where Renderer: geometry::Renderer, @@ -26,7 +26,7 @@ where /// /// By default, this method does and returns nothing. /// - /// [`Canvas`]: crate::widget::Canvas + /// [`Canvas`]: crate::Canvas fn update( &self, _state: &mut Self::State, @@ -42,8 +42,9 @@ where /// [`Geometry`] can be easily generated with a [`Frame`] or stored in a /// [`Cache`]. /// - /// [`Frame`]: crate::widget::canvas::Frame - /// [`Cache`]: crate::widget::canvas::Cache + /// [`Geometry`]: crate::canvas::Geometry + /// [`Frame`]: crate::canvas::Frame + /// [`Cache`]: crate::canvas::Cache fn draw( &self, state: &Self::State, @@ -58,7 +59,7 @@ where /// The interaction returned will be in effect even if the cursor position /// is out of bounds of the program's [`Canvas`]. /// - /// [`Canvas`]: crate::widget::Canvas + /// [`Canvas`]: crate::Canvas fn mouse_interaction( &self, _state: &Self::State, diff --git a/widget/src/checkbox.rs b/widget/src/checkbox.rs index 310a67ed..e574c3cc 100644 --- a/widget/src/checkbox.rs +++ b/widget/src/checkbox.rs @@ -122,7 +122,7 @@ where self } - /// Sets the text [`LineHeight`] of the [`Checkbox`]. + /// Sets the text [`text::LineHeight`] of the [`Checkbox`]. pub fn text_line_height( mut self, line_height: impl Into, @@ -137,9 +137,9 @@ where self } - /// Sets the [`Font`] of the text of the [`Checkbox`]. + /// Sets the [`Renderer::Font`] of the text of the [`Checkbox`]. /// - /// [`Font`]: crate::text::Renderer::Font + /// [`Renderer::Font`]: crate::core::text::Renderer pub fn font(mut self, font: impl Into) -> Self { self.font = Some(font.into()); self diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs index 690ef27c..0dc12354 100644 --- a/widget/src/combo_box.rs +++ b/widget/src/combo_box.rs @@ -20,7 +20,7 @@ use std::time::Instant; /// /// This widget is composed by a [`TextInput`] that can be filled with the text /// to search for corresponding values from the list of options that are displayed -/// as a [`Menu`]. +/// as a Menu. #[allow(missing_debug_implementations)] pub struct ComboBox<'a, T, Message, Renderer = crate::Renderer> where @@ -131,14 +131,16 @@ where self } - /// Sets the [`Font`] of the [`ComboBox`]. + /// Sets the [`Renderer::Font`] of the [`ComboBox`]. + /// + /// [`Renderer::Font`]: text::Renderer pub fn font(mut self, font: Renderer::Font) -> Self { self.text_input = self.text_input.font(font); self.font = Some(font); self } - /// Sets the [`Icon`] of the [`ComboBox`]. + /// Sets the [`text_input::Icon`] of the [`ComboBox`]. pub fn icon(mut self, icon: text_input::Icon) -> Self { self.text_input = self.text_input.icon(icon); self diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs index 9c3c83a9..289720eb 100644 --- a/widget/src/helpers.rs +++ b/widget/src/helpers.rs @@ -25,7 +25,7 @@ use std::ops::RangeInclusive; /// Creates a [`Column`] with the given children. /// -/// [`Column`]: widget::Column +/// [`Column`]: crate::Column #[macro_export] macro_rules! column { () => ( @@ -38,7 +38,7 @@ macro_rules! column { /// Creates a [`Row`] with the given children. /// -/// [`Row`]: widget::Row +/// [`Row`]: crate::Row #[macro_export] macro_rules! row { () => ( @@ -51,7 +51,7 @@ macro_rules! row { /// Creates a new [`Container`] with the provided content. /// -/// [`Container`]: widget::Container +/// [`Container`]: crate::Container pub fn container<'a, Message, Renderer>( content: impl Into>, ) -> Container<'a, Message, Renderer> @@ -64,7 +64,7 @@ where /// Creates a new [`Column`] with the given children. /// -/// [`Column`]: widget::Column +/// [`Column`]: crate::Column pub fn column( children: Vec>, ) -> Column<'_, Message, Renderer> { @@ -73,7 +73,7 @@ pub fn column( /// Creates a new [`Row`] with the given children. /// -/// [`Row`]: widget::Row +/// [`Row`]: crate::Row pub fn row( children: Vec>, ) -> Row<'_, Message, Renderer> { @@ -82,7 +82,7 @@ pub fn row( /// Creates a new [`Scrollable`] with the provided content. /// -/// [`Scrollable`]: widget::Scrollable +/// [`Scrollable`]: crate::Scrollable pub fn scrollable<'a, Message, Renderer>( content: impl Into>, ) -> Scrollable<'a, Message, Renderer> @@ -95,7 +95,7 @@ where /// Creates a new [`Button`] with the provided content. /// -/// [`Button`]: widget::Button +/// [`Button`]: crate::Button pub fn button<'a, Message, Renderer>( content: impl Into>, ) -> Button<'a, Message, Renderer> @@ -109,8 +109,8 @@ where /// Creates a new [`Tooltip`] with the provided content, tooltip text, and [`tooltip::Position`]. /// -/// [`Tooltip`]: widget::Tooltip -/// [`tooltip::Position`]: widget::tooltip::Position +/// [`Tooltip`]: crate::Tooltip +/// [`tooltip::Position`]: crate::tooltip::Position pub fn tooltip<'a, Message, Renderer>( content: impl Into>, tooltip: impl ToString, @@ -125,7 +125,7 @@ where /// Creates a new [`Text`] widget with the provided content. /// -/// [`Text`]: widget::Text +/// [`Text`]: core::widget::Text pub fn text<'a, Renderer>(text: impl ToString) -> Text<'a, Renderer> where Renderer: core::text::Renderer, @@ -136,7 +136,7 @@ where /// Creates a new [`Checkbox`]. /// -/// [`Checkbox`]: widget::Checkbox +/// [`Checkbox`]: crate::Checkbox pub fn checkbox<'a, Message, Renderer>( label: impl Into, is_checked: bool, @@ -151,7 +151,7 @@ where /// Creates a new [`Radio`]. /// -/// [`Radio`]: widget::Radio +/// [`Radio`]: crate::Radio pub fn radio( label: impl Into, value: V, @@ -169,7 +169,7 @@ where /// Creates a new [`Toggler`]. /// -/// [`Toggler`]: widget::Toggler +/// [`Toggler`]: crate::Toggler pub fn toggler<'a, Message, Renderer>( label: impl Into>, is_checked: bool, @@ -184,7 +184,7 @@ where /// Creates a new [`TextInput`]. /// -/// [`TextInput`]: widget::TextInput +/// [`TextInput`]: crate::TextInput pub fn text_input<'a, Message, Renderer>( placeholder: &str, value: &str, @@ -199,7 +199,7 @@ where /// Creates a new [`Slider`]. /// -/// [`Slider`]: widget::Slider +/// [`Slider`]: crate::Slider pub fn slider<'a, T, Message, Renderer>( range: std::ops::RangeInclusive, value: T, @@ -216,7 +216,7 @@ where /// Creates a new [`VerticalSlider`]. /// -/// [`VerticalSlider`]: widget::VerticalSlider +/// [`VerticalSlider`]: crate::VerticalSlider pub fn vertical_slider<'a, T, Message, Renderer>( range: std::ops::RangeInclusive, value: T, @@ -233,7 +233,7 @@ where /// Creates a new [`PickList`]. /// -/// [`PickList`]: widget::PickList +/// [`PickList`]: crate::PickList pub fn pick_list<'a, Message, Renderer, T>( options: impl Into>, selected: Option, @@ -255,7 +255,7 @@ where /// Creates a new [`ComboBox`]. /// -/// [`ComboBox`]: widget::ComboBox +/// [`ComboBox`]: crate::ComboBox pub fn combo_box<'a, T, Message, Renderer>( state: &'a combo_box::State, placeholder: &str, @@ -272,21 +272,21 @@ where /// Creates a new horizontal [`Space`] with the given [`Length`]. /// -/// [`Space`]: widget::Space +/// [`Space`]: crate::Space pub fn horizontal_space(width: impl Into) -> Space { Space::with_width(width) } /// Creates a new vertical [`Space`] with the given [`Length`]. /// -/// [`Space`]: widget::Space +/// [`Space`]: crate::Space pub fn vertical_space(height: impl Into) -> Space { Space::with_height(height) } /// Creates a horizontal [`Rule`] with the given height. /// -/// [`Rule`]: widget::Rule +/// [`Rule`]: crate::Rule pub fn horizontal_rule(height: impl Into) -> Rule where Renderer: core::Renderer, @@ -297,7 +297,7 @@ where /// Creates a vertical [`Rule`] with the given width. /// -/// [`Rule`]: widget::Rule +/// [`Rule`]: crate::Rule pub fn vertical_rule(width: impl Into) -> Rule where Renderer: core::Renderer, @@ -312,7 +312,7 @@ where /// * an inclusive range of possible values, and /// * the current value of the [`ProgressBar`]. /// -/// [`ProgressBar`]: widget::ProgressBar +/// [`ProgressBar`]: crate::ProgressBar pub fn progress_bar( range: RangeInclusive, value: f32, @@ -326,7 +326,7 @@ where /// Creates a new [`Image`]. /// -/// [`Image`]: widget::Image +/// [`Image`]: crate::Image #[cfg(feature = "image")] pub fn image(handle: impl Into) -> crate::Image { crate::Image::new(handle.into()) @@ -334,8 +334,8 @@ pub fn image(handle: impl Into) -> crate::Image { /// Creates a new [`Svg`] widget from the given [`Handle`]. /// -/// [`Svg`]: widget::Svg -/// [`Handle`]: widget::svg::Handle +/// [`Svg`]: crate::Svg +/// [`Handle`]: crate::svg::Handle #[cfg(feature = "svg")] pub fn svg( handle: impl Into, @@ -348,6 +348,8 @@ where } /// Creates a new [`Canvas`]. +/// +/// [`Canvas`]: crate::Canvas #[cfg(feature = "canvas")] pub fn canvas( program: P, diff --git a/widget/src/overlay/menu.rs b/widget/src/overlay/menu.rs index f7bdeef6..711a8891 100644 --- a/widget/src/overlay/menu.rs +++ b/widget/src/overlay/menu.rs @@ -89,7 +89,7 @@ where self } - /// Sets the text [`LineHeight`] of the [`Menu`]. + /// Sets the text [`text::LineHeight`] of the [`Menu`]. pub fn text_line_height( mut self, line_height: impl Into, diff --git a/widget/src/pane_grid/configuration.rs b/widget/src/pane_grid/configuration.rs index ddbc3bc2..b8aa2c7d 100644 --- a/widget/src/pane_grid/configuration.rs +++ b/widget/src/pane_grid/configuration.rs @@ -2,7 +2,7 @@ use crate::pane_grid::Axis; /// The arrangement of a [`PaneGrid`]. /// -/// [`PaneGrid`]: crate::widget::PaneGrid +/// [`PaneGrid`]: super::PaneGrid #[derive(Debug, Clone)] pub enum Configuration { /// A split of the available space. @@ -21,6 +21,6 @@ pub enum Configuration { }, /// A [`Pane`]. /// - /// [`Pane`]: crate::widget::pane_grid::Pane + /// [`Pane`]: super::Pane Pane(T), } diff --git a/widget/src/pane_grid/content.rs b/widget/src/pane_grid/content.rs index e890e41a..218adcd5 100644 --- a/widget/src/pane_grid/content.rs +++ b/widget/src/pane_grid/content.rs @@ -10,7 +10,7 @@ use crate::pane_grid::{Draggable, TitleBar}; /// The content of a [`Pane`]. /// -/// [`Pane`]: crate::widget::pane_grid::Pane +/// [`Pane`]: super::Pane #[allow(missing_debug_implementations)] pub struct Content<'a, Message, Renderer = crate::Renderer> where @@ -87,7 +87,7 @@ where /// Draws the [`Content`] with the provided [`Renderer`] and [`Layout`]. /// - /// [`Renderer`]: crate::Renderer + /// [`Renderer`]: crate::core::Renderer pub fn draw( &self, tree: &Tree, diff --git a/widget/src/pane_grid/node.rs b/widget/src/pane_grid/node.rs index 6de5920f..3c707f15 100644 --- a/widget/src/pane_grid/node.rs +++ b/widget/src/pane_grid/node.rs @@ -5,7 +5,7 @@ use std::collections::BTreeMap; /// A layout node of a [`PaneGrid`]. /// -/// [`PaneGrid`]: crate::widget::PaneGrid +/// [`PaneGrid`]: super::PaneGrid #[derive(Debug, Clone)] pub enum Node { /// The region of this [`Node`] is split into two. diff --git a/widget/src/pane_grid/pane.rs b/widget/src/pane_grid/pane.rs index d6fbab83..cabf55c1 100644 --- a/widget/src/pane_grid/pane.rs +++ b/widget/src/pane_grid/pane.rs @@ -1,5 +1,5 @@ /// A rectangular region in a [`PaneGrid`] used to display widgets. /// -/// [`PaneGrid`]: crate::widget::PaneGrid +/// [`PaneGrid`]: super::PaneGrid #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Pane(pub(super) usize); diff --git a/widget/src/pane_grid/split.rs b/widget/src/pane_grid/split.rs index 8132272a..ce021978 100644 --- a/widget/src/pane_grid/split.rs +++ b/widget/src/pane_grid/split.rs @@ -1,5 +1,5 @@ /// A divider that splits a region in a [`PaneGrid`] into two different panes. /// -/// [`PaneGrid`]: crate::widget::PaneGrid +/// [`PaneGrid`]: super::PaneGrid #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Split(pub(super) usize); diff --git a/widget/src/pane_grid/state.rs b/widget/src/pane_grid/state.rs index 6fd15890..28a52cf0 100644 --- a/widget/src/pane_grid/state.rs +++ b/widget/src/pane_grid/state.rs @@ -1,6 +1,6 @@ //! The state of a [`PaneGrid`]. //! -//! [`PaneGrid`]: crate::widget::PaneGrid +//! [`PaneGrid`]: super::PaneGrid use crate::core::{Point, Size}; use crate::pane_grid::{ Axis, Configuration, Direction, Edge, Node, Pane, Region, Split, Target, @@ -18,23 +18,23 @@ use std::collections::HashMap; /// provided to the view function of [`PaneGrid::new`] for displaying each /// [`Pane`]. /// -/// [`PaneGrid`]: crate::widget::PaneGrid -/// [`PaneGrid::new`]: crate::widget::PaneGrid::new +/// [`PaneGrid`]: super::PaneGrid +/// [`PaneGrid::new`]: super::PaneGrid::new #[derive(Debug, Clone)] pub struct State { /// The panes of the [`PaneGrid`]. /// - /// [`PaneGrid`]: crate::widget::PaneGrid + /// [`PaneGrid`]: super::PaneGrid pub panes: HashMap, /// The internal state of the [`PaneGrid`]. /// - /// [`PaneGrid`]: crate::widget::PaneGrid + /// [`PaneGrid`]: super::PaneGrid pub internal: Internal, /// The maximized [`Pane`] of the [`PaneGrid`]. /// - /// [`PaneGrid`]: crate::widget::PaneGrid + /// [`PaneGrid`]: super::PaneGrid pub(super) maximized: Option, } @@ -236,6 +236,8 @@ impl State { } /// Move [`Pane`] to an [`Edge`] of the [`PaneGrid`]. + /// + /// [`PaneGrid`]: super::PaneGrid pub fn move_to_edge(&mut self, pane: &Pane, edge: Edge) { match edge { Edge::Top => { @@ -269,8 +271,8 @@ impl State { /// If you want to swap panes on drag and drop in your [`PaneGrid`], you /// will need to call this method when handling a [`DragEvent`]. /// - /// [`PaneGrid`]: crate::widget::PaneGrid - /// [`DragEvent`]: crate::widget::pane_grid::DragEvent + /// [`PaneGrid`]: super::PaneGrid + /// [`DragEvent`]: super::DragEvent pub fn swap(&mut self, a: &Pane, b: &Pane) { self.internal.layout.update(&|node| match node { Node::Split { .. } => {} @@ -292,8 +294,8 @@ impl State { /// If you want to enable resize interactions in your [`PaneGrid`], you will /// need to call this method when handling a [`ResizeEvent`]. /// - /// [`PaneGrid`]: crate::widget::PaneGrid - /// [`ResizeEvent`]: crate::widget::pane_grid::ResizeEvent + /// [`PaneGrid`]: super::PaneGrid + /// [`ResizeEvent`]: super::ResizeEvent pub fn resize(&mut self, split: &Split, ratio: f32) { let _ = self.internal.layout.resize(split, ratio); } @@ -315,7 +317,7 @@ impl State { /// Maximize the given [`Pane`]. Only this pane will be rendered by the /// [`PaneGrid`] until [`Self::restore()`] is called. /// - /// [`PaneGrid`]: crate::widget::PaneGrid + /// [`PaneGrid`]: super::PaneGrid pub fn maximize(&mut self, pane: &Pane) { self.maximized = Some(*pane); } @@ -323,14 +325,14 @@ impl State { /// Restore the currently maximized [`Pane`] to it's normal size. All panes /// will be rendered by the [`PaneGrid`]. /// - /// [`PaneGrid`]: crate::widget::PaneGrid + /// [`PaneGrid`]: super::PaneGrid pub fn restore(&mut self) { let _ = self.maximized.take(); } /// Returns the maximized [`Pane`] of the [`PaneGrid`]. /// - /// [`PaneGrid`]: crate::widget::PaneGrid + /// [`PaneGrid`]: super::PaneGrid pub fn maximized(&self) -> Option { self.maximized } @@ -338,7 +340,7 @@ impl State { /// The internal state of a [`PaneGrid`]. /// -/// [`PaneGrid`]: crate::widget::PaneGrid +/// [`PaneGrid`]: super::PaneGrid #[derive(Debug, Clone)] pub struct Internal { layout: Node, @@ -349,7 +351,7 @@ impl Internal { /// Initializes the [`Internal`] state of a [`PaneGrid`] from a /// [`Configuration`]. /// - /// [`PaneGrid`]: crate::widget::PaneGrid + /// [`PaneGrid`]: super::PaneGrid pub fn from_configuration( panes: &mut HashMap, content: Configuration, @@ -394,16 +396,16 @@ impl Internal { /// The current action of a [`PaneGrid`]. /// -/// [`PaneGrid`]: crate::widget::PaneGrid +/// [`PaneGrid`]: super::PaneGrid #[derive(Debug, Clone, Copy, PartialEq)] pub enum Action { /// The [`PaneGrid`] is idle. /// - /// [`PaneGrid`]: crate::widget::PaneGrid + /// [`PaneGrid`]: super::PaneGrid Idle, /// A [`Pane`] in the [`PaneGrid`] is being dragged. /// - /// [`PaneGrid`]: crate::widget::PaneGrid + /// [`PaneGrid`]: super::PaneGrid Dragging { /// The [`Pane`] being dragged. pane: Pane, @@ -412,7 +414,7 @@ pub enum Action { }, /// A [`Split`] in the [`PaneGrid`] is being dragged. /// - /// [`PaneGrid`]: crate::widget::PaneGrid + /// [`PaneGrid`]: super::PaneGrid Resizing { /// The [`Split`] being dragged. split: Split, diff --git a/widget/src/pane_grid/title_bar.rs b/widget/src/pane_grid/title_bar.rs index cac24e68..47457337 100644 --- a/widget/src/pane_grid/title_bar.rs +++ b/widget/src/pane_grid/title_bar.rs @@ -11,7 +11,7 @@ use crate::core::{ /// The title bar of a [`Pane`]. /// -/// [`Pane`]: crate::widget::pane_grid::Pane +/// [`Pane`]: super::Pane #[allow(missing_debug_implementations)] pub struct TitleBar<'a, Message, Renderer = crate::Renderer> where @@ -75,7 +75,7 @@ where /// [`TitleBar`] is hovered. /// /// [`controls`]: Self::controls - /// [`Pane`]: crate::widget::pane_grid::Pane + /// [`Pane`]: super::Pane pub fn always_show_controls(mut self) -> Self { self.always_show_controls = true; self @@ -114,7 +114,7 @@ where /// Draws the [`TitleBar`] with the provided [`Renderer`] and [`Layout`]. /// - /// [`Renderer`]: crate::Renderer + /// [`Renderer`]: crate::core::Renderer pub fn draw( &self, tree: &Tree, diff --git a/widget/src/pick_list.rs b/widget/src/pick_list.rs index 0a1e2a99..26fe5ca2 100644 --- a/widget/src/pick_list.rs +++ b/widget/src/pick_list.rs @@ -105,7 +105,7 @@ where self } - /// Sets the text [`LineHeight`] of the [`PickList`]. + /// Sets the text [`text::LineHeight`] of the [`PickList`]. pub fn text_line_height( mut self, line_height: impl Into, diff --git a/widget/src/radio.rs b/widget/src/radio.rs index 65d71ec2..12bbd9c7 100644 --- a/widget/src/radio.rs +++ b/widget/src/radio.rs @@ -156,7 +156,7 @@ where self } - /// Sets the text [`LineHeight`] of the [`Radio`] button. + /// Sets the text [`text::LineHeight`] of the [`Radio`] button. pub fn text_line_height( mut self, line_height: impl Into, diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index 61fc0055..f7a90880 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -182,7 +182,7 @@ where self } - /// Sets the [`LineHeight`] of the [`TextInput`]. + /// Sets the [`text::LineHeight`] of the [`TextInput`]. pub fn line_height( mut self, line_height: impl Into, diff --git a/widget/src/text_input/value.rs b/widget/src/text_input/value.rs index cf4da562..d1b056c8 100644 --- a/widget/src/text_input/value.rs +++ b/widget/src/text_input/value.rs @@ -2,7 +2,7 @@ use unicode_segmentation::UnicodeSegmentation; /// The value of a [`TextInput`]. /// -/// [`TextInput`]: crate::widget::TextInput +/// [`TextInput`]: super::TextInput // TODO: Reduce allocations, cache results (?) #[derive(Debug, Clone)] pub struct Value { diff --git a/widget/src/toggler.rs b/widget/src/toggler.rs index c8187181..3793f5b0 100644 --- a/widget/src/toggler.rs +++ b/widget/src/toggler.rs @@ -109,7 +109,7 @@ where self } - /// Sets the text [`LineHeight`] of the [`Toggler`]. + /// Sets the text [`text::LineHeight`] of the [`Toggler`]. pub fn text_line_height( mut self, line_height: impl Into, @@ -136,9 +136,9 @@ where self } - /// Sets the [`Font`] of the text of the [`Toggler`] + /// Sets the [`Renderer::Font`] of the text of the [`Toggler`] /// - /// [`Font`]: crate::text::Renderer::Font + /// [`Renderer::Font`]: crate::core::text::Renderer pub fn font(mut self, font: impl Into) -> Self { self.font = Some(font.into()); self diff --git a/winit/src/application/state.rs b/winit/src/application/state.rs index 967f43f2..e655529a 100644 --- a/winit/src/application/state.rs +++ b/winit/src/application/state.rs @@ -184,9 +184,7 @@ where /// window. /// /// Normally an [`Application`] should be synchronized with its [`State`] - /// and window after calling [`Application::update`]. - /// - /// [`Application::update`]: crate::Program::update + /// and window after calling [`crate::application::update`]. pub fn synchronize(&mut self, application: &A, window: &Window) { // Update window title let new_title = application.title(); diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index b2398e62..3ecd044c 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -521,7 +521,7 @@ pub fn user_attention( } } -/// Converts some [`Icon`] into it's `winit` counterpart. +/// Converts some [`window::Icon`] into it's `winit` counterpart. /// /// Returns `None` if there is an error during the conversion. pub fn icon(icon: window::Icon) -> Option { From f60884f6f8639f75258c264bf4a15591351ef05b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 9 Sep 2023 20:58:45 +0200 Subject: [PATCH 157/321] Deny `broken_intradoc_links` and verify documentation in CI --- .github/workflows/document.yml | 6 ++---- core/src/lib.rs | 5 +++-- futures/src/lib.rs | 5 +++-- graphics/src/lib.rs | 5 +++-- renderer/src/lib.rs | 13 +++++++++++++ runtime/src/lib.rs | 5 +++-- src/lib.rs | 5 +++-- style/src/lib.rs | 8 +++++--- tiny_skia/src/geometry.rs | 2 +- tiny_skia/src/lib.rs | 13 +++++++++++++ tiny_skia/src/raster.rs | 4 ++-- tiny_skia/src/text.rs | 6 +++--- tiny_skia/src/vector.rs | 8 ++++---- tiny_skia/src/window/compositor.rs | 1 + wgpu/src/lib.rs | 5 +++-- widget/src/lib.rs | 5 +++-- winit/src/lib.rs | 5 +++-- 17 files changed, 68 insertions(+), 33 deletions(-) diff --git a/.github/workflows/document.yml b/.github/workflows/document.yml index 09a7a4d5..230c5cb0 100644 --- a/.github/workflows/document.yml +++ b/.github/workflows/document.yml @@ -1,8 +1,5 @@ name: Document -on: - push: - branches: - - master +on: [push, pull_request] jobs: all: runs-on: ubuntu-20.04 @@ -31,6 +28,7 @@ jobs: - name: Write CNAME file run: echo 'docs.iced.rs' > ./target/doc/CNAME - name: Publish documentation + if: github.ref == 'refs/heads/master' uses: peaceiris/actions-gh-pages@v3 with: deploy_key: ${{ secrets.DOCS_DEPLOY_KEY }} diff --git a/core/src/lib.rs b/core/src/lib.rs index c1c8424b..1bfba7bd 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -9,6 +9,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] +#![forbid(unsafe_code, rust_2018_idioms)] #![deny( missing_debug_implementations, missing_docs, @@ -17,9 +18,9 @@ clippy::from_over_into, clippy::needless_borrow, clippy::new_without_default, - clippy::useless_conversion + clippy::useless_conversion, + rustdoc::broken_intra_doc_links )] -#![forbid(unsafe_code, rust_2018_idioms)] #![allow(clippy::inherent_to_string, clippy::type_complexity)] pub mod alignment; pub mod clipboard; diff --git a/futures/src/lib.rs b/futures/src/lib.rs index 8e75331f..abc46176 100644 --- a/futures/src/lib.rs +++ b/futures/src/lib.rs @@ -4,6 +4,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] +#![forbid(unsafe_code, rust_2018_idioms)] #![deny( missing_debug_implementations, missing_docs, @@ -12,9 +13,9 @@ clippy::from_over_into, clippy::needless_borrow, clippy::new_without_default, - clippy::useless_conversion + clippy::useless_conversion, + rustdoc::broken_intra_doc_links )] -#![forbid(unsafe_code, rust_2018_idioms)] #![allow(clippy::inherent_to_string, clippy::type_complexity)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] pub use futures; diff --git a/graphics/src/lib.rs b/graphics/src/lib.rs index af374a2f..4e814eb0 100644 --- a/graphics/src/lib.rs +++ b/graphics/src/lib.rs @@ -7,6 +7,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] +#![forbid(rust_2018_idioms)] #![deny( missing_debug_implementations, missing_docs, @@ -16,9 +17,9 @@ clippy::from_over_into, clippy::needless_borrow, clippy::new_without_default, - clippy::useless_conversion + clippy::useless_conversion, + rustdoc::broken_intra_doc_links )] -#![forbid(rust_2018_idioms)] #![allow(clippy::inherent_to_string, clippy::type_complexity)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] mod antialiasing; diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs index 7d1a02c2..6dcc0e96 100644 --- a/renderer/src/lib.rs +++ b/renderer/src/lib.rs @@ -1,3 +1,16 @@ +#![forbid(rust_2018_idioms)] +#![deny( + unsafe_code, + unused_results, + clippy::extra_unused_lifetimes, + clippy::from_over_into, + clippy::needless_borrow, + clippy::new_without_default, + clippy::useless_conversion, + rustdoc::broken_intra_doc_links +)] +#![allow(clippy::inherent_to_string, clippy::type_complexity)] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] pub mod compositor; #[cfg(feature = "geometry")] diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index dc631d47..c3261cca 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -8,6 +8,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] +#![forbid(unsafe_code, rust_2018_idioms)] #![deny( missing_debug_implementations, missing_docs, @@ -16,9 +17,9 @@ clippy::from_over_into, clippy::needless_borrow, clippy::new_without_default, - clippy::useless_conversion + clippy::useless_conversion, + rustdoc::broken_intra_doc_links )] -#![forbid(unsafe_code, rust_2018_idioms)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] pub mod clipboard; pub mod command; diff --git a/src/lib.rs b/src/lib.rs index 8780d276..3cbe716a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -151,6 +151,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] +#![forbid(rust_2018_idioms, unsafe_code)] #![deny( missing_debug_implementations, missing_docs, @@ -159,9 +160,9 @@ clippy::from_over_into, clippy::needless_borrow, clippy::new_without_default, - clippy::useless_conversion + clippy::useless_conversion, + rustdoc::broken_intra_doc_links )] -#![forbid(rust_2018_idioms, unsafe_code)] #![allow(clippy::inherent_to_string, clippy::type_complexity)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] use iced_widget::graphics; diff --git a/style/src/lib.rs b/style/src/lib.rs index 286ff9db..0c555ed8 100644 --- a/style/src/lib.rs +++ b/style/src/lib.rs @@ -7,16 +7,18 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] +#![forbid(unsafe_code, rust_2018_idioms)] #![deny( unused_results, clippy::extra_unused_lifetimes, clippy::from_over_into, clippy::needless_borrow, clippy::new_without_default, - clippy::useless_conversion + clippy::useless_conversion, + missing_docs, + unused_results, + rustdoc::broken_intra_doc_links )] -#![deny(missing_docs, unused_results)] -#![forbid(unsafe_code, rust_2018_idioms)] #![allow(clippy::inherent_to_string, clippy::type_complexity)] pub use iced_core as core; diff --git a/tiny_skia/src/geometry.rs b/tiny_skia/src/geometry.rs index 1df5aa18..047bc0ff 100644 --- a/tiny_skia/src/geometry.rs +++ b/tiny_skia/src/geometry.rs @@ -303,7 +303,7 @@ pub fn into_fill_rule(rule: fill::Rule) -> tiny_skia::FillRule { } } -pub fn into_stroke(stroke: &Stroke) -> tiny_skia::Stroke { +pub fn into_stroke(stroke: &Stroke<'_>) -> tiny_skia::Stroke { tiny_skia::Stroke { width: stroke.width, line_cap: match stroke.line_cap { diff --git a/tiny_skia/src/lib.rs b/tiny_skia/src/lib.rs index 15de6ce2..e48468e9 100644 --- a/tiny_skia/src/lib.rs +++ b/tiny_skia/src/lib.rs @@ -1,3 +1,16 @@ +#![forbid(rust_2018_idioms)] +#![deny( + unsafe_code, + unused_results, + clippy::extra_unused_lifetimes, + clippy::from_over_into, + clippy::needless_borrow, + clippy::new_without_default, + clippy::useless_conversion, + rustdoc::broken_intra_doc_links +)] +#![allow(clippy::inherent_to_string, clippy::type_complexity)] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] pub mod window; mod backend; diff --git a/tiny_skia/src/raster.rs b/tiny_skia/src/raster.rs index dedb127c..d13b1167 100644 --- a/tiny_skia/src/raster.rs +++ b/tiny_skia/src/raster.rs @@ -85,14 +85,14 @@ impl Cache { ); } - entry.insert(Some(Entry { + let _ = entry.insert(Some(Entry { width: image.width(), height: image.height(), pixels: buffer, })); } - self.hits.insert(id); + let _ = self.hits.insert(id); self.entries.get(&id).unwrap().as_ref().map(|entry| { tiny_skia::PixmapRef::from_bytes( bytemuck::cast_slice(&entry.pixels), diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index 306b400a..dabbe952 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -32,7 +32,7 @@ impl Pipeline { } pub fn load_font(&mut self, bytes: Cow<'static, [u8]>) { - self.font_system.get_mut().db_mut().load_font_source( + let _ = self.font_system.get_mut().db_mut().load_font_source( cosmic_text::fontdb::Source::Binary(Arc::new(bytes.into_owned())), ); @@ -335,10 +335,10 @@ impl GlyphCache { } } - entry.insert((buffer, image.placement)); + let _ = entry.insert((buffer, image.placement)); } - self.recently_used.insert(key); + let _ = self.recently_used.insert(key); self.entries.get(&key).map(|(buffer, placement)| { (bytemuck::cast_slice(buffer.as_slice()), *placement) diff --git a/tiny_skia/src/vector.rs b/tiny_skia/src/vector.rs index 433ca0f5..490b9f69 100644 --- a/tiny_skia/src/vector.rs +++ b/tiny_skia/src/vector.rs @@ -92,10 +92,10 @@ impl Cache { } }; - entry.insert(svg); + let _ = entry.insert(svg); } - self.tree_hits.insert(id); + let _ = self.tree_hits.insert(id); self.trees.get(&id).unwrap().as_ref() } @@ -178,10 +178,10 @@ impl Cache { } } - self.rasters.insert(key, image); + let _ = self.rasters.insert(key, image); } - self.raster_hits.insert(key); + let _ = self.raster_hits.insert(key); self.rasters.get(&key).map(tiny_skia::Pixmap::as_ref) } diff --git a/tiny_skia/src/window/compositor.rs b/tiny_skia/src/window/compositor.rs index 775cf9e5..c0da5142 100644 --- a/tiny_skia/src/window/compositor.rs +++ b/tiny_skia/src/window/compositor.rs @@ -39,6 +39,7 @@ impl crate::graphics::Compositor for Compositor { width: u32, height: u32, ) -> Surface { + #[allow(unsafe_code)] let window = unsafe { softbuffer::GraphicsContext::new(window, window) } .expect("Create softbuffer for window"); diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index d1e4b7af..b9f54560 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -20,6 +20,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] +#![forbid(rust_2018_idioms)] #![deny( missing_debug_implementations, missing_docs, @@ -29,9 +30,9 @@ clippy::from_over_into, clippy::needless_borrow, clippy::new_without_default, - clippy::useless_conversion + clippy::useless_conversion, + rustdoc::broken_intra_doc_links )] -#![forbid(rust_2018_idioms)] #![allow(clippy::inherent_to_string, clippy::type_complexity)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] pub mod layer; diff --git a/widget/src/lib.rs b/widget/src/lib.rs index 316e8829..5cb0f8de 100644 --- a/widget/src/lib.rs +++ b/widget/src/lib.rs @@ -2,6 +2,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] +#![forbid(unsafe_code, rust_2018_idioms)] #![deny( missing_debug_implementations, missing_docs, @@ -10,9 +11,9 @@ clippy::from_over_into, clippy::needless_borrow, clippy::new_without_default, - clippy::useless_conversion + clippy::useless_conversion, + rustdoc::broken_intra_doc_links )] -#![forbid(unsafe_code, rust_2018_idioms)] #![allow(clippy::inherent_to_string, clippy::type_complexity)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] pub use iced_renderer as renderer; diff --git a/winit/src/lib.rs b/winit/src/lib.rs index 1a87ca11..9852a182 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -17,6 +17,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] +#![forbid(rust_2018_idioms)] #![deny( missing_debug_implementations, missing_docs, @@ -26,9 +27,9 @@ clippy::needless_borrow, clippy::new_without_default, clippy::useless_conversion, - unsafe_code + unsafe_code, + rustdoc::broken_intra_doc_links )] -#![forbid(rust_2018_idioms)] #![allow(clippy::inherent_to_string, clippy::type_complexity)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] pub use iced_graphics as graphics; From 419d9374b79b39293ba9a17967c2356d29377d8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 9 Sep 2023 21:08:23 +0200 Subject: [PATCH 158/321] Fix outstanding broken intradoc links --- core/src/gradient.rs | 2 -- graphics/src/compositor.rs | 2 +- graphics/src/geometry/fill.rs | 4 +++- graphics/src/geometry/stroke.rs | 4 +++- graphics/src/gradient.rs | 7 +------ 5 files changed, 8 insertions(+), 11 deletions(-) diff --git a/core/src/gradient.rs b/core/src/gradient.rs index 576c9e4d..4a0d5ea0 100644 --- a/core/src/gradient.rs +++ b/core/src/gradient.rs @@ -6,8 +6,6 @@ use std::cmp::Ordering; #[derive(Debug, Clone, Copy, PartialEq)] /// A fill which transitions colors progressively along a direction, either linearly, radially (TBD), /// or conically (TBD). -/// -/// For a gradient which can be used as a fill on a canvas, see [`iced_graphics::Gradient`]. pub enum Gradient { /// A linear gradient interpolates colors along a direction at a specific angle. Linear(Linear), diff --git a/graphics/src/compositor.rs b/graphics/src/compositor.rs index f7b86045..7173ffa7 100644 --- a/graphics/src/compositor.rs +++ b/graphics/src/compositor.rs @@ -63,7 +63,7 @@ pub trait Compositor: Sized { /// Screenshots the current [`Renderer`] primitives to an offscreen texture, and returns the bytes of /// the texture ordered as `RGBA` in the sRGB color space. /// - /// [`Renderer`]: Self::Renderer; + /// [`Renderer`]: Self::Renderer fn screenshot>( &mut self, renderer: &mut Self::Renderer, diff --git a/graphics/src/geometry/fill.rs b/graphics/src/geometry/fill.rs index b773c99b..670fbc12 100644 --- a/graphics/src/geometry/fill.rs +++ b/graphics/src/geometry/fill.rs @@ -1,4 +1,6 @@ -//! Fill [crate::widget::canvas::Geometry] with a certain style. +//! Fill [`Geometry`] with a certain style. +//! +//! [`Geometry`]: super::Renderer::Geometry pub use crate::geometry::Style; use crate::core::Color; diff --git a/graphics/src/geometry/stroke.rs b/graphics/src/geometry/stroke.rs index 69a76e1c..aff49ab3 100644 --- a/graphics/src/geometry/stroke.rs +++ b/graphics/src/geometry/stroke.rs @@ -1,4 +1,6 @@ -//! Create lines from a [crate::widget::canvas::Path] and assigns them various attributes/styles. +//! Create lines from a [`Path`] and assigns them various attributes/styles. +//! +//! [`Path`]: super::Path pub use crate::geometry::Style; use iced_core::Color; diff --git a/graphics/src/gradient.rs b/graphics/src/gradient.rs index f5f5f8b4..b274ec86 100644 --- a/graphics/src/gradient.rs +++ b/graphics/src/gradient.rs @@ -1,8 +1,6 @@ //! A gradient that can be used as a fill for some geometry. //! //! For a gradient that you can use as a background variant for a widget, see [`Gradient`]. -//! -//! [`Gradient`]: crate::core::Gradient; use crate::color; use crate::core::gradient::ColorStop; use crate::core::{self, Color, Point, Rectangle}; @@ -36,10 +34,7 @@ impl Gradient { } } -/// A linear gradient that can be used in the style of [`Fill`] or [`Stroke`]. -/// -/// [`Fill`]: crate::geometry::Fill; -/// [`Stroke`]: crate::geometry::Stroke; +/// A linear gradient. #[derive(Debug, Clone, Copy, PartialEq)] pub struct Linear { /// The absolute starting position of the gradient. From fbc9ef74c406b2a58bb2a093262323e346faf485 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sat, 9 Sep 2023 22:42:41 +0200 Subject: [PATCH 159/321] Change init_with_level to init in examples --- examples/integration/Cargo.toml | 1 - examples/integration/src/main.rs | 2 +- examples/tour/Cargo.toml | 1 - examples/tour/src/main.rs | 2 +- 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/examples/integration/Cargo.toml b/examples/integration/Cargo.toml index 6b9fcc57..a4a961f8 100644 --- a/examples/integration/Cargo.toml +++ b/examples/integration/Cargo.toml @@ -19,6 +19,5 @@ iced_wgpu.features = ["webgl"] console_error_panic_hook = "0.1" console_log = "1.0" -log.workspace = true wasm-bindgen = "0.2" web-sys = { version = "0.3", features = ["Element", "HtmlCanvasElement", "Window", "Document"] } diff --git a/examples/integration/src/main.rs b/examples/integration/src/main.rs index af48af5f..d0b2d891 100644 --- a/examples/integration/src/main.rs +++ b/examples/integration/src/main.rs @@ -29,7 +29,7 @@ use winit::platform::web::WindowBuilderExtWebSys; pub fn main() -> Result<(), Box> { #[cfg(target_arch = "wasm32")] let canvas_element = { - console_log::init_with_level(log::Level::Debug)?; + console_log::init().expect("Initialize logger"); std::panic::set_hook(Box::new(console_error_panic_hook::hook)); diff --git a/examples/tour/Cargo.toml b/examples/tour/Cargo.toml index 11920e0d..9e984ad1 100644 --- a/examples/tour/Cargo.toml +++ b/examples/tour/Cargo.toml @@ -18,4 +18,3 @@ iced.features = ["image", "debug", "webgl"] console_error_panic_hook = "0.1" console_log = "1.0" -log.workspace = true diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs index f0e3c0cd..3387b481 100644 --- a/examples/tour/src/main.rs +++ b/examples/tour/src/main.rs @@ -10,7 +10,7 @@ use iced::{Color, Element, Font, Length, Renderer, Sandbox, Settings}; pub fn main() -> iced::Result { #[cfg(target_arch = "wasm32")] { - console_log::init_with_level(log::Level::Debug).expect("Initialize logger"); + console_log::init().expect("Initialize logger"); std::panic::set_hook(Box::new(console_error_panic_hook::hook)); } From bbb9c2d92819f2ff96e51773037138fef488290a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 9 Sep 2023 23:05:44 +0200 Subject: [PATCH 160/321] Count grapheme clusters in `Paragraph::grapheme_position` --- graphics/src/text/paragraph.rs | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/graphics/src/text/paragraph.rs b/graphics/src/text/paragraph.rs index cd12bc8f..e4350cff 100644 --- a/graphics/src/text/paragraph.rs +++ b/graphics/src/text/paragraph.rs @@ -189,8 +189,27 @@ impl core::text::Paragraph for Paragraph { fn grapheme_position(&self, line: usize, index: usize) -> Option { let run = self.internal().buffer.layout_runs().nth(line)?; - // TODO: Index represents a grapheme, not a glyph - let glyph = run.glyphs.get(index).or_else(|| run.glyphs.last())?; + // index represents a grapheme, not a glyph + // Let's find the first glyph for the given grapheme cluster + let mut last_start = None; + let mut graphemes_seen = 0; + + let glyph = run + .glyphs + .iter() + .find(|glyph| { + if graphemes_seen == index { + return true; + } + + if Some(glyph.start) != last_start { + last_start = Some(glyph.start); + graphemes_seen += 1; + } + + false + }) + .or_else(|| run.glyphs.last())?; let advance_last = if index == run.glyphs.len() { glyph.w From 956512338905bac0b156fdaf16fe3c3e07e97a84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 9 Sep 2023 23:06:06 +0200 Subject: [PATCH 161/321] Remove unused `unicode-segmentation` dependency from `iced_graphics` --- graphics/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml index 442eb007..6fc6ab00 100644 --- a/graphics/Cargo.toml +++ b/graphics/Cargo.toml @@ -25,7 +25,6 @@ thiserror = "1.0" bitflags = "1.2" cosmic-text = "0.9" rustc-hash = "1.1" -unicode-segmentation = "1.6" [dependencies.bytemuck] version = "1.4" From 8aa7874ba9ba4a0e7cafb9a447a3db92e95aeb87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 10 Sep 2023 00:43:38 +0200 Subject: [PATCH 162/321] Fix Wasm build of `todos` example --- examples/todos/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/todos/src/main.rs b/examples/todos/src/main.rs index 5d8936df..501bf67e 100644 --- a/examples/todos/src/main.rs +++ b/examples/todos/src/main.rs @@ -17,6 +17,7 @@ use uuid::Uuid; static INPUT_ID: Lazy = Lazy::new(text_input::Id::unique); pub fn main() -> iced::Result { + #[cfg(not(target_arch = "wasm32"))] tracing_subscriber::fmt::init(); Todos::run(Settings { From c6928457440319af3e2cf482b9e916bad9f277a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 10 Sep 2023 00:44:58 +0200 Subject: [PATCH 163/321] Fix broken intradoc link in `widget::keyed` module --- widget/src/keyed.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/widget/src/keyed.rs b/widget/src/keyed.rs index 55019535..ad531e66 100644 --- a/widget/src/keyed.rs +++ b/widget/src/keyed.rs @@ -42,8 +42,6 @@ pub mod column; pub use column::Column; /// Creates a [`Column`] with the given children. -/// -/// [`Column`]: widget::Column #[macro_export] macro_rules! keyed_column { () => ( From b42b24b79a097aab10006490cd2ec8a2332fd5d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 10 Sep 2023 00:55:46 +0200 Subject: [PATCH 164/321] Fix (more) broken intradoc links Good thing I just set up CI earlier for this :sweat_smile: --- core/src/text.rs | 2 +- graphics/src/backend.rs | 2 +- graphics/src/primitive.rs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/src/text.rs b/core/src/text.rs index f5e9abc4..0e3617b1 100644 --- a/core/src/text.rs +++ b/core/src/text.rs @@ -215,7 +215,7 @@ pub trait Paragraph: Default { /// Returns the [`LineHeight`] of the [`Paragraph`]. fn line_height(&self) -> LineHeight; - /// Returns the [`Font`] of the [`Paragraph`]. + /// Returns the [`Self::Font`] of the [`Paragraph`]. fn font(&self) -> Self::Font; /// Returns the [`Shaping`] strategy of the [`Paragraph`]. diff --git a/graphics/src/backend.rs b/graphics/src/backend.rs index 6774b9ca..c2ac82ba 100644 --- a/graphics/src/backend.rs +++ b/graphics/src/backend.rs @@ -16,7 +16,7 @@ pub trait Backend { /// A graphics backend that supports text rendering. pub trait Text { - /// Loads a [`Font`] from its bytes. + /// Loads a font from its bytes. fn load_font(&mut self, font: Cow<'static, [u8]>); /// Returns the [`cosmic_text::FontSystem`] of the [`Backend`]. diff --git a/graphics/src/primitive.rs b/graphics/src/primitive.rs index cdc8923e..8a97e6e7 100644 --- a/graphics/src/primitive.rs +++ b/graphics/src/primitive.rs @@ -34,11 +34,11 @@ pub enum Primitive { }, /// A paragraph primitive Paragraph { - /// The [`Paragraph`]. + /// The [`paragraph::Weak`] reference. paragraph: paragraph::Weak, - /// The position of the [`Paragraph`]. + /// The position of the paragraph. position: Point, - /// The color of the [`Paragraph`]. + /// The color of the paragraph. color: Color, }, /// A quad primitive From 1cc5bf59d7c4f47ae47d9a4e22ebaab3ea4975c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 10 Sep 2023 00:59:54 +0200 Subject: [PATCH 165/321] Fix `CHANGELOG` --- CHANGELOG.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed02baf7..fdd832e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added +- Explicit text caching. [#2058](https://github.com/iced-rs/iced/pull/2058) - `Theme::Custom::with_fn` for custom extended palette generation. [#2067](https://github.com/iced-rs/iced/pull/2067) ### Changed @@ -20,13 +21,6 @@ Many thanks to... - @akshayr-mecha - @dtzxporter -### Added -- Explicit text caching. [#2058](https://github.com/iced-rs/iced/pull/2058) - -Many thanks to... - -- Add your name here - ## [0.10.0] - 2023-07-28 ### Added - Text shaping, font fallback, and `iced_wgpu` overhaul. [#1697](https://github.com/iced-rs/iced/pull/1697) From df72fd1095baf76357e9fe04df7b66b643509f42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 10 Sep 2023 03:04:02 +0200 Subject: [PATCH 166/321] Fix `Widget::layout` implementation of `MouseArea` --- widget/src/mouse_area.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/widget/src/mouse_area.rs b/widget/src/mouse_area.rs index 65d44dd5..3a5b01a3 100644 --- a/widget/src/mouse_area.rs +++ b/widget/src/mouse_area.rs @@ -124,7 +124,9 @@ where renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - self.content.as_widget().layout(tree, renderer, limits) + self.content + .as_widget() + .layout(&mut tree.children[0], renderer, limits) } fn operate( From b329950a4244c572114288431ad6beca558124ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 10 Sep 2023 03:15:31 +0200 Subject: [PATCH 167/321] Fix `Tooltip` widget state management --- widget/src/tooltip.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/widget/src/tooltip.rs b/widget/src/tooltip.rs index 534d901a..b889f8db 100644 --- a/widget/src/tooltip.rs +++ b/widget/src/tooltip.rs @@ -139,7 +139,9 @@ where renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - self.content.as_widget().layout(tree, renderer, limits) + self.content + .as_widget() + .layout(&mut tree.children[0], renderer, limits) } fn on_event( @@ -434,7 +436,7 @@ where Widget::<(), Renderer>::draw( self.tooltip, - &widget::Tree::empty(), + &self.state, renderer, theme, &defaults, From 6d379b7fcef817bee1b1cb367bd308f9c6655b0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 10 Sep 2023 03:16:55 +0200 Subject: [PATCH 168/321] Fix unnecessary dereference in `Tooltip` --- widget/src/tooltip.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget/src/tooltip.rs b/widget/src/tooltip.rs index b889f8db..edc74e31 100644 --- a/widget/src/tooltip.rs +++ b/widget/src/tooltip.rs @@ -436,7 +436,7 @@ where Widget::<(), Renderer>::draw( self.tooltip, - &self.state, + self.state, renderer, theme, &defaults, From bc1bde0d5ca1ec291f13e108f1543daa75b97848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 10 Sep 2023 03:36:31 +0200 Subject: [PATCH 169/321] Fix `ComboBox` widget not displaying selection text --- widget/src/combo_box.rs | 25 +++++++++++++++++++++++-- widget/src/text_input.rs | 28 +++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs index d6915281..044dc0ef 100644 --- a/widget/src/combo_box.rs +++ b/widget/src/combo_box.rs @@ -311,7 +311,20 @@ where renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - self.text_input.layout(tree, renderer, limits) + let is_focused = { + let text_input_state = tree.children[0] + .state + .downcast_ref::>(); + + text_input_state.is_focused() + }; + + self.text_input.layout( + &mut tree.children[0], + renderer, + limits, + (!is_focused).then_some(&self.selection), + ) } fn tag(&self) -> widget::tree::Tag { @@ -665,7 +678,15 @@ where menu, &filtered_options.options, hovered_option, - |x| (self.on_selected)(x), + |x| { + tree.children[0] + .state + .downcast_mut::>( + ) + .unfocus(); + + (self.on_selected)(x) + }, self.on_option_hovered.as_deref(), ) .width(bounds.width) diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index bfd196fd..7d5ae806 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -200,6 +200,32 @@ where self } + /// Lays out the [`TextInput`], overriding its [`Value`] if provided. + /// + /// [`Renderer`]: text::Renderer + pub fn layout( + &self, + tree: &mut Tree, + renderer: &Renderer, + limits: &layout::Limits, + value: Option<&Value>, + ) -> layout::Node { + layout( + renderer, + limits, + self.width, + self.padding, + self.size, + self.font, + self.line_height, + self.icon.as_ref(), + tree.state.downcast_mut::>(), + value.unwrap_or(&self.value), + &self.placeholder, + self.is_secure, + ) + } + /// Draws the [`TextInput`] with the given [`Renderer`], overriding its /// [`Value`] if provided. /// @@ -1411,7 +1437,7 @@ fn find_cursor_position( Some( unicode_segmentation::UnicodeSegmentation::graphemes( - &value[..char_offset], + &value[..char_offset.min(value.len())], true, ) .count(), From 90bd581d8ed72ac1a927a90ba04ebdd156fa2922 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sun, 10 Sep 2023 10:18:58 +0200 Subject: [PATCH 170/321] Fix `ComboBox` widget panic on wasm --- widget/src/combo_box.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs index 044dc0ef..768c2402 100644 --- a/widget/src/combo_box.rs +++ b/widget/src/combo_box.rs @@ -6,6 +6,7 @@ use crate::core::mouse; use crate::core::overlay; use crate::core::renderer; use crate::core::text; +use crate::core::time::Instant; use crate::core::widget::{self, Widget}; use crate::core::{Clipboard, Element, Length, Padding, Rectangle, Shell}; use crate::overlay::menu; @@ -14,7 +15,6 @@ use crate::{container, scrollable, text_input, TextInput}; use std::cell::RefCell; use std::fmt::Display; -use std::time::Instant; /// A widget for searching and selecting a single value from a list of options. /// From 9245423c5d82f88c99adecaaf5dd2ac3559a05a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 11 Sep 2023 01:10:31 +0200 Subject: [PATCH 171/321] Fix link in `CONTRIBUTING` guide --- CONTRIBUTING.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c01acc4e..4e7075c6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,7 +17,6 @@ Besides directly writing code, there are many other different ways you can contr [the ecosystem overview]: ECOSYSTEM.md [the roadmap]: ROADMAP.md -[our Discourse fourm]: https://discourse.iced.rs/ -[our Discord server]: https://discord.gg/3xZJ65GAhd +[our Discourse forum]: https://discourse.iced.rs/ [Code is the Easy Part]: https://youtu.be/DSjbTC-hvqQ?t=1138 [The Hard Parts of Open Source]: https://www.youtube.com/watch?v=o_4EX4dPppA From 346af3f8b0baa418fd37b878bc2930ff0bd57cc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 11 Sep 2023 02:47:24 +0200 Subject: [PATCH 172/321] Make `FontSystem` global and simplify `Paragraph` API --- core/src/renderer/null.rs | 34 +------- core/src/text.rs | 90 ++++++-------------- core/src/widget/text.rs | 23 +++--- graphics/Cargo.toml | 12 +-- graphics/src/backend.rs | 4 - graphics/src/renderer.rs | 35 -------- graphics/src/text.rs | 47 +++++------ graphics/src/text/paragraph.rs | 145 ++++++++++++++++----------------- renderer/src/lib.rs | 16 ---- tiny_skia/src/backend.rs | 5 -- tiny_skia/src/text.rs | 21 ++--- wgpu/src/backend.rs | 5 -- wgpu/src/text.rs | 17 ++-- widget/src/pick_list.rs | 22 ++--- widget/src/text_input.rs | 17 ++-- 15 files changed, 165 insertions(+), 328 deletions(-) diff --git a/core/src/renderer/null.rs b/core/src/renderer/null.rs index 55d58a59..0ffd3649 100644 --- a/core/src/renderer/null.rs +++ b/core/src/renderer/null.rs @@ -58,16 +58,6 @@ impl text::Renderer for Null { fn load_font(&mut self, _font: Cow<'static, [u8]>) {} - fn create_paragraph(&self, _text: Text<'_, Self::Font>) -> Self::Paragraph { - } - - fn resize_paragraph( - &self, - _paragraph: &mut Self::Paragraph, - _new_bounds: Size, - ) { - } - fn fill_paragraph( &mut self, _paragraph: &Self::Paragraph, @@ -88,24 +78,12 @@ impl text::Renderer for Null { impl text::Paragraph for () { type Font = Font; - fn content(&self) -> &str { - "" - } + fn with_text(_text: Text<'_, Self::Font>) -> Self {} - fn text_size(&self) -> Pixels { - Pixels(16.0) - } + fn resize(&mut self, _new_bounds: Size) {} - fn font(&self) -> Self::Font { - Font::default() - } - - fn line_height(&self) -> text::LineHeight { - text::LineHeight::default() - } - - fn shaping(&self) -> text::Shaping { - text::Shaping::default() + fn compare(&self, _text: Text<'_, Self::Font>) -> text::Difference { + text::Difference::None } fn horizontal_alignment(&self) -> alignment::Horizontal { @@ -120,10 +98,6 @@ impl text::Paragraph for () { None } - fn bounds(&self) -> Size { - Size::ZERO - } - fn min_bounds(&self) -> Size { Size::ZERO } diff --git a/core/src/text.rs b/core/src/text.rs index 0e3617b1..ff85696e 100644 --- a/core/src/text.rs +++ b/core/src/text.rs @@ -156,33 +156,6 @@ pub trait Renderer: crate::Renderer { /// Loads a [`Self::Font`] from its bytes. fn load_font(&mut self, font: Cow<'static, [u8]>); - /// Creates a new [`Paragraph`] laid out with the given [`Text`]. - fn create_paragraph(&self, text: Text<'_, Self::Font>) -> Self::Paragraph; - - /// Lays out the given [`Paragraph`] with some new boundaries. - fn resize_paragraph( - &self, - paragraph: &mut Self::Paragraph, - new_bounds: Size, - ); - - /// Updates a [`Paragraph`] to match the given [`Text`], if needed. - fn update_paragraph( - &self, - paragraph: &mut Self::Paragraph, - text: Text<'_, Self::Font>, - ) { - match compare(paragraph, text) { - Difference::None => {} - Difference::Bounds => { - self.resize_paragraph(paragraph, text.bounds); - } - Difference::Shape => { - *paragraph = self.create_paragraph(text); - } - } - } - /// Draws the given [`Paragraph`] at the given position and with the given /// [`Color`]. fn fill_paragraph( @@ -201,25 +174,21 @@ pub trait Renderer: crate::Renderer { color: Color, ); } + /// A text paragraph. -pub trait Paragraph: Default { +pub trait Paragraph: Sized + Default { /// The font of this [`Paragraph`]. - type Font; + type Font: Copy + PartialEq; - /// Returns the content of the [`Paragraph`]. - fn content(&self) -> &str; + /// Creates a new [`Paragraph`] laid out with the given [`Text`]. + fn with_text(text: Text<'_, Self::Font>) -> Self; - /// Returns the text size of the [`Paragraph`]. - fn text_size(&self) -> Pixels; + /// Lays out the [`Paragraph`] with some new boundaries. + fn resize(&mut self, new_bounds: Size); - /// Returns the [`LineHeight`] of the [`Paragraph`]. - fn line_height(&self) -> LineHeight; - - /// Returns the [`Self::Font`] of the [`Paragraph`]. - fn font(&self) -> Self::Font; - - /// Returns the [`Shaping`] strategy of the [`Paragraph`]. - fn shaping(&self) -> Shaping; + /// Compares the [`Paragraph`] with some desired [`Text`] and returns the + /// [`Difference`]. + fn compare(&self, text: Text<'_, Self::Font>) -> Difference; /// Returns the horizontal alignment of the [`Paragraph`]. fn horizontal_alignment(&self) -> alignment::Horizontal; @@ -227,9 +196,6 @@ pub trait Paragraph: Default { /// Returns the vertical alignment of the [`Paragraph`]. fn vertical_alignment(&self) -> alignment::Vertical; - /// Returns the boundaries of the [`Paragraph`]. - fn bounds(&self) -> Size; - /// Returns the minimum boundaries that can fit the contents of the /// [`Paragraph`]. fn min_bounds(&self) -> Size; @@ -241,6 +207,19 @@ pub trait Paragraph: Default { /// Returns the distance to the given grapheme index in the [`Paragraph`]. fn grapheme_position(&self, line: usize, index: usize) -> Option; + /// Updates the [`Paragraph`] to match the given [`Text`], if needed. + fn update(&mut self, text: Text<'_, Self::Font>) { + match self.compare(text) { + Difference::None => {} + Difference::Bounds => { + self.resize(text.bounds); + } + Difference::Shape => { + *self = Self::with_text(text); + } + } + } + /// Returns the minimum width that can fit the contents of the [`Paragraph`]. fn min_width(&self) -> f32 { self.min_bounds().width @@ -276,26 +255,3 @@ pub enum Difference { /// the text is necessary. Shape, } - -/// Compares a [`Paragraph`] with some desired [`Text`] and returns the -/// [`Difference`]. -pub fn compare( - paragraph: &impl Paragraph, - text: Text<'_, Font>, -) -> Difference { - if paragraph.content() != text.content - || paragraph.text_size() != text.size - || paragraph.line_height().to_absolute(text.size) - != text.line_height.to_absolute(text.size) - || paragraph.font() != text.font - || paragraph.shaping() != text.shaping - || paragraph.horizontal_alignment() != text.horizontal_alignment - || paragraph.vertical_alignment() != text.vertical_alignment - { - Difference::Shape - } else if paragraph.bounds() != text.bounds { - Difference::Bounds - } else { - Difference::None - } -} diff --git a/core/src/widget/text.rs b/core/src/widget/text.rs index 53ed463e..c7c9f539 100644 --- a/core/src/widget/text.rs +++ b/core/src/widget/text.rs @@ -212,19 +212,16 @@ where let State(ref mut paragraph) = state; - renderer.update_paragraph( - paragraph, - text::Text { - content, - bounds, - size, - line_height, - font, - shaping, - horizontal_alignment, - vertical_alignment, - }, - ); + paragraph.update(text::Text { + content, + bounds, + size, + line_height, + font, + shaping, + horizontal_alignment, + vertical_alignment, + }); let size = limits.resolve(paragraph.min_bounds()); diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml index ff698649..26bd1435 100644 --- a/graphics/Cargo.toml +++ b/graphics/Cargo.toml @@ -25,16 +25,15 @@ iced_core.workspace = true bitflags.workspace = true bytemuck.workspace = true +cosmic-text.workspace = true glam.workspace = true half.workspace = true log.workspace = true +once_cell.workspace = true raw-window-handle.workspace = true -thiserror.workspace = true -cosmic-text.workspace = true rustc-hash.workspace = true - -lyon_path.workspace = true -lyon_path.optional = true +thiserror.workspace = true +twox-hash.workspace = true image.workspace = true image.optional = true @@ -42,7 +41,8 @@ image.optional = true kamadak-exif.workspace = true kamadak-exif.optional = true -twox-hash.workspace = true +lyon_path.workspace = true +lyon_path.optional = true [target.'cfg(not(target_arch = "wasm32"))'.dependencies] twox-hash.workspace = true diff --git a/graphics/src/backend.rs b/graphics/src/backend.rs index c2ac82ba..10eb337f 100644 --- a/graphics/src/backend.rs +++ b/graphics/src/backend.rs @@ -2,7 +2,6 @@ use crate::core::image; use crate::core::svg; use crate::core::Size; -use crate::text; use std::borrow::Cow; @@ -18,9 +17,6 @@ pub trait Backend { pub trait Text { /// Loads a font from its bytes. fn load_font(&mut self, font: Cow<'static, [u8]>); - - /// Returns the [`cosmic_text::FontSystem`] of the [`Backend`]. - fn font_system(&self) -> &text::FontSystem; } /// A graphics backend that supports image rendering. diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index d4df29a5..c5033d36 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -158,41 +158,6 @@ where self.backend.load_font(bytes); } - fn create_paragraph(&self, text: Text<'_, Self::Font>) -> text::Paragraph { - text::Paragraph::with_text(text, self.backend.font_system()) - } - - fn update_paragraph( - &self, - paragraph: &mut Self::Paragraph, - text: Text<'_, Self::Font>, - ) { - let font_system = self.backend.font_system(); - - if paragraph.version() != font_system.version() { - // The font system has changed, paragraph fonts may be outdated - *paragraph = self.create_paragraph(text); - } else { - match core::text::compare(paragraph, text) { - core::text::Difference::None => {} - core::text::Difference::Bounds => { - self.resize_paragraph(paragraph, text.bounds); - } - core::text::Difference::Shape => { - *paragraph = self.create_paragraph(text); - } - } - } - } - - fn resize_paragraph( - &self, - paragraph: &mut Self::Paragraph, - new_bounds: Size, - ) { - paragraph.resize(new_bounds, self.backend.font_system()); - } - fn fill_paragraph( &mut self, paragraph: &Self::Paragraph, diff --git a/graphics/src/text.rs b/graphics/src/text.rs index bc06aa3c..f5ccaf52 100644 --- a/graphics/src/text.rs +++ b/graphics/src/text.rs @@ -10,40 +10,39 @@ use crate::core::font::{self, Font}; use crate::core::text::Shaping; use crate::core::Size; +use once_cell::sync::OnceCell; use std::borrow::Cow; -use std::sync::{self, Arc, RwLock}; +use std::sync::{Arc, RwLock}; -#[allow(missing_debug_implementations)] -pub struct FontSystem { - raw: RwLock, - version: Version, -} +pub fn font_system() -> &'static RwLock { + static FONT_SYSTEM: OnceCell> = OnceCell::new(); -impl FontSystem { - pub fn new() -> Self { - FontSystem { - raw: RwLock::new(cosmic_text::FontSystem::new_with_fonts( + FONT_SYSTEM.get_or_init(|| { + RwLock::new(FontSystem { + raw: cosmic_text::FontSystem::new_with_fonts( [cosmic_text::fontdb::Source::Binary(Arc::new( include_bytes!("../fonts/Iced-Icons.ttf").as_slice(), ))] .into_iter(), - )), + ), version: Version::default(), - } - } + }) + }) +} - pub fn get_mut(&mut self) -> &mut cosmic_text::FontSystem { - self.raw.get_mut().expect("Lock font system") - } +#[allow(missing_debug_implementations)] +pub struct FontSystem { + raw: cosmic_text::FontSystem, + version: Version, +} - pub fn write( - &self, - ) -> (sync::RwLockWriteGuard<'_, cosmic_text::FontSystem>, Version) { - (self.raw.write().expect("Write font system"), self.version) +impl FontSystem { + pub fn raw(&mut self) -> &mut cosmic_text::FontSystem { + &mut self.raw } pub fn load_font(&mut self, bytes: Cow<'static, [u8]>) { - let _ = self.get_mut().db_mut().load_font_source( + let _ = self.raw.db_mut().load_font_source( cosmic_text::fontdb::Source::Binary(Arc::new(bytes.into_owned())), ); @@ -58,12 +57,6 @@ impl FontSystem { #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] pub struct Version(u32); -impl Default for FontSystem { - fn default() -> Self { - Self::new() - } -} - pub fn measure(buffer: &cosmic_text::Buffer) -> Size { let (width, total_lines) = buffer .layout_runs() diff --git a/graphics/src/text/paragraph.rs b/graphics/src/text/paragraph.rs index e4350cff..d0396e8e 100644 --- a/graphics/src/text/paragraph.rs +++ b/graphics/src/text/paragraph.rs @@ -2,7 +2,7 @@ use crate::core; use crate::core::alignment; use crate::core::text::{Hit, LineHeight, Shaping, Text}; use crate::core::{Font, Pixels, Point, Size}; -use crate::text::{self, FontSystem}; +use crate::text; use std::fmt; use std::sync::{self, Arc}; @@ -27,13 +27,39 @@ impl Paragraph { Self::default() } - pub fn with_text(text: Text<'_, Font>, font_system: &FontSystem) -> Self { + pub fn buffer(&self) -> &cosmic_text::Buffer { + &self.internal().buffer + } + + pub fn downgrade(&self) -> Weak { + let paragraph = self.internal(); + + Weak { + raw: Arc::downgrade(paragraph), + min_bounds: paragraph.min_bounds, + horizontal_alignment: paragraph.horizontal_alignment, + vertical_alignment: paragraph.vertical_alignment, + } + } + + fn internal(&self) -> &Arc { + self.0 + .as_ref() + .expect("paragraph should always be initialized") + } +} + +impl core::text::Paragraph for Paragraph { + type Font = Font; + + fn with_text(text: Text<'_, Font>) -> Self { log::trace!("Allocating paragraph: {}", text.content); - let (mut font_system, version) = font_system.write(); + let mut font_system = + text::font_system().write().expect("Write font system"); let mut buffer = cosmic_text::Buffer::new( - &mut font_system, + font_system.raw(), cosmic_text::Metrics::new( text.size.into(), text.line_height.to_absolute(text.size).into(), @@ -41,13 +67,13 @@ impl Paragraph { ); buffer.set_size( - &mut font_system, + font_system.raw(), text.bounds.width, text.bounds.height, ); buffer.set_text( - &mut font_system, + font_system.raw(), text.content, text::to_attributes(text.font), text::to_shaping(text.shaping), @@ -64,30 +90,11 @@ impl Paragraph { shaping: text.shaping, bounds: text.bounds, min_bounds, - version, + version: font_system.version(), }))) } - pub fn buffer(&self) -> &cosmic_text::Buffer { - &self.internal().buffer - } - - pub fn version(&self) -> text::Version { - self.internal().version - } - - pub fn downgrade(&self) -> Weak { - let paragraph = self.internal(); - - Weak { - raw: Arc::downgrade(paragraph), - min_bounds: paragraph.min_bounds, - horizontal_alignment: paragraph.horizontal_alignment, - vertical_alignment: paragraph.vertical_alignment, - } - } - - pub fn resize(&mut self, new_bounds: Size, font_system: &FontSystem) { + fn resize(&mut self, new_bounds: Size) { let paragraph = self .0 .take() @@ -95,10 +102,11 @@ impl Paragraph { match Arc::try_unwrap(paragraph) { Ok(mut internal) => { - let (mut font_system, _) = font_system.write(); + let mut font_system = + text::font_system().write().expect("Write font system"); internal.buffer.set_size( - &mut font_system, + font_system.raw(), new_bounds.width, new_bounds.height, ); @@ -113,55 +121,42 @@ impl Paragraph { // If there is a strong reference somewhere, we recompute the // buffer from scratch - *self = Self::with_text( - Text { - content: &internal.content, - bounds: internal.bounds, - size: Pixels(metrics.font_size), - line_height: LineHeight::Absolute(Pixels( - metrics.line_height, - )), - font: internal.font, - horizontal_alignment: internal.horizontal_alignment, - vertical_alignment: internal.vertical_alignment, - shaping: internal.shaping, - }, - font_system, - ); + *self = Self::with_text(Text { + content: &internal.content, + bounds: internal.bounds, + size: Pixels(metrics.font_size), + line_height: LineHeight::Absolute(Pixels( + metrics.line_height, + )), + font: internal.font, + horizontal_alignment: internal.horizontal_alignment, + vertical_alignment: internal.vertical_alignment, + shaping: internal.shaping, + }); } } } - fn internal(&self) -> &Arc { - self.0 - .as_ref() - .expect("paragraph should always be initialized") - } -} + fn compare(&self, text: Text<'_, Font>) -> core::text::Difference { + let font_system = text::font_system().read().expect("Read font system"); + let paragraph = self.internal(); + let metrics = paragraph.buffer.metrics(); -impl core::text::Paragraph for Paragraph { - type Font = Font; - - fn content(&self) -> &str { - &self.internal().content - } - - fn text_size(&self) -> Pixels { - Pixels(self.internal().buffer.metrics().font_size) - } - - fn line_height(&self) -> LineHeight { - LineHeight::Absolute(Pixels( - self.internal().buffer.metrics().line_height, - )) - } - - fn font(&self) -> Font { - self.internal().font - } - - fn shaping(&self) -> Shaping { - self.internal().shaping + if paragraph.version != font_system.version + || paragraph.content != text.content + || metrics.font_size != text.size.0 + || metrics.line_height != text.line_height.to_absolute(text.size).0 + || paragraph.font != text.font + || paragraph.shaping != text.shaping + || paragraph.horizontal_alignment != text.horizontal_alignment + || paragraph.vertical_alignment != text.vertical_alignment + { + core::text::Difference::Shape + } else if paragraph.bounds != text.bounds { + core::text::Difference::Bounds + } else { + core::text::Difference::None + } } fn horizontal_alignment(&self) -> alignment::Horizontal { @@ -172,10 +167,6 @@ impl core::text::Paragraph for Paragraph { self.internal().vertical_alignment } - fn bounds(&self) -> Size { - self.internal().bounds - } - fn min_bounds(&self) -> Size { self.internal().min_bounds } diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs index 8bdf231d..73e56890 100644 --- a/renderer/src/lib.rs +++ b/renderer/src/lib.rs @@ -173,22 +173,6 @@ impl text::Renderer for Renderer { delegate!(self, renderer, renderer.default_size()) } - fn create_paragraph(&self, text: Text<'_, Self::Font>) -> Self::Paragraph { - delegate!(self, renderer, renderer.create_paragraph(text)) - } - - fn resize_paragraph( - &self, - paragraph: &mut Self::Paragraph, - new_bounds: Size, - ) { - delegate!( - self, - renderer, - renderer.resize_paragraph(paragraph, new_bounds) - ); - } - fn load_font(&mut self, bytes: Cow<'static, [u8]>) { delegate!(self, renderer, renderer.load_font(bytes)); } diff --git a/tiny_skia/src/backend.rs b/tiny_skia/src/backend.rs index c721d96e..72184c8a 100644 --- a/tiny_skia/src/backend.rs +++ b/tiny_skia/src/backend.rs @@ -1,6 +1,5 @@ use crate::core::{Background, Color, Gradient, Rectangle, Vector}; use crate::graphics::backend; -use crate::graphics::text; use crate::graphics::{Damage, Viewport}; use crate::primitive::{self, Primitive}; @@ -805,10 +804,6 @@ impl iced_graphics::Backend for Backend { } impl backend::Text for Backend { - fn font_system(&self) -> &text::FontSystem { - self.text_pipeline.font_system() - } - fn load_font(&mut self, font: Cow<'static, [u8]>) { self.text_pipeline.load_font(font); } diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index cb3ef54c..4f6e3941 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -2,8 +2,8 @@ use crate::core::alignment; use crate::core::text::{LineHeight, Shaping}; use crate::core::{Color, Font, Pixels, Point, Rectangle}; use crate::graphics::text::cache::{self, Cache}; +use crate::graphics::text::font_system; use crate::graphics::text::paragraph; -use crate::graphics::text::FontSystem; use rustc_hash::{FxHashMap, FxHashSet}; use std::borrow::Cow; @@ -12,7 +12,6 @@ use std::collections::hash_map; #[allow(missing_debug_implementations)] pub struct Pipeline { - font_system: FontSystem, glyph_cache: GlyphCache, cache: RefCell, } @@ -20,18 +19,16 @@ pub struct Pipeline { impl Pipeline { pub fn new() -> Self { Pipeline { - font_system: FontSystem::new(), glyph_cache: GlyphCache::new(), cache: RefCell::new(Cache::new()), } } - pub fn font_system(&self) -> &FontSystem { - &self.font_system - } - pub fn load_font(&mut self, bytes: Cow<'static, [u8]>) { - self.font_system.load_font(bytes); + font_system() + .write() + .expect("Write font system") + .load_font(bytes); self.cache = RefCell::new(Cache::new()); } @@ -51,8 +48,10 @@ impl Pipeline { return; }; + let mut font_system = font_system().write().expect("Write font system"); + draw( - self.font_system.get_mut(), + font_system.raw(), &mut self.glyph_cache, paragraph.buffer(), Rectangle::new(position, paragraph.min_bounds()), @@ -82,7 +81,9 @@ impl Pipeline { ) { let line_height = f32::from(line_height.to_absolute(size)); - let font_system = self.font_system.get_mut(); + let mut font_system = font_system().write().expect("Write font system"); + let font_system = font_system.raw(); + let key = cache::Key { bounds: bounds.size(), content, diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index 65c63f19..3d1755e1 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -1,5 +1,4 @@ use crate::core::{Color, Size}; -use crate::graphics; use crate::graphics::backend; use crate::graphics::color; use crate::graphics::{Transformation, Viewport}; @@ -310,10 +309,6 @@ impl crate::graphics::Backend for Backend { } impl backend::Text for Backend { - fn font_system(&self) -> &graphics::text::FontSystem { - self.text_pipeline.font_system() - } - fn load_font(&mut self, font: Cow<'static, [u8]>) { self.text_pipeline.load_font(font); } diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index bd4f3e06..5c9f4d7e 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -2,7 +2,7 @@ use crate::core::alignment; use crate::core::{Rectangle, Size}; use crate::graphics::color; use crate::graphics::text::cache::{self, Cache}; -use crate::graphics::text::{FontSystem, Paragraph}; +use crate::graphics::text::{font_system, Paragraph}; use crate::layer::Text; use std::borrow::Cow; @@ -10,7 +10,6 @@ use std::cell::RefCell; #[allow(missing_debug_implementations)] pub struct Pipeline { - font_system: FontSystem, renderers: Vec, atlas: glyphon::TextAtlas, prepare_layer: usize, @@ -24,7 +23,6 @@ impl Pipeline { format: wgpu::TextureFormat, ) -> Self { Pipeline { - font_system: FontSystem::new(), renderers: Vec::new(), atlas: glyphon::TextAtlas::with_color_mode( device, @@ -41,12 +39,11 @@ impl Pipeline { } } - pub fn font_system(&self) -> &FontSystem { - &self.font_system - } - pub fn load_font(&mut self, bytes: Cow<'static, [u8]>) { - self.font_system.load_font(bytes); + font_system() + .write() + .expect("Write font system") + .load_font(bytes); self.cache = RefCell::new(Cache::new()); } @@ -69,7 +66,9 @@ impl Pipeline { )); } - let font_system = self.font_system.get_mut(); + let mut font_system = font_system().write().expect("Write font system"); + let font_system = font_system.raw(); + let renderer = &mut self.renderers[self.prepare_layer]; let cache = self.cache.get_mut(); diff --git a/widget/src/pick_list.rs b/widget/src/pick_list.rs index 056a5e65..4b89d6ff 100644 --- a/widget/src/pick_list.rs +++ b/widget/src/pick_list.rs @@ -415,23 +415,17 @@ where for (option, paragraph) in options.iter().zip(state.options.iter_mut()) { let label = option.to_string(); - renderer.update_paragraph( - paragraph, - Text { - content: &label, - ..option_text - }, - ); + paragraph.update(Text { + content: &label, + ..option_text + }); } if let Some(placeholder) = placeholder { - renderer.update_paragraph( - &mut state.placeholder, - Text { - content: placeholder, - ..option_text - }, - ); + state.placeholder.update(Text { + content: placeholder, + ..option_text + }); } let max_width = match width { diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index 7d5ae806..f9a2d419 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -523,18 +523,15 @@ where shaping: text::Shaping::Advanced, }; - renderer.update_paragraph(&mut state.placeholder, placeholder_text); + state.placeholder.update(placeholder_text); let secure_value = is_secure.then(|| value.secure()); let value = secure_value.as_ref().unwrap_or(value); - renderer.update_paragraph( - &mut state.value, - Text { - content: &value.to_string(), - ..placeholder_text - }, - ); + state.value.update(Text { + content: &value.to_string(), + ..placeholder_text + }); if let Some(icon) = icon { let icon_text = Text { @@ -548,7 +545,7 @@ where shaping: text::Shaping::Advanced, }; - renderer.update_paragraph(&mut state.icon, icon_text); + state.icon.update(icon_text); let icon_width = state.icon.min_width(); @@ -1461,7 +1458,7 @@ fn replace_paragraph( let mut children_layout = layout.children(); let text_bounds = children_layout.next().unwrap().bounds(); - state.value = renderer.create_paragraph(Text { + state.value = Renderer::Paragraph::with_text(Text { font, line_height, content: &value.to_string(), From 6448429103c9c82b90040ac5a5a097bdded23f82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 12 Sep 2023 14:51:00 +0200 Subject: [PATCH 173/321] Draft `Editor` API and `TextEditor` widget --- core/src/layout/limits.rs | 2 +- core/src/lib.rs | 2 +- core/src/renderer/null.rs | 38 +++ core/src/text.rs | 123 ++++------ core/src/text/editor.rs | 68 ++++++ core/src/text/paragraph.rs | 59 +++++ examples/editor/Cargo.toml | 10 + examples/editor/src/main.rs | 49 ++++ graphics/src/damage.rs | 7 + graphics/src/primitive.rs | 10 + graphics/src/renderer.rs | 14 ++ graphics/src/text.rs | 2 + graphics/src/text/editor.rs | 327 ++++++++++++++++++++++++++ renderer/src/lib.rs | 19 +- style/src/lib.rs | 1 + style/src/text_editor.rs | 47 ++++ style/src/theme.rs | 113 +++++++++ tiny_skia/src/backend.rs | 25 ++ tiny_skia/src/text.rs | 32 +++ wgpu/src/layer.rs | 15 +- wgpu/src/layer/text.rs | 8 +- wgpu/src/text.rs | 28 ++- widget/src/helpers.rs | 15 ++ widget/src/lib.rs | 5 +- widget/src/text_editor.rs | 457 ++++++++++++++++++++++++++++++++++++ 25 files changed, 1384 insertions(+), 92 deletions(-) create mode 100644 core/src/text/editor.rs create mode 100644 core/src/text/paragraph.rs create mode 100644 examples/editor/Cargo.toml create mode 100644 examples/editor/src/main.rs create mode 100644 graphics/src/text/editor.rs create mode 100644 style/src/text_editor.rs create mode 100644 widget/src/text_editor.rs diff --git a/core/src/layout/limits.rs b/core/src/layout/limits.rs index 5d3c1556..39a3d98b 100644 --- a/core/src/layout/limits.rs +++ b/core/src/layout/limits.rs @@ -2,7 +2,7 @@ use crate::{Length, Padding, Size}; /// A set of size constraints for layouting. -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq)] pub struct Limits { min: Size, max: Size, diff --git a/core/src/lib.rs b/core/src/lib.rs index 1bfba7bd..13a9f06b 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -12,7 +12,7 @@ #![forbid(unsafe_code, rust_2018_idioms)] #![deny( missing_debug_implementations, - missing_docs, + // missing_docs, unused_results, clippy::extra_unused_lifetimes, clippy::from_over_into, diff --git a/core/src/renderer/null.rs b/core/src/renderer/null.rs index 0ffd3649..adf75969 100644 --- a/core/src/renderer/null.rs +++ b/core/src/renderer/null.rs @@ -43,6 +43,7 @@ impl Renderer for Null { impl text::Renderer for Null { type Font = Font; type Paragraph = (); + type Editor = (); const ICON_FONT: Font = Font::DEFAULT; const CHECKMARK_ICON: char = '0'; @@ -66,6 +67,14 @@ impl text::Renderer for Null { ) { } + fn fill_editor( + &mut self, + _editor: &Self::Editor, + _position: Point, + _color: Color, + ) { + } + fn fill_text( &mut self, _paragraph: Text<'_, Self::Font>, @@ -106,3 +115,32 @@ impl text::Paragraph for () { None } } + +impl text::Editor for () { + type Font = Font; + + fn with_text(_text: &str) -> Self {} + + fn cursor(&self) -> text::editor::Cursor { + text::editor::Cursor::Caret(Point::ORIGIN) + } + + fn perform(&mut self, _action: text::editor::Action) {} + + fn bounds(&self) -> Size { + Size::ZERO + } + + fn min_bounds(&self) -> Size { + Size::ZERO + } + + fn update( + &mut self, + _new_bounds: Size, + _new_font: Self::Font, + _new_size: Pixels, + _new_line_height: text::LineHeight, + ) { + } +} diff --git a/core/src/text.rs b/core/src/text.rs index ff85696e..5aacbcc5 100644 --- a/core/src/text.rs +++ b/core/src/text.rs @@ -1,4 +1,11 @@ //! Draw and interact with text. +mod paragraph; + +pub mod editor; + +pub use editor::Editor; +pub use paragraph::Paragraph; + use crate::alignment; use crate::{Color, Pixels, Point, Size}; @@ -126,6 +133,31 @@ impl Hit { } } +/// The difference detected in some text. +/// +/// You will obtain a [`Difference`] when you [`compare`] a [`Paragraph`] with some +/// [`Text`]. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Difference { + /// No difference. + /// + /// The text can be reused as it is! + None, + + /// A bounds difference. + /// + /// This normally means a relayout is necessary, but the shape of the text can + /// be reused. + Bounds, + + /// A shape difference. + /// + /// The contents, alignment, sizes, fonts, or any other essential attributes + /// of the shape of the text have changed. A complete reshape and relayout of + /// the text is necessary. + Shape, +} + /// A renderer capable of measuring and drawing [`Text`]. pub trait Renderer: crate::Renderer { /// The font type used. @@ -134,6 +166,9 @@ pub trait Renderer: crate::Renderer { /// The [`Paragraph`] of this [`Renderer`]. type Paragraph: Paragraph + 'static; + /// The [`Editor`] of this [`Renderer`]. + type Editor: Editor + 'static; + /// The icon font of the backend. const ICON_FONT: Self::Font; @@ -165,6 +200,13 @@ pub trait Renderer: crate::Renderer { color: Color, ); + fn fill_editor( + &mut self, + editor: &Self::Editor, + position: Point, + color: Color, + ); + /// Draws the given [`Text`] at the given position and with the given /// [`Color`]. fn fill_text( @@ -174,84 +216,3 @@ pub trait Renderer: crate::Renderer { color: Color, ); } - -/// A text paragraph. -pub trait Paragraph: Sized + Default { - /// The font of this [`Paragraph`]. - type Font: Copy + PartialEq; - - /// Creates a new [`Paragraph`] laid out with the given [`Text`]. - fn with_text(text: Text<'_, Self::Font>) -> Self; - - /// Lays out the [`Paragraph`] with some new boundaries. - fn resize(&mut self, new_bounds: Size); - - /// Compares the [`Paragraph`] with some desired [`Text`] and returns the - /// [`Difference`]. - fn compare(&self, text: Text<'_, Self::Font>) -> Difference; - - /// Returns the horizontal alignment of the [`Paragraph`]. - fn horizontal_alignment(&self) -> alignment::Horizontal; - - /// Returns the vertical alignment of the [`Paragraph`]. - fn vertical_alignment(&self) -> alignment::Vertical; - - /// Returns the minimum boundaries that can fit the contents of the - /// [`Paragraph`]. - fn min_bounds(&self) -> Size; - - /// Tests whether the provided point is within the boundaries of the - /// [`Paragraph`], returning information about the nearest character. - fn hit_test(&self, point: Point) -> Option; - - /// Returns the distance to the given grapheme index in the [`Paragraph`]. - fn grapheme_position(&self, line: usize, index: usize) -> Option; - - /// Updates the [`Paragraph`] to match the given [`Text`], if needed. - fn update(&mut self, text: Text<'_, Self::Font>) { - match self.compare(text) { - Difference::None => {} - Difference::Bounds => { - self.resize(text.bounds); - } - Difference::Shape => { - *self = Self::with_text(text); - } - } - } - - /// Returns the minimum width that can fit the contents of the [`Paragraph`]. - fn min_width(&self) -> f32 { - self.min_bounds().width - } - - /// Returns the minimum height that can fit the contents of the [`Paragraph`]. - fn min_height(&self) -> f32 { - self.min_bounds().height - } -} - -/// The difference detected in some text. -/// -/// You will obtain a [`Difference`] when you [`compare`] a [`Paragraph`] with some -/// [`Text`]. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Difference { - /// No difference. - /// - /// The text can be reused as it is! - None, - - /// A bounds difference. - /// - /// This normally means a relayout is necessary, but the shape of the text can - /// be reused. - Bounds, - - /// A shape difference. - /// - /// The contents, alignment, sizes, fonts, or any other essential attributes - /// of the shape of the text have changed. A complete reshape and relayout of - /// the text is necessary. - Shape, -} diff --git a/core/src/text/editor.rs b/core/src/text/editor.rs new file mode 100644 index 00000000..a4fd0ec1 --- /dev/null +++ b/core/src/text/editor.rs @@ -0,0 +1,68 @@ +use crate::text::LineHeight; +use crate::{Pixels, Point, Rectangle, Size}; + +pub trait Editor: Sized + Default { + type Font: Copy + PartialEq + Default; + + /// Creates a new [`Editor`] laid out with the given text. + fn with_text(text: &str) -> Self; + + fn cursor(&self) -> Cursor; + + fn perform(&mut self, action: Action); + + /// Returns the current boundaries of the [`Editor`]. + fn bounds(&self) -> Size; + + /// Returns the minimum boundaries that can fit the contents of the + /// [`Editor`]. + fn min_bounds(&self) -> Size; + + /// Updates the [`Editor`] with some new attributes. + fn update( + &mut self, + new_bounds: Size, + new_font: Self::Font, + new_size: Pixels, + new_line_height: LineHeight, + ); + + /// Returns the minimum width that can fit the contents of the [`Editor`]. + fn min_width(&self) -> f32 { + self.min_bounds().width + } + + /// Returns the minimum height that can fit the contents of the [`Editor`]. + fn min_height(&self) -> f32 { + self.min_bounds().height + } +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum Action { + MoveLeft, + MoveRight, + MoveUp, + MoveDown, + MoveLeftWord, + MoveRightWord, + MoveHome, + MoveEnd, + SelectWord, + SelectLine, + Insert(char), + Backspace, + Delete, + Click(Point), + Drag(Point), +} + +/// The cursor of an [`Editor`]. +#[derive(Debug, Clone)] +pub enum Cursor { + /// Cursor without a selection + Caret(Point), + + /// Cursor selecting a range of text + Selection(Vec), +} diff --git a/core/src/text/paragraph.rs b/core/src/text/paragraph.rs new file mode 100644 index 00000000..de1fb74d --- /dev/null +++ b/core/src/text/paragraph.rs @@ -0,0 +1,59 @@ +use crate::alignment; +use crate::text::{Difference, Hit, Text}; +use crate::{Point, Size}; + +/// A text paragraph. +pub trait Paragraph: Sized + Default { + /// The font of this [`Paragraph`]. + type Font: Copy + PartialEq; + + /// Creates a new [`Paragraph`] laid out with the given [`Text`]. + fn with_text(text: Text<'_, Self::Font>) -> Self; + + /// Lays out the [`Paragraph`] with some new boundaries. + fn resize(&mut self, new_bounds: Size); + + /// Compares the [`Paragraph`] with some desired [`Text`] and returns the + /// [`Difference`]. + fn compare(&self, text: Text<'_, Self::Font>) -> Difference; + + /// Returns the horizontal alignment of the [`Paragraph`]. + fn horizontal_alignment(&self) -> alignment::Horizontal; + + /// Returns the vertical alignment of the [`Paragraph`]. + fn vertical_alignment(&self) -> alignment::Vertical; + + /// Returns the minimum boundaries that can fit the contents of the + /// [`Paragraph`]. + fn min_bounds(&self) -> Size; + + /// Tests whether the provided point is within the boundaries of the + /// [`Paragraph`], returning information about the nearest character. + fn hit_test(&self, point: Point) -> Option; + + /// Returns the distance to the given grapheme index in the [`Paragraph`]. + fn grapheme_position(&self, line: usize, index: usize) -> Option; + + /// Updates the [`Paragraph`] to match the given [`Text`], if needed. + fn update(&mut self, text: Text<'_, Self::Font>) { + match self.compare(text) { + Difference::None => {} + Difference::Bounds => { + self.resize(text.bounds); + } + Difference::Shape => { + *self = Self::with_text(text); + } + } + } + + /// Returns the minimum width that can fit the contents of the [`Paragraph`]. + fn min_width(&self) -> f32 { + self.min_bounds().width + } + + /// Returns the minimum height that can fit the contents of the [`Paragraph`]. + fn min_height(&self) -> f32 { + self.min_bounds().height + } +} diff --git a/examples/editor/Cargo.toml b/examples/editor/Cargo.toml new file mode 100644 index 00000000..528cf23c --- /dev/null +++ b/examples/editor/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "editor" +version = "0.1.0" +authors = ["Héctor Ramón Jiménez "] +edition = "2021" +publish = false + +[dependencies] +iced.workspace = true +iced.features = ["debug"] \ No newline at end of file diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs new file mode 100644 index 00000000..50989ac5 --- /dev/null +++ b/examples/editor/src/main.rs @@ -0,0 +1,49 @@ +use iced::widget::{container, text_editor}; +use iced::{Element, Font, Sandbox, Settings}; + +pub fn main() -> iced::Result { + Editor::run(Settings::default()) +} + +struct Editor { + content: text_editor::Content, +} + +#[derive(Debug, Clone, Copy)] +enum Message { + Edit(text_editor::Action), +} + +impl Sandbox for Editor { + type Message = Message; + + fn new() -> Self { + Self { + content: text_editor::Content::with(include_str!( + "../../../README.md" + )), + } + } + + fn title(&self) -> String { + String::from("Editor - Iced") + } + + fn update(&mut self, message: Message) { + match message { + Message::Edit(action) => { + self.content.edit(action); + } + } + } + + fn view(&self) -> Element { + container( + text_editor(&self.content) + .on_edit(Message::Edit) + .font(Font::with_name("Hasklug Nerd Font Mono")), + ) + .padding(20) + .into() + } +} diff --git a/graphics/src/damage.rs b/graphics/src/damage.rs index 3276c2d4..595cc274 100644 --- a/graphics/src/damage.rs +++ b/graphics/src/damage.rs @@ -66,6 +66,13 @@ impl Damage for Primitive { bounds.expand(1.5) } + Self::Editor { + editor, position, .. + } => { + let bounds = Rectangle::new(*position, editor.bounds); + + bounds.expand(1.5) + } Self::Quad { bounds, .. } | Self::Image { bounds, .. } | Self::Svg { bounds, .. } => bounds.expand(1.0), diff --git a/graphics/src/primitive.rs b/graphics/src/primitive.rs index 8a97e6e7..ce0b734b 100644 --- a/graphics/src/primitive.rs +++ b/graphics/src/primitive.rs @@ -4,6 +4,7 @@ use crate::core::image; use crate::core::svg; use crate::core::text; use crate::core::{Background, Color, Font, Pixels, Point, Rectangle, Vector}; +use crate::text::editor; use crate::text::paragraph; use std::sync::Arc; @@ -41,6 +42,15 @@ pub enum Primitive { /// The color of the paragraph. color: Color, }, + /// An editor primitive + Editor { + /// The [`editor::Weak`] reference. + editor: editor::Weak, + /// The position of the paragraph. + position: Point, + /// The color of the paragraph. + color: Color, + }, /// A quad primitive Quad { /// The bounds of the quad diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index c5033d36..9b699183 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -141,6 +141,7 @@ where { type Font = Font; type Paragraph = text::Paragraph; + type Editor = text::Editor; const ICON_FONT: Font = Font::with_name("Iced-Icons"); const CHECKMARK_ICON: char = '\u{f00c}'; @@ -171,6 +172,19 @@ where }); } + fn fill_editor( + &mut self, + editor: &Self::Editor, + position: Point, + color: Color, + ) { + self.primitives.push(Primitive::Editor { + editor: editor.downgrade(), + position, + color, + }); + } + fn fill_text( &mut self, text: Text<'_, Self::Font>, diff --git a/graphics/src/text.rs b/graphics/src/text.rs index f5ccaf52..280e4f01 100644 --- a/graphics/src/text.rs +++ b/graphics/src/text.rs @@ -1,7 +1,9 @@ pub mod cache; +pub mod editor; pub mod paragraph; pub use cache::Cache; +pub use editor::Editor; pub use paragraph::Paragraph; pub use cosmic_text; diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs new file mode 100644 index 00000000..53f63fea --- /dev/null +++ b/graphics/src/text/editor.rs @@ -0,0 +1,327 @@ +use crate::core::text::editor::{self, Action, Cursor}; +use crate::core::text::LineHeight; +use crate::core::{Font, Pixels, Point, Size}; +use crate::text; + +use cosmic_text::Edit; + +use std::fmt; +use std::sync::{self, Arc}; + +#[derive(Debug, PartialEq)] +pub struct Editor(Option>); + +struct Internal { + editor: cosmic_text::Editor, + font: Font, + bounds: Size, + min_bounds: Size, + version: text::Version, +} + +impl Editor { + pub fn new() -> Self { + Self::default() + } + + pub fn buffer(&self) -> &cosmic_text::Buffer { + &self.internal().editor.buffer() + } + + pub fn downgrade(&self) -> Weak { + let editor = self.internal(); + + Weak { + raw: Arc::downgrade(editor), + bounds: editor.bounds, + } + } + + fn internal(&self) -> &Arc { + self.0 + .as_ref() + .expect("editor should always be initialized") + } +} + +impl editor::Editor for Editor { + type Font = Font; + + fn with_text(text: &str) -> Self { + let mut buffer = cosmic_text::Buffer::new_empty(cosmic_text::Metrics { + font_size: 1.0, + line_height: 1.0, + }); + + buffer.set_text( + text::font_system() + .write() + .expect("Write font system") + .raw(), + text, + cosmic_text::Attrs::new(), + cosmic_text::Shaping::Advanced, + ); + + Editor(Some(Arc::new(Internal { + editor: cosmic_text::Editor::new(buffer), + ..Default::default() + }))) + } + + fn cursor(&self) -> editor::Cursor { + let internal = self.internal(); + + match internal.editor.select_opt() { + Some(selection) => { + // TODO + Cursor::Selection(vec![]) + } + None => { + let cursor = internal.editor.cursor(); + let buffer = internal.editor.buffer(); + + let lines_before_cursor: usize = buffer + .lines + .iter() + .take(cursor.line) + .map(|line| { + line.layout_opt() + .as_ref() + .expect("Line layout should be cached") + .len() + }) + .sum(); + + let line = buffer + .lines + .get(cursor.line) + .expect("Cursor line should be present"); + + let layout = line + .layout_opt() + .as_ref() + .expect("Line layout should be cached"); + + let mut lines = layout.iter().enumerate(); + + let (subline, offset) = lines + .find_map(|(i, line)| { + let start = line + .glyphs + .first() + .map(|glyph| glyph.start) + .unwrap_or(0); + let end = line + .glyphs + .last() + .map(|glyph| glyph.end) + .unwrap_or(0); + + let is_cursor_after_start = start <= cursor.index; + + let is_cursor_before_end = match cursor.affinity { + cosmic_text::Affinity::Before => { + cursor.index <= end + } + cosmic_text::Affinity::After => cursor.index < end, + }; + + if is_cursor_after_start && is_cursor_before_end { + let offset = line + .glyphs + .iter() + .take_while(|glyph| cursor.index > glyph.start) + .map(|glyph| glyph.w) + .sum(); + + Some((i, offset)) + } else { + None + } + }) + .unwrap_or((0, 0.0)); + + let line_height = buffer.metrics().line_height; + + let scroll_offset = buffer.scroll() as f32 * line_height; + + Cursor::Caret(Point::new( + offset, + (lines_before_cursor + subline) as f32 * line_height + - scroll_offset, + )) + } + } + } + + fn perform(&mut self, action: Action) { + let mut font_system = + text::font_system().write().expect("Write font system"); + + let editor = + self.0.take().expect("Editor should always be initialized"); + + // TODO: Handle multiple strong references somehow + let mut internal = Arc::try_unwrap(editor) + .expect("Editor cannot have multiple strong references"); + + let editor = &mut internal.editor; + + let mut act = |action| editor.action(font_system.raw(), action); + + match action { + Action::MoveLeft => act(cosmic_text::Action::Left), + Action::MoveRight => act(cosmic_text::Action::Right), + Action::MoveUp => act(cosmic_text::Action::Up), + Action::MoveDown => act(cosmic_text::Action::Down), + Action::Insert(c) => act(cosmic_text::Action::Insert(c)), + Action::Backspace => act(cosmic_text::Action::Backspace), + Action::Delete => act(cosmic_text::Action::Delete), + Action::Click(position) => act(cosmic_text::Action::Click { + x: position.x as i32, + y: position.y as i32, + }), + Action::Drag(position) => act(cosmic_text::Action::Drag { + x: position.x as i32, + y: position.y as i32, + }), + _ => todo!(), + } + + editor.shape_as_needed(font_system.raw()); + + self.0 = Some(Arc::new(internal)); + } + + fn bounds(&self) -> Size { + self.internal().bounds + } + + fn min_bounds(&self) -> Size { + self.internal().min_bounds + } + + fn update( + &mut self, + new_bounds: Size, + new_font: Font, + new_size: Pixels, + new_line_height: LineHeight, + ) { + let editor = + self.0.take().expect("editor should always be initialized"); + + let mut internal = Arc::try_unwrap(editor) + .expect("Editor cannot have multiple strong references"); + + let mut font_system = + text::font_system().write().expect("Write font system"); + + let mut changed = false; + + if new_font != internal.font { + for line in internal.editor.buffer_mut().lines.iter_mut() { + let _ = line.set_attrs_list(cosmic_text::AttrsList::new( + text::to_attributes(new_font), + )); + } + + changed = true; + } + + let metrics = internal.editor.buffer().metrics(); + let new_line_height = new_line_height.to_absolute(new_size); + + if new_size.0 != metrics.font_size + || new_line_height.0 != metrics.line_height + { + internal.editor.buffer_mut().set_metrics( + font_system.raw(), + cosmic_text::Metrics::new(new_size.0, new_line_height.0), + ); + + changed = true; + } + + if new_bounds != internal.bounds { + internal.editor.buffer_mut().set_size( + font_system.raw(), + new_bounds.width, + new_bounds.height, + ); + + internal.bounds = new_bounds; + changed = true; + } + + if changed { + internal.min_bounds = text::measure(&internal.editor.buffer()); + } + + self.0 = Some(Arc::new(internal)); + } +} + +impl Default for Editor { + fn default() -> Self { + Self(Some(Arc::new(Internal::default()))) + } +} + +impl PartialEq for Internal { + fn eq(&self, other: &Self) -> bool { + self.font == other.font + && self.bounds == other.bounds + && self.min_bounds == other.min_bounds + && self.editor.buffer().metrics() == other.editor.buffer().metrics() + } +} + +impl Default for Internal { + fn default() -> Self { + Self { + editor: cosmic_text::Editor::new(cosmic_text::Buffer::new_empty( + cosmic_text::Metrics { + font_size: 1.0, + line_height: 1.0, + }, + )), + font: Font::default(), + bounds: Size::ZERO, + min_bounds: Size::ZERO, + version: text::Version::default(), + } + } +} + +impl fmt::Debug for Internal { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Internal") + .field("font", &self.font) + .field("bounds", &self.bounds) + .field("min_bounds", &self.min_bounds) + .finish() + } +} + +#[derive(Debug, Clone)] +pub struct Weak { + raw: sync::Weak, + pub bounds: Size, +} + +impl Weak { + pub fn upgrade(&self) -> Option { + self.raw.upgrade().map(Some).map(Editor) + } +} + +impl PartialEq for Weak { + fn eq(&self, other: &Self) -> bool { + match (self.raw.upgrade(), other.raw.upgrade()) { + (Some(p1), Some(p2)) => p1 == p2, + _ => false, + } + } +} diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs index 73e56890..6f044af6 100644 --- a/renderer/src/lib.rs +++ b/renderer/src/lib.rs @@ -32,6 +32,7 @@ use crate::core::text::{self, Text}; use crate::core::{ Background, Color, Font, Pixels, Point, Rectangle, Size, Vector, }; +use crate::graphics::text::Editor; use crate::graphics::text::Paragraph; use crate::graphics::Mesh; @@ -159,6 +160,7 @@ impl core::Renderer for Renderer { impl text::Renderer for Renderer { type Font = Font; type Paragraph = Paragraph; + type Editor = Editor; const ICON_FONT: Font = iced_tiny_skia::Renderer::::ICON_FONT; const CHECKMARK_ICON: char = iced_tiny_skia::Renderer::::CHECKMARK_ICON; @@ -179,14 +181,27 @@ impl text::Renderer for Renderer { fn fill_paragraph( &mut self, - text: &Self::Paragraph, + paragraph: &Self::Paragraph, position: Point, color: Color, ) { delegate!( self, renderer, - renderer.fill_paragraph(text, position, color) + renderer.fill_paragraph(paragraph, position, color) + ); + } + + fn fill_editor( + &mut self, + editor: &Self::Editor, + position: Point, + color: Color, + ) { + delegate!( + self, + renderer, + renderer.fill_editor(editor, position, color) ); } diff --git a/style/src/lib.rs b/style/src/lib.rs index 0c555ed8..7a97ac77 100644 --- a/style/src/lib.rs +++ b/style/src/lib.rs @@ -35,6 +35,7 @@ pub mod rule; pub mod scrollable; pub mod slider; pub mod svg; +pub mod text_editor; pub mod text_input; pub mod theme; pub mod toggler; diff --git a/style/src/text_editor.rs b/style/src/text_editor.rs new file mode 100644 index 00000000..45c9bad8 --- /dev/null +++ b/style/src/text_editor.rs @@ -0,0 +1,47 @@ +//! Change the appearance of a text editor. +use iced_core::{Background, BorderRadius, Color}; + +/// The appearance of a text input. +#[derive(Debug, Clone, Copy)] +pub struct Appearance { + /// The [`Background`] of the text input. + pub background: Background, + /// The border radius of the text input. + pub border_radius: BorderRadius, + /// The border width of the text input. + pub border_width: f32, + /// The border [`Color`] of the text input. + pub border_color: Color, +} + +/// A set of rules that dictate the style of a text input. +pub trait StyleSheet { + /// The supported style of the [`StyleSheet`]. + type Style: Default; + + /// Produces the style of an active text input. + fn active(&self, style: &Self::Style) -> Appearance; + + /// Produces the style of a focused text input. + fn focused(&self, style: &Self::Style) -> Appearance; + + /// Produces the [`Color`] of the placeholder of a text input. + fn placeholder_color(&self, style: &Self::Style) -> Color; + + /// Produces the [`Color`] of the value of a text input. + fn value_color(&self, style: &Self::Style) -> Color; + + /// Produces the [`Color`] of the value of a disabled text input. + fn disabled_color(&self, style: &Self::Style) -> Color; + + /// Produces the [`Color`] of the selection of a text input. + fn selection_color(&self, style: &Self::Style) -> Color; + + /// Produces the style of an hovered text input. + fn hovered(&self, style: &Self::Style) -> Appearance { + self.focused(style) + } + + /// Produces the style of a disabled text input. + fn disabled(&self, style: &Self::Style) -> Appearance; +} diff --git a/style/src/theme.rs b/style/src/theme.rs index 893d7202..a1501c01 100644 --- a/style/src/theme.rs +++ b/style/src/theme.rs @@ -17,6 +17,7 @@ use crate::rule; use crate::scrollable; use crate::slider; use crate::svg; +use crate::text_editor; use crate::text_input; use crate::toggler; @@ -1174,3 +1175,115 @@ impl text_input::StyleSheet for Theme { self.placeholder_color(style) } } + +/// The style of a text input. +#[derive(Default)] +pub enum TextEditor { + /// The default style. + #[default] + Default, + /// A custom style. + Custom(Box>), +} + +impl text_editor::StyleSheet for Theme { + type Style = TextEditor; + + fn active(&self, style: &Self::Style) -> text_editor::Appearance { + if let TextEditor::Custom(custom) = style { + return custom.active(self); + } + + let palette = self.extended_palette(); + + text_editor::Appearance { + background: palette.background.base.color.into(), + border_radius: 2.0.into(), + border_width: 1.0, + border_color: palette.background.strong.color, + } + } + + fn hovered(&self, style: &Self::Style) -> text_editor::Appearance { + if let TextEditor::Custom(custom) = style { + return custom.hovered(self); + } + + let palette = self.extended_palette(); + + text_editor::Appearance { + background: palette.background.base.color.into(), + border_radius: 2.0.into(), + border_width: 1.0, + border_color: palette.background.base.text, + } + } + + fn focused(&self, style: &Self::Style) -> text_editor::Appearance { + if let TextEditor::Custom(custom) = style { + return custom.focused(self); + } + + let palette = self.extended_palette(); + + text_editor::Appearance { + background: palette.background.base.color.into(), + border_radius: 2.0.into(), + border_width: 1.0, + border_color: palette.primary.strong.color, + } + } + + fn placeholder_color(&self, style: &Self::Style) -> Color { + if let TextEditor::Custom(custom) = style { + return custom.placeholder_color(self); + } + + let palette = self.extended_palette(); + + palette.background.strong.color + } + + fn value_color(&self, style: &Self::Style) -> Color { + if let TextEditor::Custom(custom) = style { + return custom.value_color(self); + } + + let palette = self.extended_palette(); + + palette.background.base.text + } + + fn selection_color(&self, style: &Self::Style) -> Color { + if let TextEditor::Custom(custom) = style { + return custom.selection_color(self); + } + + let palette = self.extended_palette(); + + palette.primary.weak.color + } + + fn disabled(&self, style: &Self::Style) -> text_editor::Appearance { + if let TextEditor::Custom(custom) = style { + return custom.disabled(self); + } + + let palette = self.extended_palette(); + + text_editor::Appearance { + background: palette.background.weak.color.into(), + border_radius: 2.0.into(), + border_width: 1.0, + border_color: palette.background.strong.color, + } + } + + fn disabled_color(&self, style: &Self::Style) -> Color { + if let TextEditor::Custom(custom) = style { + return custom.disabled_color(self); + } + + self.placeholder_color(style) + } +} diff --git a/tiny_skia/src/backend.rs b/tiny_skia/src/backend.rs index 72184c8a..5f66dff2 100644 --- a/tiny_skia/src/backend.rs +++ b/tiny_skia/src/backend.rs @@ -383,6 +383,31 @@ impl Backend { clip_mask, ); } + Primitive::Editor { + editor, + position, + color, + } => { + let physical_bounds = + (Rectangle::new(*position, editor.bounds) + translation) + * scale_factor; + + if !clip_bounds.intersects(&physical_bounds) { + return; + } + + let clip_mask = (!physical_bounds.is_within(&clip_bounds)) + .then_some(clip_mask as &_); + + self.text_pipeline.draw_editor( + editor, + *position + translation, + *color, + scale_factor, + pixels, + clip_mask, + ); + } Primitive::Text { content, bounds, diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index 4f6e3941..d055c749 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -2,6 +2,7 @@ use crate::core::alignment; use crate::core::text::{LineHeight, Shaping}; use crate::core::{Color, Font, Pixels, Point, Rectangle}; use crate::graphics::text::cache::{self, Cache}; +use crate::graphics::text::editor; use crate::graphics::text::font_system; use crate::graphics::text::paragraph; @@ -64,6 +65,37 @@ impl Pipeline { ); } + pub fn draw_editor( + &mut self, + editor: &editor::Weak, + position: Point, + color: Color, + scale_factor: f32, + pixels: &mut tiny_skia::PixmapMut<'_>, + clip_mask: Option<&tiny_skia::Mask>, + ) { + use crate::core::text::Editor as _; + + let Some(editor) = editor.upgrade() else { + return; + }; + + let mut font_system = font_system().write().expect("Write font system"); + + draw( + font_system.raw(), + &mut self.glyph_cache, + editor.buffer(), + Rectangle::new(position, editor.min_bounds()), + color, + alignment::Horizontal::Left, + alignment::Vertical::Top, + scale_factor, + pixels, + clip_mask, + ); + } + pub fn draw_cached( &mut self, content: &str, diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs index 7a5a0f7c..10b3332d 100644 --- a/wgpu/src/layer.rs +++ b/wgpu/src/layer.rs @@ -120,12 +120,25 @@ impl<'a> Layer<'a> { } => { let layer = &mut layers[current_layer]; - layer.text.push(Text::Managed { + layer.text.push(Text::Paragraph { paragraph: paragraph.clone(), position: *position + translation, color: *color, }); } + Primitive::Editor { + editor, + position, + color, + } => { + let layer = &mut layers[current_layer]; + + layer.text.push(Text::Editor { + editor: editor.clone(), + position: *position + translation, + color: *color, + }); + } Primitive::Text { content, bounds, diff --git a/wgpu/src/layer/text.rs b/wgpu/src/layer/text.rs index b61615d6..d46b39da 100644 --- a/wgpu/src/layer/text.rs +++ b/wgpu/src/layer/text.rs @@ -1,16 +1,22 @@ use crate::core::alignment; use crate::core::text; use crate::core::{Color, Font, Pixels, Point, Rectangle}; +use crate::graphics::text::editor; use crate::graphics::text::paragraph; /// A paragraph of text. #[derive(Debug, Clone)] pub enum Text<'a> { - Managed { + Paragraph { paragraph: paragraph::Weak, position: Point, color: Color, }, + Editor { + editor: editor::Weak, + position: Point, + color: Color, + }, Cached(Cached<'a>), } diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index 5c9f4d7e..397c38dd 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -2,7 +2,7 @@ use crate::core::alignment; use crate::core::{Rectangle, Size}; use crate::graphics::color; use crate::graphics::text::cache::{self, Cache}; -use crate::graphics::text::{font_system, Paragraph}; +use crate::graphics::text::{font_system, Editor, Paragraph}; use crate::layer::Text; use std::borrow::Cow; @@ -74,15 +74,19 @@ impl Pipeline { enum Allocation { Paragraph(Paragraph), + Editor(Editor), Cache(cache::KeyHash), } let allocations: Vec<_> = sections .iter() .map(|section| match section { - Text::Managed { paragraph, .. } => { + Text::Paragraph { paragraph, .. } => { paragraph.upgrade().map(Allocation::Paragraph) } + Text::Editor { editor, .. } => { + editor.upgrade().map(Allocation::Editor) + } Text::Cached(text) => { let (key, _) = cache.allocate( font_system, @@ -117,7 +121,7 @@ impl Pipeline { vertical_alignment, color, ) = match section { - Text::Managed { + Text::Paragraph { position, color, .. } => { use crate::core::text::Paragraph as _; @@ -135,6 +139,24 @@ impl Pipeline { *color, ) } + Text::Editor { + position, color, .. + } => { + use crate::core::text::Editor as _; + + let Some(Allocation::Editor(editor)) = allocation + else { + return None; + }; + + ( + editor.buffer(), + Rectangle::new(*position, editor.min_bounds()), + alignment::Horizontal::Left, + alignment::Vertical::Top, + *color, + ) + } Text::Cached(text) => { let Some(Allocation::Cache(key)) = allocation else { return None; diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs index 3c9c2b29..61541eac 100644 --- a/widget/src/helpers.rs +++ b/widget/src/helpers.rs @@ -16,6 +16,7 @@ use crate::runtime::Command; use crate::scrollable::{self, Scrollable}; use crate::slider::{self, Slider}; use crate::text::{self, Text}; +use crate::text_editor::{self, TextEditor}; use crate::text_input::{self, TextInput}; use crate::toggler::{self, Toggler}; use crate::tooltip::{self, Tooltip}; @@ -206,6 +207,20 @@ where TextInput::new(placeholder, value) } +/// Creates a new [`TextEditor`]. +/// +/// [`TextEditor`]: crate::TextEditor +pub fn text_editor<'a, Message, Renderer>( + content: &'a text_editor::Content, +) -> TextEditor<'a, Message, Renderer> +where + Message: Clone, + Renderer: core::text::Renderer, + Renderer::Theme: text_editor::StyleSheet, +{ + TextEditor::new(content) +} + /// Creates a new [`Slider`]. /// /// [`Slider`]: crate::Slider diff --git a/widget/src/lib.rs b/widget/src/lib.rs index 7e204171..f8e5e865 100644 --- a/widget/src/lib.rs +++ b/widget/src/lib.rs @@ -4,8 +4,8 @@ )] #![forbid(unsafe_code, rust_2018_idioms)] #![deny( - missing_debug_implementations, - missing_docs, + // missing_debug_implementations, + // missing_docs, unused_results, clippy::extra_unused_lifetimes, clippy::from_over_into, @@ -41,6 +41,7 @@ pub mod scrollable; pub mod slider; pub mod space; pub mod text; +pub mod text_editor; pub mod text_input; pub mod toggler; pub mod tooltip; diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs new file mode 100644 index 00000000..d09f2c3e --- /dev/null +++ b/widget/src/text_editor.rs @@ -0,0 +1,457 @@ +use crate::core::event::{self, Event}; +use crate::core::keyboard; +use crate::core::layout::{self, Layout}; +use crate::core::mouse; +use crate::core::renderer; +use crate::core::text::editor::{Cursor, Editor as _}; +use crate::core::text::{self, LineHeight}; +use crate::core::widget::{self, Widget}; +use crate::core::{ + Clipboard, Color, Element, Length, Padding, Pixels, Point, Rectangle, + Shell, Vector, +}; + +use std::cell::RefCell; + +pub use crate::style::text_editor::{Appearance, StyleSheet}; +pub use text::editor::Action; + +pub struct TextEditor<'a, Message, Renderer = crate::Renderer> +where + Renderer: text::Renderer, + Renderer::Theme: StyleSheet, +{ + content: &'a Content, + font: Option, + text_size: Option, + line_height: LineHeight, + width: Length, + height: Length, + padding: Padding, + style: ::Style, + on_edit: Option Message + 'a>>, +} + +impl<'a, Message, Renderer> TextEditor<'a, Message, Renderer> +where + Renderer: text::Renderer, + Renderer::Theme: StyleSheet, +{ + pub fn new(content: &'a Content) -> Self { + Self { + content, + font: None, + text_size: None, + line_height: LineHeight::default(), + width: Length::Fill, + height: Length::Fill, + padding: Padding::new(5.0), + style: Default::default(), + on_edit: None, + } + } + + pub fn on_edit(mut self, on_edit: impl Fn(Action) -> Message + 'a) -> Self { + self.on_edit = Some(Box::new(on_edit)); + self + } + + pub fn font(mut self, font: impl Into) -> Self { + self.font = Some(font.into()); + self + } + + pub fn padding(mut self, padding: impl Into) -> Self { + self.padding = padding.into(); + self + } +} + +pub struct Content(RefCell>) +where + R: text::Renderer; + +struct Internal +where + R: text::Renderer, +{ + editor: R::Editor, + is_dirty: bool, +} + +impl Content +where + R: text::Renderer, +{ + pub fn new() -> Self { + Self::with("") + } + + pub fn with(text: &str) -> Self { + Self(RefCell::new(Internal { + editor: R::Editor::with_text(text), + is_dirty: true, + })) + } + + pub fn edit(&mut self, action: Action) { + let internal = self.0.get_mut(); + + internal.editor.perform(action); + internal.is_dirty = true; + } +} + +impl Default for Content +where + Renderer: text::Renderer, +{ + fn default() -> Self { + Self::new() + } +} + +struct State { + is_focused: bool, + is_dragging: bool, + last_click: Option, +} + +impl<'a, Message, Renderer> Widget + for TextEditor<'a, Message, Renderer> +where + Renderer: text::Renderer, + Renderer::Theme: StyleSheet, +{ + fn tag(&self) -> widget::tree::Tag { + widget::tree::Tag::of::() + } + + fn state(&self) -> widget::tree::State { + widget::tree::State::new(State { + is_focused: false, + is_dragging: false, + last_click: None, + }) + } + + fn width(&self) -> Length { + self.width + } + + fn height(&self) -> Length { + self.height + } + + fn layout( + &self, + _tree: &mut widget::Tree, + renderer: &Renderer, + limits: &layout::Limits, + ) -> iced_renderer::core::layout::Node { + let mut internal = self.content.0.borrow_mut(); + + internal.editor.update( + limits.pad(self.padding).max(), + self.font.unwrap_or_else(|| renderer.default_font()), + self.text_size.unwrap_or_else(|| renderer.default_size()), + self.line_height, + ); + + layout::Node::new(limits.max()) + } + + fn on_event( + &mut self, + tree: &mut widget::Tree, + event: Event, + layout: Layout<'_>, + cursor: mouse::Cursor, + _renderer: &Renderer, + clipboard: &mut dyn Clipboard, + shell: &mut Shell<'_, Message>, + _viewport: &Rectangle, + ) -> event::Status { + let Some(on_edit) = self.on_edit.as_ref() else { + return event::Status::Ignored; + }; + + let state = tree.state.downcast_mut::(); + + let Some(update) = Update::from_event( + event, + state, + layout.bounds(), + self.padding, + cursor, + ) else { + return event::Status::Ignored; + }; + + match update { + Update::Focus { click, action } => { + state.is_focused = true; + state.last_click = Some(click); + shell.publish(on_edit(action)); + } + Update::Unfocus => { + state.is_focused = false; + state.is_dragging = false; + } + Update::Click { click, action } => { + state.last_click = Some(click); + state.is_dragging = true; + shell.publish(on_edit(action)); + } + Update::StopDragging => { + state.is_dragging = false; + } + Update::Edit(action) => { + shell.publish(on_edit(action)); + } + Update::Copy => {} + Update::Paste => if let Some(_contents) = clipboard.read() {}, + } + + event::Status::Captured + } + + fn draw( + &self, + tree: &widget::Tree, + renderer: &mut Renderer, + theme: &::Theme, + style: &renderer::Style, + layout: Layout<'_>, + cursor: mouse::Cursor, + _viewport: &Rectangle, + ) { + let bounds = layout.bounds(); + + let internal = self.content.0.borrow(); + let state = tree.state.downcast_ref::(); + + let is_disabled = self.on_edit.is_none(); + let is_mouse_over = cursor.is_over(bounds); + + let appearance = if is_disabled { + theme.disabled(&self.style) + } else if state.is_focused { + theme.focused(&self.style) + } else if is_mouse_over { + theme.hovered(&self.style) + } else { + theme.active(&self.style) + }; + + renderer.fill_quad( + renderer::Quad { + bounds, + border_radius: appearance.border_radius, + border_width: appearance.border_width, + border_color: appearance.border_color, + }, + appearance.background, + ); + + renderer.fill_editor( + &internal.editor, + bounds.position() + + Vector::new(self.padding.left, self.padding.top), + style.text_color, + ); + + if state.is_focused { + match internal.editor.cursor() { + Cursor::Caret(position) => { + renderer.fill_quad( + renderer::Quad { + bounds: Rectangle { + x: position.x + bounds.x + self.padding.left, + y: position.y + bounds.y + self.padding.top, + width: 1.0, + height: self + .line_height + .to_absolute(self.text_size.unwrap_or_else( + || renderer.default_size(), + )) + .into(), + }, + border_radius: 0.0.into(), + border_width: 0.0, + border_color: Color::TRANSPARENT, + }, + theme.value_color(&self.style), + ); + } + Cursor::Selection(ranges) => { + for range in ranges { + renderer.fill_quad( + renderer::Quad { + bounds: range + Vector::new(bounds.x, bounds.y), + border_radius: 0.0.into(), + border_width: 0.0, + border_color: Color::TRANSPARENT, + }, + theme.selection_color(&self.style), + ); + } + } + } + } + } + + fn mouse_interaction( + &self, + _state: &widget::Tree, + layout: Layout<'_>, + cursor: mouse::Cursor, + _viewport: &Rectangle, + _renderer: &Renderer, + ) -> mouse::Interaction { + let is_disabled = self.on_edit.is_none(); + + if cursor.is_over(layout.bounds()) { + if is_disabled { + mouse::Interaction::NotAllowed + } else { + mouse::Interaction::Text + } + } else { + mouse::Interaction::default() + } + } +} + +impl<'a, Message, Renderer> From> + for Element<'a, Message, Renderer> +where + Message: 'a, + Renderer: text::Renderer, + Renderer::Theme: StyleSheet, +{ + fn from(text_editor: TextEditor<'a, Message, Renderer>) -> Self { + Self::new(text_editor) + } +} + +enum Update { + Focus { click: mouse::Click, action: Action }, + Unfocus, + Click { click: mouse::Click, action: Action }, + StopDragging, + Edit(Action), + Copy, + Paste, +} + +impl Update { + fn from_event( + event: Event, + state: &State, + bounds: Rectangle, + padding: Padding, + cursor: mouse::Cursor, + ) -> Option { + match event { + Event::Mouse(event) => match event { + mouse::Event::ButtonPressed(mouse::Button::Left) => { + if let Some(cursor_position) = cursor.position_in(bounds) { + let cursor_position = cursor_position + - Vector::new(padding.top, padding.left); + + if state.is_focused { + let click = mouse::Click::new( + cursor_position, + state.last_click, + ); + + let action = match click.kind() { + mouse::click::Kind::Single => { + Action::Click(cursor_position) + } + mouse::click::Kind::Double => { + Action::SelectWord + } + mouse::click::Kind::Triple => { + Action::SelectLine + } + }; + + Some(Update::Click { click, action }) + } else { + Some(Update::Focus { + click: mouse::Click::new(cursor_position, None), + action: Action::Click(cursor_position), + }) + } + } else if state.is_focused { + Some(Update::Unfocus) + } else { + None + } + } + mouse::Event::ButtonReleased(mouse::Button::Left) => { + Some(Update::StopDragging) + } + mouse::Event::CursorMoved { .. } if state.is_dragging => { + let cursor_position = cursor.position_in(bounds)? + - Vector::new(padding.top, padding.left); + + Some(Self::Edit(Action::Drag(cursor_position))) + } + _ => None, + }, + Event::Keyboard(event) => match event { + keyboard::Event::KeyPressed { + key_code, + modifiers, + } if state.is_focused => match key_code { + keyboard::KeyCode::Left => { + if platform::is_jump_modifier_pressed(modifiers) { + Some(Self::Edit(Action::MoveLeftWord)) + } else { + Some(Self::Edit(Action::MoveLeft)) + } + } + keyboard::KeyCode::Right => { + if platform::is_jump_modifier_pressed(modifiers) { + Some(Self::Edit(Action::MoveRightWord)) + } else { + Some(Self::Edit(Action::MoveRight)) + } + } + keyboard::KeyCode::Up => Some(Self::Edit(Action::MoveUp)), + keyboard::KeyCode::Down => { + Some(Self::Edit(Action::MoveDown)) + } + keyboard::KeyCode::Backspace => { + Some(Self::Edit(Action::Backspace)) + } + keyboard::KeyCode::Delete => { + Some(Self::Edit(Action::Delete)) + } + keyboard::KeyCode::Escape => Some(Self::Unfocus), + _ => None, + }, + keyboard::Event::CharacterReceived(c) if state.is_focused => { + Some(Self::Edit(Action::Insert(c))) + } + _ => None, + }, + _ => None, + } + } +} + +mod platform { + use crate::core::keyboard; + + pub fn is_jump_modifier_pressed(modifiers: keyboard::Modifiers) -> bool { + if cfg!(target_os = "macos") { + modifiers.alt() + } else { + modifiers.control() + } + } +} From 1455911b636f19810e12eeb12a6eed11c5244cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 12 Sep 2023 15:03:23 +0200 Subject: [PATCH 174/321] Add `Enter` variant to `Action` in `text::Editor` --- core/src/text/editor.rs | 1 + graphics/src/text/editor.rs | 1 + widget/src/text_editor.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/core/src/text/editor.rs b/core/src/text/editor.rs index a4fd0ec1..09d4efde 100644 --- a/core/src/text/editor.rs +++ b/core/src/text/editor.rs @@ -51,6 +51,7 @@ pub enum Action { SelectWord, SelectLine, Insert(char), + Enter, Backspace, Delete, Click(Point), diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index 53f63fea..b4d6819f 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -176,6 +176,7 @@ impl editor::Editor for Editor { Action::MoveUp => act(cosmic_text::Action::Up), Action::MoveDown => act(cosmic_text::Action::Down), Action::Insert(c) => act(cosmic_text::Action::Insert(c)), + Action::Enter => act(cosmic_text::Action::Enter), Action::Backspace => act(cosmic_text::Action::Backspace), Action::Delete => act(cosmic_text::Action::Delete), Action::Click(position) => act(cosmic_text::Action::Click { diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index d09f2c3e..fcbd3dad 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -425,6 +425,7 @@ impl Update { keyboard::KeyCode::Down => { Some(Self::Edit(Action::MoveDown)) } + keyboard::KeyCode::Enter => Some(Self::Edit(Action::Enter)), keyboard::KeyCode::Backspace => { Some(Self::Edit(Action::Backspace)) } From abab1448576fbfa4717b65cdf1455debf44f2df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 12 Sep 2023 18:20:02 +0200 Subject: [PATCH 175/321] Return `Cursor::Caret` if selection matches cursor position in `Editor::cursor` --- graphics/src/text/editor.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index b4d6819f..7b0ddec1 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -72,15 +72,18 @@ impl editor::Editor for Editor { fn cursor(&self) -> editor::Cursor { let internal = self.internal(); + let cursor = internal.editor.cursor(); + let buffer = internal.editor.buffer(); + match internal.editor.select_opt() { - Some(selection) => { + Some(selection) + if cursor.line != selection.line + || cursor.index != selection.index => + { // TODO Cursor::Selection(vec![]) } - None => { - let cursor = internal.editor.cursor(); - let buffer = internal.editor.buffer(); - + _ => { let lines_before_cursor: usize = buffer .lines .iter() From 4389ab9865d13e17ce3c66223d7c149437be692b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 12 Sep 2023 18:27:30 +0200 Subject: [PATCH 176/321] Fix cursor offset with `Affinity::After` at the end of lines in `Editor::cursor` --- graphics/src/text/editor.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index 7b0ddec1..b39e9831 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -143,7 +143,10 @@ impl editor::Editor for Editor { None } }) - .unwrap_or((0, 0.0)); + .unwrap_or(( + 0, + layout.last().map(|line| line.w).unwrap_or(0.0), + )); let line_height = buffer.metrics().line_height; From a28ed825c1f48c61a655c5583eb207999e98f400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 12 Sep 2023 20:57:46 +0200 Subject: [PATCH 177/321] Fix subline positioning in `Editor::cursor` --- graphics/src/text/editor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index b39e9831..52a5d942 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -144,7 +144,7 @@ impl editor::Editor for Editor { } }) .unwrap_or(( - 0, + layout.len().saturating_sub(1), layout.last().map(|line| line.w).unwrap_or(0.0), )); From 40eb648f1e1e2ceb2782eddacbbc966f44de6961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 13 Sep 2023 15:00:33 +0200 Subject: [PATCH 178/321] Implement `Cursor::Selection` calculation in `Editor::cursor` --- graphics/src/text/editor.rs | 118 +++++++++++++++++++++++++++++++++++- widget/src/text_editor.rs | 6 +- 2 files changed, 120 insertions(+), 4 deletions(-) diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index 52a5d942..3544bde6 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -1,6 +1,6 @@ use crate::core::text::editor::{self, Action, Cursor}; use crate::core::text::LineHeight; -use crate::core::{Font, Pixels, Point, Size}; +use crate::core::{Font, Pixels, Point, Rectangle, Size, Vector}; use crate::text; use cosmic_text::Edit; @@ -80,8 +80,70 @@ impl editor::Editor for Editor { if cursor.line != selection.line || cursor.index != selection.index => { - // TODO - Cursor::Selection(vec![]) + let line_height = buffer.metrics().line_height; + let scroll_offset = buffer.scroll() as f32 * line_height; + + let (start, end) = if cursor < selection { + (cursor, selection) + } else { + (selection, cursor) + }; + + let visual_lines_before_start: usize = buffer + .lines + .iter() + .take(start.line) + .map(|line| { + line.layout_opt() + .as_ref() + .expect("Line layout should be cached") + .len() + }) + .sum(); + + let selected_lines = end.line - start.line + 1; + + let regions = buffer + .lines + .iter() + .skip(start.line) + .take(selected_lines) + .enumerate() + .flat_map(|(i, line)| { + highlight_line( + line, + if i == 0 { start.index } else { 0 }, + if i == selected_lines - 1 { + end.index + } else { + line.text().len() + }, + ) + }) + .enumerate() + .filter_map(|(visual_line, (x, width))| { + if width > 0.0 { + Some(Rectangle { + x, + width, + y: visual_line as f32 * line_height, + height: line_height, + }) + } else { + None + } + }) + .map(|region| { + region + + Vector::new( + 0.0, + visual_lines_before_start as f32 * line_height + + scroll_offset, + ) + }) + .collect(); + + Cursor::Selection(regions) } _ => { let lines_before_cursor: usize = buffer @@ -332,3 +394,53 @@ impl PartialEq for Weak { } } } + +fn highlight_line<'a>( + line: &'a cosmic_text::BufferLine, + from: usize, + to: usize, +) -> impl Iterator + 'a { + let layout = line + .layout_opt() + .as_ref() + .expect("Line layout should be cached"); + + layout.iter().map(move |visual_line| { + let start = visual_line + .glyphs + .first() + .map(|glyph| glyph.start) + .unwrap_or(0); + let end = visual_line + .glyphs + .last() + .map(|glyph| glyph.end) + .unwrap_or(0); + + let range = start.max(from)..end.min(to); + + if range.is_empty() { + (0.0, 0.0) + } else if range.start == start && range.end == end { + (0.0, visual_line.w) + } else { + let first_glyph = visual_line + .glyphs + .iter() + .position(|glyph| range.start <= glyph.start) + .unwrap_or(0); + + let mut glyphs = visual_line.glyphs.iter(); + + let x = + glyphs.by_ref().take(first_glyph).map(|glyph| glyph.w).sum(); + + let width: f32 = glyphs + .take_while(|glyph| range.end > glyph.start) + .map(|glyph| glyph.w) + .sum(); + + (x, width) + } + }) +} diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index fcbd3dad..12e66f68 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -288,7 +288,11 @@ where for range in ranges { renderer.fill_quad( renderer::Quad { - bounds: range + Vector::new(bounds.x, bounds.y), + bounds: range + + Vector::new( + bounds.x + self.padding.left, + bounds.y + self.padding.top, + ), border_radius: 0.0.into(), border_width: 0.0, border_color: Color::TRANSPARENT, From d502c9f16fc78bf6b5253152751480c5b5e5999c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 13 Sep 2023 15:16:47 +0200 Subject: [PATCH 179/321] Unify `Focus` and `Click` updates in `widget::text_editor` --- widget/src/text_editor.rs | 44 +++++++++++++-------------------------- 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index 12e66f68..a8069069 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -189,16 +189,12 @@ where }; match update { - Update::Focus { click, action } => { - state.is_focused = true; - state.last_click = Some(click); - shell.publish(on_edit(action)); - } Update::Unfocus => { state.is_focused = false; state.is_dragging = false; } Update::Click { click, action } => { + state.is_focused = true; state.last_click = Some(click); state.is_dragging = true; shell.publish(on_edit(action)); @@ -340,9 +336,8 @@ where } enum Update { - Focus { click: mouse::Click, action: Action }, - Unfocus, Click { click: mouse::Click, action: Action }, + Unfocus, StopDragging, Edit(Action), Copy, @@ -364,31 +359,20 @@ impl Update { let cursor_position = cursor_position - Vector::new(padding.top, padding.left); - if state.is_focused { - let click = mouse::Click::new( - cursor_position, - state.last_click, - ); + let click = mouse::Click::new( + cursor_position, + state.last_click, + ); - let action = match click.kind() { - mouse::click::Kind::Single => { - Action::Click(cursor_position) - } - mouse::click::Kind::Double => { - Action::SelectWord - } - mouse::click::Kind::Triple => { - Action::SelectLine - } - }; + let action = match click.kind() { + mouse::click::Kind::Single => { + Action::Click(cursor_position) + } + mouse::click::Kind::Double => Action::SelectWord, + mouse::click::Kind::Triple => Action::SelectLine, + }; - Some(Update::Click { click, action }) - } else { - Some(Update::Focus { - click: mouse::Click::new(cursor_position, None), - action: Action::Click(cursor_position), - }) - } + Some(Update::Click { click, action }) } else if state.is_focused { Some(Update::Unfocus) } else { From 52b36a9574f45138363a4bfc6394c6da03baa433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 13 Sep 2023 15:17:04 +0200 Subject: [PATCH 180/321] Use `Theme::Dark` in `editor` example --- examples/editor/src/main.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs index 50989ac5..2a70b34c 100644 --- a/examples/editor/src/main.rs +++ b/examples/editor/src/main.rs @@ -1,5 +1,5 @@ use iced::widget::{container, text_editor}; -use iced::{Element, Font, Sandbox, Settings}; +use iced::{Element, Font, Sandbox, Settings, Theme}; pub fn main() -> iced::Result { Editor::run(Settings::default()) @@ -46,4 +46,8 @@ impl Sandbox for Editor { .padding(20) .into() } + + fn theme(&self) -> Theme { + Theme::Dark + } } From f4c51a96d50953d5fb6e9eb62194f226e2cbfd3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 13 Sep 2023 16:11:43 +0200 Subject: [PATCH 181/321] Introduce `Motion` concept in `core::text::editor` --- core/src/text/editor.rs | 38 ++++++++++--- graphics/src/text/editor.rs | 106 ++++++++++++++++++++++++++++-------- widget/src/text_editor.rs | 79 +++++++++++++++------------ 3 files changed, 157 insertions(+), 66 deletions(-) diff --git a/core/src/text/editor.rs b/core/src/text/editor.rs index 09d4efde..f87e18f3 100644 --- a/core/src/text/editor.rs +++ b/core/src/text/editor.rs @@ -40,14 +40,8 @@ pub trait Editor: Sized + Default { #[derive(Debug, Clone, Copy, PartialEq)] pub enum Action { - MoveLeft, - MoveRight, - MoveUp, - MoveDown, - MoveLeftWord, - MoveRightWord, - MoveHome, - MoveEnd, + Move(Motion), + Select(Motion), SelectWord, SelectLine, Insert(char), @@ -58,6 +52,34 @@ pub enum Action { Drag(Point), } +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum Motion { + Left, + Right, + Up, + Down, + WordLeft, + WordRight, + Home, + End, + PageUp, + PageDown, + DocumentStart, + DocumentEnd, +} + +impl Motion { + pub fn widen(self) -> Self { + match self { + Self::Left => Self::WordLeft, + Self::Right => Self::WordRight, + Self::Home => Self::DocumentStart, + Self::End => Self::DocumentEnd, + _ => self, + } + } +} + /// The cursor of an [`Editor`]. #[derive(Debug, Clone)] pub enum Cursor { diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index 3544bde6..747f3a80 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -1,4 +1,4 @@ -use crate::core::text::editor::{self, Action, Cursor}; +use crate::core::text::editor::{self, Action, Cursor, Motion}; use crate::core::text::LineHeight; use crate::core::{Font, Pixels, Point, Rectangle, Size, Vector}; use crate::text; @@ -76,10 +76,7 @@ impl editor::Editor for Editor { let buffer = internal.editor.buffer(); match internal.editor.select_opt() { - Some(selection) - if cursor.line != selection.line - || cursor.index != selection.index => - { + Some(selection) => { let line_height = buffer.metrics().line_height; let scroll_offset = buffer.scroll() as f32 * line_height; @@ -236,26 +233,87 @@ impl editor::Editor for Editor { let editor = &mut internal.editor; - let mut act = |action| editor.action(font_system.raw(), action); - match action { - Action::MoveLeft => act(cosmic_text::Action::Left), - Action::MoveRight => act(cosmic_text::Action::Right), - Action::MoveUp => act(cosmic_text::Action::Up), - Action::MoveDown => act(cosmic_text::Action::Down), - Action::Insert(c) => act(cosmic_text::Action::Insert(c)), - Action::Enter => act(cosmic_text::Action::Enter), - Action::Backspace => act(cosmic_text::Action::Backspace), - Action::Delete => act(cosmic_text::Action::Delete), - Action::Click(position) => act(cosmic_text::Action::Click { - x: position.x as i32, - y: position.y as i32, - }), - Action::Drag(position) => act(cosmic_text::Action::Drag { - x: position.x as i32, - y: position.y as i32, - }), - _ => todo!(), + // Motion events + Action::Move(motion) => { + if let Some(_selection) = editor.select_opt() { + editor.set_select_opt(None); + } else { + editor.action( + font_system.raw(), + match motion { + Motion::Left => cosmic_text::Action::Left, + Motion::Right => cosmic_text::Action::Right, + Motion::Up => cosmic_text::Action::Up, + Motion::Down => cosmic_text::Action::Down, + Motion::WordLeft => cosmic_text::Action::LeftWord, + Motion::WordRight => cosmic_text::Action::RightWord, + Motion::Home => cosmic_text::Action::Home, + Motion::End => cosmic_text::Action::End, + Motion::PageUp => cosmic_text::Action::PageUp, + Motion::PageDown => cosmic_text::Action::PageDown, + Motion::DocumentStart => { + cosmic_text::Action::BufferStart + } + Motion::DocumentEnd => { + cosmic_text::Action::BufferEnd + } + }, + ); + } + } + + // Selection events + Action::Select(_motion) => todo!(), + Action::SelectWord => todo!(), + Action::SelectLine => todo!(), + + // Editing events + Action::Insert(c) => { + editor + .action(font_system.raw(), cosmic_text::Action::Insert(c)); + } + Action::Enter => { + editor.action(font_system.raw(), cosmic_text::Action::Enter); + } + Action::Backspace => { + editor + .action(font_system.raw(), cosmic_text::Action::Backspace); + } + Action::Delete => { + editor.action(font_system.raw(), cosmic_text::Action::Delete); + } + + // Mouse events + Action::Click(position) => { + editor.action( + font_system.raw(), + cosmic_text::Action::Click { + x: position.x as i32, + y: position.y as i32, + }, + ); + } + Action::Drag(position) => { + editor.action( + font_system.raw(), + cosmic_text::Action::Drag { + x: position.x as i32, + y: position.y as i32, + }, + ); + + // Deselect if selection matches cursor position + if let Some(selection) = editor.select_opt() { + let cursor = editor.cursor(); + + if cursor.line == selection.line + && cursor.index == selection.index + { + editor.set_select_opt(None); + } + } + } } editor.shape_as_needed(font_system.raw()); diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index a8069069..38c243bd 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -14,7 +14,7 @@ use crate::core::{ use std::cell::RefCell; pub use crate::style::text_editor::{Appearance, StyleSheet}; -pub use text::editor::Action; +pub use text::editor::{Action, Motion}; pub struct TextEditor<'a, Message, Renderer = crate::Renderer> where @@ -189,16 +189,16 @@ where }; match update { + Update::Click { click, action } => { + state.is_focused = true; + state.is_dragging = true; + state.last_click = Some(click); + shell.publish(on_edit(action)); + } Update::Unfocus => { state.is_focused = false; state.is_dragging = false; } - Update::Click { click, action } => { - state.is_focused = true; - state.last_click = Some(click); - state.is_dragging = true; - shell.publish(on_edit(action)); - } Update::StopDragging => { state.is_dragging = false; } @@ -352,6 +352,9 @@ impl Update { padding: Padding, cursor: mouse::Cursor, ) -> Option { + let edit = |action| Some(Update::Edit(action)); + let move_ = |motion| Some(Update::Edit(Action::Move(motion))); + match event { Event::Mouse(event) => match event { mouse::Event::ButtonPressed(mouse::Button::Left) => { @@ -386,7 +389,7 @@ impl Update { let cursor_position = cursor.position_in(bounds)? - Vector::new(padding.top, padding.left); - Some(Self::Edit(Action::Drag(cursor_position))) + edit(Action::Drag(cursor_position)) } _ => None, }, @@ -394,37 +397,31 @@ impl Update { keyboard::Event::KeyPressed { key_code, modifiers, - } if state.is_focused => match key_code { - keyboard::KeyCode::Left => { - if platform::is_jump_modifier_pressed(modifiers) { - Some(Self::Edit(Action::MoveLeftWord)) + } if state.is_focused => { + if let Some(motion) = motion(key_code) { + let motion = if modifiers.control() { + motion.widen() } else { - Some(Self::Edit(Action::MoveLeft)) - } - } - keyboard::KeyCode::Right => { - if platform::is_jump_modifier_pressed(modifiers) { - Some(Self::Edit(Action::MoveRightWord)) + motion + }; + + return edit(if modifiers.shift() { + Action::Select(motion) } else { - Some(Self::Edit(Action::MoveRight)) - } + Action::Move(motion) + }); } - keyboard::KeyCode::Up => Some(Self::Edit(Action::MoveUp)), - keyboard::KeyCode::Down => { - Some(Self::Edit(Action::MoveDown)) + + match key_code { + keyboard::KeyCode::Enter => edit(Action::Enter), + keyboard::KeyCode::Backspace => edit(Action::Backspace), + keyboard::KeyCode::Delete => edit(Action::Delete), + keyboard::KeyCode::Escape => Some(Self::Unfocus), + _ => None, } - keyboard::KeyCode::Enter => Some(Self::Edit(Action::Enter)), - keyboard::KeyCode::Backspace => { - Some(Self::Edit(Action::Backspace)) - } - keyboard::KeyCode::Delete => { - Some(Self::Edit(Action::Delete)) - } - keyboard::KeyCode::Escape => Some(Self::Unfocus), - _ => None, - }, + } keyboard::Event::CharacterReceived(c) if state.is_focused => { - Some(Self::Edit(Action::Insert(c))) + edit(Action::Insert(c)) } _ => None, }, @@ -433,6 +430,20 @@ impl Update { } } +fn motion(key_code: keyboard::KeyCode) -> Option { + match key_code { + keyboard::KeyCode::Left => Some(Motion::Left), + keyboard::KeyCode::Right => Some(Motion::Right), + keyboard::KeyCode::Up => Some(Motion::Up), + keyboard::KeyCode::Down => Some(Motion::Down), + keyboard::KeyCode::Home => Some(Motion::Home), + keyboard::KeyCode::End => Some(Motion::End), + keyboard::KeyCode::PageUp => Some(Motion::PageUp), + keyboard::KeyCode::PageDown => Some(Motion::PageDown), + _ => None, + } +} + mod platform { use crate::core::keyboard; From f14ef7a6069cf45ae11261d7d20df6a5d7870dde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 13 Sep 2023 16:31:56 +0200 Subject: [PATCH 182/321] Fix `clippy` lints --- graphics/src/text/editor.rs | 27 ++++++++++++++++++--------- widget/src/helpers.rs | 6 +++--- widget/src/text_editor.rs | 30 ++++++++++++++++++++---------- 3 files changed, 41 insertions(+), 22 deletions(-) diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index 747f3a80..d31ea390 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -25,7 +25,7 @@ impl Editor { } pub fn buffer(&self) -> &cosmic_text::Buffer { - &self.internal().editor.buffer() + self.internal().editor.buffer() } pub fn downgrade(&self) -> Weak { @@ -53,11 +53,11 @@ impl editor::Editor for Editor { line_height: 1.0, }); + let mut font_system = + text::font_system().write().expect("Write font system"); + buffer.set_text( - text::font_system() - .write() - .expect("Write font system") - .raw(), + font_system.raw(), text, cosmic_text::Attrs::new(), cosmic_text::Shaping::Advanced, @@ -65,6 +65,7 @@ impl editor::Editor for Editor { Editor(Some(Arc::new(Internal { editor: cosmic_text::Editor::new(buffer), + version: font_system.version(), ..Default::default() }))) } @@ -347,6 +348,14 @@ impl editor::Editor for Editor { let mut changed = false; + if font_system.version() != internal.version { + for line in internal.editor.buffer_mut().lines.iter_mut() { + line.reset(); + } + + changed = true; + } + if new_font != internal.font { for line in internal.editor.buffer_mut().lines.iter_mut() { let _ = line.set_attrs_list(cosmic_text::AttrsList::new( @@ -383,7 +392,7 @@ impl editor::Editor for Editor { } if changed { - internal.min_bounds = text::measure(&internal.editor.buffer()); + internal.min_bounds = text::measure(internal.editor.buffer()); } self.0 = Some(Arc::new(internal)); @@ -453,11 +462,11 @@ impl PartialEq for Weak { } } -fn highlight_line<'a>( - line: &'a cosmic_text::BufferLine, +fn highlight_line( + line: &cosmic_text::BufferLine, from: usize, to: usize, -) -> impl Iterator + 'a { +) -> impl Iterator + '_ { let layout = line .layout_opt() .as_ref() diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs index 61541eac..e3f31513 100644 --- a/widget/src/helpers.rs +++ b/widget/src/helpers.rs @@ -210,9 +210,9 @@ where /// Creates a new [`TextEditor`]. /// /// [`TextEditor`]: crate::TextEditor -pub fn text_editor<'a, Message, Renderer>( - content: &'a text_editor::Content, -) -> TextEditor<'a, Message, Renderer> +pub fn text_editor( + content: &text_editor::Content, +) -> TextEditor<'_, Message, Renderer> where Message: Clone, Renderer: core::text::Renderer, diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index 38c243bd..48de6409 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -7,8 +7,8 @@ use crate::core::text::editor::{Cursor, Editor as _}; use crate::core::text::{self, LineHeight}; use crate::core::widget::{self, Widget}; use crate::core::{ - Clipboard, Color, Element, Length, Padding, Pixels, Point, Rectangle, - Shell, Vector, + Clipboard, Color, Element, Length, Padding, Pixels, Rectangle, Shell, + Vector, }; use std::cell::RefCell; @@ -205,8 +205,12 @@ where Update::Edit(action) => { shell.publish(on_edit(action)); } - Update::Copy => {} - Update::Paste => if let Some(_contents) = clipboard.read() {}, + Update::Copy => todo!(), + Update::Paste => { + if let Some(_contents) = clipboard.read() { + todo!() + } + } } event::Status::Captured @@ -353,7 +357,6 @@ impl Update { cursor: mouse::Cursor, ) -> Option { let edit = |action| Some(Update::Edit(action)); - let move_ = |motion| Some(Update::Edit(Action::Move(motion))); match event { Event::Mouse(event) => match event { @@ -399,11 +402,12 @@ impl Update { modifiers, } if state.is_focused => { if let Some(motion) = motion(key_code) { - let motion = if modifiers.control() { - motion.widen() - } else { - motion - }; + let motion = + if platform::is_jump_modifier_pressed(modifiers) { + motion.widen() + } else { + motion + }; return edit(if modifiers.shift() { Action::Select(motion) @@ -417,6 +421,12 @@ impl Update { keyboard::KeyCode::Backspace => edit(Action::Backspace), keyboard::KeyCode::Delete => edit(Action::Delete), keyboard::KeyCode::Escape => Some(Self::Unfocus), + keyboard::KeyCode::C => Some(Self::Copy), + keyboard::KeyCode::V + if modifiers.command() && !modifiers.alt() => + { + Some(Self::Paste) + } _ => None, } } From c829b4b04e1274f157ea7bb3adf832c4c53ce3e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 13 Sep 2023 17:55:33 +0200 Subject: [PATCH 183/321] Fix unused import in `iced_renderer` --- renderer/src/lib.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs index 6f044af6..81f60886 100644 --- a/renderer/src/lib.rs +++ b/renderer/src/lib.rs @@ -29,9 +29,7 @@ pub use geometry::Geometry; use crate::core::renderer; use crate::core::text::{self, Text}; -use crate::core::{ - Background, Color, Font, Pixels, Point, Rectangle, Size, Vector, -}; +use crate::core::{Background, Color, Font, Pixels, Point, Rectangle, Vector}; use crate::graphics::text::Editor; use crate::graphics::text::Paragraph; use crate::graphics::Mesh; @@ -219,7 +217,10 @@ impl text::Renderer for Renderer { impl crate::core::image::Renderer for Renderer { type Handle = crate::core::image::Handle; - fn dimensions(&self, handle: &crate::core::image::Handle) -> Size { + fn dimensions( + &self, + handle: &crate::core::image::Handle, + ) -> core::Size { delegate!(self, renderer, renderer.dimensions(handle)) } @@ -230,7 +231,7 @@ impl crate::core::image::Renderer for Renderer { #[cfg(feature = "svg")] impl crate::core::svg::Renderer for Renderer { - fn dimensions(&self, handle: &crate::core::svg::Handle) -> Size { + fn dimensions(&self, handle: &crate::core::svg::Handle) -> core::Size { delegate!(self, renderer, renderer.dimensions(handle)) } From ab020383b9fd7f2cc15d145dd1a3c0870dc71d8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 14 Sep 2023 00:41:15 +0200 Subject: [PATCH 184/321] Fix scrolling offset for `Cursor::Selection` --- graphics/src/text/editor.rs | 74 ++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 43 deletions(-) diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index d31ea390..c0f8d9d5 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -1,6 +1,6 @@ use crate::core::text::editor::{self, Action, Cursor, Motion}; use crate::core::text::LineHeight; -use crate::core::{Font, Pixels, Point, Rectangle, Size, Vector}; +use crate::core::{Font, Pixels, Point, Rectangle, Size}; use crate::text; use cosmic_text::Edit; @@ -78,29 +78,18 @@ impl editor::Editor for Editor { match internal.editor.select_opt() { Some(selection) => { - let line_height = buffer.metrics().line_height; - let scroll_offset = buffer.scroll() as f32 * line_height; - let (start, end) = if cursor < selection { (cursor, selection) } else { (selection, cursor) }; - let visual_lines_before_start: usize = buffer - .lines - .iter() - .take(start.line) - .map(|line| { - line.layout_opt() - .as_ref() - .expect("Line layout should be cached") - .len() - }) - .sum(); - + let line_height = buffer.metrics().line_height; let selected_lines = end.line - start.line + 1; + let visual_lines_offset = + visual_lines_offset(start.line, buffer); + let regions = buffer .lines .iter() @@ -124,37 +113,24 @@ impl editor::Editor for Editor { Some(Rectangle { x, width, - y: visual_line as f32 * line_height, + y: (visual_line as i32 + visual_lines_offset) + as f32 + * line_height, height: line_height, }) } else { None } }) - .map(|region| { - region - + Vector::new( - 0.0, - visual_lines_before_start as f32 * line_height - + scroll_offset, - ) - }) .collect(); Cursor::Selection(regions) } _ => { - let lines_before_cursor: usize = buffer - .lines - .iter() - .take(cursor.line) - .map(|line| { - line.layout_opt() - .as_ref() - .expect("Line layout should be cached") - .len() - }) - .sum(); + let line_height = buffer.metrics().line_height; + + let visual_lines_offset = + visual_lines_offset(cursor.line, buffer); let line = buffer .lines @@ -168,7 +144,7 @@ impl editor::Editor for Editor { let mut lines = layout.iter().enumerate(); - let (subline, offset) = lines + let (visual_line, offset) = lines .find_map(|(i, line)| { let start = line .glyphs @@ -208,14 +184,10 @@ impl editor::Editor for Editor { layout.last().map(|line| line.w).unwrap_or(0.0), )); - let line_height = buffer.metrics().line_height; - - let scroll_offset = buffer.scroll() as f32 * line_height; - Cursor::Caret(Point::new( offset, - (lines_before_cursor + subline) as f32 * line_height - - scroll_offset, + (visual_lines_offset + visual_line as i32) as f32 + * line_height, )) } } @@ -511,3 +483,19 @@ fn highlight_line( } }) } + +fn visual_lines_offset(line: usize, buffer: &cosmic_text::Buffer) -> i32 { + let visual_lines_before_start: usize = buffer + .lines + .iter() + .take(line) + .map(|line| { + line.layout_opt() + .as_ref() + .expect("Line layout should be cached") + .len() + }) + .sum(); + + visual_lines_before_start as i32 - buffer.scroll() +} From e6c2db8a9312e3fe37f30f049d1fa497892f1a86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 14 Sep 2023 00:47:04 +0200 Subject: [PATCH 185/321] Fix `Cursor::Caret` position on lines that wrap on whitespace --- graphics/src/text/editor.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index c0f8d9d5..83d41c85 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -157,7 +157,7 @@ impl editor::Editor for Editor { .map(|glyph| glyph.end) .unwrap_or(0); - let is_cursor_after_start = start <= cursor.index; + let is_cursor_before_start = start > cursor.index; let is_cursor_before_end = match cursor.affinity { cosmic_text::Affinity::Before => { @@ -166,7 +166,17 @@ impl editor::Editor for Editor { cosmic_text::Affinity::After => cursor.index < end, }; - if is_cursor_after_start && is_cursor_before_end { + if is_cursor_before_start { + // Sometimes, the glyph we are looking for is right + // between lines. This can happen when a line wraps + // on a space. + // In that case, we can assume the cursor is at the + // end of the previous line. + // i is guaranteed to be > 0 because `start` is always + // 0 for the first line, so there is no way for the + // cursor to be before it. + Some((i - 1, layout[i - 1].w)) + } else if is_cursor_before_end { let offset = line .glyphs .iter() From b24b94d82778733ddae1b824d0d7690afcec3056 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 14 Sep 2023 14:18:49 +0200 Subject: [PATCH 186/321] Handle motions when a selection is present in `text::Editor` --- core/src/text/editor.rs | 23 ++++++++++++ graphics/src/text/editor.rs | 70 +++++++++++++++++++++++++------------ 2 files changed, 70 insertions(+), 23 deletions(-) diff --git a/core/src/text/editor.rs b/core/src/text/editor.rs index f87e18f3..3adfc61a 100644 --- a/core/src/text/editor.rs +++ b/core/src/text/editor.rs @@ -78,6 +78,29 @@ impl Motion { _ => self, } } + + pub fn direction(&self) -> Direction { + match self { + Self::Left + | Self::Up + | Self::WordLeft + | Self::Home + | Self::PageUp + | Self::DocumentStart => Direction::Left, + Self::Right + | Self::Down + | Self::WordRight + | Self::End + | Self::PageDown + | Self::DocumentEnd => Direction::Right, + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Direction { + Left, + Right, } /// The cursor of an [`Editor`]. diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index 83d41c85..d88bcd1d 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -1,4 +1,4 @@ -use crate::core::text::editor::{self, Action, Cursor, Motion}; +use crate::core::text::editor::{self, Action, Cursor, Direction, Motion}; use crate::core::text::LineHeight; use crate::core::{Font, Pixels, Point, Rectangle, Size}; use crate::text; @@ -219,30 +219,37 @@ impl editor::Editor for Editor { match action { // Motion events Action::Move(motion) => { - if let Some(_selection) = editor.select_opt() { + if let Some(selection) = editor.select_opt() { + let cursor = editor.cursor(); + + let (left, right) = if cursor < selection { + (cursor, selection) + } else { + (selection, cursor) + }; + editor.set_select_opt(None); + + match motion { + // These motions are performed as-is even when a selection + // is present + Motion::Home + | Motion::End + | Motion::DocumentStart + | Motion::DocumentEnd => { + editor.action( + font_system.raw(), + motion_to_action(motion), + ); + } + // Other motions simply move the cursor to one end of the selection + _ => editor.set_cursor(match motion.direction() { + Direction::Left => left, + Direction::Right => right, + }), + } } else { - editor.action( - font_system.raw(), - match motion { - Motion::Left => cosmic_text::Action::Left, - Motion::Right => cosmic_text::Action::Right, - Motion::Up => cosmic_text::Action::Up, - Motion::Down => cosmic_text::Action::Down, - Motion::WordLeft => cosmic_text::Action::LeftWord, - Motion::WordRight => cosmic_text::Action::RightWord, - Motion::Home => cosmic_text::Action::Home, - Motion::End => cosmic_text::Action::End, - Motion::PageUp => cosmic_text::Action::PageUp, - Motion::PageDown => cosmic_text::Action::PageDown, - Motion::DocumentStart => { - cosmic_text::Action::BufferStart - } - Motion::DocumentEnd => { - cosmic_text::Action::BufferEnd - } - }, - ); + editor.action(font_system.raw(), motion_to_action(motion)); } } @@ -509,3 +516,20 @@ fn visual_lines_offset(line: usize, buffer: &cosmic_text::Buffer) -> i32 { visual_lines_before_start as i32 - buffer.scroll() } + +fn motion_to_action(motion: Motion) -> cosmic_text::Action { + match motion { + Motion::Left => cosmic_text::Action::Left, + Motion::Right => cosmic_text::Action::Right, + Motion::Up => cosmic_text::Action::Up, + Motion::Down => cosmic_text::Action::Down, + Motion::WordLeft => cosmic_text::Action::LeftWord, + Motion::WordRight => cosmic_text::Action::RightWord, + Motion::Home => cosmic_text::Action::Home, + Motion::End => cosmic_text::Action::End, + Motion::PageUp => cosmic_text::Action::PageUp, + Motion::PageDown => cosmic_text::Action::PageDown, + Motion::DocumentStart => cosmic_text::Action::BufferStart, + Motion::DocumentEnd => cosmic_text::Action::BufferEnd, + } +} From edd591847599a3e47601646ce075cb5b71ea751b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 14 Sep 2023 14:25:46 +0200 Subject: [PATCH 187/321] Implement motion selection in `text::Editor` --- graphics/src/text/editor.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index d88bcd1d..c6b2abd5 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -254,7 +254,26 @@ impl editor::Editor for Editor { } // Selection events - Action::Select(_motion) => todo!(), + Action::Select(motion) => { + let cursor = editor.cursor(); + + if editor.select_opt().is_none() { + editor.set_select_opt(Some(cursor)); + } + + editor.action(font_system.raw(), motion_to_action(motion)); + + // Deselect if selection matches cursor position + if let Some(selection) = editor.select_opt() { + let cursor = editor.cursor(); + + if cursor.line == selection.line + && cursor.index == selection.index + { + editor.set_select_opt(None); + } + } + } Action::SelectWord => todo!(), Action::SelectLine => todo!(), From f7d66899f1ae087a87be5d084ec1ee9a03dd4ecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 14 Sep 2023 15:20:23 +0200 Subject: [PATCH 188/321] Implement `Action::SelectWord` in `text::Editor` --- graphics/Cargo.toml | 1 + graphics/src/text/editor.rs | 61 ++++++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml index 26bd1435..3165810b 100644 --- a/graphics/Cargo.toml +++ b/graphics/Cargo.toml @@ -34,6 +34,7 @@ raw-window-handle.workspace = true rustc-hash.workspace = true thiserror.workspace = true twox-hash.workspace = true +unicode-segmentation.workspace = true image.workspace = true image.optional = true diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index c6b2abd5..3fd2c4fe 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -274,7 +274,66 @@ impl editor::Editor for Editor { } } } - Action::SelectWord => todo!(), + Action::SelectWord => { + use unicode_segmentation::UnicodeSegmentation; + + let cursor = editor.cursor(); + + if let Some(line) = editor.buffer().lines.get(cursor.line) { + let (start, end) = + UnicodeSegmentation::unicode_word_indices(line.text()) + // Split words with dots + .flat_map(|(i, word)| { + word.split('.').scan(i, |current, word| { + let start = *current; + *current += word.len() + 1; + + Some((start, word)) + }) + }) + // Turn words into ranges + .map(|(i, word)| (i, i + word.len())) + // Find the word at cursor + .find(|&(start, end)| { + start <= cursor.index && cursor.index < end + }) + // Cursor is not in a word. Let's select its punctuation cluster. + .unwrap_or_else(|| { + let start = line.text()[..cursor.index] + .char_indices() + .rev() + .take_while(|(_, c)| { + c.is_ascii_punctuation() + }) + .map(|(i, _)| i) + .last() + .unwrap_or(cursor.index); + + let end = line.text()[cursor.index..] + .char_indices() + .skip_while(|(_, c)| { + c.is_ascii_punctuation() + }) + .map(|(i, _)| i + cursor.index) + .next() + .unwrap_or(cursor.index); + + (start, end) + }); + + if start != end { + editor.set_cursor(cosmic_text::Cursor { + index: start, + ..cursor + }); + + editor.set_select_opt(Some(cosmic_text::Cursor { + index: end, + ..cursor + })); + } + } + } Action::SelectLine => todo!(), // Editing events From 8cad1d682a306071f1f03bff4e70196adc946491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 14 Sep 2023 15:23:20 +0200 Subject: [PATCH 189/321] Implement `Action::SelectLine` in `text::Editor` --- graphics/src/text/editor.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index 3fd2c4fe..8eec94c9 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -334,7 +334,24 @@ impl editor::Editor for Editor { } } } - Action::SelectLine => todo!(), + Action::SelectLine => { + let cursor = editor.cursor(); + + if let Some(line_length) = editor + .buffer() + .lines + .get(cursor.line) + .map(|line| line.text().len()) + { + editor + .set_cursor(cosmic_text::Cursor { index: 0, ..cursor }); + + editor.set_select_opt(Some(cosmic_text::Cursor { + index: line_length, + ..cursor + })); + } + } // Editing events Action::Insert(c) => { From c7d02e24e6f8265c205a68bd97b2643d40ae30ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 14 Sep 2023 18:57:09 +0200 Subject: [PATCH 190/321] Remove `Editor::min_bounds` and use `bounds` instead --- core/src/renderer/null.rs | 4 ---- core/src/text/editor.rs | 14 -------------- graphics/src/text/editor.rs | 4 ---- tiny_skia/src/text.rs | 2 +- wgpu/src/text.rs | 2 +- 5 files changed, 2 insertions(+), 24 deletions(-) diff --git a/core/src/renderer/null.rs b/core/src/renderer/null.rs index adf75969..e714e492 100644 --- a/core/src/renderer/null.rs +++ b/core/src/renderer/null.rs @@ -131,10 +131,6 @@ impl text::Editor for () { Size::ZERO } - fn min_bounds(&self) -> Size { - Size::ZERO - } - fn update( &mut self, _new_bounds: Size, diff --git a/core/src/text/editor.rs b/core/src/text/editor.rs index 3adfc61a..56cda3ef 100644 --- a/core/src/text/editor.rs +++ b/core/src/text/editor.rs @@ -14,10 +14,6 @@ pub trait Editor: Sized + Default { /// Returns the current boundaries of the [`Editor`]. fn bounds(&self) -> Size; - /// Returns the minimum boundaries that can fit the contents of the - /// [`Editor`]. - fn min_bounds(&self) -> Size; - /// Updates the [`Editor`] with some new attributes. fn update( &mut self, @@ -26,16 +22,6 @@ pub trait Editor: Sized + Default { new_size: Pixels, new_line_height: LineHeight, ); - - /// Returns the minimum width that can fit the contents of the [`Editor`]. - fn min_width(&self) -> f32 { - self.min_bounds().width - } - - /// Returns the minimum height that can fit the contents of the [`Editor`]. - fn min_height(&self) -> f32 { - self.min_bounds().height - } } #[derive(Debug, Clone, Copy, PartialEq)] diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index 8eec94c9..6d9e9bb6 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -410,10 +410,6 @@ impl editor::Editor for Editor { self.internal().bounds } - fn min_bounds(&self) -> Size { - self.internal().min_bounds - } - fn update( &mut self, new_bounds: Size, diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index d055c749..96cfbf32 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -86,7 +86,7 @@ impl Pipeline { font_system.raw(), &mut self.glyph_cache, editor.buffer(), - Rectangle::new(position, editor.min_bounds()), + Rectangle::new(position, editor.bounds()), color, alignment::Horizontal::Left, alignment::Vertical::Top, diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index 397c38dd..581df0cb 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -151,7 +151,7 @@ impl Pipeline { ( editor.buffer(), - Rectangle::new(*position, editor.min_bounds()), + Rectangle::new(*position, editor.bounds()), alignment::Horizontal::Left, alignment::Vertical::Top, *color, From 3afac11784b9cedc7e6208e3bf1d0365e1f5e902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 14 Sep 2023 18:58:52 +0200 Subject: [PATCH 191/321] Remove `min_bounds` field in `graphics::text::Editor` --- graphics/src/text/editor.rs | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index 6d9e9bb6..07a2d72a 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -15,7 +15,6 @@ struct Internal { editor: cosmic_text::Editor, font: Font, bounds: Size, - min_bounds: Size, version: text::Version, } @@ -426,14 +425,10 @@ impl editor::Editor for Editor { let mut font_system = text::font_system().write().expect("Write font system"); - let mut changed = false; - if font_system.version() != internal.version { for line in internal.editor.buffer_mut().lines.iter_mut() { line.reset(); } - - changed = true; } if new_font != internal.font { @@ -442,8 +437,6 @@ impl editor::Editor for Editor { text::to_attributes(new_font), )); } - - changed = true; } let metrics = internal.editor.buffer().metrics(); @@ -456,8 +449,6 @@ impl editor::Editor for Editor { font_system.raw(), cosmic_text::Metrics::new(new_size.0, new_line_height.0), ); - - changed = true; } if new_bounds != internal.bounds { @@ -468,11 +459,6 @@ impl editor::Editor for Editor { ); internal.bounds = new_bounds; - changed = true; - } - - if changed { - internal.min_bounds = text::measure(internal.editor.buffer()); } self.0 = Some(Arc::new(internal)); @@ -489,7 +475,6 @@ impl PartialEq for Internal { fn eq(&self, other: &Self) -> bool { self.font == other.font && self.bounds == other.bounds - && self.min_bounds == other.min_bounds && self.editor.buffer().metrics() == other.editor.buffer().metrics() } } @@ -505,7 +490,6 @@ impl Default for Internal { )), font: Font::default(), bounds: Size::ZERO, - min_bounds: Size::ZERO, version: text::Version::default(), } } @@ -516,7 +500,6 @@ impl fmt::Debug for Internal { f.debug_struct("Internal") .field("font", &self.font) .field("bounds", &self.bounds) - .field("min_bounds", &self.min_bounds) .finish() } } From 8e6e37e0cee79a2f293abedd18a6a7249575bb63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 14 Sep 2023 19:05:50 +0200 Subject: [PATCH 192/321] Fix broken intra-doc links --- core/src/text.rs | 2 ++ widget/src/lib.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/core/src/text.rs b/core/src/text.rs index 5aacbcc5..90581fea 100644 --- a/core/src/text.rs +++ b/core/src/text.rs @@ -137,6 +137,8 @@ impl Hit { /// /// You will obtain a [`Difference`] when you [`compare`] a [`Paragraph`] with some /// [`Text`]. +/// +/// [`compare`]: Paragraph::compare #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Difference { /// No difference. diff --git a/widget/src/lib.rs b/widget/src/lib.rs index f8e5e865..4c318d75 100644 --- a/widget/src/lib.rs +++ b/widget/src/lib.rs @@ -93,6 +93,8 @@ pub use space::Space; #[doc(no_inline)] pub use text::Text; #[doc(no_inline)] +pub use text_editor::TextEditor; +#[doc(no_inline)] pub use text_input::TextInput; #[doc(no_inline)] pub use toggler::Toggler; From 2c782bbe7a048f6f091e15f68de29a846b9bb059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 14 Sep 2023 19:35:29 +0200 Subject: [PATCH 193/321] Fix width of horizontal scrollbar in `Scrollable` --- widget/src/scrollable.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index def28821..7b1d7a30 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -1399,8 +1399,8 @@ impl Scrollbars { // Need to adjust the width of the horizontal scrollbar if the vertical scrollbar // is present - let scrollbar_y_width = show_scrollbar_y - .map_or(0.0, |v| v.width.max(v.scroller_width) + v.margin); + let scrollbar_y_width = y_scrollbar + .map_or(0.0, |scrollbar| scrollbar.total_bounds.width); let total_scrollbar_height = width.max(scroller_width) + 2.0 * margin; @@ -1425,12 +1425,12 @@ impl Scrollbars { let ratio = bounds.width / content_bounds.width; // min width for easier grabbing with extra wide content - let scroller_length = (bounds.width * ratio).max(2.0); - let scroller_offset = translation.x * ratio; + let scroller_length = (scrollbar_bounds.width * ratio).max(2.0); + let scroller_offset = + translation.x * ratio * scrollbar_bounds.width / bounds.width; let scroller_bounds = Rectangle { - x: (scrollbar_bounds.x + scroller_offset - scrollbar_y_width) - .max(0.0), + x: (scrollbar_bounds.x + scroller_offset).max(0.0), y: bounds.y + bounds.height - total_scrollbar_height / 2.0 - scroller_width / 2.0, From bebb2b0252cba7af3641e28a12de2c6db46b8946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 14 Sep 2023 19:37:15 +0200 Subject: [PATCH 194/321] Fix styling of horizontal scrollbar in `scrollable` example --- examples/scrollable/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/scrollable/src/main.rs b/examples/scrollable/src/main.rs index 8c08d993..21e69284 100644 --- a/examples/scrollable/src/main.rs +++ b/examples/scrollable/src/main.rs @@ -389,12 +389,12 @@ impl scrollable::StyleSheet for ScrollbarCustomStyle { background: style .active(&theme::Scrollable::default()) .background, - border_radius: 0.0.into(), + border_radius: 2.0.into(), border_width: 0.0, border_color: Default::default(), scroller: Scroller { color: Color::from_rgb8(250, 85, 134), - border_radius: 0.0.into(), + border_radius: 2.0.into(), border_width: 0.0, border_color: Default::default(), }, From f7fc13d98c52a9260b1ab55394a0c3d2693318ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 14 Sep 2023 22:55:54 +0200 Subject: [PATCH 195/321] Fix `Copy` action being triggered without any modifiers --- widget/src/text_editor.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index 48de6409..114d35ef 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -421,7 +421,9 @@ impl Update { keyboard::KeyCode::Backspace => edit(Action::Backspace), keyboard::KeyCode::Delete => edit(Action::Delete), keyboard::KeyCode::Escape => Some(Self::Unfocus), - keyboard::KeyCode::C => Some(Self::Copy), + keyboard::KeyCode::C if modifiers.command() => { + Some(Self::Copy) + } keyboard::KeyCode::V if modifiers.command() && !modifiers.alt() => { From ed11b04f6054809ea55ec9b3f0bd221ac2caf9ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 14 Sep 2023 22:59:02 +0200 Subject: [PATCH 196/321] Fix `height` of vertical scroller in `Scrollbar` --- widget/src/scrollable.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index 7b1d7a30..f92e6223 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -1364,15 +1364,15 @@ impl Scrollbars { let ratio = bounds.height / content_bounds.height; // min height for easier grabbing with super tall content - let scroller_height = (bounds.height * ratio).max(2.0); - let scroller_offset = translation.y * ratio; + let scroller_height = (scrollbar_bounds.height * ratio).max(2.0); + let scroller_offset = + translation.y * ratio * scrollbar_bounds.height / bounds.height; let scroller_bounds = Rectangle { x: bounds.x + bounds.width - total_scrollbar_width / 2.0 - scroller_width / 2.0, - y: (scrollbar_bounds.y + scroller_offset - x_scrollbar_height) - .max(0.0), + y: (scrollbar_bounds.y + scroller_offset).max(0.0), width: scroller_width, height: scroller_height, }; From c6d0443627c22dcf1576303e5a426aa3622f1b7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 16 Sep 2023 15:27:25 +0200 Subject: [PATCH 197/321] Implement methods to query the contents of a `TextEditor` --- core/src/renderer/null.rs | 12 ++++++++++ core/src/text/editor.rs | 6 +++++ graphics/src/text/editor.rs | 41 +++++++++++++++++++++++++++++++ widget/src/text_editor.rs | 48 +++++++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+) diff --git a/core/src/renderer/null.rs b/core/src/renderer/null.rs index e714e492..01a52c7a 100644 --- a/core/src/renderer/null.rs +++ b/core/src/renderer/null.rs @@ -125,6 +125,18 @@ impl text::Editor for () { text::editor::Cursor::Caret(Point::ORIGIN) } + fn selection(&self) -> Option { + None + } + + fn line(&self, _index: usize) -> Option<&str> { + None + } + + fn line_count(&self) -> usize { + 0 + } + fn perform(&mut self, _action: text::editor::Action) {} fn bounds(&self) -> Size { diff --git a/core/src/text/editor.rs b/core/src/text/editor.rs index 56cda3ef..5532fac5 100644 --- a/core/src/text/editor.rs +++ b/core/src/text/editor.rs @@ -9,6 +9,12 @@ pub trait Editor: Sized + Default { fn cursor(&self) -> Cursor; + fn selection(&self) -> Option; + + fn line(&self, index: usize) -> Option<&str>; + + fn line_count(&self) -> usize; + fn perform(&mut self, action: Action); /// Returns the current boundaries of the [`Editor`]. diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index 07a2d72a..1e375a25 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -69,6 +69,47 @@ impl editor::Editor for Editor { }))) } + fn line(&self, index: usize) -> Option<&str> { + self.buffer() + .lines + .get(index) + .map(cosmic_text::BufferLine::text) + } + + fn line_count(&self) -> usize { + self.buffer().lines.len() + } + + fn selection(&self) -> Option { + let internal = self.internal(); + + let cursor = internal.editor.cursor(); + let selection = internal.editor.select_opt()?; + + let (start, end) = if cursor < selection { + (cursor, selection) + } else { + (selection, cursor) + }; + + Some( + internal.editor.buffer().lines[start.line..=end.line] + .iter() + .enumerate() + .map(|(i, line)| { + if i == 0 { + &line.text()[start.index..] + } else if i == end.line - start.line { + &line.text()[..end.index] + } else { + line.text() + } + }) + .collect::>() + .join("\n"), + ) + } + fn cursor(&self) -> editor::Cursor { let internal = self.internal(); diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index 114d35ef..ec7a6d1d 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -100,6 +100,54 @@ where internal.editor.perform(action); internal.is_dirty = true; } + + pub fn line_count(&self) -> usize { + self.0.borrow().editor.line_count() + } + + pub fn line( + &self, + index: usize, + ) -> Option + '_> { + std::cell::Ref::filter_map(self.0.borrow(), |internal| { + internal.editor.line(index) + }) + .ok() + } + + pub fn lines( + &self, + ) -> impl Iterator + '_> { + struct Lines<'a, Renderer: text::Renderer> { + internal: std::cell::Ref<'a, Internal>, + current: usize, + } + + impl<'a, Renderer: text::Renderer> Iterator for Lines<'a, Renderer> { + type Item = std::cell::Ref<'a, str>; + + fn next(&mut self) -> Option { + let line = std::cell::Ref::filter_map( + std::cell::Ref::clone(&self.internal), + |internal| internal.editor.line(self.current), + ) + .ok()?; + + self.current += 1; + + Some(line) + } + } + + Lines { + internal: self.0.borrow(), + current: 0, + } + } + + pub fn selection(&self) -> Option { + self.0.borrow().editor.selection() + } } impl Default for Content From d051f21597bb333ac10183aaa3214a292e9aa365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 16 Sep 2023 15:40:16 +0200 Subject: [PATCH 198/321] Implement `Copy` and `Paste` actions for `text::Editor` --- core/src/text/editor.rs | 5 ++++- examples/editor/src/main.rs | 2 +- graphics/src/text/editor.rs | 11 +++++++++++ widget/src/text_editor.rs | 11 ++++++++--- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/core/src/text/editor.rs b/core/src/text/editor.rs index 5532fac5..003557c1 100644 --- a/core/src/text/editor.rs +++ b/core/src/text/editor.rs @@ -1,6 +1,8 @@ use crate::text::LineHeight; use crate::{Pixels, Point, Rectangle, Size}; +use std::sync::Arc; + pub trait Editor: Sized + Default { type Font: Copy + PartialEq + Default; @@ -30,13 +32,14 @@ pub trait Editor: Sized + Default { ); } -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, PartialEq)] pub enum Action { Move(Motion), Select(Motion), SelectWord, SelectLine, Insert(char), + Paste(Arc), Enter, Backspace, Delete, diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs index 2a70b34c..11819c69 100644 --- a/examples/editor/src/main.rs +++ b/examples/editor/src/main.rs @@ -9,7 +9,7 @@ struct Editor { content: text_editor::Content, } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone)] enum Message { Edit(text_editor::Action), } diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index 1e375a25..1890cb82 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -398,6 +398,17 @@ impl editor::Editor for Editor { editor .action(font_system.raw(), cosmic_text::Action::Insert(c)); } + Action::Paste(text) => { + editor.insert_string(&text, None); + + // TODO: Fix cosmic-text + // Cursor should be marked as moved after `insert_string`. + let cursor = editor.cursor(); + + editor + .buffer_mut() + .shape_until_cursor(font_system.raw(), cursor); + } Action::Enter => { editor.action(font_system.raw(), cosmic_text::Action::Enter); } diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index ec7a6d1d..0bb6b7d3 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -12,6 +12,7 @@ use crate::core::{ }; use std::cell::RefCell; +use std::sync::Arc; pub use crate::style::text_editor::{Appearance, StyleSheet}; pub use text::editor::{Action, Motion}; @@ -253,10 +254,14 @@ where Update::Edit(action) => { shell.publish(on_edit(action)); } - Update::Copy => todo!(), + Update::Copy => { + if let Some(selection) = self.content.selection() { + clipboard.write(selection); + } + } Update::Paste => { - if let Some(_contents) = clipboard.read() { - todo!() + if let Some(contents) = clipboard.read() { + shell.publish(on_edit(Action::Paste(Arc::new(contents)))); } } } From c9dbccba468da683af2513535c40374da804aa60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 16 Sep 2023 16:27:02 +0200 Subject: [PATCH 199/321] Use fork of `cosmic-text` with some minor fixes --- Cargo.toml | 4 ++++ graphics/src/text/editor.rs | 36 +----------------------------------- 2 files changed, 5 insertions(+), 35 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index af74a3cf..f8dd5f14 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -151,3 +151,7 @@ wgpu = "0.17" winapi = "0.3" window_clipboard = "0.3" winit = { git = "https://github.com/iced-rs/winit.git", rev = "c52db2045d0a2f1b8d9923870de1d4ab1994146e", default-features = false } + +[patch.crates-io.cosmic-text] +git = "https://github.com/hecrj/cosmic-text.git" +rev = "cb83458e7d0b84ef37c5beb72dda5046d7d343a6" diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index 1890cb82..a828a3bc 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -81,33 +81,7 @@ impl editor::Editor for Editor { } fn selection(&self) -> Option { - let internal = self.internal(); - - let cursor = internal.editor.cursor(); - let selection = internal.editor.select_opt()?; - - let (start, end) = if cursor < selection { - (cursor, selection) - } else { - (selection, cursor) - }; - - Some( - internal.editor.buffer().lines[start.line..=end.line] - .iter() - .enumerate() - .map(|(i, line)| { - if i == 0 { - &line.text()[start.index..] - } else if i == end.line - start.line { - &line.text()[..end.index] - } else { - line.text() - } - }) - .collect::>() - .join("\n"), - ) + self.internal().editor.copy_selection() } fn cursor(&self) -> editor::Cursor { @@ -400,14 +374,6 @@ impl editor::Editor for Editor { } Action::Paste(text) => { editor.insert_string(&text, None); - - // TODO: Fix cosmic-text - // Cursor should be marked as moved after `insert_string`. - let cursor = editor.cursor(); - - editor - .buffer_mut() - .shape_until_cursor(font_system.raw(), cursor); } Action::Enter => { editor.action(font_system.raw(), cosmic_text::Action::Enter); From 45c5cfe5774ac99a6e1b1d1014418f68b21b41cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 16 Sep 2023 19:05:31 +0200 Subject: [PATCH 200/321] Avoid drag on double or triple click for now in `TextEditor` --- core/src/mouse/click.rs | 4 +++ widget/src/text_editor.rs | 52 +++++++++++++++++++++------------------ 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/core/src/mouse/click.rs b/core/src/mouse/click.rs index 4a7d796c..e8e5fb56 100644 --- a/core/src/mouse/click.rs +++ b/core/src/mouse/click.rs @@ -61,6 +61,10 @@ impl Click { self.kind } + pub fn position(&self) -> Point { + self.position + } + fn is_consecutive(&self, new_position: Point, time: Instant) -> bool { let duration = if time > self.time { Some(time - self.time) diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index 0bb6b7d3..68e3c656 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -162,8 +162,8 @@ where struct State { is_focused: bool, - is_dragging: bool, last_click: Option, + drag_click: Option, } impl<'a, Message, Renderer> Widget @@ -179,8 +179,8 @@ where fn state(&self) -> widget::tree::State { widget::tree::State::new(State { is_focused: false, - is_dragging: false, last_click: None, + drag_click: None, }) } @@ -238,18 +238,27 @@ where }; match update { - Update::Click { click, action } => { + Update::Click(click) => { + let action = match click.kind() { + mouse::click::Kind::Single => { + Action::Click(click.position()) + } + mouse::click::Kind::Double => Action::SelectWord, + mouse::click::Kind::Triple => Action::SelectLine, + }; + state.is_focused = true; - state.is_dragging = true; state.last_click = Some(click); + state.drag_click = Some(click.kind()); + shell.publish(on_edit(action)); } Update::Unfocus => { state.is_focused = false; - state.is_dragging = false; + state.drag_click = None; } - Update::StopDragging => { - state.is_dragging = false; + Update::Release => { + state.drag_click = None; } Update::Edit(action) => { shell.publish(on_edit(action)); @@ -393,9 +402,9 @@ where } enum Update { - Click { click: mouse::Click, action: Action }, + Click(mouse::Click), Unfocus, - StopDragging, + Release, Edit(Action), Copy, Paste, @@ -423,15 +432,7 @@ impl Update { state.last_click, ); - let action = match click.kind() { - mouse::click::Kind::Single => { - Action::Click(cursor_position) - } - mouse::click::Kind::Double => Action::SelectWord, - mouse::click::Kind::Triple => Action::SelectLine, - }; - - Some(Update::Click { click, action }) + Some(Update::Click(click)) } else if state.is_focused { Some(Update::Unfocus) } else { @@ -439,14 +440,17 @@ impl Update { } } mouse::Event::ButtonReleased(mouse::Button::Left) => { - Some(Update::StopDragging) + Some(Update::Release) } - mouse::Event::CursorMoved { .. } if state.is_dragging => { - let cursor_position = cursor.position_in(bounds)? - - Vector::new(padding.top, padding.left); + mouse::Event::CursorMoved { .. } => match state.drag_click { + Some(mouse::click::Kind::Single) => { + let cursor_position = cursor.position_in(bounds)? + - Vector::new(padding.top, padding.left); - edit(Action::Drag(cursor_position)) - } + edit(Action::Drag(cursor_position)) + } + _ => None, + }, _ => None, }, Event::Keyboard(event) => match event { From 723111bb0df486bffaedcaed0722b1793d65bfe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 16 Sep 2023 19:09:31 +0200 Subject: [PATCH 201/321] Remove unnecessary `into_iter` call in `graphics::text` --- graphics/src/text.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/graphics/src/text.rs b/graphics/src/text.rs index 280e4f01..b4aeb2be 100644 --- a/graphics/src/text.rs +++ b/graphics/src/text.rs @@ -21,12 +21,11 @@ pub fn font_system() -> &'static RwLock { FONT_SYSTEM.get_or_init(|| { RwLock::new(FontSystem { - raw: cosmic_text::FontSystem::new_with_fonts( - [cosmic_text::fontdb::Source::Binary(Arc::new( + raw: cosmic_text::FontSystem::new_with_fonts([ + cosmic_text::fontdb::Source::Binary(Arc::new( include_bytes!("../fonts/Iced-Icons.ttf").as_slice(), - ))] - .into_iter(), - ), + )), + ]), version: Version::default(), }) }) From 76dc82e8e8b5201ec10f8d00d851c1decf998583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 17 Sep 2023 15:29:14 +0200 Subject: [PATCH 202/321] Draft `Highlighter` API --- core/src/renderer/null.rs | 11 ++++++ core/src/text.rs | 2 ++ core/src/text/editor.rs | 9 +++++ core/src/text/highlighter.rs | 56 ++++++++++++++++++++++++++++++ graphics/src/text.rs | 8 ++++- graphics/src/text/editor.rs | 67 ++++++++++++++++++++++++++++++++++++ style/src/lib.rs | 2 +- style/src/text_editor.rs | 16 ++++++++- widget/src/helpers.rs | 2 +- widget/src/text_editor.rs | 64 ++++++++++++++++++++++++++-------- 10 files changed, 218 insertions(+), 19 deletions(-) create mode 100644 core/src/text/highlighter.rs diff --git a/core/src/renderer/null.rs b/core/src/renderer/null.rs index 01a52c7a..21597c8e 100644 --- a/core/src/renderer/null.rs +++ b/core/src/renderer/null.rs @@ -149,6 +149,17 @@ impl text::Editor for () { _new_font: Self::Font, _new_size: Pixels, _new_line_height: text::LineHeight, + _new_highlighter: &mut impl text::Highlighter, + ) { + } + + fn highlight( + &mut self, + _font: Self::Font, + _highlighter: &mut H, + _format_highlight: impl Fn( + &H::Highlight, + ) -> text::highlighter::Format, ) { } } diff --git a/core/src/text.rs b/core/src/text.rs index 90581fea..9b9c753c 100644 --- a/core/src/text.rs +++ b/core/src/text.rs @@ -2,8 +2,10 @@ mod paragraph; pub mod editor; +pub mod highlighter; pub use editor::Editor; +pub use highlighter::Highlighter; pub use paragraph::Paragraph; use crate::alignment; diff --git a/core/src/text/editor.rs b/core/src/text/editor.rs index 003557c1..0f439c8d 100644 --- a/core/src/text/editor.rs +++ b/core/src/text/editor.rs @@ -1,3 +1,4 @@ +use crate::text::highlighter::{self, Highlighter}; use crate::text::LineHeight; use crate::{Pixels, Point, Rectangle, Size}; @@ -29,6 +30,14 @@ pub trait Editor: Sized + Default { new_font: Self::Font, new_size: Pixels, new_line_height: LineHeight, + new_highlighter: &mut impl Highlighter, + ); + + fn highlight( + &mut self, + font: Self::Font, + highlighter: &mut H, + format_highlight: impl Fn(&H::Highlight) -> highlighter::Format, ); } diff --git a/core/src/text/highlighter.rs b/core/src/text/highlighter.rs new file mode 100644 index 00000000..1f9ac840 --- /dev/null +++ b/core/src/text/highlighter.rs @@ -0,0 +1,56 @@ +use crate::Color; + +use std::hash::Hash; +use std::ops::Range; + +pub trait Highlighter: Clone + 'static { + type Settings: Hash; + type Highlight; + + type Iterator<'a>: Iterator, Self::Highlight)> + where + Self: 'a; + + fn new(settings: &Self::Settings) -> Self; + + fn change_line(&mut self, line: usize); + + fn highlight_line(&mut self, line: &str) -> Self::Iterator<'_>; + + fn current_line(&self) -> usize; +} + +#[derive(Debug, Clone, Copy)] +pub struct Style { + pub color: Color, +} + +#[derive(Debug, Clone, Copy)] +pub struct PlainText; + +impl Highlighter for PlainText { + type Settings = (); + type Highlight = (); + + type Iterator<'a> = std::iter::Empty<(Range, Self::Highlight)>; + + fn new(_settings: &Self::Settings) -> Self { + Self + } + + fn change_line(&mut self, _line: usize) {} + + fn highlight_line(&mut self, _line: &str) -> Self::Iterator<'_> { + std::iter::empty() + } + + fn current_line(&self) -> usize { + usize::MAX + } +} + +#[derive(Debug, Clone, Copy)] +pub struct Format { + pub color: Option, + pub font: Option, +} diff --git a/graphics/src/text.rs b/graphics/src/text.rs index b4aeb2be..5fcfc699 100644 --- a/graphics/src/text.rs +++ b/graphics/src/text.rs @@ -10,7 +10,7 @@ pub use cosmic_text; use crate::core::font::{self, Font}; use crate::core::text::Shaping; -use crate::core::Size; +use crate::core::{Color, Size}; use once_cell::sync::OnceCell; use std::borrow::Cow; @@ -129,3 +129,9 @@ pub fn to_shaping(shaping: Shaping) -> cosmic_text::Shaping { Shaping::Advanced => cosmic_text::Shaping::Advanced, } } + +pub fn to_color(color: Color) -> cosmic_text::Color { + let [r, g, b, a] = color.into_rgba8(); + + cosmic_text::Color::rgba(r, g, b, a) +} diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index a828a3bc..901b4295 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -1,4 +1,5 @@ use crate::core::text::editor::{self, Action, Cursor, Direction, Motion}; +use crate::core::text::highlighter::{self, Highlighter}; use crate::core::text::LineHeight; use crate::core::{Font, Pixels, Point, Rectangle, Size}; use crate::text; @@ -15,6 +16,7 @@ struct Internal { editor: cosmic_text::Editor, font: Font, bounds: Size, + topmost_line_changed: Option, version: text::Version, } @@ -433,6 +435,7 @@ impl editor::Editor for Editor { new_font: Font, new_size: Pixels, new_line_height: LineHeight, + new_highlighter: &mut impl Highlighter, ) { let editor = self.0.take().expect("editor should always be initialized"); @@ -479,6 +482,69 @@ impl editor::Editor for Editor { internal.bounds = new_bounds; } + if let Some(topmost_line_changed) = internal.topmost_line_changed.take() + { + new_highlighter.change_line(topmost_line_changed); + } + + self.0 = Some(Arc::new(internal)); + } + + fn highlight( + &mut self, + font: Self::Font, + highlighter: &mut H, + format_highlight: impl Fn(&H::Highlight) -> highlighter::Format, + ) { + let internal = self.internal(); + + let scroll = internal.editor.buffer().scroll(); + let visible_lines = internal.editor.buffer().visible_lines(); + let last_visible_line = (scroll + visible_lines - 1) as usize; + + let current_line = highlighter.current_line(); + + if current_line > last_visible_line { + return; + } + + let editor = + self.0.take().expect("editor should always be initialized"); + + let mut internal = Arc::try_unwrap(editor) + .expect("Editor cannot have multiple strong references"); + + let mut font_system = + text::font_system().write().expect("Write font system"); + + let attributes = text::to_attributes(font); + + for line in &mut internal.editor.buffer_mut().lines + [current_line..=last_visible_line] + { + let mut list = cosmic_text::AttrsList::new(attributes); + + for (range, highlight) in highlighter.highlight_line(line.text()) { + let format = format_highlight(&highlight); + + list.add_span( + range, + cosmic_text::Attrs { + color_opt: format.color.map(text::to_color), + ..if let Some(font) = format.font { + text::to_attributes(font) + } else { + attributes + } + }, + ); + } + + let _ = line.set_attrs_list(list); + } + + internal.editor.shape_as_needed(font_system.raw()); + self.0 = Some(Arc::new(internal)); } } @@ -508,6 +574,7 @@ impl Default for Internal { )), font: Font::default(), bounds: Size::ZERO, + topmost_line_changed: None, version: text::Version::default(), } } diff --git a/style/src/lib.rs b/style/src/lib.rs index 7a97ac77..c9879f24 100644 --- a/style/src/lib.rs +++ b/style/src/lib.rs @@ -15,7 +15,7 @@ clippy::needless_borrow, clippy::new_without_default, clippy::useless_conversion, - missing_docs, + // missing_docs, unused_results, rustdoc::broken_intra_doc_links )] diff --git a/style/src/text_editor.rs b/style/src/text_editor.rs index 45c9bad8..f1c31287 100644 --- a/style/src/text_editor.rs +++ b/style/src/text_editor.rs @@ -1,5 +1,6 @@ //! Change the appearance of a text editor. -use iced_core::{Background, BorderRadius, Color}; +use crate::core::text::highlighter; +use crate::core::{self, Background, BorderRadius, Color}; /// The appearance of a text input. #[derive(Debug, Clone, Copy)] @@ -45,3 +46,16 @@ pub trait StyleSheet { /// Produces the style of a disabled text input. fn disabled(&self, style: &Self::Style) -> Appearance; } + +pub trait Highlight { + fn format(&self, theme: &Theme) -> highlighter::Format; +} + +impl Highlight for () { + fn format(&self, _theme: &Theme) -> highlighter::Format { + highlighter::Format { + color: None, + font: None, + } + } +} diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs index e3f31513..e0b58722 100644 --- a/widget/src/helpers.rs +++ b/widget/src/helpers.rs @@ -212,7 +212,7 @@ where /// [`TextEditor`]: crate::TextEditor pub fn text_editor( content: &text_editor::Content, -) -> TextEditor<'_, Message, Renderer> +) -> TextEditor<'_, core::text::highlighter::PlainText, Message, Renderer> where Message: Clone, Renderer: core::text::Renderer, diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index 68e3c656..b17e1156 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -4,6 +4,7 @@ use crate::core::layout::{self, Layout}; use crate::core::mouse; use crate::core::renderer; use crate::core::text::editor::{Cursor, Editor as _}; +use crate::core::text::highlighter::{self, Highlighter}; use crate::core::text::{self, LineHeight}; use crate::core::widget::{self, Widget}; use crate::core::{ @@ -12,13 +13,15 @@ use crate::core::{ }; use std::cell::RefCell; +use std::ops::DerefMut; use std::sync::Arc; -pub use crate::style::text_editor::{Appearance, StyleSheet}; +pub use crate::style::text_editor::{Appearance, Highlight, StyleSheet}; pub use text::editor::{Action, Motion}; -pub struct TextEditor<'a, Message, Renderer = crate::Renderer> +pub struct TextEditor<'a, Highlighter, Message, Renderer = crate::Renderer> where + Highlighter: text::Highlighter, Renderer: text::Renderer, Renderer::Theme: StyleSheet, { @@ -31,9 +34,11 @@ where padding: Padding, style: ::Style, on_edit: Option Message + 'a>>, + highlighter_settings: Highlighter::Settings, } -impl<'a, Message, Renderer> TextEditor<'a, Message, Renderer> +impl<'a, Message, Renderer> + TextEditor<'a, highlighter::PlainText, Message, Renderer> where Renderer: text::Renderer, Renderer::Theme: StyleSheet, @@ -49,9 +54,19 @@ where padding: Padding::new(5.0), style: Default::default(), on_edit: None, + highlighter_settings: (), } } +} +impl<'a, Highlighter, Message, Renderer> + TextEditor<'a, Highlighter, Message, Renderer> +where + Highlighter: text::Highlighter, + Highlighter::Highlight: Highlight, + Renderer: text::Renderer, + Renderer::Theme: StyleSheet, +{ pub fn on_edit(mut self, on_edit: impl Fn(Action) -> Message + 'a) -> Self { self.on_edit = Some(Box::new(on_edit)); self @@ -160,20 +175,23 @@ where } } -struct State { +struct State { is_focused: bool, last_click: Option, drag_click: Option, + highlighter: RefCell, } -impl<'a, Message, Renderer> Widget - for TextEditor<'a, Message, Renderer> +impl<'a, Highlighter, Message, Renderer> Widget + for TextEditor<'a, Highlighter, Message, Renderer> where + Highlighter: text::Highlighter, + Highlighter::Highlight: Highlight, Renderer: text::Renderer, Renderer::Theme: StyleSheet, { fn tag(&self) -> widget::tree::Tag { - widget::tree::Tag::of::() + widget::tree::Tag::of::>() } fn state(&self) -> widget::tree::State { @@ -181,6 +199,9 @@ where is_focused: false, last_click: None, drag_click: None, + highlighter: RefCell::new(Highlighter::new( + &self.highlighter_settings, + )), }) } @@ -194,17 +215,19 @@ where fn layout( &self, - _tree: &mut widget::Tree, + tree: &mut widget::Tree, renderer: &Renderer, limits: &layout::Limits, ) -> iced_renderer::core::layout::Node { let mut internal = self.content.0.borrow_mut(); + let state = tree.state.downcast_mut::>(); internal.editor.update( limits.pad(self.padding).max(), self.font.unwrap_or_else(|| renderer.default_font()), self.text_size.unwrap_or_else(|| renderer.default_size()), self.line_height, + state.highlighter.borrow_mut().deref_mut(), ); layout::Node::new(limits.max()) @@ -225,7 +248,7 @@ where return event::Status::Ignored; }; - let state = tree.state.downcast_mut::(); + let state = tree.state.downcast_mut::>(); let Some(update) = Update::from_event( event, @@ -290,8 +313,14 @@ where ) { let bounds = layout.bounds(); - let internal = self.content.0.borrow(); - let state = tree.state.downcast_ref::(); + let mut internal = self.content.0.borrow_mut(); + let state = tree.state.downcast_ref::>(); + + internal.editor.highlight( + self.font.unwrap_or_else(|| renderer.default_font()), + state.highlighter.borrow_mut().deref_mut(), + |highlight| highlight.format(theme), + ); let is_disabled = self.on_edit.is_none(); let is_mouse_over = cursor.is_over(bounds); @@ -389,14 +418,19 @@ where } } -impl<'a, Message, Renderer> From> +impl<'a, Highlighter, Message, Renderer> + From> for Element<'a, Message, Renderer> where + Highlighter: text::Highlighter, + Highlighter::Highlight: Highlight, Message: 'a, Renderer: text::Renderer, Renderer::Theme: StyleSheet, { - fn from(text_editor: TextEditor<'a, Message, Renderer>) -> Self { + fn from( + text_editor: TextEditor<'a, Highlighter, Message, Renderer>, + ) -> Self { Self::new(text_editor) } } @@ -411,9 +445,9 @@ enum Update { } impl Update { - fn from_event( + fn from_event( event: Event, - state: &State, + state: &State, bounds: Rectangle, padding: Padding, cursor: mouse::Cursor, From d3011992a76e83e12f74402c2ade616cdc7f1497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 17 Sep 2023 19:03:58 +0200 Subject: [PATCH 203/321] Implement basic syntax highlighting with `syntect` in `editor` example --- core/src/text/highlighter.rs | 2 +- examples/editor/Cargo.toml | 4 +- examples/editor/src/main.rs | 168 ++++++++++++++++++++++++++++++++++- graphics/src/text/editor.rs | 25 +++++- widget/src/text_editor.rs | 18 ++++ 5 files changed, 211 insertions(+), 6 deletions(-) diff --git a/core/src/text/highlighter.rs b/core/src/text/highlighter.rs index 1f9ac840..a929826f 100644 --- a/core/src/text/highlighter.rs +++ b/core/src/text/highlighter.rs @@ -3,7 +3,7 @@ use crate::Color; use std::hash::Hash; use std::ops::Range; -pub trait Highlighter: Clone + 'static { +pub trait Highlighter: 'static { type Settings: Hash; type Highlight; diff --git a/examples/editor/Cargo.toml b/examples/editor/Cargo.toml index 528cf23c..930ee592 100644 --- a/examples/editor/Cargo.toml +++ b/examples/editor/Cargo.toml @@ -7,4 +7,6 @@ publish = false [dependencies] iced.workspace = true -iced.features = ["debug"] \ No newline at end of file +iced.features = ["advanced", "debug"] + +syntect = "5.1" \ No newline at end of file diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs index 11819c69..a72feebc 100644 --- a/examples/editor/src/main.rs +++ b/examples/editor/src/main.rs @@ -1,6 +1,8 @@ use iced::widget::{container, text_editor}; use iced::{Element, Font, Sandbox, Settings, Theme}; +use highlighter::Highlighter; + pub fn main() -> iced::Result { Editor::run(Settings::default()) } @@ -41,7 +43,10 @@ impl Sandbox for Editor { container( text_editor(&self.content) .on_edit(Message::Edit) - .font(Font::with_name("Hasklug Nerd Font Mono")), + .font(Font::with_name("Hasklug Nerd Font Mono")) + .highlight::(highlighter::Settings { + token: String::from("md"), + }), ) .padding(20) .into() @@ -51,3 +56,164 @@ impl Sandbox for Editor { Theme::Dark } } + +mod highlighter { + use iced::advanced::text::highlighter; + use iced::widget::text_editor; + use iced::{Color, Font, Theme}; + + use std::ops::Range; + use syntect::highlighting; + use syntect::parsing; + + #[derive(Debug, Clone, Hash)] + pub struct Settings { + pub token: String, + } + + pub struct Highlight(highlighting::StyleModifier); + + impl text_editor::Highlight for Highlight { + fn format(&self, _theme: &Theme) -> highlighter::Format { + highlighter::Format { + color: self.0.foreground.map(|color| { + Color::from_rgba8( + color.r, + color.g, + color.b, + color.a as f32 / 255.0, + ) + }), + font: None, + } + } + } + + pub struct Highlighter { + syntaxes: parsing::SyntaxSet, + parser: parsing::ParseState, + stack: parsing::ScopeStack, + theme: highlighting::Theme, + token: String, + current_line: usize, + } + + impl highlighter::Highlighter for Highlighter { + type Settings = Settings; + type Highlight = Highlight; + + type Iterator<'a> = + Box, Self::Highlight)> + 'a>; + + fn new(settings: &Self::Settings) -> Self { + let syntaxes = parsing::SyntaxSet::load_defaults_nonewlines(); + + let syntax = syntaxes + .find_syntax_by_token(&settings.token) + .unwrap_or_else(|| syntaxes.find_syntax_plain_text()); + + let parser = parsing::ParseState::new(&syntax); + let stack = parsing::ScopeStack::new(); + + let theme = highlighting::ThemeSet::load_defaults() + .themes + .remove("base16-mocha.dark") + .unwrap(); + + Highlighter { + syntaxes, + parser, + stack, + theme, + token: settings.token.clone(), + current_line: 0, + } + } + + fn change_line(&mut self, _line: usize) { + // TODO: Caching + let syntax = self + .syntaxes + .find_syntax_by_token(&self.token) + .unwrap_or_else(|| self.syntaxes.find_syntax_plain_text()); + + self.parser = parsing::ParseState::new(&syntax); + self.stack = parsing::ScopeStack::new(); + self.current_line = 0; + } + + fn highlight_line(&mut self, line: &str) -> Self::Iterator<'_> { + self.current_line += 1; + + let ops = self + .parser + .parse_line(line, &self.syntaxes) + .unwrap_or_default(); + + Box::new( + ScopeRangeIterator { + ops, + line_length: line.len(), + index: 0, + last_str_index: 0, + } + .filter_map(move |(range, scope)| { + let highlighter = + highlighting::Highlighter::new(&self.theme); + let _ = self.stack.apply(&scope); + + if range.is_empty() { + None + } else { + Some(( + range, + Highlight( + highlighter + .style_mod_for_stack(&self.stack.scopes), + ), + )) + } + }), + ) + } + + fn current_line(&self) -> usize { + self.current_line + } + } + + pub struct ScopeRangeIterator { + ops: Vec<(usize, parsing::ScopeStackOp)>, + line_length: usize, + index: usize, + last_str_index: usize, + } + + impl Iterator for ScopeRangeIterator { + type Item = (std::ops::Range, parsing::ScopeStackOp); + + fn next(&mut self) -> Option { + if self.index > self.ops.len() { + return None; + } + + let next_str_i = if self.index == self.ops.len() { + self.line_length + } else { + self.ops[self.index].0 + }; + + let range = self.last_str_index..next_str_i; + self.last_str_index = next_str_i; + + let op = if self.index == 0 { + parsing::ScopeStackOp::Noop + } else { + self.ops[self.index - 1].1.clone() + }; + + self.index += 1; + Some((range, op)) + } + } +} diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index 901b4295..58fcc3dc 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -447,17 +447,26 @@ impl editor::Editor for Editor { text::font_system().write().expect("Write font system"); if font_system.version() != internal.version { + log::trace!("Updating `FontSystem` of `Editor`..."); + for line in internal.editor.buffer_mut().lines.iter_mut() { line.reset(); } } if new_font != internal.font { + log::trace!("Updating font of `Editor`..."); + for line in internal.editor.buffer_mut().lines.iter_mut() { let _ = line.set_attrs_list(cosmic_text::AttrsList::new( text::to_attributes(new_font), )); } + + internal.font = new_font; + internal.topmost_line_changed = Some(0); + + internal.editor.shape_as_needed(font_system.raw()); } let metrics = internal.editor.buffer().metrics(); @@ -466,6 +475,8 @@ impl editor::Editor for Editor { if new_size.0 != metrics.font_size || new_line_height.0 != metrics.line_height { + log::trace!("Updating `Metrics` of `Editor`..."); + internal.editor.buffer_mut().set_metrics( font_system.raw(), cosmic_text::Metrics::new(new_size.0, new_line_height.0), @@ -473,6 +484,8 @@ impl editor::Editor for Editor { } if new_bounds != internal.bounds { + log::trace!("Updating size of `Editor`..."); + internal.editor.buffer_mut().set_size( font_system.raw(), new_bounds.width, @@ -484,6 +497,10 @@ impl editor::Editor for Editor { if let Some(topmost_line_changed) = internal.topmost_line_changed.take() { + log::trace!( + "Notifying highlighter of line change: {topmost_line_changed}" + ); + new_highlighter.change_line(topmost_line_changed); } @@ -497,10 +514,12 @@ impl editor::Editor for Editor { format_highlight: impl Fn(&H::Highlight) -> highlighter::Format, ) { let internal = self.internal(); + let buffer = internal.editor.buffer(); - let scroll = internal.editor.buffer().scroll(); - let visible_lines = internal.editor.buffer().visible_lines(); - let last_visible_line = (scroll + visible_lines - 1) as usize; + let scroll = buffer.scroll(); + let visible_lines = buffer.visible_lines(); + let last_visible_line = + ((scroll + visible_lines) as usize).min(buffer.lines.len()) - 1; let current_line = highlighter.current_line(); diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index b17e1156..03adbb59 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -81,6 +81,24 @@ where self.padding = padding.into(); self } + + pub fn highlight( + self, + settings: H::Settings, + ) -> TextEditor<'a, H, Message, Renderer> { + TextEditor { + content: self.content, + font: self.font, + text_size: self.text_size, + line_height: self.line_height, + width: self.width, + height: self.height, + padding: self.padding, + style: self.style, + on_edit: self.on_edit, + highlighter_settings: settings, + } + } } pub struct Content(RefCell>) From 23d00445ff1225b3e5ca99cb27966143cda8a2ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 17 Sep 2023 19:06:20 +0200 Subject: [PATCH 204/321] Use `saturating_sub` for `last_visible_line` in `text::Editor` --- graphics/src/text/editor.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index 58fcc3dc..fbae287e 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -518,8 +518,9 @@ impl editor::Editor for Editor { let scroll = buffer.scroll(); let visible_lines = buffer.visible_lines(); - let last_visible_line = - ((scroll + visible_lines) as usize).min(buffer.lines.len()) - 1; + let last_visible_line = ((scroll + visible_lines) as usize) + .min(buffer.lines.len()) + .saturating_sub(1); let current_line = highlighter.current_line(); From 2897986f2ded7318894a52572bec3d62754ebfaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 17 Sep 2023 19:27:51 +0200 Subject: [PATCH 205/321] Notify `Highlighter` of topmost line change --- core/src/text/editor.rs | 9 ++++-- graphics/src/text/editor.rs | 58 +++++++++++++++++++++++++------------ widget/src/text_editor.rs | 25 +++++++++------- 3 files changed, 61 insertions(+), 31 deletions(-) diff --git a/core/src/text/editor.rs b/core/src/text/editor.rs index 0f439c8d..2144715f 100644 --- a/core/src/text/editor.rs +++ b/core/src/text/editor.rs @@ -47,13 +47,18 @@ pub enum Action { Select(Motion), SelectWord, SelectLine, + Edit(Edit), + Click(Point), + Drag(Point), +} + +#[derive(Debug, Clone, PartialEq)] +pub enum Edit { Insert(char), Paste(Arc), Enter, Backspace, Delete, - Click(Point), - Drag(Point), } #[derive(Debug, Clone, Copy, PartialEq)] diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index fbae287e..47c210bd 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -1,10 +1,12 @@ -use crate::core::text::editor::{self, Action, Cursor, Direction, Motion}; +use crate::core::text::editor::{ + self, Action, Cursor, Direction, Edit, Motion, +}; use crate::core::text::highlighter::{self, Highlighter}; use crate::core::text::LineHeight; use crate::core::{Font, Pixels, Point, Rectangle, Size}; use crate::text; -use cosmic_text::Edit; +use cosmic_text::Edit as _; use std::fmt; use std::sync::{self, Arc}; @@ -370,22 +372,42 @@ impl editor::Editor for Editor { } // Editing events - Action::Insert(c) => { - editor - .action(font_system.raw(), cosmic_text::Action::Insert(c)); - } - Action::Paste(text) => { - editor.insert_string(&text, None); - } - Action::Enter => { - editor.action(font_system.raw(), cosmic_text::Action::Enter); - } - Action::Backspace => { - editor - .action(font_system.raw(), cosmic_text::Action::Backspace); - } - Action::Delete => { - editor.action(font_system.raw(), cosmic_text::Action::Delete); + Action::Edit(edit) => { + match edit { + Edit::Insert(c) => { + editor.action( + font_system.raw(), + cosmic_text::Action::Insert(c), + ); + } + Edit::Paste(text) => { + editor.insert_string(&text, None); + } + Edit::Enter => { + editor.action( + font_system.raw(), + cosmic_text::Action::Enter, + ); + } + Edit::Backspace => { + editor.action( + font_system.raw(), + cosmic_text::Action::Backspace, + ); + } + Edit::Delete => { + editor.action( + font_system.raw(), + cosmic_text::Action::Delete, + ); + } + } + + let cursor = editor.cursor(); + let selection = editor.select_opt().unwrap_or(cursor); + + internal.topmost_line_changed = + Some(cursor.min(selection).line); } // Mouse events diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index 03adbb59..c30e185f 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -17,7 +17,7 @@ use std::ops::DerefMut; use std::sync::Arc; pub use crate::style::text_editor::{Appearance, Highlight, StyleSheet}; -pub use text::editor::{Action, Motion}; +pub use text::editor::{Action, Edit, Motion}; pub struct TextEditor<'a, Highlighter, Message, Renderer = crate::Renderer> where @@ -301,7 +301,7 @@ where Update::Release => { state.drag_click = None; } - Update::Edit(action) => { + Update::Action(action) => { shell.publish(on_edit(action)); } Update::Copy => { @@ -311,7 +311,9 @@ where } Update::Paste => { if let Some(contents) = clipboard.read() { - shell.publish(on_edit(Action::Paste(Arc::new(contents)))); + shell.publish(on_edit(Action::Edit(Edit::Paste( + Arc::new(contents), + )))); } } } @@ -457,7 +459,7 @@ enum Update { Click(mouse::Click), Unfocus, Release, - Edit(Action), + Action(Action), Copy, Paste, } @@ -470,7 +472,8 @@ impl Update { padding: Padding, cursor: mouse::Cursor, ) -> Option { - let edit = |action| Some(Update::Edit(action)); + let action = |action| Some(Update::Action(action)); + let edit = |edit| action(Action::Edit(edit)); match event { Event::Mouse(event) => match event { @@ -499,7 +502,7 @@ impl Update { let cursor_position = cursor.position_in(bounds)? - Vector::new(padding.top, padding.left); - edit(Action::Drag(cursor_position)) + action(Action::Drag(cursor_position)) } _ => None, }, @@ -518,7 +521,7 @@ impl Update { motion }; - return edit(if modifiers.shift() { + return action(if modifiers.shift() { Action::Select(motion) } else { Action::Move(motion) @@ -526,9 +529,9 @@ impl Update { } match key_code { - keyboard::KeyCode::Enter => edit(Action::Enter), - keyboard::KeyCode::Backspace => edit(Action::Backspace), - keyboard::KeyCode::Delete => edit(Action::Delete), + keyboard::KeyCode::Enter => edit(Edit::Enter), + keyboard::KeyCode::Backspace => edit(Edit::Backspace), + keyboard::KeyCode::Delete => edit(Edit::Delete), keyboard::KeyCode::Escape => Some(Self::Unfocus), keyboard::KeyCode::C if modifiers.command() => { Some(Self::Copy) @@ -542,7 +545,7 @@ impl Update { } } keyboard::Event::CharacterReceived(c) if state.is_focused => { - edit(Action::Insert(c)) + edit(Edit::Insert(c)) } _ => None, }, From 790c0dabcf0a50a2466e47daeb4f1e149b2ede5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 17 Sep 2023 21:45:13 +0200 Subject: [PATCH 206/321] Implement syntax highlighting cache in `editor` example --- Cargo.toml | 4 +++ examples/editor/src/main.rs | 67 +++++++++++++++++++++++-------------- 2 files changed, 46 insertions(+), 25 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f8dd5f14..70f84460 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -155,3 +155,7 @@ winit = { git = "https://github.com/iced-rs/winit.git", rev = "c52db2045d0a2f1b8 [patch.crates-io.cosmic-text] git = "https://github.com/hecrj/cosmic-text.git" rev = "cb83458e7d0b84ef37c5beb72dda5046d7d343a6" + +[patch.crates-io.rangemap] +git = "https://github.com/hecrj/rangemap.git" +branch = "fix/partial-eq" diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs index a72feebc..1235d38b 100644 --- a/examples/editor/src/main.rs +++ b/examples/editor/src/main.rs @@ -64,7 +64,7 @@ mod highlighter { use std::ops::Range; use syntect::highlighting; - use syntect::parsing; + use syntect::parsing::{self, SyntaxReference}; #[derive(Debug, Clone, Hash)] pub struct Settings { @@ -91,13 +91,14 @@ mod highlighter { pub struct Highlighter { syntaxes: parsing::SyntaxSet, - parser: parsing::ParseState, - stack: parsing::ScopeStack, + syntax: SyntaxReference, + caches: Vec<(parsing::ParseState, parsing::ScopeStack)>, theme: highlighting::Theme, - token: String, current_line: usize, } + const LINES_PER_SNAPSHOT: usize = 50; + impl highlighter::Highlighter for Highlighter { type Settings = Settings; type Highlight = Highlight; @@ -121,34 +122,53 @@ mod highlighter { .unwrap(); Highlighter { + syntax: syntax.clone(), syntaxes, - parser, - stack, + caches: vec![(parser, stack)], theme, - token: settings.token.clone(), current_line: 0, } } - fn change_line(&mut self, _line: usize) { - // TODO: Caching - let syntax = self - .syntaxes - .find_syntax_by_token(&self.token) - .unwrap_or_else(|| self.syntaxes.find_syntax_plain_text()); + fn change_line(&mut self, line: usize) { + let snapshot = line / LINES_PER_SNAPSHOT; - self.parser = parsing::ParseState::new(&syntax); - self.stack = parsing::ScopeStack::new(); - self.current_line = 0; + if snapshot <= self.caches.len() { + self.caches.truncate(snapshot); + self.current_line = snapshot * LINES_PER_SNAPSHOT; + } else { + self.caches.truncate(1); + self.current_line = 0; + } + + let (parser, stack) = + self.caches.last().cloned().unwrap_or_else(|| { + ( + parsing::ParseState::new(&self.syntax), + parsing::ScopeStack::new(), + ) + }); + + self.caches.push((parser, stack)); } fn highlight_line(&mut self, line: &str) -> Self::Iterator<'_> { + if self.current_line / LINES_PER_SNAPSHOT >= self.caches.len() { + let (parser, stack) = + self.caches.last().expect("Caches must not be empty"); + + self.caches.push((parser.clone(), stack.clone())); + } + self.current_line += 1; - let ops = self - .parser - .parse_line(line, &self.syntaxes) - .unwrap_or_default(); + let (parser, stack) = + self.caches.last_mut().expect("Caches must not be empty"); + + let ops = + parser.parse_line(line, &self.syntaxes).unwrap_or_default(); + + let highlighter = highlighting::Highlighter::new(&self.theme); Box::new( ScopeRangeIterator { @@ -158,9 +178,7 @@ mod highlighter { last_str_index: 0, } .filter_map(move |(range, scope)| { - let highlighter = - highlighting::Highlighter::new(&self.theme); - let _ = self.stack.apply(&scope); + let _ = stack.apply(&scope); if range.is_empty() { None @@ -168,8 +186,7 @@ mod highlighter { Some(( range, Highlight( - highlighter - .style_mod_for_stack(&self.stack.scopes), + highlighter.style_mod_for_stack(&stack.scopes), ), )) } From 86d396cf8bede8155bdd4a7d3f115a0108c67297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 17 Sep 2023 23:15:38 +0200 Subject: [PATCH 207/321] Avoid adding unnecessary spans when syntax highlighting --- Cargo.toml | 2 +- graphics/src/text/editor.rs | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 70f84460..ac59085d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -154,7 +154,7 @@ winit = { git = "https://github.com/iced-rs/winit.git", rev = "c52db2045d0a2f1b8 [patch.crates-io.cosmic-text] git = "https://github.com/hecrj/cosmic-text.git" -rev = "cb83458e7d0b84ef37c5beb72dda5046d7d343a6" +branch = "editor-fixes" [patch.crates-io.rangemap] git = "https://github.com/hecrj/rangemap.git" diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index 47c210bd..95061c3c 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -569,17 +569,19 @@ impl editor::Editor for Editor { for (range, highlight) in highlighter.highlight_line(line.text()) { let format = format_highlight(&highlight); - list.add_span( - range, - cosmic_text::Attrs { - color_opt: format.color.map(text::to_color), - ..if let Some(font) = format.font { - text::to_attributes(font) - } else { - attributes - } - }, - ); + if format.color.is_some() || format.font.is_some() { + list.add_span( + range, + cosmic_text::Attrs { + color_opt: format.color.map(text::to_color), + ..if let Some(font) = format.font { + text::to_attributes(font) + } else { + attributes + } + }, + ); + } } let _ = line.set_attrs_list(list); From 8f8528a4ccee049aba779fe86cda786a52afac30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 17 Sep 2023 23:20:15 +0200 Subject: [PATCH 208/321] Fix unnecessary dereference in `editor` example --- examples/editor/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs index 1235d38b..74649676 100644 --- a/examples/editor/src/main.rs +++ b/examples/editor/src/main.rs @@ -113,7 +113,7 @@ mod highlighter { .find_syntax_by_token(&settings.token) .unwrap_or_else(|| syntaxes.find_syntax_plain_text()); - let parser = parsing::ParseState::new(&syntax); + let parser = parsing::ParseState::new(syntax); let stack = parsing::ScopeStack::new(); let theme = highlighting::ThemeSet::load_defaults() From d1440ceca6340d045e556eb05354c254881732f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 18 Sep 2023 13:39:47 +0200 Subject: [PATCH 209/321] Find correct `last_visible_line` in `Editor::highlight` --- graphics/src/text/editor.rs | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index 95061c3c..18c9b572 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -538,11 +538,27 @@ impl editor::Editor for Editor { let internal = self.internal(); let buffer = internal.editor.buffer(); - let scroll = buffer.scroll(); - let visible_lines = buffer.visible_lines(); - let last_visible_line = ((scroll + visible_lines) as usize) - .min(buffer.lines.len()) - .saturating_sub(1); + let mut window = buffer.scroll() + buffer.visible_lines(); + + let last_visible_line = buffer + .lines + .iter() + .enumerate() + .find_map(|(i, line)| { + let visible_lines = line + .layout_opt() + .as_ref() + .expect("Line layout should be cached") + .len() as i32; + + if window > visible_lines { + window -= visible_lines; + None + } else { + Some(i) + } + }) + .unwrap_or(buffer.lines.len()); let current_line = highlighter.current_line(); From a01b123cec1b57a9100d56f567fcfbf91967b12f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 18 Sep 2023 13:57:47 +0200 Subject: [PATCH 210/321] Shape as needed only in `update` during `layout` --- graphics/src/text/editor.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index 18c9b572..59096e74 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -442,8 +442,6 @@ impl editor::Editor for Editor { } } - editor.shape_as_needed(font_system.raw()); - self.0 = Some(Arc::new(internal)); } @@ -487,8 +485,6 @@ impl editor::Editor for Editor { internal.font = new_font; internal.topmost_line_changed = Some(0); - - internal.editor.shape_as_needed(font_system.raw()); } let metrics = internal.editor.buffer().metrics(); @@ -526,6 +522,8 @@ impl editor::Editor for Editor { new_highlighter.change_line(topmost_line_changed); } + internal.editor.shape_as_needed(font_system.raw()); + self.0 = Some(Arc::new(internal)); } From b5466f41ca33452fb0d4e8470856c027d3b26e39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 18 Sep 2023 13:58:39 +0200 Subject: [PATCH 211/321] Fix inconsistent `expect` messages in `text::editor` --- graphics/src/text/editor.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index 59096e74..de1b998b 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -43,7 +43,7 @@ impl Editor { fn internal(&self) -> &Arc { self.0 .as_ref() - .expect("editor should always be initialized") + .expect("Editor should always be initialized") } } @@ -458,7 +458,7 @@ impl editor::Editor for Editor { new_highlighter: &mut impl Highlighter, ) { let editor = - self.0.take().expect("editor should always be initialized"); + self.0.take().expect("Editor should always be initialized"); let mut internal = Arc::try_unwrap(editor) .expect("Editor cannot have multiple strong references"); @@ -565,7 +565,7 @@ impl editor::Editor for Editor { } let editor = - self.0.take().expect("editor should always be initialized"); + self.0.take().expect("Editor should always be initialized"); let mut internal = Arc::try_unwrap(editor) .expect("Editor cannot have multiple strong references"); From 61ef8f3249218b301d434d04c483ba70562c1df4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 18 Sep 2023 13:58:55 +0200 Subject: [PATCH 212/321] Update `version` properly when `FontSystem` changes in `text::editor` --- graphics/src/text/editor.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index de1b998b..4673fce3 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -472,6 +472,9 @@ impl editor::Editor for Editor { for line in internal.editor.buffer_mut().lines.iter_mut() { line.reset(); } + + internal.version = font_system.version(); + internal.topmost_line_changed = Some(0); } if new_font != internal.font { From 8446fe6de52fa68077d23d39f728f79a29b52f00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 18 Sep 2023 14:38:54 +0200 Subject: [PATCH 213/321] Implement theme selector in `editor` example --- core/src/text/highlighter.rs | 7 ++- examples/editor/src/main.rs | 103 ++++++++++++++++++++++++++++------- widget/src/text_editor.rs | 13 ++++- 3 files changed, 100 insertions(+), 23 deletions(-) diff --git a/core/src/text/highlighter.rs b/core/src/text/highlighter.rs index a929826f..b462d083 100644 --- a/core/src/text/highlighter.rs +++ b/core/src/text/highlighter.rs @@ -1,10 +1,9 @@ use crate::Color; -use std::hash::Hash; use std::ops::Range; pub trait Highlighter: 'static { - type Settings: Hash; + type Settings: PartialEq + Clone; type Highlight; type Iterator<'a>: Iterator, Self::Highlight)> @@ -13,6 +12,8 @@ pub trait Highlighter: 'static { fn new(settings: &Self::Settings) -> Self; + fn update(&mut self, new_settings: &Self::Settings); + fn change_line(&mut self, line: usize); fn highlight_line(&mut self, line: &str) -> Self::Iterator<'_>; @@ -38,6 +39,8 @@ impl Highlighter for PlainText { Self } + fn update(&mut self, _new_settings: &Self::Settings) {} + fn change_line(&mut self, _line: usize) {} fn highlight_line(&mut self, _line: &str) -> Self::Iterator<'_> { diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs index 74649676..fa35ba0f 100644 --- a/examples/editor/src/main.rs +++ b/examples/editor/src/main.rs @@ -1,5 +1,5 @@ -use iced::widget::{container, text_editor}; -use iced::{Element, Font, Sandbox, Settings, Theme}; +use iced::widget::{column, horizontal_space, pick_list, row, text_editor}; +use iced::{Element, Font, Length, Sandbox, Settings, Theme}; use highlighter::Highlighter; @@ -9,11 +9,13 @@ pub fn main() -> iced::Result { struct Editor { content: text_editor::Content, + theme: highlighter::Theme, } #[derive(Debug, Clone)] enum Message { Edit(text_editor::Action), + ThemeSelected(highlighter::Theme), } impl Sandbox for Editor { @@ -21,9 +23,8 @@ impl Sandbox for Editor { fn new() -> Self { Self { - content: text_editor::Content::with(include_str!( - "../../../README.md" - )), + content: text_editor::Content::with(include_str!("main.rs")), + theme: highlighter::Theme::SolarizedDark, } } @@ -36,18 +37,33 @@ impl Sandbox for Editor { Message::Edit(action) => { self.content.edit(action); } + Message::ThemeSelected(theme) => { + self.theme = theme; + } } } fn view(&self) -> Element { - container( + column![ + row![ + horizontal_space(Length::Fill), + pick_list( + highlighter::Theme::ALL, + Some(self.theme), + Message::ThemeSelected + ) + .padding([5, 10]) + ] + .spacing(10), text_editor(&self.content) .on_edit(Message::Edit) .font(Font::with_name("Hasklug Nerd Font Mono")) .highlight::(highlighter::Settings { - token: String::from("md"), + theme: self.theme, + extension: String::from("rs"), }), - ) + ] + .spacing(10) .padding(20) .into() } @@ -60,21 +76,52 @@ impl Sandbox for Editor { mod highlighter { use iced::advanced::text::highlighter; use iced::widget::text_editor; - use iced::{Color, Font, Theme}; + use iced::{Color, Font}; use std::ops::Range; use syntect::highlighting; use syntect::parsing::{self, SyntaxReference}; - #[derive(Debug, Clone, Hash)] + #[derive(Debug, Clone, PartialEq)] pub struct Settings { - pub token: String, + pub theme: Theme, + pub extension: String, + } + + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + pub enum Theme { + SolarizedDark, + InspiredGitHub, + Base16Mocha, + } + + impl Theme { + pub const ALL: &[Self] = + &[Self::SolarizedDark, Self::InspiredGitHub, Self::Base16Mocha]; + + fn key(&self) -> &'static str { + match self { + Theme::InspiredGitHub => "InspiredGitHub", + Theme::Base16Mocha => "base16-mocha.dark", + Theme::SolarizedDark => "Solarized (dark)", + } + } + } + + impl std::fmt::Display for Theme { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Theme::InspiredGitHub => write!(f, "Inspired GitHub"), + Theme::Base16Mocha => write!(f, "Mocha"), + Theme::SolarizedDark => write!(f, "Solarized Dark"), + } + } } pub struct Highlight(highlighting::StyleModifier); impl text_editor::Highlight for Highlight { - fn format(&self, _theme: &Theme) -> highlighter::Format { + fn format(&self, _theme: &iced::Theme) -> highlighter::Format { highlighter::Format { color: self.0.foreground.map(|color| { Color::from_rgba8( @@ -92,8 +139,8 @@ mod highlighter { pub struct Highlighter { syntaxes: parsing::SyntaxSet, syntax: SyntaxReference, - caches: Vec<(parsing::ParseState, parsing::ScopeStack)>, theme: highlighting::Theme, + caches: Vec<(parsing::ParseState, parsing::ScopeStack)>, current_line: usize, } @@ -110,26 +157,42 @@ mod highlighter { let syntaxes = parsing::SyntaxSet::load_defaults_nonewlines(); let syntax = syntaxes - .find_syntax_by_token(&settings.token) + .find_syntax_by_token(&settings.extension) .unwrap_or_else(|| syntaxes.find_syntax_plain_text()); + let theme = highlighting::ThemeSet::load_defaults() + .themes + .remove(settings.theme.key()) + .unwrap(); + let parser = parsing::ParseState::new(syntax); let stack = parsing::ScopeStack::new(); - let theme = highlighting::ThemeSet::load_defaults() - .themes - .remove("base16-mocha.dark") - .unwrap(); - Highlighter { syntax: syntax.clone(), syntaxes, - caches: vec![(parser, stack)], theme, + caches: vec![(parser, stack)], current_line: 0, } } + fn update(&mut self, new_settings: &Self::Settings) { + self.syntax = self + .syntaxes + .find_syntax_by_token(&new_settings.extension) + .unwrap_or_else(|| self.syntaxes.find_syntax_plain_text()) + .clone(); + + self.theme = highlighting::ThemeSet::load_defaults() + .themes + .remove(new_settings.theme.key()) + .unwrap(); + + // Restart the highlighter + self.change_line(0); + } + fn change_line(&mut self, line: usize) { let snapshot = line / LINES_PER_SNAPSHOT; diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index c30e185f..0cde2c98 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -193,11 +193,12 @@ where } } -struct State { +struct State { is_focused: bool, last_click: Option, drag_click: Option, highlighter: RefCell, + highlighter_settings: Highlighter::Settings, } impl<'a, Highlighter, Message, Renderer> Widget @@ -220,6 +221,7 @@ where highlighter: RefCell::new(Highlighter::new( &self.highlighter_settings, )), + highlighter_settings: self.highlighter_settings.clone(), }) } @@ -240,6 +242,15 @@ where let mut internal = self.content.0.borrow_mut(); let state = tree.state.downcast_mut::>(); + if state.highlighter_settings != self.highlighter_settings { + state + .highlighter + .borrow_mut() + .update(&self.highlighter_settings); + + state.highlighter_settings = self.highlighter_settings.clone(); + } + internal.editor.update( limits.pad(self.padding).max(), self.font.unwrap_or_else(|| renderer.default_font()), From e7326f0af6f16cf2ff04fbac93bf296a044923f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 18 Sep 2023 19:07:41 +0200 Subject: [PATCH 214/321] Flesh out the `editor` example a bit more --- core/src/renderer/null.rs | 4 + core/src/text/editor.rs | 8 + examples/editor/Cargo.toml | 8 +- examples/editor/fonts/icons.ttf | Bin 0 -> 6352 bytes examples/editor/src/main.rs | 285 +++++++++++++++++++++++++++++--- graphics/src/text/editor.rs | 8 +- src/settings.rs | 8 + widget/src/text_editor.rs | 4 + winit/src/application.rs | 9 +- winit/src/settings.rs | 4 + 10 files changed, 311 insertions(+), 27 deletions(-) create mode 100644 examples/editor/fonts/icons.ttf diff --git a/core/src/renderer/null.rs b/core/src/renderer/null.rs index 21597c8e..da0f32de 100644 --- a/core/src/renderer/null.rs +++ b/core/src/renderer/null.rs @@ -125,6 +125,10 @@ impl text::Editor for () { text::editor::Cursor::Caret(Point::ORIGIN) } + fn cursor_position(&self) -> (usize, usize) { + (0, 0) + } + fn selection(&self) -> Option { None } diff --git a/core/src/text/editor.rs b/core/src/text/editor.rs index 2144715f..13bafc3d 100644 --- a/core/src/text/editor.rs +++ b/core/src/text/editor.rs @@ -12,6 +12,8 @@ pub trait Editor: Sized + Default { fn cursor(&self) -> Cursor; + fn cursor_position(&self) -> (usize, usize); + fn selection(&self) -> Option; fn line(&self, index: usize) -> Option<&str>; @@ -52,6 +54,12 @@ pub enum Action { Drag(Point), } +impl Action { + pub fn is_edit(&self) -> bool { + matches!(self, Self::Edit(_)) + } +} + #[derive(Debug, Clone, PartialEq)] pub enum Edit { Insert(char), diff --git a/examples/editor/Cargo.toml b/examples/editor/Cargo.toml index 930ee592..eeb34aa1 100644 --- a/examples/editor/Cargo.toml +++ b/examples/editor/Cargo.toml @@ -7,6 +7,10 @@ publish = false [dependencies] iced.workspace = true -iced.features = ["advanced", "debug"] +iced.features = ["advanced", "tokio", "debug"] -syntect = "5.1" \ No newline at end of file +tokio.workspace = true +tokio.features = ["fs"] + +syntect = "5.1" +rfd = "0.12" diff --git a/examples/editor/fonts/icons.ttf b/examples/editor/fonts/icons.ttf new file mode 100644 index 0000000000000000000000000000000000000000..393c6922e52f0fce49800b294962763daee5a0f3 GIT binary patch literal 6352 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 iced::Result { - Editor::run(Settings::default()) + Editor::run(Settings { + fonts: vec![include_bytes!("../fonts/icons.ttf").as_slice().into()], + default_font: Font { + monospaced: true, + ..Font::with_name("Hasklug Nerd Font Mono") + }, + ..Settings::default() + }) } struct Editor { + file: Option, content: text_editor::Content, theme: highlighter::Theme, + is_loading: bool, + is_dirty: bool, } #[derive(Debug, Clone)] enum Message { Edit(text_editor::Action), ThemeSelected(highlighter::Theme), + NewFile, + OpenFile, + FileOpened(Result<(PathBuf, Arc), Error>), + SaveFile, + FileSaved(Result), } -impl Sandbox for Editor { +impl Application for Editor { type Message = Message; + type Theme = Theme; + type Executor = executor::Default; + type Flags = (); - fn new() -> Self { - Self { - content: text_editor::Content::with(include_str!("main.rs")), - theme: highlighter::Theme::SolarizedDark, - } + fn new(_flags: Self::Flags) -> (Self, Command) { + ( + Self { + file: None, + content: text_editor::Content::new(), + theme: highlighter::Theme::SolarizedDark, + is_loading: true, + is_dirty: false, + }, + Command::perform(load_file(default_file()), Message::FileOpened), + ) } fn title(&self) -> String { String::from("Editor - Iced") } - fn update(&mut self, message: Message) { + fn update(&mut self, message: Message) -> Command { match message { Message::Edit(action) => { + self.is_dirty = self.is_dirty || action.is_edit(); + self.content.edit(action); + + Command::none() } Message::ThemeSelected(theme) => { self.theme = theme; + + Command::none() + } + Message::NewFile => { + if !self.is_loading { + self.file = None; + self.content = text_editor::Content::new(); + } + + Command::none() + } + Message::OpenFile => { + if self.is_loading { + Command::none() + } else { + self.is_loading = true; + + Command::perform(open_file(), Message::FileOpened) + } + } + Message::FileOpened(result) => { + self.is_loading = false; + self.is_dirty = false; + + if let Ok((path, contents)) = result { + self.file = Some(path); + self.content = text_editor::Content::with(&contents); + } + + Command::none() + } + Message::SaveFile => { + if self.is_loading { + Command::none() + } else { + self.is_loading = true; + + let mut contents = self.content.lines().enumerate().fold( + String::new(), + |mut contents, (i, line)| { + if i > 0 { + contents.push_str("\n"); + } + + contents.push_str(&line); + + contents + }, + ); + + if !contents.ends_with("\n") { + contents.push_str("\n"); + } + + Command::perform( + save_file(self.file.clone(), contents), + Message::FileSaved, + ) + } + } + Message::FileSaved(result) => { + self.is_loading = false; + + if let Ok(path) = result { + self.file = Some(path); + self.is_dirty = false; + } + + Command::none() } } } fn view(&self) -> Element { + let controls = row![ + action(new_icon(), "New file", Some(Message::NewFile)), + action( + open_icon(), + "Open file", + (!self.is_loading).then_some(Message::OpenFile) + ), + action( + save_icon(), + "Save file", + self.is_dirty.then_some(Message::SaveFile) + ), + horizontal_space(Length::Fill), + pick_list( + highlighter::Theme::ALL, + Some(self.theme), + Message::ThemeSelected + ) + .text_size(14) + .padding([5, 10]) + ] + .spacing(10); + + let status = row![ + text(if let Some(path) = &self.file { + let path = path.display().to_string(); + + if path.len() > 60 { + format!("...{}", &path[path.len() - 40..]) + } else { + path + } + } else { + String::from("New file") + }), + horizontal_space(Length::Fill), + text({ + let (line, column) = self.content.cursor_position(); + + format!("{}:{}", line + 1, column + 1) + }) + ] + .spacing(10); + column![ - row![ - horizontal_space(Length::Fill), - pick_list( - highlighter::Theme::ALL, - Some(self.theme), - Message::ThemeSelected - ) - .padding([5, 10]) - ] - .spacing(10), + controls, text_editor(&self.content) .on_edit(Message::Edit) - .font(Font::with_name("Hasklug Nerd Font Mono")) .highlight::(highlighter::Settings { theme: self.theme, - extension: String::from("rs"), + extension: self + .file + .as_deref() + .and_then(Path::extension) + .and_then(ffi::OsStr::to_str) + .map(str::to_string) + .unwrap_or(String::from("rs")), }), + status, ] .spacing(10) - .padding(20) + .padding(10) .into() } @@ -73,6 +221,97 @@ impl Sandbox for Editor { } } +#[derive(Debug, Clone)] +pub enum Error { + DialogClosed, + IoError(io::ErrorKind), +} + +fn default_file() -> PathBuf { + PathBuf::from(format!("{}/src/main.rs", env!("CARGO_MANIFEST_DIR"))) +} + +async fn open_file() -> Result<(PathBuf, Arc), Error> { + let picked_file = rfd::AsyncFileDialog::new() + .set_title("Open a text file...") + .pick_file() + .await + .ok_or(Error::DialogClosed)?; + + load_file(picked_file.path().to_owned()).await +} + +async fn load_file(path: PathBuf) -> Result<(PathBuf, Arc), Error> { + let contents = tokio::fs::read_to_string(&path) + .await + .map(Arc::new) + .map_err(|error| Error::IoError(error.kind()))?; + + Ok((path, contents)) +} + +async fn save_file( + path: Option, + contents: String, +) -> Result { + let path = if let Some(path) = path { + path + } else { + rfd::AsyncFileDialog::new() + .save_file() + .await + .as_ref() + .map(rfd::FileHandle::path) + .map(Path::to_owned) + .ok_or(Error::DialogClosed)? + }; + + let _ = tokio::fs::write(&path, contents) + .await + .map_err(|error| Error::IoError(error.kind()))?; + + Ok(path) +} + +fn action<'a, Message: Clone + 'a>( + content: impl Into>, + label: &'a str, + on_press: Option, +) -> Element<'a, Message> { + let action = + button(container(content).width(Length::Fill).center_x()).width(40); + + if let Some(on_press) = on_press { + tooltip( + action.on_press(on_press), + label, + tooltip::Position::FollowCursor, + ) + .style(theme::Container::Box) + .into() + } else { + action.style(theme::Button::Secondary).into() + } +} + +fn new_icon<'a, Message>() -> Element<'a, Message> { + icon('\u{0e800}') +} + +fn save_icon<'a, Message>() -> Element<'a, Message> { + icon('\u{0e801}') +} + +fn open_icon<'a, Message>() -> Element<'a, Message> { + icon('\u{0f115}') +} + +fn icon<'a, Message>(codepoint: char) -> Element<'a, Message> { + const ICON_FONT: Font = Font::with_name("editor-icons"); + + text(codepoint).font(ICON_FONT).into() +} + mod highlighter { use iced::advanced::text::highlighter; use iced::widget::text_editor; diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index 4673fce3..dfb91f34 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -221,6 +221,12 @@ impl editor::Editor for Editor { } } + fn cursor_position(&self) -> (usize, usize) { + let cursor = self.internal().editor.cursor(); + + (cursor.line, cursor.index) + } + fn perform(&mut self, action: Action) { let mut font_system = text::font_system().write().expect("Write font system"); @@ -559,7 +565,7 @@ impl editor::Editor for Editor { Some(i) } }) - .unwrap_or(buffer.lines.len()); + .unwrap_or(buffer.lines.len().saturating_sub(1)); let current_line = highlighter.current_line(); diff --git a/src/settings.rs b/src/settings.rs index d9778d7e..6b9ce095 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -2,6 +2,8 @@ use crate::window; use crate::{Font, Pixels}; +use std::borrow::Cow; + /// The settings of an application. #[derive(Debug, Clone)] pub struct Settings { @@ -21,6 +23,9 @@ pub struct Settings { /// [`Application`]: crate::Application pub flags: Flags, + /// The fonts to load on boot. + pub fonts: Vec>, + /// The default [`Font`] to be used. /// /// By default, it uses [`Family::SansSerif`](crate::font::Family::SansSerif). @@ -62,6 +67,7 @@ impl Settings { flags, id: default_settings.id, window: default_settings.window, + fonts: default_settings.fonts, default_font: default_settings.default_font, default_text_size: default_settings.default_text_size, antialiasing: default_settings.antialiasing, @@ -79,6 +85,7 @@ where id: None, window: Default::default(), flags: Default::default(), + fonts: Default::default(), default_font: Default::default(), default_text_size: Pixels(16.0), antialiasing: false, @@ -93,6 +100,7 @@ impl From> for iced_winit::Settings { id: settings.id, window: settings.window.into(), flags: settings.flags, + fonts: settings.fonts, exit_on_close_request: settings.exit_on_close_request, } } diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index 0cde2c98..970ec031 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -182,6 +182,10 @@ where pub fn selection(&self) -> Option { self.0.borrow().editor.selection() } + + pub fn cursor_position(&self) -> (usize, usize) { + self.0.borrow().editor.cursor_position() + } } impl Default for Content diff --git a/winit/src/application.rs b/winit/src/application.rs index d1689452..e80e9783 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -193,7 +193,14 @@ where }; } - let (compositor, renderer) = C::new(compositor_settings, Some(&window))?; + let (compositor, mut renderer) = + C::new(compositor_settings, Some(&window))?; + + for font in settings.fonts { + use crate::core::text::Renderer; + + renderer.load_font(font); + } let (mut event_sender, event_receiver) = mpsc::unbounded(); let (control_sender, mut control_receiver) = mpsc::unbounded(); diff --git a/winit/src/settings.rs b/winit/src/settings.rs index 8d3e1b47..b4a1dd61 100644 --- a/winit/src/settings.rs +++ b/winit/src/settings.rs @@ -33,6 +33,7 @@ use crate::Position; use winit::monitor::MonitorHandle; use winit::window::WindowBuilder; +use std::borrow::Cow; use std::fmt; /// The settings of an application. @@ -52,6 +53,9 @@ pub struct Settings { /// [`Application`]: crate::Application pub flags: Flags, + /// The fonts to load on boot. + pub fonts: Vec>, + /// Whether the [`Application`] should exit when the user requests the /// window to close (e.g. the user presses the close button). /// From 161a971d065b3254a2f11cb374d2c94c2d67646b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 18 Sep 2023 19:08:57 +0200 Subject: [PATCH 215/321] Fix `clippy` lints --- examples/editor/src/main.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs index 09c4b9b5..785dfb3b 100644 --- a/examples/editor/src/main.rs +++ b/examples/editor/src/main.rs @@ -118,7 +118,7 @@ impl Application for Editor { String::new(), |mut contents, (i, line)| { if i > 0 { - contents.push_str("\n"); + contents.push('\n'); } contents.push_str(&line); @@ -127,8 +127,8 @@ impl Application for Editor { }, ); - if !contents.ends_with("\n") { - contents.push_str("\n"); + if !contents.ends_with('\n') { + contents.push('\n'); } Command::perform( @@ -266,7 +266,7 @@ async fn save_file( .ok_or(Error::DialogClosed)? }; - let _ = tokio::fs::write(&path, contents) + tokio::fs::write(&path, contents) .await .map_err(|error| Error::IoError(error.kind()))?; From 8eec0033dee816bfcc102fc4f511c8bfe08c14ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 18 Sep 2023 19:24:09 +0200 Subject: [PATCH 216/321] Remove unnecessary `monospaced` flag in `Font` --- core/src/font.rs | 4 ---- examples/editor/src/main.rs | 5 +---- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/core/src/font.rs b/core/src/font.rs index 7f647847..2b68decf 100644 --- a/core/src/font.rs +++ b/core/src/font.rs @@ -12,8 +12,6 @@ pub struct Font { pub stretch: Stretch, /// The [`Style`] of the [`Font`]. pub style: Style, - /// Whether if the [`Font`] is monospaced or not. - pub monospaced: bool, } impl Font { @@ -23,13 +21,11 @@ impl Font { weight: Weight::Normal, stretch: Stretch::Normal, style: Style::Normal, - monospaced: false, }; /// A monospaced font with normal [`Weight`]. pub const MONOSPACE: Font = Font { family: Family::Monospace, - monospaced: true, ..Self::DEFAULT }; diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs index 785dfb3b..5018b3cb 100644 --- a/examples/editor/src/main.rs +++ b/examples/editor/src/main.rs @@ -16,10 +16,7 @@ use std::sync::Arc; pub fn main() -> iced::Result { Editor::run(Settings { fonts: vec![include_bytes!("../fonts/icons.ttf").as_slice().into()], - default_font: Font { - monospaced: true, - ..Font::with_name("Hasklug Nerd Font Mono") - }, + default_font: Font::with_name("Hasklug Nerd Font Mono"), ..Settings::default() }) } From d1d0b3aaee84003278b9db3e86687e776f20b346 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 18 Sep 2023 20:14:38 +0200 Subject: [PATCH 217/321] Use `Font::MONOSPACE` in `editor` example --- Cargo.toml | 2 +- examples/editor/src/main.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ac59085d..e887afc0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -154,7 +154,7 @@ winit = { git = "https://github.com/iced-rs/winit.git", rev = "c52db2045d0a2f1b8 [patch.crates-io.cosmic-text] git = "https://github.com/hecrj/cosmic-text.git" -branch = "editor-fixes" +branch = "respect-fontconfig-aliases" [patch.crates-io.rangemap] git = "https://github.com/hecrj/rangemap.git" diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs index 5018b3cb..277eb3e9 100644 --- a/examples/editor/src/main.rs +++ b/examples/editor/src/main.rs @@ -16,7 +16,7 @@ use std::sync::Arc; pub fn main() -> iced::Result { Editor::run(Settings { fonts: vec![include_bytes!("../fonts/icons.ttf").as_slice().into()], - default_font: Font::with_name("Hasklug Nerd Font Mono"), + default_font: Font::MONOSPACE, ..Settings::default() }) } From 36e867de693d4e9fc64da3d9d7745a5b1398d8a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 18 Sep 2023 20:59:39 +0200 Subject: [PATCH 218/321] Fix `lint` and `test` GitHub CI workflows --- .github/workflows/lint.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 6fd98374..af34bb13 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -2,7 +2,7 @@ name: Lint on: [push, pull_request] jobs: all: - runs-on: ubuntu-latest + runs-on: macOS-latest steps: - uses: hecrj/setup-rust-action@v1 with: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ac8d27f9..215b616b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,7 +17,7 @@ jobs: run: | export DEBIAN_FRONTED=noninteractive sudo apt-get -qq update - sudo apt-get install -y libxkbcommon-dev + sudo apt-get install -y libxkbcommon-dev libgtk-3-dev - name: Run tests run: | cargo test --verbose --workspace From 4e757a26d0c1c58001f31cf0592131cd5ad886ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 19 Sep 2023 01:18:06 +0200 Subject: [PATCH 219/321] Implement `Scroll` action in `text::editor` --- core/src/text/editor.rs | 1 + graphics/src/text/editor.rs | 6 ++++++ widget/src/text_editor.rs | 12 ++++++++++++ 3 files changed, 19 insertions(+) diff --git a/core/src/text/editor.rs b/core/src/text/editor.rs index 13bafc3d..e9d66ce9 100644 --- a/core/src/text/editor.rs +++ b/core/src/text/editor.rs @@ -52,6 +52,7 @@ pub enum Action { Edit(Edit), Click(Point), Drag(Point), + Scroll { lines: i32 }, } impl Action { diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index dfb91f34..a05312dc 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -446,6 +446,12 @@ impl editor::Editor for Editor { } } } + Action::Scroll { lines } => { + editor.action( + font_system.raw(), + cosmic_text::Action::Scroll { lines }, + ); + } } self.0 = Some(Arc::new(internal)); diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index 970ec031..ad12a076 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -521,6 +521,18 @@ impl Update { } _ => None, }, + mouse::Event::WheelScrolled { delta } => { + action(Action::Scroll { + lines: match delta { + mouse::ScrollDelta::Lines { y, .. } => { + -y as i32 * 4 + } + mouse::ScrollDelta::Pixels { y, .. } => { + -y.signum() as i32 + } + }, + }) + } _ => None, }, Event::Keyboard(event) => match event { From 3d6b9637c3b1c9f3c654a3ecef7a247cfd6edef3 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Tue, 19 Sep 2023 01:31:10 -0400 Subject: [PATCH 220/321] Chore: Inline format args for ease of reading A minor cleanup to inline all simple cases of format arguments. Makes the format strings just a bit easier to read. --- examples/game_of_life/src/main.rs | 3 +-- examples/screenshot/src/main.rs | 10 +++++----- examples/system_information/src/main.rs | 4 ++-- examples/todos/src/main.rs | 3 +-- examples/visible_bounds/src/main.rs | 2 +- futures/src/subscription/tracker.rs | 3 +-- renderer/src/lib.rs | 2 +- tiny_skia/src/backend.rs | 6 ++---- wgpu/src/image/atlas.rs | 8 ++++---- wgpu/src/image/vector.rs | 2 +- wgpu/src/window/compositor.rs | 6 +++--- winit/src/application.rs | 4 ++-- winit/src/clipboard.rs | 2 +- 13 files changed, 25 insertions(+), 30 deletions(-) diff --git a/examples/game_of_life/src/main.rs b/examples/game_of_life/src/main.rs index e451cb06..21a21142 100644 --- a/examples/game_of_life/src/main.rs +++ b/examples/game_of_life/src/main.rs @@ -610,8 +610,7 @@ mod grid { frame.fill_text(Text { content: format!( - "{} cell{} @ {:?} ({})", - cell_count, + "{cell_count} cell{} @ {:?} ({})", if cell_count == 1 { "" } else { "s" }, self.last_tick_duration, self.last_queued_ticks diff --git a/examples/screenshot/src/main.rs b/examples/screenshot/src/main.rs index 68c9d031..1c9e187c 100644 --- a/examples/screenshot/src/main.rs +++ b/examples/screenshot/src/main.rs @@ -184,8 +184,8 @@ impl Application for Example { .align_items(Alignment::Center); if let Some(crop_error) = &self.crop_error { - crop_controls = crop_controls - .push(text(format!("Crop error! \n{}", crop_error))); + crop_controls = + crop_controls.push(text(format!("Crop error! \n{crop_error}"))); } let mut controls = column![ @@ -221,9 +221,9 @@ impl Application for Example { if let Some(png_result) = &self.saved_png_path { let msg = match png_result { - Ok(path) => format!("Png saved as: {:?}!", path), + Ok(path) => format!("Png saved as: {path:?}!"), Err(msg) => { - format!("Png could not be saved due to:\n{:?}", msg) + format!("Png could not be saved due to:\n{msg:?}") } }; @@ -281,7 +281,7 @@ async fn save_to_png(screenshot: Screenshot) -> Result { ColorType::Rgba8, ) .map(|_| path) - .map_err(|err| PngError(format!("{:?}", err))) + .map_err(|err| PngError(format!("{err:?}"))) } #[derive(Clone, Debug)] diff --git a/examples/system_information/src/main.rs b/examples/system_information/src/main.rs index 633b6e2b..507431ee 100644 --- a/examples/system_information/src/main.rs +++ b/examples/system_information/src/main.rs @@ -105,8 +105,8 @@ impl Application for Example { ByteSize::kb(information.memory_total).to_string(); let memory_total = text(format!( - "Memory (total): {} kb ({})", - information.memory_total, memory_readable + "Memory (total): {} kb ({memory_readable})", + information.memory_total, )); let memory_text = if let Some(memory_used) = diff --git a/examples/todos/src/main.rs b/examples/todos/src/main.rs index 501bf67e..3048a668 100644 --- a/examples/todos/src/main.rs +++ b/examples/todos/src/main.rs @@ -415,8 +415,7 @@ fn view_controls(tasks: &[Task], current_filter: Filter) -> Element { row![ text(format!( - "{} {} left", - tasks_left, + "{tasks_left} {} left", if tasks_left == 1 { "task" } else { "tasks" } )) .width(Length::Fill), diff --git a/examples/visible_bounds/src/main.rs b/examples/visible_bounds/src/main.rs index 42dfc24c..697badb4 100644 --- a/examples/visible_bounds/src/main.rs +++ b/examples/visible_bounds/src/main.rs @@ -94,7 +94,7 @@ impl Application for Example { data_row( label, match bounds { - Some(bounds) => format!("{:?}", bounds), + Some(bounds) => format!("{bounds:?}"), None => "not visible".to_string(), }, if bounds diff --git a/futures/src/subscription/tracker.rs b/futures/src/subscription/tracker.rs index 3a83da09..15ed5b87 100644 --- a/futures/src/subscription/tracker.rs +++ b/futures/src/subscription/tracker.rs @@ -147,8 +147,7 @@ impl Tracker { .for_each(|listener| { if let Err(error) = listener.try_send((event.clone(), status)) { log::warn!( - "Error sending event to subscription: {:?}", - error + "Error sending event to subscription: {error:?}" ); } }); diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs index 8bdf231d..ef5c4182 100644 --- a/renderer/src/lib.rs +++ b/renderer/src/lib.rs @@ -60,7 +60,7 @@ impl Renderer { pub fn draw_mesh(&mut self, mesh: Mesh) { match self { Self::TinySkia(_) => { - log::warn!("Unsupported mesh primitive: {:?}", mesh) + log::warn!("Unsupported mesh primitive: {mesh:?}") } #[cfg(feature = "wgpu")] Self::Wgpu(renderer) => { diff --git a/tiny_skia/src/backend.rs b/tiny_skia/src/backend.rs index c721d96e..65aca4b0 100644 --- a/tiny_skia/src/backend.rs +++ b/tiny_skia/src/backend.rs @@ -443,8 +443,7 @@ impl Backend { #[cfg(not(feature = "image"))] Primitive::Image { .. } => { log::warn!( - "Unsupported primitive in `iced_tiny_skia`: {:?}", - primitive + "Unsupported primitive in `iced_tiny_skia`: {primitive:?}", ); } #[cfg(feature = "svg")] @@ -473,8 +472,7 @@ impl Backend { #[cfg(not(feature = "svg"))] Primitive::Svg { .. } => { log::warn!( - "Unsupported primitive in `iced_tiny_skia`: {:?}", - primitive + "Unsupported primitive in `iced_tiny_skia`: {primitive:?}", ); } Primitive::Custom(primitive::Custom::Fill { diff --git a/wgpu/src/image/atlas.rs b/wgpu/src/image/atlas.rs index e3de1290..1253496b 100644 --- a/wgpu/src/image/atlas.rs +++ b/wgpu/src/image/atlas.rs @@ -86,7 +86,7 @@ impl Atlas { entry }; - log::info!("Allocated atlas entry: {:?}", entry); + log::info!("Allocated atlas entry: {entry:?}"); // It is a webgpu requirement that: // BufferCopyView.layout.bytes_per_row % wgpu::COPY_BYTES_PER_ROW_ALIGNMENT == 0 @@ -139,13 +139,13 @@ impl Atlas { } } - log::info!("Current atlas: {:?}", self); + log::info!("Current atlas: {self:?}"); Some(entry) } pub fn remove(&mut self, entry: &Entry) { - log::info!("Removing atlas entry: {:?}", entry); + log::info!("Removing atlas entry: {entry:?}"); match entry { Entry::Contiguous(allocation) => { @@ -258,7 +258,7 @@ impl Atlas { } fn deallocate(&mut self, allocation: &Allocation) { - log::info!("Deallocating atlas: {:?}", allocation); + log::info!("Deallocating atlas: {allocation:?}"); match allocation { Allocation::Full { layer } => { diff --git a/wgpu/src/image/vector.rs b/wgpu/src/image/vector.rs index 2c03d36b..6582bb82 100644 --- a/wgpu/src/image/vector.rs +++ b/wgpu/src/image/vector.rs @@ -152,7 +152,7 @@ impl Cache { let allocation = atlas.upload(device, encoder, width, height, &rgba)?; - log::debug!("allocating {} {}x{}", id, width, height); + log::debug!("allocating {id} {width}x{height}"); let _ = self.svg_hits.insert(id); let _ = self.rasterized_hits.insert(key); diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index a9521a15..1ddbe5fe 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -35,7 +35,7 @@ impl Compositor { ..Default::default() }); - log::info!("{:#?}", settings); + log::info!("{settings:#?}"); #[cfg(not(target_arch = "wasm32"))] if log::max_level() >= log::LevelFilter::Info { @@ -43,7 +43,7 @@ impl Compositor { .enumerate_adapters(settings.internal_backend) .map(|adapter| adapter.get_info()) .collect(); - log::info!("Available adapters: {:#?}", available_adapters); + log::info!("Available adapters: {available_adapters:#?}"); } #[allow(unsafe_code)] @@ -83,7 +83,7 @@ impl Compositor { }) })?; - log::info!("Selected format: {:?}", format); + log::info!("Selected format: {format:?}"); #[cfg(target_arch = "wasm32")] let limits = [wgpu::Limits::downlevel_webgl2_defaults() diff --git a/winit/src/application.rs b/winit/src/application.rs index d1689452..dec77e80 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -157,7 +157,7 @@ where ) .with_visible(false); - log::debug!("Window builder: {:#?}", builder); + log::debug!("Window builder: {builder:#?}"); let window = builder .build(&event_loop) @@ -174,7 +174,7 @@ where let body = document.body().unwrap(); let target = target.and_then(|target| { - body.query_selector(&format!("#{}", target)) + body.query_selector(&format!("#{target}")) .ok() .unwrap_or(None) }); diff --git a/winit/src/clipboard.rs b/winit/src/clipboard.rs index 7271441d..8b6c83ce 100644 --- a/winit/src/clipboard.rs +++ b/winit/src/clipboard.rs @@ -45,7 +45,7 @@ impl Clipboard { State::Connected(clipboard) => match clipboard.write(contents) { Ok(()) => {} Err(error) => { - log::warn!("error writing to clipboard: {}", error) + log::warn!("error writing to clipboard: {error}") } }, State::Unavailable => {} From c997aad85d7ee6e77085e50e5e599002549d228f Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Tue, 19 Sep 2023 01:46:46 -0400 Subject: [PATCH 221/321] Chore: Apply clippy map transformations Convert `.map().unwrap_or()` to `.map_or()` and similar transformations. --- core/src/mouse/click.rs | 4 +--- examples/integration/src/main.rs | 6 ++++-- examples/screenshot/src/main.rs | 5 +---- wgpu/src/image/vector.rs | 2 +- wgpu/src/triangle.rs | 2 +- winit/src/application/state.rs | 3 +-- winit/src/clipboard.rs | 3 +-- 7 files changed, 10 insertions(+), 15 deletions(-) diff --git a/core/src/mouse/click.rs b/core/src/mouse/click.rs index 4a7d796c..240e5c64 100644 --- a/core/src/mouse/click.rs +++ b/core/src/mouse/click.rs @@ -69,8 +69,6 @@ impl Click { }; self.position == new_position - && duration - .map(|duration| duration.as_millis() <= 300) - .unwrap_or(false) + && duration.is_some_and(|duration| duration.as_millis() <= 300) } } diff --git a/examples/integration/src/main.rs b/examples/integration/src/main.rs index 7945bd20..243297b2 100644 --- a/examples/integration/src/main.rs +++ b/examples/integration/src/main.rs @@ -200,8 +200,10 @@ pub fn main() -> Result<(), Box> { viewport.scale_factor(), ) }) - .map(mouse::Cursor::Available) - .unwrap_or(mouse::Cursor::Unavailable), + .map_or( + mouse::Cursor::Unavailable, + mouse::Cursor::Available, + ), &mut renderer, &Theme::Dark, &renderer::Style { diff --git a/examples/screenshot/src/main.rs b/examples/screenshot/src/main.rs index 68c9d031..4dc1b051 100644 --- a/examples/screenshot/src/main.rs +++ b/examples/screenshot/src/main.rs @@ -293,10 +293,7 @@ fn numeric_input( ) -> Element<'_, Option> { text_input( placeholder, - &value - .as_ref() - .map(ToString::to_string) - .unwrap_or_else(String::new), + &value.as_ref().map_or_else(String::new, ToString::to_string), ) .on_input(move |text| { if text.is_empty() { diff --git a/wgpu/src/image/vector.rs b/wgpu/src/image/vector.rs index 2c03d36b..1ac82bc7 100644 --- a/wgpu/src/image/vector.rs +++ b/wgpu/src/image/vector.rs @@ -56,7 +56,7 @@ impl Cache { .ok() }); - tree.map(Svg::Loaded).unwrap_or(Svg::NotFound) + tree.map_or(Svg::NotFound, Svg::Loaded) } svg::Data::Bytes(bytes) => { match usvg::Tree::from_data(bytes, &usvg::Options::default()) { diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs index d430e607..7e1bd9cc 100644 --- a/wgpu/src/triangle.rs +++ b/wgpu/src/triangle.rs @@ -349,7 +349,7 @@ fn multisample_state( antialiasing: Option, ) -> wgpu::MultisampleState { wgpu::MultisampleState { - count: antialiasing.map(|a| a.sample_count()).unwrap_or(1), + count: antialiasing.map_or(1, Antialiasing::sample_count), mask: !0, alpha_to_coverage_enabled: false, } diff --git a/winit/src/application/state.rs b/winit/src/application/state.rs index e655529a..9d1d5dcf 100644 --- a/winit/src/application/state.rs +++ b/winit/src/application/state.rs @@ -97,8 +97,7 @@ where self.viewport.scale_factor(), ) }) - .map(mouse::Cursor::Available) - .unwrap_or(mouse::Cursor::Unavailable) + .map_or(mouse::Cursor::Unavailable, mouse::Cursor::Available) } /// Returns the current keyboard modifiers of the [`State`]. diff --git a/winit/src/clipboard.rs b/winit/src/clipboard.rs index 7271441d..14bbcbee 100644 --- a/winit/src/clipboard.rs +++ b/winit/src/clipboard.rs @@ -17,8 +17,7 @@ impl Clipboard { pub fn connect(window: &winit::window::Window) -> Clipboard { let state = window_clipboard::Clipboard::connect(window) .ok() - .map(State::Connected) - .unwrap_or(State::Unavailable); + .map_or(State::Unavailable, State::Connected); Clipboard { state } } From c6554d990770b941b5003d6ef40af3f9dedcd052 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Tue, 19 Sep 2023 01:50:05 -0400 Subject: [PATCH 222/321] Chore: Apply clippy docs keyword quoting Add quotes a number of doc strings like `sRGB` --- core/src/color.rs | 2 +- core/src/window/icon.rs | 2 +- futures/src/subscription.rs | 4 ++-- graphics/src/compositor.rs | 2 +- runtime/src/window/screenshot.rs | 2 +- style/src/rule.rs | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/color.rs b/core/src/color.rs index 1392f28b..0e8b7475 100644 --- a/core/src/color.rs +++ b/core/src/color.rs @@ -1,7 +1,7 @@ #[cfg(feature = "palette")] use palette::rgb::{Srgb, Srgba}; -/// A color in the sRGB color space. +/// A color in the `sRGB` color space. #[derive(Debug, Clone, Copy, PartialEq, Default)] pub struct Color { /// Red component, 0.0 - 1.0 diff --git a/core/src/window/icon.rs b/core/src/window/icon.rs index 2fc48e3b..5ef0eed7 100644 --- a/core/src/window/icon.rs +++ b/core/src/window/icon.rs @@ -3,7 +3,7 @@ use crate::Size; use std::mem; -/// Builds an [`Icon`] from its RGBA pixels in the sRGB color space. +/// Builds an [`Icon`] from its RGBA pixels in the `sRGB` color space. pub fn from_rgba( rgba: Vec, width: u32, diff --git a/futures/src/subscription.rs b/futures/src/subscription.rs index d40125e3..7163248d 100644 --- a/futures/src/subscription.rs +++ b/futures/src/subscription.rs @@ -25,7 +25,7 @@ pub type EventStream = BoxStream<(Event, event::Status)>; /// A [`Subscription`] is normally provided to some runtime, like a `Command`, /// and it will generate events as long as the user keeps requesting it. /// -/// For instance, you can use a [`Subscription`] to listen to a WebSocket +/// For instance, you can use a [`Subscription`] to listen to a `WebSocket` /// connection, keyboard presses, mouse events, time ticks, etc. #[must_use = "`Subscription` must be returned to runtime to take effect"] pub struct Subscription { @@ -355,7 +355,7 @@ where /// } /// ``` /// -/// Check out the [`websocket`] example, which showcases this pattern to maintain a WebSocket +/// Check out the [`websocket`] example, which showcases this pattern to maintain a `WebSocket` /// connection open. /// /// [`websocket`]: https://github.com/iced-rs/iced/tree/0.10/examples/websocket diff --git a/graphics/src/compositor.rs b/graphics/src/compositor.rs index 7173ffa7..0222a80f 100644 --- a/graphics/src/compositor.rs +++ b/graphics/src/compositor.rs @@ -61,7 +61,7 @@ pub trait Compositor: Sized { ) -> Result<(), SurfaceError>; /// Screenshots the current [`Renderer`] primitives to an offscreen texture, and returns the bytes of - /// the texture ordered as `RGBA` in the sRGB color space. + /// the texture ordered as `RGBA` in the `sRGB` color space. /// /// [`Renderer`]: Self::Renderer fn screenshot>( diff --git a/runtime/src/window/screenshot.rs b/runtime/src/window/screenshot.rs index c84286b6..21e04718 100644 --- a/runtime/src/window/screenshot.rs +++ b/runtime/src/window/screenshot.rs @@ -6,7 +6,7 @@ use std::sync::Arc; /// Data of a screenshot, captured with `window::screenshot()`. /// -/// The `bytes` of this screenshot will always be ordered as `RGBA` in the sRGB color space. +/// The `bytes` of this screenshot will always be ordered as `RGBA` in the `sRGB` color space. #[derive(Clone)] pub struct Screenshot { /// The bytes of the [`Screenshot`]. diff --git a/style/src/rule.rs b/style/src/rule.rs index afae085c..efbe7444 100644 --- a/style/src/rule.rs +++ b/style/src/rule.rs @@ -47,7 +47,7 @@ impl FillMode { /// /// # Returns /// - /// * (starting_offset, length) + /// * (`starting_offset`, `length`) pub fn fill(&self, space: f32) -> (f32, f32) { match *self { FillMode::Full => (0.0, space), From efd0ff6ded4e647e5fad0964555dbed541a075d7 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Tue, 19 Sep 2023 01:52:25 -0400 Subject: [PATCH 223/321] Chore: Apply some minor clippy fixes * Use `.elapsed()` for duration * Use direct iteration without calling `.iter()` and the like * order fields in the `Text` struct creation as declared --- core/src/gradient.rs | 2 +- core/src/widget/text.rs | 2 +- examples/game_of_life/src/main.rs | 2 +- examples/tour/src/main.rs | 2 +- graphics/src/gradient.rs | 2 +- runtime/src/debug/basic.rs | 20 +++++++------------- tiny_skia/src/geometry.rs | 2 +- 7 files changed, 13 insertions(+), 19 deletions(-) diff --git a/core/src/gradient.rs b/core/src/gradient.rs index 4a0d5ea0..6a5533f8 100644 --- a/core/src/gradient.rs +++ b/core/src/gradient.rs @@ -94,7 +94,7 @@ impl Linear { mut self, stops: impl IntoIterator, ) -> Self { - for stop in stops.into_iter() { + for stop in stops { self = self.add_stop(stop.offset, stop.color) } diff --git a/core/src/widget/text.rs b/core/src/widget/text.rs index 53ed463e..ba98f2d8 100644 --- a/core/src/widget/text.rs +++ b/core/src/widget/text.rs @@ -220,9 +220,9 @@ where size, line_height, font, - shaping, horizontal_alignment, vertical_alignment, + shaping, }, ); diff --git a/examples/game_of_life/src/main.rs b/examples/game_of_life/src/main.rs index e451cb06..e3089beb 100644 --- a/examples/game_of_life/src/main.rs +++ b/examples/game_of_life/src/main.rs @@ -793,7 +793,7 @@ mod grid { } } - for (cell, amount) in adjacent_life.iter() { + for (cell, amount) in &adjacent_life { match amount { 2 => {} 3 => { diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs index 3e3a8ad7..952300bb 100644 --- a/examples/tour/src/main.rs +++ b/examples/tour/src/main.rs @@ -482,7 +482,7 @@ impl<'a> Step { column( Language::all() .iter() - .cloned() + .copied() .map(|language| { radio( language, diff --git a/graphics/src/gradient.rs b/graphics/src/gradient.rs index b274ec86..7460e12e 100644 --- a/graphics/src/gradient.rs +++ b/graphics/src/gradient.rs @@ -87,7 +87,7 @@ impl Linear { mut self, stops: impl IntoIterator, ) -> Self { - for stop in stops.into_iter() { + for stop in stops { self = self.add_stop(stop.offset, stop.color) } diff --git a/runtime/src/debug/basic.rs b/runtime/src/debug/basic.rs index 32f725a1..4c994a2f 100644 --- a/runtime/src/debug/basic.rs +++ b/runtime/src/debug/basic.rs @@ -75,7 +75,7 @@ impl Debug { } pub fn startup_finished(&mut self) { - self.startup_duration = time::Instant::now() - self.startup_start; + self.startup_duration = self.startup_start.elapsed(); } pub fn update_started(&mut self) { @@ -83,8 +83,7 @@ impl Debug { } pub fn update_finished(&mut self) { - self.update_durations - .push(time::Instant::now() - self.update_start); + self.update_durations.push(self.update_start.elapsed()); } pub fn view_started(&mut self) { @@ -92,8 +91,7 @@ impl Debug { } pub fn view_finished(&mut self) { - self.view_durations - .push(time::Instant::now() - self.view_start); + self.view_durations.push(self.view_start.elapsed()); } pub fn layout_started(&mut self) { @@ -101,8 +99,7 @@ impl Debug { } pub fn layout_finished(&mut self) { - self.layout_durations - .push(time::Instant::now() - self.layout_start); + self.layout_durations.push(self.layout_start.elapsed()); } pub fn event_processing_started(&mut self) { @@ -110,8 +107,7 @@ impl Debug { } pub fn event_processing_finished(&mut self) { - self.event_durations - .push(time::Instant::now() - self.event_start); + self.event_durations.push(self.event_start.elapsed()); } pub fn draw_started(&mut self) { @@ -119,8 +115,7 @@ impl Debug { } pub fn draw_finished(&mut self) { - self.draw_durations - .push(time::Instant::now() - self.draw_start); + self.draw_durations.push(self.draw_start.elapsed()); } pub fn render_started(&mut self) { @@ -128,8 +123,7 @@ impl Debug { } pub fn render_finished(&mut self) { - self.render_durations - .push(time::Instant::now() - self.render_start); + self.render_durations.push(self.render_start.elapsed()); } pub fn log_message(&mut self, message: &Message) { diff --git a/tiny_skia/src/geometry.rs b/tiny_skia/src/geometry.rs index 047bc0ff..1d573f6a 100644 --- a/tiny_skia/src/geometry.rs +++ b/tiny_skia/src/geometry.rs @@ -182,7 +182,7 @@ fn convert_path(path: &Path) -> Option { let mut builder = tiny_skia::PathBuilder::new(); let mut last_point = Default::default(); - for event in path.raw().iter() { + for event in path.raw() { match event { lyon_path::Event::Begin { at } => { builder.move_to(at.x, at.y); From 06dc12bfbf75958c6534306b3d1b57ae47bdb37a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 19 Sep 2023 19:35:28 +0200 Subject: [PATCH 224/321] Simplify `editor` example --- examples/editor/src/main.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs index 277eb3e9..6def2082 100644 --- a/examples/editor/src/main.rs +++ b/examples/editor/src/main.rs @@ -4,7 +4,7 @@ use iced::widget::{ button, column, container, horizontal_space, pick_list, row, text, text_editor, tooltip, }; -use iced::{Application, Command, Element, Font, Length, Settings}; +use iced::{Alignment, Application, Command, Element, Font, Length, Settings}; use highlighter::Highlighter; @@ -169,7 +169,8 @@ impl Application for Editor { .text_size(14) .padding([5, 10]) ] - .spacing(10); + .spacing(10) + .align_items(Alignment::Center); let status = row![ text(if let Some(path) = &self.file { @@ -275,8 +276,7 @@ fn action<'a, Message: Clone + 'a>( label: &'a str, on_press: Option, ) -> Element<'a, Message> { - let action = - button(container(content).width(Length::Fill).center_x()).width(40); + let action = button(container(content).width(30).center_x()); if let Some(on_press) = on_press { tooltip( @@ -316,7 +316,7 @@ mod highlighter { use std::ops::Range; use syntect::highlighting; - use syntect::parsing::{self, SyntaxReference}; + use syntect::parsing; #[derive(Debug, Clone, PartialEq)] pub struct Settings { @@ -374,7 +374,7 @@ mod highlighter { pub struct Highlighter { syntaxes: parsing::SyntaxSet, - syntax: SyntaxReference, + syntax: parsing::SyntaxReference, theme: highlighting::Theme, caches: Vec<(parsing::ParseState, parsing::ScopeStack)>, current_line: usize, From c0a141ab026f5686d6bd92c8807b174396cb9105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 19 Sep 2023 19:39:23 +0200 Subject: [PATCH 225/321] Save file on `Cmd+S` in `editor` example --- examples/editor/src/main.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs index 6def2082..36d4287c 100644 --- a/examples/editor/src/main.rs +++ b/examples/editor/src/main.rs @@ -1,10 +1,14 @@ use iced::executor; +use iced::keyboard; use iced::theme::{self, Theme}; use iced::widget::{ button, column, container, horizontal_space, pick_list, row, text, text_editor, tooltip, }; -use iced::{Alignment, Application, Command, Element, Font, Length, Settings}; +use iced::{ + Alignment, Application, Command, Element, Font, Length, Settings, + Subscription, +}; use highlighter::Highlighter; @@ -147,6 +151,15 @@ impl Application for Editor { } } + fn subscription(&self) -> Subscription { + keyboard::on_key_press(|key_code, modifiers| match key_code { + keyboard::KeyCode::S if modifiers.command() => { + Some(Message::SaveFile) + } + _ => None, + }) + } + fn view(&self) -> Element { let controls = row![ action(new_icon(), "New file", Some(Message::NewFile)), From f806d001e6fb44b5a45029ca257261e6e0d4d4b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 19 Sep 2023 20:48:50 +0200 Subject: [PATCH 226/321] Introduce new `iced_highlighter` subcrate --- Cargo.toml | 10 +- core/src/text/highlighter.rs | 11 +- examples/editor/Cargo.toml | 2 +- examples/editor/src/main.rs | 251 ++--------------------------------- highlighter/Cargo.toml | 16 +++ highlighter/src/lib.rs | 225 +++++++++++++++++++++++++++++++ src/lib.rs | 3 + style/src/text_editor.rs | 16 +-- widget/src/text_editor.rs | 28 +++- 9 files changed, 302 insertions(+), 260 deletions(-) create mode 100644 highlighter/Cargo.toml create mode 100644 highlighter/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index e887afc0..8899fa67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,6 +47,8 @@ system = ["iced_winit/system"] web-colors = ["iced_renderer/web-colors"] # Enables the WebGL backend, replacing WebGPU webgl = ["iced_renderer/webgl"] +# Enables the syntax `highlighter` module +highlighter = ["iced_highlighter"] # Enables the advanced module advanced = [] @@ -58,6 +60,9 @@ iced_widget.workspace = true iced_winit.features = ["application"] iced_winit.workspace = true +iced_highlighter.workspace = true +iced_highlighter.optional = true + thiserror.workspace = true image.workspace = true @@ -78,8 +83,9 @@ members = [ "core", "futures", "graphics", - "runtime", + "highlighter", "renderer", + "runtime", "style", "tiny_skia", "wgpu", @@ -103,6 +109,7 @@ iced = { version = "0.12", path = "." } iced_core = { version = "0.12", path = "core" } iced_futures = { version = "0.12", path = "futures" } iced_graphics = { version = "0.12", path = "graphics" } +iced_highlighter = { version = "0.12", path = "highlighter" } iced_renderer = { version = "0.12", path = "renderer" } iced_runtime = { version = "0.12", path = "runtime" } iced_style = { version = "0.12", path = "style" } @@ -137,6 +144,7 @@ resvg = "0.35" rustc-hash = "1.0" smol = "1.0" softbuffer = "0.2" +syntect = "5.1" sysinfo = "0.28" thiserror = "1.0" tiny-skia = "0.10" diff --git a/core/src/text/highlighter.rs b/core/src/text/highlighter.rs index b462d083..9a9cff89 100644 --- a/core/src/text/highlighter.rs +++ b/core/src/text/highlighter.rs @@ -52,8 +52,17 @@ impl Highlighter for PlainText { } } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq)] pub struct Format { pub color: Option, pub font: Option, } + +impl Default for Format { + fn default() -> Self { + Self { + color: None, + font: None, + } + } +} diff --git a/examples/editor/Cargo.toml b/examples/editor/Cargo.toml index eeb34aa1..a77b1e9f 100644 --- a/examples/editor/Cargo.toml +++ b/examples/editor/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies] iced.workspace = true -iced.features = ["advanced", "tokio", "debug"] +iced.features = ["highlighter", "tokio", "debug"] tokio.workspace = true tokio.features = ["fs"] diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs index 36d4287c..d513090f 100644 --- a/examples/editor/src/main.rs +++ b/examples/editor/src/main.rs @@ -1,4 +1,5 @@ use iced::executor; +use iced::highlighter::{self, Highlighter}; use iced::keyboard; use iced::theme::{self, Theme}; use iced::widget::{ @@ -10,8 +11,6 @@ use iced::{ Subscription, }; -use highlighter::Highlighter; - use std::ffi; use std::io; use std::path::{Path, PathBuf}; @@ -210,16 +209,19 @@ impl Application for Editor { controls, text_editor(&self.content) .on_edit(Message::Edit) - .highlight::(highlighter::Settings { - theme: self.theme, - extension: self - .file - .as_deref() - .and_then(Path::extension) - .and_then(ffi::OsStr::to_str) - .map(str::to_string) - .unwrap_or(String::from("rs")), - }), + .highlight::( + highlighter::Settings { + theme: self.theme, + extension: self + .file + .as_deref() + .and_then(Path::extension) + .and_then(ffi::OsStr::to_str) + .map(str::to_string) + .unwrap_or(String::from("rs")), + }, + |highlight, _theme| highlight.to_format() + ), status, ] .spacing(10) @@ -321,228 +323,3 @@ fn icon<'a, Message>(codepoint: char) -> Element<'a, Message> { text(codepoint).font(ICON_FONT).into() } - -mod highlighter { - use iced::advanced::text::highlighter; - use iced::widget::text_editor; - use iced::{Color, Font}; - - use std::ops::Range; - use syntect::highlighting; - use syntect::parsing; - - #[derive(Debug, Clone, PartialEq)] - pub struct Settings { - pub theme: Theme, - pub extension: String, - } - - #[derive(Debug, Clone, Copy, PartialEq, Eq)] - pub enum Theme { - SolarizedDark, - InspiredGitHub, - Base16Mocha, - } - - impl Theme { - pub const ALL: &[Self] = - &[Self::SolarizedDark, Self::InspiredGitHub, Self::Base16Mocha]; - - fn key(&self) -> &'static str { - match self { - Theme::InspiredGitHub => "InspiredGitHub", - Theme::Base16Mocha => "base16-mocha.dark", - Theme::SolarizedDark => "Solarized (dark)", - } - } - } - - impl std::fmt::Display for Theme { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Theme::InspiredGitHub => write!(f, "Inspired GitHub"), - Theme::Base16Mocha => write!(f, "Mocha"), - Theme::SolarizedDark => write!(f, "Solarized Dark"), - } - } - } - - pub struct Highlight(highlighting::StyleModifier); - - impl text_editor::Highlight for Highlight { - fn format(&self, _theme: &iced::Theme) -> highlighter::Format { - highlighter::Format { - color: self.0.foreground.map(|color| { - Color::from_rgba8( - color.r, - color.g, - color.b, - color.a as f32 / 255.0, - ) - }), - font: None, - } - } - } - - pub struct Highlighter { - syntaxes: parsing::SyntaxSet, - syntax: parsing::SyntaxReference, - theme: highlighting::Theme, - caches: Vec<(parsing::ParseState, parsing::ScopeStack)>, - current_line: usize, - } - - const LINES_PER_SNAPSHOT: usize = 50; - - impl highlighter::Highlighter for Highlighter { - type Settings = Settings; - type Highlight = Highlight; - - type Iterator<'a> = - Box, Self::Highlight)> + 'a>; - - fn new(settings: &Self::Settings) -> Self { - let syntaxes = parsing::SyntaxSet::load_defaults_nonewlines(); - - let syntax = syntaxes - .find_syntax_by_token(&settings.extension) - .unwrap_or_else(|| syntaxes.find_syntax_plain_text()); - - let theme = highlighting::ThemeSet::load_defaults() - .themes - .remove(settings.theme.key()) - .unwrap(); - - let parser = parsing::ParseState::new(syntax); - let stack = parsing::ScopeStack::new(); - - Highlighter { - syntax: syntax.clone(), - syntaxes, - theme, - caches: vec![(parser, stack)], - current_line: 0, - } - } - - fn update(&mut self, new_settings: &Self::Settings) { - self.syntax = self - .syntaxes - .find_syntax_by_token(&new_settings.extension) - .unwrap_or_else(|| self.syntaxes.find_syntax_plain_text()) - .clone(); - - self.theme = highlighting::ThemeSet::load_defaults() - .themes - .remove(new_settings.theme.key()) - .unwrap(); - - // Restart the highlighter - self.change_line(0); - } - - fn change_line(&mut self, line: usize) { - let snapshot = line / LINES_PER_SNAPSHOT; - - if snapshot <= self.caches.len() { - self.caches.truncate(snapshot); - self.current_line = snapshot * LINES_PER_SNAPSHOT; - } else { - self.caches.truncate(1); - self.current_line = 0; - } - - let (parser, stack) = - self.caches.last().cloned().unwrap_or_else(|| { - ( - parsing::ParseState::new(&self.syntax), - parsing::ScopeStack::new(), - ) - }); - - self.caches.push((parser, stack)); - } - - fn highlight_line(&mut self, line: &str) -> Self::Iterator<'_> { - if self.current_line / LINES_PER_SNAPSHOT >= self.caches.len() { - let (parser, stack) = - self.caches.last().expect("Caches must not be empty"); - - self.caches.push((parser.clone(), stack.clone())); - } - - self.current_line += 1; - - let (parser, stack) = - self.caches.last_mut().expect("Caches must not be empty"); - - let ops = - parser.parse_line(line, &self.syntaxes).unwrap_or_default(); - - let highlighter = highlighting::Highlighter::new(&self.theme); - - Box::new( - ScopeRangeIterator { - ops, - line_length: line.len(), - index: 0, - last_str_index: 0, - } - .filter_map(move |(range, scope)| { - let _ = stack.apply(&scope); - - if range.is_empty() { - None - } else { - Some(( - range, - Highlight( - highlighter.style_mod_for_stack(&stack.scopes), - ), - )) - } - }), - ) - } - - fn current_line(&self) -> usize { - self.current_line - } - } - - pub struct ScopeRangeIterator { - ops: Vec<(usize, parsing::ScopeStackOp)>, - line_length: usize, - index: usize, - last_str_index: usize, - } - - impl Iterator for ScopeRangeIterator { - type Item = (std::ops::Range, parsing::ScopeStackOp); - - fn next(&mut self) -> Option { - if self.index > self.ops.len() { - return None; - } - - let next_str_i = if self.index == self.ops.len() { - self.line_length - } else { - self.ops[self.index].0 - }; - - let range = self.last_str_index..next_str_i; - self.last_str_index = next_str_i; - - let op = if self.index == 0 { - parsing::ScopeStackOp::Noop - } else { - self.ops[self.index - 1].1.clone() - }; - - self.index += 1; - Some((range, op)) - } - } -} diff --git a/highlighter/Cargo.toml b/highlighter/Cargo.toml new file mode 100644 index 00000000..311d2998 --- /dev/null +++ b/highlighter/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "iced_highlighter" +description = "A syntax higlighter for iced" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true +categories.workspace = true +keywords.workspace = true + +[dependencies] +iced_core.workspace = true + +syntect.workspace = true diff --git a/highlighter/src/lib.rs b/highlighter/src/lib.rs new file mode 100644 index 00000000..79cfafcd --- /dev/null +++ b/highlighter/src/lib.rs @@ -0,0 +1,225 @@ +use iced_core as core; + +use crate::core::text::highlighter::{self, Format}; +use crate::core::{Color, Font}; + +use std::ops::Range; +use syntect::highlighting; +use syntect::parsing; + +pub struct Highlighter { + syntaxes: parsing::SyntaxSet, + syntax: parsing::SyntaxReference, + theme: highlighting::Theme, + caches: Vec<(parsing::ParseState, parsing::ScopeStack)>, + current_line: usize, +} + +const LINES_PER_SNAPSHOT: usize = 50; + +impl highlighter::Highlighter for Highlighter { + type Settings = Settings; + type Highlight = Highlight; + + type Iterator<'a> = + Box, Self::Highlight)> + 'a>; + + fn new(settings: &Self::Settings) -> Self { + let syntaxes = parsing::SyntaxSet::load_defaults_nonewlines(); + + let syntax = syntaxes + .find_syntax_by_token(&settings.extension) + .unwrap_or_else(|| syntaxes.find_syntax_plain_text()); + + let theme = highlighting::ThemeSet::load_defaults() + .themes + .remove(settings.theme.key()) + .unwrap(); + + let parser = parsing::ParseState::new(syntax); + let stack = parsing::ScopeStack::new(); + + Highlighter { + syntax: syntax.clone(), + syntaxes, + theme, + caches: vec![(parser, stack)], + current_line: 0, + } + } + + fn update(&mut self, new_settings: &Self::Settings) { + self.syntax = self + .syntaxes + .find_syntax_by_token(&new_settings.extension) + .unwrap_or_else(|| self.syntaxes.find_syntax_plain_text()) + .clone(); + + self.theme = highlighting::ThemeSet::load_defaults() + .themes + .remove(new_settings.theme.key()) + .unwrap(); + + // Restart the highlighter + self.change_line(0); + } + + fn change_line(&mut self, line: usize) { + let snapshot = line / LINES_PER_SNAPSHOT; + + if snapshot <= self.caches.len() { + self.caches.truncate(snapshot); + self.current_line = snapshot * LINES_PER_SNAPSHOT; + } else { + self.caches.truncate(1); + self.current_line = 0; + } + + let (parser, stack) = + self.caches.last().cloned().unwrap_or_else(|| { + ( + parsing::ParseState::new(&self.syntax), + parsing::ScopeStack::new(), + ) + }); + + self.caches.push((parser, stack)); + } + + fn highlight_line(&mut self, line: &str) -> Self::Iterator<'_> { + if self.current_line / LINES_PER_SNAPSHOT >= self.caches.len() { + let (parser, stack) = + self.caches.last().expect("Caches must not be empty"); + + self.caches.push((parser.clone(), stack.clone())); + } + + self.current_line += 1; + + let (parser, stack) = + self.caches.last_mut().expect("Caches must not be empty"); + + let ops = parser.parse_line(line, &self.syntaxes).unwrap_or_default(); + + let highlighter = highlighting::Highlighter::new(&self.theme); + + Box::new( + ScopeRangeIterator { + ops, + line_length: line.len(), + index: 0, + last_str_index: 0, + } + .filter_map(move |(range, scope)| { + let _ = stack.apply(&scope); + + if range.is_empty() { + None + } else { + Some(( + range, + Highlight( + highlighter.style_mod_for_stack(&stack.scopes), + ), + )) + } + }), + ) + } + + fn current_line(&self) -> usize { + self.current_line + } +} + +#[derive(Debug, Clone, PartialEq)] +pub struct Settings { + pub theme: Theme, + pub extension: String, +} + +pub struct Highlight(highlighting::StyleModifier); + +impl Highlight { + pub fn color(&self) -> Option { + self.0.foreground.map(|color| { + Color::from_rgba8(color.r, color.g, color.b, color.a as f32 / 255.0) + }) + } + + pub fn font(&self) -> Option { + None + } + + pub fn to_format(&self) -> Format { + Format { + color: self.color(), + font: self.font(), + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Theme { + SolarizedDark, + InspiredGitHub, + Base16Mocha, +} + +impl Theme { + pub const ALL: &[Self] = + &[Self::SolarizedDark, Self::InspiredGitHub, Self::Base16Mocha]; + + fn key(&self) -> &'static str { + match self { + Theme::InspiredGitHub => "InspiredGitHub", + Theme::Base16Mocha => "base16-mocha.dark", + Theme::SolarizedDark => "Solarized (dark)", + } + } +} + +impl std::fmt::Display for Theme { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Theme::InspiredGitHub => write!(f, "Inspired GitHub"), + Theme::Base16Mocha => write!(f, "Mocha"), + Theme::SolarizedDark => write!(f, "Solarized Dark"), + } + } +} + +pub struct ScopeRangeIterator { + ops: Vec<(usize, parsing::ScopeStackOp)>, + line_length: usize, + index: usize, + last_str_index: usize, +} + +impl Iterator for ScopeRangeIterator { + type Item = (std::ops::Range, parsing::ScopeStackOp); + + fn next(&mut self) -> Option { + if self.index > self.ops.len() { + return None; + } + + let next_str_i = if self.index == self.ops.len() { + self.line_length + } else { + self.ops[self.index].0 + }; + + let range = self.last_str_index..next_str_i; + self.last_str_index = next_str_i; + + let op = if self.index == 0 { + parsing::ScopeStackOp::Noop + } else { + self.ops[self.index - 1].1.clone() + }; + + self.index += 1; + Some((range, op)) + } +} diff --git a/src/lib.rs b/src/lib.rs index 3cbe716a..e435a041 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -174,6 +174,9 @@ use iced_winit::runtime; pub use iced_futures::futures; +#[cfg(feature = "highlighter")] +pub use iced_highlighter as highlighter; + mod error; mod sandbox; diff --git a/style/src/text_editor.rs b/style/src/text_editor.rs index f1c31287..f6bae7e6 100644 --- a/style/src/text_editor.rs +++ b/style/src/text_editor.rs @@ -1,6 +1,5 @@ //! Change the appearance of a text editor. -use crate::core::text::highlighter; -use crate::core::{self, Background, BorderRadius, Color}; +use crate::core::{Background, BorderRadius, Color}; /// The appearance of a text input. #[derive(Debug, Clone, Copy)] @@ -46,16 +45,3 @@ pub trait StyleSheet { /// Produces the style of a disabled text input. fn disabled(&self, style: &Self::Style) -> Appearance; } - -pub trait Highlight { - fn format(&self, theme: &Theme) -> highlighter::Format; -} - -impl Highlight for () { - fn format(&self, _theme: &Theme) -> highlighter::Format { - highlighter::Format { - color: None, - font: None, - } - } -} diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index ad12a076..c384b8a2 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -16,7 +16,7 @@ use std::cell::RefCell; use std::ops::DerefMut; use std::sync::Arc; -pub use crate::style::text_editor::{Appearance, Highlight, StyleSheet}; +pub use crate::style::text_editor::{Appearance, StyleSheet}; pub use text::editor::{Action, Edit, Motion}; pub struct TextEditor<'a, Highlighter, Message, Renderer = crate::Renderer> @@ -35,6 +35,10 @@ where style: ::Style, on_edit: Option Message + 'a>>, highlighter_settings: Highlighter::Settings, + highlighter_format: fn( + &Highlighter::Highlight, + &Renderer::Theme, + ) -> highlighter::Format, } impl<'a, Message, Renderer> @@ -55,6 +59,9 @@ where style: Default::default(), on_edit: None, highlighter_settings: (), + highlighter_format: |_highlight, _theme| { + highlighter::Format::default() + }, } } } @@ -63,7 +70,6 @@ impl<'a, Highlighter, Message, Renderer> TextEditor<'a, Highlighter, Message, Renderer> where Highlighter: text::Highlighter, - Highlighter::Highlight: Highlight, Renderer: text::Renderer, Renderer::Theme: StyleSheet, { @@ -85,6 +91,10 @@ where pub fn highlight( self, settings: H::Settings, + to_format: fn( + &H::Highlight, + &Renderer::Theme, + ) -> highlighter::Format, ) -> TextEditor<'a, H, Message, Renderer> { TextEditor { content: self.content, @@ -97,6 +107,7 @@ where style: self.style, on_edit: self.on_edit, highlighter_settings: settings, + highlighter_format: to_format, } } } @@ -203,13 +214,13 @@ struct State { drag_click: Option, highlighter: RefCell, highlighter_settings: Highlighter::Settings, + highlighter_format_address: usize, } impl<'a, Highlighter, Message, Renderer> Widget for TextEditor<'a, Highlighter, Message, Renderer> where Highlighter: text::Highlighter, - Highlighter::Highlight: Highlight, Renderer: text::Renderer, Renderer::Theme: StyleSheet, { @@ -226,6 +237,7 @@ where &self.highlighter_settings, )), highlighter_settings: self.highlighter_settings.clone(), + highlighter_format_address: self.highlighter_format as usize, }) } @@ -246,6 +258,13 @@ where let mut internal = self.content.0.borrow_mut(); let state = tree.state.downcast_mut::>(); + if state.highlighter_format_address != self.highlighter_format as usize + { + state.highlighter.borrow_mut().change_line(0); + + state.highlighter_format_address = self.highlighter_format as usize; + } + if state.highlighter_settings != self.highlighter_settings { state .highlighter @@ -354,7 +373,7 @@ where internal.editor.highlight( self.font.unwrap_or_else(|| renderer.default_font()), state.highlighter.borrow_mut().deref_mut(), - |highlight| highlight.format(theme), + |highlight| (self.highlighter_format)(highlight, theme), ); let is_disabled = self.on_edit.is_none(); @@ -458,7 +477,6 @@ impl<'a, Highlighter, Message, Renderer> for Element<'a, Message, Renderer> where Highlighter: text::Highlighter, - Highlighter::Highlight: Highlight, Message: 'a, Renderer: text::Renderer, Renderer::Theme: StyleSheet, From 77db1699028cf50fb92b9282ffd1f73507fce974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 19 Sep 2023 20:55:39 +0200 Subject: [PATCH 227/321] Fix typo in `higlighter` (why is it so hard to spell?) --- highlighter/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/highlighter/Cargo.toml b/highlighter/Cargo.toml index 311d2998..488546c0 100644 --- a/highlighter/Cargo.toml +++ b/highlighter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_highlighter" -description = "A syntax higlighter for iced" +description = "A syntax highlighter for iced" version.workspace = true authors.workspace = true edition.workspace = true From 01667446549d10fab18f3ca0306f278b0fe22b13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 19 Sep 2023 20:56:50 +0200 Subject: [PATCH 228/321] Add `iced_highlighter` to `document` workflow --- .github/workflows/document.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/document.yml b/.github/workflows/document.yml index 230c5cb0..62e28ca3 100644 --- a/.github/workflows/document.yml +++ b/.github/workflows/document.yml @@ -15,6 +15,7 @@ jobs: RUSTDOCFLAGS="--cfg docsrs" \ cargo doc --no-deps --all-features \ -p iced_core \ + -p iced_highlighter \ -p iced_style \ -p iced_futures \ -p iced_runtime \ From d9fbecf0d80234d63e7e5711f28fc35ee75fa503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 19 Sep 2023 20:58:15 +0200 Subject: [PATCH 229/321] Remove `syntect` dependency from `editor` example --- examples/editor/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/editor/Cargo.toml b/examples/editor/Cargo.toml index a77b1e9f..a3f6ea3b 100644 --- a/examples/editor/Cargo.toml +++ b/examples/editor/Cargo.toml @@ -12,5 +12,4 @@ iced.features = ["highlighter", "tokio", "debug"] tokio.workspace = true tokio.features = ["fs"] -syntect = "5.1" rfd = "0.12" From a9ee8f62fdd0f74976947c21199684829aa8a496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 19 Sep 2023 21:57:09 +0200 Subject: [PATCH 230/321] Reuse syntaxes and themes lazily in `iced_highlighter` --- highlighter/Cargo.toml | 1 + highlighter/src/lib.rs | 51 +++++++++++++++++++++--------------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/highlighter/Cargo.toml b/highlighter/Cargo.toml index 488546c0..2d108d6f 100644 --- a/highlighter/Cargo.toml +++ b/highlighter/Cargo.toml @@ -13,4 +13,5 @@ keywords.workspace = true [dependencies] iced_core.workspace = true +once_cell.workspace = true syntect.workspace = true diff --git a/highlighter/src/lib.rs b/highlighter/src/lib.rs index 79cfafcd..b80d6499 100644 --- a/highlighter/src/lib.rs +++ b/highlighter/src/lib.rs @@ -3,20 +3,26 @@ use iced_core as core; use crate::core::text::highlighter::{self, Format}; use crate::core::{Color, Font}; +use once_cell::sync::Lazy; use std::ops::Range; use syntect::highlighting; use syntect::parsing; +static SYNTAXES: Lazy = + Lazy::new(|| parsing::SyntaxSet::load_defaults_nonewlines()); + +static THEMES: Lazy = + Lazy::new(|| highlighting::ThemeSet::load_defaults()); + +const LINES_PER_SNAPSHOT: usize = 50; + pub struct Highlighter { - syntaxes: parsing::SyntaxSet, - syntax: parsing::SyntaxReference, - theme: highlighting::Theme, + syntax: &'static parsing::SyntaxReference, + highlighter: highlighting::Highlighter<'static>, caches: Vec<(parsing::ParseState, parsing::ScopeStack)>, current_line: usize, } -const LINES_PER_SNAPSHOT: usize = 50; - impl highlighter::Highlighter for Highlighter { type Settings = Settings; type Highlight = Highlight; @@ -25,40 +31,33 @@ impl highlighter::Highlighter for Highlighter { Box, Self::Highlight)> + 'a>; fn new(settings: &Self::Settings) -> Self { - let syntaxes = parsing::SyntaxSet::load_defaults_nonewlines(); - - let syntax = syntaxes + let syntax = SYNTAXES .find_syntax_by_token(&settings.extension) - .unwrap_or_else(|| syntaxes.find_syntax_plain_text()); + .unwrap_or_else(|| SYNTAXES.find_syntax_plain_text()); - let theme = highlighting::ThemeSet::load_defaults() - .themes - .remove(settings.theme.key()) - .unwrap(); + let highlighter = highlighting::Highlighter::new( + &THEMES.themes[settings.theme.key()], + ); let parser = parsing::ParseState::new(syntax); let stack = parsing::ScopeStack::new(); Highlighter { - syntax: syntax.clone(), - syntaxes, - theme, + syntax, + highlighter, caches: vec![(parser, stack)], current_line: 0, } } fn update(&mut self, new_settings: &Self::Settings) { - self.syntax = self - .syntaxes + self.syntax = SYNTAXES .find_syntax_by_token(&new_settings.extension) - .unwrap_or_else(|| self.syntaxes.find_syntax_plain_text()) - .clone(); + .unwrap_or_else(|| SYNTAXES.find_syntax_plain_text()); - self.theme = highlighting::ThemeSet::load_defaults() - .themes - .remove(new_settings.theme.key()) - .unwrap(); + self.highlighter = highlighting::Highlighter::new( + &THEMES.themes[new_settings.theme.key()], + ); // Restart the highlighter self.change_line(0); @@ -99,9 +98,9 @@ impl highlighter::Highlighter for Highlighter { let (parser, stack) = self.caches.last_mut().expect("Caches must not be empty"); - let ops = parser.parse_line(line, &self.syntaxes).unwrap_or_default(); + let ops = parser.parse_line(line, &SYNTAXES).unwrap_or_default(); - let highlighter = highlighting::Highlighter::new(&self.theme); + let highlighter = &self.highlighter; Box::new( ScopeRangeIterator { From 9af0a27e675b71164f32f8d82eb4cde9cdd459f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 19 Sep 2023 22:28:28 +0200 Subject: [PATCH 231/321] Draw colored glyphs in `iced_tiny_skia` --- tiny_skia/src/text.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index 96cfbf32..d1b33293 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -188,7 +188,7 @@ fn draw( if let Some((buffer, placement)) = glyph_cache.allocate( physical_glyph.cache_key, - color, + glyph.color_opt.map(from_color).unwrap_or(color), font_system, &mut swash, ) { @@ -213,6 +213,12 @@ fn draw( } } +fn from_color(color: cosmic_text::Color) -> Color { + let [r, g, b, a] = color.as_rgba(); + + Color::from_rgba8(r, g, b, a as f32 / 255.0) +} + #[derive(Debug, Clone, Default)] struct GlyphCache { entries: FxHashMap< From be340a8cd822be1ea0fe4c1b1f3a62ca66d705b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 19 Sep 2023 23:00:20 +0200 Subject: [PATCH 232/321] Fix gamma correction for colored glyphs in `iced_wgpu` --- core/src/color.rs | 20 ++++++++++++++++++++ graphics/src/text.rs | 10 ++++++++-- tiny_skia/src/text.rs | 14 +++++++++++++- wgpu/src/text.rs | 13 ++----------- 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/core/src/color.rs b/core/src/color.rs index 1392f28b..cce8b340 100644 --- a/core/src/color.rs +++ b/core/src/color.rs @@ -89,6 +89,26 @@ impl Color { } } + /// Creates a [`Color`] from its linear RGBA components. + pub fn from_linear_rgba(r: f32, g: f32, b: f32, a: f32) -> Self { + // As described in: + // https://en.wikipedia.org/wiki/SRGB + fn gamma_component(u: f32) -> f32 { + if u < 0.0031308 { + 12.92 * u + } else { + 1.055 * u.powf(1.0 / 2.4) - 0.055 + } + } + + Self { + r: gamma_component(r), + g: gamma_component(g), + b: gamma_component(b), + a, + } + } + /// Converts the [`Color`] into its RGBA8 equivalent. #[must_use] pub fn into_rgba8(self) -> [u8; 4] { diff --git a/graphics/src/text.rs b/graphics/src/text.rs index 5fcfc699..c10eacad 100644 --- a/graphics/src/text.rs +++ b/graphics/src/text.rs @@ -8,6 +8,7 @@ pub use paragraph::Paragraph; pub use cosmic_text; +use crate::color; use crate::core::font::{self, Font}; use crate::core::text::Shaping; use crate::core::{Color, Size}; @@ -131,7 +132,12 @@ pub fn to_shaping(shaping: Shaping) -> cosmic_text::Shaping { } pub fn to_color(color: Color) -> cosmic_text::Color { - let [r, g, b, a] = color.into_rgba8(); + let [r, g, b, a] = color::pack(color).components(); - cosmic_text::Color::rgba(r, g, b, a) + cosmic_text::Color::rgba( + (r * 255.0) as u8, + (g * 255.0) as u8, + (b * 255.0) as u8, + (a * 255.0) as u8, + ) } diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index d1b33293..70e95d01 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -1,6 +1,7 @@ use crate::core::alignment; use crate::core::text::{LineHeight, Shaping}; use crate::core::{Color, Font, Pixels, Point, Rectangle}; +use crate::graphics::color; use crate::graphics::text::cache::{self, Cache}; use crate::graphics::text::editor; use crate::graphics::text::font_system; @@ -216,7 +217,18 @@ fn draw( fn from_color(color: cosmic_text::Color) -> Color { let [r, g, b, a] = color.as_rgba(); - Color::from_rgba8(r, g, b, a as f32 / 255.0) + if color::GAMMA_CORRECTION { + // `cosmic_text::Color` is linear RGB in this case, so we + // need to convert back to sRGB + Color::from_linear_rgba( + r as f32 / 255.0, + g as f32 / 255.0, + b as f32 / 255.0, + a as f32 / 255.0, + ) + } else { + Color::from_rgba8(r, g, b, a as f32 / 255.0) + } } #[derive(Debug, Clone, Default)] diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index 581df0cb..f746be63 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -2,7 +2,7 @@ use crate::core::alignment; use crate::core::{Rectangle, Size}; use crate::graphics::color; use crate::graphics::text::cache::{self, Cache}; -use crate::graphics::text::{font_system, Editor, Paragraph}; +use crate::graphics::text::{font_system, to_color, Editor, Paragraph}; use crate::layer::Text; use std::borrow::Cow; @@ -214,16 +214,7 @@ impl Pipeline { right: (clip_bounds.x + clip_bounds.width) as i32, bottom: (clip_bounds.y + clip_bounds.height) as i32, }, - default_color: { - let [r, g, b, a] = color::pack(color).components(); - - glyphon::Color::rgba( - (r * 255.0) as u8, - (g * 255.0) as u8, - (b * 255.0) as u8, - (a * 255.0) as u8, - ) - }, + default_color: to_color(color), }) }, ); From 93d6f748f69fc4ccf6c18f95c5f16b369c776da0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 20 Sep 2023 01:13:36 +0200 Subject: [PATCH 233/321] Fix `clippy` lints in `iced_highlighter` --- highlighter/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/highlighter/src/lib.rs b/highlighter/src/lib.rs index b80d6499..f5a4fae5 100644 --- a/highlighter/src/lib.rs +++ b/highlighter/src/lib.rs @@ -9,10 +9,10 @@ use syntect::highlighting; use syntect::parsing; static SYNTAXES: Lazy = - Lazy::new(|| parsing::SyntaxSet::load_defaults_nonewlines()); + Lazy::new(parsing::SyntaxSet::load_defaults_nonewlines); static THEMES: Lazy = - Lazy::new(|| highlighting::ThemeSet::load_defaults()); + Lazy::new(highlighting::ThemeSet::load_defaults); const LINES_PER_SNAPSHOT: usize = 50; @@ -77,7 +77,7 @@ impl highlighter::Highlighter for Highlighter { let (parser, stack) = self.caches.last().cloned().unwrap_or_else(|| { ( - parsing::ParseState::new(&self.syntax), + parsing::ParseState::new(self.syntax), parsing::ScopeStack::new(), ) }); From ff78e97ad7df4db3b2a97b94e99854f2f9e3021a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 20 Sep 2023 01:21:42 +0200 Subject: [PATCH 234/321] Introduce more themes to `iced_highlighter` --- examples/editor/src/main.rs | 6 +++++- highlighter/src/lib.rs | 35 ++++++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs index d513090f..f49ca6e8 100644 --- a/examples/editor/src/main.rs +++ b/examples/editor/src/main.rs @@ -230,7 +230,11 @@ impl Application for Editor { } fn theme(&self) -> Theme { - Theme::Dark + if self.theme.is_dark() { + Theme::Dark + } else { + Theme::Light + } } } diff --git a/highlighter/src/lib.rs b/highlighter/src/lib.rs index f5a4fae5..db28b5b1 100644 --- a/highlighter/src/lib.rs +++ b/highlighter/src/lib.rs @@ -161,19 +161,38 @@ impl Highlight { #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Theme { SolarizedDark, - InspiredGitHub, Base16Mocha, + Base16Ocean, + Base16Eighties, + InspiredGitHub, } impl Theme { - pub const ALL: &[Self] = - &[Self::SolarizedDark, Self::InspiredGitHub, Self::Base16Mocha]; + pub const ALL: &[Self] = &[ + Self::SolarizedDark, + Self::Base16Mocha, + Self::Base16Ocean, + Self::Base16Eighties, + Self::InspiredGitHub, + ]; + + pub fn is_dark(self) -> bool { + match self { + Self::SolarizedDark + | Self::Base16Mocha + | Self::Base16Ocean + | Self::Base16Eighties => true, + Self::InspiredGitHub => false, + } + } fn key(&self) -> &'static str { match self { - Theme::InspiredGitHub => "InspiredGitHub", - Theme::Base16Mocha => "base16-mocha.dark", Theme::SolarizedDark => "Solarized (dark)", + Theme::Base16Mocha => "base16-mocha.dark", + Theme::Base16Ocean => "base16-ocean.dark", + Theme::Base16Eighties => "base16-eighties.dark", + Theme::InspiredGitHub => "InspiredGitHub", } } } @@ -181,9 +200,11 @@ impl Theme { impl std::fmt::Display for Theme { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Theme::InspiredGitHub => write!(f, "Inspired GitHub"), - Theme::Base16Mocha => write!(f, "Mocha"), Theme::SolarizedDark => write!(f, "Solarized Dark"), + Theme::Base16Mocha => write!(f, "Mocha"), + Theme::Base16Ocean => write!(f, "Ocean"), + Theme::Base16Eighties => write!(f, "Eighties"), + Theme::InspiredGitHub => write!(f, "Inspired GitHub"), } } } From 29fb4eab878a7ba399cae6ab1ec18a71e369ee59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 20 Sep 2023 01:23:50 +0200 Subject: [PATCH 235/321] Scroll `TextEditor` only if `cursor.is_over(bounds)` --- widget/src/text_editor.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index c384b8a2..4191e02c 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -539,7 +539,9 @@ impl Update { } _ => None, }, - mouse::Event::WheelScrolled { delta } => { + mouse::Event::WheelScrolled { delta } + if cursor.is_over(bounds) => + { action(Action::Scroll { lines: match delta { mouse::ScrollDelta::Lines { y, .. } => { From 9991052ce5617abf0f270bc9a74627ab6d45b35d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 20 Sep 2023 04:07:20 +0200 Subject: [PATCH 236/321] Create `cargo lint` alias --- .cargo/config.toml | 2 ++ .github/workflows/lint.yml | 2 +- .gitignore | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 .cargo/config.toml diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 00000000..08884888 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[alias] +lint = "clippy --workspace --no-deps -- -D warnings -D clippy::semicolon_if_nothing_returned" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 6fd98374..7fdc8867 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -9,4 +9,4 @@ jobs: components: clippy - uses: actions/checkout@master - name: Check lints - run: cargo clippy --workspace --all-features --all-targets --no-deps -- -D warnings + run: cargo lint diff --git a/.gitignore b/.gitignore index 0c46184f..f05ec438 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,5 @@ target/ pkg/ **/*.rs.bk Cargo.lock -.cargo/ dist/ traces/ From 34f07b60273d6cfe13834af54cd0e24d34569387 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 20 Sep 2023 04:11:52 +0200 Subject: [PATCH 237/321] Fix `clippy::semicolon_if_nothing_returned` --- core/src/element.rs | 6 +++--- core/src/gradient.rs | 2 +- core/src/hasher.rs | 2 +- core/src/overlay/element.rs | 6 +++--- core/src/overlay/group.rs | 2 +- core/src/shell.rs | 2 +- core/src/widget/operation/focusable.rs | 10 +++++----- core/src/widget/operation/scrollable.rs | 4 ++-- core/src/widget/operation/text_input.rs | 8 ++++---- core/src/widget/tree.rs | 4 ++-- examples/bezier_tool/src/main.rs | 2 +- examples/clock/src/main.rs | 2 +- examples/toast/src/main.rs | 2 +- examples/tooltip/src/main.rs | 2 +- examples/tour/src/main.rs | 2 +- graphics/src/geometry/path/builder.rs | 2 +- graphics/src/gradient.rs | 2 +- graphics/src/image.rs | 2 +- graphics/src/renderer.rs | 4 ++-- renderer/src/lib.rs | 4 ++-- runtime/src/overlay/nested.rs | 2 +- runtime/src/program/state.rs | 2 +- wgpu/src/buffer.rs | 2 +- wgpu/src/geometry.rs | 4 ++-- wgpu/src/image/atlas.rs | 2 +- wgpu/src/layer.rs | 2 +- widget/src/button.rs | 2 +- widget/src/column.rs | 2 +- widget/src/image.rs | 6 +++--- widget/src/image/viewer.rs | 2 +- widget/src/keyed/column.rs | 2 +- widget/src/lazy.rs | 6 +++--- widget/src/lazy/responsive.rs | 4 ++-- widget/src/pane_grid.rs | 4 ++-- widget/src/pane_grid/state.rs | 18 +++++++++--------- widget/src/pane_grid/title_bar.rs | 4 ++-- widget/src/pick_list.rs | 2 +- widget/src/row.rs | 4 ++-- widget/src/scrollable.rs | 10 +++++----- widget/src/slider.rs | 2 +- widget/src/text_input.rs | 24 ++++++++++++------------ widget/src/text_input/cursor.rs | 22 +++++++++++----------- widget/src/tooltip.rs | 2 +- widget/src/vertical_slider.rs | 2 +- winit/src/application.rs | 10 +++++----- winit/src/clipboard.rs | 4 ++-- 46 files changed, 108 insertions(+), 108 deletions(-) diff --git a/core/src/element.rs b/core/src/element.rs index 02f16bcb..dea111af 100644 --- a/core/src/element.rs +++ b/core/src/element.rs @@ -293,7 +293,7 @@ where } fn diff(&self, tree: &mut Tree) { - self.widget.diff(tree) + self.widget.diff(tree); } fn width(&self) -> Length { @@ -418,7 +418,7 @@ where viewport: &Rectangle, ) { self.widget - .draw(tree, renderer, theme, style, layout, cursor, viewport) + .draw(tree, renderer, theme, style, layout, cursor, viewport); } fn mouse_interaction( @@ -508,7 +508,7 @@ where ) { self.element .widget - .operate(state, layout, renderer, operation) + .operate(state, layout, renderer, operation); } fn on_event( diff --git a/core/src/gradient.rs b/core/src/gradient.rs index 6a5533f8..4711b044 100644 --- a/core/src/gradient.rs +++ b/core/src/gradient.rs @@ -95,7 +95,7 @@ impl Linear { stops: impl IntoIterator, ) -> Self { for stop in stops { - self = self.add_stop(stop.offset, stop.color) + self = self.add_stop(stop.offset, stop.color); } self diff --git a/core/src/hasher.rs b/core/src/hasher.rs index fa52f16d..9d8f75b3 100644 --- a/core/src/hasher.rs +++ b/core/src/hasher.rs @@ -4,7 +4,7 @@ pub struct Hasher(twox_hash::XxHash64); impl core::hash::Hasher for Hasher { fn write(&mut self, bytes: &[u8]) { - self.0.write(bytes) + self.0.write(bytes); } fn finish(&self) -> u64 { diff --git a/core/src/overlay/element.rs b/core/src/overlay/element.rs index 689e69be..3dd58f9b 100644 --- a/core/src/overlay/element.rs +++ b/core/src/overlay/element.rs @@ -98,7 +98,7 @@ where layout: Layout<'_>, cursor: mouse::Cursor, ) { - self.overlay.draw(renderer, theme, style, layout, cursor) + self.overlay.draw(renderer, theme, style, layout, cursor); } /// Applies a [`widget::Operation`] to the [`Element`]. @@ -205,7 +205,7 @@ where state: &mut dyn widget::operation::TextInput, id: Option<&widget::Id>, ) { - self.operation.text_input(state, id) + self.operation.text_input(state, id); } fn custom(&mut self, state: &mut dyn Any, id: Option<&widget::Id>) { @@ -262,7 +262,7 @@ where layout: Layout<'_>, cursor: mouse::Cursor, ) { - self.content.draw(renderer, theme, style, layout, cursor) + self.content.draw(renderer, theme, style, layout, cursor); } fn is_over( diff --git a/core/src/overlay/group.rs b/core/src/overlay/group.rs index a0bae6bb..dccf6dba 100644 --- a/core/src/overlay/group.rs +++ b/core/src/overlay/group.rs @@ -143,7 +143,7 @@ where |(child, layout)| { child.operate(layout, renderer, operation); }, - ) + ); }); } diff --git a/core/src/shell.rs b/core/src/shell.rs index 246c937a..2952ceff 100644 --- a/core/src/shell.rs +++ b/core/src/shell.rs @@ -71,7 +71,7 @@ impl<'a, Message> Shell<'a, Message> { if self.is_layout_invalid { self.is_layout_invalid = false; - f() + f(); } } diff --git a/core/src/widget/operation/focusable.rs b/core/src/widget/operation/focusable.rs index ab1b677e..68c22faa 100644 --- a/core/src/widget/operation/focusable.rs +++ b/core/src/widget/operation/focusable.rs @@ -49,7 +49,7 @@ pub fn focus(target: Id) -> impl Operation { _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { - operate_on_children(self) + operate_on_children(self); } } @@ -85,7 +85,7 @@ where _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { - operate_on_children(self) + operate_on_children(self); } fn finish(&self) -> Outcome { @@ -132,7 +132,7 @@ pub fn focus_previous() -> impl Operation { _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { - operate_on_children(self) + operate_on_children(self); } } @@ -166,7 +166,7 @@ pub fn focus_next() -> impl Operation { _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { - operate_on_children(self) + operate_on_children(self); } } @@ -193,7 +193,7 @@ pub fn find_focused() -> impl Operation { _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { - operate_on_children(self) + operate_on_children(self); } fn finish(&self) -> Outcome { diff --git a/core/src/widget/operation/scrollable.rs b/core/src/widget/operation/scrollable.rs index 4f8b2a98..12161255 100644 --- a/core/src/widget/operation/scrollable.rs +++ b/core/src/widget/operation/scrollable.rs @@ -26,7 +26,7 @@ pub fn snap_to(target: Id, offset: RelativeOffset) -> impl Operation { _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { - operate_on_children(self) + operate_on_children(self); } fn scrollable( @@ -60,7 +60,7 @@ pub fn scroll_to(target: Id, offset: AbsoluteOffset) -> impl Operation { _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { - operate_on_children(self) + operate_on_children(self); } fn scrollable( diff --git a/core/src/widget/operation/text_input.rs b/core/src/widget/operation/text_input.rs index a9ea2e81..41731d4c 100644 --- a/core/src/widget/operation/text_input.rs +++ b/core/src/widget/operation/text_input.rs @@ -38,7 +38,7 @@ pub fn move_cursor_to_front(target: Id) -> impl Operation { _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { - operate_on_children(self) + operate_on_children(self); } } @@ -68,7 +68,7 @@ pub fn move_cursor_to_end(target: Id) -> impl Operation { _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { - operate_on_children(self) + operate_on_children(self); } } @@ -99,7 +99,7 @@ pub fn move_cursor_to(target: Id, position: usize) -> impl Operation { _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { - operate_on_children(self) + operate_on_children(self); } } @@ -128,7 +128,7 @@ pub fn select_all(target: Id) -> impl Operation { _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { - operate_on_children(self) + operate_on_children(self); } } diff --git a/core/src/widget/tree.rs b/core/src/widget/tree.rs index 202cca9a..d4b8828a 100644 --- a/core/src/widget/tree.rs +++ b/core/src/widget/tree.rs @@ -61,7 +61,7 @@ impl Tree { Renderer: crate::Renderer, { if self.tag == new.borrow().tag() { - new.borrow().diff(self) + new.borrow().diff(self); } else { *self = Self::new(new); } @@ -78,7 +78,7 @@ impl Tree { new_children, |tree, widget| tree.diff(widget.borrow()), |widget| Self::new(widget.borrow()), - ) + ); } /// Reconciliates the children of the tree with the provided list of widgets using custom diff --git a/examples/bezier_tool/src/main.rs b/examples/bezier_tool/src/main.rs index 310be28f..9e4bc49c 100644 --- a/examples/bezier_tool/src/main.rs +++ b/examples/bezier_tool/src/main.rs @@ -81,7 +81,7 @@ mod bezier { } pub fn request_redraw(&mut self) { - self.cache.clear() + self.cache.clear(); } } diff --git a/examples/clock/src/main.rs b/examples/clock/src/main.rs index fae77bc0..eec70dde 100644 --- a/examples/clock/src/main.rs +++ b/examples/clock/src/main.rs @@ -141,7 +141,7 @@ impl canvas::Program for Clock { frame.with_save(|frame| { frame.rotate(hand_rotation(self.now.second(), 60)); frame.stroke(&long_hand, thin_stroke()); - }) + }); }); vec![clock] diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs index 8570a38e..20c3dd42 100644 --- a/examples/toast/src/main.rs +++ b/examples/toast/src/main.rs @@ -639,7 +639,7 @@ mod toast { child .as_widget() .operate(state, layout, renderer, operation); - }) + }); }); } diff --git a/examples/tooltip/src/main.rs b/examples/tooltip/src/main.rs index 35b862a8..a904cce0 100644 --- a/examples/tooltip/src/main.rs +++ b/examples/tooltip/src/main.rs @@ -40,7 +40,7 @@ impl Sandbox for Example { Position::Right => Position::FollowCursor, }; - self.position = position + self.position = position; } } } diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs index 952300bb..d46e40d1 100644 --- a/examples/tour/src/main.rs +++ b/examples/tour/src/main.rs @@ -285,7 +285,7 @@ impl<'a> Step { is_showing_icon, .. } = self { - *is_showing_icon = toggle + *is_showing_icon = toggle; } } }; diff --git a/graphics/src/geometry/path/builder.rs b/graphics/src/geometry/path/builder.rs index 794dd3bc..b0959fbf 100644 --- a/graphics/src/geometry/path/builder.rs +++ b/graphics/src/geometry/path/builder.rs @@ -174,7 +174,7 @@ impl Builder { /// the starting point. #[inline] pub fn close(&mut self) { - self.raw.close() + self.raw.close(); } /// Builds the [`Path`] of this [`Builder`]. diff --git a/graphics/src/gradient.rs b/graphics/src/gradient.rs index 7460e12e..603f1b4a 100644 --- a/graphics/src/gradient.rs +++ b/graphics/src/gradient.rs @@ -88,7 +88,7 @@ impl Linear { stops: impl IntoIterator, ) -> Self { for stop in stops { - self = self.add_stop(stop.offset, stop.color) + self = self.add_stop(stop.offset, stop.color); } self diff --git a/graphics/src/image.rs b/graphics/src/image.rs index 6b43f4a8..d89caace 100644 --- a/graphics/src/image.rs +++ b/graphics/src/image.rs @@ -79,7 +79,7 @@ impl Operation { use image::imageops; if self.contains(Self::FLIP_DIAGONALLY) { - imageops::flip_vertical_in_place(&mut image) + imageops::flip_vertical_in_place(&mut image); } if self.contains(Self::ROTATE_180) { diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index d4df29a5..a9d7895e 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -237,7 +237,7 @@ where } fn draw(&mut self, handle: image::Handle, bounds: Rectangle) { - self.primitives.push(Primitive::Image { handle, bounds }) + self.primitives.push(Primitive::Image { handle, bounds }); } } @@ -259,6 +259,6 @@ where handle, color, bounds, - }) + }); } } diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs index ef5c4182..8c76f52e 100644 --- a/renderer/src/lib.rs +++ b/renderer/src/lib.rs @@ -60,7 +60,7 @@ impl Renderer { pub fn draw_mesh(&mut self, mesh: Mesh) { match self { Self::TinySkia(_) => { - log::warn!("Unsupported mesh primitive: {mesh:?}") + log::warn!("Unsupported mesh primitive: {mesh:?}"); } #[cfg(feature = "wgpu")] Self::Wgpu(renderer) => { @@ -241,7 +241,7 @@ impl crate::core::svg::Renderer for Renderer { color: Option, bounds: Rectangle, ) { - delegate!(self, renderer, renderer.draw(handle, color, bounds)) + delegate!(self, renderer, renderer.draw(handle, color, bounds)); } } diff --git a/runtime/src/overlay/nested.rs b/runtime/src/overlay/nested.rs index 21b6f7c1..062ccc72 100644 --- a/runtime/src/overlay/nested.rs +++ b/runtime/src/overlay/nested.rs @@ -164,7 +164,7 @@ where } } - recurse(&mut self.overlay, layout, renderer, operation) + recurse(&mut self.overlay, layout, renderer, operation); } /// Processes a runtime [`Event`]. diff --git a/runtime/src/program/state.rs b/runtime/src/program/state.rs index 9aa2d550..6f8f4063 100644 --- a/runtime/src/program/state.rs +++ b/runtime/src/program/state.rs @@ -200,7 +200,7 @@ where match operation.finish() { operation::Outcome::None => {} operation::Outcome::Some(message) => { - self.queued_messages.push(message) + self.queued_messages.push(message); } operation::Outcome::Chain(next) => { current_operation = Some(next); diff --git a/wgpu/src/buffer.rs b/wgpu/src/buffer.rs index 94122187..ef00c58f 100644 --- a/wgpu/src/buffer.rs +++ b/wgpu/src/buffer.rs @@ -87,7 +87,7 @@ impl Buffer { /// Clears any temporary data (i.e. offsets) from the buffer. pub fn clear(&mut self) { - self.offsets.clear() + self.offsets.clear(); } /// Returns the offset at `index`, if it exists. diff --git a/wgpu/src/geometry.rs b/wgpu/src/geometry.rs index 63a59c05..655362b7 100644 --- a/wgpu/src/geometry.rs +++ b/wgpu/src/geometry.rs @@ -480,7 +480,7 @@ impl Frame { }, size: self.size, }), - )) + )); } } Buffer::Gradient(buffer) => { @@ -493,7 +493,7 @@ impl Frame { }, size: self.size, }), - )) + )); } } } diff --git a/wgpu/src/image/atlas.rs b/wgpu/src/image/atlas.rs index 1253496b..e8ca4bd3 100644 --- a/wgpu/src/image/atlas.rs +++ b/wgpu/src/image/atlas.rs @@ -104,7 +104,7 @@ impl Atlas { padded_data[offset..offset + 4 * width as usize].copy_from_slice( &data[row * 4 * width as usize..(row + 1) * 4 * width as usize], - ) + ); } match &entry { diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs index 7a5a0f7c..d20dbe66 100644 --- a/wgpu/src/layer.rs +++ b/wgpu/src/layer.rs @@ -202,7 +202,7 @@ impl<'a> Layer<'a> { translation, primitive, current_layer, - ) + ); } } Primitive::Clip { bounds, content } => { diff --git a/widget/src/button.rs b/widget/src/button.rs index 4915bd49..384a3156 100644 --- a/widget/src/button.rs +++ b/widget/src/button.rs @@ -146,7 +146,7 @@ where } fn diff(&self, tree: &mut Tree) { - tree.diff_children(std::slice::from_ref(&self.content)) + tree.diff_children(std::slice::from_ref(&self.content)); } fn width(&self) -> Length { diff --git a/widget/src/column.rs b/widget/src/column.rs index f2347cc9..42e90ac1 100644 --- a/widget/src/column.rs +++ b/widget/src/column.rs @@ -159,7 +159,7 @@ where child .as_widget() .operate(state, layout, renderer, operation); - }) + }); }); } diff --git a/widget/src/image.rs b/widget/src/image.rs index 3c83c87b..a0e89920 100644 --- a/widget/src/image.rs +++ b/widget/src/image.rs @@ -141,14 +141,14 @@ pub fn draw( ..bounds }; - renderer.draw(handle.clone(), drawing_bounds + offset) + renderer.draw(handle.clone(), drawing_bounds + offset); }; if adjusted_fit.width > bounds.width || adjusted_fit.height > bounds.height { renderer.with_layer(bounds, render); } else { - render(renderer) + render(renderer); } } @@ -191,7 +191,7 @@ where _cursor: mouse::Cursor, _viewport: &Rectangle, ) { - draw(renderer, layout, &self.handle, self.content_fit) + draw(renderer, layout, &self.handle, self.content_fit); } } diff --git a/widget/src/image/viewer.rs b/widget/src/image/viewer.rs index 724d121e..44624fc8 100644 --- a/widget/src/image/viewer.rs +++ b/widget/src/image/viewer.rs @@ -334,7 +334,7 @@ where y: bounds.y, ..Rectangle::with_size(image_size) }, - ) + ); }); }); } diff --git a/widget/src/keyed/column.rs b/widget/src/keyed/column.rs index 19016679..0ef82407 100644 --- a/widget/src/keyed/column.rs +++ b/widget/src/keyed/column.rs @@ -220,7 +220,7 @@ where child .as_widget() .operate(state, layout, renderer, operation); - }) + }); }); } diff --git a/widget/src/lazy.rs b/widget/src/lazy.rs index bf695a57..589dd938 100644 --- a/widget/src/lazy.rs +++ b/widget/src/lazy.rs @@ -135,7 +135,7 @@ where (*self.element.borrow_mut()) = Some(current.element.clone()); self.with_element(|element| { - tree.diff_children(std::slice::from_ref(&element.as_widget())) + tree.diff_children(std::slice::from_ref(&element.as_widget())); }); } else { (*self.element.borrow_mut()) = Some(current.element.clone()); @@ -243,8 +243,8 @@ where layout, cursor, viewport, - ) - }) + ); + }); } fn overlay<'b>( diff --git a/widget/src/lazy/responsive.rs b/widget/src/lazy/responsive.rs index 0b819455..ed471988 100644 --- a/widget/src/lazy/responsive.rs +++ b/widget/src/lazy/responsive.rs @@ -240,9 +240,9 @@ where |tree, renderer, layout, element| { element.as_widget().draw( tree, renderer, theme, style, layout, cursor, viewport, - ) + ); }, - ) + ); } fn mouse_interaction( diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs index f868a648..3fb25972 100644 --- a/widget/src/pane_grid.rs +++ b/widget/src/pane_grid.rs @@ -308,7 +308,7 @@ where .zip(layout.children()) .for_each(|(((_pane, content), state), layout)| { content.operate(state, layout, renderer, operation); - }) + }); }); } @@ -436,7 +436,7 @@ where tree, renderer, theme, style, layout, cursor, rectangle, ); }, - ) + ); } fn overlay<'b>( diff --git a/widget/src/pane_grid/state.rs b/widget/src/pane_grid/state.rs index 28a52cf0..3721fa55 100644 --- a/widget/src/pane_grid/state.rs +++ b/widget/src/pane_grid/state.rs @@ -156,16 +156,16 @@ impl State { Region::Center => self.swap(pane, target), Region::Edge(edge) => match edge { Edge::Top => { - self.split_and_swap(Axis::Horizontal, target, pane, true) + self.split_and_swap(Axis::Horizontal, target, pane, true); } Edge::Bottom => { - self.split_and_swap(Axis::Horizontal, target, pane, false) + self.split_and_swap(Axis::Horizontal, target, pane, false); } Edge::Left => { - self.split_and_swap(Axis::Vertical, target, pane, true) + self.split_and_swap(Axis::Vertical, target, pane, true); } Edge::Right => { - self.split_and_swap(Axis::Vertical, target, pane, false) + self.split_and_swap(Axis::Vertical, target, pane, false); } }, } @@ -176,7 +176,7 @@ impl State { match target { Target::Edge(edge) => self.move_to_edge(pane, edge), Target::Pane(target, region) => { - self.split_with(&target, pane, region) + self.split_with(&target, pane, region); } } } @@ -241,16 +241,16 @@ impl State { pub fn move_to_edge(&mut self, pane: &Pane, edge: Edge) { match edge { Edge::Top => { - self.split_major_node_and_swap(Axis::Horizontal, pane, true) + self.split_major_node_and_swap(Axis::Horizontal, pane, true); } Edge::Bottom => { - self.split_major_node_and_swap(Axis::Horizontal, pane, false) + self.split_major_node_and_swap(Axis::Horizontal, pane, false); } Edge::Left => { - self.split_major_node_and_swap(Axis::Vertical, pane, true) + self.split_major_node_and_swap(Axis::Vertical, pane, true); } Edge::Right => { - self.split_major_node_and_swap(Axis::Vertical, pane, false) + self.split_major_node_and_swap(Axis::Vertical, pane, false); } } } diff --git a/widget/src/pane_grid/title_bar.rs b/widget/src/pane_grid/title_bar.rs index 5ae7a6a0..f4dbb6b1 100644 --- a/widget/src/pane_grid/title_bar.rs +++ b/widget/src/pane_grid/title_bar.rs @@ -286,7 +286,7 @@ where controls_layout, renderer, operation, - ) + ); }; if show_title { @@ -295,7 +295,7 @@ where title_layout, renderer, operation, - ) + ); } } diff --git a/widget/src/pick_list.rs b/widget/src/pick_list.rs index 056a5e65..fa0e3471 100644 --- a/widget/src/pick_list.rs +++ b/widget/src/pick_list.rs @@ -253,7 +253,7 @@ where &self.handle, &self.style, || tree.state.downcast_ref::>(), - ) + ); } fn overlay<'b>( diff --git a/widget/src/row.rs b/widget/src/row.rs index 71cf0509..7ca90fbb 100644 --- a/widget/src/row.rs +++ b/widget/src/row.rs @@ -101,7 +101,7 @@ where } fn diff(&self, tree: &mut Tree) { - tree.diff_children(&self.children) + tree.diff_children(&self.children); } fn width(&self) -> Length { @@ -148,7 +148,7 @@ where child .as_widget() .operate(state, layout, renderer, operation); - }) + }); }); } diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index f92e6223..6f1e68fc 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -217,7 +217,7 @@ where } fn diff(&self, tree: &mut Tree) { - tree.diff_children(std::slice::from_ref(&self.content)) + tree.diff_children(std::slice::from_ref(&self.content)); } fn width(&self) -> Length { @@ -348,9 +348,9 @@ where layout, cursor, viewport, - ) + ); }, - ) + ); } fn mouse_interaction( @@ -1069,7 +1069,7 @@ impl operation::Scrollable for State { } fn scroll_to(&mut self, offset: AbsoluteOffset) { - State::scroll_to(self, offset) + State::scroll_to(self, offset); } } @@ -1203,7 +1203,7 @@ impl State { (self.offset_y.absolute(bounds.height, content_bounds.height) - delta.y) .clamp(0.0, content_bounds.height - bounds.height), - ) + ); } if bounds.width < content_bounds.width { diff --git a/widget/src/slider.rs b/widget/src/slider.rs index 2c4a2913..ac0982c8 100644 --- a/widget/src/slider.rs +++ b/widget/src/slider.rs @@ -223,7 +223,7 @@ where &self.range, theme, &self.style, - ) + ); } fn mouse_interaction( diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index 7d5ae806..9e1fb796 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -250,7 +250,7 @@ where self.is_secure, self.icon.as_ref(), &self.style, - ) + ); } } @@ -375,7 +375,7 @@ where self.is_secure, self.icon.as_ref(), &self.style, - ) + ); } fn mouse_interaction( @@ -622,7 +622,7 @@ where font, size, line_height, - ) + ); }; match event { @@ -849,7 +849,7 @@ where state.cursor.move_left_by_words(value); } } else if modifiers.shift() { - state.cursor.select_left(value) + state.cursor.select_left(value); } else { state.cursor.move_left(value); } @@ -864,7 +864,7 @@ where state.cursor.move_right_by_words(value); } } else if modifiers.shift() { - state.cursor.select_right(value) + state.cursor.select_right(value); } else { state.cursor.move_right(value); } @@ -1220,7 +1220,7 @@ pub fn draw( if text_width > text_bounds.width { renderer.with_layer(text_bounds, |renderer| { - renderer.with_translation(Vector::new(-offset, 0.0), render) + renderer.with_translation(Vector::new(-offset, 0.0), render); }); } else { render(renderer); @@ -1342,29 +1342,29 @@ impl operation::Focusable for State

{ } fn focus(&mut self) { - State::focus(self) + State::focus(self); } fn unfocus(&mut self) { - State::unfocus(self) + State::unfocus(self); } } impl operation::TextInput for State

{ fn move_cursor_to_front(&mut self) { - State::move_cursor_to_front(self) + State::move_cursor_to_front(self); } fn move_cursor_to_end(&mut self) { - State::move_cursor_to_end(self) + State::move_cursor_to_end(self); } fn move_cursor_to(&mut self, position: usize) { - State::move_cursor_to(self, position) + State::move_cursor_to(self, position); } fn select_all(&mut self) { - State::select_all(self) + State::select_all(self); } } diff --git a/widget/src/text_input/cursor.rs b/widget/src/text_input/cursor.rs index 9680dfd7..ea902485 100644 --- a/widget/src/text_input/cursor.rs +++ b/widget/src/text_input/cursor.rs @@ -65,11 +65,11 @@ impl Cursor { } pub(crate) fn move_right(&mut self, value: &Value) { - self.move_right_by_amount(value, 1) + self.move_right_by_amount(value, 1); } pub(crate) fn move_right_by_words(&mut self, value: &Value) { - self.move_to(value.next_end_of_word(self.right(value))) + self.move_to(value.next_end_of_word(self.right(value))); } pub(crate) fn move_right_by_amount( @@ -79,7 +79,7 @@ impl Cursor { ) { match self.state(value) { State::Index(index) => { - self.move_to(index.saturating_add(amount).min(value.len())) + self.move_to(index.saturating_add(amount).min(value.len())); } State::Selection { start, end } => self.move_to(end.max(start)), } @@ -108,10 +108,10 @@ impl Cursor { pub(crate) fn select_left(&mut self, value: &Value) { match self.state(value) { State::Index(index) if index > 0 => { - self.select_range(index, index - 1) + self.select_range(index, index - 1); } State::Selection { start, end } if end > 0 => { - self.select_range(start, end - 1) + self.select_range(start, end - 1); } _ => {} } @@ -120,10 +120,10 @@ impl Cursor { pub(crate) fn select_right(&mut self, value: &Value) { match self.state(value) { State::Index(index) if index < value.len() => { - self.select_range(index, index + 1) + self.select_range(index, index + 1); } State::Selection { start, end } if end < value.len() => { - self.select_range(start, end + 1) + self.select_range(start, end + 1); } _ => {} } @@ -132,10 +132,10 @@ impl Cursor { pub(crate) fn select_left_by_words(&mut self, value: &Value) { match self.state(value) { State::Index(index) => { - self.select_range(index, value.previous_start_of_word(index)) + self.select_range(index, value.previous_start_of_word(index)); } State::Selection { start, end } => { - self.select_range(start, value.previous_start_of_word(end)) + self.select_range(start, value.previous_start_of_word(end)); } } } @@ -143,10 +143,10 @@ impl Cursor { pub(crate) fn select_right_by_words(&mut self, value: &Value) { match self.state(value) { State::Index(index) => { - self.select_range(index, value.next_end_of_word(index)) + self.select_range(index, value.next_end_of_word(index)); } State::Selection { start, end } => { - self.select_range(start, value.next_end_of_word(end)) + self.select_range(start, value.next_end_of_word(end)); } } } diff --git a/widget/src/tooltip.rs b/widget/src/tooltip.rs index edc74e31..b041d2e9 100644 --- a/widget/src/tooltip.rs +++ b/widget/src/tooltip.rs @@ -114,7 +114,7 @@ where } fn diff(&self, tree: &mut widget::Tree) { - tree.diff_children(&[self.content.as_widget(), &self.tooltip]) + tree.diff_children(&[self.content.as_widget(), &self.tooltip]); } fn state(&self) -> widget::tree::State { diff --git a/widget/src/vertical_slider.rs b/widget/src/vertical_slider.rs index 1efcd63b..01d3359c 100644 --- a/widget/src/vertical_slider.rs +++ b/widget/src/vertical_slider.rs @@ -220,7 +220,7 @@ where &self.range, theme, &self.style, - ) + ); } fn mouse_interaction( diff --git a/winit/src/application.rs b/winit/src/application.rs index dec77e80..8105f8d9 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -762,7 +762,7 @@ pub fn run_command( size.width, size.height, ))) - .expect("Send message to event loop") + .expect("Send message to event loop"); } window::Action::Maximize(maximized) => { window.set_maximized(maximized); @@ -784,7 +784,7 @@ pub fn run_command( )); } window::Action::ChangeIcon(icon) => { - window.set_window_icon(conversion::icon(icon)) + window.set_window_icon(conversion::icon(icon)); } window::Action::FetchMode(tag) => { let mode = if window.is_visible().unwrap_or(true) { @@ -798,7 +798,7 @@ pub fn run_command( .expect("Send message to event loop"); } window::Action::ToggleMaximize => { - window.set_maximized(!window.is_maximized()) + window.set_maximized(!window.is_maximized()); } window::Action::ToggleDecorations => { window.set_decorations(!window.is_decorated()); @@ -833,7 +833,7 @@ pub fn run_command( bytes, state.physical_size(), ))) - .expect("Send message to event loop.") + .expect("Send message to event loop."); } }, command::Action::System(action) => match action { @@ -851,7 +851,7 @@ pub fn run_command( proxy .send_event(message) - .expect("Send message to event loop") + .expect("Send message to event loop"); }); } } diff --git a/winit/src/clipboard.rs b/winit/src/clipboard.rs index 4228e46f..0a09c255 100644 --- a/winit/src/clipboard.rs +++ b/winit/src/clipboard.rs @@ -44,7 +44,7 @@ impl Clipboard { State::Connected(clipboard) => match clipboard.write(contents) { Ok(()) => {} Err(error) => { - log::warn!("error writing to clipboard: {error}") + log::warn!("error writing to clipboard: {error}"); } }, State::Unavailable => {} @@ -58,6 +58,6 @@ impl crate::core::Clipboard for Clipboard { } fn write(&mut self, contents: String) { - self.write(contents) + self.write(contents); } } From 6c386e90a12fd26da12541da3f086dddb7211c0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 20 Sep 2023 04:33:48 +0200 Subject: [PATCH 238/321] Fix `clippy::trivially-copy-pass-by-ref` --- .cargo/config.toml | 2 +- core/src/mouse/click.rs | 2 +- examples/pane_grid/src/main.rs | 29 +++++++----------- examples/todos/src/main.rs | 2 +- widget/src/pane_grid/node.rs | 14 ++++----- widget/src/pane_grid/state.rs | 54 +++++++++++++++++----------------- 6 files changed, 48 insertions(+), 55 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 08884888..1e55e447 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,2 +1,2 @@ [alias] -lint = "clippy --workspace --no-deps -- -D warnings -D clippy::semicolon_if_nothing_returned" +lint = "clippy --workspace --no-deps -- -D warnings -D clippy::semicolon_if_nothing_returned -D clippy::trivially-copy-pass-by-ref" diff --git a/core/src/mouse/click.rs b/core/src/mouse/click.rs index 240e5c64..53354098 100644 --- a/core/src/mouse/click.rs +++ b/core/src/mouse/click.rs @@ -24,7 +24,7 @@ pub enum Kind { } impl Kind { - fn next(&self) -> Kind { + fn next(self) -> Kind { match self { Kind::Single => Kind::Double, Kind::Double => Kind::Triple, diff --git a/examples/pane_grid/src/main.rs b/examples/pane_grid/src/main.rs index af87e2c0..aa3149bb 100644 --- a/examples/pane_grid/src/main.rs +++ b/examples/pane_grid/src/main.rs @@ -61,11 +61,8 @@ impl Application for Example { fn update(&mut self, message: Message) -> Command { match message { Message::Split(axis, pane) => { - let result = self.panes.split( - axis, - &pane, - Pane::new(self.panes_created), - ); + let result = + self.panes.split(axis, pane, Pane::new(self.panes_created)); if let Some((pane, _)) = result { self.focus = Some(pane); @@ -77,7 +74,7 @@ impl Application for Example { if let Some(pane) = self.focus { let result = self.panes.split( axis, - &pane, + pane, Pane::new(self.panes_created), ); @@ -90,8 +87,7 @@ impl Application for Example { } Message::FocusAdjacent(direction) => { if let Some(pane) = self.focus { - if let Some(adjacent) = - self.panes.adjacent(&pane, direction) + if let Some(adjacent) = self.panes.adjacent(pane, direction) { self.focus = Some(adjacent); } @@ -101,37 +97,34 @@ impl Application for Example { self.focus = Some(pane); } Message::Resized(pane_grid::ResizeEvent { split, ratio }) => { - self.panes.resize(&split, ratio); + self.panes.resize(split, ratio); } Message::Dragged(pane_grid::DragEvent::Dropped { pane, target, }) => { - self.panes.drop(&pane, target); + self.panes.drop(pane, target); } Message::Dragged(_) => {} Message::TogglePin(pane) => { - if let Some(Pane { is_pinned, .. }) = self.panes.get_mut(&pane) - { + if let Some(Pane { is_pinned, .. }) = self.panes.get_mut(pane) { *is_pinned = !*is_pinned; } } - Message::Maximize(pane) => self.panes.maximize(&pane), + Message::Maximize(pane) => self.panes.maximize(pane), Message::Restore => { self.panes.restore(); } Message::Close(pane) => { - if let Some((_, sibling)) = self.panes.close(&pane) { + if let Some((_, sibling)) = self.panes.close(pane) { self.focus = Some(sibling); } } Message::CloseFocused => { if let Some(pane) = self.focus { - if let Some(Pane { is_pinned, .. }) = self.panes.get(&pane) - { + if let Some(Pane { is_pinned, .. }) = self.panes.get(pane) { if !is_pinned { - if let Some((_, sibling)) = self.panes.close(&pane) - { + if let Some((_, sibling)) = self.panes.close(pane) { self.focus = Some(sibling); } } diff --git a/examples/todos/src/main.rs b/examples/todos/src/main.rs index 3048a668..1ad3aba7 100644 --- a/examples/todos/src/main.rs +++ b/examples/todos/src/main.rs @@ -443,7 +443,7 @@ pub enum Filter { } impl Filter { - fn matches(&self, task: &Task) -> bool { + fn matches(self, task: &Task) -> bool { match self { Filter::All => true, Filter::Active => !task.completed, diff --git a/widget/src/pane_grid/node.rs b/widget/src/pane_grid/node.rs index 3c707f15..1f568f95 100644 --- a/widget/src/pane_grid/node.rs +++ b/widget/src/pane_grid/node.rs @@ -95,13 +95,13 @@ impl Node { splits } - pub(crate) fn find(&mut self, pane: &Pane) -> Option<&mut Node> { + pub(crate) fn find(&mut self, pane: Pane) -> Option<&mut Node> { match self { Node::Split { a, b, .. } => { a.find(pane).or_else(move || b.find(pane)) } Node::Pane(p) => { - if p == pane { + if *p == pane { Some(self) } else { None @@ -139,12 +139,12 @@ impl Node { f(self); } - pub(crate) fn resize(&mut self, split: &Split, percentage: f32) -> bool { + pub(crate) fn resize(&mut self, split: Split, percentage: f32) -> bool { match self { Node::Split { id, ratio, a, b, .. } => { - if id == split { + if *id == split { *ratio = percentage; true @@ -158,13 +158,13 @@ impl Node { } } - pub(crate) fn remove(&mut self, pane: &Pane) -> Option { + pub(crate) fn remove(&mut self, pane: Pane) -> Option { match self { Node::Split { a, b, .. } => { - if a.pane() == Some(*pane) { + if a.pane() == Some(pane) { *self = *b.clone(); Some(self.first_pane()) - } else if b.pane() == Some(*pane) { + } else if b.pane() == Some(pane) { *self = *a.clone(); Some(self.first_pane()) } else { diff --git a/widget/src/pane_grid/state.rs b/widget/src/pane_grid/state.rs index 3721fa55..481cd770 100644 --- a/widget/src/pane_grid/state.rs +++ b/widget/src/pane_grid/state.rs @@ -75,14 +75,14 @@ impl State { } /// Returns the internal state of the given [`Pane`], if it exists. - pub fn get(&self, pane: &Pane) -> Option<&T> { - self.panes.get(pane) + pub fn get(&self, pane: Pane) -> Option<&T> { + self.panes.get(&pane) } /// Returns the internal state of the given [`Pane`] with mutability, if it /// exists. - pub fn get_mut(&mut self, pane: &Pane) -> Option<&mut T> { - self.panes.get_mut(pane) + pub fn get_mut(&mut self, pane: Pane) -> Option<&mut T> { + self.panes.get_mut(&pane) } /// Returns an iterator over all the panes of the [`State`], alongside its @@ -104,13 +104,13 @@ impl State { /// Returns the adjacent [`Pane`] of another [`Pane`] in the given /// direction, if there is one. - pub fn adjacent(&self, pane: &Pane, direction: Direction) -> Option { + pub fn adjacent(&self, pane: Pane, direction: Direction) -> Option { let regions = self .internal .layout .pane_regions(0.0, Size::new(4096.0, 4096.0)); - let current_region = regions.get(pane)?; + let current_region = regions.get(&pane)?; let target = match direction { Direction::Left => { @@ -142,7 +142,7 @@ impl State { pub fn split( &mut self, axis: Axis, - pane: &Pane, + pane: Pane, state: T, ) -> Option<(Pane, Split)> { self.split_node(axis, Some(pane), state, false) @@ -151,7 +151,7 @@ impl State { /// Split a target [`Pane`] with a given [`Pane`] on a given [`Region`]. /// /// Panes will be swapped by default for [`Region::Center`]. - pub fn split_with(&mut self, target: &Pane, pane: &Pane, region: Region) { + pub fn split_with(&mut self, target: Pane, pane: Pane, region: Region) { match region { Region::Center => self.swap(pane, target), Region::Edge(edge) => match edge { @@ -172,11 +172,11 @@ impl State { } /// Drops the given [`Pane`] into the provided [`Target`]. - pub fn drop(&mut self, pane: &Pane, target: Target) { + pub fn drop(&mut self, pane: Pane, target: Target) { match target { Target::Edge(edge) => self.move_to_edge(pane, edge), Target::Pane(target, region) => { - self.split_with(&target, pane, region); + self.split_with(target, pane, region); } } } @@ -184,7 +184,7 @@ impl State { fn split_node( &mut self, axis: Axis, - pane: Option<&Pane>, + pane: Option, state: T, inverse: bool, ) -> Option<(Pane, Split)> { @@ -222,14 +222,14 @@ impl State { fn split_and_swap( &mut self, axis: Axis, - target: &Pane, - pane: &Pane, + target: Pane, + pane: Pane, swap: bool, ) { if let Some((state, _)) = self.close(pane) { if let Some((new_pane, _)) = self.split(axis, target, state) { if swap { - self.swap(target, &new_pane); + self.swap(target, new_pane); } } } @@ -238,7 +238,7 @@ impl State { /// Move [`Pane`] to an [`Edge`] of the [`PaneGrid`]. /// /// [`PaneGrid`]: super::PaneGrid - pub fn move_to_edge(&mut self, pane: &Pane, edge: Edge) { + pub fn move_to_edge(&mut self, pane: Pane, edge: Edge) { match edge { Edge::Top => { self.split_major_node_and_swap(Axis::Horizontal, pane, true); @@ -258,7 +258,7 @@ impl State { fn split_major_node_and_swap( &mut self, axis: Axis, - pane: &Pane, + pane: Pane, swap: bool, ) { if let Some((state, _)) = self.close(pane) { @@ -273,14 +273,14 @@ impl State { /// /// [`PaneGrid`]: super::PaneGrid /// [`DragEvent`]: super::DragEvent - pub fn swap(&mut self, a: &Pane, b: &Pane) { + pub fn swap(&mut self, a: Pane, b: Pane) { self.internal.layout.update(&|node| match node { Node::Split { .. } => {} Node::Pane(pane) => { - if pane == a { - *node = Node::Pane(*b); - } else if pane == b { - *node = Node::Pane(*a); + if *pane == a { + *node = Node::Pane(b); + } else if *pane == b { + *node = Node::Pane(a); } } }); @@ -296,19 +296,19 @@ impl State { /// /// [`PaneGrid`]: super::PaneGrid /// [`ResizeEvent`]: super::ResizeEvent - pub fn resize(&mut self, split: &Split, ratio: f32) { + pub fn resize(&mut self, split: Split, ratio: f32) { let _ = self.internal.layout.resize(split, ratio); } /// Closes the given [`Pane`] and returns its internal state and its closest /// sibling, if it exists. - pub fn close(&mut self, pane: &Pane) -> Option<(T, Pane)> { - if self.maximized == Some(*pane) { + pub fn close(&mut self, pane: Pane) -> Option<(T, Pane)> { + if self.maximized == Some(pane) { let _ = self.maximized.take(); } if let Some(sibling) = self.internal.layout.remove(pane) { - self.panes.remove(pane).map(|state| (state, sibling)) + self.panes.remove(&pane).map(|state| (state, sibling)) } else { None } @@ -318,8 +318,8 @@ impl State { /// [`PaneGrid`] until [`Self::restore()`] is called. /// /// [`PaneGrid`]: super::PaneGrid - pub fn maximize(&mut self, pane: &Pane) { - self.maximized = Some(*pane); + pub fn maximize(&mut self, pane: Pane) { + self.maximized = Some(pane); } /// Restore the currently maximized [`Pane`] to it's normal size. All panes From 42ed90bc6f92b2085d193e7f143430b8d3847c21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 20 Sep 2023 04:51:08 +0200 Subject: [PATCH 239/321] Fix `clippy::default_trait_access` --- .cargo/config.toml | 2 +- examples/arc/src/main.rs | 2 +- examples/clock/src/main.rs | 2 +- examples/integration/src/controls.rs | 2 +- examples/lazy/src/main.rs | 4 ++-- examples/modal/src/main.rs | 6 ++++-- examples/scrollable/src/main.rs | 4 ++-- examples/solar_system/src/main.rs | 4 ++-- renderer/src/geometry/cache.rs | 2 +- src/settings.rs | 4 ++-- src/window/settings.rs | 2 +- style/src/theme.rs | 6 +++--- tiny_skia/src/geometry.rs | 2 +- wgpu/src/color.rs | 6 +++--- wgpu/src/text.rs | 2 +- widget/src/pick_list.rs | 2 +- widget/src/scrollable.rs | 2 +- widget/src/toggler.rs | 2 +- winit/src/settings.rs | 2 +- 19 files changed, 30 insertions(+), 28 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 1e55e447..f5c00d9b 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,2 +1,2 @@ [alias] -lint = "clippy --workspace --no-deps -- -D warnings -D clippy::semicolon_if_nothing_returned -D clippy::trivially-copy-pass-by-ref" +lint = "clippy --workspace --no-deps -- -D warnings -D clippy::semicolon_if_nothing_returned -D clippy::trivially-copy-pass-by-ref -D clippy::default_trait_access" diff --git a/examples/arc/src/main.rs b/examples/arc/src/main.rs index df565859..6a68cca1 100644 --- a/examples/arc/src/main.rs +++ b/examples/arc/src/main.rs @@ -37,7 +37,7 @@ impl Application for Arc { ( Arc { start: Instant::now(), - cache: Default::default(), + cache: Cache::default(), }, Command::none(), ) diff --git a/examples/clock/src/main.rs b/examples/clock/src/main.rs index eec70dde..920aa0c5 100644 --- a/examples/clock/src/main.rs +++ b/examples/clock/src/main.rs @@ -35,7 +35,7 @@ impl Application for Clock { Clock { now: time::OffsetDateTime::now_local() .unwrap_or_else(|_| time::OffsetDateTime::now_utc()), - clock: Default::default(), + clock: Cache::default(), }, Command::none(), ) diff --git a/examples/integration/src/controls.rs b/examples/integration/src/controls.rs index 14e53ede..4714c397 100644 --- a/examples/integration/src/controls.rs +++ b/examples/integration/src/controls.rs @@ -19,7 +19,7 @@ impl Controls { pub fn new() -> Controls { Controls { background_color: Color::BLACK, - text: Default::default(), + text: String::default(), } } diff --git a/examples/lazy/src/main.rs b/examples/lazy/src/main.rs index c6baa6a1..9bf17c56 100644 --- a/examples/lazy/src/main.rs +++ b/examples/lazy/src/main.rs @@ -27,7 +27,7 @@ impl Default for App { .into_iter() .map(From::from) .collect(), - input: Default::default(), + input: String::default(), order: Order::Ascending, } } @@ -107,7 +107,7 @@ impl From<&str> for Item { fn from(s: &str) -> Self { Self { name: s.to_owned(), - color: Default::default(), + color: Color::default(), } } } diff --git a/examples/modal/src/main.rs b/examples/modal/src/main.rs index c050d3cc..b0e2c81b 100644 --- a/examples/modal/src/main.rs +++ b/examples/modal/src/main.rs @@ -228,7 +228,9 @@ mod modal { use iced::alignment::Alignment; use iced::event; use iced::mouse; - use iced::{Color, Element, Event, Length, Point, Rectangle, Size}; + use iced::{ + BorderRadius, Color, Element, Event, Length, Point, Rectangle, Size, + }; /// A widget that centers a modal element over some base element pub struct Modal<'a, Message, Renderer> { @@ -474,7 +476,7 @@ mod modal { renderer.fill_quad( renderer::Quad { bounds: layout.bounds(), - border_radius: Default::default(), + border_radius: BorderRadius::default(), border_width: 0.0, border_color: Color::TRANSPARENT, }, diff --git a/examples/scrollable/src/main.rs b/examples/scrollable/src/main.rs index 21e69284..d82ea841 100644 --- a/examples/scrollable/src/main.rs +++ b/examples/scrollable/src/main.rs @@ -391,12 +391,12 @@ impl scrollable::StyleSheet for ScrollbarCustomStyle { .background, border_radius: 2.0.into(), border_width: 0.0, - border_color: Default::default(), + border_color: Color::default(), scroller: Scroller { color: Color::from_rgb8(250, 85, 134), border_radius: 2.0.into(), border_width: 0.0, - border_color: Default::default(), + border_color: Color::default(), }, } } else { diff --git a/examples/solar_system/src/main.rs b/examples/solar_system/src/main.rs index 8fa8946e..8295dded 100644 --- a/examples/solar_system/src/main.rs +++ b/examples/solar_system/src/main.rs @@ -117,8 +117,8 @@ impl State { let (width, height) = window::Settings::default().size; State { - space_cache: Default::default(), - system_cache: Default::default(), + space_cache: canvas::Cache::default(), + system_cache: canvas::Cache::default(), start: now, now, stars: Self::generate_stars(width, height), diff --git a/renderer/src/geometry/cache.rs b/renderer/src/geometry/cache.rs index d82e7f69..d4bb04b3 100644 --- a/renderer/src/geometry/cache.rs +++ b/renderer/src/geometry/cache.rs @@ -35,7 +35,7 @@ impl Cache { /// Creates a new empty [`Cache`]. pub fn new() -> Self { Cache { - state: Default::default(), + state: RefCell::default(), } } diff --git a/src/settings.rs b/src/settings.rs index d9778d7e..c5e28e86 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -77,9 +77,9 @@ where fn default() -> Self { Self { id: None, - window: Default::default(), + window: window::Settings::default(), flags: Default::default(), - default_font: Default::default(), + default_font: Font::default(), default_text_size: Pixels(16.0), antialiasing: false, exit_on_close_request: true, diff --git a/src/window/settings.rs b/src/window/settings.rs index 458b9232..0ee573e5 100644 --- a/src/window/settings.rs +++ b/src/window/settings.rs @@ -52,7 +52,7 @@ impl Default for Settings { transparent: false, level: Level::default(), icon: None, - platform_specific: Default::default(), + platform_specific: PlatformSpecific::default(), } } } diff --git a/style/src/theme.rs b/style/src/theme.rs index 893d7202..3c1f2de6 100644 --- a/style/src/theme.rs +++ b/style/src/theme.rs @@ -393,7 +393,7 @@ impl container::StyleSheet for Theme { fn appearance(&self, style: &Self::Style) -> container::Appearance { match style { - Container::Transparent => Default::default(), + Container::Transparent => container::Appearance::default(), Container::Box => { let palette = self.extended_palette(); @@ -904,7 +904,7 @@ impl svg::StyleSheet for Theme { fn appearance(&self, style: &Self::Style) -> svg::Appearance { match style { - Svg::Default => Default::default(), + Svg::Default => svg::Appearance::default(), Svg::Custom(custom) => custom.appearance(self), } } @@ -1053,7 +1053,7 @@ impl text::StyleSheet for Theme { fn appearance(&self, style: Self::Style) -> text::Appearance { match style { - Text::Default => Default::default(), + Text::Default => text::Appearance::default(), Text::Color(c) => text::Appearance { color: Some(c) }, } } diff --git a/tiny_skia/src/geometry.rs b/tiny_skia/src/geometry.rs index 1d573f6a..1d14aa03 100644 --- a/tiny_skia/src/geometry.rs +++ b/tiny_skia/src/geometry.rs @@ -180,7 +180,7 @@ fn convert_path(path: &Path) -> Option { use iced_graphics::geometry::path::lyon_path; let mut builder = tiny_skia::PathBuilder::new(); - let mut last_point = Default::default(); + let mut last_point = lyon_path::math::Point::default(); for event in path.raw() { match event { diff --git a/wgpu/src/color.rs b/wgpu/src/color.rs index a1025601..20827e3c 100644 --- a/wgpu/src/color.rs +++ b/wgpu/src/color.rs @@ -12,7 +12,7 @@ pub fn convert( let sampler = device.create_sampler(&wgpu::SamplerDescriptor { label: Some("iced_wgpu.offscreen.sampler"), - ..Default::default() + ..wgpu::SamplerDescriptor::default() }); //sampler in 0 @@ -102,10 +102,10 @@ pub fn convert( primitive: wgpu::PrimitiveState { topology: wgpu::PrimitiveTopology::TriangleList, front_face: wgpu::FrontFace::Cw, - ..Default::default() + ..wgpu::PrimitiveState::default() }, depth_stencil: None, - multisample: Default::default(), + multisample: wgpu::MultisampleState::default(), multiview: None, }); diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index bd4f3e06..2a530cad 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -64,7 +64,7 @@ impl Pipeline { self.renderers.push(glyphon::TextRenderer::new( &mut self.atlas, device, - Default::default(), + wgpu::MultisampleState::default(), None, )); } diff --git a/widget/src/pick_list.rs b/widget/src/pick_list.rs index fa0e3471..27f32907 100644 --- a/widget/src/pick_list.rs +++ b/widget/src/pick_list.rs @@ -76,7 +76,7 @@ where text_line_height: text::LineHeight::default(), text_shaping: text::Shaping::Basic, font: None, - handle: Default::default(), + handle: Handle::default(), style: Default::default(), } } diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index 6f1e68fc..4cc97684 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -46,7 +46,7 @@ where id: None, width: Length::Shrink, height: Length::Shrink, - direction: Default::default(), + direction: Direction::default(), content: content.into(), on_scroll: None, style: Default::default(), diff --git a/widget/src/toggler.rs b/widget/src/toggler.rs index 2440317f..476c8330 100644 --- a/widget/src/toggler.rs +++ b/widget/src/toggler.rs @@ -286,7 +286,7 @@ where style, label_layout, tree.state.downcast_ref(), - Default::default(), + crate::text::Appearance::default(), ); } diff --git a/winit/src/settings.rs b/winit/src/settings.rs index 8d3e1b47..867dad0f 100644 --- a/winit/src/settings.rs +++ b/winit/src/settings.rs @@ -235,7 +235,7 @@ impl Default for Window { transparent: false, level: Level::default(), icon: None, - platform_specific: Default::default(), + platform_specific: PlatformSpecific::default(), } } } From caed50b277495e4375975f3f4e271b8fcbc0c33f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 20 Sep 2023 05:03:25 +0200 Subject: [PATCH 240/321] Fix `clippy::match-wildcard-for-single-variants` --- .cargo/config.toml | 32 +++++++++++++++++++++++++- examples/download_progress/src/main.rs | 2 +- examples/game_of_life/src/main.rs | 4 ++-- renderer/src/lib.rs | 4 ++-- wgpu/src/image/atlas.rs | 2 +- widget/src/scrollable.rs | 4 ++-- widget/src/text_input/cursor.rs | 4 ++-- 7 files changed, 41 insertions(+), 11 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index f5c00d9b..83564651 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,2 +1,32 @@ [alias] -lint = "clippy --workspace --no-deps -- -D warnings -D clippy::semicolon_if_nothing_returned -D clippy::trivially-copy-pass-by-ref -D clippy::default_trait_access" +lint = """ +clippy --workspace --no-deps -- \ + -D warnings \ + -D clippy::semicolon_if_nothing_returned \ + -D clippy::trivially-copy-pass-by-ref \ + -D clippy::default_trait_access \ + -D clippy::match-wildcard-for-single-variants +""" + +nitpick = """ +clippy --workspace --no-deps -- \ + -D warnings \ + -D clippy::pedantic \ + -A clippy::must_use_candidate \ + -A clippy::return_self_not_must_use \ + -A clippy::needless_pass_by_value \ + -A clippy::cast_precision_loss \ + -A clippy::cast_sign_loss \ + -A clippy::cast_possible_truncation \ + -A clippy::match_same_arms \ + -A clippy::missing-errors-doc \ + -A clippy::missing-panics-doc \ + -A clippy::cast_lossless \ + -A clippy::doc_markdown \ + -A clippy::items_after_statements \ + -A clippy::too_many_lines \ + -A clippy::module_name_repetitions \ + -A clippy::if_not_else \ + -A clippy::redundant_else \ + -A clippy::used_underscore_binding +""" diff --git a/examples/download_progress/src/main.rs b/examples/download_progress/src/main.rs index 001a1f8f..e52c604c 100644 --- a/examples/download_progress/src/main.rs +++ b/examples/download_progress/src/main.rs @@ -123,7 +123,7 @@ impl Download { | State::Errored { .. } => { self.state = State::Downloading { progress: 0.0 }; } - _ => {} + State::Downloading{ .. } => {} } } diff --git a/examples/game_of_life/src/main.rs b/examples/game_of_life/src/main.rs index 437d89d5..c774e769 100644 --- a/examples/game_of_life/src/main.rs +++ b/examples/game_of_life/src/main.rs @@ -472,7 +472,7 @@ mod grid { * (1.0 / self.scaling), )) } - _ => None, + Interaction::None => None, }; let event_status = match interaction { @@ -676,7 +676,7 @@ mod grid { Interaction::None if cursor.is_over(bounds) => { mouse::Interaction::Crosshair } - _ => mouse::Interaction::default(), + Interaction::None => mouse::Interaction::default(), } } } diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs index 8c76f52e..1347ce04 100644 --- a/renderer/src/lib.rs +++ b/renderer/src/lib.rs @@ -257,7 +257,7 @@ impl crate::graphics::geometry::Renderer for Renderer { crate::Geometry::TinySkia(primitive) => { renderer.draw_primitive(primitive); } - _ => unreachable!(), + crate::Geometry::Wgpu(_) => unreachable!(), } } } @@ -268,7 +268,7 @@ impl crate::graphics::geometry::Renderer for Renderer { crate::Geometry::Wgpu(primitive) => { renderer.draw_primitive(primitive); } - _ => unreachable!(), + crate::Geometry::TinySkia(_) => unreachable!(), } } } diff --git a/wgpu/src/image/atlas.rs b/wgpu/src/image/atlas.rs index e8ca4bd3..789e35b4 100644 --- a/wgpu/src/image/atlas.rs +++ b/wgpu/src/image/atlas.rs @@ -237,7 +237,7 @@ impl Atlas { })); } } - _ => {} + Layer::Full => {} } } diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index 4cc97684..49aed2f0 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -117,7 +117,7 @@ impl Direction { match self { Self::Horizontal(properties) => Some(properties), Self::Both { horizontal, .. } => Some(horizontal), - _ => None, + Self::Vertical(_) => None, } } @@ -126,7 +126,7 @@ impl Direction { match self { Self::Vertical(properties) => Some(properties), Self::Both { vertical, .. } => Some(vertical), - _ => None, + Self::Horizontal(_) => None, } } } diff --git a/widget/src/text_input/cursor.rs b/widget/src/text_input/cursor.rs index ea902485..f682b17d 100644 --- a/widget/src/text_input/cursor.rs +++ b/widget/src/text_input/cursor.rs @@ -56,7 +56,7 @@ impl Cursor { State::Selection { start, end } => { Some((start.min(end), start.max(end))) } - _ => None, + State::Index(_) => None, } } @@ -89,7 +89,7 @@ impl Cursor { match self.state(value) { State::Index(index) if index > 0 => self.move_to(index - 1), State::Selection { start, end } => self.move_to(start.min(end)), - _ => self.move_to(0), + State::Index(_) => self.move_to(0), } } From 1e4bade53aaaeb17542d0372ac827bcb7daf037c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 20 Sep 2023 05:07:34 +0200 Subject: [PATCH 241/321] Fix `clippy::redundant-closure-for-method-calls` --- .cargo/config.toml | 6 ++++-- widget/src/lazy/component.rs | 2 +- winit/src/system.rs | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 83564651..61bfbf17 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -5,7 +5,8 @@ clippy --workspace --no-deps -- \ -D clippy::semicolon_if_nothing_returned \ -D clippy::trivially-copy-pass-by-ref \ -D clippy::default_trait_access \ - -D clippy::match-wildcard-for-single-variants + -D clippy::match-wildcard-for-single-variants \ + -D clippy::redundant-closure-for-method-calls """ nitpick = """ @@ -28,5 +29,6 @@ clippy --workspace --no-deps -- \ -A clippy::module_name_repetitions \ -A clippy::if_not_else \ -A clippy::redundant_else \ - -A clippy::used_underscore_binding + -A clippy::used_underscore_binding \ + -A clippy::cast_possible_wrap """ diff --git a/widget/src/lazy/component.rs b/widget/src/lazy/component.rs index fe99a7f2..d454b72b 100644 --- a/widget/src/lazy/component.rs +++ b/widget/src/lazy/component.rs @@ -511,7 +511,7 @@ impl<'a, 'b, Message, Renderer, Event, S> Drop for Overlay<'a, 'b, Message, Renderer, Event, S> { fn drop(&mut self) { - if let Some(heads) = self.0.take().map(|inner| inner.into_heads()) { + if let Some(heads) = self.0.take().map(Inner::into_heads) { *heads.instance.tree.borrow_mut().borrow_mut() = Some(heads.tree); } } diff --git a/winit/src/system.rs b/winit/src/system.rs index 145a4d92..d4cef60e 100644 --- a/winit/src/system.rs +++ b/winit/src/system.rs @@ -23,7 +23,7 @@ pub(crate) fn information( let memory_used = sysinfo::get_current_pid() .and_then(|pid| system.process(pid).ok_or("Process not found")) - .map(|process| process.memory()) + .map(ProcessExt::memory) .ok(); Information { From 14ba939e674ec4d9ca53b506ffa3259d30216e85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 20 Sep 2023 05:19:24 +0200 Subject: [PATCH 242/321] Fix `clippy::unreadable_literal` --- .cargo/config.toml | 9 +++++++-- tiny_skia/src/vector.rs | 6 +++--- wgpu/src/triangle.rs | 10 +++++----- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 61bfbf17..4ae09897 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -6,7 +6,7 @@ clippy --workspace --no-deps -- \ -D clippy::trivially-copy-pass-by-ref \ -D clippy::default_trait_access \ -D clippy::match-wildcard-for-single-variants \ - -D clippy::redundant-closure-for-method-calls + -D clippy::redundant-closure-for-method-calls \ """ nitpick = """ @@ -30,5 +30,10 @@ clippy --workspace --no-deps -- \ -A clippy::if_not_else \ -A clippy::redundant_else \ -A clippy::used_underscore_binding \ - -A clippy::cast_possible_wrap + -A clippy::cast_possible_wrap \ + -A clippy::unnecessary_wraps \ + -A clippy::struct-excessive-bools \ + -A clippy::float-cmp \ + -A clippy::single_match_else \ + -A clippy::unreadable_literal """ diff --git a/tiny_skia/src/vector.rs b/tiny_skia/src/vector.rs index 490b9f69..a1cd269d 100644 --- a/tiny_skia/src/vector.rs +++ b/tiny_skia/src/vector.rs @@ -172,9 +172,9 @@ impl Cache { for pixel in bytemuck::cast_slice_mut::(image.data_mut()) { - *pixel = *pixel & 0xFF00FF00 - | ((0x000000FF & *pixel) << 16) - | ((0x00FF0000 & *pixel) >> 16); + *pixel = *pixel & 0xFF00_FF00 + | ((0x0000_00FF & *pixel) << 16) + | ((0x00FF_0000 & *pixel) >> 16); } } diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs index 7e1bd9cc..f8014ceb 100644 --- a/wgpu/src/triangle.rs +++ b/wgpu/src/triangle.rs @@ -329,12 +329,12 @@ impl Pipeline { fn fragment_target( texture_format: wgpu::TextureFormat, -) -> Option { - Some(wgpu::ColorTargetState { +) -> wgpu::ColorTargetState { + wgpu::ColorTargetState { format: texture_format, blend: Some(wgpu::BlendState::ALPHA_BLENDING), write_mask: wgpu::ColorWrites::ALL, - }) + } } fn primitive_state() -> wgpu::PrimitiveState { @@ -521,7 +521,7 @@ mod solid { fragment: Some(wgpu::FragmentState { module: &shader, entry_point: "solid_fs_main", - targets: &[triangle::fragment_target(format)], + targets: &[Some(triangle::fragment_target(format))], }), primitive: triangle::primitive_state(), depth_stencil: None, @@ -698,7 +698,7 @@ mod gradient { fragment: Some(wgpu::FragmentState { module: &shader, entry_point: "gradient_fs_main", - targets: &[triangle::fragment_target(format)], + targets: &[Some(triangle::fragment_target(format))], }), primitive: triangle::primitive_state(), depth_stencil: None, From 1019d1e518d8ffe760142ccd5ff33d077434c8b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 20 Sep 2023 05:23:15 +0200 Subject: [PATCH 243/321] Fix `clippy::filter_map_next` --- .cargo/config.toml | 5 ++++- widget/src/pane_grid.rs | 25 +++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 4ae09897..d49e034f 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -7,6 +7,7 @@ clippy --workspace --no-deps -- \ -D clippy::default_trait_access \ -D clippy::match-wildcard-for-single-variants \ -D clippy::redundant-closure-for-method-calls \ + -D clippy::filter_map_next """ nitpick = """ @@ -35,5 +36,7 @@ clippy --workspace --no-deps -- \ -A clippy::struct-excessive-bools \ -A clippy::float-cmp \ -A clippy::single_match_else \ - -A clippy::unreadable_literal + -A clippy::unreadable_literal \ + -A clippy::explicit_deref_methods \ + -A clippy::map_unwrap_or """ diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs index 3fb25972..2d25a543 100644 --- a/widget/src/pane_grid.rs +++ b/widget/src/pane_grid.rs @@ -606,11 +606,10 @@ pub fn update<'a, Message, T: Draggable>( } else { let dropped_region = contents .zip(layout.children()) - .filter_map(|(target, layout)| { + .find_map(|(target, layout)| { layout_region(layout, cursor_position) .map(|region| (target, region)) - }) - .next(); + }); match dropped_region { Some(((target, _), region)) @@ -1151,21 +1150,19 @@ pub struct ResizeEvent { * Helpers */ fn hovered_split<'a>( - splits: impl Iterator, + mut splits: impl Iterator, spacing: f32, cursor_position: Point, ) -> Option<(Split, Axis, Rectangle)> { - splits - .filter_map(|(split, (axis, region, ratio))| { - let bounds = axis.split_line_bounds(*region, *ratio, spacing); + splits.find_map(|(split, (axis, region, ratio))| { + let bounds = axis.split_line_bounds(*region, *ratio, spacing); - if bounds.contains(cursor_position) { - Some((*split, *axis, bounds)) - } else { - None - } - }) - .next() + if bounds.contains(cursor_position) { + Some((*split, *axis, bounds)) + } else { + None + } + }) } /// The visible contents of the [`PaneGrid`] From f8f1a8634402a5eb4275ff0814d03a3104fea65a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 20 Sep 2023 05:30:08 +0200 Subject: [PATCH 244/321] Fix `clippy::manual_let_else` --- .cargo/config.toml | 8 ++++++-- examples/bezier_tool/src/main.rs | 9 +++------ examples/game_of_life/src/main.rs | 9 +++------ examples/integration/src/main.rs | 2 +- examples/integration/src/scene.rs | 1 - examples/sierpinski_triangle/src/main.rs | 5 +---- examples/websocket/src/echo/server.rs | 5 +---- 7 files changed, 15 insertions(+), 24 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index d49e034f..2c6b20b6 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -7,7 +7,8 @@ clippy --workspace --no-deps -- \ -D clippy::default_trait_access \ -D clippy::match-wildcard-for-single-variants \ -D clippy::redundant-closure-for-method-calls \ - -D clippy::filter_map_next + -D clippy::filter_map_next \ + -D clippy::manual_let_else """ nitpick = """ @@ -38,5 +39,8 @@ clippy --workspace --no-deps -- \ -A clippy::single_match_else \ -A clippy::unreadable_literal \ -A clippy::explicit_deref_methods \ - -A clippy::map_unwrap_or + -A clippy::map_unwrap_or \ + -A clippy::unnested_or_patterns \ + -A clippy::similar_names \ + -A clippy::unused_self """ diff --git a/examples/bezier_tool/src/main.rs b/examples/bezier_tool/src/main.rs index 9e4bc49c..56cb23ba 100644 --- a/examples/bezier_tool/src/main.rs +++ b/examples/bezier_tool/src/main.rs @@ -100,12 +100,9 @@ mod bezier { bounds: Rectangle, cursor: mouse::Cursor, ) -> (event::Status, Option) { - let cursor_position = - if let Some(position) = cursor.position_in(bounds) { - position - } else { - return (event::Status::Ignored, None); - }; + let Some(cursor_position) = cursor.position_in(bounds) else { + return (event::Status::Ignored, None); + }; match event { Event::Mouse(mouse_event) => { diff --git a/examples/game_of_life/src/main.rs b/examples/game_of_life/src/main.rs index c774e769..96840143 100644 --- a/examples/game_of_life/src/main.rs +++ b/examples/game_of_life/src/main.rs @@ -406,12 +406,9 @@ mod grid { *interaction = Interaction::None; } - let cursor_position = - if let Some(position) = cursor.position_in(bounds) { - position - } else { - return (event::Status::Ignored, None); - }; + let Some(cursor_position) = cursor.position_in(bounds) else { + return (event::Status::Ignored, None); + }; let cell = Cell::at(self.project(cursor_position, bounds.size())); let is_populated = self.state.contains(&cell); diff --git a/examples/integration/src/main.rs b/examples/integration/src/main.rs index 243297b2..4415fefa 100644 --- a/examples/integration/src/main.rs +++ b/examples/integration/src/main.rs @@ -256,7 +256,7 @@ pub fn main() -> Result<(), Box> { { // We clear the frame - let mut render_pass = scene.clear( + let mut render_pass = Scene::clear( &view, &mut encoder, program.background_color(), diff --git a/examples/integration/src/scene.rs b/examples/integration/src/scene.rs index 90c7efbf..01808f40 100644 --- a/examples/integration/src/scene.rs +++ b/examples/integration/src/scene.rs @@ -16,7 +16,6 @@ impl Scene { } pub fn clear<'a>( - &self, target: &'a wgpu::TextureView, encoder: &'a mut wgpu::CommandEncoder, background_color: Color, diff --git a/examples/sierpinski_triangle/src/main.rs b/examples/sierpinski_triangle/src/main.rs index 885d3c63..ef935c33 100644 --- a/examples/sierpinski_triangle/src/main.rs +++ b/examples/sierpinski_triangle/src/main.rs @@ -108,10 +108,7 @@ impl canvas::Program for SierpinskiGraph { bounds: Rectangle, cursor: mouse::Cursor, ) -> (event::Status, Option) { - let cursor_position = if let Some(position) = cursor.position_in(bounds) - { - position - } else { + let Some(cursor_position) = cursor.position_in(bounds) else { return (event::Status::Ignored, None); }; diff --git a/examples/websocket/src/echo/server.rs b/examples/websocket/src/echo/server.rs index 168a635e..a696a7a4 100644 --- a/examples/websocket/src/echo/server.rs +++ b/examples/websocket/src/echo/server.rs @@ -47,10 +47,7 @@ async fn user_connected(ws: WebSocket) { }); while let Some(result) = user_ws_rx.next().await { - let msg = match result { - Ok(msg) => msg, - Err(_) => break, - }; + let Ok(msg) = result else { break }; let _ = tx.send(msg).await; } From 432d9f5f97a7312878f2f86ead13b6742638f7e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 20 Sep 2023 05:36:11 +0200 Subject: [PATCH 245/321] Fix `clippy::unused_async` --- .cargo/config.toml | 3 ++- examples/screenshot/Cargo.toml | 8 ++++++-- examples/screenshot/src/main.rs | 23 ++++++++++++++--------- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 2c6b20b6..9e265aa9 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -8,7 +8,8 @@ clippy --workspace --no-deps -- \ -D clippy::match-wildcard-for-single-variants \ -D clippy::redundant-closure-for-method-calls \ -D clippy::filter_map_next \ - -D clippy::manual_let_else + -D clippy::manual_let_else \ + -D clippy::unused_async """ nitpick = """ diff --git a/examples/screenshot/Cargo.toml b/examples/screenshot/Cargo.toml index dcd77439..77b108bd 100644 --- a/examples/screenshot/Cargo.toml +++ b/examples/screenshot/Cargo.toml @@ -7,7 +7,11 @@ publish = false [dependencies] iced.workspace = true -iced.features = ["debug", "image", "advanced"] +iced.features = ["debug", "image", "advanced", "tokio"] + +image.workspace = true +image.features = ["png"] + +tokio.workspace = true -image = { workspace = true, features = ["png"]} tracing-subscriber = "0.3" \ No newline at end of file diff --git a/examples/screenshot/src/main.rs b/examples/screenshot/src/main.rs index d9784dc8..fa06d3e9 100644 --- a/examples/screenshot/src/main.rs +++ b/examples/screenshot/src/main.rs @@ -273,15 +273,20 @@ impl Application for Example { async fn save_to_png(screenshot: Screenshot) -> Result { let path = "screenshot.png".to_string(); - img::save_buffer( - &path, - &screenshot.bytes, - screenshot.size.width, - screenshot.size.height, - ColorType::Rgba8, - ) - .map(|_| path) - .map_err(|err| PngError(format!("{err:?}"))) + + tokio::task::spawn_blocking(move || { + img::save_buffer( + &path, + &screenshot.bytes, + screenshot.size.width, + screenshot.size.height, + ColorType::Rgba8, + ) + .map(|_| path) + .map_err(|err| PngError(format!("{err:?}"))) + }) + .await + .expect("Blocking task to finish") } #[derive(Clone, Debug)] From 33d780f691829ecd32f3a218008fcb40e005deb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 20 Sep 2023 05:37:20 +0200 Subject: [PATCH 246/321] Run `cargo fmt` --- examples/download_progress/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/download_progress/src/main.rs b/examples/download_progress/src/main.rs index e52c604c..a2fcb275 100644 --- a/examples/download_progress/src/main.rs +++ b/examples/download_progress/src/main.rs @@ -123,7 +123,7 @@ impl Download { | State::Errored { .. } => { self.state = State::Downloading { progress: 0.0 }; } - State::Downloading{ .. } => {} + State::Downloading { .. } => {} } } From 76873921af3cd04ac0cbed01ebbd66936454dbe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 20 Sep 2023 15:56:05 +0200 Subject: [PATCH 247/321] Fix `build` workflow in GitHub CI --- .github/workflows/build.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b30b7a61..7cfbff89 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,7 +40,6 @@ jobs: - uses: actions/checkout@master - name: Enable static CRT linkage run: | - mkdir .cargo echo '[target.x86_64-pc-windows-msvc]' >> .cargo/config echo 'rustflags = ["-Ctarget-feature=+crt-static"]' >> .cargo/config - name: Run the application without starting the shell From b27762554627b8e89f2b840b1a8a512e22d4cd87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 20 Sep 2023 16:26:43 +0200 Subject: [PATCH 248/321] Revert "Chore: Apply clippy map transformations" This reverts commit c997aad85d7ee6e77085e50e5e599002549d228f. --- core/src/mouse/click.rs | 4 +++- examples/integration/src/main.rs | 6 ++---- examples/screenshot/src/main.rs | 5 ++++- wgpu/src/image/vector.rs | 2 +- wgpu/src/triangle.rs | 2 +- winit/src/application/state.rs | 3 ++- winit/src/clipboard.rs | 3 ++- 7 files changed, 15 insertions(+), 10 deletions(-) diff --git a/core/src/mouse/click.rs b/core/src/mouse/click.rs index 53354098..9cc44a71 100644 --- a/core/src/mouse/click.rs +++ b/core/src/mouse/click.rs @@ -69,6 +69,8 @@ impl Click { }; self.position == new_position - && duration.is_some_and(|duration| duration.as_millis() <= 300) + && duration + .map(|duration| duration.as_millis() <= 300) + .unwrap_or(false) } } diff --git a/examples/integration/src/main.rs b/examples/integration/src/main.rs index 4415fefa..c26d52fe 100644 --- a/examples/integration/src/main.rs +++ b/examples/integration/src/main.rs @@ -200,10 +200,8 @@ pub fn main() -> Result<(), Box> { viewport.scale_factor(), ) }) - .map_or( - mouse::Cursor::Unavailable, - mouse::Cursor::Available, - ), + .map(mouse::Cursor::Available) + .unwrap_or(mouse::Cursor::Unavailable), &mut renderer, &Theme::Dark, &renderer::Style { diff --git a/examples/screenshot/src/main.rs b/examples/screenshot/src/main.rs index fa06d3e9..ab0a2ae3 100644 --- a/examples/screenshot/src/main.rs +++ b/examples/screenshot/src/main.rs @@ -298,7 +298,10 @@ fn numeric_input( ) -> Element<'_, Option> { text_input( placeholder, - &value.as_ref().map_or_else(String::new, ToString::to_string), + &value + .as_ref() + .map(ToString::to_string) + .unwrap_or_else(String::new), ) .on_input(move |text| { if text.is_empty() { diff --git a/wgpu/src/image/vector.rs b/wgpu/src/image/vector.rs index e8baae4f..6582bb82 100644 --- a/wgpu/src/image/vector.rs +++ b/wgpu/src/image/vector.rs @@ -56,7 +56,7 @@ impl Cache { .ok() }); - tree.map_or(Svg::NotFound, Svg::Loaded) + tree.map(Svg::Loaded).unwrap_or(Svg::NotFound) } svg::Data::Bytes(bytes) => { match usvg::Tree::from_data(bytes, &usvg::Options::default()) { diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs index f8014ceb..c55b93bf 100644 --- a/wgpu/src/triangle.rs +++ b/wgpu/src/triangle.rs @@ -349,7 +349,7 @@ fn multisample_state( antialiasing: Option, ) -> wgpu::MultisampleState { wgpu::MultisampleState { - count: antialiasing.map_or(1, Antialiasing::sample_count), + count: antialiasing.map(|a| a.sample_count()).unwrap_or(1), mask: !0, alpha_to_coverage_enabled: false, } diff --git a/winit/src/application/state.rs b/winit/src/application/state.rs index 9d1d5dcf..e655529a 100644 --- a/winit/src/application/state.rs +++ b/winit/src/application/state.rs @@ -97,7 +97,8 @@ where self.viewport.scale_factor(), ) }) - .map_or(mouse::Cursor::Unavailable, mouse::Cursor::Available) + .map(mouse::Cursor::Available) + .unwrap_or(mouse::Cursor::Unavailable) } /// Returns the current keyboard modifiers of the [`State`]. diff --git a/winit/src/clipboard.rs b/winit/src/clipboard.rs index 0a09c255..f7a32868 100644 --- a/winit/src/clipboard.rs +++ b/winit/src/clipboard.rs @@ -17,7 +17,8 @@ impl Clipboard { pub fn connect(window: &winit::window::Window) -> Clipboard { let state = window_clipboard::Clipboard::connect(window) .ok() - .map_or(State::Unavailable, State::Connected); + .map(State::Connected) + .unwrap_or(State::Unavailable); Clipboard { state } } From b8ddd158da1b4e73e67fd090f8d36ed07f191874 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 20 Sep 2023 16:27:54 +0200 Subject: [PATCH 249/321] Simplify `map` call in `iced_wgpu::triangle` --- wgpu/src/triangle.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs index c55b93bf..644c9f84 100644 --- a/wgpu/src/triangle.rs +++ b/wgpu/src/triangle.rs @@ -349,7 +349,7 @@ fn multisample_state( antialiasing: Option, ) -> wgpu::MultisampleState { wgpu::MultisampleState { - count: antialiasing.map(|a| a.sample_count()).unwrap_or(1), + count: antialiasing.map(Antialiasing::sample_count).unwrap_or(1), mask: !0, alpha_to_coverage_enabled: false, } From f137d71e8fb926e784680d56d1cfa6817c3710a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 20 Sep 2023 16:40:03 +0200 Subject: [PATCH 250/321] Centralize `clippy` lints in `.cargo/config.toml` --- .cargo/config.toml | 9 ++++++++- core/src/lib.rs | 6 ------ futures/src/lib.rs | 6 ------ graphics/src/lib.rs | 6 ------ renderer/src/lib.rs | 12 +----------- runtime/src/lib.rs | 5 ----- src/lib.rs | 6 ------ style/src/lib.rs | 6 ------ tiny_skia/src/lib.rs | 12 +----------- wgpu/src/lib.rs | 6 ------ widget/src/lib.rs | 6 ------ widget/src/text_input/value.rs | 11 ++++++----- winit/src/lib.rs | 6 ------ 13 files changed, 16 insertions(+), 81 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 9e265aa9..e3e32033 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -2,6 +2,7 @@ lint = """ clippy --workspace --no-deps -- \ -D warnings \ + -A clippy::type_complexity \ -D clippy::semicolon_if_nothing_returned \ -D clippy::trivially-copy-pass-by-ref \ -D clippy::default_trait_access \ @@ -9,9 +10,15 @@ clippy --workspace --no-deps -- \ -D clippy::redundant-closure-for-method-calls \ -D clippy::filter_map_next \ -D clippy::manual_let_else \ - -D clippy::unused_async + -D clippy::unused_async \ + -D clippy::from_over_into \ + -D clippy::needless_borrow \ + -D clippy::new_without_default \ + -D clippy::useless_conversion """ +#![allow(clippy::inherent_to_string, clippy::type_complexity)] + nitpick = """ clippy --workspace --no-deps -- \ -D warnings \ diff --git a/core/src/lib.rs b/core/src/lib.rs index 1bfba7bd..54ea5839 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -14,14 +14,8 @@ missing_debug_implementations, missing_docs, unused_results, - clippy::extra_unused_lifetimes, - clippy::from_over_into, - clippy::needless_borrow, - clippy::new_without_default, - clippy::useless_conversion, rustdoc::broken_intra_doc_links )] -#![allow(clippy::inherent_to_string, clippy::type_complexity)] pub mod alignment; pub mod clipboard; pub mod event; diff --git a/futures/src/lib.rs b/futures/src/lib.rs index abc46176..d54ba18a 100644 --- a/futures/src/lib.rs +++ b/futures/src/lib.rs @@ -9,14 +9,8 @@ missing_debug_implementations, missing_docs, unused_results, - clippy::extra_unused_lifetimes, - clippy::from_over_into, - clippy::needless_borrow, - clippy::new_without_default, - clippy::useless_conversion, rustdoc::broken_intra_doc_links )] -#![allow(clippy::inherent_to_string, clippy::type_complexity)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] pub use futures; pub use iced_core as core; diff --git a/graphics/src/lib.rs b/graphics/src/lib.rs index 01a358ca..a0729058 100644 --- a/graphics/src/lib.rs +++ b/graphics/src/lib.rs @@ -13,14 +13,8 @@ //missing_docs, unsafe_code, unused_results, - clippy::extra_unused_lifetimes, - clippy::from_over_into, - clippy::needless_borrow, - clippy::new_without_default, - clippy::useless_conversion, rustdoc::broken_intra_doc_links )] -#![allow(clippy::inherent_to_string, clippy::type_complexity)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] mod antialiasing; mod error; diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs index 1347ce04..7594d532 100644 --- a/renderer/src/lib.rs +++ b/renderer/src/lib.rs @@ -1,15 +1,5 @@ #![forbid(rust_2018_idioms)] -#![deny( - unsafe_code, - unused_results, - clippy::extra_unused_lifetimes, - clippy::from_over_into, - clippy::needless_borrow, - clippy::new_without_default, - clippy::useless_conversion, - rustdoc::broken_intra_doc_links -)] -#![allow(clippy::inherent_to_string, clippy::type_complexity)] +#![deny(unsafe_code, unused_results, rustdoc::broken_intra_doc_links)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] pub mod compositor; diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index c3261cca..29e94d65 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -13,11 +13,6 @@ missing_debug_implementations, missing_docs, unused_results, - clippy::extra_unused_lifetimes, - clippy::from_over_into, - clippy::needless_borrow, - clippy::new_without_default, - clippy::useless_conversion, rustdoc::broken_intra_doc_links )] #![cfg_attr(docsrs, feature(doc_auto_cfg))] diff --git a/src/lib.rs b/src/lib.rs index 3cbe716a..cb6e86d4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -156,14 +156,8 @@ missing_debug_implementations, missing_docs, unused_results, - clippy::extra_unused_lifetimes, - clippy::from_over_into, - clippy::needless_borrow, - clippy::new_without_default, - clippy::useless_conversion, rustdoc::broken_intra_doc_links )] -#![allow(clippy::inherent_to_string, clippy::type_complexity)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] use iced_widget::graphics; use iced_widget::renderer; diff --git a/style/src/lib.rs b/style/src/lib.rs index 0c555ed8..30f17a44 100644 --- a/style/src/lib.rs +++ b/style/src/lib.rs @@ -10,16 +10,10 @@ #![forbid(unsafe_code, rust_2018_idioms)] #![deny( unused_results, - clippy::extra_unused_lifetimes, - clippy::from_over_into, - clippy::needless_borrow, - clippy::new_without_default, - clippy::useless_conversion, missing_docs, unused_results, rustdoc::broken_intra_doc_links )] -#![allow(clippy::inherent_to_string, clippy::type_complexity)] pub use iced_core as core; pub mod application; diff --git a/tiny_skia/src/lib.rs b/tiny_skia/src/lib.rs index e48468e9..ec8012be 100644 --- a/tiny_skia/src/lib.rs +++ b/tiny_skia/src/lib.rs @@ -1,15 +1,5 @@ #![forbid(rust_2018_idioms)] -#![deny( - unsafe_code, - unused_results, - clippy::extra_unused_lifetimes, - clippy::from_over_into, - clippy::needless_borrow, - clippy::new_without_default, - clippy::useless_conversion, - rustdoc::broken_intra_doc_links -)] -#![allow(clippy::inherent_to_string, clippy::type_complexity)] +#![deny(unsafe_code, unused_results, rustdoc::broken_intra_doc_links)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] pub mod window; diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 2f483751..6d26723e 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -26,14 +26,8 @@ //missing_docs, unsafe_code, unused_results, - clippy::extra_unused_lifetimes, - clippy::from_over_into, - clippy::needless_borrow, - clippy::new_without_default, - clippy::useless_conversion, rustdoc::broken_intra_doc_links )] -#![allow(clippy::inherent_to_string, clippy::type_complexity)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] pub mod layer; pub mod primitive; diff --git a/widget/src/lib.rs b/widget/src/lib.rs index 7e204171..6feb948c 100644 --- a/widget/src/lib.rs +++ b/widget/src/lib.rs @@ -7,14 +7,8 @@ missing_debug_implementations, missing_docs, unused_results, - clippy::extra_unused_lifetimes, - clippy::from_over_into, - clippy::needless_borrow, - clippy::new_without_default, - clippy::useless_conversion, rustdoc::broken_intra_doc_links )] -#![allow(clippy::inherent_to_string, clippy::type_complexity)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] pub use iced_renderer as renderer; pub use iced_renderer::graphics; diff --git a/widget/src/text_input/value.rs b/widget/src/text_input/value.rs index d1b056c8..46a1f754 100644 --- a/widget/src/text_input/value.rs +++ b/widget/src/text_input/value.rs @@ -89,11 +89,6 @@ impl Value { Self { graphemes } } - /// Converts the [`Value`] into a `String`. - pub fn to_string(&self) -> String { - self.graphemes.concat() - } - /// Inserts a new `char` at the given grapheme `index`. pub fn insert(&mut self, index: usize, c: char) { self.graphemes.insert(index, c.to_string()); @@ -131,3 +126,9 @@ impl Value { } } } + +impl std::fmt::Display for Value { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.graphemes.concat()) + } +} diff --git a/winit/src/lib.rs b/winit/src/lib.rs index 9852a182..95b55bb9 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -22,15 +22,9 @@ missing_debug_implementations, missing_docs, unused_results, - clippy::extra_unused_lifetimes, - clippy::from_over_into, - clippy::needless_borrow, - clippy::new_without_default, - clippy::useless_conversion, unsafe_code, rustdoc::broken_intra_doc_links )] -#![allow(clippy::inherent_to_string, clippy::type_complexity)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] pub use iced_graphics as graphics; pub use iced_runtime as runtime; From bc9bb28b1ccd1248d63ccdfef2f57d7aa837abbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 20 Sep 2023 16:41:08 +0200 Subject: [PATCH 251/321] Fix `cargo nitpick` alias --- .cargo/config.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/.cargo/config.toml b/.cargo/config.toml index e3e32033..3e02dda8 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -23,6 +23,7 @@ nitpick = """ clippy --workspace --no-deps -- \ -D warnings \ -D clippy::pedantic \ + -A clippy::type_complexity \ -A clippy::must_use_candidate \ -A clippy::return_self_not_must_use \ -A clippy::needless_pass_by_value \ From 25d47c3238ce23854e2c78e2bd9ad2b1f4b326b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 21 Sep 2023 06:05:46 +0200 Subject: [PATCH 252/321] Remove `rangemap` patch in `Cargo.toml` --- Cargo.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8899fa67..77d4c647 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -163,7 +163,3 @@ winit = { git = "https://github.com/iced-rs/winit.git", rev = "c52db2045d0a2f1b8 [patch.crates-io.cosmic-text] git = "https://github.com/hecrj/cosmic-text.git" branch = "respect-fontconfig-aliases" - -[patch.crates-io.rangemap] -git = "https://github.com/hecrj/rangemap.git" -branch = "fix/partial-eq" From da5dd2526a2d9ee27e9405ed19c0f7a641160c54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 21 Sep 2023 06:07:19 +0200 Subject: [PATCH 253/321] Round `ScrollDelta::Lines` in `TextEditor` --- widget/src/text_editor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index 4191e02c..ac927fbc 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -545,7 +545,7 @@ impl Update { action(Action::Scroll { lines: match delta { mouse::ScrollDelta::Lines { y, .. } => { - -y as i32 * 4 + -y.round() as i32 * 4 } mouse::ScrollDelta::Pixels { y, .. } => { -y.signum() as i32 From 7373dd856b8837c2d91067b45e43b8f0e767c917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 21 Sep 2023 06:13:08 +0200 Subject: [PATCH 254/321] Scroll at least one line on macOS in `TextEditor` --- widget/src/text_editor.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index ac927fbc..76f3cc18 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -545,7 +545,11 @@ impl Update { action(Action::Scroll { lines: match delta { mouse::ScrollDelta::Lines { y, .. } => { - -y.round() as i32 * 4 + if y > 0.0 { + -(y * 4.0).min(1.0) as i32 + } else { + 0 + } } mouse::ScrollDelta::Pixels { y, .. } => { -y.signum() as i32 From 68d49459ce0e8b28e56b71970cb26e66ac1b01b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 21 Sep 2023 06:17:47 +0200 Subject: [PATCH 255/321] Fix vertical scroll for `TextEditor` --- widget/src/text_editor.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index 76f3cc18..e8187b9c 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -545,8 +545,9 @@ impl Update { action(Action::Scroll { lines: match delta { mouse::ScrollDelta::Lines { y, .. } => { - if y > 0.0 { - -(y * 4.0).min(1.0) as i32 + if y.abs() > 0.0 { + (y.signum() * -(y.abs() * 4.0).max(1.0)) + as i32 } else { 0 } From 70e49df4289b925d24f92ce5c91ef2b03dbc54e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 22 Sep 2023 05:50:31 +0200 Subject: [PATCH 256/321] Fix selection clipping out of bounds in `TextEditor` --- widget/src/text_editor.rs | 63 ++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index e8187b9c..c142c22d 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -406,38 +406,47 @@ where style.text_color, ); + let translation = Vector::new( + bounds.x + self.padding.left, + bounds.y + self.padding.top, + ); + if state.is_focused { match internal.editor.cursor() { Cursor::Caret(position) => { - renderer.fill_quad( - renderer::Quad { - bounds: Rectangle { - x: position.x + bounds.x + self.padding.left, - y: position.y + bounds.y + self.padding.top, - width: 1.0, - height: self - .line_height - .to_absolute(self.text_size.unwrap_or_else( - || renderer.default_size(), - )) - .into(), - }, - border_radius: 0.0.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, - }, - theme.value_color(&self.style), - ); - } - Cursor::Selection(ranges) => { - for range in ranges { + let position = position + translation; + + if bounds.contains(position) { renderer.fill_quad( renderer::Quad { - bounds: range - + Vector::new( - bounds.x + self.padding.left, - bounds.y + self.padding.top, - ), + bounds: Rectangle { + x: position.x, + y: position.y, + width: 1.0, + height: self + .line_height + .to_absolute( + self.text_size.unwrap_or_else( + || renderer.default_size(), + ), + ) + .into(), + }, + border_radius: 0.0.into(), + border_width: 0.0, + border_color: Color::TRANSPARENT, + }, + theme.value_color(&self.style), + ); + } + } + Cursor::Selection(ranges) => { + for range in ranges.into_iter().filter_map(|range| { + bounds.intersection(&(range + translation)) + }) { + renderer.fill_quad( + renderer::Quad { + bounds: range, border_radius: 0.0.into(), border_width: 0.0, border_color: Color::TRANSPARENT, From af21cf82492bf7ffa1241cebae182c5916fc07d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 22 Sep 2023 05:55:27 +0200 Subject: [PATCH 257/321] Remove `patch.crates-io` section for `cosmic-text` in `Cargo.toml` --- Cargo.toml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 77d4c647..888e2df8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -121,10 +121,10 @@ iced_winit = { version = "0.12", path = "winit" } async-std = "1.0" bitflags = "1.0" bytemuck = { version = "1.0", features = ["derive"] } -cosmic-text = "0.9" +cosmic-text = { git = "https://github.com/pop-os/cosmic-text.git", rev = "30398c2f0cb79267d440870bc47967579e31a2ae" } futures = "0.3" glam = "0.24" -glyphon = { git = "https://github.com/grovesNL/glyphon.git", rev = "20f0f8fa80e0d0df4c63634ce9176fa489546ca9" } +glyphon = { git = "https://github.com/hecrj/glyphon.git", rev = "0a8366be5ec6d48c3e10c996ba840936992d878f" } guillotiere = "0.6" half = "2.2" image = "0.24" @@ -159,7 +159,3 @@ wgpu = "0.17" winapi = "0.3" window_clipboard = "0.3" winit = { git = "https://github.com/iced-rs/winit.git", rev = "c52db2045d0a2f1b8d9923870de1d4ab1994146e", default-features = false } - -[patch.crates-io.cosmic-text] -git = "https://github.com/hecrj/cosmic-text.git" -branch = "respect-fontconfig-aliases" From 8cc19de254c37d3123d5ea1b6513f1f34d35c7c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 22 Sep 2023 06:00:51 +0200 Subject: [PATCH 258/321] Add `text` helper method for `text_editor::Content` --- examples/editor/src/main.rs | 19 +------------------ widget/src/text_editor.rs | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs index f49ca6e8..a69e1f54 100644 --- a/examples/editor/src/main.rs +++ b/examples/editor/src/main.rs @@ -114,25 +114,8 @@ impl Application for Editor { } else { self.is_loading = true; - let mut contents = self.content.lines().enumerate().fold( - String::new(), - |mut contents, (i, line)| { - if i > 0 { - contents.push('\n'); - } - - contents.push_str(&line); - - contents - }, - ); - - if !contents.ends_with('\n') { - contents.push('\n'); - } - Command::perform( - save_file(self.file.clone(), contents), + save_file(self.file.clone(), self.content.text()), Message::FileSaved, ) } diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index c142c22d..6d25967e 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -190,6 +190,27 @@ where } } + pub fn text(&self) -> String { + let mut text = self.lines().enumerate().fold( + String::new(), + |mut contents, (i, line)| { + if i > 0 { + contents.push('\n'); + } + + contents.push_str(&line); + + contents + }, + ); + + if !text.ends_with('\n') { + text.push('\n'); + } + + text + } + pub fn selection(&self) -> Option { self.0.borrow().editor.selection() } From e0233ebc3ce4791d094c52eeef81cce78b9bc578 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Thu, 3 Aug 2023 10:19:28 -0700 Subject: [PATCH 259/321] Fix `Command::perform` to return a `Command` This seems like clearly the correct thing to do here. If the type bound on `Command` isn't specified, it makes no difference, since the generic is inferred in a way that works with either definition. But this is important if `Command` is aliased with a concrete type. --- runtime/src/command.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime/src/command.rs b/runtime/src/command.rs index cd4c51ff..b74097bd 100644 --- a/runtime/src/command.rs +++ b/runtime/src/command.rs @@ -40,9 +40,9 @@ impl Command { /// Creates a [`Command`] that performs the action of the given future. pub fn perform( - future: impl Future + 'static + MaybeSend, - f: impl FnOnce(T) -> A + 'static + MaybeSend, - ) -> Command { + future: impl Future + 'static + MaybeSend, + f: impl FnOnce(A) -> T + 'static + MaybeSend, + ) -> Command { use iced_futures::futures::FutureExt; Command::single(Action::Future(Box::pin(future.map(f)))) From 54e6d2b5fa1fe29e2e3588b51f6cfff36563cefc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 18 Oct 2023 17:49:19 -0500 Subject: [PATCH 260/321] Fix lint in `screenshot` example --- examples/screenshot/src/main.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/screenshot/src/main.rs b/examples/screenshot/src/main.rs index ab0a2ae3..f781a401 100644 --- a/examples/screenshot/src/main.rs +++ b/examples/screenshot/src/main.rs @@ -298,10 +298,7 @@ fn numeric_input( ) -> Element<'_, Option> { text_input( placeholder, - &value - .as_ref() - .map(ToString::to_string) - .unwrap_or_else(String::new), + &value.as_ref().map(ToString::to_string).unwrap_or_default(), ) .on_input(move |text| { if text.is_empty() { From f1b1344d59fa7354615f560bd25ed01ad0c9f865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 22 Oct 2023 15:08:08 +0200 Subject: [PATCH 261/321] Run `cargo update` before `cargo audit` in `audit` workflow --- .github/workflows/audit.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index e9f4b0c5..bfb617fb 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -12,6 +12,8 @@ jobs: - name: Install cargo-audit run: cargo install cargo-audit - uses: actions/checkout@master + - name: Resolve dependencies + run: cargo update - name: Audit vulnerabilities run: cargo audit From 86b877517feb15b2155c6cfef29246a3f281c8ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 27 Oct 2023 03:21:40 +0200 Subject: [PATCH 262/321] Update `wgpu` to `0.18` and `cosmic-text` to `0.10` --- Cargo.toml | 6 +++--- examples/integration/src/scene.rs | 4 +++- wgpu/src/backend.rs | 8 ++++++-- wgpu/src/color.rs | 4 +++- wgpu/src/triangle.rs | 7 ++++++- wgpu/src/triangle/msaa.rs | 4 +++- 6 files changed, 24 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index af74a3cf..bb8b4752 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -114,10 +114,10 @@ iced_winit = { version = "0.12", path = "winit" } async-std = "1.0" bitflags = "1.0" bytemuck = { version = "1.0", features = ["derive"] } -cosmic-text = "0.9" +cosmic-text = "0.10" futures = "0.3" glam = "0.24" -glyphon = { git = "https://github.com/grovesNL/glyphon.git", rev = "20f0f8fa80e0d0df4c63634ce9176fa489546ca9" } +glyphon = { git = "https://github.com/hecrj/glyphon.git", rev = "2caa9fc5e5923c1d827d177c3619cab7e9885b85" } guillotiere = "0.6" half = "2.2" image = "0.24" @@ -147,7 +147,7 @@ unicode-segmentation = "1.0" wasm-bindgen-futures = "0.4" wasm-timer = "0.2" web-sys = "0.3" -wgpu = "0.17" +wgpu = "0.18" winapi = "0.3" window_clipboard = "0.3" winit = { git = "https://github.com/iced-rs/winit.git", rev = "c52db2045d0a2f1b8d9923870de1d4ab1994146e", default-features = false } diff --git a/examples/integration/src/scene.rs b/examples/integration/src/scene.rs index 01808f40..e29558bf 100644 --- a/examples/integration/src/scene.rs +++ b/examples/integration/src/scene.rs @@ -36,10 +36,12 @@ impl Scene { a: a as f64, } }), - store: true, + store: wgpu::StoreOp::Store, }, })], depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, }) } diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index 65c63f19..32b8a189 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -222,10 +222,12 @@ impl Backend { }), None => wgpu::LoadOp::Load, }, - store: true, + store: wgpu::StoreOp::Store, }, })], depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, }, )); @@ -271,11 +273,13 @@ impl Backend { resolve_target: None, ops: wgpu::Operations { load: wgpu::LoadOp::Load, - store: true, + store: wgpu::StoreOp::Store, }, }, )], depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, }, )); } diff --git a/wgpu/src/color.rs b/wgpu/src/color.rs index 20827e3c..4598b0a6 100644 --- a/wgpu/src/color.rs +++ b/wgpu/src/color.rs @@ -143,10 +143,12 @@ pub fn convert( resolve_target: None, ops: wgpu::Operations { load: wgpu::LoadOp::Load, - store: true, + store: wgpu::StoreOp::Store, }, })], depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, }); pass.set_pipeline(&pipeline); diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs index 644c9f84..69270a73 100644 --- a/wgpu/src/triangle.rs +++ b/wgpu/src/triangle.rs @@ -300,10 +300,15 @@ impl Pipeline { wgpu::RenderPassColorAttachment { view: attachment, resolve_target, - ops: wgpu::Operations { load, store: true }, + ops: wgpu::Operations { + load, + store: wgpu::StoreOp::Store, + }, }, )], depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, }); let layer = &mut self.layers[layer]; diff --git a/wgpu/src/triangle/msaa.rs b/wgpu/src/triangle/msaa.rs index 320b5b12..14abd20b 100644 --- a/wgpu/src/triangle/msaa.rs +++ b/wgpu/src/triangle/msaa.rs @@ -167,10 +167,12 @@ impl Blit { resolve_target: None, ops: wgpu::Operations { load: wgpu::LoadOp::Load, - store: true, + store: wgpu::StoreOp::Store, }, })], depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, }); render_pass.set_pipeline(&self.pipeline); From a00ebcde3d698bc6b59a7a258e91c3612a6faaaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 27 Oct 2023 03:24:59 +0200 Subject: [PATCH 263/321] Remove unnecessary `into_iter` call in `iced_graphics` --- graphics/src/text.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/graphics/src/text.rs b/graphics/src/text.rs index bc06aa3c..a7d52645 100644 --- a/graphics/src/text.rs +++ b/graphics/src/text.rs @@ -22,12 +22,11 @@ pub struct FontSystem { impl FontSystem { pub fn new() -> Self { FontSystem { - raw: RwLock::new(cosmic_text::FontSystem::new_with_fonts( - [cosmic_text::fontdb::Source::Binary(Arc::new( + raw: RwLock::new(cosmic_text::FontSystem::new_with_fonts([ + cosmic_text::fontdb::Source::Binary(Arc::new( include_bytes!("../fonts/Iced-Icons.ttf").as_slice(), - ))] - .into_iter(), - )), + )), + ])), version: Version::default(), } } From 625cd745f38215b1cb8f629cdc6d2fa41c9a739a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 27 Oct 2023 05:04:14 +0200 Subject: [PATCH 264/321] Write documentation for the new text APIs --- core/src/lib.rs | 2 +- core/src/mouse/click.rs | 1 + core/src/text.rs | 2 ++ core/src/text/editor.rs | 51 +++++++++++++++++++++++++++++++++- core/src/text/highlighter.rs | 30 ++++++++++++++++---- examples/editor/src/main.rs | 10 +++---- graphics/src/lib.rs | 2 +- graphics/src/text.rs | 13 +++++++++ graphics/src/text/cache.rs | 19 +++++++++++++ graphics/src/text/editor.rs | 12 ++++++++ graphics/src/text/paragraph.rs | 14 ++++++++++ style/src/lib.rs | 2 +- wgpu/src/layer/text.rs | 7 ++++- wgpu/src/lib.rs | 2 +- widget/src/lib.rs | 4 +-- widget/src/text_editor.rs | 36 +++++++++++++++++++++--- 16 files changed, 185 insertions(+), 22 deletions(-) diff --git a/core/src/lib.rs b/core/src/lib.rs index 9eb3da34..54ea5839 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -12,7 +12,7 @@ #![forbid(unsafe_code, rust_2018_idioms)] #![deny( missing_debug_implementations, - // missing_docs, + missing_docs, unused_results, rustdoc::broken_intra_doc_links )] diff --git a/core/src/mouse/click.rs b/core/src/mouse/click.rs index b427da6c..6f3844be 100644 --- a/core/src/mouse/click.rs +++ b/core/src/mouse/click.rs @@ -61,6 +61,7 @@ impl Click { self.kind } + /// Returns the position of the [`Click`]. pub fn position(&self) -> Point { self.position } diff --git a/core/src/text.rs b/core/src/text.rs index 9b9c753c..546d0b5c 100644 --- a/core/src/text.rs +++ b/core/src/text.rs @@ -204,6 +204,8 @@ pub trait Renderer: crate::Renderer { color: Color, ); + /// Draws the given [`Editor`] at the given position and with the given + /// [`Color`]. fn fill_editor( &mut self, editor: &Self::Editor, diff --git a/core/src/text/editor.rs b/core/src/text/editor.rs index e9d66ce9..ebb0eee2 100644 --- a/core/src/text/editor.rs +++ b/core/src/text/editor.rs @@ -1,25 +1,36 @@ +//! Edit text. use crate::text::highlighter::{self, Highlighter}; use crate::text::LineHeight; use crate::{Pixels, Point, Rectangle, Size}; use std::sync::Arc; +/// A component that can be used by widgets to edit multi-line text. pub trait Editor: Sized + Default { + /// The [`Font`] of the [`Editor`]. type Font: Copy + PartialEq + Default; /// Creates a new [`Editor`] laid out with the given text. fn with_text(text: &str) -> Self; + /// Returns the current [`Cursor`] of the [`Editor`]. fn cursor(&self) -> Cursor; + /// Returns the current cursor position of the [`Editor`]. + /// + /// Line and column, respectively. fn cursor_position(&self) -> (usize, usize); + /// Returns the current selected text of the [`Editor`]. fn selection(&self) -> Option; + /// Returns the text of the given line in the [`Editor`], if it exists. fn line(&self, index: usize) -> Option<&str>; + /// Returns the amount of lines in the [`Editor`]. fn line_count(&self) -> usize; + /// Performs an [`Action`] on the [`Editor`]. fn perform(&mut self, action: Action); /// Returns the current boundaries of the [`Editor`]. @@ -35,6 +46,7 @@ pub trait Editor: Sized + Default { new_highlighter: &mut impl Highlighter, ); + /// Runs a text [`Highlighter`] in the [`Editor`]. fn highlight( &mut self, font: Self::Font, @@ -43,50 +55,83 @@ pub trait Editor: Sized + Default { ); } +/// An interaction with an [`Editor`]. #[derive(Debug, Clone, PartialEq)] pub enum Action { + /// Apply a [`Motion`]. Move(Motion), + /// Select text with a given [`Motion`]. Select(Motion), + /// Select the word at the current cursor. SelectWord, + /// Select the line at the current cursor. SelectLine, + /// Perform an [`Edit`]. Edit(Edit), + /// Click the [`Editor`] at the given [`Point`]. Click(Point), + /// Drag the mouse on the [`Editor`] to the given [`Point`]. Drag(Point), - Scroll { lines: i32 }, + /// Scroll the [`Editor`] a certain amount of lines. + Scroll { + /// The amount of lines to scroll. + lines: i32, + }, } impl Action { + /// Returns whether the [`Action`] is an editing action. pub fn is_edit(&self) -> bool { matches!(self, Self::Edit(_)) } } +/// An action that edits text. #[derive(Debug, Clone, PartialEq)] pub enum Edit { + /// Insert the given character. Insert(char), + /// Paste the given text. Paste(Arc), + /// Break the current line. Enter, + /// Delete the previous character. Backspace, + /// Delete the next character. Delete, } +/// A cursor movement. #[derive(Debug, Clone, Copy, PartialEq)] pub enum Motion { + /// Move left. Left, + /// Move right. Right, + /// Move up. Up, + /// Move down. Down, + /// Move to the left boundary of a word. WordLeft, + /// Move to the right boundary of a word. WordRight, + /// Move to the start of the line. Home, + /// Move to the end of the line. End, + /// Move to the start of the previous window. PageUp, + /// Move to the start of the next window. PageDown, + /// Move to the start of the text. DocumentStart, + /// Move to the end of the text. DocumentEnd, } impl Motion { + /// Widens the [`Motion`], if possible. pub fn widen(self) -> Self { match self { Self::Left => Self::WordLeft, @@ -97,6 +142,7 @@ impl Motion { } } + /// Returns the [`Direction`] of the [`Motion`]. pub fn direction(&self) -> Direction { match self { Self::Left @@ -115,9 +161,12 @@ impl Motion { } } +/// A direction in some text. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Direction { + /// <- Left, + /// -> Right, } diff --git a/core/src/text/highlighter.rs b/core/src/text/highlighter.rs index 9a9cff89..a0535228 100644 --- a/core/src/text/highlighter.rs +++ b/core/src/text/highlighter.rs @@ -1,31 +1,48 @@ +//! Highlight text. use crate::Color; use std::ops::Range; +/// A type capable of highlighting text. +/// +/// A [`Highlighter`] highlights lines in sequence. When a line changes, +/// it must be notified and the lines after the changed one must be fed +/// again to the [`Highlighter`]. pub trait Highlighter: 'static { + /// The settings to configure the [`Highlighter`]. type Settings: PartialEq + Clone; + + /// The output of the [`Highlighter`]. type Highlight; + /// The highlight iterator type. type Iterator<'a>: Iterator, Self::Highlight)> where Self: 'a; + /// Creates a new [`Highlighter`] from its [`Self::Settings`]. fn new(settings: &Self::Settings) -> Self; + /// Updates the [`Highlighter`] with some new [`Self::Settings`]. fn update(&mut self, new_settings: &Self::Settings); + /// Notifies the [`Highlighter`] that the line at the given index has changed. fn change_line(&mut self, line: usize); + /// Highlights the given line. + /// + /// If a line changed prior to this, the first line provided here will be the + /// line that changed. fn highlight_line(&mut self, line: &str) -> Self::Iterator<'_>; + /// Returns the current line of the [`Highlighter`]. + /// + /// If `change_line` has been called, this will normally be the least index + /// that changed. fn current_line(&self) -> usize; } -#[derive(Debug, Clone, Copy)] -pub struct Style { - pub color: Color, -} - +/// A highlighter that highlights nothing. #[derive(Debug, Clone, Copy)] pub struct PlainText; @@ -52,9 +69,12 @@ impl Highlighter for PlainText { } } +/// The format of some text. #[derive(Debug, Clone, Copy, PartialEq)] pub struct Format { + /// The [`Color`] of the text. pub color: Option, + /// The `Font` of the text. pub font: Option, } diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs index a69e1f54..03d1e283 100644 --- a/examples/editor/src/main.rs +++ b/examples/editor/src/main.rs @@ -34,7 +34,7 @@ struct Editor { #[derive(Debug, Clone)] enum Message { - Edit(text_editor::Action), + ActionPerformed(text_editor::Action), ThemeSelected(highlighter::Theme), NewFile, OpenFile, @@ -68,10 +68,10 @@ impl Application for Editor { fn update(&mut self, message: Message) -> Command { match message { - Message::Edit(action) => { + Message::ActionPerformed(action) => { self.is_dirty = self.is_dirty || action.is_edit(); - self.content.edit(action); + self.content.perform(action); Command::none() } @@ -103,7 +103,7 @@ impl Application for Editor { if let Ok((path, contents)) = result { self.file = Some(path); - self.content = text_editor::Content::with(&contents); + self.content = text_editor::Content::with_text(&contents); } Command::none() @@ -191,7 +191,7 @@ impl Application for Editor { column![ controls, text_editor(&self.content) - .on_edit(Message::Edit) + .on_action(Message::ActionPerformed) .highlight::( highlighter::Settings { theme: self.theme, diff --git a/graphics/src/lib.rs b/graphics/src/lib.rs index a0729058..7a213909 100644 --- a/graphics/src/lib.rs +++ b/graphics/src/lib.rs @@ -10,7 +10,7 @@ #![forbid(rust_2018_idioms)] #![deny( missing_debug_implementations, - //missing_docs, + missing_docs, unsafe_code, unused_results, rustdoc::broken_intra_doc_links diff --git a/graphics/src/text.rs b/graphics/src/text.rs index c10eacad..7261900e 100644 --- a/graphics/src/text.rs +++ b/graphics/src/text.rs @@ -1,3 +1,4 @@ +//! Draw text. pub mod cache; pub mod editor; pub mod paragraph; @@ -17,6 +18,7 @@ use once_cell::sync::OnceCell; use std::borrow::Cow; use std::sync::{Arc, RwLock}; +/// Returns the global [`FontSystem`]. pub fn font_system() -> &'static RwLock { static FONT_SYSTEM: OnceCell> = OnceCell::new(); @@ -32,6 +34,7 @@ pub fn font_system() -> &'static RwLock { }) } +/// A set of system fonts. #[allow(missing_debug_implementations)] pub struct FontSystem { raw: cosmic_text::FontSystem, @@ -39,10 +42,12 @@ pub struct FontSystem { } impl FontSystem { + /// Returns the raw [`cosmic_text::FontSystem`]. pub fn raw(&mut self) -> &mut cosmic_text::FontSystem { &mut self.raw } + /// Loads a font from its bytes. pub fn load_font(&mut self, bytes: Cow<'static, [u8]>) { let _ = self.raw.db_mut().load_font_source( cosmic_text::fontdb::Source::Binary(Arc::new(bytes.into_owned())), @@ -51,14 +56,19 @@ impl FontSystem { self.version = Version(self.version.0 + 1); } + /// Returns the current [`Version`] of the [`FontSystem`]. + /// + /// Loading a font will increase the version of a [`FontSystem`]. pub fn version(&self) -> Version { self.version } } +/// A version number. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] pub struct Version(u32); +/// Measures the dimensions of the given [`cosmic_text::Buffer`]. pub fn measure(buffer: &cosmic_text::Buffer) -> Size { let (width, total_lines) = buffer .layout_runs() @@ -69,6 +79,7 @@ pub fn measure(buffer: &cosmic_text::Buffer) -> Size { Size::new(width, total_lines as f32 * buffer.metrics().line_height) } +/// Returns the attributes of the given [`Font`]. pub fn to_attributes(font: Font) -> cosmic_text::Attrs<'static> { cosmic_text::Attrs::new() .family(to_family(font.family)) @@ -124,6 +135,7 @@ fn to_style(style: font::Style) -> cosmic_text::Style { } } +/// Converts some [`Shaping`] strategy to a [`cosmic_text::Shaping`] strategy. pub fn to_shaping(shaping: Shaping) -> cosmic_text::Shaping { match shaping { Shaping::Basic => cosmic_text::Shaping::Basic, @@ -131,6 +143,7 @@ pub fn to_shaping(shaping: Shaping) -> cosmic_text::Shaping { } } +/// Converts some [`Color`] to a [`cosmic_text::Color`]. pub fn to_color(color: Color) -> cosmic_text::Color { let [r, g, b, a] = color::pack(color).components(); diff --git a/graphics/src/text/cache.rs b/graphics/src/text/cache.rs index 577c4687..b3293dd4 100644 --- a/graphics/src/text/cache.rs +++ b/graphics/src/text/cache.rs @@ -1,3 +1,4 @@ +//! Cache text. use crate::core::{Font, Size}; use crate::text; @@ -5,6 +6,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; use std::collections::hash_map; use std::hash::{BuildHasher, Hash, Hasher}; +/// A store of recently used sections of text. #[allow(missing_debug_implementations)] #[derive(Default)] pub struct Cache { @@ -21,14 +23,17 @@ type HashBuilder = twox_hash::RandomXxHashBuilder64; type HashBuilder = std::hash::BuildHasherDefault; impl Cache { + /// Creates a new empty [`Cache`]. pub fn new() -> Self { Self::default() } + /// Gets the text [`Entry`] with the given [`KeyHash`]. pub fn get(&self, key: &KeyHash) -> Option<&Entry> { self.entries.get(key) } + /// Allocates a text [`Entry`] if it is not already present in the [`Cache`]. pub fn allocate( &mut self, font_system: &mut cosmic_text::FontSystem, @@ -88,6 +93,9 @@ impl Cache { (hash, self.entries.get_mut(&hash).unwrap()) } + /// Trims the [`Cache`]. + /// + /// This will clear the sections of text that have not been used since the last `trim`. pub fn trim(&mut self) { self.entries .retain(|key, _| self.recently_used.contains(key)); @@ -99,13 +107,20 @@ impl Cache { } } +/// A cache key representing a section of text. #[derive(Debug, Clone, Copy)] pub struct Key<'a> { + /// The content of the text. pub content: &'a str, + /// The size of the text. pub size: f32, + /// The line height of the text. pub line_height: f32, + /// The [`Font`] of the text. pub font: Font, + /// The bounds of the text. pub bounds: Size, + /// The shaping strategy of the text. pub shaping: text::Shaping, } @@ -123,10 +138,14 @@ impl Key<'_> { } } +/// The hash of a [`Key`]. pub type KeyHash = u64; +/// A cache entry. #[allow(missing_debug_implementations)] pub struct Entry { + /// The buffer of text, ready for drawing. pub buffer: cosmic_text::Buffer, + /// The minimum bounds of the text. pub min_bounds: Size, } diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index a05312dc..d5262ae8 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -1,3 +1,4 @@ +//! Draw and edit text. use crate::core::text::editor::{ self, Action, Cursor, Direction, Edit, Motion, }; @@ -11,6 +12,7 @@ use cosmic_text::Edit as _; use std::fmt; use std::sync::{self, Arc}; +/// A multi-line text editor. #[derive(Debug, PartialEq)] pub struct Editor(Option>); @@ -23,14 +25,21 @@ struct Internal { } impl Editor { + /// Creates a new empty [`Editor`]. pub fn new() -> Self { Self::default() } + /// Returns the buffer of the [`Editor`]. pub fn buffer(&self) -> &cosmic_text::Buffer { self.internal().editor.buffer() } + /// Creates a [`Weak`] reference to the [`Editor`]. + /// + /// This is useful to avoid cloning the [`Editor`] when + /// referential guarantees are unnecessary. For instance, + /// when creating a rendering tree. pub fn downgrade(&self) -> Weak { let editor = self.internal(); @@ -662,13 +671,16 @@ impl fmt::Debug for Internal { } } +/// A weak reference to an [`Editor`]. #[derive(Debug, Clone)] pub struct Weak { raw: sync::Weak, + /// The bounds of the [`Editor`]. pub bounds: Size, } impl Weak { + /// Tries to update the reference into an [`Editor`]. pub fn upgrade(&self) -> Option { self.raw.upgrade().map(Some).map(Editor) } diff --git a/graphics/src/text/paragraph.rs b/graphics/src/text/paragraph.rs index d0396e8e..ccfe4a61 100644 --- a/graphics/src/text/paragraph.rs +++ b/graphics/src/text/paragraph.rs @@ -1,3 +1,4 @@ +//! Draw paragraphs. use crate::core; use crate::core::alignment; use crate::core::text::{Hit, LineHeight, Shaping, Text}; @@ -7,6 +8,7 @@ use crate::text; use std::fmt; use std::sync::{self, Arc}; +/// A bunch of text. #[derive(Clone, PartialEq)] pub struct Paragraph(Option>); @@ -23,14 +25,21 @@ struct Internal { } impl Paragraph { + /// Creates a new empty [`Paragraph`]. pub fn new() -> Self { Self::default() } + /// Returns the buffer of the [`Paragraph`]. pub fn buffer(&self) -> &cosmic_text::Buffer { &self.internal().buffer } + /// Creates a [`Weak`] reference to the [`Paragraph`]. + /// + /// This is useful to avoid cloning the [`Editor`] when + /// referential guarantees are unnecessary. For instance, + /// when creating a rendering tree. pub fn downgrade(&self) -> Weak { let paragraph = self.internal(); @@ -269,15 +278,20 @@ impl Default for Internal { } } +/// A weak reference to a [`Paragraph`]. #[derive(Debug, Clone)] pub struct Weak { raw: sync::Weak, + /// The minimum bounds of the [`Paragraph`]. pub min_bounds: Size, + /// The horizontal alignment of the [`Paragraph`]. pub horizontal_alignment: alignment::Horizontal, + /// The vertical alignment of the [`Paragraph`]. pub vertical_alignment: alignment::Vertical, } impl Weak { + /// Tries to update the reference into a [`Paragraph`]. pub fn upgrade(&self) -> Option { self.raw.upgrade().map(Some).map(Paragraph) } diff --git a/style/src/lib.rs b/style/src/lib.rs index 35460f4b..e4097434 100644 --- a/style/src/lib.rs +++ b/style/src/lib.rs @@ -10,7 +10,7 @@ #![forbid(unsafe_code, rust_2018_idioms)] #![deny( unused_results, - // missing_docs, + missing_docs, unused_results, rustdoc::broken_intra_doc_links )] diff --git a/wgpu/src/layer/text.rs b/wgpu/src/layer/text.rs index d46b39da..66417cec 100644 --- a/wgpu/src/layer/text.rs +++ b/wgpu/src/layer/text.rs @@ -4,19 +4,24 @@ use crate::core::{Color, Font, Pixels, Point, Rectangle}; use crate::graphics::text::editor; use crate::graphics::text::paragraph; -/// A paragraph of text. +/// A text primitive. #[derive(Debug, Clone)] pub enum Text<'a> { + /// A paragraph. + #[allow(missing_docs)] Paragraph { paragraph: paragraph::Weak, position: Point, color: Color, }, + /// An editor. + #[allow(missing_docs)] Editor { editor: editor::Weak, position: Point, color: Color, }, + /// A cached text. Cached(Cached<'a>), } diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 6d26723e..424dfeb3 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -23,7 +23,7 @@ #![forbid(rust_2018_idioms)] #![deny( missing_debug_implementations, - //missing_docs, + missing_docs, unsafe_code, unused_results, rustdoc::broken_intra_doc_links diff --git a/widget/src/lib.rs b/widget/src/lib.rs index 97e4ac58..e3335a98 100644 --- a/widget/src/lib.rs +++ b/widget/src/lib.rs @@ -4,8 +4,8 @@ )] #![forbid(unsafe_code, rust_2018_idioms)] #![deny( - // missing_debug_implementations, - // missing_docs, + //missing_debug_implementations, + missing_docs, unused_results, rustdoc::broken_intra_doc_links )] diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index 6d25967e..da1905dc 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -1,3 +1,4 @@ +//! Display a multi-line text input for text editing. use crate::core::event::{self, Event}; use crate::core::keyboard; use crate::core::layout::{self, Layout}; @@ -19,6 +20,7 @@ use std::sync::Arc; pub use crate::style::text_editor::{Appearance, StyleSheet}; pub use text::editor::{Action, Edit, Motion}; +/// A multi-line text input. pub struct TextEditor<'a, Highlighter, Message, Renderer = crate::Renderer> where Highlighter: text::Highlighter, @@ -47,6 +49,7 @@ where Renderer: text::Renderer, Renderer::Theme: StyleSheet, { + /// Creates new [`TextEditor`] with the given [`Content`]. pub fn new(content: &'a Content) -> Self { Self { content, @@ -73,21 +76,34 @@ where Renderer: text::Renderer, Renderer::Theme: StyleSheet, { - pub fn on_edit(mut self, on_edit: impl Fn(Action) -> Message + 'a) -> Self { + /// Sets the message that should be produced when some action is performed in + /// the [`TextEditor`]. + /// + /// If this method is not called, the [`TextEditor`] will be disabled. + pub fn on_action( + mut self, + on_edit: impl Fn(Action) -> Message + 'a, + ) -> Self { self.on_edit = Some(Box::new(on_edit)); self } + /// Sets the [`Font`] of the [`TextEditor`]. + /// + /// [`Font`]: text::Renderer::Font pub fn font(mut self, font: impl Into) -> Self { self.font = Some(font.into()); self } + /// Sets the [`Padding`] of the [`TextEditor`]. pub fn padding(mut self, padding: impl Into) -> Self { self.padding = padding.into(); self } + /// Highlights the [`TextEditor`] with the given [`Highlighter`] and + /// a strategy to turn its highlights into some text format. pub fn highlight( self, settings: H::Settings, @@ -112,6 +128,7 @@ where } } +/// The content of a [`TextEditor`]. pub struct Content(RefCell>) where R: text::Renderer; @@ -128,28 +145,33 @@ impl Content where R: text::Renderer, { + /// Creates an empty [`Content`]. pub fn new() -> Self { - Self::with("") + Self::with_text("") } - pub fn with(text: &str) -> Self { + /// Creates a [`Content`] with the given text. + pub fn with_text(text: &str) -> Self { Self(RefCell::new(Internal { editor: R::Editor::with_text(text), is_dirty: true, })) } - pub fn edit(&mut self, action: Action) { + /// Performs an [`Action`] on the [`Content`]. + pub fn perform(&mut self, action: Action) { let internal = self.0.get_mut(); internal.editor.perform(action); internal.is_dirty = true; } + /// Returns the amount of lines of the [`Content`]. pub fn line_count(&self) -> usize { self.0.borrow().editor.line_count() } + /// Returns the text of the line at the given index, if it exists. pub fn line( &self, index: usize, @@ -160,6 +182,7 @@ where .ok() } + /// Returns an iterator of the text of the lines in the [`Content`]. pub fn lines( &self, ) -> impl Iterator + '_> { @@ -190,6 +213,9 @@ where } } + /// Returns the text of the [`Content`]. + /// + /// Lines are joined with `'\n'`. pub fn text(&self) -> String { let mut text = self.lines().enumerate().fold( String::new(), @@ -211,10 +237,12 @@ where text } + /// Returns the selected text of the [`Content`]. pub fn selection(&self) -> Option { self.0.borrow().editor.selection() } + /// Returns the current cursor position of the [`Content`]. pub fn cursor_position(&self) -> (usize, usize) { self.0.borrow().editor.cursor_position() } From e579d8553088c7d17784e7ff8f6e21360c2bd9ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 27 Oct 2023 05:08:06 +0200 Subject: [PATCH 265/321] Implement missing debug implementations in `iced_widget` --- widget/src/lib.rs | 2 +- widget/src/text_editor.rs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/widget/src/lib.rs b/widget/src/lib.rs index e3335a98..2f959370 100644 --- a/widget/src/lib.rs +++ b/widget/src/lib.rs @@ -4,7 +4,7 @@ )] #![forbid(unsafe_code, rust_2018_idioms)] #![deny( - //missing_debug_implementations, + missing_debug_implementations, missing_docs, unused_results, rustdoc::broken_intra_doc_links diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index da1905dc..ac24920f 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -14,6 +14,7 @@ use crate::core::{ }; use std::cell::RefCell; +use std::fmt; use std::ops::DerefMut; use std::sync::Arc; @@ -21,6 +22,7 @@ pub use crate::style::text_editor::{Appearance, StyleSheet}; pub use text::editor::{Action, Edit, Motion}; /// A multi-line text input. +#[allow(missing_debug_implementations)] pub struct TextEditor<'a, Highlighter, Message, Renderer = crate::Renderer> where Highlighter: text::Highlighter, @@ -257,6 +259,21 @@ where } } +impl fmt::Debug for Content +where + Renderer: text::Renderer, + Renderer::Editor: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let internal = self.0.borrow(); + + f.debug_struct("Content") + .field("editor", &internal.editor) + .field("is_dirty", &internal.is_dirty) + .finish() + } +} + struct State { is_focused: bool, last_click: Option, From 57f9024e89256ad3f99a3ab19bdc8524c1defa54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 27 Oct 2023 05:19:35 +0200 Subject: [PATCH 266/321] Fix intra-doc broken links --- .cargo/config.toml | 2 -- core/src/text/editor.rs | 2 +- graphics/src/text/paragraph.rs | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 3e02dda8..85a46cda 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -17,8 +17,6 @@ clippy --workspace --no-deps -- \ -D clippy::useless_conversion """ -#![allow(clippy::inherent_to_string, clippy::type_complexity)] - nitpick = """ clippy --workspace --no-deps -- \ -D warnings \ diff --git a/core/src/text/editor.rs b/core/src/text/editor.rs index ebb0eee2..f3c6e342 100644 --- a/core/src/text/editor.rs +++ b/core/src/text/editor.rs @@ -7,7 +7,7 @@ use std::sync::Arc; /// A component that can be used by widgets to edit multi-line text. pub trait Editor: Sized + Default { - /// The [`Font`] of the [`Editor`]. + /// The font of the [`Editor`]. type Font: Copy + PartialEq + Default; /// Creates a new [`Editor`] laid out with the given text. diff --git a/graphics/src/text/paragraph.rs b/graphics/src/text/paragraph.rs index ccfe4a61..4a08a8f4 100644 --- a/graphics/src/text/paragraph.rs +++ b/graphics/src/text/paragraph.rs @@ -37,7 +37,7 @@ impl Paragraph { /// Creates a [`Weak`] reference to the [`Paragraph`]. /// - /// This is useful to avoid cloning the [`Editor`] when + /// This is useful to avoid cloning the [`Paragraph`] when /// referential guarantees are unnecessary. For instance, /// when creating a rendering tree. pub fn downgrade(&self) -> Weak { From 3ec5ad42251d4f35861f3bed621223e383742b12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 27 Oct 2023 06:00:28 +0200 Subject: [PATCH 267/321] Use upstream repository for `glyphon` dependency --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index bb8b4752..03df14c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -117,7 +117,7 @@ bytemuck = { version = "1.0", features = ["derive"] } cosmic-text = "0.10" futures = "0.3" glam = "0.24" -glyphon = { git = "https://github.com/hecrj/glyphon.git", rev = "2caa9fc5e5923c1d827d177c3619cab7e9885b85" } +glyphon = { git = "https://github.com/grovesNL/glyphon.git", rev = "2caa9fc5e5923c1d827d177c3619cab7e9885b85" } guillotiere = "0.6" half = "2.2" image = "0.24" From c07315b84eb59daeb9bbe7480f30dc0937ceca13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 27 Oct 2023 05:53:29 +0200 Subject: [PATCH 268/321] Disable maximize window button if `Settings::resizable` is `false` --- winit/src/settings.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/winit/src/settings.rs b/winit/src/settings.rs index 867dad0f..16c9fcdc 100644 --- a/winit/src/settings.rs +++ b/winit/src/settings.rs @@ -130,6 +130,12 @@ impl Window { .with_title(title) .with_inner_size(winit::dpi::LogicalSize { width, height }) .with_resizable(self.resizable) + .with_enabled_buttons(if self.resizable { + winit::window::WindowButtons::all() + } else { + winit::window::WindowButtons::CLOSE + | winit::window::WindowButtons::MINIMIZE + }) .with_decorations(self.decorations) .with_transparent(self.transparent) .with_window_icon(self.icon.and_then(conversion::icon)) From c8eca4e6bfae82013e6bb08e9d8bf66560b36564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 27 Oct 2023 16:37:58 +0200 Subject: [PATCH 269/321] Improve `TextEditor` scroll interaction with a touchpad --- widget/src/text_editor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index ac24920f..1708a2e5 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -628,7 +628,7 @@ impl Update { } } mouse::ScrollDelta::Pixels { y, .. } => { - -y.signum() as i32 + (-y / 4.0) as i32 } }, }) From 98e088e731e6fbd5b5035033ae61bda823ced988 Mon Sep 17 00:00:00 2001 From: dtzxporter Date: Tue, 12 Sep 2023 18:15:00 -0400 Subject: [PATCH 270/321] Migrate twox-hash -> xxhash_rust. Switch to Xxh3 for better performance. xxhash-rust is more maintained, built against `::core`, so no workaround for wasm is necessary. Switch to Xxh3 for better performance, which shows when loading/hashing image buffers. --- Cargo.toml | 2 +- core/Cargo.toml | 2 +- core/src/hasher.rs | 5 +++-- graphics/Cargo.toml | 6 +----- graphics/src/text/cache.rs | 6 +----- tiny_skia/Cargo.toml | 6 +----- 6 files changed, 8 insertions(+), 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1a286b9b..f625f1ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -150,7 +150,7 @@ thiserror = "1.0" tiny-skia = "0.10" tokio = "1.0" tracing = "0.1" -twox-hash = { version = "1.0", default-features = false } +xxhash-rust = { version = "0.8.7", default-features = false, features = ["xxh3"] } unicode-segmentation = "1.0" wasm-bindgen-futures = "0.4" wasm-timer = "0.2" diff --git a/core/Cargo.toml b/core/Cargo.toml index 7acb7511..82946847 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -14,7 +14,7 @@ keywords.workspace = true bitflags.workspace = true log.workspace = true thiserror.workspace = true -twox-hash.workspace = true +xxhash-rust.workspace = true num-traits.workspace = true palette.workspace = true diff --git a/core/src/hasher.rs b/core/src/hasher.rs index 9d8f75b3..a13d78af 100644 --- a/core/src/hasher.rs +++ b/core/src/hasher.rs @@ -1,6 +1,7 @@ /// The hasher used to compare layouts. -#[derive(Debug, Default)] -pub struct Hasher(twox_hash::XxHash64); +#[allow(missing_debug_implementations)] // Doesn't really make sense to have debug on the hasher state anyways. +#[derive(Default)] +pub struct Hasher(xxhash_rust::xxh3::Xxh3); impl core::hash::Hasher for Hasher { fn write(&mut self, bytes: &[u8]) { diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml index 3165810b..a7aea352 100644 --- a/graphics/Cargo.toml +++ b/graphics/Cargo.toml @@ -33,8 +33,8 @@ once_cell.workspace = true raw-window-handle.workspace = true rustc-hash.workspace = true thiserror.workspace = true -twox-hash.workspace = true unicode-segmentation.workspace = true +xxhash-rust.workspace = true image.workspace = true image.optional = true @@ -44,7 +44,3 @@ kamadak-exif.optional = true lyon_path.workspace = true lyon_path.optional = true - -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -twox-hash.workspace = true -twox-hash.features = ["std"] diff --git a/graphics/src/text/cache.rs b/graphics/src/text/cache.rs index b3293dd4..7fb33567 100644 --- a/graphics/src/text/cache.rs +++ b/graphics/src/text/cache.rs @@ -16,11 +16,7 @@ pub struct Cache { hasher: HashBuilder, } -#[cfg(not(target_arch = "wasm32"))] -type HashBuilder = twox_hash::RandomXxHashBuilder64; - -#[cfg(target_arch = "wasm32")] -type HashBuilder = std::hash::BuildHasherDefault; +type HashBuilder = xxhash_rust::xxh3::Xxh3Builder; impl Cache { /// Creates a new empty [`Cache`]. diff --git a/tiny_skia/Cargo.toml b/tiny_skia/Cargo.toml index 15a6928a..df4c6143 100644 --- a/tiny_skia/Cargo.toml +++ b/tiny_skia/Cargo.toml @@ -26,11 +26,7 @@ raw-window-handle.workspace = true rustc-hash.workspace = true softbuffer.workspace = true tiny-skia.workspace = true -twox-hash.workspace = true +xxhash-rust.workspace = true resvg.workspace = true resvg.optional = true - -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -twox-hash.workspace = true -twox-hash.features = ["std"] From 4b69c71d5b570ce716b9c202e9a47d5ae9ce3ae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 11 Nov 2023 03:43:03 +0100 Subject: [PATCH 271/321] Remove patch version from `xxhash-rust` dependency --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f625f1ad..4bcf7c7a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -150,7 +150,7 @@ thiserror = "1.0" tiny-skia = "0.10" tokio = "1.0" tracing = "0.1" -xxhash-rust = { version = "0.8.7", default-features = false, features = ["xxh3"] } +xxhash-rust = { version = "0.8", default-features = false, features = ["xxh3"] } unicode-segmentation = "1.0" wasm-bindgen-futures = "0.4" wasm-timer = "0.2" From 107e842071f1300df5e0bfcb26ee0a99024e51d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 11 Nov 2023 03:43:50 +0100 Subject: [PATCH 272/321] Remove unnecessary `default-features` attribute from `xxhash-rust` dependency --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 4bcf7c7a..ac34a4ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -150,7 +150,7 @@ thiserror = "1.0" tiny-skia = "0.10" tokio = "1.0" tracing = "0.1" -xxhash-rust = { version = "0.8", default-features = false, features = ["xxh3"] } +xxhash-rust = { version = "0.8", features = ["xxh3"] } unicode-segmentation = "1.0" wasm-bindgen-futures = "0.4" wasm-timer = "0.2" From 2aaaf2cd0cb56f9efc946159a0232270f8d37eeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 11 Nov 2023 04:03:25 +0100 Subject: [PATCH 273/321] Call `convert_text` on `svg` node before rendering `tiny-skia` does not support text rendering, so we convert the text nodes to path nodes prior to that. --- Cargo.toml | 4 ++-- tiny_skia/src/vector.rs | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1a286b9b..18dd8d3e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -140,14 +140,14 @@ ouroboros = "0.17" palette = "0.7" qrcode = { version = "0.12", default-features = false } raw-window-handle = "0.5" -resvg = "0.35" +resvg = "0.36" rustc-hash = "1.0" smol = "1.0" softbuffer = "0.2" syntect = "5.1" sysinfo = "0.28" thiserror = "1.0" -tiny-skia = "0.10" +tiny-skia = "0.11" tokio = "1.0" tracing = "0.1" twox-hash = { version = "1.0", default-features = false } diff --git a/tiny_skia/src/vector.rs b/tiny_skia/src/vector.rs index a1cd269d..9c2893a2 100644 --- a/tiny_skia/src/vector.rs +++ b/tiny_skia/src/vector.rs @@ -1,7 +1,8 @@ use crate::core::svg::{Data, Handle}; use crate::core::{Color, Rectangle, Size}; +use crate::graphics::text; -use resvg::usvg; +use resvg::usvg::{self, TreeTextToPath}; use rustc_hash::{FxHashMap, FxHashSet}; use std::cell::RefCell; @@ -77,7 +78,7 @@ impl Cache { let id = handle.id(); if let hash_map::Entry::Vacant(entry) = self.trees.entry(id) { - let svg = match handle.data() { + let mut svg = match handle.data() { Data::Path(path) => { fs::read_to_string(path).ok().and_then(|contents| { usvg::Tree::from_str( @@ -92,6 +93,15 @@ impl Cache { } }; + if let Some(svg) = &mut svg { + if svg.has_text_nodes() { + let mut font_system = + text::font_system().write().expect("Read font system"); + + svg.convert_text(font_system.raw().db_mut()); + } + } + let _ = entry.insert(svg); } From bb2f557d6a75850aed8e8689348f7a544b364bf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 11 Nov 2023 04:36:45 +0100 Subject: [PATCH 274/321] Fix `artifacts` job in `audit` workflow --- .github/workflows/audit.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index bfb617fb..5f5f7f65 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -24,5 +24,7 @@ jobs: - name: Install cargo-outdated run: cargo install cargo-outdated - uses: actions/checkout@master + - name: Delete `web-sys` dependency from `integration` example + run: sed '$d' examples/integration/Cargo.toml - name: Find outdated dependencies run: cargo outdated --workspace --exit-code 1 From ef015a5e72802c059784e74d611f351df75403c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 11 Nov 2023 04:46:11 +0100 Subject: [PATCH 275/321] Run `sed` with `-i` option in `artifacts` job --- .github/workflows/audit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index 5f5f7f65..80bbcacd 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -25,6 +25,6 @@ jobs: run: cargo install cargo-outdated - uses: actions/checkout@master - name: Delete `web-sys` dependency from `integration` example - run: sed '$d' examples/integration/Cargo.toml + run: sed -i '$d' examples/integration/Cargo.toml - name: Find outdated dependencies run: cargo outdated --workspace --exit-code 1 From 5759096a4c33935fcdf5f96606143e4f21159186 Mon Sep 17 00:00:00 2001 From: Remmirad Date: Wed, 31 May 2023 15:46:21 +0200 Subject: [PATCH 276/321] Implement texture filtering options --- core/src/image.rs | 32 +++++++++++++++++++ tiny_skia/src/raster.rs | 7 ++++- wgpu/src/image.rs | 69 +++++++++++++++++++++++++++-------------- widget/src/image.rs | 2 +- 4 files changed, 84 insertions(+), 26 deletions(-) diff --git a/core/src/image.rs b/core/src/image.rs index 85d9d475..9a6011a3 100644 --- a/core/src/image.rs +++ b/core/src/image.rs @@ -5,11 +5,31 @@ use std::hash::{Hash, Hasher as _}; use std::path::PathBuf; use std::sync::Arc; +/// Image filter method +#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum FilterMethod { + /// Bilinear interpolation + #[default] + Linear, + /// Nearest Neighbor + Nearest, +} + +/// Texture filter settings +#[derive(Default, Debug, Clone, PartialEq, Eq, Hash)] +pub struct TextureFilter { + /// Filter for scaling the image down. + pub min: FilterMethod, + /// Filter for scaling the image up. + pub mag: FilterMethod, +} + /// A handle of some image data. #[derive(Debug, Clone, PartialEq, Eq)] pub struct Handle { id: u64, data: Data, + filter: TextureFilter, } impl Handle { @@ -56,6 +76,7 @@ impl Handle { Handle { id: hasher.finish(), data, + filter: TextureFilter::default(), } } @@ -68,6 +89,17 @@ impl Handle { pub fn data(&self) -> &Data { &self.data } + + /// Returns a reference to the [`TextureFilter`]. + pub fn filter(&self) -> &TextureFilter { + &self.filter + } + + /// Sets the texture filtering methods. + pub fn set_filter(mut self, filter: TextureFilter) -> Self { + self.filter = filter; + self + } } impl From for Handle diff --git a/tiny_skia/src/raster.rs b/tiny_skia/src/raster.rs index d13b1167..95f74ad1 100644 --- a/tiny_skia/src/raster.rs +++ b/tiny_skia/src/raster.rs @@ -39,12 +39,17 @@ impl Pipeline { let transform = transform.pre_scale(width_scale, height_scale); + let quality = match handle.filter().mag { + raster::FilterMethod::Linear => tiny_skia::FilterQuality::Bilinear, + raster::FilterMethod::Nearest => tiny_skia::FilterQuality::Nearest, + }; + pixels.draw_pixmap( (bounds.x / width_scale) as i32, (bounds.y / height_scale) as i32, image, &tiny_skia::PixmapPaint { - quality: tiny_skia::FilterQuality::Bilinear, + quality: quality, ..Default::default() }, transform, diff --git a/wgpu/src/image.rs b/wgpu/src/image.rs index 553ba330..a0fe7e83 100644 --- a/wgpu/src/image.rs +++ b/wgpu/src/image.rs @@ -7,6 +7,7 @@ mod raster; mod vector; use atlas::Atlas; +use iced_graphics::core::image::{TextureFilter, FilterMethod}; use crate::core::{Rectangle, Size}; use crate::graphics::Transformation; @@ -14,6 +15,7 @@ use crate::layer; use crate::Buffer; use std::cell::RefCell; +use std::collections::HashMap; use std::mem; use bytemuck::{Pod, Zeroable}; @@ -37,7 +39,7 @@ pub struct Pipeline { pipeline: wgpu::RenderPipeline, vertices: wgpu::Buffer, indices: wgpu::Buffer, - sampler: wgpu::Sampler, + sampler: HashMap, texture: wgpu::BindGroup, texture_version: usize, texture_atlas: Atlas, @@ -142,15 +144,32 @@ impl Pipeline { pub fn new(device: &wgpu::Device, format: wgpu::TextureFormat) -> Self { use wgpu::util::DeviceExt; - let sampler = device.create_sampler(&wgpu::SamplerDescriptor { - address_mode_u: wgpu::AddressMode::ClampToEdge, - address_mode_v: wgpu::AddressMode::ClampToEdge, - address_mode_w: wgpu::AddressMode::ClampToEdge, - mag_filter: wgpu::FilterMode::Linear, - min_filter: wgpu::FilterMode::Linear, - mipmap_filter: wgpu::FilterMode::Linear, - ..Default::default() - }); + let to_wgpu = |method: FilterMethod| { + match method { + FilterMethod::Linear => wgpu::FilterMode::Linear, + FilterMethod::Nearest => wgpu::FilterMode::Nearest, + } + }; + + let mut sampler = HashMap::new(); + + let filter = [FilterMethod::Linear, FilterMethod::Nearest]; + for min in 0..filter.len() { + for mag in 0..filter.len() { + let _ = sampler.insert(TextureFilter {min: filter[min], mag: filter[mag]}, + device.create_sampler(&wgpu::SamplerDescriptor { + address_mode_u: wgpu::AddressMode::ClampToEdge, + address_mode_v: wgpu::AddressMode::ClampToEdge, + address_mode_w: wgpu::AddressMode::ClampToEdge, + mag_filter: to_wgpu(filter[mag]), + min_filter: to_wgpu(filter[min]), + mipmap_filter: wgpu::FilterMode::Linear, + ..Default::default() + } + )); + } + } + let constant_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { @@ -355,7 +374,7 @@ impl Pipeline { #[cfg(feature = "tracing")] let _ = info_span!("Wgpu::Image", "DRAW").entered(); - let instances: &mut Vec = &mut Vec::new(); + let instances: &mut HashMap> = &mut HashMap::new(); #[cfg(feature = "image")] let mut raster_cache = self.raster_cache.borrow_mut(); @@ -377,7 +396,7 @@ impl Pipeline { [bounds.x, bounds.y], [bounds.width, bounds.height], atlas_entry, - instances, + instances.entry(handle.filter().clone()).or_insert(Vec::new()), ); } } @@ -405,7 +424,7 @@ impl Pipeline { [bounds.x, bounds.y], size, atlas_entry, - instances, + instances.entry(TextureFilter::default()).or_insert(Vec::new()), ); } } @@ -438,18 +457,20 @@ impl Pipeline { self.texture_version = texture_version; } - if self.layers.len() <= self.prepare_layer { - self.layers.push(Layer::new( - device, - &self.constant_layout, - &self.sampler, - )); + for (filter, instances) in instances.iter_mut() { + if self.layers.len() <= self.prepare_layer { + self.layers.push(Layer::new( + device, + &self.constant_layout, + &self.sampler.get(filter).expect("Sampler is registered"), + )); + } + + let layer = &mut self.layers[self.prepare_layer]; + layer.prepare(device, queue, &instances, transformation); + + self.prepare_layer += 1; } - - let layer = &mut self.layers[self.prepare_layer]; - layer.prepare(device, queue, instances, transformation); - - self.prepare_layer += 1; } pub fn render<'a>( diff --git a/widget/src/image.rs b/widget/src/image.rs index a0e89920..9f0b16b7 100644 --- a/widget/src/image.rs +++ b/widget/src/image.rs @@ -13,7 +13,7 @@ use crate::core::{ use std::hash::Hash; -pub use image::Handle; +pub use image::{Handle, TextureFilter, FilterMethod}; /// Creates a new [`Viewer`] with the given image `Handle`. pub fn viewer(handle: Handle) -> Viewer { From 4b32a488808e371313ce78e727c9d98ab2eb759e Mon Sep 17 00:00:00 2001 From: Remmirad Date: Fri, 4 Aug 2023 13:50:16 +0200 Subject: [PATCH 277/321] Fix clippy + fmt --- core/src/image.rs | 2 +- tiny_skia/src/raster.rs | 10 +++++++--- wgpu/src/image.rs | 42 +++++++++++++++++++++++------------------ widget/src/image.rs | 2 +- 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/core/src/image.rs b/core/src/image.rs index 9a6011a3..69f19436 100644 --- a/core/src/image.rs +++ b/core/src/image.rs @@ -11,7 +11,7 @@ pub enum FilterMethod { /// Bilinear interpolation #[default] Linear, - /// Nearest Neighbor + /// Nearest Neighbor Nearest, } diff --git a/tiny_skia/src/raster.rs b/tiny_skia/src/raster.rs index 95f74ad1..3f35ee78 100644 --- a/tiny_skia/src/raster.rs +++ b/tiny_skia/src/raster.rs @@ -40,8 +40,12 @@ impl Pipeline { let transform = transform.pre_scale(width_scale, height_scale); let quality = match handle.filter().mag { - raster::FilterMethod::Linear => tiny_skia::FilterQuality::Bilinear, - raster::FilterMethod::Nearest => tiny_skia::FilterQuality::Nearest, + raster::FilterMethod::Linear => { + tiny_skia::FilterQuality::Bilinear + } + raster::FilterMethod::Nearest => { + tiny_skia::FilterQuality::Nearest + } }; pixels.draw_pixmap( @@ -49,7 +53,7 @@ impl Pipeline { (bounds.y / height_scale) as i32, image, &tiny_skia::PixmapPaint { - quality: quality, + quality, ..Default::default() }, transform, diff --git a/wgpu/src/image.rs b/wgpu/src/image.rs index a0fe7e83..a3168001 100644 --- a/wgpu/src/image.rs +++ b/wgpu/src/image.rs @@ -7,7 +7,7 @@ mod raster; mod vector; use atlas::Atlas; -use iced_graphics::core::image::{TextureFilter, FilterMethod}; +use iced_graphics::core::image::{FilterMethod, TextureFilter}; use crate::core::{Rectangle, Size}; use crate::graphics::Transformation; @@ -39,7 +39,7 @@ pub struct Pipeline { pipeline: wgpu::RenderPipeline, vertices: wgpu::Buffer, indices: wgpu::Buffer, - sampler: HashMap, + sampler: HashMap, texture: wgpu::BindGroup, texture_version: usize, texture_atlas: Atlas, @@ -144,11 +144,9 @@ impl Pipeline { pub fn new(device: &wgpu::Device, format: wgpu::TextureFormat) -> Self { use wgpu::util::DeviceExt; - let to_wgpu = |method: FilterMethod| { - match method { - FilterMethod::Linear => wgpu::FilterMode::Linear, - FilterMethod::Nearest => wgpu::FilterMode::Nearest, - } + let to_wgpu = |method: FilterMethod| match method { + FilterMethod::Linear => wgpu::FilterMode::Linear, + FilterMethod::Nearest => wgpu::FilterMode::Nearest, }; let mut sampler = HashMap::new(); @@ -156,7 +154,11 @@ impl Pipeline { let filter = [FilterMethod::Linear, FilterMethod::Nearest]; for min in 0..filter.len() { for mag in 0..filter.len() { - let _ = sampler.insert(TextureFilter {min: filter[min], mag: filter[mag]}, + let _ = sampler.insert( + TextureFilter { + min: filter[min], + mag: filter[mag], + }, device.create_sampler(&wgpu::SamplerDescriptor { address_mode_u: wgpu::AddressMode::ClampToEdge, address_mode_v: wgpu::AddressMode::ClampToEdge, @@ -165,12 +167,11 @@ impl Pipeline { min_filter: to_wgpu(filter[min]), mipmap_filter: wgpu::FilterMode::Linear, ..Default::default() - } - )); + }), + ); } } - let constant_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { label: Some("iced_wgpu::image constants layout"), @@ -374,7 +375,8 @@ impl Pipeline { #[cfg(feature = "tracing")] let _ = info_span!("Wgpu::Image", "DRAW").entered(); - let instances: &mut HashMap> = &mut HashMap::new(); + let instances: &mut HashMap> = + &mut HashMap::new(); #[cfg(feature = "image")] let mut raster_cache = self.raster_cache.borrow_mut(); @@ -396,7 +398,9 @@ impl Pipeline { [bounds.x, bounds.y], [bounds.width, bounds.height], atlas_entry, - instances.entry(handle.filter().clone()).or_insert(Vec::new()), + instances + .entry(handle.filter().clone()) + .or_insert(Vec::new()), ); } } @@ -424,7 +428,9 @@ impl Pipeline { [bounds.x, bounds.y], size, atlas_entry, - instances.entry(TextureFilter::default()).or_insert(Vec::new()), + instances + .entry(TextureFilter::default()) + .or_insert(Vec::new()), ); } } @@ -462,13 +468,13 @@ impl Pipeline { self.layers.push(Layer::new( device, &self.constant_layout, - &self.sampler.get(filter).expect("Sampler is registered"), + self.sampler.get(filter).expect("Sampler is registered"), )); } - + let layer = &mut self.layers[self.prepare_layer]; - layer.prepare(device, queue, &instances, transformation); - + layer.prepare(device, queue, instances, transformation); + self.prepare_layer += 1; } } diff --git a/widget/src/image.rs b/widget/src/image.rs index 9f0b16b7..684f200c 100644 --- a/widget/src/image.rs +++ b/widget/src/image.rs @@ -13,7 +13,7 @@ use crate::core::{ use std::hash::Hash; -pub use image::{Handle, TextureFilter, FilterMethod}; +pub use image::{FilterMethod, Handle, TextureFilter}; /// Creates a new [`Viewer`] with the given image `Handle`. pub fn viewer(handle: Handle) -> Viewer { From e5d3e75d826e9fad8a0da5dd538aa542059dd034 Mon Sep 17 00:00:00 2001 From: Remmirad Date: Mon, 25 Sep 2023 21:54:50 +0200 Subject: [PATCH 278/321] fix design for wgpu backend --- wgpu/src/image.rs | 127 +++++++++++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 53 deletions(-) diff --git a/wgpu/src/image.rs b/wgpu/src/image.rs index a3168001..0aa7f899 100644 --- a/wgpu/src/image.rs +++ b/wgpu/src/image.rs @@ -8,6 +8,7 @@ mod vector; use atlas::Atlas; use iced_graphics::core::image::{FilterMethod, TextureFilter}; +use wgpu::Sampler; use crate::core::{Rectangle, Size}; use crate::graphics::Transformation; @@ -15,7 +16,6 @@ use crate::layer; use crate::Buffer; use std::cell::RefCell; -use std::collections::HashMap; use std::mem; use bytemuck::{Pod, Zeroable}; @@ -29,6 +29,8 @@ use crate::core::svg; #[cfg(feature = "tracing")] use tracing::info_span; +const SAMPLER_COUNT: usize = 4; + #[derive(Debug)] pub struct Pipeline { #[cfg(feature = "image")] @@ -39,14 +41,14 @@ pub struct Pipeline { pipeline: wgpu::RenderPipeline, vertices: wgpu::Buffer, indices: wgpu::Buffer, - sampler: HashMap, + sampler: [wgpu::Sampler; SAMPLER_COUNT], texture: wgpu::BindGroup, texture_version: usize, texture_atlas: Atlas, texture_layout: wgpu::BindGroupLayout, constant_layout: wgpu::BindGroupLayout, - layers: Vec, + layers: Vec<[Option; SAMPLER_COUNT]>, prepare_layer: usize, } @@ -149,28 +151,32 @@ impl Pipeline { FilterMethod::Nearest => wgpu::FilterMode::Nearest, }; - let mut sampler = HashMap::new(); + let mut sampler: [Option; SAMPLER_COUNT] = + [None, None, None, None]; let filter = [FilterMethod::Linear, FilterMethod::Nearest]; for min in 0..filter.len() { for mag in 0..filter.len() { - let _ = sampler.insert( - TextureFilter { - min: filter[min], - mag: filter[mag], - }, - device.create_sampler(&wgpu::SamplerDescriptor { - address_mode_u: wgpu::AddressMode::ClampToEdge, - address_mode_v: wgpu::AddressMode::ClampToEdge, - address_mode_w: wgpu::AddressMode::ClampToEdge, - mag_filter: to_wgpu(filter[mag]), - min_filter: to_wgpu(filter[min]), - mipmap_filter: wgpu::FilterMode::Linear, - ..Default::default() - }), - ); + sampler[to_index(&TextureFilter { + min: filter[min], + mag: filter[mag], + })] = Some(device.create_sampler(&wgpu::SamplerDescriptor { + address_mode_u: wgpu::AddressMode::ClampToEdge, + address_mode_v: wgpu::AddressMode::ClampToEdge, + address_mode_w: wgpu::AddressMode::ClampToEdge, + mag_filter: to_wgpu(filter[mag]), + min_filter: to_wgpu(filter[min]), + mipmap_filter: wgpu::FilterMode::Linear, + ..Default::default() + })); } } + let sampler = [ + sampler[0].take().unwrap(), + sampler[1].take().unwrap(), + sampler[2].take().unwrap(), + sampler[3].take().unwrap(), + ]; let constant_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { @@ -375,8 +381,8 @@ impl Pipeline { #[cfg(feature = "tracing")] let _ = info_span!("Wgpu::Image", "DRAW").entered(); - let instances: &mut HashMap> = - &mut HashMap::new(); + let mut instances: [Vec; SAMPLER_COUNT] = + [Vec::new(), Vec::new(), Vec::new(), Vec::new()]; #[cfg(feature = "image")] let mut raster_cache = self.raster_cache.borrow_mut(); @@ -398,9 +404,7 @@ impl Pipeline { [bounds.x, bounds.y], [bounds.width, bounds.height], atlas_entry, - instances - .entry(handle.filter().clone()) - .or_insert(Vec::new()), + &mut instances[to_index(handle.filter())], ); } } @@ -428,9 +432,7 @@ impl Pipeline { [bounds.x, bounds.y], size, atlas_entry, - instances - .entry(TextureFilter::default()) - .or_insert(Vec::new()), + &mut instances[to_index(&TextureFilter::default())], ); } } @@ -463,20 +465,26 @@ impl Pipeline { self.texture_version = texture_version; } - for (filter, instances) in instances.iter_mut() { - if self.layers.len() <= self.prepare_layer { - self.layers.push(Layer::new( - device, - &self.constant_layout, - self.sampler.get(filter).expect("Sampler is registered"), - )); + if self.layers.len() <= self.prepare_layer { + self.layers.push([None, None, None, None]); + } + for (i, instances) in instances.iter_mut().enumerate() { + let layer = &mut self.layers[self.prepare_layer][i]; + if !instances.is_empty() { + if layer.is_none() { + *layer = Some(Layer::new( + device, + &self.constant_layout, + &self.sampler[i], + )) + } } - let layer = &mut self.layers[self.prepare_layer]; - layer.prepare(device, queue, instances, transformation); - - self.prepare_layer += 1; + if let Some(layer) = layer { + layer.prepare(device, queue, instances, transformation); + } } + self.prepare_layer += 1; } pub fn render<'a>( @@ -485,24 +493,29 @@ impl Pipeline { bounds: Rectangle, render_pass: &mut wgpu::RenderPass<'a>, ) { - if let Some(layer) = self.layers.get(layer) { - render_pass.set_pipeline(&self.pipeline); + if let Some(layer_group) = self.layers.get(layer) { + for (i, layer) in layer_group.iter().enumerate() { + if let Some(layer) = layer { + println!("Render {i}"); + render_pass.set_pipeline(&self.pipeline); - render_pass.set_scissor_rect( - bounds.x, - bounds.y, - bounds.width, - bounds.height, - ); + render_pass.set_scissor_rect( + bounds.x, + bounds.y, + bounds.width, + bounds.height, + ); - render_pass.set_bind_group(1, &self.texture, &[]); - render_pass.set_index_buffer( - self.indices.slice(..), - wgpu::IndexFormat::Uint16, - ); - render_pass.set_vertex_buffer(0, self.vertices.slice(..)); + render_pass.set_bind_group(1, &self.texture, &[]); + render_pass.set_index_buffer( + self.indices.slice(..), + wgpu::IndexFormat::Uint16, + ); + render_pass.set_vertex_buffer(0, self.vertices.slice(..)); - layer.render(render_pass); + layer.render(render_pass); + } + } } } @@ -517,6 +530,14 @@ impl Pipeline { } } +fn to_index(filter: &TextureFilter) -> usize { + let to_index = |m| match m { + FilterMethod::Linear => 0, + FilterMethod::Nearest => 1, + }; + return (to_index(filter.mag) << 1) | (to_index(filter.min)); +} + #[repr(C)] #[derive(Clone, Copy, Zeroable, Pod)] pub struct Vertex { From 75c9afc608a4a9ff44d60a8fb6f4a5819f05bf79 Mon Sep 17 00:00:00 2001 From: Remmirad Date: Mon, 25 Sep 2023 22:03:22 +0200 Subject: [PATCH 279/321] Remove debug traces --- wgpu/src/image.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wgpu/src/image.rs b/wgpu/src/image.rs index 0aa7f899..6768a714 100644 --- a/wgpu/src/image.rs +++ b/wgpu/src/image.rs @@ -494,9 +494,8 @@ impl Pipeline { render_pass: &mut wgpu::RenderPass<'a>, ) { if let Some(layer_group) = self.layers.get(layer) { - for (i, layer) in layer_group.iter().enumerate() { + for layer in layer_group.iter() { if let Some(layer) = layer { - println!("Render {i}"); render_pass.set_pipeline(&self.pipeline); render_pass.set_scissor_rect( From a5125d6fea824df1191777fe3eb53a2f748208b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 11 Nov 2023 07:02:01 +0100 Subject: [PATCH 280/321] Refactor texture image filtering - Support only `Linear` or `Nearest` - Simplify `Layer` groups - Move `FilterMethod` to `Image` and `image::Viewer` --- core/src/image.rs | 49 +++----- examples/tour/src/main.rs | 44 +++++-- graphics/src/primitive.rs | 2 + graphics/src/renderer.rs | 13 ++- renderer/src/lib.rs | 9 +- tiny_skia/src/backend.rs | 16 ++- tiny_skia/src/raster.rs | 3 +- wgpu/src/image.rs | 230 +++++++++++++++++++++---------------- wgpu/src/layer.rs | 7 +- wgpu/src/layer/image.rs | 3 + widget/src/image.rs | 29 +++-- widget/src/image/viewer.rs | 5 +- 12 files changed, 250 insertions(+), 160 deletions(-) diff --git a/core/src/image.rs b/core/src/image.rs index 69f19436..e9675316 100644 --- a/core/src/image.rs +++ b/core/src/image.rs @@ -5,31 +5,11 @@ use std::hash::{Hash, Hasher as _}; use std::path::PathBuf; use std::sync::Arc; -/// Image filter method -#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum FilterMethod { - /// Bilinear interpolation - #[default] - Linear, - /// Nearest Neighbor - Nearest, -} - -/// Texture filter settings -#[derive(Default, Debug, Clone, PartialEq, Eq, Hash)] -pub struct TextureFilter { - /// Filter for scaling the image down. - pub min: FilterMethod, - /// Filter for scaling the image up. - pub mag: FilterMethod, -} - /// A handle of some image data. #[derive(Debug, Clone, PartialEq, Eq)] pub struct Handle { id: u64, data: Data, - filter: TextureFilter, } impl Handle { @@ -76,7 +56,6 @@ impl Handle { Handle { id: hasher.finish(), data, - filter: TextureFilter::default(), } } @@ -89,17 +68,6 @@ impl Handle { pub fn data(&self) -> &Data { &self.data } - - /// Returns a reference to the [`TextureFilter`]. - pub fn filter(&self) -> &TextureFilter { - &self.filter - } - - /// Sets the texture filtering methods. - pub fn set_filter(mut self, filter: TextureFilter) -> Self { - self.filter = filter; - self - } } impl From for Handle @@ -196,6 +164,16 @@ impl std::fmt::Debug for Data { } } +/// Image filtering strategy. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)] +pub enum FilterMethod { + /// Bilinear interpolation. + #[default] + Linear, + /// Nearest neighbor. + Nearest, +} + /// A [`Renderer`] that can render raster graphics. /// /// [renderer]: crate::renderer @@ -210,5 +188,10 @@ pub trait Renderer: crate::Renderer { /// Draws an image with the given [`Handle`] and inside the provided /// `bounds`. - fn draw(&mut self, handle: Self::Handle, bounds: Rectangle); + fn draw( + &mut self, + handle: Self::Handle, + filter_method: FilterMethod, + bounds: Rectangle, + ); } diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs index d46e40d1..7003d8ae 100644 --- a/examples/tour/src/main.rs +++ b/examples/tour/src/main.rs @@ -1,4 +1,4 @@ -use iced::alignment; +use iced::alignment::{self, Alignment}; use iced::theme; use iced::widget::{ checkbox, column, container, horizontal_space, image, radio, row, @@ -126,7 +126,10 @@ impl Steps { Step::Toggler { can_continue: false, }, - Step::Image { width: 300 }, + Step::Image { + width: 300, + filter_method: image::FilterMethod::Linear, + }, Step::Scrollable, Step::TextInput { value: String::new(), @@ -195,6 +198,7 @@ enum Step { }, Image { width: u16, + filter_method: image::FilterMethod, }, Scrollable, TextInput { @@ -215,6 +219,7 @@ pub enum StepMessage { TextColorChanged(Color), LanguageSelected(Language), ImageWidthChanged(u16), + ImageUseNearestToggled(bool), InputChanged(String), ToggleSecureInput(bool), ToggleTextInputIcon(bool), @@ -265,6 +270,15 @@ impl<'a> Step { *width = new_width; } } + StepMessage::ImageUseNearestToggled(use_nearest) => { + if let Step::Image { filter_method, .. } = self { + *filter_method = if use_nearest { + image::FilterMethod::Nearest + } else { + image::FilterMethod::Linear + }; + } + } StepMessage::InputChanged(new_value) => { if let Step::TextInput { value, .. } = self { *value = new_value; @@ -330,7 +344,10 @@ impl<'a> Step { Step::Toggler { can_continue } => Self::toggler(*can_continue), Step::Slider { value } => Self::slider(*value), Step::Text { size, color } => Self::text(*size, *color), - Step::Image { width } => Self::image(*width), + Step::Image { + width, + filter_method, + } => Self::image(*width, *filter_method), Step::RowsAndColumns { layout, spacing } => { Self::rows_and_columns(*layout, *spacing) } @@ -525,16 +542,25 @@ impl<'a> Step { ) } - fn image(width: u16) -> Column<'a, StepMessage> { + fn image( + width: u16, + filter_method: image::FilterMethod, + ) -> Column<'a, StepMessage> { Self::container("Image") .push("An image that tries to keep its aspect ratio.") - .push(ferris(width)) + .push(ferris(width, filter_method)) .push(slider(100..=500, width, StepMessage::ImageWidthChanged)) .push( text(format!("Width: {width} px")) .width(Length::Fill) .horizontal_alignment(alignment::Horizontal::Center), ) + .push(checkbox( + "Use nearest interpolation", + filter_method == image::FilterMethod::Nearest, + StepMessage::ImageUseNearestToggled, + )) + .align_items(Alignment::Center) } fn scrollable() -> Column<'a, StepMessage> { @@ -555,7 +581,7 @@ impl<'a> Step { .horizontal_alignment(alignment::Horizontal::Center), ) .push(vertical_space(4096)) - .push(ferris(300)) + .push(ferris(300, image::FilterMethod::Linear)) .push( text("You made it!") .width(Length::Fill) @@ -646,7 +672,10 @@ impl<'a> Step { } } -fn ferris<'a>(width: u16) -> Container<'a, StepMessage> { +fn ferris<'a>( + width: u16, + filter_method: image::FilterMethod, +) -> Container<'a, StepMessage> { container( // This should go away once we unify resource loading on native // platforms @@ -655,6 +684,7 @@ fn ferris<'a>(width: u16) -> Container<'a, StepMessage> { } else { image(format!("{}/images/ferris.png", env!("CARGO_MANIFEST_DIR"))) } + .filter_method(filter_method) .width(width), ) .width(Length::Fill) diff --git a/graphics/src/primitive.rs b/graphics/src/primitive.rs index ce0b734b..4ed512c1 100644 --- a/graphics/src/primitive.rs +++ b/graphics/src/primitive.rs @@ -68,6 +68,8 @@ pub enum Primitive { Image { /// The handle of the image handle: image::Handle, + /// The filter method of the image + filter_method: image::FilterMethod, /// The bounds of the image bounds: Rectangle, }, diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index 93fff3b7..d7613e36 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -215,8 +215,17 @@ where self.backend().dimensions(handle) } - fn draw(&mut self, handle: image::Handle, bounds: Rectangle) { - self.primitives.push(Primitive::Image { handle, bounds }); + fn draw( + &mut self, + handle: image::Handle, + filter_method: image::FilterMethod, + bounds: Rectangle, + ) { + self.primitives.push(Primitive::Image { + handle, + filter_method, + bounds, + }); } } diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs index cc81c6e2..43f9794b 100644 --- a/renderer/src/lib.rs +++ b/renderer/src/lib.rs @@ -214,8 +214,13 @@ impl crate::core::image::Renderer for Renderer { delegate!(self, renderer, renderer.dimensions(handle)) } - fn draw(&mut self, handle: crate::core::image::Handle, bounds: Rectangle) { - delegate!(self, renderer, renderer.draw(handle, bounds)); + fn draw( + &mut self, + handle: crate::core::image::Handle, + filter_method: crate::core::image::FilterMethod, + bounds: Rectangle, + ) { + delegate!(self, renderer, renderer.draw(handle, filter_method, bounds)); } } diff --git a/tiny_skia/src/backend.rs b/tiny_skia/src/backend.rs index 3c6fe288..f2905b00 100644 --- a/tiny_skia/src/backend.rs +++ b/tiny_skia/src/backend.rs @@ -445,7 +445,11 @@ impl Backend { ); } #[cfg(feature = "image")] - Primitive::Image { handle, bounds } => { + Primitive::Image { + handle, + filter_method, + bounds, + } => { let physical_bounds = (*bounds + translation) * scale_factor; if !clip_bounds.intersects(&physical_bounds) { @@ -461,8 +465,14 @@ impl Backend { ) .post_scale(scale_factor, scale_factor); - self.raster_pipeline - .draw(handle, *bounds, pixels, transform, clip_mask); + self.raster_pipeline.draw( + handle, + *filter_method, + *bounds, + pixels, + transform, + clip_mask, + ); } #[cfg(not(feature = "image"))] Primitive::Image { .. } => { diff --git a/tiny_skia/src/raster.rs b/tiny_skia/src/raster.rs index 3f35ee78..5f17ae60 100644 --- a/tiny_skia/src/raster.rs +++ b/tiny_skia/src/raster.rs @@ -28,6 +28,7 @@ impl Pipeline { pub fn draw( &mut self, handle: &raster::Handle, + filter_method: raster::FilterMethod, bounds: Rectangle, pixels: &mut tiny_skia::PixmapMut<'_>, transform: tiny_skia::Transform, @@ -39,7 +40,7 @@ impl Pipeline { let transform = transform.pre_scale(width_scale, height_scale); - let quality = match handle.filter().mag { + let quality = match filter_method { raster::FilterMethod::Linear => { tiny_skia::FilterQuality::Bilinear } diff --git a/wgpu/src/image.rs b/wgpu/src/image.rs index 6768a714..1a88c6ae 100644 --- a/wgpu/src/image.rs +++ b/wgpu/src/image.rs @@ -7,8 +7,6 @@ mod raster; mod vector; use atlas::Atlas; -use iced_graphics::core::image::{FilterMethod, TextureFilter}; -use wgpu::Sampler; use crate::core::{Rectangle, Size}; use crate::graphics::Transformation; @@ -29,8 +27,6 @@ use crate::core::svg; #[cfg(feature = "tracing")] use tracing::info_span; -const SAMPLER_COUNT: usize = 4; - #[derive(Debug)] pub struct Pipeline { #[cfg(feature = "image")] @@ -41,30 +37,31 @@ pub struct Pipeline { pipeline: wgpu::RenderPipeline, vertices: wgpu::Buffer, indices: wgpu::Buffer, - sampler: [wgpu::Sampler; SAMPLER_COUNT], + nearest_sampler: wgpu::Sampler, + linear_sampler: wgpu::Sampler, texture: wgpu::BindGroup, texture_version: usize, texture_atlas: Atlas, texture_layout: wgpu::BindGroupLayout, constant_layout: wgpu::BindGroupLayout, - layers: Vec<[Option; SAMPLER_COUNT]>, + layers: Vec, prepare_layer: usize, } #[derive(Debug)] struct Layer { uniforms: wgpu::Buffer, - constants: wgpu::BindGroup, - instances: Buffer, - instance_count: usize, + nearest: Data, + linear: Data, } impl Layer { fn new( device: &wgpu::Device, constant_layout: &wgpu::BindGroupLayout, - sampler: &wgpu::Sampler, + nearest_sampler: &wgpu::Sampler, + linear_sampler: &wgpu::Sampler, ) -> Self { let uniforms = device.create_buffer(&wgpu::BufferDescriptor { label: Some("iced_wgpu::image uniforms buffer"), @@ -73,6 +70,59 @@ impl Layer { mapped_at_creation: false, }); + let nearest = + Data::new(device, constant_layout, nearest_sampler, &uniforms); + + let linear = + Data::new(device, constant_layout, linear_sampler, &uniforms); + + Self { + uniforms, + nearest, + linear, + } + } + + fn prepare( + &mut self, + device: &wgpu::Device, + queue: &wgpu::Queue, + nearest_instances: &[Instance], + linear_instances: &[Instance], + transformation: Transformation, + ) { + queue.write_buffer( + &self.uniforms, + 0, + bytemuck::bytes_of(&Uniforms { + transform: transformation.into(), + }), + ); + + self.nearest.upload(device, queue, nearest_instances); + self.linear.upload(device, queue, linear_instances); + } + + fn render<'a>(&'a self, render_pass: &mut wgpu::RenderPass<'a>) { + self.nearest.render(render_pass); + self.linear.render(render_pass); + } +} + +#[derive(Debug)] +struct Data { + constants: wgpu::BindGroup, + instances: Buffer, + instance_count: usize, +} + +impl Data { + pub fn new( + device: &wgpu::Device, + constant_layout: &wgpu::BindGroupLayout, + sampler: &wgpu::Sampler, + uniforms: &wgpu::Buffer, + ) -> Self { let constants = device.create_bind_group(&wgpu::BindGroupDescriptor { label: Some("iced_wgpu::image constants bind group"), layout: constant_layout, @@ -102,28 +152,18 @@ impl Layer { ); Self { - uniforms, constants, instances, instance_count: 0, } } - fn prepare( + fn upload( &mut self, device: &wgpu::Device, queue: &wgpu::Queue, instances: &[Instance], - transformation: Transformation, ) { - queue.write_buffer( - &self.uniforms, - 0, - bytemuck::bytes_of(&Uniforms { - transform: transformation.into(), - }), - ); - let _ = self.instances.resize(device, instances.len()); let _ = self.instances.write(queue, 0, instances); @@ -146,37 +186,25 @@ impl Pipeline { pub fn new(device: &wgpu::Device, format: wgpu::TextureFormat) -> Self { use wgpu::util::DeviceExt; - let to_wgpu = |method: FilterMethod| match method { - FilterMethod::Linear => wgpu::FilterMode::Linear, - FilterMethod::Nearest => wgpu::FilterMode::Nearest, - }; + let nearest_sampler = device.create_sampler(&wgpu::SamplerDescriptor { + address_mode_u: wgpu::AddressMode::ClampToEdge, + address_mode_v: wgpu::AddressMode::ClampToEdge, + address_mode_w: wgpu::AddressMode::ClampToEdge, + min_filter: wgpu::FilterMode::Nearest, + mag_filter: wgpu::FilterMode::Nearest, + mipmap_filter: wgpu::FilterMode::Nearest, + ..Default::default() + }); - let mut sampler: [Option; SAMPLER_COUNT] = - [None, None, None, None]; - - let filter = [FilterMethod::Linear, FilterMethod::Nearest]; - for min in 0..filter.len() { - for mag in 0..filter.len() { - sampler[to_index(&TextureFilter { - min: filter[min], - mag: filter[mag], - })] = Some(device.create_sampler(&wgpu::SamplerDescriptor { - address_mode_u: wgpu::AddressMode::ClampToEdge, - address_mode_v: wgpu::AddressMode::ClampToEdge, - address_mode_w: wgpu::AddressMode::ClampToEdge, - mag_filter: to_wgpu(filter[mag]), - min_filter: to_wgpu(filter[min]), - mipmap_filter: wgpu::FilterMode::Linear, - ..Default::default() - })); - } - } - let sampler = [ - sampler[0].take().unwrap(), - sampler[1].take().unwrap(), - sampler[2].take().unwrap(), - sampler[3].take().unwrap(), - ]; + let linear_sampler = device.create_sampler(&wgpu::SamplerDescriptor { + address_mode_u: wgpu::AddressMode::ClampToEdge, + address_mode_v: wgpu::AddressMode::ClampToEdge, + address_mode_w: wgpu::AddressMode::ClampToEdge, + min_filter: wgpu::FilterMode::Linear, + mag_filter: wgpu::FilterMode::Linear, + mipmap_filter: wgpu::FilterMode::Linear, + ..Default::default() + }); let constant_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { @@ -338,7 +366,8 @@ impl Pipeline { pipeline, vertices, indices, - sampler, + nearest_sampler, + linear_sampler, texture, texture_version: texture_atlas.layer_count(), texture_atlas, @@ -381,8 +410,8 @@ impl Pipeline { #[cfg(feature = "tracing")] let _ = info_span!("Wgpu::Image", "DRAW").entered(); - let mut instances: [Vec; SAMPLER_COUNT] = - [Vec::new(), Vec::new(), Vec::new(), Vec::new()]; + let nearest_instances: &mut Vec = &mut Vec::new(); + let linear_instances: &mut Vec = &mut Vec::new(); #[cfg(feature = "image")] let mut raster_cache = self.raster_cache.borrow_mut(); @@ -393,7 +422,11 @@ impl Pipeline { for image in images { match &image { #[cfg(feature = "image")] - layer::Image::Raster { handle, bounds } => { + layer::Image::Raster { + handle, + filter_method, + bounds, + } => { if let Some(atlas_entry) = raster_cache.upload( device, encoder, @@ -404,7 +437,12 @@ impl Pipeline { [bounds.x, bounds.y], [bounds.width, bounds.height], atlas_entry, - &mut instances[to_index(handle.filter())], + match filter_method { + image::FilterMethod::Nearest => { + nearest_instances + } + image::FilterMethod::Linear => linear_instances, + }, ); } } @@ -432,7 +470,7 @@ impl Pipeline { [bounds.x, bounds.y], size, atlas_entry, - &mut instances[to_index(&TextureFilter::default())], + nearest_instances, ); } } @@ -441,7 +479,7 @@ impl Pipeline { } } - if instances.is_empty() { + if nearest_instances.is_empty() && linear_instances.is_empty() { return; } @@ -466,24 +504,24 @@ impl Pipeline { } if self.layers.len() <= self.prepare_layer { - self.layers.push([None, None, None, None]); + self.layers.push(Layer::new( + device, + &self.constant_layout, + &self.nearest_sampler, + &self.linear_sampler, + )); } - for (i, instances) in instances.iter_mut().enumerate() { - let layer = &mut self.layers[self.prepare_layer][i]; - if !instances.is_empty() { - if layer.is_none() { - *layer = Some(Layer::new( - device, - &self.constant_layout, - &self.sampler[i], - )) - } - } - if let Some(layer) = layer { - layer.prepare(device, queue, instances, transformation); - } - } + let layer = &mut self.layers[self.prepare_layer]; + + layer.prepare( + device, + queue, + &nearest_instances, + &linear_instances, + transformation, + ); + self.prepare_layer += 1; } @@ -493,28 +531,24 @@ impl Pipeline { bounds: Rectangle, render_pass: &mut wgpu::RenderPass<'a>, ) { - if let Some(layer_group) = self.layers.get(layer) { - for layer in layer_group.iter() { - if let Some(layer) = layer { - render_pass.set_pipeline(&self.pipeline); + if let Some(layer) = self.layers.get(layer) { + render_pass.set_pipeline(&self.pipeline); - render_pass.set_scissor_rect( - bounds.x, - bounds.y, - bounds.width, - bounds.height, - ); + render_pass.set_scissor_rect( + bounds.x, + bounds.y, + bounds.width, + bounds.height, + ); - render_pass.set_bind_group(1, &self.texture, &[]); - render_pass.set_index_buffer( - self.indices.slice(..), - wgpu::IndexFormat::Uint16, - ); - render_pass.set_vertex_buffer(0, self.vertices.slice(..)); + render_pass.set_bind_group(1, &self.texture, &[]); + render_pass.set_index_buffer( + self.indices.slice(..), + wgpu::IndexFormat::Uint16, + ); + render_pass.set_vertex_buffer(0, self.vertices.slice(..)); - layer.render(render_pass); - } - } + layer.render(render_pass); } } @@ -529,14 +563,6 @@ impl Pipeline { } } -fn to_index(filter: &TextureFilter) -> usize { - let to_index = |m| match m { - FilterMethod::Linear => 0, - FilterMethod::Nearest => 1, - }; - return (to_index(filter.mag) << 1) | (to_index(filter.min)); -} - #[repr(C)] #[derive(Clone, Copy, Zeroable, Pod)] pub struct Vertex { @@ -571,7 +597,7 @@ struct Instance { } impl Instance { - pub const INITIAL: usize = 1_000; + pub const INITIAL: usize = 20; } #[repr(C)] diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs index b251538e..286801e6 100644 --- a/wgpu/src/layer.rs +++ b/wgpu/src/layer.rs @@ -186,11 +186,16 @@ impl<'a> Layer<'a> { layer.quads.add(quad, background); } - Primitive::Image { handle, bounds } => { + Primitive::Image { + handle, + filter_method, + bounds, + } => { let layer = &mut layers[current_layer]; layer.images.push(Image::Raster { handle: handle.clone(), + filter_method: *filter_method, bounds: *bounds + translation, }); } diff --git a/wgpu/src/layer/image.rs b/wgpu/src/layer/image.rs index 0de589f8..facbe192 100644 --- a/wgpu/src/layer/image.rs +++ b/wgpu/src/layer/image.rs @@ -10,6 +10,9 @@ pub enum Image { /// The handle of a raster image. handle: image::Handle, + /// The filter method of a raster image. + filter_method: image::FilterMethod, + /// The bounds of the image. bounds: Rectangle, }, diff --git a/widget/src/image.rs b/widget/src/image.rs index 684f200c..67699102 100644 --- a/widget/src/image.rs +++ b/widget/src/image.rs @@ -13,7 +13,7 @@ use crate::core::{ use std::hash::Hash; -pub use image::{FilterMethod, Handle, TextureFilter}; +pub use image::{FilterMethod, Handle}; /// Creates a new [`Viewer`] with the given image `Handle`. pub fn viewer(handle: Handle) -> Viewer { @@ -37,6 +37,7 @@ pub struct Image { width: Length, height: Length, content_fit: ContentFit, + filter_method: FilterMethod, } impl Image { @@ -47,6 +48,7 @@ impl Image { width: Length::Shrink, height: Length::Shrink, content_fit: ContentFit::Contain, + filter_method: FilterMethod::default(), } } @@ -65,11 +67,15 @@ impl Image { /// Sets the [`ContentFit`] of the [`Image`]. /// /// Defaults to [`ContentFit::Contain`] - pub fn content_fit(self, content_fit: ContentFit) -> Self { - Self { - content_fit, - ..self - } + pub fn content_fit(mut self, content_fit: ContentFit) -> Self { + self.content_fit = content_fit; + self + } + + /// Sets the [`FilterMethod`] of the [`Image`]. + pub fn filter_method(mut self, filter_method: FilterMethod) -> Self { + self.filter_method = filter_method; + self } } @@ -119,6 +125,7 @@ pub fn draw( layout: Layout<'_>, handle: &Handle, content_fit: ContentFit, + filter_method: FilterMethod, ) where Renderer: image::Renderer, Handle: Clone + Hash, @@ -141,7 +148,7 @@ pub fn draw( ..bounds }; - renderer.draw(handle.clone(), drawing_bounds + offset); + renderer.draw(handle.clone(), filter_method, drawing_bounds + offset); }; if adjusted_fit.width > bounds.width || adjusted_fit.height > bounds.height @@ -191,7 +198,13 @@ where _cursor: mouse::Cursor, _viewport: &Rectangle, ) { - draw(renderer, layout, &self.handle, self.content_fit); + draw( + renderer, + layout, + &self.handle, + self.content_fit, + self.filter_method, + ); } } diff --git a/widget/src/image/viewer.rs b/widget/src/image/viewer.rs index 44624fc8..68015ba8 100644 --- a/widget/src/image/viewer.rs +++ b/widget/src/image/viewer.rs @@ -22,19 +22,21 @@ pub struct Viewer { max_scale: f32, scale_step: f32, handle: Handle, + filter_method: image::FilterMethod, } impl Viewer { /// Creates a new [`Viewer`] with the given [`State`]. pub fn new(handle: Handle) -> Self { Viewer { + handle, padding: 0.0, width: Length::Shrink, height: Length::Shrink, min_scale: 0.25, max_scale: 10.0, scale_step: 0.10, - handle, + filter_method: image::FilterMethod::default(), } } @@ -329,6 +331,7 @@ where image::Renderer::draw( renderer, self.handle.clone(), + self.filter_method, Rectangle { x: bounds.x, y: bounds.y, From 9d560c813566ba04be3e23ae1b14861365485b57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 11 Nov 2023 07:27:38 +0100 Subject: [PATCH 281/321] Fix unnecessary references in `iced_wgpu::image` --- wgpu/src/image.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wgpu/src/image.rs b/wgpu/src/image.rs index 1a88c6ae..b78802c7 100644 --- a/wgpu/src/image.rs +++ b/wgpu/src/image.rs @@ -131,7 +131,7 @@ impl Data { binding: 0, resource: wgpu::BindingResource::Buffer( wgpu::BufferBinding { - buffer: &uniforms, + buffer: uniforms, offset: 0, size: None, }, @@ -517,8 +517,8 @@ impl Pipeline { layer.prepare( device, queue, - &nearest_instances, - &linear_instances, + nearest_instances, + linear_instances, transformation, ); From ae2d59ae96ba1ec2daf6979beff0e3913ba9e0b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 12 Nov 2023 03:17:02 +0100 Subject: [PATCH 282/321] Add `check` workflow to ensure `iced_widget` crate compiles --- .github/workflows/check.yml | 29 +++++++++++++++++++++++++++++ .github/workflows/test.yml | 21 +-------------------- 2 files changed, 30 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/check.yml diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 00000000..df9c480f --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,29 @@ +name: Check +on: [push, pull_request] +jobs: + widget: + runs-on: ubuntu-latest + steps: + - uses: hecrj/setup-rust-action@v1 + - uses: actions/checkout@master + - name: Check standalone `iced_widget` crate + run: cargo check --package iced_widget --features image,svg,canvas + + wasm: + runs-on: ubuntu-latest + env: + RUSTFLAGS: --cfg=web_sys_unstable_apis + steps: + - uses: hecrj/setup-rust-action@v1 + with: + rust-version: stable + targets: wasm32-unknown-unknown + - uses: actions/checkout@master + - name: Run checks + run: cargo check --package iced --target wasm32-unknown-unknown + - name: Check compilation of `tour` example + run: cargo build --package tour --target wasm32-unknown-unknown + - name: Check compilation of `todos` example + run: cargo build --package todos --target wasm32-unknown-unknown + - name: Check compilation of `integration` example + run: cargo build --package integration --target wasm32-unknown-unknown diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 215b616b..a08033c9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,7 +1,7 @@ name: Test on: [push, pull_request] jobs: - native: + all: runs-on: ${{ matrix.os }} strategy: matrix: @@ -22,22 +22,3 @@ jobs: run: | cargo test --verbose --workspace cargo test --verbose --workspace --all-features - - web: - runs-on: ubuntu-latest - env: - RUSTFLAGS: --cfg=web_sys_unstable_apis - steps: - - uses: hecrj/setup-rust-action@v1 - with: - rust-version: stable - targets: wasm32-unknown-unknown - - uses: actions/checkout@master - - name: Run checks - run: cargo check --package iced --target wasm32-unknown-unknown - - name: Check compilation of `tour` example - run: cargo build --package tour --target wasm32-unknown-unknown - - name: Check compilation of `todos` example - run: cargo build --package todos --target wasm32-unknown-unknown - - name: Check compilation of `integration` example - run: cargo build --package integration --target wasm32-unknown-unknown From 9d5ff12063e05158ede74f1aec4167bf910c8730 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 12 Nov 2023 03:22:43 +0100 Subject: [PATCH 283/321] Fix conditional compilation in `iced_renderer` --- renderer/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs index 43f9794b..78dec847 100644 --- a/renderer/src/lib.rs +++ b/renderer/src/lib.rs @@ -252,6 +252,7 @@ impl crate::graphics::geometry::Renderer for Renderer { crate::Geometry::TinySkia(primitive) => { renderer.draw_primitive(primitive); } + #[cfg(feature = "wgpu")] crate::Geometry::Wgpu(_) => unreachable!(), } } From 93416cbebd1dad04d250bc39ee7db9482d1e5e72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 12 Nov 2023 03:33:09 +0100 Subject: [PATCH 284/321] Deny warnings in `test` workflow --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 215b616b..e9e1d86b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,6 +3,8 @@ on: [push, pull_request] jobs: native: runs-on: ${{ matrix.os }} + env: + RUSTFLAGS: --deny warnings strategy: matrix: os: [ubuntu-latest, windows-latest, macOS-latest] From f98627a317615151681ca8b324052eb4a170b789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 12 Nov 2023 03:40:32 +0100 Subject: [PATCH 285/321] Add missing `'static` lifetimes to constant slices --- examples/lazy/src/main.rs | 2 +- examples/modal/src/main.rs | 3 ++- examples/toast/src/main.rs | 2 +- highlighter/src/lib.rs | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/lazy/src/main.rs b/examples/lazy/src/main.rs index 9bf17c56..01560598 100644 --- a/examples/lazy/src/main.rs +++ b/examples/lazy/src/main.rs @@ -46,7 +46,7 @@ enum Color { } impl Color { - const ALL: &[Color] = &[ + const ALL: &'static [Color] = &[ Color::Black, Color::Red, Color::Orange, diff --git a/examples/modal/src/main.rs b/examples/modal/src/main.rs index b0e2c81b..3b69f5e6 100644 --- a/examples/modal/src/main.rs +++ b/examples/modal/src/main.rs @@ -205,7 +205,8 @@ enum Plan { } impl Plan { - pub const ALL: &[Self] = &[Self::Basic, Self::Pro, Self::Enterprise]; + pub const ALL: &'static [Self] = + &[Self::Basic, Self::Pro, Self::Enterprise]; } impl fmt::Display for Plan { diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs index 20c3dd42..5b089e8a 100644 --- a/examples/toast/src/main.rs +++ b/examples/toast/src/main.rs @@ -210,7 +210,7 @@ mod toast { } impl Status { - pub const ALL: &[Self] = + pub const ALL: &'static [Self] = &[Self::Primary, Self::Secondary, Self::Success, Self::Danger]; } diff --git a/highlighter/src/lib.rs b/highlighter/src/lib.rs index 5630756e..63f21fc0 100644 --- a/highlighter/src/lib.rs +++ b/highlighter/src/lib.rs @@ -168,7 +168,7 @@ pub enum Theme { } impl Theme { - pub const ALL: &[Self] = &[ + pub const ALL: &'static [Self] = &[ Self::SolarizedDark, Self::Base16Mocha, Self::Base16Ocean, From 781ef1f94c4859aeeb852f801b72be095b8ff82b Mon Sep 17 00:00:00 2001 From: Bingus Date: Thu, 14 Sep 2023 13:58:36 -0700 Subject: [PATCH 286/321] Added support for custom shader widget for iced_wgpu backend. --- Cargo.toml | 2 +- core/src/rectangle.rs | 11 + examples/custom_shader/Cargo.toml | 13 + examples/custom_shader/src/camera.rs | 53 ++ examples/custom_shader/src/cubes.rs | 99 +++ examples/custom_shader/src/main.rs | 174 +++++ examples/custom_shader/src/pipeline.rs | 600 ++++++++++++++++++ examples/custom_shader/src/primitive.rs | 95 +++ .../custom_shader/src/primitive/buffer.rs | 39 ++ examples/custom_shader/src/primitive/cube.rs | 324 ++++++++++ .../custom_shader/src/primitive/uniforms.rs | 22 + .../custom_shader/src/primitive/vertex.rs | 29 + examples/custom_shader/src/shaders/cubes.wgsl | 123 ++++ examples/custom_shader/src/shaders/depth.wgsl | 48 ++ .../src/textures/ice_cube_normal_map.png | Bin 0 -> 1773656 bytes .../src/textures/skybox/neg_x.jpg | Bin 0 -> 7549 bytes .../src/textures/skybox/neg_y.jpg | Bin 0 -> 2722 bytes .../src/textures/skybox/neg_z.jpg | Bin 0 -> 3986 bytes .../src/textures/skybox/pos_x.jpg | Bin 0 -> 5522 bytes .../src/textures/skybox/pos_y.jpg | Bin 0 -> 3382 bytes .../src/textures/skybox/pos_z.jpg | Bin 0 -> 5205 bytes examples/integration/src/main.rs | 1 + graphics/Cargo.toml | 1 - renderer/src/lib.rs | 21 + renderer/src/widget.rs | 3 + renderer/src/widget/shader.rs | 215 +++++++ renderer/src/widget/shader/event.rs | 21 + renderer/src/widget/shader/program.rs | 60 ++ style/src/theme.rs | 2 +- wgpu/src/backend.rs | 64 +- wgpu/src/custom.rs | 66 ++ wgpu/src/layer.rs | 16 + wgpu/src/lib.rs | 1 + wgpu/src/primitive.rs | 36 ++ wgpu/src/window/compositor.rs | 2 + widget/Cargo.toml | 1 + widget/src/lib.rs | 3 + 37 files changed, 2139 insertions(+), 6 deletions(-) create mode 100644 examples/custom_shader/Cargo.toml create mode 100644 examples/custom_shader/src/camera.rs create mode 100644 examples/custom_shader/src/cubes.rs create mode 100644 examples/custom_shader/src/main.rs create mode 100644 examples/custom_shader/src/pipeline.rs create mode 100644 examples/custom_shader/src/primitive.rs create mode 100644 examples/custom_shader/src/primitive/buffer.rs create mode 100644 examples/custom_shader/src/primitive/cube.rs create mode 100644 examples/custom_shader/src/primitive/uniforms.rs create mode 100644 examples/custom_shader/src/primitive/vertex.rs create mode 100644 examples/custom_shader/src/shaders/cubes.wgsl create mode 100644 examples/custom_shader/src/shaders/depth.wgsl create mode 100644 examples/custom_shader/src/textures/ice_cube_normal_map.png create mode 100644 examples/custom_shader/src/textures/skybox/neg_x.jpg create mode 100644 examples/custom_shader/src/textures/skybox/neg_y.jpg create mode 100644 examples/custom_shader/src/textures/skybox/neg_z.jpg create mode 100644 examples/custom_shader/src/textures/skybox/pos_x.jpg create mode 100644 examples/custom_shader/src/textures/skybox/pos_y.jpg create mode 100644 examples/custom_shader/src/textures/skybox/pos_z.jpg create mode 100644 renderer/src/widget/shader.rs create mode 100644 renderer/src/widget/shader/event.rs create mode 100644 renderer/src/widget/shader/program.rs create mode 100644 wgpu/src/custom.rs diff --git a/Cargo.toml b/Cargo.toml index d69c95cf..ad4cd1bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ maintenance = { status = "actively-developed" } [features] default = ["wgpu"] # Enable the `wgpu` GPU-accelerated renderer backend -wgpu = ["iced_renderer/wgpu"] +wgpu = ["iced_renderer/wgpu", "iced_widget/wgpu"] # Enables the `Image` widget image = ["iced_widget/image", "dep:image"] # Enables the `Svg` widget diff --git a/core/src/rectangle.rs b/core/src/rectangle.rs index c1c2eeac..d5437d51 100644 --- a/core/src/rectangle.rs +++ b/core/src/rectangle.rs @@ -183,6 +183,17 @@ impl From> for Rectangle { } } +impl From> for Rectangle { + fn from(rectangle: Rectangle) -> Self { + Rectangle { + x: rectangle.x as u32, + y: rectangle.y as u32, + width: rectangle.width as u32, + height: rectangle.height as u32, + } + } +} + impl std::ops::Add> for Rectangle where T: std::ops::Add, diff --git a/examples/custom_shader/Cargo.toml b/examples/custom_shader/Cargo.toml new file mode 100644 index 00000000..7a927811 --- /dev/null +++ b/examples/custom_shader/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "custom_shader" +version = "0.1.0" +authors = ["Bingus "] +edition = "2021" + +[dependencies] +iced = { path = "../..", features = ["debug", "advanced"]} +image = { version = "0.24.6"} +wgpu = "0.17" +bytemuck = { version = "1.13.1" } +glam = { version = "0.24.0", features = ["bytemuck"] } +rand = "0.8.5" diff --git a/examples/custom_shader/src/camera.rs b/examples/custom_shader/src/camera.rs new file mode 100644 index 00000000..2a49c102 --- /dev/null +++ b/examples/custom_shader/src/camera.rs @@ -0,0 +1,53 @@ +use glam::{mat4, vec3, vec4}; +use iced::Rectangle; + +#[derive(Copy, Clone)] +pub struct Camera { + eye: glam::Vec3, + target: glam::Vec3, + up: glam::Vec3, + fov_y: f32, + near: f32, + far: f32, +} + +impl Default for Camera { + fn default() -> Self { + Self { + eye: vec3(0.0, 2.0, 3.0), + target: glam::Vec3::ZERO, + up: glam::Vec3::Y, + fov_y: 45.0, + near: 0.1, + far: 100.0, + } + } +} + +pub const OPENGL_TO_WGPU_MATRIX: glam::Mat4 = mat4( + vec4(1.0, 0.0, 0.0, 0.0), + vec4(0.0, 1.0, 0.0, 0.0), + vec4(0.0, 0.0, 0.5, 0.0), + vec4(0.0, 0.0, 0.5, 1.0), +); + +impl Camera { + pub fn build_view_proj_matrix(&self, bounds: Rectangle) -> glam::Mat4 { + //TODO looks distorted without padding; base on surface texture size instead? + let aspect_ratio = bounds.width / (bounds.height + 150.0); + + let view = glam::Mat4::look_at_rh(self.eye, self.target, self.up); + let proj = glam::Mat4::perspective_rh( + self.fov_y, + aspect_ratio, + self.near, + self.far, + ); + + OPENGL_TO_WGPU_MATRIX * proj * view + } + + pub fn position(&self) -> glam::Vec4 { + glam::Vec4::from((self.eye, 0.0)) + } +} diff --git a/examples/custom_shader/src/cubes.rs b/examples/custom_shader/src/cubes.rs new file mode 100644 index 00000000..8dbba4b1 --- /dev/null +++ b/examples/custom_shader/src/cubes.rs @@ -0,0 +1,99 @@ +use crate::camera::Camera; +use crate::primitive; +use crate::primitive::cube::Cube; +use glam::Vec3; +use iced::widget::shader; +use iced::{mouse, Color, Rectangle}; +use rand::Rng; +use std::cmp::Ordering; +use std::iter; +use std::time::Duration; + +pub const MAX: u32 = 500; + +#[derive(Clone)] +pub struct Cubes { + pub size: f32, + pub cubes: Vec, + pub camera: Camera, + pub show_depth_buffer: bool, + pub light_color: Color, +} + +impl Cubes { + pub fn new() -> Self { + let mut cubes = Self { + size: 0.2, + cubes: vec![], + camera: Camera::default(), + show_depth_buffer: false, + light_color: Color::WHITE, + }; + + cubes.adjust_num_cubes(MAX); + + cubes + } + + pub fn update(&mut self, time: Duration) { + for cube in self.cubes.iter_mut() { + cube.update(self.size, time.as_secs_f32()); + } + } + + pub fn adjust_num_cubes(&mut self, num_cubes: u32) { + let curr_cubes = self.cubes.len() as u32; + + match num_cubes.cmp(&curr_cubes) { + Ordering::Greater => { + // spawn + let cubes_2_spawn = (num_cubes - curr_cubes) as usize; + + let mut cubes = 0; + self.cubes.extend(iter::from_fn(|| { + if cubes < cubes_2_spawn { + cubes += 1; + Some(Cube::new(self.size, rnd_origin())) + } else { + None + } + })); + } + Ordering::Less => { + // chop + let cubes_2_cut = curr_cubes - num_cubes; + let new_len = self.cubes.len() - cubes_2_cut as usize; + self.cubes.truncate(new_len); + } + _ => {} + } + } +} + +impl shader::Program for Cubes { + type State = (); + type Primitive = primitive::Primitive; + + fn draw( + &self, + _state: &Self::State, + _cursor: mouse::Cursor, + bounds: Rectangle, + ) -> Self::Primitive { + primitive::Primitive::new( + &self.cubes, + &self.camera, + bounds, + self.show_depth_buffer, + self.light_color, + ) + } +} + +fn rnd_origin() -> Vec3 { + Vec3::new( + rand::thread_rng().gen_range(-4.0..4.0), + rand::thread_rng().gen_range(-4.0..4.0), + rand::thread_rng().gen_range(-4.0..2.0), + ) +} diff --git a/examples/custom_shader/src/main.rs b/examples/custom_shader/src/main.rs new file mode 100644 index 00000000..76fa1625 --- /dev/null +++ b/examples/custom_shader/src/main.rs @@ -0,0 +1,174 @@ +mod camera; +mod cubes; +mod pipeline; +mod primitive; + +use crate::cubes::Cubes; +use iced::widget::{ + checkbox, column, container, row, slider, text, vertical_space, Shader, +}; +use iced::{ + executor, window, Alignment, Application, Color, Command, Element, Length, + Renderer, Subscription, Theme, +}; +use std::time::Instant; + +fn main() -> iced::Result { + IcedCubes::run(iced::Settings::default()) +} + +struct IcedCubes { + start: Instant, + cubes: Cubes, + num_cubes_slider: u32, +} + +impl Default for IcedCubes { + fn default() -> Self { + Self { + start: Instant::now(), + cubes: Cubes::new(), + num_cubes_slider: cubes::MAX, + } + } +} + +#[derive(Debug, Clone)] +enum Message { + CubeAmountChanged(u32), + CubeSizeChanged(f32), + Tick(Instant), + ShowDepthBuffer(bool), + LightColorChanged(Color), +} + +impl Application for IcedCubes { + type Executor = executor::Default; + type Message = Message; + type Theme = Theme; + type Flags = (); + + fn new(_flags: Self::Flags) -> (Self, Command) { + (IcedCubes::default(), Command::none()) + } + + fn title(&self) -> String { + "Iced Cubes".to_string() + } + + fn update(&mut self, message: Self::Message) -> Command { + match message { + Message::CubeAmountChanged(num) => { + self.num_cubes_slider = num; + self.cubes.adjust_num_cubes(num); + } + Message::CubeSizeChanged(size) => { + self.cubes.size = size; + } + Message::Tick(time) => { + self.cubes.update(time - self.start); + } + Message::ShowDepthBuffer(show) => { + self.cubes.show_depth_buffer = show; + } + Message::LightColorChanged(color) => { + self.cubes.light_color = color; + } + } + + Command::none() + } + + fn view(&self) -> Element<'_, Self::Message, Renderer> { + let top_controls = row![ + control( + "Amount", + slider( + 1..=cubes::MAX, + self.num_cubes_slider, + Message::CubeAmountChanged + ) + .width(100) + ), + control( + "Size", + slider(0.1..=0.25, self.cubes.size, Message::CubeSizeChanged) + .step(0.01) + .width(100), + ), + checkbox( + "Show Depth Buffer", + self.cubes.show_depth_buffer, + Message::ShowDepthBuffer + ), + ] + .spacing(40); + + let bottom_controls = row![ + control( + "R", + slider(0.0..=1.0, self.cubes.light_color.r, move |r| { + Message::LightColorChanged(Color { + r, + ..self.cubes.light_color + }) + }) + .step(0.01) + .width(100) + ), + control( + "G", + slider(0.0..=1.0, self.cubes.light_color.g, move |g| { + Message::LightColorChanged(Color { + g, + ..self.cubes.light_color + }) + }) + .step(0.01) + .width(100) + ), + control( + "B", + slider(0.0..=1.0, self.cubes.light_color.b, move |b| { + Message::LightColorChanged(Color { + b, + ..self.cubes.light_color + }) + }) + .step(0.01) + .width(100) + ) + ] + .spacing(40); + + let controls = column![top_controls, bottom_controls,] + .spacing(10) + .align_items(Alignment::Center); + + let shader = Shader::new(&self.cubes) + .width(Length::Fill) + .height(Length::Fill); + + container( + column![shader, controls, vertical_space(20),] + .spacing(40) + .align_items(Alignment::Center), + ) + .width(Length::Fill) + .height(Length::Fill) + .center_x() + .center_y() + .into() + } + + fn subscription(&self) -> Subscription { + window::frames().map(Message::Tick) + } +} + +fn control<'a>( + label: &'static str, + control: impl Into>, +) -> Element<'a, Message> { + row![text(label), control.into()].spacing(10).into() +} diff --git a/examples/custom_shader/src/pipeline.rs b/examples/custom_shader/src/pipeline.rs new file mode 100644 index 00000000..9dd154e8 --- /dev/null +++ b/examples/custom_shader/src/pipeline.rs @@ -0,0 +1,600 @@ +use crate::primitive; +use crate::primitive::cube; +use crate::primitive::{Buffer, Uniforms}; +use iced::{Rectangle, Size}; +use wgpu::util::DeviceExt; + +const SKY_TEXTURE_SIZE: u32 = 128; + +pub struct Pipeline { + pipeline: wgpu::RenderPipeline, + vertices: wgpu::Buffer, + cubes: Buffer, + uniforms: wgpu::Buffer, + uniform_bind_group: wgpu::BindGroup, + depth_texture_size: Size, + depth_view: wgpu::TextureView, + depth_pipeline: DepthPipeline, +} + +impl Pipeline { + pub fn new( + device: &wgpu::Device, + queue: &wgpu::Queue, + format: wgpu::TextureFormat, + target_size: Size, + ) -> Self { + //vertices of one cube + let vertices = + device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("cubes vertex buffer"), + contents: bytemuck::cast_slice(&cube::Raw::vertices()), + usage: wgpu::BufferUsages::VERTEX, + }); + + //cube instance data + let cubes_buffer = Buffer::new( + device, + "cubes instance buffer", + std::mem::size_of::() as u64, + wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST, + ); + + //uniforms for all cubes + let uniforms = device.create_buffer(&wgpu::BufferDescriptor { + label: Some("cubes uniform buffer"), + size: std::mem::size_of::() as u64, + usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, + mapped_at_creation: false, + }); + + //depth buffer + let depth_texture = device.create_texture(&wgpu::TextureDescriptor { + label: Some("cubes depth texture"), + size: wgpu::Extent3d { + width: target_size.width, + height: target_size.height, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Depth32Float, + usage: wgpu::TextureUsages::RENDER_ATTACHMENT + | wgpu::TextureUsages::TEXTURE_BINDING, + view_formats: &[], + }); + + let depth_view = + depth_texture.create_view(&wgpu::TextureViewDescriptor::default()); + + let normal_map_data = load_normal_map_data(); + + //normal map + let normal_texture = device.create_texture_with_data( + queue, + &wgpu::TextureDescriptor { + label: Some("cubes normal map texture"), + size: wgpu::Extent3d { + width: 1024, + height: 1024, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Rgba8Unorm, + usage: wgpu::TextureUsages::TEXTURE_BINDING, + view_formats: &[], + }, + &normal_map_data, + ); + + let normal_view = + normal_texture.create_view(&wgpu::TextureViewDescriptor::default()); + + //skybox texture for reflection/refraction + let skybox_data = load_skybox_data(); + + let skybox_texture = device.create_texture_with_data( + queue, + &wgpu::TextureDescriptor { + label: Some("cubes skybox texture"), + size: wgpu::Extent3d { + width: SKY_TEXTURE_SIZE, + height: SKY_TEXTURE_SIZE, + depth_or_array_layers: 6, //one for each face of the cube + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Rgba8Unorm, + usage: wgpu::TextureUsages::TEXTURE_BINDING, + view_formats: &[], + }, + &skybox_data, + ); + + let sky_view = + skybox_texture.create_view(&wgpu::TextureViewDescriptor { + label: Some("cubes skybox texture view"), + dimension: Some(wgpu::TextureViewDimension::Cube), + ..Default::default() + }); + + let sky_sampler = device.create_sampler(&wgpu::SamplerDescriptor { + label: Some("cubes skybox sampler"), + address_mode_u: wgpu::AddressMode::ClampToEdge, + address_mode_v: wgpu::AddressMode::ClampToEdge, + address_mode_w: wgpu::AddressMode::ClampToEdge, + mag_filter: wgpu::FilterMode::Linear, + min_filter: wgpu::FilterMode::Linear, + mipmap_filter: wgpu::FilterMode::Linear, + ..Default::default() + }); + + let uniform_bind_group_layout = + device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: Some("cubes uniform bind group layout"), + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::VERTEX_FRAGMENT, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: None, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Texture { + sample_type: wgpu::TextureSampleType::Float { + filterable: true, + }, + view_dimension: wgpu::TextureViewDimension::Cube, + multisampled: false, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 2, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Sampler( + wgpu::SamplerBindingType::Filtering, + ), + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 3, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Texture { + sample_type: wgpu::TextureSampleType::Float { + filterable: true, + }, + view_dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + }, + ], + }); + + let uniform_bind_group = + device.create_bind_group(&wgpu::BindGroupDescriptor { + label: Some("cubes uniform bind group"), + layout: &uniform_bind_group_layout, + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: uniforms.as_entire_binding(), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::TextureView(&sky_view), + }, + wgpu::BindGroupEntry { + binding: 2, + resource: wgpu::BindingResource::Sampler(&sky_sampler), + }, + wgpu::BindGroupEntry { + binding: 3, + resource: wgpu::BindingResource::TextureView( + &normal_view, + ), + }, + ], + }); + + let layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("cubes pipeline layout"), + bind_group_layouts: &[&uniform_bind_group_layout], + push_constant_ranges: &[], + }); + + let shader = + device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: Some("cubes shader"), + source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed( + include_str!("shaders/cubes.wgsl"), + )), + }); + + let pipeline = + device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("cubes pipeline"), + layout: Some(&layout), + vertex: wgpu::VertexState { + module: &shader, + entry_point: "vs_main", + buffers: &[primitive::Vertex::desc(), cube::Raw::desc()], + }, + primitive: wgpu::PrimitiveState::default(), + depth_stencil: Some(wgpu::DepthStencilState { + format: wgpu::TextureFormat::Depth32Float, + depth_write_enabled: true, + depth_compare: wgpu::CompareFunction::Less, + stencil: wgpu::StencilState::default(), + bias: wgpu::DepthBiasState::default(), + }), + multisample: wgpu::MultisampleState { + count: 1, + mask: !0, + alpha_to_coverage_enabled: false, + }, + fragment: Some(wgpu::FragmentState { + module: &shader, + entry_point: "fs_main", + targets: &[Some(wgpu::ColorTargetState { + format, + blend: Some(wgpu::BlendState { + color: wgpu::BlendComponent { + src_factor: wgpu::BlendFactor::SrcAlpha, + dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha, + operation: wgpu::BlendOperation::Add, + }, + alpha: wgpu::BlendComponent { + src_factor: wgpu::BlendFactor::One, + dst_factor: wgpu::BlendFactor::One, + operation: wgpu::BlendOperation::Max, + }, + }), + write_mask: wgpu::ColorWrites::ALL, + })], + }), + multiview: None, + }); + + let depth_pipeline = DepthPipeline::new( + device, + format, + depth_texture.create_view(&wgpu::TextureViewDescriptor::default()), + ); + + Self { + pipeline, + cubes: cubes_buffer, + uniforms, + uniform_bind_group, + vertices, + depth_texture_size: target_size, + depth_view, + depth_pipeline, + } + } + + fn update_depth_texture(&mut self, device: &wgpu::Device, size: Size) { + if self.depth_texture_size.height != size.height + || self.depth_texture_size.width != size.width + { + let text = device.create_texture(&wgpu::TextureDescriptor { + label: Some("cubes depth texture"), + size: wgpu::Extent3d { + width: size.width, + height: size.height, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Depth32Float, + usage: wgpu::TextureUsages::RENDER_ATTACHMENT + | wgpu::TextureUsages::TEXTURE_BINDING, + view_formats: &[], + }); + + self.depth_view = + text.create_view(&wgpu::TextureViewDescriptor::default()); + self.depth_texture_size = size; + + self.depth_pipeline.update(device, &text); + } + } + + pub fn update( + &mut self, + device: &wgpu::Device, + queue: &wgpu::Queue, + target_size: Size, + uniforms: &Uniforms, + num_cubes: usize, + cubes: &[cube::Raw], + ) { + //recreate depth texture if surface texture size has changed + self.update_depth_texture(device, target_size); + + // update uniforms + queue.write_buffer(&self.uniforms, 0, bytemuck::bytes_of(uniforms)); + + //resize cubes vertex buffer if cubes amount changed + let new_size = num_cubes * std::mem::size_of::(); + self.cubes.resize(device, new_size as u64); + + //always write new cube data since they are constantly rotating + queue.write_buffer(&self.cubes.raw, 0, bytemuck::cast_slice(cubes)); + } + + pub fn render( + &self, + target: &wgpu::TextureView, + encoder: &mut wgpu::CommandEncoder, + bounds: Rectangle, + num_cubes: u32, + show_depth: bool, + ) { + { + let mut pass = + encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: Some("cubes.pipeline.pass"), + color_attachments: &[Some( + wgpu::RenderPassColorAttachment { + view: target, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Load, + store: true, + }, + }, + )], + depth_stencil_attachment: Some( + wgpu::RenderPassDepthStencilAttachment { + view: &self.depth_view, + depth_ops: Some(wgpu::Operations { + load: wgpu::LoadOp::Clear(1.0), + store: true, + }), + stencil_ops: None, + }, + ), + }); + + pass.set_scissor_rect( + bounds.x, + bounds.y, + bounds.width, + bounds.height, + ); + pass.set_pipeline(&self.pipeline); + pass.set_bind_group(0, &self.uniform_bind_group, &[]); + pass.set_vertex_buffer(0, self.vertices.slice(..)); + pass.set_vertex_buffer(1, self.cubes.raw.slice(..)); + pass.draw(0..36, 0..num_cubes); + } + + if show_depth { + self.depth_pipeline.render(encoder, target, bounds); + } + } +} + +struct DepthPipeline { + pipeline: wgpu::RenderPipeline, + bind_group_layout: wgpu::BindGroupLayout, + bind_group: wgpu::BindGroup, + sampler: wgpu::Sampler, + depth_view: wgpu::TextureView, +} + +impl DepthPipeline { + pub fn new( + device: &wgpu::Device, + format: wgpu::TextureFormat, + depth_texture: wgpu::TextureView, + ) -> Self { + let sampler = device.create_sampler(&wgpu::SamplerDescriptor { + label: Some("cubes.depth_pipeline.sampler"), + ..Default::default() + }); + + let bind_group_layout = + device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: Some("cubes.depth_pipeline.bind_group_layout"), + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Sampler( + wgpu::SamplerBindingType::NonFiltering, + ), + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Texture { + sample_type: wgpu::TextureSampleType::Float { + filterable: false, + }, + view_dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + }, + ], + }); + + let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { + label: Some("cubes.depth_pipeline.bind_group"), + layout: &bind_group_layout, + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::Sampler(&sampler), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::TextureView( + &depth_texture, + ), + }, + ], + }); + + let layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("cubes.depth_pipeline.layout"), + bind_group_layouts: &[&bind_group_layout], + push_constant_ranges: &[], + }); + + let shader = + device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: Some("cubes.depth_pipeline.shader"), + source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed( + include_str!("shaders/depth.wgsl"), + )), + }); + + let pipeline = + device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("cubes.depth_pipeline.pipeline"), + layout: Some(&layout), + vertex: wgpu::VertexState { + module: &shader, + entry_point: "vs_main", + buffers: &[], + }, + primitive: Default::default(), + depth_stencil: Some(wgpu::DepthStencilState { + format: wgpu::TextureFormat::Depth32Float, + depth_write_enabled: false, + depth_compare: wgpu::CompareFunction::Less, + stencil: Default::default(), + bias: Default::default(), + }), + multisample: Default::default(), + fragment: Some(wgpu::FragmentState { + module: &shader, + entry_point: "fs_main", + targets: &[Some(wgpu::ColorTargetState { + format, + blend: Some(wgpu::BlendState::REPLACE), + write_mask: wgpu::ColorWrites::ALL, + })], + }), + multiview: None, + }); + + Self { + pipeline, + bind_group_layout, + bind_group, + sampler, + depth_view: depth_texture, + } + } + + pub fn update( + &mut self, + device: &wgpu::Device, + depth_texture: &wgpu::Texture, + ) { + self.depth_view = + depth_texture.create_view(&wgpu::TextureViewDescriptor::default()); + + self.bind_group = + device.create_bind_group(&wgpu::BindGroupDescriptor { + label: Some("cubes.depth_pipeline.bind_group"), + layout: &self.bind_group_layout, + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::Sampler(&self.sampler), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::TextureView( + &self.depth_view, + ), + }, + ], + }); + } + + pub fn render( + &self, + encoder: &mut wgpu::CommandEncoder, + target: &wgpu::TextureView, + bounds: Rectangle, + ) { + let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: Some("cubes.pipeline.depth_pass"), + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view: target, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Load, + store: true, + }, + })], + depth_stencil_attachment: Some( + wgpu::RenderPassDepthStencilAttachment { + view: &self.depth_view, + depth_ops: None, + stencil_ops: None, + }, + ), + }); + + pass.set_scissor_rect(bounds.x, bounds.y, bounds.width, bounds.height); + pass.set_pipeline(&self.pipeline); + pass.set_bind_group(0, &self.bind_group, &[]); + pass.draw(0..6, 0..1); + } +} + +fn load_skybox_data() -> Vec { + let pos_x: &[u8] = include_bytes!("textures/skybox/pos_x.jpg"); + let neg_x: &[u8] = include_bytes!("textures/skybox/neg_x.jpg"); + let pos_y: &[u8] = include_bytes!("textures/skybox/pos_y.jpg"); + let neg_y: &[u8] = include_bytes!("textures/skybox/neg_y.jpg"); + let pos_z: &[u8] = include_bytes!("textures/skybox/pos_z.jpg"); + let neg_z: &[u8] = include_bytes!("textures/skybox/neg_z.jpg"); + + let data: [&[u8]; 6] = [pos_x, neg_x, pos_y, neg_y, pos_z, neg_z]; + + data.iter().fold(vec![], |mut acc, bytes| { + let i = image::load_from_memory_with_format( + bytes, + image::ImageFormat::Jpeg, + ) + .unwrap() + .to_rgba8() + .into_raw(); + + acc.extend(i); + acc + }) +} + +fn load_normal_map_data() -> Vec { + let bytes: &[u8] = include_bytes!("textures/ice_cube_normal_map.png"); + + image::load_from_memory_with_format(bytes, image::ImageFormat::Png) + .unwrap() + .to_rgba8() + .into_raw() +} diff --git a/examples/custom_shader/src/primitive.rs b/examples/custom_shader/src/primitive.rs new file mode 100644 index 00000000..2201218f --- /dev/null +++ b/examples/custom_shader/src/primitive.rs @@ -0,0 +1,95 @@ +pub mod cube; +pub mod vertex; + +mod buffer; +mod uniforms; + +use crate::camera::Camera; +use crate::pipeline::Pipeline; +use crate::primitive::cube::Cube; +use iced::advanced::graphics::Transformation; +use iced::widget::shader; +use iced::{Color, Rectangle, Size}; + +pub use crate::primitive::vertex::Vertex; +pub use buffer::Buffer; +pub use uniforms::Uniforms; + +/// A collection of `Cube`s that can be rendered. +#[derive(Debug)] +pub struct Primitive { + cubes: Vec, + uniforms: Uniforms, + show_depth_buffer: bool, +} + +impl Primitive { + pub fn new( + cubes: &[Cube], + camera: &Camera, + bounds: Rectangle, + show_depth_buffer: bool, + light_color: Color, + ) -> Self { + let uniforms = Uniforms::new(camera, bounds, light_color); + + Self { + cubes: cubes + .iter() + .map(cube::Raw::from_cube) + .collect::>(), + uniforms, + show_depth_buffer, + } + } +} + +impl shader::Primitive for Primitive { + fn prepare( + &self, + format: wgpu::TextureFormat, + device: &wgpu::Device, + queue: &wgpu::Queue, + target_size: Size, + _scale_factor: f32, + _transform: Transformation, + storage: &mut shader::Storage, + ) { + if !storage.has::() { + storage.store(Pipeline::new(device, queue, format, target_size)) + } + + let pipeline = storage.get_mut::().unwrap(); + + //upload data to GPU + pipeline.update( + device, + queue, + target_size, + &self.uniforms, + self.cubes.len(), + &self.cubes, + ); + } + + fn render( + &self, + storage: &shader::Storage, + bounds: Rectangle, + target: &wgpu::TextureView, + _target_size: Size, + encoder: &mut wgpu::CommandEncoder, + ) { + //at this point our pipeline should always be initialized + let pipeline = storage.get::().unwrap(); + + //render primitive + pipeline.render( + target, + encoder, + bounds, + self.cubes.len() as u32, + self.show_depth_buffer, + ) + } +} diff --git a/examples/custom_shader/src/primitive/buffer.rs b/examples/custom_shader/src/primitive/buffer.rs new file mode 100644 index 00000000..377ce1bb --- /dev/null +++ b/examples/custom_shader/src/primitive/buffer.rs @@ -0,0 +1,39 @@ +// A custom buffer container for dynamic resizing. +pub struct Buffer { + pub raw: wgpu::Buffer, + label: &'static str, + size: u64, + usage: wgpu::BufferUsages, +} + +impl Buffer { + pub fn new( + device: &wgpu::Device, + label: &'static str, + size: u64, + usage: wgpu::BufferUsages, + ) -> Self { + Self { + raw: device.create_buffer(&wgpu::BufferDescriptor { + label: Some(label), + size, + usage, + mapped_at_creation: false, + }), + label, + size, + usage, + } + } + + pub fn resize(&mut self, device: &wgpu::Device, new_size: u64) { + if new_size > self.size { + self.raw = device.create_buffer(&wgpu::BufferDescriptor { + label: Some(self.label), + size: new_size, + usage: self.usage, + mapped_at_creation: false, + }); + } + } +} diff --git a/examples/custom_shader/src/primitive/cube.rs b/examples/custom_shader/src/primitive/cube.rs new file mode 100644 index 00000000..c23f2132 --- /dev/null +++ b/examples/custom_shader/src/primitive/cube.rs @@ -0,0 +1,324 @@ +use crate::primitive::Vertex; +use glam::{vec2, vec3, Vec3}; +use rand::{thread_rng, Rng}; + +/// A single instance of a cube. +#[derive(Debug, Clone)] +pub struct Cube { + pub rotation: glam::Quat, + pub position: Vec3, + pub size: f32, + rotation_dir: f32, + rotation_axis: glam::Vec3, +} + +impl Default for Cube { + fn default() -> Self { + Self { + rotation: glam::Quat::IDENTITY, + position: glam::Vec3::ZERO, + size: 0.1, + rotation_dir: 1.0, + rotation_axis: glam::Vec3::Y, + } + } +} + +impl Cube { + pub fn new(size: f32, origin: Vec3) -> Self { + let rnd = thread_rng().gen_range(0.0..=1.0f32); + + Self { + rotation: glam::Quat::IDENTITY, + position: origin + Vec3::new(0.1, 0.1, 0.1), + size, + rotation_dir: if rnd <= 0.5 { -1.0 } else { 1.0 }, + rotation_axis: if rnd <= 0.33 { + glam::Vec3::Y + } else if rnd <= 0.66 { + glam::Vec3::X + } else { + glam::Vec3::Z + }, + } + } + + pub fn update(&mut self, size: f32, time: f32) { + self.rotation = glam::Quat::from_axis_angle( + self.rotation_axis, + time / 2.0 * self.rotation_dir, + ); + self.size = size; + } +} + +#[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable, Debug)] +#[repr(C)] +pub struct Raw { + transformation: glam::Mat4, + normal: glam::Mat3, + _padding: [f32; 3], +} + +impl Raw { + const ATTRIBS: [wgpu::VertexAttribute; 7] = wgpu::vertex_attr_array![ + //cube transformation matrix + 4 => Float32x4, + 5 => Float32x4, + 6 => Float32x4, + 7 => Float32x4, + //normal rotation matrix + 8 => Float32x3, + 9 => Float32x3, + 10 => Float32x3, + ]; + + pub fn desc<'a>() -> wgpu::VertexBufferLayout<'a> { + wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::VertexStepMode::Instance, + attributes: &Self::ATTRIBS, + } + } +} + +impl Raw { + pub fn from_cube(cube: &Cube) -> Raw { + Raw { + transformation: glam::Mat4::from_scale_rotation_translation( + glam::vec3(cube.size, cube.size, cube.size), + cube.rotation, + cube.position, + ), + normal: glam::Mat3::from_quat(cube.rotation), + _padding: [0.0; 3], + } + } + + pub fn vertices() -> [Vertex; 36] { + [ + //face 1 + Vertex { + pos: vec3(-0.5, -0.5, -0.5), + normal: vec3(0.0, 0.0, -1.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(0.0, 1.0), + }, + Vertex { + pos: vec3(0.5, -0.5, -0.5), + normal: vec3(0.0, 0.0, -1.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(1.0, 1.0), + }, + Vertex { + pos: vec3(0.5, 0.5, -0.5), + normal: vec3(0.0, 0.0, -1.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(1.0, 0.0), + }, + Vertex { + pos: vec3(0.5, 0.5, -0.5), + normal: vec3(0.0, 0.0, -1.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(1.0, 0.0), + }, + Vertex { + pos: vec3(-0.5, 0.5, -0.5), + normal: vec3(0.0, 0.0, -1.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(0.0, 0.0), + }, + Vertex { + pos: vec3(-0.5, -0.5, -0.5), + normal: vec3(0.0, 0.0, -1.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(0.0, 1.0), + }, + //face 2 + Vertex { + pos: vec3(-0.5, -0.5, 0.5), + normal: vec3(0.0, 0.0, 1.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(0.0, 1.0), + }, + Vertex { + pos: vec3(0.5, -0.5, 0.5), + normal: vec3(0.0, 0.0, 1.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(1.0, 1.0), + }, + Vertex { + pos: vec3(0.5, 0.5, 0.5), + normal: vec3(0.0, 0.0, 1.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(1.0, 0.0), + }, + Vertex { + pos: vec3(0.5, 0.5, 0.5), + normal: vec3(0.0, 0.0, 1.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(1.0, 0.0), + }, + Vertex { + pos: vec3(-0.5, 0.5, 0.5), + normal: vec3(0.0, 0.0, 1.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(0.0, 0.0), + }, + Vertex { + pos: vec3(-0.5, -0.5, 0.5), + normal: vec3(0.0, 0.0, 1.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(0.0, 1.0), + }, + //face 3 + Vertex { + pos: vec3(-0.5, 0.5, 0.5), + normal: vec3(-1.0, 0.0, 0.0), + tangent: vec3(0.0, 0.0, -1.0), + uv: vec2(0.0, 1.0), + }, + Vertex { + pos: vec3(-0.5, 0.5, -0.5), + normal: vec3(-1.0, 0.0, 0.0), + tangent: vec3(0.0, 0.0, -1.0), + uv: vec2(1.0, 1.0), + }, + Vertex { + pos: vec3(-0.5, -0.5, -0.5), + normal: vec3(-1.0, 0.0, 0.0), + tangent: vec3(0.0, 0.0, -1.0), + uv: vec2(1.0, 0.0), + }, + Vertex { + pos: vec3(-0.5, -0.5, -0.5), + normal: vec3(-1.0, 0.0, 0.0), + tangent: vec3(0.0, 0.0, -1.0), + uv: vec2(1.0, 0.0), + }, + Vertex { + pos: vec3(-0.5, -0.5, 0.5), + normal: vec3(-1.0, 0.0, 0.0), + tangent: vec3(0.0, 0.0, -1.0), + uv: vec2(0.0, 0.0), + }, + Vertex { + pos: vec3(-0.5, 0.5, 0.5), + normal: vec3(-1.0, 0.0, 0.0), + tangent: vec3(0.0, 0.0, -1.0), + uv: vec2(0.0, 1.0), + }, + //face 4 + Vertex { + pos: vec3(0.5, 0.5, 0.5), + normal: vec3(1.0, 0.0, 0.0), + tangent: vec3(0.0, 0.0, -1.0), + uv: vec2(0.0, 1.0), + }, + Vertex { + pos: vec3(0.5, 0.5, -0.5), + normal: vec3(1.0, 0.0, 0.0), + tangent: vec3(0.0, 0.0, -1.0), + uv: vec2(1.0, 1.0), + }, + Vertex { + pos: vec3(0.5, -0.5, -0.5), + normal: vec3(1.0, 0.0, 0.0), + tangent: vec3(0.0, 0.0, -1.0), + uv: vec2(1.0, 0.0), + }, + Vertex { + pos: vec3(0.5, -0.5, -0.5), + normal: vec3(1.0, 0.0, 0.0), + tangent: vec3(0.0, 0.0, -1.0), + uv: vec2(1.0, 0.0), + }, + Vertex { + pos: vec3(0.5, -0.5, 0.5), + normal: vec3(1.0, 0.0, 0.0), + tangent: vec3(0.0, 0.0, -1.0), + uv: vec2(0.0, 0.0), + }, + Vertex { + pos: vec3(0.5, 0.5, 0.5), + normal: vec3(1.0, 0.0, 0.0), + tangent: vec3(0.0, 0.0, -1.0), + uv: vec2(0.0, 1.0), + }, + //face 5 + Vertex { + pos: vec3(-0.5, -0.5, -0.5), + normal: vec3(0.0, -1.0, 0.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(0.0, 1.0), + }, + Vertex { + pos: vec3(0.5, -0.5, -0.5), + normal: vec3(0.0, -1.0, 0.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(1.0, 1.0), + }, + Vertex { + pos: vec3(0.5, -0.5, 0.5), + normal: vec3(0.0, -1.0, 0.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(1.0, 0.0), + }, + Vertex { + pos: vec3(0.5, -0.5, 0.5), + normal: vec3(0.0, -1.0, 0.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(1.0, 0.0), + }, + Vertex { + pos: vec3(-0.5, -0.5, 0.5), + normal: vec3(0.0, -1.0, 0.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(0.0, 0.0), + }, + Vertex { + pos: vec3(-0.5, -0.5, -0.5), + normal: vec3(0.0, -1.0, 0.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(0.0, 1.0), + }, + //face 6 + Vertex { + pos: vec3(-0.5, 0.5, -0.5), + normal: vec3(0.0, 1.0, 0.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(0.0, 1.0), + }, + Vertex { + pos: vec3(0.5, 0.5, -0.5), + normal: vec3(0.0, 1.0, 0.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(1.0, 1.0), + }, + Vertex { + pos: vec3(0.5, 0.5, 0.5), + normal: vec3(0.0, 1.0, 0.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(1.0, 0.0), + }, + Vertex { + pos: vec3(0.5, 0.5, 0.5), + normal: vec3(0.0, 1.0, 0.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(1.0, 0.0), + }, + Vertex { + pos: vec3(-0.5, 0.5, 0.5), + normal: vec3(0.0, 1.0, 0.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(0.0, 0.0), + }, + Vertex { + pos: vec3(-0.5, 0.5, -0.5), + normal: vec3(0.0, 1.0, 0.0), + tangent: vec3(1.0, 0.0, 0.0), + uv: vec2(0.0, 1.0), + }, + ] + } +} diff --git a/examples/custom_shader/src/primitive/uniforms.rs b/examples/custom_shader/src/primitive/uniforms.rs new file mode 100644 index 00000000..4fcb413b --- /dev/null +++ b/examples/custom_shader/src/primitive/uniforms.rs @@ -0,0 +1,22 @@ +use crate::camera::Camera; +use iced::{Color, Rectangle}; + +#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] +#[repr(C)] +pub struct Uniforms { + camera_proj: glam::Mat4, + camera_pos: glam::Vec4, + light_color: glam::Vec4, +} + +impl Uniforms { + pub fn new(camera: &Camera, bounds: Rectangle, light_color: Color) -> Self { + let camera_proj = camera.build_view_proj_matrix(bounds); + + Self { + camera_proj, + camera_pos: camera.position(), + light_color: glam::Vec4::from(light_color.into_linear()), + } + } +} diff --git a/examples/custom_shader/src/primitive/vertex.rs b/examples/custom_shader/src/primitive/vertex.rs new file mode 100644 index 00000000..6d17aa0f --- /dev/null +++ b/examples/custom_shader/src/primitive/vertex.rs @@ -0,0 +1,29 @@ +#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] +#[repr(C)] +pub struct Vertex { + pub pos: glam::Vec3, + pub normal: glam::Vec3, + pub tangent: glam::Vec3, + pub uv: glam::Vec2, +} + +impl Vertex { + const ATTRIBS: [wgpu::VertexAttribute; 4] = wgpu::vertex_attr_array![ + //position + 0 => Float32x3, + //normal + 1 => Float32x3, + //tangent + 2 => Float32x3, + //uv + 3 => Float32x2, + ]; + + pub fn desc<'a>() -> wgpu::VertexBufferLayout<'a> { + wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &Self::ATTRIBS, + } + } +} diff --git a/examples/custom_shader/src/shaders/cubes.wgsl b/examples/custom_shader/src/shaders/cubes.wgsl new file mode 100644 index 00000000..cd7f94d8 --- /dev/null +++ b/examples/custom_shader/src/shaders/cubes.wgsl @@ -0,0 +1,123 @@ +struct Uniforms { + projection: mat4x4, + camera_pos: vec4, + light_color: vec4, +} + +const LIGHT_POS: vec3 = vec3(0.0, 3.0, 3.0); + +@group(0) @binding(0) var uniforms: Uniforms; +@group(0) @binding(1) var sky_texture: texture_cube; +@group(0) @binding(2) var tex_sampler: sampler; +@group(0) @binding(3) var normal_texture: texture_2d; + +struct Vertex { + @location(0) position: vec3, + @location(1) normal: vec3, + @location(2) tangent: vec3, + @location(3) uv: vec2, +} + +struct Cube { + @location(4) matrix_0: vec4, + @location(5) matrix_1: vec4, + @location(6) matrix_2: vec4, + @location(7) matrix_3: vec4, + @location(8) normal_matrix_0: vec3, + @location(9) normal_matrix_1: vec3, + @location(10) normal_matrix_2: vec3, +} + +struct Output { + @builtin(position) clip_pos: vec4, + @location(0) uv: vec2, + @location(1) tangent_pos: vec3, + @location(2) tangent_camera_pos: vec3, + @location(3) tangent_light_pos: vec3, +} + +@vertex +fn vs_main(vertex: Vertex, cube: Cube) -> Output { + let cube_matrix = mat4x4( + cube.matrix_0, + cube.matrix_1, + cube.matrix_2, + cube.matrix_3, + ); + + let normal_matrix = mat3x3( + cube.normal_matrix_0, + cube.normal_matrix_1, + cube.normal_matrix_2, + ); + + //convert to tangent space to calculate lighting in same coordinate space as normal map sample + let tangent = normalize(normal_matrix * vertex.tangent); + let normal = normalize(normal_matrix * vertex.normal); + let bitangent = cross(tangent, normal); + + //shift everything into tangent space + let tbn = transpose(mat3x3(tangent, bitangent, normal)); + + let world_pos = cube_matrix * vec4(vertex.position, 1.0); + + var out: Output; + out.clip_pos = uniforms.projection * world_pos; + out.uv = vertex.uv; + out.tangent_pos = tbn * world_pos.xyz; + out.tangent_camera_pos = tbn * uniforms.camera_pos.xyz; + out.tangent_light_pos = tbn * LIGHT_POS; + + return out; +} + +//cube properties +const CUBE_BASE_COLOR: vec4 = vec4(0.294118, 0.462745, 0.611765, 0.6); +const SHINE_DAMPER: f32 = 1.0; +const REFLECTIVITY: f32 = 0.8; +const REFRACTION_INDEX: f32 = 1.31; + +//fog, for the ~* cinematic effect *~ +const FOG_DENSITY: f32 = 0.15; +const FOG_GRADIENT: f32 = 8.0; +const FOG_COLOR: vec4 = vec4(1.0, 1.0, 1.0, 1.0); + +@fragment +fn fs_main(in: Output) -> @location(0) vec4 { + let to_camera = in.tangent_camera_pos - in.tangent_pos; + + //normal sample from texture + var normal = textureSample(normal_texture, tex_sampler, in.uv).xyz; + normal = normal * 2.0 - 1.0; + + //diffuse + let dir_to_light: vec3 = normalize(in.tangent_light_pos - in.tangent_pos); + let brightness = max(dot(normal, dir_to_light), 0.0); + let diffuse: vec3 = brightness * uniforms.light_color.xyz; + + //specular + let dir_to_camera = normalize(to_camera); + let light_dir = -dir_to_light; + let reflected_light_dir = reflect(light_dir, normal); + let specular_factor = max(dot(reflected_light_dir, dir_to_camera), 0.0); + let damped_factor = pow(specular_factor, SHINE_DAMPER); + let specular: vec3 = damped_factor * uniforms.light_color.xyz * REFLECTIVITY; + + //fog + let distance = length(to_camera); + let visibility = clamp(exp(-pow((distance * FOG_DENSITY), FOG_GRADIENT)), 0.0, 1.0); + + //reflection + let reflection_dir = reflect(dir_to_camera, normal); + let reflection_color = textureSample(sky_texture, tex_sampler, reflection_dir); + let refraction_dir = refract(dir_to_camera, normal, REFRACTION_INDEX); + let refraction_color = textureSample(sky_texture, tex_sampler, refraction_dir); + let final_reflect_color = mix(reflection_color, refraction_color, 0.5); + + //mix it all together! + var color = vec4(CUBE_BASE_COLOR.xyz * diffuse + specular, CUBE_BASE_COLOR.w); + color = mix(color, final_reflect_color, 0.8); + color = mix(FOG_COLOR, color, visibility); + + return color; +} diff --git a/examples/custom_shader/src/shaders/depth.wgsl b/examples/custom_shader/src/shaders/depth.wgsl new file mode 100644 index 00000000..a3f7e5ec --- /dev/null +++ b/examples/custom_shader/src/shaders/depth.wgsl @@ -0,0 +1,48 @@ +var positions: array, 6> = array, 6>( + vec2(-1.0, 1.0), + vec2(-1.0, -1.0), + vec2(1.0, -1.0), + vec2(-1.0, 1.0), + vec2(1.0, 1.0), + vec2(1.0, -1.0) +); + +var uvs: array, 6> = array, 6>( + vec2(0.0, 0.0), + vec2(0.0, 1.0), + vec2(1.0, 1.0), + vec2(0.0, 0.0), + vec2(1.0, 0.0), + vec2(1.0, 1.0) +); + +@group(0) @binding(0) var depth_sampler: sampler; +@group(0) @binding(1) var depth_texture: texture_2d; + +struct Output { + @builtin(position) position: vec4, + @location(0) uv: vec2, +} + +@vertex +fn vs_main(@builtin(vertex_index) v_index: u32) -> Output { + var out: Output; + + out.position = vec4(positions[v_index], 0.0, 1.0); + out.uv = uvs[v_index]; + + return out; +} + +@fragment +fn fs_main(input: Output) -> @location(0) vec4 { + let depth = textureSample(depth_texture, depth_sampler, input.uv).r; + + if (depth > .9999) { + discard; + } + + let c = 1.0 - depth; + + return vec4(c, c, c, 1.0); +} diff --git a/examples/custom_shader/src/textures/ice_cube_normal_map.png b/examples/custom_shader/src/textures/ice_cube_normal_map.png new file mode 100644 index 0000000000000000000000000000000000000000..7b4b7228a7d5404fa8c062d4894875d4f9f9974c GIT binary patch literal 1773656 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ä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

OPP}vRCrf|a8HQ>@rgQ(#O=$`I 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

ZCwCv_4eOacalrR^?ls_8Td-$K0FN2h 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 Date: Thu, 13 Jul 2023 14:30:54 +0100 Subject: [PATCH 026/321] Swap unwrap_or_else to unwrap_or_default --- widget/src/combo_box.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs index 262f83a8..23839980 100644 --- a/widget/src/combo_box.rs +++ b/widget/src/combo_box.rs @@ -58,7 +58,7 @@ where let text_input = TextInput::new(placeholder, &state.value()) .on_input(TextInputEvent::TextChanged); - let selection = selection.map(T::to_string).unwrap_or_else(String::new); + let selection = selection.map(T::to_string).unwrap_or_default(); Self { state, @@ -204,7 +204,7 @@ where /// Creates a new [`State`] for a [`ComboBox`] with the given list of options /// and selected value. pub fn with_selection(options: Vec, selection: Option<&T>) -> Self { - let value = selection.map(T::to_string).unwrap_or_else(String::new); + let value = selection.map(T::to_string).unwrap_or_default(); // Pre-build "matcher" strings ahead of time so that search is fast let option_matchers = build_matchers(&options); From 14fb723eecdf3ee667874882210ac826aa700919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 26 Jul 2023 22:01:17 +0200 Subject: [PATCH 027/321] Add `Viewport` to `on_event` for `ComboBox` --- widget/src/combo_box.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs index 23839980..956a470a 100644 --- a/widget/src/combo_box.rs +++ b/widget/src/combo_box.rs @@ -394,6 +394,7 @@ where renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + viewport: &Rectangle, ) -> event::Status { let menu = tree.state.downcast_mut::>(); @@ -416,6 +417,7 @@ where renderer, clipboard, &mut local_shell, + viewport, ); self.state.update_text_input(tree); @@ -554,6 +556,7 @@ where renderer, clipboard, &mut Shell::new(&mut vec![]), + viewport, ); state.update_text_input(tree); } From 9eb2889d09e42b250f12be9ba9ef8a470d8eeeae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 26 Jul 2023 22:33:33 +0200 Subject: [PATCH 028/321] Use default padding of `TextInput` in `ComboBox` --- widget/src/combo_box.rs | 2 +- widget/src/text_input.rs | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs index 956a470a..91a91c32 100644 --- a/widget/src/combo_box.rs +++ b/widget/src/combo_box.rs @@ -70,7 +70,7 @@ where on_input: None, on_blur: None, menu_style: Default::default(), - padding: Padding::new(0.0), + padding: text_input::DEFAULT_PADDING, size: None, } } diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index 9958cbcc..b899eb67 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -76,6 +76,9 @@ where style: ::Style, } +/// The default [`Padding`] of a [`TextInput`]. +pub const DEFAULT_PADDING: Padding = Padding::new(5.0); + impl<'a, Message, Renderer> TextInput<'a, Message, Renderer> where Message: Clone, @@ -95,7 +98,7 @@ where is_secure: false, font: None, width: Length::Fill, - padding: Padding::new(5.0), + padding: DEFAULT_PADDING, size: None, line_height: text::LineHeight::default(), on_input: None, From 28d32a8b6463b5756aa7cc497c1e26e173f70bee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 26 Jul 2023 22:34:56 +0200 Subject: [PATCH 029/321] Fix `on_option_hovered` support in `ComboBox` --- examples/combo_box/src/main.rs | 20 ++++++++-------- widget/src/combo_box.rs | 42 +++++++++++++++++++++++++--------- widget/src/overlay/menu.rs | 23 +++++++++++++++++-- widget/src/pick_list.rs | 1 + 4 files changed, 63 insertions(+), 23 deletions(-) diff --git a/examples/combo_box/src/main.rs b/examples/combo_box/src/main.rs index 22d05132..2e6f95d5 100644 --- a/examples/combo_box/src/main.rs +++ b/examples/combo_box/src/main.rs @@ -15,9 +15,9 @@ struct Example { #[derive(Debug, Clone, Copy)] enum Message { - LanguageSelected(Language), - LanguagePreview(Language), - LanguageBlurred, + Selected(Language), + OptionHovered(Language), + Closed, } impl Sandbox for Example { @@ -37,15 +37,15 @@ impl Sandbox for Example { fn update(&mut self, message: Message) { match message { - Message::LanguageSelected(language) => { + Message::Selected(language) => { self.selected_language = Some(language); self.text = language.hello().to_string(); self.languages.unfocus(); } - Message::LanguagePreview(language) => { + Message::OptionHovered(language) => { self.text = language.hello().to_string(); } - Message::LanguageBlurred => { + Message::Closed => { self.text = self .selected_language .map(|language| language.hello().to_string()) @@ -59,17 +59,17 @@ impl Sandbox for Example { &self.languages, "Type a language...", self.selected_language.as_ref(), - Message::LanguageSelected, + Message::Selected, ) - .on_selection(Message::LanguagePreview) - .on_blur(Message::LanguageBlurred) + .on_option_hovered(Message::OptionHovered) + .on_close(Message::Closed) .width(250); let content = column![ + text(&self.text), "What is your language?", combo_box, vertical_space(150), - text(&self.text), ] .width(Length::Fill) .align_items(Alignment::Center) diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs index 91a91c32..14fe2528 100644 --- a/widget/src/combo_box.rs +++ b/widget/src/combo_box.rs @@ -32,8 +32,8 @@ where font: Option, selection: text_input::Value, on_selected: Box Message>, - on_selection: Option Message>>, - on_blur: Option, + on_option_hovered: Option Message>>, + on_close: Option, on_input: Option Message>>, menu_style: ::Style, padding: Padding, @@ -66,9 +66,9 @@ where font: None, selection: text_input::Value::new(&selection), on_selected: Box::new(on_selected), - on_selection: None, + on_option_hovered: None, on_input: None, - on_blur: None, + on_close: None, menu_style: Default::default(), padding: text_input::DEFAULT_PADDING, size: None, @@ -87,18 +87,18 @@ where /// Sets the message that will be produced when an option of the /// [`ComboBox`] is hovered using the arrow keys. - pub fn on_selection( + pub fn on_option_hovered( mut self, on_selection: impl Fn(T) -> Message + 'static, ) -> Self { - self.on_selection = Some(Box::new(on_selection)); + self.on_option_hovered = Some(Box::new(on_selection)); self } /// Sets the message that will be produced when the outside area /// of the [`ComboBox`] is pressed. - pub fn on_blur(mut self, message: Message) -> Self { - self.on_blur = Some(message); + pub fn on_close(mut self, message: Message) -> Self { + self.on_close = Some(message); self } @@ -424,6 +424,7 @@ where // Then finally react to them here for message in local_messages { let TextInputEvent::TextChanged(new_value) = message; + if let Some(on_input) = &self.on_input { shell.publish((on_input)(new_value.clone())); published_message_to_shell = true; @@ -451,6 +452,20 @@ where if self.state.is_focused() { self.state.with_inner(|state| { + if !started_focused { + if let Some(on_option_hovered) = &mut self.on_option_hovered + { + let hovered_option = menu.hovered_option.unwrap_or(0); + + if let Some(option) = + state.filtered_options.options.get(hovered_option) + { + shell.publish(on_option_hovered(option.clone())); + published_message_to_shell = true; + } + } + } + if let Event::Keyboard(keyboard::Event::KeyPressed { key_code, .. @@ -475,7 +490,9 @@ where menu.hovered_option = Some(0); } - if let Some(on_selection) = &mut self.on_selection { + if let Some(on_selection) = + &mut self.on_option_hovered + { if let Some(option) = menu.hovered_option.and_then(|index| { state @@ -507,7 +524,9 @@ where menu.hovered_option = Some(0); } - if let Some(on_selection) = &mut self.on_selection { + if let Some(on_selection) = + &mut self.on_option_hovered + { if let Some(option) = menu.hovered_option.and_then(|index| { state @@ -566,7 +585,7 @@ where && !self.state.is_focused() && !published_message_to_shell { - if let Some(message) = self.on_blur.take() { + if let Some(message) = self.on_close.take() { shell.publish(message); } } @@ -637,6 +656,7 @@ where &filtered_options.options, hovered_option, |x| (self.on_selected)(x), + self.on_option_hovered.as_deref(), ) .width(bounds.width) .padding(self.padding) diff --git a/widget/src/overlay/menu.rs b/widget/src/overlay/menu.rs index 72662422..f7bdeef6 100644 --- a/widget/src/overlay/menu.rs +++ b/widget/src/overlay/menu.rs @@ -28,6 +28,7 @@ where options: &'a [T], hovered_option: &'a mut Option, on_selected: Box Message + 'a>, + on_option_hovered: Option<&'a dyn Fn(T) -> Message>, width: f32, padding: Padding, text_size: Option, @@ -52,12 +53,14 @@ where options: &'a [T], hovered_option: &'a mut Option, on_selected: impl FnMut(T) -> Message + 'a, + on_option_hovered: Option<&'a dyn Fn(T) -> Message>, ) -> Self { Menu { state, options, hovered_option, on_selected: Box::new(on_selected), + on_option_hovered, width: 0.0, padding: Padding::ZERO, text_size: None, @@ -187,6 +190,7 @@ where options, hovered_option, on_selected, + on_option_hovered, width, padding, font, @@ -200,6 +204,7 @@ where options, hovered_option, on_selected, + on_option_hovered, font, text_size, text_line_height, @@ -321,6 +326,7 @@ where options: &'a [T], hovered_option: &'a mut Option, on_selected: Box Message + 'a>, + on_option_hovered: Option<&'a dyn Fn(T) -> Message>, padding: Padding, text_size: Option, text_line_height: text::LineHeight, @@ -405,8 +411,21 @@ where self.text_line_height.to_absolute(Pixels(text_size)), ) + self.padding.vertical(); - *self.hovered_option = - Some((cursor_position.y / option_height) as usize); + let new_hovered_option = + (cursor_position.y / option_height) as usize; + + if let Some(on_option_hovered) = self.on_option_hovered { + if *self.hovered_option != Some(new_hovered_option) { + if let Some(option) = + self.options.get(new_hovered_option) + { + shell + .publish(on_option_hovered(option.clone())); + } + } + } + + *self.hovered_option = Some(new_hovered_option); } } Event::Touch(touch::Event::FingerPressed { .. }) => { diff --git a/widget/src/pick_list.rs b/widget/src/pick_list.rs index d99ada10..0a1e2a99 100644 --- a/widget/src/pick_list.rs +++ b/widget/src/pick_list.rs @@ -566,6 +566,7 @@ where (on_selected)(option) }, + None, ) .width(bounds.width) .padding(padding) From 559ebdbb3a0b90ff28f361f5466f17178b6d8137 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 26 Jul 2023 22:35:42 +0200 Subject: [PATCH 030/321] Update `CHANGELOG` --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3036af4f..d6a989f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Nested overlays. [#1719](https://github.com/iced-rs/iced/pull/1719) - Cursor availability. [#1904](https://github.com/iced-rs/iced/pull/1904) - Backend-specific primitives. [#1932](https://github.com/iced-rs/iced/pull/1932) +- `ComboBox` widget. [#1954](https://github.com/iced-rs/iced/pull/1954) - `web-colors` feature flag to enable "sRGB linear" blending. [#1888](https://github.com/iced-rs/iced/pull/1888) - `PaneGrid` logic to split panes by drag & drop. [#1856](https://github.com/iced-rs/iced/pull/1856) - `PaneGrid` logic to drag & drop panes to the edges. [#1865](https://github.com/iced-rs/iced/pull/1865) From e29754f32d03efc4b075e9b63cc554d128bc2ccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 26 Jul 2023 22:36:50 +0200 Subject: [PATCH 031/321] Rename `on_selection` to `on_option_hovered` in `combo_box` --- widget/src/combo_box.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs index 14fe2528..93fc92b9 100644 --- a/widget/src/combo_box.rs +++ b/widget/src/combo_box.rs @@ -89,9 +89,9 @@ where /// [`ComboBox`] is hovered using the arrow keys. pub fn on_option_hovered( mut self, - on_selection: impl Fn(T) -> Message + 'static, + on_option_hovered: impl Fn(T) -> Message + 'static, ) -> Self { - self.on_option_hovered = Some(Box::new(on_selection)); + self.on_option_hovered = Some(Box::new(on_option_hovered)); self } @@ -490,7 +490,7 @@ where menu.hovered_option = Some(0); } - if let Some(on_selection) = + if let Some(on_option_hovered) = &mut self.on_option_hovered { if let Some(option) = @@ -502,7 +502,7 @@ where }) { // Notify the selection - shell.publish((on_selection)( + shell.publish((on_option_hovered)( option.clone(), )); published_message_to_shell = true; @@ -524,7 +524,7 @@ where menu.hovered_option = Some(0); } - if let Some(on_selection) = + if let Some(on_option_hovered) = &mut self.on_option_hovered { if let Some(option) = @@ -536,7 +536,7 @@ where }) { // Notify the selection - shell.publish((on_selection)( + shell.publish((on_option_hovered)( option.clone(), )); published_message_to_shell = true; From e2ba7ece83f141c149659747977147392df008f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 27 Jul 2023 01:02:28 +0200 Subject: [PATCH 032/321] Introduce `visible_bounds` operation for `Container` --- core/src/element.rs | 11 ++- core/src/overlay/element.rs | 7 +- core/src/overlay/group.rs | 2 +- core/src/rectangle.rs | 15 ++++ core/src/widget/operation.rs | 32 +++++++-- core/src/widget/operation/focusable.rs | 6 ++ core/src/widget/operation/scrollable.rs | 19 ++++- core/src/widget/operation/text_input.rs | 5 ++ examples/toast/src/main.rs | 4 +- widget/src/button.rs | 2 +- widget/src/column.rs | 2 +- widget/src/container.rs | 93 ++++++++++++++++++++++++- widget/src/lazy/component.rs | 10 ++- widget/src/pane_grid.rs | 2 +- widget/src/row.rs | 2 +- widget/src/scrollable.rs | 14 +++- 16 files changed, 201 insertions(+), 25 deletions(-) diff --git a/core/src/element.rs b/core/src/element.rs index b9b76247..d2c6358b 100644 --- a/core/src/element.rs +++ b/core/src/element.rs @@ -5,7 +5,9 @@ use crate::overlay; use crate::renderer; use crate::widget; use crate::widget::tree::{self, Tree}; -use crate::{Clipboard, Color, Layout, Length, Rectangle, Shell, Widget}; +use crate::{ + Clipboard, Color, Layout, Length, Rectangle, Shell, Vector, Widget, +}; use std::any::Any; use std::borrow::Borrow; @@ -325,11 +327,12 @@ where fn container( &mut self, id: Option<&widget::Id>, + bounds: Rectangle, operate_on_children: &mut dyn FnMut( &mut dyn widget::Operation, ), ) { - self.operation.container(id, &mut |operation| { + self.operation.container(id, bounds, &mut |operation| { operate_on_children(&mut MapOperation { operation }); }); } @@ -346,8 +349,10 @@ where &mut self, state: &mut dyn widget::operation::Scrollable, id: Option<&widget::Id>, + bounds: Rectangle, + translation: Vector, ) { - self.operation.scrollable(state, id); + self.operation.scrollable(state, id, bounds, translation); } fn text_input( diff --git a/core/src/overlay/element.rs b/core/src/overlay/element.rs index c2134343..29b404b8 100644 --- a/core/src/overlay/element.rs +++ b/core/src/overlay/element.rs @@ -172,11 +172,12 @@ where fn container( &mut self, id: Option<&widget::Id>, + bounds: Rectangle, operate_on_children: &mut dyn FnMut( &mut dyn widget::Operation, ), ) { - self.operation.container(id, &mut |operation| { + self.operation.container(id, bounds, &mut |operation| { operate_on_children(&mut MapOperation { operation }); }); } @@ -193,8 +194,10 @@ where &mut self, state: &mut dyn widget::operation::Scrollable, id: Option<&widget::Id>, + bounds: Rectangle, + translation: Vector, ) { - self.operation.scrollable(state, id); + self.operation.scrollable(state, id, bounds, translation); } fn text_input( diff --git a/core/src/overlay/group.rs b/core/src/overlay/group.rs index deffaad0..691686cd 100644 --- a/core/src/overlay/group.rs +++ b/core/src/overlay/group.rs @@ -138,7 +138,7 @@ where renderer: &Renderer, operation: &mut dyn widget::Operation, ) { - operation.container(None, &mut |operation| { + operation.container(None, layout.bounds(), &mut |operation| { self.children.iter_mut().zip(layout.children()).for_each( |(child, layout)| { child.operate(layout, renderer, operation); diff --git a/core/src/rectangle.rs b/core/src/rectangle.rs index 7ff324cb..db56aa18 100644 --- a/core/src/rectangle.rs +++ b/core/src/rectangle.rs @@ -197,3 +197,18 @@ where } } } + +impl std::ops::Sub> for Rectangle +where + T: std::ops::Sub, +{ + type Output = Rectangle; + + fn sub(self, translation: Vector) -> Self { + Rectangle { + x: self.x - translation.x, + y: self.y - translation.y, + ..self + } + } +} diff --git a/core/src/widget/operation.rs b/core/src/widget/operation.rs index ad188c36..b91cf9ac 100644 --- a/core/src/widget/operation.rs +++ b/core/src/widget/operation.rs @@ -8,6 +8,7 @@ pub use scrollable::Scrollable; pub use text_input::TextInput; use crate::widget::Id; +use crate::{Rectangle, Vector}; use std::any::Any; use std::fmt; @@ -23,6 +24,7 @@ pub trait Operation { fn container( &mut self, id: Option<&Id>, + bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ); @@ -30,7 +32,14 @@ pub trait Operation { fn focusable(&mut self, _state: &mut dyn Focusable, _id: Option<&Id>) {} /// Operates on a widget that can be scrolled. - fn scrollable(&mut self, _state: &mut dyn Scrollable, _id: Option<&Id>) {} + fn scrollable( + &mut self, + _state: &mut dyn Scrollable, + _id: Option<&Id>, + _bounds: Rectangle, + _translation: Vector, + ) { + } /// Operates on a widget that has text input. fn text_input(&mut self, _state: &mut dyn TextInput, _id: Option<&Id>) {} @@ -92,6 +101,7 @@ where fn container( &mut self, id: Option<&Id>, + bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { struct MapRef<'a, A> { @@ -102,11 +112,12 @@ where fn container( &mut self, id: Option<&Id>, + bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { let Self { operation, .. } = self; - operation.container(id, &mut |operation| { + operation.container(id, bounds, &mut |operation| { operate_on_children(&mut MapRef { operation }); }); } @@ -115,8 +126,10 @@ where &mut self, state: &mut dyn Scrollable, id: Option<&Id>, + bounds: Rectangle, + translation: Vector, ) { - self.operation.scrollable(state, id); + self.operation.scrollable(state, id, bounds, translation); } fn focusable( @@ -145,15 +158,21 @@ where MapRef { operation: operation.as_mut(), } - .container(id, operate_on_children); + .container(id, bounds, operate_on_children); } fn focusable(&mut self, state: &mut dyn Focusable, id: Option<&Id>) { self.operation.focusable(state, id); } - fn scrollable(&mut self, state: &mut dyn Scrollable, id: Option<&Id>) { - self.operation.scrollable(state, id); + fn scrollable( + &mut self, + state: &mut dyn Scrollable, + id: Option<&Id>, + bounds: Rectangle, + translation: Vector, + ) { + self.operation.scrollable(state, id, bounds, translation); } fn text_input(&mut self, state: &mut dyn TextInput, id: Option<&Id>) { @@ -197,6 +216,7 @@ pub fn scope( fn container( &mut self, id: Option<&Id>, + _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { if id == Some(&self.target) { diff --git a/core/src/widget/operation/focusable.rs b/core/src/widget/operation/focusable.rs index 312e4894..ab1b677e 100644 --- a/core/src/widget/operation/focusable.rs +++ b/core/src/widget/operation/focusable.rs @@ -1,6 +1,7 @@ //! Operate on widgets that can be focused. use crate::widget::operation::{Operation, Outcome}; use crate::widget::Id; +use crate::Rectangle; /// The internal state of a widget that can be focused. pub trait Focusable { @@ -45,6 +46,7 @@ pub fn focus(target: Id) -> impl Operation { fn container( &mut self, _id: Option<&Id>, + _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { operate_on_children(self) @@ -80,6 +82,7 @@ where fn container( &mut self, _id: Option<&Id>, + _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { operate_on_children(self) @@ -126,6 +129,7 @@ pub fn focus_previous() -> impl Operation { fn container( &mut self, _id: Option<&Id>, + _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { operate_on_children(self) @@ -159,6 +163,7 @@ pub fn focus_next() -> impl Operation { fn container( &mut self, _id: Option<&Id>, + _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { operate_on_children(self) @@ -185,6 +190,7 @@ pub fn find_focused() -> impl Operation { fn container( &mut self, _id: Option<&Id>, + _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { operate_on_children(self) diff --git a/core/src/widget/operation/scrollable.rs b/core/src/widget/operation/scrollable.rs index f947344d..4f8b2a98 100644 --- a/core/src/widget/operation/scrollable.rs +++ b/core/src/widget/operation/scrollable.rs @@ -1,5 +1,6 @@ //! Operate on widgets that can be scrolled. use crate::widget::{Id, Operation}; +use crate::{Rectangle, Vector}; /// The internal state of a widget that can be scrolled. pub trait Scrollable { @@ -22,12 +23,19 @@ pub fn snap_to(target: Id, offset: RelativeOffset) -> impl Operation { fn container( &mut self, _id: Option<&Id>, + _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { operate_on_children(self) } - fn scrollable(&mut self, state: &mut dyn Scrollable, id: Option<&Id>) { + fn scrollable( + &mut self, + state: &mut dyn Scrollable, + id: Option<&Id>, + _bounds: Rectangle, + _translation: Vector, + ) { if Some(&self.target) == id { state.snap_to(self.offset); } @@ -49,12 +57,19 @@ pub fn scroll_to(target: Id, offset: AbsoluteOffset) -> impl Operation { fn container( &mut self, _id: Option<&Id>, + _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { operate_on_children(self) } - fn scrollable(&mut self, state: &mut dyn Scrollable, id: Option<&Id>) { + fn scrollable( + &mut self, + state: &mut dyn Scrollable, + id: Option<&Id>, + _bounds: Rectangle, + _translation: Vector, + ) { if Some(&self.target) == id { state.scroll_to(self.offset); } diff --git a/core/src/widget/operation/text_input.rs b/core/src/widget/operation/text_input.rs index 4c773e99..a9ea2e81 100644 --- a/core/src/widget/operation/text_input.rs +++ b/core/src/widget/operation/text_input.rs @@ -1,6 +1,7 @@ //! Operate on widgets that have text input. use crate::widget::operation::Operation; use crate::widget::Id; +use crate::Rectangle; /// The internal state of a widget that has text input. pub trait TextInput { @@ -34,6 +35,7 @@ pub fn move_cursor_to_front(target: Id) -> impl Operation { fn container( &mut self, _id: Option<&Id>, + _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { operate_on_children(self) @@ -63,6 +65,7 @@ pub fn move_cursor_to_end(target: Id) -> impl Operation { fn container( &mut self, _id: Option<&Id>, + _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { operate_on_children(self) @@ -93,6 +96,7 @@ pub fn move_cursor_to(target: Id, position: usize) -> impl Operation { fn container( &mut self, _id: Option<&Id>, + _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { operate_on_children(self) @@ -121,6 +125,7 @@ pub fn select_all(target: Id) -> impl Operation { fn container( &mut self, _id: Option<&Id>, + _bounds: Rectangle, operate_on_children: &mut dyn FnMut(&mut dyn Operation), ) { operate_on_children(self) diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs index 5d29e895..42f6c348 100644 --- a/examples/toast/src/main.rs +++ b/examples/toast/src/main.rs @@ -381,7 +381,7 @@ mod toast { renderer: &Renderer, operation: &mut dyn Operation, ) { - operation.container(None, &mut |operation| { + operation.container(None, layout.bounds(), &mut |operation| { self.content.as_widget().operate( &mut state.children[0], layout, @@ -622,7 +622,7 @@ mod toast { renderer: &Renderer, operation: &mut dyn widget::Operation, ) { - operation.container(None, &mut |operation| { + operation.container(None, layout.bounds(), &mut |operation| { self.toasts .iter() .zip(self.state.iter_mut()) diff --git a/widget/src/button.rs b/widget/src/button.rs index 1312095f..5727c631 100644 --- a/widget/src/button.rs +++ b/widget/src/button.rs @@ -181,7 +181,7 @@ where renderer: &Renderer, operation: &mut dyn Operation, ) { - operation.container(None, &mut |operation| { + operation.container(None, layout.bounds(), &mut |operation| { self.content.as_widget().operate( &mut tree.children[0], layout.children().next().unwrap(), diff --git a/widget/src/column.rs b/widget/src/column.rs index 9271d5ef..c16477f3 100644 --- a/widget/src/column.rs +++ b/widget/src/column.rs @@ -148,7 +148,7 @@ where renderer: &Renderer, operation: &mut dyn Operation, ) { - operation.container(None, &mut |operation| { + operation.container(None, layout.bounds(), &mut |operation| { self.children .iter() .zip(&mut tree.children) diff --git a/widget/src/container.rs b/widget/src/container.rs index 64cf5cd5..1f1df861 100644 --- a/widget/src/container.rs +++ b/widget/src/container.rs @@ -8,8 +8,9 @@ use crate::core::renderer; use crate::core::widget::{self, Operation, Tree}; use crate::core::{ Background, Clipboard, Color, Element, Layout, Length, Padding, Pixels, - Point, Rectangle, Shell, Widget, + Point, Rectangle, Shell, Size, Vector, Widget, }; +use crate::runtime::Command; pub use iced_style::container::{Appearance, StyleSheet}; @@ -180,6 +181,7 @@ where ) { operation.container( self.id.as_ref().map(|id| &id.0), + layout.bounds(), &mut |operation| { self.content.as_widget().operate( &mut tree.children[0], @@ -368,3 +370,92 @@ impl From for widget::Id { id.0 } } + +/// Produces a [`Command`] that queries the visible screen bounds of the +/// [`Container`] with the given [`Id`]. +pub fn visible_bounds(id: Id) -> Command> { + struct VisibleBounds { + target: widget::Id, + depth: usize, + scrollables: Vec<(Vector, Rectangle, usize)>, + bounds: Option, + } + + impl Operation> for VisibleBounds { + fn scrollable( + &mut self, + _state: &mut dyn widget::operation::Scrollable, + _id: Option<&widget::Id>, + bounds: Rectangle, + translation: Vector, + ) { + match self.scrollables.last() { + Some((last_translation, last_viewport, _depth)) => { + let viewport = last_viewport + .intersection(&(bounds - *last_translation)) + .unwrap_or(Rectangle::new(Point::ORIGIN, Size::ZERO)); + + self.scrollables.push(( + translation + *last_translation, + viewport, + self.depth, + )); + } + None => { + self.scrollables.push((translation, bounds, self.depth)); + } + } + } + + fn container( + &mut self, + id: Option<&widget::Id>, + bounds: Rectangle, + operate_on_children: &mut dyn FnMut( + &mut dyn Operation>, + ), + ) { + if self.bounds.is_some() { + return; + } + + if id == Some(&self.target) { + match self.scrollables.last() { + Some((translation, viewport, _)) => { + self.bounds = + viewport.intersection(&(bounds - *translation)); + } + None => { + self.bounds = Some(bounds); + } + } + + return; + } + + self.depth += 1; + + operate_on_children(self); + + self.depth -= 1; + + match self.scrollables.last() { + Some((_, _, depth)) if self.depth == *depth => { + let _ = self.scrollables.pop(); + } + _ => {} + } + } + + fn finish(&self) -> widget::operation::Outcome> { + widget::operation::Outcome::Some(self.bounds) + } + } + + Command::widget(VisibleBounds { + target: id.into(), + depth: 0, + scrollables: Vec::new(), + bounds: None, + }) +} diff --git a/widget/src/lazy/component.rs b/widget/src/lazy/component.rs index bc0e23df..19df2792 100644 --- a/widget/src/lazy/component.rs +++ b/widget/src/lazy/component.rs @@ -7,7 +7,8 @@ use crate::core::renderer; use crate::core::widget; use crate::core::widget::tree::{self, Tree}; use crate::core::{ - self, Clipboard, Element, Length, Point, Rectangle, Shell, Size, Widget, + self, Clipboard, Element, Length, Point, Rectangle, Shell, Size, Vector, + Widget, }; use crate::runtime::overlay::Nested; @@ -340,11 +341,12 @@ where fn container( &mut self, id: Option<&widget::Id>, + bounds: Rectangle, operate_on_children: &mut dyn FnMut( &mut dyn widget::Operation, ), ) { - self.operation.container(id, &mut |operation| { + self.operation.container(id, bounds, &mut |operation| { operate_on_children(&mut MapOperation { operation }); }); } @@ -369,8 +371,10 @@ where &mut self, state: &mut dyn widget::operation::Scrollable, id: Option<&widget::Id>, + bounds: Rectangle, + translation: Vector, ) { - self.operation.scrollable(state, id); + self.operation.scrollable(state, id, bounds, translation); } fn custom( diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs index 4f6dfbe8..0f4ab9eb 100644 --- a/widget/src/pane_grid.rs +++ b/widget/src/pane_grid.rs @@ -297,7 +297,7 @@ where renderer: &Renderer, operation: &mut dyn widget::Operation, ) { - operation.container(None, &mut |operation| { + operation.container(None, layout.bounds(), &mut |operation| { self.contents .iter() .zip(&mut tree.children) diff --git a/widget/src/row.rs b/widget/src/row.rs index 7baaaae3..99b2a0bf 100644 --- a/widget/src/row.rs +++ b/widget/src/row.rs @@ -137,7 +137,7 @@ where renderer: &Renderer, operation: &mut dyn Operation, ) { - operation.container(None, &mut |operation| { + operation.container(None, layout.bounds(), &mut |operation| { self.children .iter() .zip(&mut tree.children) diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index f621fb26..103e3944 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -254,10 +254,22 @@ where ) { let state = tree.state.downcast_mut::(); - operation.scrollable(state, self.id.as_ref().map(|id| &id.0)); + let bounds = layout.bounds(); + let content_layout = layout.children().next().unwrap(); + let content_bounds = content_layout.bounds(); + let translation = + state.translation(self.direction, bounds, content_bounds); + + operation.scrollable( + state, + self.id.as_ref().map(|id| &id.0), + bounds, + translation, + ); operation.container( self.id.as_ref().map(|id| &id.0), + bounds, &mut |operation| { self.content.as_widget().operate( &mut tree.children[0], From 09f2887da582ed7d39a56b2c0b37d0b24b6c1e57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 27 Jul 2023 01:02:47 +0200 Subject: [PATCH 033/321] Create `visible_bounds` example --- examples/visible_bounds/Cargo.toml | 10 ++ examples/visible_bounds/src/main.rs | 151 ++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 examples/visible_bounds/Cargo.toml create mode 100644 examples/visible_bounds/src/main.rs diff --git a/examples/visible_bounds/Cargo.toml b/examples/visible_bounds/Cargo.toml new file mode 100644 index 00000000..cfa56dd2 --- /dev/null +++ b/examples/visible_bounds/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "visible_bounds" +version = "0.1.0" +authors = ["HĂ©ctor RamĂłn JimĂ©nez "] +edition = "2021" +publish = false + +[dependencies] +iced = { path = "../..", features = ["debug"] } +once_cell = "1" diff --git a/examples/visible_bounds/src/main.rs b/examples/visible_bounds/src/main.rs new file mode 100644 index 00000000..bd7ccdc0 --- /dev/null +++ b/examples/visible_bounds/src/main.rs @@ -0,0 +1,151 @@ +use iced::executor; +use iced::mouse; +use iced::subscription::{self, Subscription}; +use iced::theme::{self, Theme}; +use iced::widget::{column, container, scrollable, text, vertical_space}; +use iced::{ + Application, Command, Element, Event, Length, Point, Rectangle, Settings, +}; + +pub fn main() -> iced::Result { + Example::run(Settings::default()) +} + +struct Example { + mouse_position: Option, + outer_bounds: Option, + inner_bounds: Option, +} + +#[derive(Debug, Clone, Copy)] +enum Message { + MouseMoved(Point), + Scrolled(scrollable::Viewport), + OuterBoundsFetched(Option), + InnerBoundsFetched(Option), +} + +impl Application for Example { + type Message = Message; + type Theme = Theme; + type Flags = (); + type Executor = executor::Default; + + fn new(_flags: Self::Flags) -> (Self, Command) { + ( + Self { + mouse_position: None, + outer_bounds: None, + inner_bounds: None, + }, + Command::none(), + ) + } + + fn title(&self) -> String { + String::from("Visible bounds - Iced") + } + + fn update(&mut self, message: Message) -> Command { + match message { + Message::MouseMoved(position) => { + self.mouse_position = Some(position); + + Command::none() + } + Message::Scrolled(_) => Command::batch(vec![ + container::visible_bounds(OUTER_CONTAINER.clone()) + .map(Message::OuterBoundsFetched), + container::visible_bounds(INNER_CONTAINER.clone()) + .map(Message::InnerBoundsFetched), + ]), + Message::OuterBoundsFetched(outer_bounds) => { + self.outer_bounds = outer_bounds; + + Command::none() + } + Message::InnerBoundsFetched(inner_bounds) => { + self.inner_bounds = inner_bounds; + + Command::none() + } + } + } + + fn view(&self) -> Element { + let view_bounds = |label, bounds| { + text(format!( + "The {label} container is {}", + match bounds { + Some(bounds) => format!("visible at {:?}", bounds), + None => "not visible".to_string(), + } + )) + }; + + column![ + text(format!( + "Mouse position is {}", + match self.mouse_position { + Some(Point { x, y }) => format!("({x}, {y})"), + None => "unknown".to_string(), + } + )), + view_bounds("outer", self.outer_bounds), + view_bounds("inner", self.inner_bounds), + scrollable( + column![ + text("Scroll me!"), + vertical_space(400), + container(text("I am the outer container!")) + .id(OUTER_CONTAINER.clone()) + .padding(40) + .style(theme::Container::Box), + vertical_space(400), + scrollable( + column![ + text("Scroll me!"), + vertical_space(400), + container(text("I am the inner container!")) + .id(INNER_CONTAINER.clone()) + .padding(40) + .style(theme::Container::Box), + vertical_space(400) + ] + .padding(20) + ) + .on_scroll(Message::Scrolled) + .width(Length::Fill) + .height(300), + ] + .padding(20) + ) + .on_scroll(Message::Scrolled) + .width(Length::Fill) + .height(300), + ] + .spacing(10) + .padding(20) + .into() + } + + fn subscription(&self) -> Subscription { + subscription::events_with(|event, _| match event { + Event::Mouse(mouse::Event::CursorMoved { position }) => { + Some(Message::MouseMoved(position)) + } + _ => None, + }) + } + + fn theme(&self) -> Theme { + Theme::Dark + } +} + +use once_cell::sync::Lazy; + +static OUTER_CONTAINER: Lazy = + Lazy::new(|| container::Id::new("outer")); +static INNER_CONTAINER: Lazy = + Lazy::new(|| container::Id::new("inner")); From 8961fcd50179d76fa07edfeedee9edc1a0aa93ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 27 Jul 2023 01:21:50 +0200 Subject: [PATCH 034/321] Highlight container bounds on hover in `visible_bounds` example --- examples/visible_bounds/src/main.rs | 57 ++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/examples/visible_bounds/src/main.rs b/examples/visible_bounds/src/main.rs index bd7ccdc0..8bc645b7 100644 --- a/examples/visible_bounds/src/main.rs +++ b/examples/visible_bounds/src/main.rs @@ -2,9 +2,12 @@ use iced::executor; use iced::mouse; use iced::subscription::{self, Subscription}; use iced::theme::{self, Theme}; -use iced::widget::{column, container, scrollable, text, vertical_space}; +use iced::widget::{ + column, container, horizontal_space, row, scrollable, text, vertical_space, +}; use iced::{ - Application, Command, Element, Event, Length, Point, Rectangle, Settings, + Alignment, Application, Color, Command, Element, Event, Font, Length, + Point, Rectangle, Settings, }; pub fn main() -> iced::Result { @@ -73,26 +76,52 @@ impl Application for Example { } fn view(&self) -> Element { - let view_bounds = |label, bounds| { - text(format!( - "The {label} container is {}", + let data_row = |label, value, color| { + row![ + text(label), + horizontal_space(Length::Fill), + text(value).font(Font::MONOSPACE).size(14).style(color), + ] + .height(40) + .align_items(Alignment::Center) + }; + + let view_bounds = |label, bounds: Option| { + data_row( + label, match bounds { - Some(bounds) => format!("visible at {:?}", bounds), + Some(bounds) => format!("{:?}", bounds), None => "not visible".to_string(), - } - )) + }, + if bounds + .zip(self.mouse_position) + .map(|(bounds, mouse_position)| { + bounds.contains(mouse_position) + }) + .unwrap_or_default() + { + Color { + g: 1.0, + ..Color::BLACK + } + .into() + } else { + theme::Text::Default + }, + ) }; column![ - text(format!( - "Mouse position is {}", + data_row( + "Mouse position", match self.mouse_position { Some(Point { x, y }) => format!("({x}, {y})"), None => "unknown".to_string(), - } - )), - view_bounds("outer", self.outer_bounds), - view_bounds("inner", self.inner_bounds), + }, + theme::Text::Default, + ), + view_bounds("Outer container", self.outer_bounds), + view_bounds("Inner container", self.inner_bounds), scrollable( column![ text("Scroll me!"), From 34851c9c394f1200be613c3947acc418ed69f2a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 27 Jul 2023 01:24:57 +0200 Subject: [PATCH 035/321] Update `CHANGELOG` --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6a989f6..c68ad2c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Helpers to change viewport alignment of a `Scrollable`. [#1953](https://github.com/iced-rs/iced/pull/1953) - `scroll_to` widget operation. [#1796](https://github.com/iced-rs/iced/pull/1796) - `scroll_to` helper. [#1804](https://github.com/iced-rs/iced/pull/1804) +- `visible_bounds` widget operation for `Container`. [#1971](https://github.com/iced-rs/iced/pull/1971) - Command to fetch window size. [#1927](https://github.com/iced-rs/iced/pull/1927) - Conversion support from `Fn` trait to custom theme. [#1861](https://github.com/iced-rs/iced/pull/1861) - Configurable border radii on relevant widgets. [#1869](https://github.com/iced-rs/iced/pull/1869) From cbb5fcc8829e6fbe60f97cad8597c86ffd4f5b1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 27 Jul 2023 01:29:20 +0200 Subject: [PATCH 036/321] Fetch bounds on window resize in `visible_bounds` example --- examples/visible_bounds/src/main.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/examples/visible_bounds/src/main.rs b/examples/visible_bounds/src/main.rs index 8bc645b7..8b684514 100644 --- a/examples/visible_bounds/src/main.rs +++ b/examples/visible_bounds/src/main.rs @@ -5,6 +5,7 @@ use iced::theme::{self, Theme}; use iced::widget::{ column, container, horizontal_space, row, scrollable, text, vertical_space, }; +use iced::window; use iced::{ Alignment, Application, Color, Command, Element, Event, Font, Length, Point, Rectangle, Settings, @@ -23,6 +24,7 @@ struct Example { #[derive(Debug, Clone, Copy)] enum Message { MouseMoved(Point), + WindowResized, Scrolled(scrollable::Viewport), OuterBoundsFetched(Option), InnerBoundsFetched(Option), @@ -56,12 +58,14 @@ impl Application for Example { Command::none() } - Message::Scrolled(_) => Command::batch(vec![ - container::visible_bounds(OUTER_CONTAINER.clone()) - .map(Message::OuterBoundsFetched), - container::visible_bounds(INNER_CONTAINER.clone()) - .map(Message::InnerBoundsFetched), - ]), + Message::Scrolled(_) | Message::WindowResized => { + Command::batch(vec![ + container::visible_bounds(OUTER_CONTAINER.clone()) + .map(Message::OuterBoundsFetched), + container::visible_bounds(INNER_CONTAINER.clone()) + .map(Message::InnerBoundsFetched), + ]) + } Message::OuterBoundsFetched(outer_bounds) => { self.outer_bounds = outer_bounds; @@ -163,6 +167,9 @@ impl Application for Example { Event::Mouse(mouse::Event::CursorMoved { position }) => { Some(Message::MouseMoved(position)) } + Event::Window(window::Event::Resized { .. }) => { + Some(Message::WindowResized) + } _ => None, }) } From e5a054f2704881145ceeba074668bdb0129f8eed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 27 Jul 2023 01:42:19 +0200 Subject: [PATCH 037/321] Improve name of `verify` workflow step --- .github/workflows/verify.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index 3de8a21c..089dd5c9 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -13,7 +13,7 @@ jobs: - name: Check `CHANGELOG.md` has changes run: | ! git diff --exit-code origin/master HEAD -- CHANGELOG.md - - name: Check `CHANGELOG.md` has PR author + - name: Check `CHANGELOG.md` thanks the PR author if: ${{ github.event.pull_request.user.login != 'hecrj' }} run: | sed -n '/## \[Unreleased\]/,/^## /p' CHANGELOG.md | sed -n '/Many thanks to.../,//p' | grep '@${{ github.event.pull_request.user.login }}' From a9b95f39dd8f55b00b5f4b2f6690c05b5a921d4d Mon Sep 17 00:00:00 2001 From: wiiznokes <78230769+wiiznokes@users.noreply.github.com> Date: Thu, 27 Jul 2023 04:27:19 +0200 Subject: [PATCH 038/321] add border radius to public API --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index ce6c513d..174fd890 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -191,7 +191,7 @@ pub use crate::core::event; pub use crate::core::gradient; pub use crate::core::{ color, Alignment, Background, Color, ContentFit, Degrees, Gradient, Length, - Padding, Pixels, Point, Radians, Rectangle, Size, Vector, + Padding, Pixels, Point, Radians, Rectangle, Size, Vector, BorderRadius }; pub use crate::runtime::Command; From e4b75ec9c76402dda7c6b6631918da240bb1c7ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 27 Jul 2023 16:51:06 +0200 Subject: [PATCH 039/321] Update `glyphon` to `0.3` :tada: --- wgpu/Cargo.toml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index a0500f83..3c08b569 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -15,13 +15,14 @@ web-colors = ["iced_graphics/web-colors"] [dependencies] wgpu = "0.16" +glyphon = "0.3" raw-window-handle = "0.5" -log = "0.4" guillotiere = "0.6" futures = "0.3" bitflags = "1.2" once_cell = "1.0" rustc-hash = "1.1" +log = "0.4" [target.'cfg(target_arch = "wasm32")'.dependencies] wgpu = { version = "0.16", features = ["webgl"] } @@ -42,11 +43,6 @@ features = ["derive"] version = "0.8" path = "../graphics" -[dependencies.glyphon] -version = "0.2" -git = "https://github.com/grovesNL/glyphon.git" -rev = "81dedbd04237e181c2118931c5f37d341aeb6837" - [dependencies.glam] version = "0.24" From 274fae5aff5dbfce59cec3eaa4893d1ed6b7e459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 27 Jul 2023 18:50:56 +0200 Subject: [PATCH 040/321] Run `cargo fmt` --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 174fd890..0905a31c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -190,8 +190,8 @@ pub use crate::core::alignment; pub use crate::core::event; pub use crate::core::gradient; pub use crate::core::{ - color, Alignment, Background, Color, ContentFit, Degrees, Gradient, Length, - Padding, Pixels, Point, Radians, Rectangle, Size, Vector, BorderRadius + color, Alignment, Background, BorderRadius, Color, ContentFit, Degrees, + Gradient, Length, Padding, Pixels, Point, Radians, Rectangle, Size, Vector, }; pub use crate::runtime::Command; From 74e14e562eef1e837c2cffc58cf23f29652f16c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 27 Jul 2023 18:51:49 +0200 Subject: [PATCH 041/321] Update `CHANGELOG` --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6a989f6..8836b5de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,6 +73,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Quad rendering including border only inside of the bounds. [#1843](https://github.com/iced-rs/iced/pull/1843) - Redraw requests not being forwarded for `Component` overlays. [#1949](https://github.com/iced-rs/iced/pull/1949) - Blinking input cursor when window loses focus. [#1955](https://github.com/iced-rs/iced/pull/1955) +- `BorderRadius` not exposed in root crate. [#1972](https://github.com/iced-rs/iced/pull/1972) - Outdated `ROADMAP`. [#1958](https://github.com/iced-rs/iced/pull/1958) Many thanks to... @@ -99,6 +100,7 @@ Many thanks to... - @tarkah - @thunderstorm010 - @wash2 +- @wiiznokes ## [0.9.0] - 2023-04-13 ### Added From 126aef88e7647c4690055b4c96aee46ecadcf60e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 28 Jul 2023 19:48:39 +0200 Subject: [PATCH 042/321] Bump versions :tada: --- Cargo.toml | 8 ++++---- README.md | 2 +- core/Cargo.toml | 2 +- core/src/lib.rs | 5 +---- core/src/widget.rs | 10 +++++----- futures/Cargo.toml | 4 ++-- futures/src/subscription.rs | 8 ++++---- graphics/Cargo.toml | 4 ++-- renderer/Cargo.toml | 11 +++++++++-- runtime/Cargo.toml | 6 +++--- runtime/src/lib.rs | 4 ++-- runtime/src/user_interface.rs | 2 +- src/application.rs | 18 +++++++++--------- src/lib.rs | 8 ++++---- src/sandbox.rs | 22 +++++++++++----------- style/Cargo.toml | 4 ++-- tiny_skia/Cargo.toml | 9 ++++++++- wgpu/Cargo.toml | 4 ++-- wgpu/src/lib.rs | 9 +++------ widget/Cargo.toml | 11 +++++++++-- widget/src/pane_grid.rs | 2 +- winit/Cargo.toml | 6 +++--- winit/src/conversion.rs | 25 ++++++++++++------------- winit/src/lib.rs | 4 ++-- 24 files changed, 101 insertions(+), 87 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 070cd0ce..05bb883d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced" -version = "0.9.0" +version = "0.10.0" authors = ["HĂ©ctor RamĂłn JimĂ©nez "] edition = "2021" description = "A cross-platform GUI library inspired by Elm" @@ -61,11 +61,11 @@ members = [ ] [dependencies] -iced_core = { version = "0.9", path = "core" } -iced_futures = { version = "0.6", path = "futures" } +iced_core = { version = "0.10", path = "core" } +iced_futures = { version = "0.7", path = "futures" } iced_renderer = { version = "0.1", path = "renderer" } iced_widget = { version = "0.1", path = "widget" } -iced_winit = { version = "0.9", path = "winit", features = ["application"] } +iced_winit = { version = "0.10", path = "winit", features = ["application"] } thiserror = "1" [dependencies.image_rs] diff --git a/README.md b/README.md index e013246a..9604aadb 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ __Iced is currently experimental software.__ [Take a look at the roadmap], Add `iced` as a dependency in your `Cargo.toml`: ```toml -iced = "0.9" +iced = "0.10" ``` If your project is using a Rust edition older than 2021, then you will need to diff --git a/core/Cargo.toml b/core/Cargo.toml index 55f2e85f..8bb37309 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_core" -version = "0.9.0" +version = "0.10.0" authors = ["HĂ©ctor RamĂłn JimĂ©nez "] edition = "2021" description = "The essential concepts of Iced" diff --git a/core/src/lib.rs b/core/src/lib.rs index 76d775e7..c1c8424b 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -1,14 +1,11 @@ //! The core library of [Iced]. //! //! This library holds basic types that can be reused and re-exported in -//! different runtime implementations. For instance, both [`iced_native`] and -//! [`iced_web`] are built on top of `iced_core`. +//! different runtime implementations. //! //! ![The foundations of the Iced ecosystem](https://github.com/iced-rs/iced/blob/0525d76ff94e828b7b21634fa94a747022001c83/docs/graphs/foundations.png?raw=true) //! //! [Iced]: https://github.com/iced-rs/iced -//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.9/native -//! [`iced_web`]: https://github.com/iced-rs/iced_web #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] diff --git a/core/src/widget.rs b/core/src/widget.rs index 25c1cae8..d6a99208 100644 --- a/core/src/widget.rs +++ b/core/src/widget.rs @@ -33,12 +33,12 @@ use crate::{Clipboard, Length, Rectangle, Shell}; /// - [`geometry`], a custom widget showcasing how to draw geometry with the /// `Mesh2D` primitive in [`iced_wgpu`]. /// -/// [examples]: https://github.com/iced-rs/iced/tree/0.9/examples -/// [`bezier_tool`]: https://github.com/iced-rs/iced/tree/0.9/examples/bezier_tool -/// [`custom_widget`]: https://github.com/iced-rs/iced/tree/0.9/examples/custom_widget -/// [`geometry`]: https://github.com/iced-rs/iced/tree/0.9/examples/geometry +/// [examples]: https://github.com/iced-rs/iced/tree/0.10/examples +/// [`bezier_tool`]: https://github.com/iced-rs/iced/tree/0.10/examples/bezier_tool +/// [`custom_widget`]: https://github.com/iced-rs/iced/tree/0.10/examples/custom_widget +/// [`geometry`]: https://github.com/iced-rs/iced/tree/0.10/examples/geometry /// [`lyon`]: https://github.com/nical/lyon -/// [`iced_wgpu`]: https://github.com/iced-rs/iced/tree/0.9/wgpu +/// [`iced_wgpu`]: https://github.com/iced-rs/iced/tree/0.10/wgpu pub trait Widget where Renderer: crate::Renderer, diff --git a/futures/Cargo.toml b/futures/Cargo.toml index f636a304..044827c2 100644 --- a/futures/Cargo.toml +++ b/futures/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_futures" -version = "0.6.0" +version = "0.7.0" authors = ["HĂ©ctor RamĂłn JimĂ©nez "] edition = "2021" description = "Commands, subscriptions, and runtimes for Iced" @@ -17,7 +17,7 @@ thread-pool = ["futures/thread-pool"] log = "0.4" [dependencies.iced_core] -version = "0.9" +version = "0.10" path = "../core" [dependencies.futures] diff --git a/futures/src/subscription.rs b/futures/src/subscription.rs index 0642a924..8f78ce3a 100644 --- a/futures/src/subscription.rs +++ b/futures/src/subscription.rs @@ -128,9 +128,9 @@ impl std::fmt::Debug for Subscription { /// - [`stopwatch`], a watch with start/stop and reset buttons showcasing how /// to listen to time. /// -/// [examples]: https://github.com/iced-rs/iced/tree/0.9/examples -/// [`download_progress`]: https://github.com/iced-rs/iced/tree/0.9/examples/download_progress -/// [`stopwatch`]: https://github.com/iced-rs/iced/tree/0.9/examples/stopwatch +/// [examples]: https://github.com/iced-rs/iced/tree/0.10/examples +/// [`download_progress`]: https://github.com/iced-rs/iced/tree/0.10/examples/download_progress +/// [`stopwatch`]: https://github.com/iced-rs/iced/tree/0.10/examples/stopwatch pub trait Recipe { /// The events that will be produced by a [`Subscription`] with this /// [`Recipe`]. @@ -413,7 +413,7 @@ where /// Check out the [`websocket`] example, which showcases this pattern to maintain a WebSocket /// connection open. /// -/// [`websocket`]: https://github.com/iced-rs/iced/tree/0.9/examples/websocket +/// [`websocket`]: https://github.com/iced-rs/iced/tree/0.10/examples/websocket pub fn channel( id: I, size: usize, diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml index 7a9e6aee..ca7bf61a 100644 --- a/graphics/Cargo.toml +++ b/graphics/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_graphics" -version = "0.8.0" +version = "0.9.0" authors = ["HĂ©ctor RamĂłn JimĂ©nez "] edition = "2021" description = "A bunch of backend-agnostic types that can be leveraged to build a renderer for Iced" @@ -29,7 +29,7 @@ version = "1.4" features = ["derive"] [dependencies.iced_core] -version = "0.9" +version = "0.10" path = "../core" [dependencies.image] diff --git a/renderer/Cargo.toml b/renderer/Cargo.toml index fda2bc7b..89326d73 100644 --- a/renderer/Cargo.toml +++ b/renderer/Cargo.toml @@ -1,7 +1,14 @@ [package] name = "iced_renderer" version = "0.1.0" +authors = ["HĂ©ctor RamĂłn JimĂ©nez "] edition = "2021" +description = "The official renderer for Iced" +license = "MIT" +repository = "https://github.com/iced-rs/iced" +documentation = "https://docs.rs/iced_renderer" +keywords = ["gui", "ui", "graphics", "interface", "widgets"] +categories = ["gui"] [features] wgpu = ["iced_wgpu"] @@ -17,7 +24,7 @@ thiserror = "1" log = "0.4" [dependencies.iced_graphics] -version = "0.8" +version = "0.9" path = "../graphics" [dependencies.iced_tiny_skia] @@ -25,6 +32,6 @@ version = "0.1" path = "../tiny_skia" [dependencies.iced_wgpu] -version = "0.10" +version = "0.11" path = "../wgpu" optional = true diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index a65f07f2..7ee4f6b7 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -3,7 +3,7 @@ name = "iced_runtime" version = "0.1.0" authors = ["HĂ©ctor RamĂłn JimĂ©nez "] edition = "2021" -description = "A renderer-agnostic library for native GUIs" +description = "The renderer-agnostic runtime for Iced" license = "MIT" repository = "https://github.com/iced-rs/iced" @@ -14,10 +14,10 @@ debug = [] thiserror = "1" [dependencies.iced_core] -version = "0.9" +version = "0.10" path = "../core" [dependencies.iced_futures] -version = "0.6" +version = "0.7" path = "../futures" features = ["thread-pool"] diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 4bbf9687..59c70ff7 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -23,8 +23,8 @@ //! - Build a new renderer, see the [renderer] module. //! - Build a custom widget, start at the [`Widget`] trait. //! -//! [`iced_core`]: https://github.com/iced-rs/iced/tree/0.9/core -//! [`iced_winit`]: https://github.com/iced-rs/iced/tree/0.9/winit +//! [`iced_core`]: https://github.com/iced-rs/iced/tree/0.10/core +//! [`iced_winit`]: https://github.com/iced-rs/iced/tree/0.10/winit //! [`druid`]: https://github.com/xi-editor/druid //! [`raw-window-handle`]: https://github.com/rust-windowing/raw-window-handle //! [renderer]: crate::renderer diff --git a/runtime/src/user_interface.rs b/runtime/src/user_interface.rs index 8a936b98..5e910eab 100644 --- a/runtime/src/user_interface.rs +++ b/runtime/src/user_interface.rs @@ -19,7 +19,7 @@ use crate::overlay; /// The [`integration`] example uses a [`UserInterface`] to integrate Iced in an /// existing graphical application. /// -/// [`integration`]: https://github.com/iced-rs/iced/tree/0.9/examples/integration +/// [`integration`]: https://github.com/iced-rs/iced/tree/0.10/examples/integration #[allow(missing_debug_implementations)] pub struct UserInterface<'a, Message, Renderer> { root: Element<'a, Message, Renderer>, diff --git a/src/application.rs b/src/application.rs index abf58fa3..9518b8c5 100644 --- a/src/application.rs +++ b/src/application.rs @@ -39,15 +39,15 @@ pub use crate::style::application::{Appearance, StyleSheet}; /// to listen to time. /// - [`todos`], a todos tracker inspired by [TodoMVC]. /// -/// [The repository has a bunch of examples]: https://github.com/iced-rs/iced/tree/0.9/examples -/// [`clock`]: https://github.com/iced-rs/iced/tree/0.9/examples/clock -/// [`download_progress`]: https://github.com/iced-rs/iced/tree/0.9/examples/download_progress -/// [`events`]: https://github.com/iced-rs/iced/tree/0.9/examples/events -/// [`game_of_life`]: https://github.com/iced-rs/iced/tree/0.9/examples/game_of_life -/// [`pokedex`]: https://github.com/iced-rs/iced/tree/0.9/examples/pokedex -/// [`solar_system`]: https://github.com/iced-rs/iced/tree/0.9/examples/solar_system -/// [`stopwatch`]: https://github.com/iced-rs/iced/tree/0.9/examples/stopwatch -/// [`todos`]: https://github.com/iced-rs/iced/tree/0.9/examples/todos +/// [The repository has a bunch of examples]: https://github.com/iced-rs/iced/tree/0.10/examples +/// [`clock`]: https://github.com/iced-rs/iced/tree/0.10/examples/clock +/// [`download_progress`]: https://github.com/iced-rs/iced/tree/0.10/examples/download_progress +/// [`events`]: https://github.com/iced-rs/iced/tree/0.10/examples/events +/// [`game_of_life`]: https://github.com/iced-rs/iced/tree/0.10/examples/game_of_life +/// [`pokedex`]: https://github.com/iced-rs/iced/tree/0.10/examples/pokedex +/// [`solar_system`]: https://github.com/iced-rs/iced/tree/0.10/examples/solar_system +/// [`stopwatch`]: https://github.com/iced-rs/iced/tree/0.10/examples/stopwatch +/// [`todos`]: https://github.com/iced-rs/iced/tree/0.10/examples/todos /// [`Sandbox`]: crate::Sandbox /// [`Canvas`]: crate::widget::Canvas /// [PokĂ©API]: https://pokeapi.co/ diff --git a/src/lib.rs b/src/lib.rs index 0905a31c..19e7456e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,13 +24,13 @@ //! [scrollables]: https://gfycat.com/perkybaggybaboon-rust-gui //! [Debug overlay with performance metrics]: https://gfycat.com/incredibledarlingbee //! [Modular ecosystem]: https://github.com/iced-rs/iced/blob/master/ECOSYSTEM.md -//! [renderer-agnostic native runtime]: https://github.com/iced-rs/iced/tree/0.9/native +//! [renderer-agnostic native runtime]: https://github.com/iced-rs/iced/tree/0.10/runtime //! [`wgpu`]: https://github.com/gfx-rs/wgpu-rs -//! [built-in renderer]: https://github.com/iced-rs/iced/tree/0.9/wgpu -//! [windowing shell]: https://github.com/iced-rs/iced/tree/0.9/winit +//! [built-in renderer]: https://github.com/iced-rs/iced/tree/0.10/wgpu +//! [windowing shell]: https://github.com/iced-rs/iced/tree/0.10/winit //! [`dodrio`]: https://github.com/fitzgen/dodrio //! [web runtime]: https://github.com/iced-rs/iced_web -//! [examples]: https://github.com/iced-rs/iced/tree/0.9/examples +//! [examples]: https://github.com/iced-rs/iced/tree/0.10/examples //! [repository]: https://github.com/iced-rs/iced //! //! # Overview diff --git a/src/sandbox.rs b/src/sandbox.rs index cca327b6..825a0b60 100644 --- a/src/sandbox.rs +++ b/src/sandbox.rs @@ -34,19 +34,19 @@ use crate::{Application, Command, Element, Error, Settings, Subscription}; /// - [`tour`], a simple UI tour that can run both on native platforms and the /// web! /// -/// [The repository has a bunch of examples]: https://github.com/iced-rs/iced/tree/0.9/examples -/// [`bezier_tool`]: https://github.com/iced-rs/iced/tree/0.9/examples/bezier_tool -/// [`counter`]: https://github.com/iced-rs/iced/tree/0.9/examples/counter -/// [`custom_widget`]: https://github.com/iced-rs/iced/tree/0.9/examples/custom_widget -/// [`geometry`]: https://github.com/iced-rs/iced/tree/0.9/examples/geometry -/// [`pane_grid`]: https://github.com/iced-rs/iced/tree/0.9/examples/pane_grid -/// [`progress_bar`]: https://github.com/iced-rs/iced/tree/0.9/examples/progress_bar -/// [`styling`]: https://github.com/iced-rs/iced/tree/0.9/examples/styling -/// [`svg`]: https://github.com/iced-rs/iced/tree/0.9/examples/svg -/// [`tour`]: https://github.com/iced-rs/iced/tree/0.9/examples/tour +/// [The repository has a bunch of examples]: https://github.com/iced-rs/iced/tree/0.10/examples +/// [`bezier_tool`]: https://github.com/iced-rs/iced/tree/0.10/examples/bezier_tool +/// [`counter`]: https://github.com/iced-rs/iced/tree/0.10/examples/counter +/// [`custom_widget`]: https://github.com/iced-rs/iced/tree/0.10/examples/custom_widget +/// [`geometry`]: https://github.com/iced-rs/iced/tree/0.10/examples/geometry +/// [`pane_grid`]: https://github.com/iced-rs/iced/tree/0.10/examples/pane_grid +/// [`progress_bar`]: https://github.com/iced-rs/iced/tree/0.10/examples/progress_bar +/// [`styling`]: https://github.com/iced-rs/iced/tree/0.10/examples/styling +/// [`svg`]: https://github.com/iced-rs/iced/tree/0.10/examples/svg +/// [`tour`]: https://github.com/iced-rs/iced/tree/0.10/examples/tour /// [`Canvas widget`]: crate::widget::Canvas /// [the overview]: index.html#overview -/// [`iced_wgpu`]: https://github.com/iced-rs/iced/tree/0.9/wgpu +/// [`iced_wgpu`]: https://github.com/iced-rs/iced/tree/0.10/wgpu /// [`Svg` widget]: crate::widget::Svg /// [Ghostscript Tiger]: https://commons.wikimedia.org/wiki/File:Ghostscript_Tiger.svg /// diff --git a/style/Cargo.toml b/style/Cargo.toml index 8af4a9b3..689cf978 100644 --- a/style/Cargo.toml +++ b/style/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_style" -version = "0.8.0" +version = "0.9.0" authors = ["HĂ©ctor RamĂłn JimĂ©nez "] edition = "2021" description = "The default set of styles of Iced" @@ -11,7 +11,7 @@ keywords = ["gui", "ui", "graphics", "interface", "widgets"] categories = ["gui"] [dependencies.iced_core] -version = "0.9" +version = "0.10" path = "../core" features = ["palette"] diff --git a/tiny_skia/Cargo.toml b/tiny_skia/Cargo.toml index 66ad35fd..9aa63a4f 100644 --- a/tiny_skia/Cargo.toml +++ b/tiny_skia/Cargo.toml @@ -1,7 +1,14 @@ [package] name = "iced_tiny_skia" version = "0.1.0" +authors = ["HĂ©ctor RamĂłn JimĂ©nez "] edition = "2021" +description = "A software renderer for Iced" +license = "MIT" +repository = "https://github.com/iced-rs/iced" +documentation = "https://docs.rs/iced_tiny_skia" +keywords = ["gui", "ui", "graphics", "interface", "widgets"] +categories = ["gui"] [features] image = ["iced_graphics/image"] @@ -19,7 +26,7 @@ kurbo = "0.9" log = "0.4" [dependencies.iced_graphics] -version = "0.8" +version = "0.9" path = "../graphics" [dependencies.twox-hash] diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 3c08b569..f3713eb9 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_wgpu" -version = "0.10.0" +version = "0.11.0" authors = ["HĂ©ctor RamĂłn JimĂ©nez "] edition = "2021" description = "A wgpu renderer for Iced" @@ -40,7 +40,7 @@ version = "1.9" features = ["derive"] [dependencies.iced_graphics] -version = "0.8" +version = "0.9" path = "../graphics" [dependencies.glam] diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index deb223ef..d1e4b7af 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -1,25 +1,22 @@ -//! A [`wgpu`] renderer for [`iced_native`]. +//! A [`wgpu`] renderer for [Iced]. //! //! ![The native path of the Iced ecosystem](https://github.com/iced-rs/iced/blob/0525d76ff94e828b7b21634fa94a747022001c83/docs/graphs/native.png?raw=true) //! -//! For now, it is the default renderer of [Iced] in native platforms. -//! //! [`wgpu`] supports most modern graphics backends: Vulkan, Metal, DX11, and //! DX12 (OpenGL and WebGL are still WIP). Additionally, it will support the //! incoming [WebGPU API]. //! //! Currently, `iced_wgpu` supports the following primitives: -//! - Text, which is rendered using [`wgpu_glyph`]. No shaping at all. +//! - Text, which is rendered using [`glyphon`]. //! - Quads or rectangles, with rounded borders and a solid background color. //! - Clip areas, useful to implement scrollables or hide overflowing content. //! - Images and SVG, loaded from memory or the file system. //! - Meshes of triangles, useful to draw geometry freely. //! //! [Iced]: https://github.com/iced-rs/iced -//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.9/native //! [`wgpu`]: https://github.com/gfx-rs/wgpu-rs //! [WebGPU API]: https://gpuweb.github.io/gpuweb/ -//! [`wgpu_glyph`]: https://github.com/hecrj/wgpu_glyph +//! [`glyphon`]: https://github.com/grovesNL/glyphon #![doc( html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" )] diff --git a/widget/Cargo.toml b/widget/Cargo.toml index 14aae72e..6e66689d 100644 --- a/widget/Cargo.toml +++ b/widget/Cargo.toml @@ -1,7 +1,14 @@ [package] name = "iced_widget" -version = "0.1.0" +version = "0.1.1" +authors = ["HĂ©ctor RamĂłn JimĂ©nez "] edition = "2021" +description = "The built-in widgets for Iced" +license = "MIT" +repository = "https://github.com/iced-rs/iced" +documentation = "https://docs.rs/iced_widget" +keywords = ["gui", "ui", "graphics", "interface", "widgets"] +categories = ["gui"] [features] lazy = ["ouroboros"] @@ -24,7 +31,7 @@ version = "0.1" path = "../renderer" [dependencies.iced_style] -version = "0.8" +version = "0.9" path = "../style" [dependencies.ouroboros] diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs index 0f4ab9eb..d8c98858 100644 --- a/widget/src/pane_grid.rs +++ b/widget/src/pane_grid.rs @@ -6,7 +6,7 @@ //! The [`pane_grid` example] showcases how to use a [`PaneGrid`] with resizing, //! drag and drop, and hotkey support. //! -//! [`pane_grid` example]: https://github.com/iced-rs/iced/tree/0.9/examples/pane_grid +//! [`pane_grid` example]: https://github.com/iced-rs/iced/tree/0.10/examples/pane_grid mod axis; mod configuration; mod content; diff --git a/winit/Cargo.toml b/winit/Cargo.toml index de7c1c62..67216147 100644 --- a/winit/Cargo.toml +++ b/winit/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_winit" -version = "0.9.1" +version = "0.10.0" authors = ["HĂ©ctor RamĂłn JimĂ©nez "] edition = "2021" description = "A winit runtime for Iced" @@ -39,11 +39,11 @@ version = "0.1" path = "../runtime" [dependencies.iced_graphics] -version = "0.8" +version = "0.9" path = "../graphics" [dependencies.iced_style] -version = "0.8" +version = "0.9" path = "../style" [dependencies.tracing] diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index dcae7074..b2398e62 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -1,7 +1,7 @@ -//! Convert [`winit`] types into [`iced_native`] types, and viceversa. +//! Convert [`winit`] types into [`iced_runtime`] types, and viceversa. //! //! [`winit`]: https://github.com/rust-windowing/winit -//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.9/native +//! [`iced_runtime`]: https://github.com/iced-rs/iced/tree/0.10/runtime use crate::core::keyboard; use crate::core::mouse; use crate::core::touch; @@ -229,10 +229,9 @@ pub fn mode(mode: Option) -> window::Mode { } } -/// Converts a `MouseCursor` from [`iced_native`] to a [`winit`] cursor icon. +/// Converts a [`mouse::Interaction`] to a [`winit`] cursor icon. /// /// [`winit`]: https://github.com/rust-windowing/winit -/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.9/native pub fn mouse_interaction( interaction: mouse::Interaction, ) -> winit::window::CursorIcon { @@ -254,10 +253,10 @@ pub fn mouse_interaction( } } -/// Converts a `MouseButton` from [`winit`] to an [`iced_native`] mouse button. +/// Converts a `MouseButton` from [`winit`] to an [`iced`] mouse button. /// /// [`winit`]: https://github.com/rust-windowing/winit -/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.9/native +/// [`iced`]: https://github.com/iced-rs/iced/tree/0.10 pub fn mouse_button(mouse_button: winit::event::MouseButton) -> mouse::Button { match mouse_button { winit::event::MouseButton::Left => mouse::Button::Left, @@ -267,11 +266,11 @@ pub fn mouse_button(mouse_button: winit::event::MouseButton) -> mouse::Button { } } -/// Converts some `ModifiersState` from [`winit`] to an [`iced_native`] -/// modifiers state. +/// Converts some `ModifiersState` from [`winit`] to an [`iced`] modifiers +/// state. /// /// [`winit`]: https://github.com/rust-windowing/winit -/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.9/native +/// [`iced`]: https://github.com/iced-rs/iced/tree/0.10 pub fn modifiers( modifiers: winit::event::ModifiersState, ) -> keyboard::Modifiers { @@ -295,10 +294,10 @@ pub fn cursor_position( Point::new(logical_position.x, logical_position.y) } -/// Converts a `Touch` from [`winit`] to an [`iced_native`] touch event. +/// Converts a `Touch` from [`winit`] to an [`iced`] touch event. /// /// [`winit`]: https://github.com/rust-windowing/winit -/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.9/native +/// [`iced`]: https://github.com/iced-rs/iced/tree/0.10 pub fn touch_event( touch: winit::event::Touch, scale_factor: f64, @@ -326,10 +325,10 @@ pub fn touch_event( } } -/// Converts a `VirtualKeyCode` from [`winit`] to an [`iced_native`] key code. +/// Converts a `VirtualKeyCode` from [`winit`] to an [`iced`] key code. /// /// [`winit`]: https://github.com/rust-windowing/winit -/// [`iced_native`]: https://github.com/iced-rs/iced/tree/0.9/native +/// [`iced`]: https://github.com/iced-rs/iced/tree/0.10 pub fn key_code( virtual_keycode: winit::event::VirtualKeyCode, ) -> keyboard::KeyCode { diff --git a/winit/src/lib.rs b/winit/src/lib.rs index 4776ea2c..1a87ca11 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -2,7 +2,7 @@ //! //! ![The native path of the Iced ecosystem](https://github.com/iced-rs/iced/blob/0525d76ff94e828b7b21634fa94a747022001c83/docs/graphs/native.png?raw=true) //! -//! `iced_winit` offers some convenient abstractions on top of [`iced_native`] +//! `iced_winit` offers some convenient abstractions on top of [`iced_runtime`] //! to quickstart development when using [`winit`]. //! //! It exposes a renderer-agnostic [`Application`] trait that can be implemented @@ -11,7 +11,7 @@ //! Additionally, a [`conversion`] module is available for users that decide to //! implement a custom event loop. //! -//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.9/native +//! [`iced_runtime`]: https://github.com/iced-rs/iced/tree/0.10/runtime //! [`winit`]: https://github.com/rust-windowing/winit //! [`conversion`]: crate::conversion #![doc( From d6c6d07ddaa170d288afd43bb117e188cdafcfa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 28 Jul 2023 19:49:36 +0200 Subject: [PATCH 043/321] Fix `iced_runtime` description --- runtime/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 7ee4f6b7..fac010b3 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -3,7 +3,7 @@ name = "iced_runtime" version = "0.1.0" authors = ["HĂ©ctor RamĂłn JimĂ©nez "] edition = "2021" -description = "The renderer-agnostic runtime for Iced" +description = "A renderer-agnostic runtime for Iced" license = "MIT" repository = "https://github.com/iced-rs/iced" From 8c7308d9cee3bb8a32b94024e461f612b1eafe04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 28 Jul 2023 19:55:45 +0200 Subject: [PATCH 044/321] Enable all features in `docs.rs` --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 05bb883d..71484b7a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,7 +75,7 @@ optional = true [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docsrs"] -features = ["image", "svg", "canvas", "qr_code"] +all-features = true [profile.release-opt] inherits = "release" From 7c772c35fe1cfddb903aa74dfb5f2a58ec0117d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 28 Jul 2023 19:59:31 +0200 Subject: [PATCH 045/321] Enable all features for `iced_widget` in `docs.rs` --- widget/Cargo.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/widget/Cargo.toml b/widget/Cargo.toml index 6e66689d..2cba4c5a 100644 --- a/widget/Cargo.toml +++ b/widget/Cargo.toml @@ -42,3 +42,7 @@ optional = true version = "0.12" optional = true default-features = false + +[package.metadata.docs.rs] +rustdoc-args = ["--cfg", "docsrs"] +all-features = true From 226e9d1cb9af6f42261a6269579d69080c7db091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 28 Jul 2023 20:02:44 +0200 Subject: [PATCH 046/321] Update `CHANGELOG` --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a338925..c1074065 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.10.0] - 2023-07-28 ### Added - Text shaping, font fallback, and `iced_wgpu` overhaul. [#1697](https://github.com/iced-rs/iced/pull/1697) - Software renderer, runtime renderer fallback, and core consolidation. [#1748](https://github.com/iced-rs/iced/pull/1748) @@ -564,7 +565,8 @@ Many thanks to... ### Added - First release! :tada: -[Unreleased]: https://github.com/iced-rs/iced/compare/0.9.0...HEAD +[Unreleased]: https://github.com/iced-rs/iced/compare/0.10.0...HEAD +[0.10.0]: https://github.com/iced-rs/iced/compare/0.9.0...0.10.0 [0.9.0]: https://github.com/iced-rs/iced/compare/0.8.0...0.9.0 [0.8.0]: https://github.com/iced-rs/iced/compare/0.7.0...0.8.0 [0.7.0]: https://github.com/iced-rs/iced/compare/0.6.0...0.7.0 From 16a8a494a46361c5bbb0f902a381a182c59a093e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 29 Jul 2023 19:48:04 +0200 Subject: [PATCH 047/321] Fix `Tooltip` overlay position inside `Scrollable` --- widget/src/tooltip.rs | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/widget/src/tooltip.rs b/widget/src/tooltip.rs index ff7f960f..faa3f3e1 100644 --- a/widget/src/tooltip.rs +++ b/widget/src/tooltip.rs @@ -314,7 +314,7 @@ where &self, renderer: &Renderer, bounds: Size, - _position: Point, + position: Point, ) -> layout::Node { let viewport = Rectangle::with_size(bounds); @@ -331,45 +331,43 @@ where ); let text_bounds = text_layout.bounds(); - let x_center = self.content_bounds.x - + (self.content_bounds.width - text_bounds.width) / 2.0; - let y_center = self.content_bounds.y + let x_center = + position.x + (self.content_bounds.width - text_bounds.width) / 2.0; + let y_center = position.y + (self.content_bounds.height - text_bounds.height) / 2.0; let mut tooltip_bounds = { let offset = match self.position { Position::Top => Vector::new( x_center, - self.content_bounds.y - - text_bounds.height - - self.gap - - self.padding, + position.y - text_bounds.height - self.gap - self.padding, ), Position::Bottom => Vector::new( x_center, - self.content_bounds.y + position.y + self.content_bounds.height + self.gap + self.padding, ), Position::Left => Vector::new( - self.content_bounds.x - - text_bounds.width - - self.gap - - self.padding, + position.x - text_bounds.width - self.gap - self.padding, y_center, ), Position::Right => Vector::new( - self.content_bounds.x + position.x + self.content_bounds.width + self.gap + self.padding, y_center, ), - Position::FollowCursor => Vector::new( - self.cursor_position.x, - self.cursor_position.y - text_bounds.height, - ), + Position::FollowCursor => { + let translation = position - self.content_bounds.position(); + + Vector::new( + self.cursor_position.x, + self.cursor_position.y - text_bounds.height, + ) + translation + } }; Rectangle { From 34ca3db1ca371ddaeb1196a2ad20d8945017c607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 29 Jul 2023 19:50:00 +0200 Subject: [PATCH 048/321] Update `CHANGELOG` --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1074065..9ab7b247 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -75,6 +75,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Quad rendering including border only inside of the bounds. [#1843](https://github.com/iced-rs/iced/pull/1843) - Redraw requests not being forwarded for `Component` overlays. [#1949](https://github.com/iced-rs/iced/pull/1949) - Blinking input cursor when window loses focus. [#1955](https://github.com/iced-rs/iced/pull/1955) +- `Tooltip` overlay position inside `Scrollable`. [#1978](https://github.com/iced-rs/iced/pull/1978) - `BorderRadius` not exposed in root crate. [#1972](https://github.com/iced-rs/iced/pull/1972) - Outdated `ROADMAP`. [#1958](https://github.com/iced-rs/iced/pull/1958) From 50ce65b3b7ad10a8537b751b3890d9dcfaecf846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 29 Jul 2023 20:08:07 +0200 Subject: [PATCH 049/321] Bump version of `iced_widget` :tada: --- widget/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget/Cargo.toml b/widget/Cargo.toml index 2cba4c5a..51319d29 100644 --- a/widget/Cargo.toml +++ b/widget/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_widget" -version = "0.1.1" +version = "0.1.2" authors = ["HĂ©ctor RamĂłn JimĂ©nez "] edition = "2021" description = "The built-in widgets for Iced" From 32a95171d2c2a7a7ac8c141277b8c3555dbb3e77 Mon Sep 17 00:00:00 2001 From: Casper Rogild Storm Date: Mon, 31 Jul 2023 22:59:42 +0200 Subject: [PATCH 050/321] cycle combobox with keybinds --- widget/src/combo_box.rs | 43 ++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs index 93fc92b9..c9397433 100644 --- a/widget/src/combo_box.rs +++ b/widget/src/combo_box.rs @@ -468,11 +468,13 @@ where if let Event::Keyboard(keyboard::Event::KeyPressed { key_code, + modifiers, .. }) = event { - match key_code { - keyboard::KeyCode::Enter => { + let shift_modifer = modifiers.shift(); + match (key_code, shift_modifer) { + (keyboard::KeyCode::Enter, _) => { if let Some(index) = &menu.hovered_option { if let Some(option) = state.filtered_options.options.get(*index) @@ -483,9 +485,19 @@ where event_status = event::Status::Captured; } - keyboard::KeyCode::Up => { + + (keyboard::KeyCode::Up, _) + | (keyboard::KeyCode::Tab, true) => { if let Some(index) = &mut menu.hovered_option { - *index = index.saturating_sub(1); + if *index == 0 { + *index = state + .filtered_options + .options + .len() + .saturating_sub(1); + } else { + *index = index.saturating_sub(1); + } } else { menu.hovered_option = Some(0); } @@ -511,15 +523,28 @@ where event_status = event::Status::Captured; } - keyboard::KeyCode::Down => { + (keyboard::KeyCode::Down, _) + | (keyboard::KeyCode::Tab, false) + if !modifiers.shift() => + { if let Some(index) = &mut menu.hovered_option { - *index = index.saturating_add(1).min( - state + if *index + == state .filtered_options .options .len() - .saturating_sub(1), - ); + .saturating_sub(1) + { + *index = 0; + } else { + *index = index.saturating_add(1).min( + state + .filtered_options + .options + .len() + .saturating_sub(1), + ); + } } else { menu.hovered_option = Some(0); } From e1da5fa63525cf749ec5ebbef42703fb761a0dd1 Mon Sep 17 00:00:00 2001 From: Casper Rogild Storm Date: Mon, 31 Jul 2023 23:07:35 +0200 Subject: [PATCH 051/321] Update widget/src/combo_box.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: HĂ©ctor RamĂłn --- widget/src/combo_box.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs index c9397433..5e36ec57 100644 --- a/widget/src/combo_box.rs +++ b/widget/src/combo_box.rs @@ -529,7 +529,7 @@ where { if let Some(index) = &mut menu.hovered_option { if *index - == state + >= state .filtered_options .options .len() From c7e17391c53c9aa076d76982189a5184681aac0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 2 Aug 2023 22:05:11 +0200 Subject: [PATCH 052/321] Fix `iced_wgpu` freezing on empty layers The `render` method would return when an empty layer is encountered without explicitly dropping the `RenderPass` (necessary because we use `ManuallyDrop`), which would then leak memory and freeze `wgpu` until the surface was recreated. --- wgpu/src/backend.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index 9966a38c..c6a17f2c 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -236,7 +236,7 @@ impl Backend { let bounds = (layer.bounds * scale_factor).snap(); if bounds.width < 1 || bounds.height < 1 { - return; + continue; } if !layer.quads.is_empty() { From a7609a723ff0102ef8f606ac2c3bbabc30974db9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 2 Aug 2023 22:08:14 +0200 Subject: [PATCH 053/321] Avoid empty overlay layer in `iced_wgpu` --- wgpu/src/backend.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index c6a17f2c..68d1f805 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -87,7 +87,10 @@ impl Backend { let transformation = viewport.projection(); let mut layers = Layer::generate(primitives, viewport); - layers.push(Layer::overlay(overlay_text, viewport)); + + if !overlay_text.is_empty() { + layers.push(Layer::overlay(overlay_text, viewport)); + } self.prepare( device, From 4dfa2f0abf9c8219d9f04980e9e5959d1a93b555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 2 Aug 2023 22:12:15 +0200 Subject: [PATCH 054/321] Update `CHANGELOG` --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ab7b247..c94c5de3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -78,6 +78,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Tooltip` overlay position inside `Scrollable`. [#1978](https://github.com/iced-rs/iced/pull/1978) - `BorderRadius` not exposed in root crate. [#1972](https://github.com/iced-rs/iced/pull/1972) - Outdated `ROADMAP`. [#1958](https://github.com/iced-rs/iced/pull/1958) +- `iced_wgpu` freezing on empty layers. [#1996](https://github.com/iced-rs/iced/pull/1996) Many thanks to... From 983764db6a65cad673d35d3112145a8e40e82be0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 2 Aug 2023 22:22:51 +0200 Subject: [PATCH 055/321] Update `CHANGELOG` --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ab7b247..f7e60030 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Nix instructions to `DEPENDENCIES.md`. [#1859](https://github.com/iced-rs/iced/pull/1859) - Loading spinners example. [#1902](https://github.com/iced-rs/iced/pull/1902) - Workflow that verifies `CHANGELOG` is always up-to-date. [#1970](https://github.com/iced-rs/iced/pull/1970) +- Keybinds to cycle `ComboBox` options. [#1991](https://github.com/iced-rs/iced/pull/1991) ### Changed - Updated `wgpu` to `0.16`. [#1807](https://github.com/iced-rs/iced/pull/1807) From b9e00590b9cc4ab6c855a1d6eaaa1fae34cdaca8 Mon Sep 17 00:00:00 2001 From: Ryan Scheidter Date: Sat, 29 Jul 2023 14:32:28 -0500 Subject: [PATCH 056/321] Update README.md to reflect native->runtime rename --- runtime/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/runtime/README.md b/runtime/README.md index 1b0fa857..35c7eb5e 100644 --- a/runtime/README.md +++ b/runtime/README.md @@ -1,12 +1,12 @@ # `iced_runtime` -[![Documentation](https://docs.rs/iced_native/badge.svg)][documentation] -[![Crates.io](https://img.shields.io/crates/v/iced_native.svg)](https://crates.io/crates/iced_native) -[![License](https://img.shields.io/crates/l/iced_native.svg)](https://github.com/iced-rs/iced/blob/master/LICENSE) +[![Documentation](https://docs.rs/iced_runtime/badge.svg)][documentation] +[![Crates.io](https://img.shields.io/crates/v/iced_runtime.svg)](https://crates.io/crates/iced_runtime) +[![License](https://img.shields.io/crates/l/iced_runtime.svg)](https://github.com/iced-rs/iced/blob/master/LICENSE) [![Discord Server](https://img.shields.io/discord/628993209984614400?label=&labelColor=6A7EC2&logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/3xZJ65GAhd) -`iced_runtime` takes [`iced_core`] and builds a native runtime on top of it. +`iced_runtime` takes [`iced_core`] and builds a runtime on top of it. -[documentation]: https://docs.rs/iced_native +[documentation]: https://docs.rs/iced_runtime [`iced_core`]: ../core [`iced_winit`]: ../winit [`druid`]: https://github.com/xi-editor/druid From 5493f94984d8babda692177ff9cd540bdd178000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 2 Aug 2023 22:25:21 +0200 Subject: [PATCH 057/321] Update `CHANGELOG` --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2ffbed4..e3637149 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Loading spinners example. [#1902](https://github.com/iced-rs/iced/pull/1902) - Workflow that verifies `CHANGELOG` is always up-to-date. [#1970](https://github.com/iced-rs/iced/pull/1970) - Keybinds to cycle `ComboBox` options. [#1991](https://github.com/iced-rs/iced/pull/1991) +- Outdated mentions of `iced_native` in `README`. [#1979](https://github.com/iced-rs/iced/pull/1979) ### Changed - Updated `wgpu` to `0.16`. [#1807](https://github.com/iced-rs/iced/pull/1807) @@ -102,6 +103,7 @@ Many thanks to... - @nicoburns - @Redhawk18 - @RGBCube +- @rs017991 - @tarkah - @thunderstorm010 - @wash2 From 8a589084e1ecc049c78668b85f34791954e247c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 2 Aug 2023 22:29:24 +0200 Subject: [PATCH 058/321] Bump version of `iced_widget` :tada: --- widget/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget/Cargo.toml b/widget/Cargo.toml index 51319d29..128a7c38 100644 --- a/widget/Cargo.toml +++ b/widget/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_widget" -version = "0.1.2" +version = "0.1.3" authors = ["HĂ©ctor RamĂłn JimĂ©nez "] edition = "2021" description = "The built-in widgets for Iced" From 51ba0267a6e4f494197c5718b3c8d780d09f3497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 2 Aug 2023 22:29:39 +0200 Subject: [PATCH 059/321] Bump version of `iced_wgpu` :tada: --- wgpu/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index f3713eb9..69568099 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_wgpu" -version = "0.11.0" +version = "0.11.1" authors = ["HĂ©ctor RamĂłn JimĂ©nez "] edition = "2021" description = "A wgpu renderer for Iced" From dd6d8875585796252f6b54c950a1c9b143d00904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 2 Aug 2023 22:44:55 +0200 Subject: [PATCH 060/321] Bump version of `iced_runtime` :tada: --- runtime/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index fac010b3..9fbe4be7 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_runtime" -version = "0.1.0" +version = "0.1.1" authors = ["HĂ©ctor RamĂłn JimĂ©nez "] edition = "2021" description = "A renderer-agnostic runtime for Iced" From 004a1f3848fe279a6222c960f84ab271b792a7a0 Mon Sep 17 00:00:00 2001 From: Malcolm Ramsay Date: Thu, 3 Aug 2023 08:42:46 +0930 Subject: [PATCH 061/321] fix: Check cursor in bounds when scrolling image::Viewer Ensure that the cursor is within the bounds of the image::Viewer when performing the scrolling. Fixes #1997 --- widget/src/image/viewer.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/widget/src/image/viewer.rs b/widget/src/image/viewer.rs index 0038f858..c04ddfa6 100644 --- a/widget/src/image/viewer.rs +++ b/widget/src/image/viewer.rs @@ -154,7 +154,8 @@ where match event { Event::Mouse(mouse::Event::WheelScrolled { delta }) => { - let Some(cursor_position) = cursor.position() else { + // Ensure the cursor is within the bounds of the widget + let Some(cursor_position) = cursor.position_over(bounds) else { return event::Status::Ignored; }; From 085842e7651d1ff7794417fe787727347315c3e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 3 Aug 2023 20:18:31 +0200 Subject: [PATCH 062/321] Remove unnecessary comment in `image::viewer` --- widget/src/image/viewer.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/widget/src/image/viewer.rs b/widget/src/image/viewer.rs index c04ddfa6..6e095667 100644 --- a/widget/src/image/viewer.rs +++ b/widget/src/image/viewer.rs @@ -154,7 +154,6 @@ where match event { Event::Mouse(mouse::Event::WheelScrolled { delta }) => { - // Ensure the cursor is within the bounds of the widget let Some(cursor_position) = cursor.position_over(bounds) else { return event::Status::Ignored; }; From 30d5361f6369bb0f619191c38de51561bd4b26cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Thu, 3 Aug 2023 20:19:45 +0200 Subject: [PATCH 063/321] Update `CHANGELOG` --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3637149..8e838f8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -81,6 +81,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `BorderRadius` not exposed in root crate. [#1972](https://github.com/iced-rs/iced/pull/1972) - Outdated `ROADMAP`. [#1958](https://github.com/iced-rs/iced/pull/1958) - `iced_wgpu` freezing on empty layers. [#1996](https://github.com/iced-rs/iced/pull/1996) +- `image::Viewer` reacting to any scroll event. [#1998](https://github.com/iced-rs/iced/pull/1998) Many thanks to... @@ -99,6 +100,7 @@ Many thanks to... - @JonathanLindsey - @kr105 - @marienz +- @malramsay64 - @nicksenger - @nicoburns - @Redhawk18 From c81f4676fb39f7ac4a9129be3fbabe7888a88042 Mon Sep 17 00:00:00 2001 From: Casper Rogild Storm Date: Sat, 5 Aug 2023 21:47:02 +0200 Subject: [PATCH 064/321] ensure no paste with alt --- widget/src/text_input.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index b899eb67..ef6d31ac 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -842,7 +842,9 @@ where shell.publish(message); } keyboard::KeyCode::V => { - if state.keyboard_modifiers.command() { + if state.keyboard_modifiers.command() + && !state.keyboard_modifiers.alt() + { let content = match state.is_pasting.take() { Some(content) => content, None => { From 3940947db7f474ec97fe1030678f21a7f19a5c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 15 Aug 2023 07:21:59 +0200 Subject: [PATCH 065/321] Update `CHANGELOG` --- CHANGELOG.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e838f8d..14f0e48a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,7 +41,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Nix instructions to `DEPENDENCIES.md`. [#1859](https://github.com/iced-rs/iced/pull/1859) - Loading spinners example. [#1902](https://github.com/iced-rs/iced/pull/1902) - Workflow that verifies `CHANGELOG` is always up-to-date. [#1970](https://github.com/iced-rs/iced/pull/1970) -- Keybinds to cycle `ComboBox` options. [#1991](https://github.com/iced-rs/iced/pull/1991) - Outdated mentions of `iced_native` in `README`. [#1979](https://github.com/iced-rs/iced/pull/1979) ### Changed @@ -77,11 +76,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Quad rendering including border only inside of the bounds. [#1843](https://github.com/iced-rs/iced/pull/1843) - Redraw requests not being forwarded for `Component` overlays. [#1949](https://github.com/iced-rs/iced/pull/1949) - Blinking input cursor when window loses focus. [#1955](https://github.com/iced-rs/iced/pull/1955) -- `Tooltip` overlay position inside `Scrollable`. [#1978](https://github.com/iced-rs/iced/pull/1978) - `BorderRadius` not exposed in root crate. [#1972](https://github.com/iced-rs/iced/pull/1972) - Outdated `ROADMAP`. [#1958](https://github.com/iced-rs/iced/pull/1958) + +### Patched +- Keybinds to cycle `ComboBox` options. [#1991](https://github.com/iced-rs/iced/pull/1991) +- `Tooltip` overlay position inside `Scrollable`. [#1978](https://github.com/iced-rs/iced/pull/1978) - `iced_wgpu` freezing on empty layers. [#1996](https://github.com/iced-rs/iced/pull/1996) - `image::Viewer` reacting to any scroll event. [#1998](https://github.com/iced-rs/iced/pull/1998) +- `TextInput` pasting text when `Alt` key is pressed. [#2006](https://github.com/iced-rs/iced/pull/2006) Many thanks to... From f7760618b66c85576e8835207b22df1acf249624 Mon Sep 17 00:00:00 2001 From: Alexandra Reaves Date: Mon, 14 Aug 2023 14:33:26 -0400 Subject: [PATCH 066/321] fix dead link to `iced_native` in `README.md` --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9604aadb..508413e6 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ __Iced is currently experimental software.__ [Take a look at the roadmap], [scrollables]: https://gfycat.com/perkybaggybaboon-rust-gui [Debug overlay with performance metrics]: https://gfycat.com/incredibledarlingbee [Modular ecosystem]: ECOSYSTEM.md -[renderer-agnostic native runtime]: native/ +[renderer-agnostic native runtime]: runtime/ [`wgpu`]: https://github.com/gfx-rs/wgpu [`tiny-skia`]: https://github.com/RazrFalcon/tiny-skia [`iced_wgpu`]: wgpu/ From 72f7cf17e318a66743d0947e5a0f55cc71e7b609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 15 Aug 2023 07:27:46 +0200 Subject: [PATCH 067/321] Update `CHANGELOG` --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14f0e48a..f6a87c1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -85,6 +85,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `iced_wgpu` freezing on empty layers. [#1996](https://github.com/iced-rs/iced/pull/1996) - `image::Viewer` reacting to any scroll event. [#1998](https://github.com/iced-rs/iced/pull/1998) - `TextInput` pasting text when `Alt` key is pressed. [#2006](https://github.com/iced-rs/iced/pull/2006) +- Broken link to old `iced_native` crate in `README`. [#2024](https://github.com/iced-rs/iced/pull/2024) Many thanks to... @@ -106,6 +107,7 @@ Many thanks to... - @malramsay64 - @nicksenger - @nicoburns +- @NyxAlexandra - @Redhawk18 - @RGBCube - @rs017991 From f5b95629009ecde8c6f6388c8f33ec43d30d17d1 Mon Sep 17 00:00:00 2001 From: "Andrew Wheeler(Genusis)" Date: Tue, 15 Aug 2023 01:47:53 -0400 Subject: [PATCH 068/321] Bounds Contains update. (#2017) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * changed the way contains works to exclude <= for point.y and point.x on width and height check to avoid multiple selects * update changelog * Update `CHANGELOG` --------- Co-authored-by: HĂ©ctor RamĂłn JimĂ©nez --- CHANGELOG.md | 2 ++ core/src/rectangle.rs | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6a87c1a..5d9c7349 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -86,6 +86,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `image::Viewer` reacting to any scroll event. [#1998](https://github.com/iced-rs/iced/pull/1998) - `TextInput` pasting text when `Alt` key is pressed. [#2006](https://github.com/iced-rs/iced/pull/2006) - Broken link to old `iced_native` crate in `README`. [#2024](https://github.com/iced-rs/iced/pull/2024) +- `Rectangle::contains` being non-exclusive. [#2017](https://github.com/iced-rs/iced/pull/2017) Many thanks to... @@ -98,6 +99,7 @@ Many thanks to... - @clarkmoody - @Davidster - @Drakulix +- @genusistimelord - @GyulyVGC - @ids1024 - @jhff diff --git a/core/src/rectangle.rs b/core/src/rectangle.rs index db56aa18..c1c2eeac 100644 --- a/core/src/rectangle.rs +++ b/core/src/rectangle.rs @@ -74,9 +74,9 @@ impl Rectangle { /// Returns true if the given [`Point`] is contained in the [`Rectangle`]. pub fn contains(&self, point: Point) -> bool { self.x <= point.x - && point.x <= self.x + self.width + && point.x < self.x + self.width && self.y <= point.y - && point.y <= self.y + self.height + && point.y < self.y + self.height } /// Returns true if the current [`Rectangle`] is completely within the given From 76ffbbd06e53e2793cba7f7e640279b1f6ef1b12 Mon Sep 17 00:00:00 2001 From: Kxie <56177821+ua-kxie@users.noreply.github.com> Date: Mon, 7 Aug 2023 17:35:26 +0800 Subject: [PATCH 069/321] Update arc.rs with improved documentation added units and improved description to field comments of Arc and Ellipse structs. --- graphics/src/geometry/path/arc.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/graphics/src/geometry/path/arc.rs b/graphics/src/geometry/path/arc.rs index 2cdebb66..dd4fcf33 100644 --- a/graphics/src/geometry/path/arc.rs +++ b/graphics/src/geometry/path/arc.rs @@ -8,9 +8,9 @@ pub struct Arc { pub center: Point, /// The radius of the arc. pub radius: f32, - /// The start of the segment's angle, clockwise rotation. + /// The start of the segment's angle in radians, clockwise rotation from positive x-axis. pub start_angle: f32, - /// The end of the segment's angle, clockwise rotation. + /// The end of the segment's angle in radians, clockwise rotation from positive x-axis. pub end_angle: f32, } @@ -19,13 +19,13 @@ pub struct Arc { pub struct Elliptical { /// The center of the arc. pub center: Point, - /// The radii of the arc's ellipse, defining its axes. + /// The radii of the arc's ellipse. The horizontal and vertical half-dimensions of the ellipse will match the x and y values of the radii vector. pub radii: Vector, - /// The rotation of the arc's ellipse. + /// The clockwise rotation of the arc's ellipse. pub rotation: f32, - /// The start of the segment's angle, clockwise rotation. + /// The start of the segment's angle in radians, clockwise rotation from positive x-axis. pub start_angle: f32, - /// The end of the segment's angle, clockwise rotation. + /// The end of the segment's angle in radians, clockwise rotation from positive x-axis. pub end_angle: f32, } From 5dbf5adb0af83e3acc9d7c62bb75c0a83f8543bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 15 Aug 2023 07:53:32 +0200 Subject: [PATCH 070/321] Update `CHANGELOG` --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d9c7349..e69b26eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -87,6 +87,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `TextInput` pasting text when `Alt` key is pressed. [#2006](https://github.com/iced-rs/iced/pull/2006) - Broken link to old `iced_native` crate in `README`. [#2024](https://github.com/iced-rs/iced/pull/2024) - `Rectangle::contains` being non-exclusive. [#2017](https://github.com/iced-rs/iced/pull/2017) +- Documentation for `Arc` and `arc::Elliptical`. [#2008](https://github.com/iced-rs/iced/pull/2008) Many thanks to... @@ -115,6 +116,7 @@ Many thanks to... - @rs017991 - @tarkah - @thunderstorm010 +- @ua-kxie - @wash2 - @wiiznokes From c9c5be7b01fbf4c09368cba278942e4a9d985871 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Mary=C5=84czak?= Date: Wed, 16 Aug 2023 20:21:57 +0200 Subject: [PATCH 071/321] [docs] Don't use &mut self for view() --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 19e7456e..ff87e245 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -86,7 +86,7 @@ //! use iced::widget::{button, column, text, Column}; //! //! impl Counter { -//! pub fn view(&mut self) -> Column { +//! pub fn view(&self) -> Column { //! // We use a column: a simple vertical layout //! column![ //! // The increment button. We tell it to produce an From e86363837d8e3a6241a90cb5b895034f07106059 Mon Sep 17 00:00:00 2001 From: lufte Date: Fri, 18 Aug 2023 18:46:22 -0300 Subject: [PATCH 072/321] Make the style attribute available on Font --- core/src/font.rs | 13 +++++++++++++ tiny_skia/src/text.rs | 11 ++++++++++- wgpu/src/text.rs | 11 ++++++++++- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/core/src/font.rs b/core/src/font.rs index bb425fd6..7f647847 100644 --- a/core/src/font.rs +++ b/core/src/font.rs @@ -10,6 +10,8 @@ pub struct Font { pub weight: Weight, /// The [`Stretch`] of the [`Font`]. pub stretch: Stretch, + /// The [`Style`] of the [`Font`]. + pub style: Style, /// Whether if the [`Font`] is monospaced or not. pub monospaced: bool, } @@ -20,6 +22,7 @@ impl Font { family: Family::SansSerif, weight: Weight::Normal, stretch: Stretch::Normal, + style: Style::Normal, monospaced: false, }; @@ -100,3 +103,13 @@ pub enum Stretch { ExtraExpanded, UltraExpanded, } + +/// The style of some text. +#[allow(missing_docs)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)] +pub enum Style { + #[default] + Normal, + Italic, + Oblique, +} diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index 15f25740..08fde4bf 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -233,6 +233,14 @@ fn to_stretch(stretch: font::Stretch) -> cosmic_text::Stretch { } } +fn to_style(style: font::Style) -> cosmic_text::Style { + match style { + font::Style::Normal => cosmic_text::Style::Normal, + font::Style::Italic => cosmic_text::Style::Italic, + font::Style::Oblique => cosmic_text::Style::Oblique, + } +} + fn to_shaping(shaping: Shaping) -> cosmic_text::Shaping { match shaping { Shaping::Basic => cosmic_text::Shaping::Basic, @@ -411,7 +419,8 @@ impl Cache { cosmic_text::Attrs::new() .family(to_family(key.font.family)) .weight(to_weight(key.font.weight)) - .stretch(to_stretch(key.font.stretch)), + .stretch(to_stretch(key.font.stretch)) + .style(to_style(key.font.style)), to_shaping(key.shaping), ); diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index ef910c39..fb13545d 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -339,6 +339,14 @@ fn to_stretch(stretch: font::Stretch) -> glyphon::Stretch { } } +fn to_style(style: font::Style) -> glyphon::Style { + match style { + font::Style::Normal => glyphon::Style::Normal, + font::Style::Italic => glyphon::Style::Italic, + font::Style::Oblique => glyphon::Style::Oblique, + } +} + fn to_shaping(shaping: Shaping) -> glyphon::Shaping { match shaping { Shaping::Basic => glyphon::Shaping::Basic, @@ -420,7 +428,8 @@ impl Cache { glyphon::Attrs::new() .family(to_family(key.font.family)) .weight(to_weight(key.font.weight)) - .stretch(to_stretch(key.font.stretch)), + .stretch(to_stretch(key.font.stretch)) + .style(to_style(key.font.style)), to_shaping(key.shaping), ); From c31a63c1cc7191507beca451bcb391656a13e974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 21 Aug 2023 15:24:17 +0200 Subject: [PATCH 073/321] Update `CONTRIBUTING` guidelines --- CONTRIBUTING.md | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 412cf08f..9c4cacc8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,32 +2,21 @@ Thank you for considering contributing to Iced! Feel free to read [the ecosystem overview] and [the roadmap] to get an idea of the current state of the library. -The main advice for new contributors is to share your ideas with the community. Introduce yourself over our [Discord server] or [start a discussion in an issue](https://github.com/iced-rs/iced/issues) explaining what you have in mind (do not be afraid of duplicated issues!). +The core team is busy and does not have time to mentor nor babysit new contributors. If a member of the core team thinks that reviewing and understanding your work will take more time and effort than writing it from scratch by themselves, your contribution will be dismissed. It is your responsibility to communicate and figure out how to help us! -This is a very important step. It helps to coordinate work, get on the same page, and start building trust. Please, do not skip it! Remember that [Code is the Easy Part] and also [The Hard Parts of Open Source]! +The general advice for new contributors is to share your ideas with the community. Introduce yourself over our [Discord server] or [start a discussion](https://github.com/iced-rs/iced/discussions) explaining what you have in mind. This is a very important step. It helps to coordinate work, get on the same page, and start building trust. Remember that [Code is the Easy Part] and also [The Hard Parts of Open Source]! -Provided you get in touch first, all kinds of contributions are welcome! Here are a few interesting ideas: - -- New widgets: toggle, table, grid, color picker, video... -- New renderers: `iced_piet` (already in the works!), `iced_skia`, `iced_raqote`, `iced_pathfinder`... -- New shells: `iced_sdl` could be useful for gamedev! -- Better style generation for `iced_web` -- Optimizations for `iced_wgpu`: tiling, incremental rendering... -- Alternative to [`wgpu_glyph`] for proper (shaped), efficient text rendering -- Time travelling debugger built on top of Iced itself -- Testing library -- Cool website to serve on https://iced.rs +Once you have started a channel of communication, you must wait until someone from the core team chimes in. If the core team is busy, this can take a long time (maybe months!). Your idea may need a bunch of iteration, or it may turn into something completely different, or it may be completely discarded! You will have to be patient and humble. Remember that open-source is a gift. Besides directly writing code, there are many other different ways you can contribute. To name a few: - Writing tutorials or blog posts - Improving the documentation - Submitting bug reports and use cases -- Sharing, discussing, researching and exploring new ideas +- Sharing, discussing, researching and exploring new ideas or crates [the ecosystem overview]: ECOSYSTEM.md [the roadmap]: ROADMAP.md [Discord server]: https://discord.gg/3xZJ65GAhd [Code is the Easy Part]: https://youtu.be/DSjbTC-hvqQ?t=1138 [The Hard Parts of Open Source]: https://www.youtube.com/watch?v=o_4EX4dPppA -[`wgpu_glyph`]: https://github.com/hecrj/wgpu_glyph From f99f0a3644108579566b8eacf47edf653870b1d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 21 Aug 2023 15:24:41 +0200 Subject: [PATCH 074/321] Create `PULL_REQUEST_TEMPLATE` --- .github/PULL_REQUEST_TEMPLATE.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..c4e22460 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,3 @@ +The core team is busy and does not have time to mentor nor babysit new contributors. If a member of the core team thinks that reviewing and understanding your work will take more time and effort than writing it from scratch by themselves, your contribution will be dismissed. It is your responsibility to communicate and figure out how to help us! + +Read the contributing guide for more details: https://github.com/iced-rs/iced/blob/master/CONTRIBUTING.md From fb02040b39b5be5125c1ed2e0f14b92479ba3fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 21 Aug 2023 15:26:49 +0200 Subject: [PATCH 075/321] Clarify the `CONTRIBUTING` guidelines a bit --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- CONTRIBUTING.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index c4e22460..84668d7b 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,3 +1,3 @@ -The core team is busy and does not have time to mentor nor babysit new contributors. If a member of the core team thinks that reviewing and understanding your work will take more time and effort than writing it from scratch by themselves, your contribution will be dismissed. It is your responsibility to communicate and figure out how to help us! +The core team is busy and does not have time to mentor nor babysit new contributors. If a member of the core team thinks that reviewing and understanding your work will take more time and effort than writing it from scratch by themselves, your contribution will be dismissed. It is your responsibility to communicate and figure out how to reduce the likelihood of this! Read the contributing guide for more details: https://github.com/iced-rs/iced/blob/master/CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9c4cacc8..a3081b96 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ Thank you for considering contributing to Iced! Feel free to read [the ecosystem overview] and [the roadmap] to get an idea of the current state of the library. -The core team is busy and does not have time to mentor nor babysit new contributors. If a member of the core team thinks that reviewing and understanding your work will take more time and effort than writing it from scratch by themselves, your contribution will be dismissed. It is your responsibility to communicate and figure out how to help us! +The core team is busy and does not have time to mentor nor babysit new contributors. If a member of the core team thinks that reviewing and understanding your work will take more time and effort than writing it from scratch by themselves, your contribution will be dismissed. It is your responsibility to communicate and figure out how to reduce the likelihood of this! The general advice for new contributors is to share your ideas with the community. Introduce yourself over our [Discord server] or [start a discussion](https://github.com/iced-rs/iced/discussions) explaining what you have in mind. This is a very important step. It helps to coordinate work, get on the same page, and start building trust. Remember that [Code is the Easy Part] and also [The Hard Parts of Open Source]! From 7e5be8680b997aa10062617763c49f4497d95908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 21 Aug 2023 15:29:22 +0200 Subject: [PATCH 076/321] Replace `guide` with `guidelines` in `PULL_REQUEST_TEMPLATE` --- .github/PULL_REQUEST_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 84668d7b..224bb8f3 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,3 +1,3 @@ The core team is busy and does not have time to mentor nor babysit new contributors. If a member of the core team thinks that reviewing and understanding your work will take more time and effort than writing it from scratch by themselves, your contribution will be dismissed. It is your responsibility to communicate and figure out how to reduce the likelihood of this! -Read the contributing guide for more details: https://github.com/iced-rs/iced/blob/master/CONTRIBUTING.md +Read the contributing guidelines for more details: https://github.com/iced-rs/iced/blob/master/CONTRIBUTING.md From 398a3f08973f39ad7cb67a236b2e6b44e57d453b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 23 Aug 2023 20:50:31 +0200 Subject: [PATCH 077/321] Use `Dark` theme in `stopwatch` example --- examples/stopwatch/src/main.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/stopwatch/src/main.rs b/examples/stopwatch/src/main.rs index 9581a3ce..842ba3d4 100644 --- a/examples/stopwatch/src/main.rs +++ b/examples/stopwatch/src/main.rs @@ -134,4 +134,8 @@ impl Application for Stopwatch { .center_y() .into() } + + fn theme(&self) -> Theme { + Theme::Dark + } } From 0ae136b5737253e0e74c93e2491ef25f307b73e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 23 Aug 2023 21:01:15 +0200 Subject: [PATCH 078/321] Update vulnerable `env_logger` dependency in examples --- examples/game_of_life/Cargo.toml | 2 +- examples/multitouch/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/game_of_life/Cargo.toml b/examples/game_of_life/Cargo.toml index f0a794fb..6de45db6 100644 --- a/examples/game_of_life/Cargo.toml +++ b/examples/game_of_life/Cargo.toml @@ -10,4 +10,4 @@ iced = { path = "../..", features = ["canvas", "tokio", "debug"] } tokio = { version = "1.0", features = ["sync"] } itertools = "0.9" rustc-hash = "1.1" -env_logger = "0.9" +env_logger = "0.10" diff --git a/examples/multitouch/Cargo.toml b/examples/multitouch/Cargo.toml index f7c8c145..867312f8 100644 --- a/examples/multitouch/Cargo.toml +++ b/examples/multitouch/Cargo.toml @@ -8,5 +8,5 @@ publish = false [dependencies] iced = { path = "../..", features = ["canvas", "tokio", "debug"] } tokio = { version = "1.0", features = ["sync"] } -env_logger = "0.9" +env_logger = "0.10" voronator = "0.2" From 8830554e4d68289bf037757e5e3e71a50f334512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 23 Aug 2023 21:01:44 +0200 Subject: [PATCH 079/321] Update vulnerable `async-tungstenite` dependency in `websocket` example --- examples/websocket/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/websocket/Cargo.toml b/examples/websocket/Cargo.toml index 03b240c6..12af9658 100644 --- a/examples/websocket/Cargo.toml +++ b/examples/websocket/Cargo.toml @@ -10,7 +10,7 @@ iced = { path = "../..", features = ["tokio", "debug"] } once_cell = "1.15" [dependencies.async-tungstenite] -version = "0.16" +version = "0.23" features = ["tokio-rustls-webpki-roots"] [dependencies.tokio] From 96b435488ac911d8f3d7b5e75d1f690bf03a93e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 26 Aug 2023 01:27:01 +0200 Subject: [PATCH 080/321] Add new Discourse forum badge to `README` --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 508413e6..2f9d3db3 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ [![License](https://img.shields.io/crates/l/iced.svg)](https://github.com/iced-rs/iced/blob/master/LICENSE) [![Downloads](https://img.shields.io/crates/d/iced.svg)](https://crates.io/crates/iced) [![Test Status](https://img.shields.io/github/actions/workflow/status/iced-rs/iced/test.yml?branch=master&event=push&label=test)](https://github.com/iced-rs/iced/actions) +[![Discourse](https://img.shields.io/discourse/users?server=https%3A%2F%2Fdiscourse.iced.rs&logo=discourse&labelColor=202225&color=5e7ce2)](https://discourse.iced.rs) [![Discord Server](https://img.shields.io/discord/628993209984614400?label=&labelColor=6A7EC2&logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/3xZJ65GAhd) A cross-platform GUI library for Rust focused on simplicity and type-safety. From 36120d5685048f761caf4b6a12a4f3a6007f9363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 26 Aug 2023 01:31:11 +0200 Subject: [PATCH 081/321] Run `cargo fmt` with Rust 1.72 --- tiny_skia/src/geometry.rs | 12 +++++++++--- widget/src/scrollable.rs | 12 ++++++------ widget/src/text_input.rs | 8 ++++++-- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/tiny_skia/src/geometry.rs b/tiny_skia/src/geometry.rs index 9bd47556..0fae7364 100644 --- a/tiny_skia/src/geometry.rs +++ b/tiny_skia/src/geometry.rs @@ -39,7 +39,9 @@ impl Frame { } pub fn fill(&mut self, path: &Path, fill: impl Into) { - let Some(path) = convert_path(path) else { return }; + let Some(path) = convert_path(path) else { + return; + }; let fill = fill.into(); self.primitives @@ -57,7 +59,9 @@ impl Frame { size: Size, fill: impl Into, ) { - let Some(path) = convert_path(&Path::rectangle(top_left, size)) else { return }; + let Some(path) = convert_path(&Path::rectangle(top_left, size)) else { + return; + }; let fill = fill.into(); self.primitives @@ -73,7 +77,9 @@ impl Frame { } pub fn stroke<'a>(&mut self, path: &Path, stroke: impl Into>) { - let Some(path) = convert_path(path) else { return }; + let Some(path) = convert_path(path) else { + return; + }; let stroke = stroke.into(); let skia_stroke = into_stroke(&stroke); diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index 103e3944..a83ed985 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -593,7 +593,7 @@ pub fn update( match event { touch::Event::FingerPressed { .. } => { let Some(cursor_position) = cursor.position() else { - return event::Status::Ignored + return event::Status::Ignored; }; state.scroll_area_touched_at = Some(cursor_position); @@ -603,7 +603,7 @@ pub fn update( state.scroll_area_touched_at { let Some(cursor_position) = cursor.position() else { - return event::Status::Ignored + return event::Status::Ignored; }; let delta = Vector::new( @@ -648,7 +648,7 @@ pub fn update( | Event::Touch(touch::Event::FingerMoved { .. }) => { if let Some(scrollbar) = scrollbars.y { let Some(cursor_position) = cursor.position() else { - return event::Status::Ignored + return event::Status::Ignored; }; state.scroll_y_to( @@ -678,7 +678,7 @@ pub fn update( Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) | Event::Touch(touch::Event::FingerPressed { .. }) => { let Some(cursor_position) = cursor.position() else { - return event::Status::Ignored + return event::Status::Ignored; }; if let (Some(scroller_grabbed_at), Some(scrollbar)) = @@ -722,7 +722,7 @@ pub fn update( Event::Mouse(mouse::Event::CursorMoved { .. }) | Event::Touch(touch::Event::FingerMoved { .. }) => { let Some(cursor_position) = cursor.position() else { - return event::Status::Ignored + return event::Status::Ignored; }; if let Some(scrollbar) = scrollbars.x { @@ -753,7 +753,7 @@ pub fn update( Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) | Event::Touch(touch::Event::FingerPressed { .. }) => { let Some(cursor_position) = cursor.position() else { - return event::Status::Ignored + return event::Status::Ignored; }; if let (Some(scroller_grabbed_at), Some(scrollbar)) = diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index ef6d31ac..61fc0055 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -693,7 +693,9 @@ where let state = state(); if let Some(focus) = &mut state.is_focused { - let Some(on_input) = on_input else { return event::Status::Ignored }; + let Some(on_input) = on_input else { + return event::Status::Ignored; + }; if state.is_pasting.is_none() && !state.keyboard_modifiers.command() @@ -716,7 +718,9 @@ where let state = state(); if let Some(focus) = &mut state.is_focused { - let Some(on_input) = on_input else { return event::Status::Ignored }; + let Some(on_input) = on_input else { + return event::Status::Ignored; + }; let modifiers = state.keyboard_modifiers; focus.updated_at = Instant::now(); From e0eb19d4cd2002c449286e67abe9a88071cd4909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 26 Aug 2023 01:32:08 +0200 Subject: [PATCH 082/321] Fix consistency of Discourse badge in `README` --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2f9d3db3..f8165d3c 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![License](https://img.shields.io/crates/l/iced.svg)](https://github.com/iced-rs/iced/blob/master/LICENSE) [![Downloads](https://img.shields.io/crates/d/iced.svg)](https://crates.io/crates/iced) [![Test Status](https://img.shields.io/github/actions/workflow/status/iced-rs/iced/test.yml?branch=master&event=push&label=test)](https://github.com/iced-rs/iced/actions) -[![Discourse](https://img.shields.io/discourse/users?server=https%3A%2F%2Fdiscourse.iced.rs&logo=discourse&labelColor=202225&color=5e7ce2)](https://discourse.iced.rs) +[![Discourse](https://img.shields.io/discourse/users?server=https%3A%2F%2Fdiscourse.iced.rs&color=5e7ce2)](https://discourse.iced.rs) [![Discord Server](https://img.shields.io/discord/628993209984614400?label=&labelColor=6A7EC2&logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/3xZJ65GAhd) A cross-platform GUI library for Rust focused on simplicity and type-safety. From 8ed06dc356e0296f0b800d4d6b92998bd4444cc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 26 Aug 2023 01:34:42 +0200 Subject: [PATCH 083/321] Fix `clippy` lints for Rust 1.72 --- runtime/src/user_interface.rs | 2 +- src/lib.rs | 1 + widget/src/combo_box.rs | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/runtime/src/user_interface.rs b/runtime/src/user_interface.rs index 5e910eab..e529c004 100644 --- a/runtime/src/user_interface.rs +++ b/runtime/src/user_interface.rs @@ -291,7 +291,7 @@ where let event_statuses = events .iter() .cloned() - .zip(overlay_statuses.into_iter()) + .zip(overlay_statuses) .map(|(event, overlay_status)| { if matches!(overlay_status, event::Status::Captured) { return overlay_status; diff --git a/src/lib.rs b/src/lib.rs index ff87e245..36f48ba2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -268,6 +268,7 @@ pub mod touch { pub use crate::core::touch::{Event, Finger}; } +#[allow(hidden_glob_reexports)] pub mod widget { //! Use the built-in widgets or create your own. pub use iced_widget::*; diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs index 5e36ec57..690ef27c 100644 --- a/widget/src/combo_box.rs +++ b/widget/src/combo_box.rs @@ -735,7 +735,7 @@ where options .into_iter() - .zip(option_matchers.into_iter()) + .zip(option_matchers) // Make sure each part of the query is found in the option .filter_map(move |(option, matcher)| { if query.iter().all(|part| matcher.as_ref().contains(part)) { From c9bd48704dd9679c033dd0b8588e2744a3df44a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sat, 26 Aug 2023 19:32:09 +0200 Subject: [PATCH 084/321] Replace GitHub discussions with Discourse --- .github/ISSUE_TEMPLATE/config.yml | 10 +++++----- CONTRIBUTING.md | 5 +++-- README.md | 10 +++++----- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 00e4748d..5177386c 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,11 +1,11 @@ blank_issues_enabled: false contact_links: - name: I have a question - url: https://github.com/iced-rs/iced/discussions/new?category=q-a - about: Open a discussion with a Q&A format. + url: https://discourse.iced.rs/c/learn/6 + about: Ask and learn from others in the Discourse forum. - name: I want to start a discussion - url: https://github.com/iced-rs/iced/discussions/new - about: Open a new discussion if you have any suggestions, ideas, feature requests, or simply want to show off something you've made. + url: https://discourse.iced.rs/c/request-feedback/7 + about: Share your idea and gather feedback in the Discourse forum. - name: I want to chat with other users of the library url: https://discord.com/invite/3xZJ65GAhd - about: Join the Discord Server and get involved with the community! + about: Join the Discord server and get involved with the community! diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a3081b96..c01acc4e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,7 @@ Thank you for considering contributing to Iced! Feel free to read [the ecosystem The core team is busy and does not have time to mentor nor babysit new contributors. If a member of the core team thinks that reviewing and understanding your work will take more time and effort than writing it from scratch by themselves, your contribution will be dismissed. It is your responsibility to communicate and figure out how to reduce the likelihood of this! -The general advice for new contributors is to share your ideas with the community. Introduce yourself over our [Discord server] or [start a discussion](https://github.com/iced-rs/iced/discussions) explaining what you have in mind. This is a very important step. It helps to coordinate work, get on the same page, and start building trust. Remember that [Code is the Easy Part] and also [The Hard Parts of Open Source]! +The general advice for new contributors is to share your ideas with the community. You can share your ideas and gather feedback in [our Discourse forum]. This is a very important step. It helps to coordinate work, get on the same page, and start building trust. Remember that [Code is the Easy Part] and also [The Hard Parts of Open Source]! Once you have started a channel of communication, you must wait until someone from the core team chimes in. If the core team is busy, this can take a long time (maybe months!). Your idea may need a bunch of iteration, or it may turn into something completely different, or it may be completely discarded! You will have to be patient and humble. Remember that open-source is a gift. @@ -17,6 +17,7 @@ Besides directly writing code, there are many other different ways you can contr [the ecosystem overview]: ECOSYSTEM.md [the roadmap]: ROADMAP.md -[Discord server]: https://discord.gg/3xZJ65GAhd +[our Discourse fourm]: https://discourse.iced.rs/ +[our Discord server]: https://discord.gg/3xZJ65GAhd [Code is the Easy Part]: https://youtu.be/DSjbTC-hvqQ?t=1138 [The Hard Parts of Open Source]: https://www.youtube.com/watch?v=o_4EX4dPppA diff --git a/README.md b/README.md index f8165d3c..431f14f9 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![License](https://img.shields.io/crates/l/iced.svg)](https://github.com/iced-rs/iced/blob/master/LICENSE) [![Downloads](https://img.shields.io/crates/d/iced.svg)](https://crates.io/crates/iced) [![Test Status](https://img.shields.io/github/actions/workflow/status/iced-rs/iced/test.yml?branch=master&event=push&label=test)](https://github.com/iced-rs/iced/actions) -[![Discourse](https://img.shields.io/discourse/users?server=https%3A%2F%2Fdiscourse.iced.rs&color=5e7ce2)](https://discourse.iced.rs) +[![Discourse](https://img.shields.io/discourse/users?server=https%3A%2F%2Fdiscourse.iced.rs&color=5e7ce2)](https://discourse.iced.rs/) [![Discord Server](https://img.shields.io/discord/628993209984614400?label=&labelColor=6A7EC2&logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/3xZJ65GAhd) A cross-platform GUI library for Rust focused on simplicity and type-safety. @@ -202,8 +202,8 @@ end-user-oriented GUI library, while keeping [the ecosystem] modular: Contributions are greatly appreciated! If you want to contribute, please read our [contributing guidelines] for more details. -Feedback is also welcome! You can open a discussion or come chat to our -[Discord server]. +Feedback is also welcome! You can create a new topic in [our Discourse forum] or +come chat to [our Discord server]. ## Sponsors @@ -216,7 +216,7 @@ The development of Iced is sponsored by the [Cryptowatch] team at [Kraken.com] [The Elm Architecture]: https://guide.elm-lang.org/architecture/ [the current issues]: https://github.com/iced-rs/iced/issues [contributing guidelines]: https://github.com/iced-rs/iced/blob/master/CONTRIBUTING.md -[Discord server]: https://discord.gg/3xZJ65GAhd -[Rust Community Discord]: https://bit.ly/rust-community +[our Discourse forum]: https://discourse.iced.rs/ +[our Discord server]: https://discord.gg/3xZJ65GAhd [Cryptowatch]: https://cryptowat.ch/charts [Kraken.com]: https://kraken.com/ From ed3454301e663a7cb7d73cd56b57b188f4d14a2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 30 Aug 2023 04:31:21 +0200 Subject: [PATCH 085/321] Implement explicit text caching in the widget state tree --- core/src/element.rs | 6 +- core/src/layout.rs | 28 +- core/src/layout/flex.rs | 12 +- core/src/renderer.rs | 15 +- core/src/renderer/null.rs | 96 +++- core/src/text.rs | 167 ++++--- core/src/widget.rs | 3 +- core/src/widget/text.rs | 136 +++-- examples/color_palette/src/main.rs | 6 +- examples/combo_box/src/main.rs | 1 - examples/custom_quad/src/main.rs | 1 + examples/custom_widget/src/main.rs | 1 + examples/game_of_life/src/main.rs | 2 +- examples/geometry/src/main.rs | 1 + examples/integration/src/main.rs | 13 +- examples/loading_spinners/src/circular.rs | 1 + examples/loading_spinners/src/linear.rs | 1 + examples/modal/src/main.rs | 11 +- examples/toast/src/main.rs | 6 +- examples/tour/src/main.rs | 4 +- graphics/Cargo.toml | 11 + {tiny_skia => graphics}/fonts/Iced-Icons.ttf | Bin graphics/src/backend.rs | 69 +-- graphics/src/damage.rs | 26 + graphics/src/geometry/text.rs | 6 +- graphics/src/lib.rs | 3 +- graphics/src/primitive.rs | 14 +- graphics/src/renderer.rs | 131 +++-- graphics/src/text.rs | 113 +++++ graphics/src/text/cache.rs | 120 +++++ graphics/src/text/paragraph.rs | 246 ++++++++++ renderer/src/compositor.rs | 19 +- renderer/src/lib.rs | 73 ++- renderer/src/settings.rs | 6 +- runtime/src/user_interface.rs | 17 +- src/settings.rs | 6 +- tiny_skia/src/backend.rs | 105 ++-- tiny_skia/src/settings.rs | 6 +- tiny_skia/src/text.rs | 305 ++---------- tiny_skia/src/window/compositor.rs | 15 +- wgpu/Cargo.toml | 9 - wgpu/fonts/Iced-Icons.ttf | Bin 5108 -> 0 bytes wgpu/src/backend.rs | 75 +-- wgpu/src/layer.rs | 29 +- wgpu/src/layer/text.rs | 19 +- wgpu/src/lib.rs | 2 +- wgpu/src/settings.rs | 6 +- wgpu/src/text.rs | 491 +++++-------------- wgpu/src/window/compositor.rs | 9 +- widget/src/button.rs | 23 +- widget/src/canvas.rs | 1 + widget/src/checkbox.rs | 103 ++-- widget/src/column.rs | 2 + widget/src/combo_box.rs | 167 +++---- widget/src/container.rs | 38 +- widget/src/image.rs | 1 + widget/src/image/viewer.rs | 1 + widget/src/lazy.rs | 3 +- widget/src/lazy/component.rs | 3 +- widget/src/lazy/responsive.rs | 17 +- widget/src/mouse_area.rs | 3 +- widget/src/overlay/menu.rs | 54 +- widget/src/pane_grid.rs | 13 +- widget/src/pane_grid/content.rs | 13 +- widget/src/pane_grid/title_bar.rs | 18 +- widget/src/pick_list.rs | 200 +++++--- widget/src/progress_bar.rs | 1 + widget/src/qr_code.rs | 1 + widget/src/radio.rs | 72 +-- widget/src/row.rs | 2 + widget/src/rule.rs | 1 + widget/src/scrollable.rs | 7 +- widget/src/slider.rs | 1 + widget/src/space.rs | 1 + widget/src/svg.rs | 1 + widget/src/text_input.rs | 322 ++++++------ widget/src/toggler.rs | 86 ++-- widget/src/tooltip.rs | 17 +- widget/src/vertical_slider.rs | 1 + 79 files changed, 1910 insertions(+), 1705 deletions(-) rename {tiny_skia => graphics}/fonts/Iced-Icons.ttf (100%) create mode 100644 graphics/src/text.rs create mode 100644 graphics/src/text/cache.rs create mode 100644 graphics/src/text/paragraph.rs delete mode 100644 wgpu/fonts/Iced-Icons.ttf diff --git a/core/src/element.rs b/core/src/element.rs index d2c6358b..0d23a9e7 100644 --- a/core/src/element.rs +++ b/core/src/element.rs @@ -306,10 +306,11 @@ where fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - self.widget.layout(renderer, limits) + self.widget.layout(tree, renderer, limits) } fn operate( @@ -491,10 +492,11 @@ where fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - self.element.widget.layout(renderer, limits) + self.element.widget.layout(tree, renderer, limits) } fn operate( diff --git a/core/src/layout.rs b/core/src/layout.rs index 04954fb9..50ccf1f4 100644 --- a/core/src/layout.rs +++ b/core/src/layout.rs @@ -7,7 +7,7 @@ pub mod flex; pub use limits::Limits; pub use node::Node; -use crate::{Point, Rectangle, Vector}; +use crate::{Point, Rectangle, Size, Vector}; /// The bounds of a [`Node`] and its children, using absolute coordinates. #[derive(Debug, Clone, Copy)] @@ -63,3 +63,29 @@ impl<'a> Layout<'a> { }) } } + +/// Produces a [`Node`] with two children nodes one right next to each other. +pub fn next_to_each_other( + limits: &Limits, + spacing: f32, + left: impl FnOnce(&Limits) -> Node, + right: impl FnOnce(&Limits) -> Node, +) -> Node { + let left_node = left(limits); + let left_size = left_node.size(); + + let right_limits = limits.shrink(Size::new(left_size.width + spacing, 0.0)); + + let mut right_node = right(&right_limits); + let right_size = right_node.size(); + + right_node.move_to(Point::new(left_size.width + spacing, 0.0)); + + Node::with_children( + Size::new( + left_size.width + spacing + right_size.width, + left_size.height.max(right_size.height), + ), + vec![left_node, right_node], + ) +} diff --git a/core/src/layout/flex.rs b/core/src/layout/flex.rs index 8b967849..86b1a45b 100644 --- a/core/src/layout/flex.rs +++ b/core/src/layout/flex.rs @@ -19,6 +19,7 @@ use crate::Element; use crate::layout::{Limits, Node}; +use crate::widget; use crate::{Alignment, Padding, Point, Size}; /// The main axis of a flex layout. @@ -66,6 +67,7 @@ pub fn resolve( spacing: f32, align_items: Alignment, items: &[Element<'_, Message, Renderer>], + trees: &[widget::Tree], ) -> Node where Renderer: crate::Renderer, @@ -81,7 +83,7 @@ where let mut nodes: Vec = Vec::with_capacity(items.len()); nodes.resize(items.len(), Node::default()); - for (i, child) in items.iter().enumerate() { + for (i, (child, tree)) in items.iter().zip(trees).enumerate() { let fill_factor = match axis { Axis::Horizontal => child.as_widget().width(), Axis::Vertical => child.as_widget().height(), @@ -94,7 +96,8 @@ where let child_limits = Limits::new(Size::ZERO, Size::new(max_width, max_height)); - let layout = child.as_widget().layout(renderer, &child_limits); + let layout = + child.as_widget().layout(tree, renderer, &child_limits); let size = layout.size(); available -= axis.main(size); @@ -108,7 +111,7 @@ where let remaining = available.max(0.0); - for (i, child) in items.iter().enumerate() { + for (i, (child, tree)) in items.iter().zip(trees).enumerate() { let fill_factor = match axis { Axis::Horizontal => child.as_widget().width(), Axis::Vertical => child.as_widget().height(), @@ -133,7 +136,8 @@ where Size::new(max_width, max_height), ); - let layout = child.as_widget().layout(renderer, &child_limits); + let layout = + child.as_widget().layout(tree, renderer, &child_limits); cross = cross.max(axis.cross(layout.size())); nodes[i] = layout; diff --git a/core/src/renderer.rs b/core/src/renderer.rs index 7c73d2e4..1b327e56 100644 --- a/core/src/renderer.rs +++ b/core/src/renderer.rs @@ -5,26 +5,13 @@ mod null; #[cfg(debug_assertions)] pub use null::Null; -use crate::layout; -use crate::{Background, BorderRadius, Color, Element, Rectangle, Vector}; +use crate::{Background, BorderRadius, Color, Rectangle, Vector}; /// A component that can be used by widgets to draw themselves on a screen. pub trait Renderer: Sized { /// The supported theme of the [`Renderer`]. type Theme; - /// Lays out the elements of a user interface. - /// - /// You should override this if you need to perform any operations before or - /// after layouting. For instance, trimming the measurements cache. - fn layout( - &mut self, - element: &Element<'_, Message, Self>, - limits: &layout::Limits, - ) -> layout::Node { - element.as_widget().layout(self, limits) - } - /// Draws the primitives recorded in the given closure in a new layer. /// /// The layer will clip its contents to the provided `bounds`. diff --git a/core/src/renderer/null.rs b/core/src/renderer/null.rs index 5d49699e..55d58a59 100644 --- a/core/src/renderer/null.rs +++ b/core/src/renderer/null.rs @@ -1,6 +1,7 @@ +use crate::alignment; use crate::renderer::{self, Renderer}; use crate::text::{self, Text}; -use crate::{Background, Font, Point, Rectangle, Size, Vector}; +use crate::{Background, Color, Font, Pixels, Point, Rectangle, Size, Vector}; use std::borrow::Cow; @@ -41,6 +42,7 @@ impl Renderer for Null { impl text::Renderer for Null { type Font = Font; + type Paragraph = (); const ICON_FONT: Font = Font::DEFAULT; const CHECKMARK_ICON: char = '0'; @@ -50,37 +52,83 @@ impl text::Renderer for Null { Font::default() } - fn default_size(&self) -> f32 { - 16.0 + fn default_size(&self) -> Pixels { + Pixels(16.0) } fn load_font(&mut self, _font: Cow<'static, [u8]>) {} - fn measure( - &self, - _content: &str, - _size: f32, - _line_height: text::LineHeight, - _font: Font, - _bounds: Size, - _shaping: text::Shaping, - ) -> Size { - Size::new(0.0, 20.0) + fn create_paragraph(&self, _text: Text<'_, Self::Font>) -> Self::Paragraph { } - fn hit_test( + fn resize_paragraph( &self, - _contents: &str, - _size: f32, - _line_height: text::LineHeight, - _font: Self::Font, - _bounds: Size, - _shaping: text::Shaping, - _point: Point, - _nearest_only: bool, - ) -> Option { + _paragraph: &mut Self::Paragraph, + _new_bounds: Size, + ) { + } + + fn fill_paragraph( + &mut self, + _paragraph: &Self::Paragraph, + _position: Point, + _color: Color, + ) { + } + + fn fill_text( + &mut self, + _paragraph: Text<'_, Self::Font>, + _position: Point, + _color: Color, + ) { + } +} + +impl text::Paragraph for () { + type Font = Font; + + fn content(&self) -> &str { + "" + } + + fn text_size(&self) -> Pixels { + Pixels(16.0) + } + + fn font(&self) -> Self::Font { + Font::default() + } + + fn line_height(&self) -> text::LineHeight { + text::LineHeight::default() + } + + fn shaping(&self) -> text::Shaping { + text::Shaping::default() + } + + fn horizontal_alignment(&self) -> alignment::Horizontal { + alignment::Horizontal::Left + } + + fn vertical_alignment(&self) -> alignment::Vertical { + alignment::Vertical::Top + } + + fn grapheme_position(&self, _line: usize, _index: usize) -> Option { None } - fn fill_text(&mut self, _text: Text<'_, Self::Font>) {} + fn bounds(&self) -> Size { + Size::ZERO + } + + fn min_bounds(&self) -> Size { + Size::ZERO + } + + fn hit_test(&self, _point: Point) -> Option { + None + } } diff --git a/core/src/text.rs b/core/src/text.rs index fc8aa20e..c59c683a 100644 --- a/core/src/text.rs +++ b/core/src/text.rs @@ -1,6 +1,6 @@ //! Draw and interact with text. use crate::alignment; -use crate::{Color, Pixels, Point, Rectangle, Size}; +use crate::{Color, Pixels, Point, Size}; use std::borrow::Cow; use std::hash::{Hash, Hasher}; @@ -12,17 +12,14 @@ pub struct Text<'a, Font> { pub content: &'a str, /// The bounds of the paragraph. - pub bounds: Rectangle, + pub bounds: Size, /// The size of the [`Text`] in logical pixels. - pub size: f32, + pub size: Pixels, /// The line height of the [`Text`]. pub line_height: LineHeight, - /// The color of the [`Text`]. - pub color: Color, - /// The font of the [`Text`]. pub font: Font, @@ -132,7 +129,10 @@ impl Hit { /// A renderer capable of measuring and drawing [`Text`]. pub trait Renderer: crate::Renderer { /// The font type used. - type Font: Copy; + type Font: Copy + PartialEq; + + /// The [`Paragraph`] of this [`Renderer`]. + type Paragraph: Paragraph + 'static; /// The icon font of the backend. const ICON_FONT: Self::Font; @@ -151,62 +151,107 @@ pub trait Renderer: crate::Renderer { fn default_font(&self) -> Self::Font; /// Returns the default size of [`Text`]. - fn default_size(&self) -> f32; - - /// Measures the text in the given bounds and returns the minimum boundaries - /// that can fit the contents. - fn measure( - &self, - content: &str, - size: f32, - line_height: LineHeight, - font: Self::Font, - bounds: Size, - shaping: Shaping, - ) -> Size; - - /// Measures the width of the text as if it were laid out in a single line. - fn measure_width( - &self, - content: &str, - size: f32, - font: Self::Font, - shaping: Shaping, - ) -> f32 { - let bounds = self.measure( - content, - size, - LineHeight::Absolute(Pixels(size)), - font, - Size::INFINITY, - shaping, - ); - - bounds.width - } - - /// Tests whether the provided point is within the boundaries of text - /// laid out with the given parameters, returning information about - /// the nearest character. - /// - /// If `nearest_only` is true, the hit test does not consider whether the - /// the point is interior to any glyph bounds, returning only the character - /// with the nearest centeroid. - fn hit_test( - &self, - contents: &str, - size: f32, - line_height: LineHeight, - font: Self::Font, - bounds: Size, - shaping: Shaping, - point: Point, - nearest_only: bool, - ) -> Option; + fn default_size(&self) -> Pixels; /// Loads a [`Self::Font`] from its bytes. fn load_font(&mut self, font: Cow<'static, [u8]>); - /// Draws the given [`Text`]. - fn fill_text(&mut self, text: Text<'_, Self::Font>); + /// Creates a new [`Paragraph`] laid out with the given [`Text`]. + fn create_paragraph(&self, text: Text<'_, Self::Font>) -> Self::Paragraph; + + /// Lays out the given [`Paragraph`] with some new boundaries. + fn resize_paragraph( + &self, + paragraph: &mut Self::Paragraph, + new_bounds: Size, + ); + + /// Updates a [`Paragraph`] to match the given [`Text`], if needed. + fn update_paragraph( + &self, + paragraph: &mut Self::Paragraph, + text: Text<'_, Self::Font>, + ) { + if paragraph.content() != text.content + || paragraph.text_size() != text.size + || paragraph.line_height().to_absolute(text.size) + != text.line_height.to_absolute(text.size) + || paragraph.font() != text.font + || paragraph.shaping() != text.shaping + || paragraph.horizontal_alignment() != text.horizontal_alignment + || paragraph.vertical_alignment() != text.vertical_alignment + { + *paragraph = self.create_paragraph(text); + } else if paragraph.bounds() != text.bounds { + self.resize_paragraph(paragraph, text.bounds); + } + } + + /// Draws the given [`Paragraph`] at the given position and with the given + /// [`Color`]. + fn fill_paragraph( + &mut self, + text: &Self::Paragraph, + position: Point, + color: Color, + ); + + /// Draws the given [`Text`] at the given position and with the given + /// [`Color`]. + fn fill_text( + &mut self, + text: Text<'_, Self::Font>, + position: Point, + color: Color, + ); +} +/// A text paragraph. +pub trait Paragraph: Default { + /// The font of this [`Paragraph`]. + type Font; + + /// Returns the content of the [`Paragraph`]. + fn content(&self) -> &str; + + /// Returns the text size of the [`Paragraph`]. + fn text_size(&self) -> Pixels; + + /// Returns the [`LineHeight`] of the [`Paragraph`]. + fn line_height(&self) -> LineHeight; + + /// Returns the [`Font`] of the [`Paragraph`]. + fn font(&self) -> Self::Font; + + /// Returns the [`Shaping`] strategy of the [`Paragraph`]. + fn shaping(&self) -> Shaping; + + /// Returns the horizontal alignment of the [`Paragraph`]. + fn horizontal_alignment(&self) -> alignment::Horizontal; + + /// Returns the vertical alignment of the [`Paragraph`]. + fn vertical_alignment(&self) -> alignment::Vertical; + + /// Returns the boundaries of the [`Paragraph`]. + fn bounds(&self) -> Size; + + /// Returns the minimum boundaries that can fit the contents of the + /// [`Paragraph`]. + fn min_bounds(&self) -> Size; + + /// Tests whether the provided point is within the boundaries of the + /// [`Paragraph`], returning information about the nearest character. + fn hit_test(&self, point: Point) -> Option; + + /// Returns the distance to the given grapheme index in the [`Paragraph`]. + fn grapheme_position(&self, line: usize, index: usize) -> Option; + + /// Returns the minimum width that can fit the contents of the [`Paragraph`]. + fn min_width(&self) -> f32 { + self.min_bounds().width + } + + /// Returns the minimum height that can fit the contents of the [`Paragraph`]. + fn min_height(&self) -> f32 { + self.min_bounds().height + } } diff --git a/core/src/widget.rs b/core/src/widget.rs index d6a99208..70328ff7 100644 --- a/core/src/widget.rs +++ b/core/src/widget.rs @@ -55,6 +55,7 @@ where /// user interface. fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node; @@ -62,7 +63,7 @@ where /// Draws the [`Widget`] using the associated `Renderer`. fn draw( &self, - state: &Tree, + tree: &Tree, renderer: &mut Renderer, theme: &Renderer::Theme, style: &renderer::Style, diff --git a/core/src/widget/text.rs b/core/src/widget/text.rs index 79df2b02..0405537b 100644 --- a/core/src/widget/text.rs +++ b/core/src/widget/text.rs @@ -3,11 +3,12 @@ use crate::alignment; use crate::layout; use crate::mouse; use crate::renderer; -use crate::text; -use crate::widget::Tree; -use crate::{Color, Element, Layout, Length, Pixels, Rectangle, Widget}; +use crate::text::{self, Paragraph as _}; +use crate::widget::tree::{self, Tree}; +use crate::{Color, Element, Layout, Length, Pixels, Point, Rectangle, Widget}; use std::borrow::Cow; +use std::cell::RefCell; pub use text::{LineHeight, Shaping}; @@ -19,7 +20,7 @@ where Renderer::Theme: StyleSheet, { content: Cow<'a, str>, - size: Option, + size: Option, line_height: LineHeight, width: Length, height: Length, @@ -53,7 +54,7 @@ where /// Sets the size of the [`Text`]. pub fn size(mut self, size: impl Into) -> Self { - self.size = Some(size.into().0); + self.size = Some(size.into()); self } @@ -117,11 +118,23 @@ where } } +/// The internal state of a [`Text`] widget. +#[derive(Debug, Default)] +pub struct State(RefCell); + impl<'a, Message, Renderer> Widget for Text<'a, Renderer> where Renderer: text::Renderer, Renderer::Theme: StyleSheet, { + fn tag(&self) -> tree::Tag { + tree::Tag::of::>() + } + + fn state(&self) -> tree::State { + tree::State::new(State(RefCell::new(Renderer::Paragraph::default()))) + } + fn width(&self) -> Length { self.width } @@ -132,30 +145,29 @@ where fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - let limits = limits.width(self.width).height(self.height); - - let size = self.size.unwrap_or_else(|| renderer.default_size()); - - let bounds = renderer.measure( + layout( + tree.state.downcast_ref::>(), + renderer, + limits, + self.width, + self.height, &self.content, - size, self.line_height, - self.font.unwrap_or_else(|| renderer.default_font()), - limits.max(), + self.size, + self.font, + self.horizontal_alignment, + self.vertical_alignment, self.shaping, - ); - - let size = limits.resolve(bounds); - - layout::Node::new(size) + ) } fn draw( &self, - _state: &Tree, + tree: &Tree, renderer: &mut Renderer, theme: &Renderer::Theme, style: &renderer::Style, @@ -163,22 +175,63 @@ where _cursor_position: mouse::Cursor, _viewport: &Rectangle, ) { + let state = tree.state.downcast_ref::>(); + draw( renderer, style, layout, - &self.content, - self.size, - self.line_height, - self.font, + state, theme.appearance(self.style.clone()), - self.horizontal_alignment, - self.vertical_alignment, - self.shaping, ); } } +/// Produces the [`layout::Node`] of a [`Text`] widget. +pub fn layout( + state: &State, + renderer: &Renderer, + limits: &layout::Limits, + width: Length, + height: Length, + content: &str, + line_height: LineHeight, + size: Option, + font: Option, + horizontal_alignment: alignment::Horizontal, + vertical_alignment: alignment::Vertical, + shaping: Shaping, +) -> layout::Node +where + Renderer: text::Renderer, +{ + let limits = limits.width(width).height(height); + let bounds = limits.max(); + + let size = size.unwrap_or_else(|| renderer.default_size()); + let font = font.unwrap_or_else(|| renderer.default_font()); + + let mut paragraph = state.0.borrow_mut(); + + renderer.update_paragraph( + &mut paragraph, + text::Text { + content, + bounds, + size, + line_height, + font, + shaping, + horizontal_alignment, + vertical_alignment, + }, + ); + + let size = limits.resolve(paragraph.min_bounds()); + + layout::Node::new(size) +} + /// Draws text using the same logic as the [`Text`] widget. /// /// Specifically: @@ -193,44 +246,31 @@ pub fn draw( renderer: &mut Renderer, style: &renderer::Style, layout: Layout<'_>, - content: &str, - size: Option, - line_height: LineHeight, - font: Option, + state: &State, appearance: Appearance, - horizontal_alignment: alignment::Horizontal, - vertical_alignment: alignment::Vertical, - shaping: Shaping, ) where Renderer: text::Renderer, { + let paragraph = state.0.borrow(); let bounds = layout.bounds(); - let x = match horizontal_alignment { + let x = match paragraph.horizontal_alignment() { alignment::Horizontal::Left => bounds.x, alignment::Horizontal::Center => bounds.center_x(), alignment::Horizontal::Right => bounds.x + bounds.width, }; - let y = match vertical_alignment { + let y = match paragraph.vertical_alignment() { alignment::Vertical::Top => bounds.y, alignment::Vertical::Center => bounds.center_y(), alignment::Vertical::Bottom => bounds.y + bounds.height, }; - let size = size.unwrap_or_else(|| renderer.default_size()); - - renderer.fill_text(crate::Text { - content, - size, - line_height, - bounds: Rectangle { x, y, ..bounds }, - color: appearance.color.unwrap_or(style.text_color), - font: font.unwrap_or_else(|| renderer.default_font()), - horizontal_alignment, - vertical_alignment, - shaping, - }); + renderer.fill_paragraph( + ¶graph, + Point::new(x, y), + appearance.color.unwrap_or(style.text_color), + ); } impl<'a, Message, Renderer> From> diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index 736a9d53..7dc981d9 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -3,8 +3,8 @@ use iced::mouse; use iced::widget::canvas::{self, Canvas, Frame, Geometry, Path}; use iced::widget::{column, row, text, Slider}; use iced::{ - Color, Element, Length, Point, Rectangle, Renderer, Sandbox, Settings, - Size, Vector, + Color, Element, Length, Pixels, Point, Rectangle, Renderer, Sandbox, + Settings, Size, Vector, }; use palette::{ self, convert::FromColor, rgb::Rgb, Darken, Hsl, Lighten, ShiftHue, @@ -168,7 +168,7 @@ impl Theme { let mut text = canvas::Text { horizontal_alignment: alignment::Horizontal::Center, vertical_alignment: alignment::Vertical::Top, - size: 15.0, + size: Pixels(15.0), ..canvas::Text::default() }; diff --git a/examples/combo_box/src/main.rs b/examples/combo_box/src/main.rs index 2e6f95d5..4f347667 100644 --- a/examples/combo_box/src/main.rs +++ b/examples/combo_box/src/main.rs @@ -40,7 +40,6 @@ impl Sandbox for Example { Message::Selected(language) => { self.selected_language = Some(language); self.text = language.hello().to_string(); - self.languages.unfocus(); } Message::OptionHovered(language) => { self.text = language.hello().to_string(); diff --git a/examples/custom_quad/src/main.rs b/examples/custom_quad/src/main.rs index 4b300116..91401f73 100644 --- a/examples/custom_quad/src/main.rs +++ b/examples/custom_quad/src/main.rs @@ -36,6 +36,7 @@ mod quad { fn layout( &self, + _tree: &widget::Tree, _renderer: &Renderer, _limits: &layout::Limits, ) -> layout::Node { diff --git a/examples/custom_widget/src/main.rs b/examples/custom_widget/src/main.rs index 713bc62d..e0a23541 100644 --- a/examples/custom_widget/src/main.rs +++ b/examples/custom_widget/src/main.rs @@ -43,6 +43,7 @@ mod circle { fn layout( &self, + _tree: &widget::Tree, _renderer: &Renderer, _limits: &layout::Limits, ) -> layout::Node { diff --git a/examples/game_of_life/src/main.rs b/examples/game_of_life/src/main.rs index e951d734..fa711744 100644 --- a/examples/game_of_life/src/main.rs +++ b/examples/game_of_life/src/main.rs @@ -591,7 +591,7 @@ mod grid { let text = Text { color: Color::WHITE, - size: 14.0, + size: 14.0.into(), position: Point::new(frame.width(), frame.height()), horizontal_alignment: alignment::Horizontal::Right, vertical_alignment: alignment::Vertical::Bottom, diff --git a/examples/geometry/src/main.rs b/examples/geometry/src/main.rs index 3bc7f46b..a0d505b8 100644 --- a/examples/geometry/src/main.rs +++ b/examples/geometry/src/main.rs @@ -26,6 +26,7 @@ mod rainbow { fn layout( &self, + _tree: &widget::Tree, _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/examples/integration/src/main.rs b/examples/integration/src/main.rs index 342d4c69..e011a411 100644 --- a/examples/integration/src/main.rs +++ b/examples/integration/src/main.rs @@ -8,7 +8,7 @@ use iced_wgpu::graphics::Viewport; use iced_wgpu::{wgpu, Backend, Renderer, Settings}; use iced_winit::core::mouse; use iced_winit::core::renderer; -use iced_winit::core::{Color, Size}; +use iced_winit::core::{Color, Font, Pixels, Size}; use iced_winit::runtime::program; use iced_winit::runtime::Debug; use iced_winit::style::Theme; @@ -143,12 +143,11 @@ pub fn main() -> Result<(), Box> { // Initialize iced let mut debug = Debug::new(); - let mut renderer = Renderer::new(Backend::new( - &device, - &queue, - Settings::default(), - format, - )); + let mut renderer = Renderer::new( + Backend::new(&device, &queue, Settings::default(), format), + Font::default(), + Pixels(16.0), + ); let mut state = program::State::new( controls, diff --git a/examples/loading_spinners/src/circular.rs b/examples/loading_spinners/src/circular.rs index 3898d76e..6bcfd507 100644 --- a/examples/loading_spinners/src/circular.rs +++ b/examples/loading_spinners/src/circular.rs @@ -254,6 +254,7 @@ where fn layout( &self, + _tree: &Tree, _renderer: &iced::Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/examples/loading_spinners/src/linear.rs b/examples/loading_spinners/src/linear.rs index 20fbe9f3..3addd7bb 100644 --- a/examples/loading_spinners/src/linear.rs +++ b/examples/loading_spinners/src/linear.rs @@ -175,6 +175,7 @@ where fn layout( &self, + _tree: &Tree, _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/examples/modal/src/main.rs b/examples/modal/src/main.rs index 8a48f830..5d47f02c 100644 --- a/examples/modal/src/main.rs +++ b/examples/modal/src/main.rs @@ -285,10 +285,13 @@ mod modal { fn layout( &self, + tree: &widget::Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - self.base.as_widget().layout(renderer, limits) + self.base + .as_widget() + .layout(&tree.children[0], renderer, limits) } fn on_event( @@ -408,7 +411,11 @@ mod modal { .width(Length::Fill) .height(Length::Fill); - let mut child = self.content.as_widget().layout(renderer, &limits); + let mut child = self + .content + .as_widget() + .layout(self.tree, renderer, &limits); + child.align(Alignment::Center, Alignment::Center, limits.max()); let mut node = layout::Node::with_children(self.size, vec![child]); diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs index 42f6c348..01eea3cc 100644 --- a/examples/toast/src/main.rs +++ b/examples/toast/src/main.rs @@ -326,10 +326,13 @@ mod toast { fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - self.content.as_widget().layout(renderer, limits) + self.content + .as_widget() + .layout(&tree.children[0], renderer, limits) } fn tag(&self) -> widget::tree::Tag { @@ -517,6 +520,7 @@ mod toast { 10.0, Alignment::End, self.toasts, + self.state, ) .translate(Vector::new(position.x, position.y)) } diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs index 13bcd5ff..10de2ae1 100644 --- a/examples/tour/src/main.rs +++ b/examples/tour/src/main.rs @@ -5,7 +5,7 @@ use iced::widget::{ scrollable, slider, text, text_input, toggler, vertical_space, }; use iced::widget::{Button, Column, Container, Slider}; -use iced::{Color, Element, Font, Length, Renderer, Sandbox, Settings}; +use iced::{Color, Element, Font, Length, Pixels, Renderer, Sandbox, Settings}; pub fn main() -> iced::Result { env_logger::init(); @@ -571,7 +571,7 @@ impl<'a> Step { text_input = text_input.icon(text_input::Icon { font: Font::default(), code_point: '🚀', - size: Some(28.0), + size: Some(Pixels(28.0)), spacing: 10.0, side: text_input::Side::Right, }); diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml index ca7bf61a..442eb007 100644 --- a/graphics/Cargo.toml +++ b/graphics/Cargo.toml @@ -23,6 +23,9 @@ log = "0.4" raw-window-handle = "0.5" thiserror = "1.0" bitflags = "1.2" +cosmic-text = "0.9" +rustc-hash = "1.1" +unicode-segmentation = "1.6" [dependencies.bytemuck] version = "1.4" @@ -32,6 +35,14 @@ features = ["derive"] version = "0.10" path = "../core" +[dependencies.twox-hash] +version = "1.6" +default-features = false + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies.twox-hash] +version = "1.6.1" +features = ["std"] + [dependencies.image] version = "0.24" optional = true diff --git a/tiny_skia/fonts/Iced-Icons.ttf b/graphics/fonts/Iced-Icons.ttf similarity index 100% rename from tiny_skia/fonts/Iced-Icons.ttf rename to graphics/fonts/Iced-Icons.ttf diff --git a/graphics/src/backend.rs b/graphics/src/backend.rs index 59e95bf8..6774b9ca 100644 --- a/graphics/src/backend.rs +++ b/graphics/src/backend.rs @@ -1,8 +1,8 @@ //! Write a graphics backend. -use iced_core::image; -use iced_core::svg; -use iced_core::text; -use iced_core::{Font, Point, Size}; +use crate::core::image; +use crate::core::svg; +use crate::core::Size; +use crate::text; use std::borrow::Cow; @@ -12,70 +12,15 @@ use std::borrow::Cow; pub trait Backend { /// The custom kind of primitives this [`Backend`] supports. type Primitive; - - /// Trims the measurements cache. - /// - /// This method is currently necessary to properly trim the text cache in - /// `iced_wgpu` and `iced_glow` because of limitations in the text rendering - /// pipeline. It will be removed in the future. - fn trim_measurements(&mut self) {} } /// A graphics backend that supports text rendering. pub trait Text { - /// The icon font of the backend. - const ICON_FONT: Font; - - /// The `char` representing a âś” icon in the [`ICON_FONT`]. - /// - /// [`ICON_FONT`]: Self::ICON_FONT - const CHECKMARK_ICON: char; - - /// The `char` representing a â–Ľ icon in the built-in [`ICON_FONT`]. - /// - /// [`ICON_FONT`]: Self::ICON_FONT - const ARROW_DOWN_ICON: char; - - /// Returns the default [`Font`]. - fn default_font(&self) -> Font; - - /// Returns the default size of text. - fn default_size(&self) -> f32; - - /// Measures the text contents with the given size and font, - /// returning the size of a laid out paragraph that fits in the provided - /// bounds. - fn measure( - &self, - contents: &str, - size: f32, - line_height: text::LineHeight, - font: Font, - bounds: Size, - shaping: text::Shaping, - ) -> Size; - - /// Tests whether the provided point is within the boundaries of [`Text`] - /// laid out with the given parameters, returning information about - /// the nearest character. - /// - /// If nearest_only is true, the hit test does not consider whether the - /// the point is interior to any glyph bounds, returning only the character - /// with the nearest centeroid. - fn hit_test( - &self, - contents: &str, - size: f32, - line_height: text::LineHeight, - font: Font, - bounds: Size, - shaping: text::Shaping, - point: Point, - nearest_only: bool, - ) -> Option; - /// Loads a [`Font`] from its bytes. fn load_font(&mut self, font: Cow<'static, [u8]>); + + /// Returns the [`cosmic_text::FontSystem`] of the [`Backend`]. + fn font_system(&self) -> &text::FontSystem; } /// A graphics backend that supports image rendering. diff --git a/graphics/src/damage.rs b/graphics/src/damage.rs index 2f29956e..3276c2d4 100644 --- a/graphics/src/damage.rs +++ b/graphics/src/damage.rs @@ -40,6 +40,32 @@ impl Damage for Primitive { bounds.expand(1.5) } + Self::Paragraph { + paragraph, + position, + .. + } => { + let mut bounds = + Rectangle::new(*position, paragraph.min_bounds); + + bounds.x = match paragraph.horizontal_alignment { + alignment::Horizontal::Left => bounds.x, + alignment::Horizontal::Center => { + bounds.x - bounds.width / 2.0 + } + alignment::Horizontal::Right => bounds.x - bounds.width, + }; + + bounds.y = match paragraph.vertical_alignment { + alignment::Vertical::Top => bounds.y, + alignment::Vertical::Center => { + bounds.y - bounds.height / 2.0 + } + alignment::Vertical::Bottom => bounds.y - bounds.height, + }; + + bounds.expand(1.5) + } Self::Quad { bounds, .. } | Self::Image { bounds, .. } | Self::Svg { bounds, .. } => bounds.expand(1.0), diff --git a/graphics/src/geometry/text.rs b/graphics/src/geometry/text.rs index c584f3cd..0bf7ec97 100644 --- a/graphics/src/geometry/text.rs +++ b/graphics/src/geometry/text.rs @@ -1,6 +1,6 @@ use crate::core::alignment; use crate::core::text::{LineHeight, Shaping}; -use crate::core::{Color, Font, Point}; +use crate::core::{Color, Font, Pixels, Point}; /// A bunch of text that can be drawn to a canvas #[derive(Debug, Clone)] @@ -19,7 +19,7 @@ pub struct Text { /// The color of the text pub color: Color, /// The size of the text - pub size: f32, + pub size: Pixels, /// The line height of the text. pub line_height: LineHeight, /// The font of the text @@ -38,7 +38,7 @@ impl Default for Text { content: String::new(), position: Point::ORIGIN, color: Color::BLACK, - size: 16.0, + size: Pixels(16.0), line_height: LineHeight::Relative(1.2), font: Font::default(), horizontal_alignment: alignment::Horizontal::Left, diff --git a/graphics/src/lib.rs b/graphics/src/lib.rs index af374a2f..902eb5b0 100644 --- a/graphics/src/lib.rs +++ b/graphics/src/lib.rs @@ -9,7 +9,7 @@ )] #![deny( missing_debug_implementations, - missing_docs, + //missing_docs, unsafe_code, unused_results, clippy::extra_unused_lifetimes, @@ -34,6 +34,7 @@ pub mod damage; pub mod gradient; pub mod mesh; pub mod renderer; +pub mod text; #[cfg(feature = "geometry")] pub mod geometry; diff --git a/graphics/src/primitive.rs b/graphics/src/primitive.rs index 7592a410..cdc8923e 100644 --- a/graphics/src/primitive.rs +++ b/graphics/src/primitive.rs @@ -3,7 +3,8 @@ use crate::core::alignment; use crate::core::image; use crate::core::svg; use crate::core::text; -use crate::core::{Background, Color, Font, Rectangle, Vector}; +use crate::core::{Background, Color, Font, Pixels, Point, Rectangle, Vector}; +use crate::text::paragraph; use std::sync::Arc; @@ -19,7 +20,7 @@ pub enum Primitive { /// The color of the text color: Color, /// The size of the text in logical pixels - size: f32, + size: Pixels, /// The line height of the text line_height: text::LineHeight, /// The font of the text @@ -31,6 +32,15 @@ pub enum Primitive { /// The shaping strategy of the text. shaping: text::Shaping, }, + /// A paragraph primitive + Paragraph { + /// The [`Paragraph`]. + paragraph: paragraph::Weak, + /// The position of the [`Paragraph`]. + position: Point, + /// The color of the [`Paragraph`]. + color: Color, + }, /// A quad primitive Quad { /// The bounds of the quad diff --git a/graphics/src/renderer.rs b/graphics/src/renderer.rs index c0cec60a..f93f4a6d 100644 --- a/graphics/src/renderer.rs +++ b/graphics/src/renderer.rs @@ -1,15 +1,15 @@ //! Create a renderer from a [`Backend`]. use crate::backend::{self, Backend}; -use crate::Primitive; - -use iced_core::image; -use iced_core::layout; -use iced_core::renderer; -use iced_core::svg; -use iced_core::text::{self, Text}; -use iced_core::{ - Background, Color, Element, Font, Point, Rectangle, Size, Vector, +use crate::core; +use crate::core::image; +use crate::core::renderer; +use crate::core::svg; +use crate::core::text::Text; +use crate::core::{ + Background, Color, Font, Pixels, Point, Rectangle, Size, Vector, }; +use crate::text; +use crate::Primitive; use std::borrow::Cow; use std::marker::PhantomData; @@ -18,15 +18,23 @@ use std::marker::PhantomData; #[derive(Debug)] pub struct Renderer { backend: B, + default_font: Font, + default_text_size: Pixels, primitives: Vec>, theme: PhantomData, } impl Renderer { /// Creates a new [`Renderer`] from the given [`Backend`]. - pub fn new(backend: B) -> Self { + pub fn new( + backend: B, + default_font: Font, + default_text_size: Pixels, + ) -> Self { Self { backend, + default_font, + default_text_size, primitives: Vec::new(), theme: PhantomData, } @@ -88,16 +96,6 @@ impl Renderer { impl iced_core::Renderer for Renderer { type Theme = T; - fn layout( - &mut self, - element: &Element<'_, Message, Self>, - limits: &layout::Limits, - ) -> layout::Node { - self.backend.trim_measurements(); - - element.as_widget().layout(self, limits) - } - fn with_layer(&mut self, bounds: Rectangle, f: impl FnOnce(&mut Self)) { let current = self.start_layer(); @@ -137,77 +135,66 @@ impl iced_core::Renderer for Renderer { } } -impl text::Renderer for Renderer +impl core::text::Renderer for Renderer where B: Backend + backend::Text, { type Font = Font; + type Paragraph = text::Paragraph; - const ICON_FONT: Font = B::ICON_FONT; - const CHECKMARK_ICON: char = B::CHECKMARK_ICON; - const ARROW_DOWN_ICON: char = B::ARROW_DOWN_ICON; + const ICON_FONT: Font = Font::with_name("Iced-Icons"); + const CHECKMARK_ICON: char = '\u{f00c}'; + const ARROW_DOWN_ICON: char = '\u{e800}'; fn default_font(&self) -> Self::Font { - self.backend().default_font() + self.default_font } - fn default_size(&self) -> f32 { - self.backend().default_size() - } - - fn measure( - &self, - content: &str, - size: f32, - line_height: text::LineHeight, - font: Font, - bounds: Size, - shaping: text::Shaping, - ) -> Size { - self.backend().measure( - content, - size, - line_height, - font, - bounds, - shaping, - ) - } - - fn hit_test( - &self, - content: &str, - size: f32, - line_height: text::LineHeight, - font: Font, - bounds: Size, - shaping: text::Shaping, - point: Point, - nearest_only: bool, - ) -> Option { - self.backend().hit_test( - content, - size, - line_height, - font, - bounds, - shaping, - point, - nearest_only, - ) + fn default_size(&self) -> Pixels { + self.default_text_size } fn load_font(&mut self, bytes: Cow<'static, [u8]>) { self.backend.load_font(bytes); } - fn fill_text(&mut self, text: Text<'_, Self::Font>) { + fn create_paragraph(&self, text: Text<'_, Self::Font>) -> text::Paragraph { + text::Paragraph::with_text(text, self.backend.font_system()) + } + + fn resize_paragraph( + &self, + paragraph: &mut Self::Paragraph, + new_bounds: Size, + ) { + paragraph.resize(new_bounds, self.backend.font_system()); + } + + fn fill_paragraph( + &mut self, + paragraph: &Self::Paragraph, + position: Point, + color: Color, + ) { + self.primitives.push(Primitive::Paragraph { + paragraph: paragraph.downgrade(), + position, + color, + }); + } + + fn fill_text( + &mut self, + text: Text<'_, Self::Font>, + position: Point, + color: Color, + ) { self.primitives.push(Primitive::Text { content: text.content.to_string(), - bounds: text.bounds, + bounds: Rectangle::new(position, text.bounds), size: text.size, line_height: text.line_height, - color: text.color, + color, font: text.font, horizontal_alignment: text.horizontal_alignment, vertical_alignment: text.vertical_alignment, diff --git a/graphics/src/text.rs b/graphics/src/text.rs new file mode 100644 index 00000000..bbe9d7cb --- /dev/null +++ b/graphics/src/text.rs @@ -0,0 +1,113 @@ +pub mod cache; +pub mod paragraph; + +pub use cache::Cache; +pub use paragraph::Paragraph; + +pub use cosmic_text; + +use crate::core::font::{self, Font}; +use crate::core::text::Shaping; +use crate::core::Size; + +use std::sync::{self, Arc, RwLock}; + +#[allow(missing_debug_implementations)] +pub struct FontSystem(RwLock); + +impl FontSystem { + pub fn new() -> Self { + FontSystem(RwLock::new(cosmic_text::FontSystem::new_with_fonts( + [cosmic_text::fontdb::Source::Binary(Arc::new( + include_bytes!("../fonts/Iced-Icons.ttf").as_slice(), + ))] + .into_iter(), + ))) + } + + pub fn get_mut(&mut self) -> &mut cosmic_text::FontSystem { + self.0.get_mut().expect("Lock font system") + } + + pub fn write(&self) -> sync::RwLockWriteGuard<'_, cosmic_text::FontSystem> { + self.0.write().expect("Write font system") + } +} + +impl Default for FontSystem { + fn default() -> Self { + Self::new() + } +} + +pub fn measure(buffer: &cosmic_text::Buffer) -> Size { + let (width, total_lines) = buffer + .layout_runs() + .fold((0.0, 0usize), |(width, total_lines), run| { + (run.line_w.max(width), total_lines + 1) + }); + + Size::new(width, total_lines as f32 * buffer.metrics().line_height) +} + +pub fn to_attributes(font: Font) -> cosmic_text::Attrs<'static> { + cosmic_text::Attrs::new() + .family(to_family(font.family)) + .weight(to_weight(font.weight)) + .stretch(to_stretch(font.stretch)) + .style(to_style(font.style)) +} + +fn to_family(family: font::Family) -> cosmic_text::Family<'static> { + match family { + font::Family::Name(name) => cosmic_text::Family::Name(name), + font::Family::SansSerif => cosmic_text::Family::SansSerif, + font::Family::Serif => cosmic_text::Family::Serif, + font::Family::Cursive => cosmic_text::Family::Cursive, + font::Family::Fantasy => cosmic_text::Family::Fantasy, + font::Family::Monospace => cosmic_text::Family::Monospace, + } +} + +fn to_weight(weight: font::Weight) -> cosmic_text::Weight { + match weight { + font::Weight::Thin => cosmic_text::Weight::THIN, + font::Weight::ExtraLight => cosmic_text::Weight::EXTRA_LIGHT, + font::Weight::Light => cosmic_text::Weight::LIGHT, + font::Weight::Normal => cosmic_text::Weight::NORMAL, + font::Weight::Medium => cosmic_text::Weight::MEDIUM, + font::Weight::Semibold => cosmic_text::Weight::SEMIBOLD, + font::Weight::Bold => cosmic_text::Weight::BOLD, + font::Weight::ExtraBold => cosmic_text::Weight::EXTRA_BOLD, + font::Weight::Black => cosmic_text::Weight::BLACK, + } +} + +fn to_stretch(stretch: font::Stretch) -> cosmic_text::Stretch { + match stretch { + font::Stretch::UltraCondensed => cosmic_text::Stretch::UltraCondensed, + font::Stretch::ExtraCondensed => cosmic_text::Stretch::ExtraCondensed, + font::Stretch::Condensed => cosmic_text::Stretch::Condensed, + font::Stretch::SemiCondensed => cosmic_text::Stretch::SemiCondensed, + font::Stretch::Normal => cosmic_text::Stretch::Normal, + font::Stretch::SemiExpanded => cosmic_text::Stretch::SemiExpanded, + font::Stretch::Expanded => cosmic_text::Stretch::Expanded, + font::Stretch::ExtraExpanded => cosmic_text::Stretch::ExtraExpanded, + font::Stretch::UltraExpanded => cosmic_text::Stretch::UltraExpanded, + } +} + +fn to_style(style: font::Style) -> cosmic_text::Style { + match style { + font::Style::Normal => cosmic_text::Style::Normal, + font::Style::Italic => cosmic_text::Style::Italic, + font::Style::Oblique => cosmic_text::Style::Oblique, + } +} + +pub fn to_shaping(shaping: Shaping) -> cosmic_text::Shaping { + match shaping { + Shaping::Basic => cosmic_text::Shaping::Basic, + Shaping::Advanced => cosmic_text::Shaping::Advanced, + } +} diff --git a/graphics/src/text/cache.rs b/graphics/src/text/cache.rs new file mode 100644 index 00000000..8aea6715 --- /dev/null +++ b/graphics/src/text/cache.rs @@ -0,0 +1,120 @@ +use crate::core::{Font, Size}; +use crate::text; + +use rustc_hash::{FxHashMap, FxHashSet}; +use std::collections::hash_map; +use std::hash::{BuildHasher, Hash, Hasher}; + +#[allow(missing_debug_implementations)] +#[derive(Default)] +pub struct Cache { + entries: FxHashMap, + aliases: FxHashMap, + recently_used: FxHashSet, + hasher: HashBuilder, +} + +#[cfg(not(target_arch = "wasm32"))] +type HashBuilder = twox_hash::RandomXxHashBuilder64; + +#[cfg(target_arch = "wasm32")] +type HashBuilder = std::hash::BuildHasherDefault; + +impl Cache { + pub fn new() -> Self { + Self::default() + } + + pub fn get(&self, key: &KeyHash) -> Option<&cosmic_text::Buffer> { + self.entries.get(key) + } + + pub fn allocate( + &mut self, + font_system: &mut cosmic_text::FontSystem, + key: Key<'_>, + ) -> (KeyHash, &mut cosmic_text::Buffer) { + let hash = key.hash(self.hasher.build_hasher()); + + if let Some(hash) = self.aliases.get(&hash) { + let _ = self.recently_used.insert(*hash); + + return (*hash, self.entries.get_mut(hash).unwrap()); + } + + if let hash_map::Entry::Vacant(entry) = self.entries.entry(hash) { + let metrics = cosmic_text::Metrics::new(key.size, key.line_height); + let mut buffer = cosmic_text::Buffer::new(font_system, metrics); + + buffer.set_size( + font_system, + key.bounds.width, + key.bounds.height.max(key.line_height), + ); + buffer.set_text( + font_system, + key.content, + text::to_attributes(key.font), + text::to_shaping(key.shaping), + ); + + let bounds = text::measure(&buffer); + let _ = entry.insert(buffer); + + for bounds in [ + bounds, + Size { + width: key.bounds.width, + ..bounds + }, + ] { + if key.bounds != bounds { + let _ = self.aliases.insert( + Key { bounds, ..key }.hash(self.hasher.build_hasher()), + hash, + ); + } + } + } + + let _ = self.recently_used.insert(hash); + + (hash, self.entries.get_mut(&hash).unwrap()) + } + + pub fn trim(&mut self) { + self.entries + .retain(|key, _| self.recently_used.contains(key)); + + self.aliases + .retain(|_, value| self.recently_used.contains(value)); + + self.recently_used.clear(); + } +} + +#[derive(Debug, Clone, Copy)] +pub struct Key<'a> { + pub content: &'a str, + pub size: f32, + pub line_height: f32, + pub font: Font, + pub bounds: Size, + pub shaping: text::Shaping, +} + +impl Key<'_> { + fn hash(self, mut hasher: H) -> KeyHash { + self.content.hash(&mut hasher); + self.size.to_bits().hash(&mut hasher); + self.line_height.to_bits().hash(&mut hasher); + self.font.hash(&mut hasher); + self.bounds.width.to_bits().hash(&mut hasher); + self.bounds.height.to_bits().hash(&mut hasher); + self.shaping.hash(&mut hasher); + + hasher.finish() + } +} + +pub type KeyHash = u64; diff --git a/graphics/src/text/paragraph.rs b/graphics/src/text/paragraph.rs new file mode 100644 index 00000000..7b70376a --- /dev/null +++ b/graphics/src/text/paragraph.rs @@ -0,0 +1,246 @@ +use crate::core; +use crate::core::alignment; +use crate::core::text::{Hit, LineHeight, Shaping, Text}; +use crate::core::{Font, Pixels, Point, Size}; +use crate::text::{self, FontSystem}; + +use std::fmt; +use std::sync::{self, Arc}; + +#[derive(Clone, PartialEq, Default)] +pub struct Paragraph(Arc); + +struct Internal { + buffer: cosmic_text::Buffer, + content: String, // TODO: Reuse from `buffer` (?) + font: Font, + shaping: Shaping, + horizontal_alignment: alignment::Horizontal, + vertical_alignment: alignment::Vertical, + bounds: Size, + min_bounds: Size, +} + +impl Paragraph { + pub fn new() -> Self { + Self::default() + } + + pub fn with_text(text: Text<'_, Font>, font_system: &FontSystem) -> Self { + let mut font_system = font_system.write(); + + let mut buffer = cosmic_text::Buffer::new( + &mut font_system, + cosmic_text::Metrics::new( + text.size.into(), + text.line_height.to_absolute(text.size).into(), + ), + ); + + buffer.set_size( + &mut font_system, + text.bounds.width, + text.bounds.height, + ); + + buffer.set_text( + &mut font_system, + text.content, + text::to_attributes(text.font), + text::to_shaping(text.shaping), + ); + + let min_bounds = text::measure(&buffer); + + Self(Arc::new(Internal { + buffer, + content: text.content.to_owned(), + font: text.font, + horizontal_alignment: text.horizontal_alignment, + vertical_alignment: text.vertical_alignment, + shaping: text.shaping, + bounds: text.bounds, + min_bounds, + })) + } + + pub fn buffer(&self) -> &cosmic_text::Buffer { + &self.0.buffer + } + + pub fn downgrade(&self) -> Weak { + Weak { + raw: Arc::downgrade(&self.0), + min_bounds: self.0.min_bounds, + horizontal_alignment: self.0.horizontal_alignment, + vertical_alignment: self.0.vertical_alignment, + } + } + + pub fn resize(&mut self, new_bounds: Size, font_system: &FontSystem) { + if let Some(internal) = Arc::get_mut(&mut self.0) { + // If there is no strong reference holding on to the paragraph, we + // resize the buffer in-place + internal.buffer.set_size( + &mut font_system.write(), + new_bounds.width, + new_bounds.height, + ); + + internal.bounds = new_bounds; + internal.min_bounds = text::measure(&internal.buffer); + } else { + let metrics = self.0.buffer.metrics(); + + // If there is a strong reference somewhere, we recompute the buffer + // from scratch + *self = Self::with_text( + Text { + content: &self.0.content, + bounds: self.0.bounds, + size: Pixels(metrics.font_size), + line_height: LineHeight::Absolute(Pixels( + metrics.line_height, + )), + font: self.0.font, + horizontal_alignment: self.0.horizontal_alignment, + vertical_alignment: self.0.vertical_alignment, + shaping: self.0.shaping, + }, + font_system, + ); + } + } +} + +impl core::text::Paragraph for Paragraph { + type Font = Font; + + fn content(&self) -> &str { + &self.0.content + } + + fn text_size(&self) -> Pixels { + Pixels(self.0.buffer.metrics().font_size) + } + + fn line_height(&self) -> LineHeight { + LineHeight::Absolute(Pixels(self.0.buffer.metrics().line_height)) + } + + fn font(&self) -> Font { + self.0.font + } + + fn shaping(&self) -> Shaping { + self.0.shaping + } + + fn horizontal_alignment(&self) -> alignment::Horizontal { + self.0.horizontal_alignment + } + + fn vertical_alignment(&self) -> alignment::Vertical { + self.0.vertical_alignment + } + + fn bounds(&self) -> Size { + self.0.bounds + } + + fn min_bounds(&self) -> Size { + self.0.min_bounds + } + + fn hit_test(&self, point: Point) -> Option { + let cursor = self.0.buffer.hit(point.x, point.y)?; + + Some(Hit::CharOffset(cursor.index)) + } + + fn grapheme_position(&self, line: usize, index: usize) -> Option { + let run = self.0.buffer.layout_runs().nth(line)?; + + // TODO: Index represents a grapheme, not a glyph + let glyph = run.glyphs.get(index).or_else(|| run.glyphs.last())?; + + let advance_last = if index == run.glyphs.len() { + glyph.w + } else { + 0.0 + }; + + Some(Point::new( + glyph.x + glyph.x_offset * glyph.font_size + advance_last, + glyph.y - glyph.y_offset * glyph.font_size, + )) + } +} + +impl PartialEq for Internal { + fn eq(&self, other: &Self) -> bool { + self.content == other.content + && self.font == other.font + && self.shaping == other.shaping + && self.horizontal_alignment == other.horizontal_alignment + && self.vertical_alignment == other.vertical_alignment + && self.bounds == other.bounds + && self.min_bounds == other.min_bounds + && self.buffer.metrics() == other.buffer.metrics() + } +} + +impl Default for Internal { + fn default() -> Self { + Self { + buffer: cosmic_text::Buffer::new_empty(cosmic_text::Metrics { + font_size: 1.0, + line_height: 1.0, + }), + content: String::new(), + font: Font::default(), + shaping: Shaping::default(), + horizontal_alignment: alignment::Horizontal::Left, + vertical_alignment: alignment::Vertical::Top, + bounds: Size::ZERO, + min_bounds: Size::ZERO, + } + } +} + +impl fmt::Debug for Paragraph { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Paragraph") + .field("content", &self.0.content) + .field("font", &self.0.font) + .field("shaping", &self.0.shaping) + .field("horizontal_alignment", &self.0.horizontal_alignment) + .field("vertical_alignment", &self.0.vertical_alignment) + .field("bounds", &self.0.bounds) + .field("min_bounds", &self.0.min_bounds) + .finish() + } +} + +#[derive(Debug, Clone)] +pub struct Weak { + raw: sync::Weak, + pub min_bounds: Size, + pub horizontal_alignment: alignment::Horizontal, + pub vertical_alignment: alignment::Vertical, +} + +impl Weak { + pub fn upgrade(&self) -> Option { + self.raw.upgrade().map(Paragraph) + } +} + +impl PartialEq for Weak { + fn eq(&self, other: &Self) -> bool { + match (self.raw.upgrade(), other.raw.upgrade()) { + (Some(p1), Some(p2)) => p1 == p2, + _ => false, + } + } +} diff --git a/renderer/src/compositor.rs b/renderer/src/compositor.rs index 8b17a4b0..d1500089 100644 --- a/renderer/src/compositor.rs +++ b/renderer/src/compositor.rs @@ -224,16 +224,15 @@ impl Candidate { match self { Self::TinySkia => { let (compositor, backend) = - iced_tiny_skia::window::compositor::new( - iced_tiny_skia::Settings { - default_font: settings.default_font, - default_text_size: settings.default_text_size, - }, - ); + iced_tiny_skia::window::compositor::new(); Ok(( Compositor::TinySkia(compositor), - Renderer::TinySkia(iced_tiny_skia::Renderer::new(backend)), + Renderer::TinySkia(iced_tiny_skia::Renderer::new( + backend, + settings.default_font, + settings.default_text_size, + )), )) } #[cfg(feature = "wgpu")] @@ -250,7 +249,11 @@ impl Candidate { Ok(( Compositor::Wgpu(compositor), - Renderer::Wgpu(iced_wgpu::Renderer::new(backend)), + Renderer::Wgpu(iced_wgpu::Renderer::new( + backend, + settings.default_font, + settings.default_text_size, + )), )) } #[cfg(not(feature = "wgpu"))] diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs index 7d1a02c2..2b282a0b 100644 --- a/renderer/src/lib.rs +++ b/renderer/src/lib.rs @@ -16,7 +16,10 @@ pub use geometry::Geometry; use crate::core::renderer; use crate::core::text::{self, Text}; -use crate::core::{Background, Font, Point, Rectangle, Size, Vector}; +use crate::core::{ + Background, Color, Font, Pixels, Point, Rectangle, Size, Vector, +}; +use crate::graphics::text::Paragraph; use crate::graphics::Mesh; use std::borrow::Cow; @@ -142,6 +145,7 @@ impl core::Renderer for Renderer { impl text::Renderer for Renderer { type Font = Font; + type Paragraph = Paragraph; const ICON_FONT: Font = iced_tiny_skia::Renderer::::ICON_FONT; const CHECKMARK_ICON: char = iced_tiny_skia::Renderer::::CHECKMARK_ICON; @@ -152,59 +156,50 @@ impl text::Renderer for Renderer { delegate!(self, renderer, renderer.default_font()) } - fn default_size(&self) -> f32 { + fn default_size(&self) -> Pixels { delegate!(self, renderer, renderer.default_size()) } - fn measure( - &self, - content: &str, - size: f32, - line_height: text::LineHeight, - font: Font, - bounds: Size, - shaping: text::Shaping, - ) -> Size { - delegate!( - self, - renderer, - renderer.measure(content, size, line_height, font, bounds, shaping) - ) + fn create_paragraph(&self, text: Text<'_, Self::Font>) -> Self::Paragraph { + delegate!(self, renderer, renderer.create_paragraph(text)) } - fn hit_test( + fn resize_paragraph( &self, - content: &str, - size: f32, - line_height: text::LineHeight, - font: Font, - bounds: Size, - shaping: text::Shaping, - point: Point, - nearest_only: bool, - ) -> Option { + paragraph: &mut Self::Paragraph, + new_bounds: Size, + ) { delegate!( self, renderer, - renderer.hit_test( - content, - size, - line_height, - font, - bounds, - shaping, - point, - nearest_only - ) - ) + renderer.resize_paragraph(paragraph, new_bounds) + ); } fn load_font(&mut self, bytes: Cow<'static, [u8]>) { delegate!(self, renderer, renderer.load_font(bytes)); } - fn fill_text(&mut self, text: Text<'_, Self::Font>) { - delegate!(self, renderer, renderer.fill_text(text)); + fn fill_paragraph( + &mut self, + text: &Self::Paragraph, + position: Point, + color: Color, + ) { + delegate!( + self, + renderer, + renderer.fill_paragraph(text, position, color) + ); + } + + fn fill_text( + &mut self, + text: Text<'_, Self::Font>, + position: Point, + color: Color, + ) { + delegate!(self, renderer, renderer.fill_text(text, position, color)); } } diff --git a/renderer/src/settings.rs b/renderer/src/settings.rs index 2e51f339..08f2099e 100644 --- a/renderer/src/settings.rs +++ b/renderer/src/settings.rs @@ -1,4 +1,4 @@ -use crate::core::Font; +use crate::core::{Font, Pixels}; use crate::graphics::Antialiasing; /// The settings of a [`Backend`]. @@ -12,7 +12,7 @@ pub struct Settings { /// The default size of text. /// /// By default, it will be set to `16.0`. - pub default_text_size: f32, + pub default_text_size: Pixels, /// The antialiasing strategy that will be used for triangle primitives. /// @@ -24,7 +24,7 @@ impl Default for Settings { fn default() -> Settings { Settings { default_font: Font::default(), - default_text_size: 16.0, + default_text_size: Pixels(16.0), antialiasing: None, } } diff --git a/runtime/src/user_interface.rs b/runtime/src/user_interface.rs index e529c004..a730102c 100644 --- a/runtime/src/user_interface.rs +++ b/runtime/src/user_interface.rs @@ -95,8 +95,11 @@ where let Cache { mut state } = cache; state.diff(root.as_widget()); - let base = - renderer.layout(&root, &layout::Limits::new(Size::ZERO, bounds)); + let base = root.as_widget().layout( + &state, + renderer, + &layout::Limits::new(Size::ZERO, bounds), + ); UserInterface { root, @@ -226,8 +229,9 @@ where if shell.is_layout_invalid() { let _ = ManuallyDrop::into_inner(manual_overlay); - self.base = renderer.layout( - &self.root, + self.base = self.root.as_widget().layout( + &self.state, + renderer, &layout::Limits::new(Size::ZERO, self.bounds), ); @@ -325,8 +329,9 @@ where } shell.revalidate_layout(|| { - self.base = renderer.layout( - &self.root, + self.base = self.root.as_widget().layout( + &self.state, + renderer, &layout::Limits::new(Size::ZERO, self.bounds), ); diff --git a/src/settings.rs b/src/settings.rs index 0dd46584..794f89fd 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -1,6 +1,6 @@ //! Configure your application. use crate::window; -use crate::Font; +use crate::{Font, Pixels}; /// The settings of an application. #[derive(Debug, Clone)] @@ -29,7 +29,7 @@ pub struct Settings { /// The text size that will be used by default. /// /// The default value is `16.0`. - pub default_text_size: f32, + pub default_text_size: Pixels, /// If set to true, the renderer will try to perform antialiasing for some /// primitives. @@ -80,7 +80,7 @@ where window: Default::default(), flags: Default::default(), default_font: Default::default(), - default_text_size: 16.0, + default_text_size: Pixels(16.0), antialiasing: false, exit_on_close_request: true, } diff --git a/tiny_skia/src/backend.rs b/tiny_skia/src/backend.rs index a8add70b..ef587bac 100644 --- a/tiny_skia/src/backend.rs +++ b/tiny_skia/src/backend.rs @@ -1,16 +1,12 @@ -use crate::core::text; -use crate::core::Gradient; -use crate::core::{Background, Color, Font, Point, Rectangle, Size, Vector}; +use crate::core::{Background, Color, Gradient, Rectangle, Vector}; use crate::graphics::backend; +use crate::graphics::text; use crate::graphics::{Damage, Viewport}; use crate::primitive::{self, Primitive}; -use crate::Settings; use std::borrow::Cow; pub struct Backend { - default_font: Font, - default_text_size: f32, text_pipeline: crate::text::Pipeline, #[cfg(feature = "image")] @@ -21,10 +17,8 @@ pub struct Backend { } impl Backend { - pub fn new(settings: Settings) -> Self { + pub fn new() -> Self { Self { - default_font: settings.default_font, - default_text_size: settings.default_text_size, text_pipeline: crate::text::Pipeline::new(), #[cfg(feature = "image")] @@ -364,6 +358,32 @@ impl Backend { } } } + Primitive::Paragraph { + paragraph, + position, + color, + } => { + let physical_bounds = + (Rectangle::new(*position, paragraph.min_bounds) + + translation) + * scale_factor; + + if !clip_bounds.intersects(&physical_bounds) { + return; + } + + let clip_mask = (!physical_bounds.is_within(&clip_bounds)) + .then_some(clip_mask as &_); + + self.text_pipeline.draw_paragraph( + paragraph, + *position + translation, + *color, + scale_factor, + pixels, + clip_mask, + ); + } Primitive::Text { content, bounds, @@ -599,6 +619,12 @@ impl Backend { } } +impl Default for Backend { + fn default() -> Self { + Self::new() + } +} + fn into_color(color: Color) -> tiny_skia::Color { tiny_skia::Color::from_rgba(color.b, color.g, color.r, color.a) .expect("Convert color from iced to tiny_skia") @@ -779,58 +805,8 @@ impl iced_graphics::Backend for Backend { } impl backend::Text for Backend { - const ICON_FONT: Font = Font::with_name("Iced-Icons"); - const CHECKMARK_ICON: char = '\u{f00c}'; - const ARROW_DOWN_ICON: char = '\u{e800}'; - - fn default_font(&self) -> Font { - self.default_font - } - - fn default_size(&self) -> f32 { - self.default_text_size - } - - fn measure( - &self, - contents: &str, - size: f32, - line_height: text::LineHeight, - font: Font, - bounds: Size, - shaping: text::Shaping, - ) -> Size { - self.text_pipeline.measure( - contents, - size, - line_height, - font, - bounds, - shaping, - ) - } - - fn hit_test( - &self, - contents: &str, - size: f32, - line_height: text::LineHeight, - font: Font, - bounds: Size, - shaping: text::Shaping, - point: Point, - nearest_only: bool, - ) -> Option { - self.text_pipeline.hit_test( - contents, - size, - line_height, - font, - bounds, - shaping, - point, - nearest_only, - ) + fn font_system(&self) -> &text::FontSystem { + self.text_pipeline.font_system() } fn load_font(&mut self, font: Cow<'static, [u8]>) { @@ -840,7 +816,10 @@ impl backend::Text for Backend { #[cfg(feature = "image")] impl backend::Image for Backend { - fn dimensions(&self, handle: &crate::core::image::Handle) -> Size { + fn dimensions( + &self, + handle: &crate::core::image::Handle, + ) -> crate::core::Size { self.raster_pipeline.dimensions(handle) } } @@ -850,7 +829,7 @@ impl backend::Svg for Backend { fn viewport_dimensions( &self, handle: &crate::core::svg::Handle, - ) -> Size { + ) -> crate::core::Size { self.vector_pipeline.viewport_dimensions(handle) } } diff --git a/tiny_skia/src/settings.rs b/tiny_skia/src/settings.rs index abffbfe6..ec27b218 100644 --- a/tiny_skia/src/settings.rs +++ b/tiny_skia/src/settings.rs @@ -1,4 +1,4 @@ -use crate::core::Font; +use crate::core::{Font, Pixels}; /// The settings of a [`Backend`]. /// @@ -11,14 +11,14 @@ pub struct Settings { /// The default size of text. /// /// By default, it will be set to `16.0`. - pub default_text_size: f32, + pub default_text_size: Pixels, } impl Default for Settings { fn default() -> Settings { Settings { default_font: Font::default(), - default_text_size: 16.0, + default_text_size: Pixels(16.0), } } } diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index 08fde4bf..e4c5ad9b 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -1,18 +1,19 @@ use crate::core::alignment; -use crate::core::font::{self, Font}; -use crate::core::text::{Hit, LineHeight, Shaping}; -use crate::core::{Color, Pixels, Point, Rectangle, Size}; +use crate::core::text::{LineHeight, Shaping}; +use crate::core::{Color, Font, Pixels, Point, Rectangle}; +use crate::graphics::text::cache::{self, Cache}; +use crate::graphics::text::paragraph; +use crate::graphics::text::FontSystem; use rustc_hash::{FxHashMap, FxHashSet}; use std::borrow::Cow; use std::cell::RefCell; use std::collections::hash_map; -use std::hash::{BuildHasher, Hash, Hasher}; use std::sync::Arc; #[allow(missing_debug_implementations)] pub struct Pipeline { - font_system: RefCell, + font_system: FontSystem, glyph_cache: GlyphCache, cache: RefCell, } @@ -20,17 +21,16 @@ pub struct Pipeline { impl Pipeline { pub fn new() -> Self { Pipeline { - font_system: RefCell::new(cosmic_text::FontSystem::new_with_fonts( - [cosmic_text::fontdb::Source::Binary(Arc::new( - include_bytes!("../fonts/Iced-Icons.ttf").as_slice(), - ))] - .into_iter(), - )), + font_system: FontSystem::new(), glyph_cache: GlyphCache::new(), cache: RefCell::new(Cache::new()), } } + pub fn font_system(&self) -> &FontSystem { + &self.font_system + } + pub fn load_font(&mut self, bytes: Cow<'static, [u8]>) { self.font_system.get_mut().db_mut().load_font_source( cosmic_text::fontdb::Source::Binary(Arc::new(bytes.into_owned())), @@ -39,12 +39,23 @@ impl Pipeline { self.cache = RefCell::new(Cache::new()); } + pub fn draw_paragraph( + &mut self, + _paragraph: ¶graph::Weak, + _position: Point, + _color: Color, + _scale_factor: f32, + _pixels: &mut tiny_skia::PixmapMut<'_>, + _clip_mask: Option<&tiny_skia::Mask>, + ) { + } + pub fn draw( &mut self, content: &str, bounds: Rectangle, color: Color, - size: f32, + size: Pixels, line_height: LineHeight, font: Font, horizontal_alignment: alignment::Horizontal, @@ -54,22 +65,22 @@ impl Pipeline { pixels: &mut tiny_skia::PixmapMut<'_>, clip_mask: Option<&tiny_skia::Mask>, ) { - let line_height = f32::from(line_height.to_absolute(Pixels(size))); + let line_height = f32::from(line_height.to_absolute(size)); let font_system = self.font_system.get_mut(); - let key = Key { + let key = cache::Key { bounds: bounds.size(), content, font, - size, + size: size.into(), line_height, shaping, }; - let (_, entry) = self.cache.get_mut().allocate(font_system, key); + let (_, buffer) = self.cache.get_mut().allocate(font_system, key); - let max_width = entry.bounds.width * scale_factor; - let total_height = entry.bounds.height * scale_factor; + let max_width = bounds.width * scale_factor; + let total_height = bounds.height * scale_factor; let bounds = bounds * scale_factor; @@ -87,7 +98,7 @@ impl Pipeline { let mut swash = cosmic_text::SwashCache::new(); - for run in entry.buffer.layout_runs() { + for run in buffer.layout_runs() { for glyph in run.glyphs { let physical_glyph = glyph.physical((x, y), scale_factor); @@ -122,130 +133,6 @@ impl Pipeline { self.cache.get_mut().trim(); self.glyph_cache.trim(); } - - pub fn measure( - &self, - content: &str, - size: f32, - line_height: LineHeight, - font: Font, - bounds: Size, - shaping: Shaping, - ) -> Size { - let mut measurement_cache = self.cache.borrow_mut(); - - let line_height = f32::from(line_height.to_absolute(Pixels(size))); - - let (_, entry) = measurement_cache.allocate( - &mut self.font_system.borrow_mut(), - Key { - content, - size, - line_height, - font, - bounds, - shaping, - }, - ); - - entry.bounds - } - - pub fn hit_test( - &self, - content: &str, - size: f32, - line_height: LineHeight, - font: Font, - bounds: Size, - shaping: Shaping, - point: Point, - _nearest_only: bool, - ) -> Option { - let mut measurement_cache = self.cache.borrow_mut(); - - let line_height = f32::from(line_height.to_absolute(Pixels(size))); - - let (_, entry) = measurement_cache.allocate( - &mut self.font_system.borrow_mut(), - Key { - content, - size, - line_height, - font, - bounds, - shaping, - }, - ); - - let cursor = entry.buffer.hit(point.x, point.y)?; - - Some(Hit::CharOffset(cursor.index)) - } -} - -fn measure(buffer: &cosmic_text::Buffer) -> Size { - let (width, total_lines) = buffer - .layout_runs() - .fold((0.0, 0usize), |(width, total_lines), run| { - (run.line_w.max(width), total_lines + 1) - }); - - Size::new(width, total_lines as f32 * buffer.metrics().line_height) -} - -fn to_family(family: font::Family) -> cosmic_text::Family<'static> { - match family { - font::Family::Name(name) => cosmic_text::Family::Name(name), - font::Family::SansSerif => cosmic_text::Family::SansSerif, - font::Family::Serif => cosmic_text::Family::Serif, - font::Family::Cursive => cosmic_text::Family::Cursive, - font::Family::Fantasy => cosmic_text::Family::Fantasy, - font::Family::Monospace => cosmic_text::Family::Monospace, - } -} - -fn to_weight(weight: font::Weight) -> cosmic_text::Weight { - match weight { - font::Weight::Thin => cosmic_text::Weight::THIN, - font::Weight::ExtraLight => cosmic_text::Weight::EXTRA_LIGHT, - font::Weight::Light => cosmic_text::Weight::LIGHT, - font::Weight::Normal => cosmic_text::Weight::NORMAL, - font::Weight::Medium => cosmic_text::Weight::MEDIUM, - font::Weight::Semibold => cosmic_text::Weight::SEMIBOLD, - font::Weight::Bold => cosmic_text::Weight::BOLD, - font::Weight::ExtraBold => cosmic_text::Weight::EXTRA_BOLD, - font::Weight::Black => cosmic_text::Weight::BLACK, - } -} - -fn to_stretch(stretch: font::Stretch) -> cosmic_text::Stretch { - match stretch { - font::Stretch::UltraCondensed => cosmic_text::Stretch::UltraCondensed, - font::Stretch::ExtraCondensed => cosmic_text::Stretch::ExtraCondensed, - font::Stretch::Condensed => cosmic_text::Stretch::Condensed, - font::Stretch::SemiCondensed => cosmic_text::Stretch::SemiCondensed, - font::Stretch::Normal => cosmic_text::Stretch::Normal, - font::Stretch::SemiExpanded => cosmic_text::Stretch::SemiExpanded, - font::Stretch::Expanded => cosmic_text::Stretch::Expanded, - font::Stretch::ExtraExpanded => cosmic_text::Stretch::ExtraExpanded, - font::Stretch::UltraExpanded => cosmic_text::Stretch::UltraExpanded, - } -} - -fn to_style(style: font::Style) -> cosmic_text::Style { - match style { - font::Style::Normal => cosmic_text::Style::Normal, - font::Style::Italic => cosmic_text::Style::Italic, - font::Style::Oblique => cosmic_text::Style::Oblique, - } -} - -fn to_shaping(shaping: Shaping) -> cosmic_text::Shaping { - match shaping { - Shaping::Basic => cosmic_text::Shaping::Basic, - Shaping::Advanced => cosmic_text::Shaping::Advanced, - } } #[derive(Debug, Clone, Default)] @@ -358,135 +245,3 @@ impl GlyphCache { } } } - -struct Cache { - entries: FxHashMap, - measurements: FxHashMap, - recently_used: FxHashSet, - hasher: HashBuilder, - trim_count: usize, -} - -struct Entry { - buffer: cosmic_text::Buffer, - bounds: Size, -} - -#[cfg(not(target_arch = "wasm32"))] -type HashBuilder = twox_hash::RandomXxHashBuilder64; - -#[cfg(target_arch = "wasm32")] -type HashBuilder = std::hash::BuildHasherDefault; - -impl Cache { - const TRIM_INTERVAL: usize = 300; - - fn new() -> Self { - Self { - entries: FxHashMap::default(), - measurements: FxHashMap::default(), - recently_used: FxHashSet::default(), - hasher: HashBuilder::default(), - trim_count: 0, - } - } - - fn allocate( - &mut self, - font_system: &mut cosmic_text::FontSystem, - key: Key<'_>, - ) -> (KeyHash, &mut Entry) { - let hash = key.hash(self.hasher.build_hasher()); - - if let Some(hash) = self.measurements.get(&hash) { - let _ = self.recently_used.insert(*hash); - - return (*hash, self.entries.get_mut(hash).unwrap()); - } - - if let hash_map::Entry::Vacant(entry) = self.entries.entry(hash) { - let metrics = cosmic_text::Metrics::new(key.size, key.size * 1.2); - let mut buffer = cosmic_text::Buffer::new(font_system, metrics); - - buffer.set_size( - font_system, - key.bounds.width, - key.bounds.height.max(key.size * 1.2), - ); - buffer.set_text( - font_system, - key.content, - cosmic_text::Attrs::new() - .family(to_family(key.font.family)) - .weight(to_weight(key.font.weight)) - .stretch(to_stretch(key.font.stretch)) - .style(to_style(key.font.style)), - to_shaping(key.shaping), - ); - - let bounds = measure(&buffer); - - let _ = entry.insert(Entry { buffer, bounds }); - - for bounds in [ - bounds, - Size { - width: key.bounds.width, - ..bounds - }, - ] { - if key.bounds != bounds { - let _ = self.measurements.insert( - Key { bounds, ..key }.hash(self.hasher.build_hasher()), - hash, - ); - } - } - } - - let _ = self.recently_used.insert(hash); - - (hash, self.entries.get_mut(&hash).unwrap()) - } - - fn trim(&mut self) { - if self.trim_count > Self::TRIM_INTERVAL { - self.entries - .retain(|key, _| self.recently_used.contains(key)); - self.measurements - .retain(|_, value| self.recently_used.contains(value)); - - self.recently_used.clear(); - - self.trim_count = 0; - } else { - self.trim_count += 1; - } - } -} - -#[derive(Debug, Clone, Copy)] -struct Key<'a> { - content: &'a str, - size: f32, - line_height: f32, - font: Font, - bounds: Size, - shaping: Shaping, -} - -impl Key<'_> { - fn hash(self, mut hasher: H) -> KeyHash { - self.content.hash(&mut hasher); - self.size.to_bits().hash(&mut hasher); - self.line_height.to_bits().hash(&mut hasher); - self.font.hash(&mut hasher); - self.bounds.width.to_bits().hash(&mut hasher); - self.bounds.height.to_bits().hash(&mut hasher); - self.shaping.hash(&mut hasher); - - hasher.finish() - } -} - -type KeyHash = u64; diff --git a/tiny_skia/src/window/compositor.rs b/tiny_skia/src/window/compositor.rs index 775cf9e5..a996fffc 100644 --- a/tiny_skia/src/window/compositor.rs +++ b/tiny_skia/src/window/compositor.rs @@ -28,9 +28,16 @@ impl crate::graphics::Compositor for Compositor { settings: Self::Settings, _compatible_window: Option<&W>, ) -> Result<(Self, Self::Renderer), Error> { - let (compositor, backend) = new(settings); + let (compositor, backend) = new(); - Ok((compositor, Renderer::new(backend))) + Ok(( + compositor, + Renderer::new( + backend, + settings.default_font, + settings.default_text_size, + ), + )) } fn create_surface( @@ -113,12 +120,12 @@ impl crate::graphics::Compositor for Compositor { } } -pub fn new(settings: Settings) -> (Compositor, Backend) { +pub fn new() -> (Compositor, Backend) { ( Compositor { _theme: PhantomData, }, - Backend::new(settings), + Backend::new(), ) } diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 69568099..09740f54 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -21,20 +21,11 @@ guillotiere = "0.6" futures = "0.3" bitflags = "1.2" once_cell = "1.0" -rustc-hash = "1.1" log = "0.4" [target.'cfg(target_arch = "wasm32")'.dependencies] wgpu = { version = "0.16", features = ["webgl"] } -[dependencies.twox-hash] -version = "1.6" -default-features = false - -[target.'cfg(not(target_arch = "wasm32"))'.dependencies.twox-hash] -version = "1.6.1" -features = ["std"] - [dependencies.bytemuck] version = "1.9" features = ["derive"] diff --git a/wgpu/fonts/Iced-Icons.ttf b/wgpu/fonts/Iced-Icons.ttf deleted file mode 100644 index e3273141c45fff98c2f411b421e2e3fd225668aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5108 zcmZQzWME(rU}RumVPJ4`3-O)xzj-$UgYXRo1_l{-7gsk1bp{Cr2H_nH3=9hX!TLsa z3IS^v7#KSk7#PBma}x`G=sw=ez`*#0fq~I0xvWHi?dpFP1_pi$kovTO^xUqA6CxQH zm>n1xxC_z~iwi)uF)#>kU|?Y2NYANEbANfRhJk@Ug@J+LKt^g}itJxr9R>zQ9tH*m zvy6FU zFo5(i2mQ}tV1TG+UJ4R{%0Vbrum~%I7?@^YU}9in5MwB2U|`T=kOeDYWENzcz`)AD zz*NPwhk=2i2SPJGU@&B40%>4n2CKs$0@7Sl7#v z10x&Q;}A9|BtRI26@sQAknP za3Ej(WAg6;+u9c4vjMTL}& ztVvD^AQ_0|AaVm^f@|^yW-Ud94Q$Q|T?$R8-jD z5FD|AQCk}1DX7i58(4KVusdsSVqk&<4V%sec4a4Jg$)eKPKg_slF~LXCU0O&*ubi# zyMbLt0pv(-=j0tM3`q(gw{LJrhy*D~Z~;4#LuV5^H-odQla?YpusL;51D^|G3Zu62 z1_tL1EUF0#u3gHBpojp66oWJzmCEN0dSBg>|kL??ov+Nz~`Kx(3PODflt{jrLRrwv@n8yFLu6cRQtCTEv~bX8AMCyY-9n^k~$k%L9~?4Mm7*Ft+SCGM9b)G~|8w3&*oIzpX3@UFxc|;SGsI+x9XlZZI z($d|aqobhUu7D%Bl@l$LL1h(Q71D~4x*K%ialk0HK}Tx?qo@Hml=YB91yxF4N5K^A zP6Hi=4UDds*>wY>Hr7-C5@!(G!T-M zdg3;^8;l7l-N5LaY@xfsL}w!tgP5ve25I9*}x#Sfkkx#iz-;j22N+~)Gj?`1qGWf3*8N72x$d9umXh*EXqzGRSFvt z0wNSPI0Qy)W>R2QklxIs#w-=-1S;S-oE5s1!K#(r5;m|nqvw+Zg$<0_kdmCqIUz-P z1G95tNJPY=U34}uh(a>w zCI(PG6xQ2dsHMBX6^FQ+&PE1C5#bF+TDlwDbvBr2>2B}_fx*PmKYCwztkQxvp z5Tpjg2m-0G)7IS(3{nGPgn-n57@;6FAVwHSjf1xChH#J?5F-Ml2E>R2sR1#fKx&+| zbvHzV)PNWuyK^vuw0=H>83>W`nu*23u|24QVWpe8_Kapm@{C|YjCrZR zKLr6Dfq$>~`F#X*1eP%73Frv;2r!9>3H(#w=VufHa|M<%<_ie;@G~$l2r=A)_xwy5 za-eKR1}=sjP&N|-JHurto0&nCQ60)=Vc=p+hO${1xEUe6Y)}uAi*W^1oQpx5i5tr1 zW)NnI2lYl-I2jlivKSbkY(@qVhDA^|69XT^VJMrK!HeNGl+D5*!srWSvoeS==0VwP z3?ht^plmLNFviVLHaCMBlR1MkLq0*T zFeEWlGAJ8S)rP7*ZK>7;+f$ z8T1&E8S)u&85o@N3o45;(=$pGG@LaRj0}tn6p|_x@{2OlGxHL26cS5IGV+Ux6&w`O z^7Bekb8_1I1~%iOi)<^!k|)u Pfq~)v&0Qc>C}UUvroxeh diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index 68d1f805..65c63f19 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -1,5 +1,5 @@ -use crate::core; -use crate::core::{Color, Font, Point, Size}; +use crate::core::{Color, Size}; +use crate::graphics; use crate::graphics::backend; use crate::graphics::color; use crate::graphics::{Transformation, Viewport}; @@ -29,9 +29,6 @@ pub struct Backend { #[cfg(any(feature = "image", feature = "svg"))] image_pipeline: image::Pipeline, - - default_font: Font, - default_text_size: f32, } impl Backend { @@ -57,9 +54,6 @@ impl Backend { #[cfg(any(feature = "image", feature = "svg"))] image_pipeline, - - default_font: settings.default_font, - default_text_size: settings.default_text_size, } } @@ -313,65 +307,11 @@ impl Backend { impl crate::graphics::Backend for Backend { type Primitive = primitive::Custom; - - fn trim_measurements(&mut self) { - self.text_pipeline.trim_measurements(); - } } impl backend::Text for Backend { - const ICON_FONT: Font = Font::with_name("Iced-Icons"); - const CHECKMARK_ICON: char = '\u{f00c}'; - const ARROW_DOWN_ICON: char = '\u{e800}'; - - fn default_font(&self) -> Font { - self.default_font - } - - fn default_size(&self) -> f32 { - self.default_text_size - } - - fn measure( - &self, - contents: &str, - size: f32, - line_height: core::text::LineHeight, - font: Font, - bounds: Size, - shaping: core::text::Shaping, - ) -> Size { - self.text_pipeline.measure( - contents, - size, - line_height, - font, - bounds, - shaping, - ) - } - - fn hit_test( - &self, - contents: &str, - size: f32, - line_height: core::text::LineHeight, - font: Font, - bounds: Size, - shaping: core::text::Shaping, - point: Point, - nearest_only: bool, - ) -> Option { - self.text_pipeline.hit_test( - contents, - size, - line_height, - font, - bounds, - shaping, - point, - nearest_only, - ) + fn font_system(&self) -> &graphics::text::FontSystem { + self.text_pipeline.font_system() } fn load_font(&mut self, font: Cow<'static, [u8]>) { @@ -381,14 +321,17 @@ impl backend::Text for Backend { #[cfg(feature = "image")] impl backend::Image for Backend { - fn dimensions(&self, handle: &core::image::Handle) -> Size { + fn dimensions(&self, handle: &crate::core::image::Handle) -> Size { self.image_pipeline.dimensions(handle) } } #[cfg(feature = "svg")] impl backend::Svg for Backend { - fn viewport_dimensions(&self, handle: &core::svg::Handle) -> Size { + fn viewport_dimensions( + &self, + handle: &crate::core::svg::Handle, + ) -> Size { self.image_pipeline.viewport_dimensions(handle) } } diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs index b8f32db1..7a5a0f7c 100644 --- a/wgpu/src/layer.rs +++ b/wgpu/src/layer.rs @@ -10,7 +10,7 @@ pub use text::Text; use crate::core; use crate::core::alignment; -use crate::core::{Color, Font, Point, Rectangle, Size, Vector}; +use crate::core::{Color, Font, Pixels, Point, Rectangle, Size, Vector}; use crate::graphics; use crate::graphics::color; use crate::graphics::Viewport; @@ -56,14 +56,14 @@ impl<'a> Layer<'a> { Layer::new(Rectangle::with_size(viewport.logical_size())); for (i, line) in lines.iter().enumerate() { - let text = Text { + let text = text::Cached { content: line.as_ref(), bounds: Rectangle::new( Point::new(11.0, 11.0 + 25.0 * i as f32), Size::INFINITY, ), color: Color::new(0.9, 0.9, 0.9, 1.0), - size: 20.0, + size: Pixels(20.0), line_height: core::text::LineHeight::default(), font: Font::MONOSPACE, horizontal_alignment: alignment::Horizontal::Left, @@ -71,13 +71,13 @@ impl<'a> Layer<'a> { shaping: core::text::Shaping::Basic, }; - overlay.text.push(text); + overlay.text.push(Text::Cached(text.clone())); - overlay.text.push(Text { + overlay.text.push(Text::Cached(text::Cached { bounds: text.bounds + Vector::new(-1.0, -1.0), color: Color::BLACK, ..text - }); + })); } overlay @@ -113,6 +113,19 @@ impl<'a> Layer<'a> { current_layer: usize, ) { match primitive { + Primitive::Paragraph { + paragraph, + position, + color, + } => { + let layer = &mut layers[current_layer]; + + layer.text.push(Text::Managed { + paragraph: paragraph.clone(), + position: *position + translation, + color: *color, + }); + } Primitive::Text { content, bounds, @@ -126,7 +139,7 @@ impl<'a> Layer<'a> { } => { let layer = &mut layers[current_layer]; - layer.text.push(Text { + layer.text.push(Text::Cached(text::Cached { content, bounds: *bounds + translation, size: *size, @@ -136,7 +149,7 @@ impl<'a> Layer<'a> { horizontal_alignment: *horizontal_alignment, vertical_alignment: *vertical_alignment, shaping: *shaping, - }); + })); } Primitive::Quad { bounds, diff --git a/wgpu/src/layer/text.rs b/wgpu/src/layer/text.rs index ba1bdca8..b61615d6 100644 --- a/wgpu/src/layer/text.rs +++ b/wgpu/src/layer/text.rs @@ -1,10 +1,21 @@ use crate::core::alignment; use crate::core::text; -use crate::core::{Color, Font, Rectangle}; +use crate::core::{Color, Font, Pixels, Point, Rectangle}; +use crate::graphics::text::paragraph; /// A paragraph of text. -#[derive(Debug, Clone, Copy)] -pub struct Text<'a> { +#[derive(Debug, Clone)] +pub enum Text<'a> { + Managed { + paragraph: paragraph::Weak, + position: Point, + color: Color, + }, + Cached(Cached<'a>), +} + +#[derive(Debug, Clone)] +pub struct Cached<'a> { /// The content of the [`Text`]. pub content: &'a str, @@ -15,7 +26,7 @@ pub struct Text<'a> { pub color: Color, /// The size of the [`Text`] in logical pixels. - pub size: f32, + pub size: Pixels, /// The line height of the [`Text`]. pub line_height: text::LineHeight, diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index d1e4b7af..cd457072 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -22,7 +22,7 @@ )] #![deny( missing_debug_implementations, - missing_docs, + //missing_docs, unsafe_code, unused_results, clippy::extra_unused_lifetimes, diff --git a/wgpu/src/settings.rs b/wgpu/src/settings.rs index 266a2c87..c9338fec 100644 --- a/wgpu/src/settings.rs +++ b/wgpu/src/settings.rs @@ -1,5 +1,5 @@ //! Configure a renderer. -use crate::core::Font; +use crate::core::{Font, Pixels}; use crate::graphics::Antialiasing; /// The settings of a [`Backend`]. @@ -21,7 +21,7 @@ pub struct Settings { /// The default size of text. /// /// By default, it will be set to `16.0`. - pub default_text_size: f32, + pub default_text_size: Pixels, /// The antialiasing strategy that will be used for triangle primitives. /// @@ -59,7 +59,7 @@ impl Default for Settings { present_mode: wgpu::PresentMode::AutoVsync, internal_backend: wgpu::Backends::all(), default_font: Font::default(), - default_text_size: 16.0, + default_text_size: Pixels(16.0), antialiasing: None, } } diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index fb13545d..da2062fe 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -1,20 +1,17 @@ use crate::core::alignment; -use crate::core::font::{self, Font}; -use crate::core::text::{Hit, LineHeight, Shaping}; -use crate::core::{Pixels, Point, Rectangle, Size}; +use crate::core::{Rectangle, Size}; use crate::graphics::color; +use crate::graphics::text::cache::{self, Cache}; +use crate::graphics::text::{FontSystem, Paragraph}; use crate::layer::Text; -use rustc_hash::{FxHashMap, FxHashSet}; use std::borrow::Cow; use std::cell::RefCell; -use std::collections::hash_map; -use std::hash::{BuildHasher, Hash, Hasher}; use std::sync::Arc; #[allow(missing_debug_implementations)] pub struct Pipeline { - font_system: RefCell, + font_system: FontSystem, renderers: Vec, atlas: glyphon::TextAtlas, prepare_layer: usize, @@ -28,12 +25,7 @@ impl Pipeline { format: wgpu::TextureFormat, ) -> Self { Pipeline { - font_system: RefCell::new(glyphon::FontSystem::new_with_fonts( - [glyphon::fontdb::Source::Binary(Arc::new( - include_bytes!("../fonts/Iced-Icons.ttf").as_slice(), - ))] - .into_iter(), - )), + font_system: FontSystem::new(), renderers: Vec::new(), atlas: glyphon::TextAtlas::with_color_mode( device, @@ -50,6 +42,10 @@ impl Pipeline { } } + pub fn font_system(&self) -> &FontSystem { + &self.font_system + } + pub fn load_font(&mut self, bytes: Cow<'static, [u8]>) { let _ = self.font_system.get_mut().db_mut().load_font_source( glyphon::fontdb::Source::Binary(Arc::new(bytes.into_owned())), @@ -80,97 +76,137 @@ impl Pipeline { let renderer = &mut self.renderers[self.prepare_layer]; let cache = self.cache.get_mut(); - if self.prepare_layer == 0 { - cache.trim(Purpose::Drawing); + enum Allocation { + Paragraph(Paragraph), + Cache(cache::KeyHash), } - let keys: Vec<_> = sections + let allocations: Vec<_> = sections .iter() - .map(|section| { - let (key, _) = cache.allocate( - font_system, - Key { - content: section.content, - size: section.size, - line_height: f32::from( - section - .line_height - .to_absolute(Pixels(section.size)), - ), - font: section.font, - bounds: Size { - width: section.bounds.width, - height: section.bounds.height, + .map(|section| match section { + Text::Managed { paragraph, .. } => { + paragraph.upgrade().map(Allocation::Paragraph) + } + Text::Cached(text) => { + let (key, _) = cache.allocate( + font_system, + cache::Key { + content: text.content, + size: text.size.into(), + line_height: f32::from( + text.line_height.to_absolute(text.size), + ), + font: text.font, + bounds: Size { + width: bounds.width, + height: bounds.height, + }, + shaping: text.shaping, }, - shaping: section.shaping, - }, - Purpose::Drawing, - ); + ); - key + Some(Allocation::Cache(key)) + } }) .collect(); - let bounds = bounds * scale_factor; + let layer_bounds = bounds * scale_factor; - let text_areas = - sections - .iter() - .zip(keys.iter()) - .filter_map(|(section, key)| { - let entry = cache.get(key).expect("Get cached buffer"); + let text_areas = sections.iter().zip(allocations.iter()).filter_map( + |(section, allocation)| { + let ( + buffer, + bounds, + horizontal_alignment, + vertical_alignment, + color, + ) = match section { + Text::Managed { + position, color, .. + } => { + use crate::core::text::Paragraph as _; - let x = section.bounds.x * scale_factor; - let y = section.bounds.y * scale_factor; + let Some(Allocation::Paragraph(paragraph)) = allocation + else { + return None; + }; - let max_width = entry.bounds.width * scale_factor; - let total_height = entry.bounds.height * scale_factor; + ( + paragraph.buffer(), + Rectangle::new(*position, paragraph.min_bounds()), + paragraph.horizontal_alignment(), + paragraph.vertical_alignment(), + *color, + ) + } + Text::Cached(text) => { + let Some(Allocation::Cache(key)) = allocation else { + return None; + }; - let left = match section.horizontal_alignment { - alignment::Horizontal::Left => x, - alignment::Horizontal::Center => x - max_width / 2.0, - alignment::Horizontal::Right => x - max_width, - }; + let buffer = cache.get(key).expect("Get cached buffer"); - let top = match section.vertical_alignment { - alignment::Vertical::Top => y, - alignment::Vertical::Center => y - total_height / 2.0, - alignment::Vertical::Bottom => y - total_height, - }; + ( + buffer, + text.bounds, + text.horizontal_alignment, + text.vertical_alignment, + text.color, + ) + } + }; - let section_bounds = Rectangle { - x: left, - y: top, - width: section.bounds.width * scale_factor, - height: section.bounds.height * scale_factor, - }; + let x = bounds.x * scale_factor; + let y = bounds.y * scale_factor; - let clip_bounds = bounds.intersection(§ion_bounds)?; + let max_width = bounds.width * scale_factor; + let total_height = bounds.height * scale_factor; - Some(glyphon::TextArea { - buffer: &entry.buffer, - left, - top, - scale: scale_factor, - bounds: glyphon::TextBounds { - left: clip_bounds.x as i32, - top: clip_bounds.y as i32, - right: (clip_bounds.x + clip_bounds.width) as i32, - bottom: (clip_bounds.y + clip_bounds.height) as i32, - }, - default_color: { - let [r, g, b, a] = - color::pack(section.color).components(); + let left = match horizontal_alignment { + alignment::Horizontal::Left => x, + alignment::Horizontal::Center => x - max_width / 2.0, + alignment::Horizontal::Right => x - max_width, + }; - glyphon::Color::rgba( - (r * 255.0) as u8, - (g * 255.0) as u8, - (b * 255.0) as u8, - (a * 255.0) as u8, - ) - }, - }) - }); + let top = match vertical_alignment { + alignment::Vertical::Top => y, + alignment::Vertical::Center => y - total_height / 2.0, + alignment::Vertical::Bottom => y - total_height, + }; + + let section_bounds = Rectangle { + x: left, + y: top, + width: max_width, + height: total_height, + }; + + let clip_bounds = layer_bounds.intersection(§ion_bounds)?; + + Some(glyphon::TextArea { + buffer, + left, + top, + scale: scale_factor, + bounds: glyphon::TextBounds { + left: clip_bounds.x as i32, + top: clip_bounds.y as i32, + right: (clip_bounds.x + clip_bounds.width) as i32, + bottom: (clip_bounds.y + clip_bounds.height) as i32, + }, + default_color: { + let [r, g, b, a] = color::pack(color).components(); + + glyphon::Color::rgba( + (r * 255.0) as u8, + (g * 255.0) as u8, + (b * 255.0) as u8, + (a * 255.0) as u8, + ) + }, + }) + }, + ); let result = renderer.prepare( device, @@ -219,287 +255,8 @@ impl Pipeline { pub fn end_frame(&mut self) { self.atlas.trim(); + self.cache.get_mut().trim(); self.prepare_layer = 0; } - - pub fn trim_measurements(&mut self) { - self.cache.get_mut().trim(Purpose::Measuring); - } - - pub fn measure( - &self, - content: &str, - size: f32, - line_height: LineHeight, - font: Font, - bounds: Size, - shaping: Shaping, - ) -> Size { - let mut cache = self.cache.borrow_mut(); - - let line_height = f32::from(line_height.to_absolute(Pixels(size))); - - let (_, entry) = cache.allocate( - &mut self.font_system.borrow_mut(), - Key { - content, - size, - line_height, - font, - bounds, - shaping, - }, - Purpose::Measuring, - ); - - entry.bounds - } - - pub fn hit_test( - &self, - content: &str, - size: f32, - line_height: LineHeight, - font: Font, - bounds: Size, - shaping: Shaping, - point: Point, - _nearest_only: bool, - ) -> Option { - let mut cache = self.cache.borrow_mut(); - - let line_height = f32::from(line_height.to_absolute(Pixels(size))); - - let (_, entry) = cache.allocate( - &mut self.font_system.borrow_mut(), - Key { - content, - size, - line_height, - font, - bounds, - shaping, - }, - Purpose::Measuring, - ); - - let cursor = entry.buffer.hit(point.x, point.y)?; - - Some(Hit::CharOffset(cursor.index)) - } } - -fn measure(buffer: &glyphon::Buffer) -> Size { - let (width, total_lines) = buffer - .layout_runs() - .fold((0.0, 0usize), |(width, total_lines), run| { - (run.line_w.max(width), total_lines + 1) - }); - - Size::new(width, total_lines as f32 * buffer.metrics().line_height) -} - -fn to_family(family: font::Family) -> glyphon::Family<'static> { - match family { - font::Family::Name(name) => glyphon::Family::Name(name), - font::Family::SansSerif => glyphon::Family::SansSerif, - font::Family::Serif => glyphon::Family::Serif, - font::Family::Cursive => glyphon::Family::Cursive, - font::Family::Fantasy => glyphon::Family::Fantasy, - font::Family::Monospace => glyphon::Family::Monospace, - } -} - -fn to_weight(weight: font::Weight) -> glyphon::Weight { - match weight { - font::Weight::Thin => glyphon::Weight::THIN, - font::Weight::ExtraLight => glyphon::Weight::EXTRA_LIGHT, - font::Weight::Light => glyphon::Weight::LIGHT, - font::Weight::Normal => glyphon::Weight::NORMAL, - font::Weight::Medium => glyphon::Weight::MEDIUM, - font::Weight::Semibold => glyphon::Weight::SEMIBOLD, - font::Weight::Bold => glyphon::Weight::BOLD, - font::Weight::ExtraBold => glyphon::Weight::EXTRA_BOLD, - font::Weight::Black => glyphon::Weight::BLACK, - } -} - -fn to_stretch(stretch: font::Stretch) -> glyphon::Stretch { - match stretch { - font::Stretch::UltraCondensed => glyphon::Stretch::UltraCondensed, - font::Stretch::ExtraCondensed => glyphon::Stretch::ExtraCondensed, - font::Stretch::Condensed => glyphon::Stretch::Condensed, - font::Stretch::SemiCondensed => glyphon::Stretch::SemiCondensed, - font::Stretch::Normal => glyphon::Stretch::Normal, - font::Stretch::SemiExpanded => glyphon::Stretch::SemiExpanded, - font::Stretch::Expanded => glyphon::Stretch::Expanded, - font::Stretch::ExtraExpanded => glyphon::Stretch::ExtraExpanded, - font::Stretch::UltraExpanded => glyphon::Stretch::UltraExpanded, - } -} - -fn to_style(style: font::Style) -> glyphon::Style { - match style { - font::Style::Normal => glyphon::Style::Normal, - font::Style::Italic => glyphon::Style::Italic, - font::Style::Oblique => glyphon::Style::Oblique, - } -} - -fn to_shaping(shaping: Shaping) -> glyphon::Shaping { - match shaping { - Shaping::Basic => glyphon::Shaping::Basic, - Shaping::Advanced => glyphon::Shaping::Advanced, - } -} - -struct Cache { - entries: FxHashMap, - aliases: FxHashMap, - recently_measured: FxHashSet, - recently_drawn: FxHashSet, - hasher: HashBuilder, -} - -struct Entry { - buffer: glyphon::Buffer, - bounds: Size, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -enum Purpose { - Measuring, - Drawing, -} - -#[cfg(not(target_arch = "wasm32"))] -type HashBuilder = twox_hash::RandomXxHashBuilder64; - -#[cfg(target_arch = "wasm32")] -type HashBuilder = std::hash::BuildHasherDefault; - -impl Cache { - fn new() -> Self { - Self { - entries: FxHashMap::default(), - aliases: FxHashMap::default(), - recently_measured: FxHashSet::default(), - recently_drawn: FxHashSet::default(), - hasher: HashBuilder::default(), - } - } - - fn get(&self, key: &KeyHash) -> Option<&Entry> { - self.entries.get(key) - } - - fn allocate( - &mut self, - font_system: &mut glyphon::FontSystem, - key: Key<'_>, - purpose: Purpose, - ) -> (KeyHash, &mut Entry) { - let hash = key.hash(self.hasher.build_hasher()); - - let recently_used = match purpose { - Purpose::Measuring => &mut self.recently_measured, - Purpose::Drawing => &mut self.recently_drawn, - }; - - if let Some(hash) = self.aliases.get(&hash) { - let _ = recently_used.insert(*hash); - - return (*hash, self.entries.get_mut(hash).unwrap()); - } - - if let hash_map::Entry::Vacant(entry) = self.entries.entry(hash) { - let metrics = glyphon::Metrics::new(key.size, key.line_height); - let mut buffer = glyphon::Buffer::new(font_system, metrics); - - buffer.set_size( - font_system, - key.bounds.width, - key.bounds.height.max(key.line_height), - ); - buffer.set_text( - font_system, - key.content, - glyphon::Attrs::new() - .family(to_family(key.font.family)) - .weight(to_weight(key.font.weight)) - .stretch(to_stretch(key.font.stretch)) - .style(to_style(key.font.style)), - to_shaping(key.shaping), - ); - - let bounds = measure(&buffer); - let _ = entry.insert(Entry { buffer, bounds }); - - for bounds in [ - bounds, - Size { - width: key.bounds.width, - ..bounds - }, - ] { - if key.bounds != bounds { - let _ = self.aliases.insert( - Key { bounds, ..key }.hash(self.hasher.build_hasher()), - hash, - ); - } - } - } - - let _ = recently_used.insert(hash); - - (hash, self.entries.get_mut(&hash).unwrap()) - } - - fn trim(&mut self, purpose: Purpose) { - self.entries.retain(|key, _| { - self.recently_measured.contains(key) - || self.recently_drawn.contains(key) - }); - self.aliases.retain(|_, value| { - self.recently_measured.contains(value) - || self.recently_drawn.contains(value) - }); - - match purpose { - Purpose::Measuring => { - self.recently_measured.clear(); - } - Purpose::Drawing => { - self.recently_drawn.clear(); - } - } - } -} - -#[derive(Debug, Clone, Copy)] -struct Key<'a> { - content: &'a str, - size: f32, - line_height: f32, - font: Font, - bounds: Size, - shaping: Shaping, -} - -impl Key<'_> { - fn hash(self, mut hasher: H) -> KeyHash { - self.content.hash(&mut hasher); - self.size.to_bits().hash(&mut hasher); - self.line_height.to_bits().hash(&mut hasher); - self.font.hash(&mut hasher); - self.bounds.width.to_bits().hash(&mut hasher); - self.bounds.height.to_bits().hash(&mut hasher); - self.shaping.hash(&mut hasher); - - hasher.finish() - } -} - -type KeyHash = u64; diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index cd5b20cc..09e11fdc 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -216,7 +216,14 @@ impl graphics::Compositor for Compositor { ) -> Result<(Self, Self::Renderer), Error> { let (compositor, backend) = new(settings, compatible_window)?; - Ok((compositor, Renderer::new(backend))) + Ok(( + compositor, + Renderer::new( + backend, + settings.default_font, + settings.default_text_size, + ), + )) } fn create_surface( diff --git a/widget/src/button.rs b/widget/src/button.rs index 5727c631..1788b6c4 100644 --- a/widget/src/button.rs +++ b/widget/src/button.rs @@ -159,19 +159,15 @@ where fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - layout( - renderer, - limits, - self.width, - self.height, - self.padding, - |renderer, limits| { - self.content.as_widget().layout(renderer, limits) - }, - ) + layout(limits, self.width, self.height, self.padding, |limits| { + self.content + .as_widget() + .layout(&tree.children[0], renderer, limits) + }) } fn operate( @@ -426,17 +422,16 @@ where } /// Computes the layout of a [`Button`]. -pub fn layout( - renderer: &Renderer, +pub fn layout( limits: &layout::Limits, width: Length, height: Length, padding: Padding, - layout_content: impl FnOnce(&Renderer, &layout::Limits) -> layout::Node, + layout_content: impl FnOnce(&layout::Limits) -> layout::Node, ) -> layout::Node { let limits = limits.width(width).height(height); - let mut content = layout_content(renderer, &limits.pad(padding)); + let mut content = layout_content(&limits.pad(padding)); let padding = padding.fit(content.size(), limits.max()); let size = limits.pad(padding).resolve(content.size()).pad(padding); diff --git a/widget/src/canvas.rs b/widget/src/canvas.rs index 1a186432..d749355b 100644 --- a/widget/src/canvas.rs +++ b/widget/src/canvas.rs @@ -129,6 +129,7 @@ where fn layout( &self, + _tree: &Tree, _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/checkbox.rs b/widget/src/checkbox.rs index 310a67ed..a66ce3ff 100644 --- a/widget/src/checkbox.rs +++ b/widget/src/checkbox.rs @@ -6,12 +6,11 @@ use crate::core::mouse; use crate::core::renderer; use crate::core::text; use crate::core::touch; -use crate::core::widget::Tree; +use crate::core::widget; +use crate::core::widget::tree::{self, Tree}; use crate::core::{ - Alignment, Clipboard, Element, Layout, Length, Pixels, Rectangle, Shell, - Widget, + Clipboard, Element, Layout, Length, Pixels, Rectangle, Shell, Size, Widget, }; -use crate::{Row, Text}; pub use iced_style::checkbox::{Appearance, StyleSheet}; @@ -45,7 +44,7 @@ where width: Length, size: f32, spacing: f32, - text_size: Option, + text_size: Option, text_line_height: text::LineHeight, text_shaping: text::Shaping, font: Option, @@ -118,7 +117,7 @@ where /// Sets the text size of the [`Checkbox`]. pub fn text_size(mut self, text_size: impl Into) -> Self { - self.text_size = Some(text_size.into().0); + self.text_size = Some(text_size.into()); self } @@ -167,6 +166,14 @@ where Renderer: text::Renderer, Renderer::Theme: StyleSheet + crate::text::StyleSheet, { + fn tag(&self) -> tree::Tag { + tree::Tag::of::>() + } + + fn state(&self) -> tree::State { + tree::State::new(widget::text::State::::default()) + } + fn width(&self) -> Length { self.width } @@ -177,26 +184,35 @@ where fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - Row::<(), Renderer>::new() - .width(self.width) - .spacing(self.spacing) - .align_items(Alignment::Center) - .push(Row::new().width(self.size).height(self.size)) - .push( - Text::new(&self.label) - .font(self.font.unwrap_or_else(|| renderer.default_font())) - .width(self.width) - .size( - self.text_size - .unwrap_or_else(|| renderer.default_size()), - ) - .line_height(self.text_line_height) - .shaping(self.text_shaping), - ) - .layout(renderer, limits) + layout::next_to_each_other( + &limits.width(self.width), + self.spacing, + |_| layout::Node::new(Size::new(self.size, self.size)), + |limits| { + let state = tree + .state + .downcast_ref::>(); + + widget::text::layout( + state, + renderer, + limits, + self.width, + Length::Shrink, + &self.label, + self.text_line_height, + self.text_size, + self.font, + alignment::Horizontal::Left, + alignment::Vertical::Top, + self.text_shaping, + ) + }, + ) } fn on_event( @@ -244,7 +260,7 @@ where fn draw( &self, - _tree: &Tree, + tree: &Tree, renderer: &mut Renderer, theme: &Renderer::Theme, style: &renderer::Style, @@ -283,24 +299,23 @@ where line_height, shaping, } = &self.icon; - let size = size.unwrap_or(bounds.height * 0.7); + let size = size.unwrap_or(Pixels(bounds.height * 0.7)); if self.is_checked { - renderer.fill_text(text::Text { - content: &code_point.to_string(), - font: *font, - size, - line_height: *line_height, - bounds: Rectangle { - x: bounds.center_x(), - y: bounds.center_y(), - ..bounds + renderer.fill_text( + text::Text { + content: &code_point.to_string(), + font: *font, + size, + line_height: *line_height, + bounds: bounds.size(), + horizontal_alignment: alignment::Horizontal::Center, + vertical_alignment: alignment::Vertical::Center, + shaping: *shaping, }, - color: custom_style.icon_color, - horizontal_alignment: alignment::Horizontal::Center, - vertical_alignment: alignment::Vertical::Center, - shaping: *shaping, - }); + bounds.center(), + custom_style.icon_color, + ); } } @@ -311,16 +326,10 @@ where renderer, style, label_layout, - &self.label, - self.text_size, - self.text_line_height, - self.font, + tree.state.downcast_ref(), crate::text::Appearance { color: custom_style.text_color, }, - alignment::Horizontal::Left, - alignment::Vertical::Center, - self.text_shaping, ); } } @@ -348,7 +357,7 @@ pub struct Icon { /// The unicode code point that will be used as the icon. pub code_point: char, /// Font size of the content. - pub size: Option, + pub size: Option, /// The line height of the icon. pub line_height: text::LineHeight, /// The shaping strategy of the icon. diff --git a/widget/src/column.rs b/widget/src/column.rs index c16477f3..107c3475 100644 --- a/widget/src/column.rs +++ b/widget/src/column.rs @@ -122,6 +122,7 @@ where fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -138,6 +139,7 @@ where self.spacing, self.align_items, &self.children, + &tree.children, ) } diff --git a/widget/src/combo_box.rs b/widget/src/combo_box.rs index 690ef27c..8c20ae8e 100644 --- a/widget/src/combo_box.rs +++ b/widget/src/combo_box.rs @@ -144,11 +144,6 @@ where self } - /// Returns whether the [`ComboBox`] is currently focused or not. - pub fn is_focused(&self) -> bool { - self.state.is_focused() - } - /// Sets the text sixe of the [`ComboBox`]. pub fn size(mut self, size: f32) -> Self { self.text_input = self.text_input.size(size); @@ -179,7 +174,6 @@ pub struct State(RefCell>); #[derive(Debug, Clone)] struct Inner { - text_input: text_input::State, value: String, options: Vec, option_matchers: Vec, @@ -216,7 +210,6 @@ where ); Self(RefCell::new(Inner { - text_input: text_input::State::new(), value, options, option_matchers, @@ -224,51 +217,12 @@ where })) } - /// Focuses the [`ComboBox`]. - pub fn focused(self) -> Self { - self.focus(); - self - } - - /// Focuses the [`ComboBox`]. - pub fn focus(&self) { - let mut inner = self.0.borrow_mut(); - - inner.text_input.focus(); - } - - /// Unfocuses the [`ComboBox`]. - pub fn unfocus(&self) { - let mut inner = self.0.borrow_mut(); - - inner.text_input.unfocus(); - } - - /// Returns whether the [`ComboBox`] is currently focused or not. - pub fn is_focused(&self) -> bool { - let inner = self.0.borrow(); - - inner.text_input.is_focused() - } - fn value(&self) -> String { let inner = self.0.borrow(); inner.value.clone() } - fn text_input_tree(&self) -> widget::Tree { - let inner = self.0.borrow(); - - inner.text_input_tree() - } - - fn update_text_input(&self, tree: widget::Tree) { - let mut inner = self.0.borrow_mut(); - - inner.update_text_input(tree) - } - fn with_inner(&self, f: impl FnOnce(&Inner) -> O) -> O { let inner = self.0.borrow(); @@ -288,21 +242,6 @@ where } } -impl Inner { - fn text_input_tree(&self) -> widget::Tree { - widget::Tree { - tag: widget::tree::Tag::of::(), - state: widget::tree::State::new(self.text_input.clone()), - children: vec![], - } - } - - fn update_text_input(&mut self, tree: widget::Tree) { - self.text_input = - tree.state.downcast_ref::().clone(); - } -} - impl Filtered where T: Clone, @@ -366,10 +305,11 @@ where fn layout( &self, + tree: &widget::Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - self.text_input.layout(renderer, limits) + self.text_input.layout(tree, renderer, limits) } fn tag(&self) -> widget::tree::Tag { @@ -385,6 +325,10 @@ where }) } + fn children(&self) -> Vec { + vec![widget::Tree::new(&self.text_input as &dyn Widget<_, _>)] + } + fn on_event( &mut self, tree: &mut widget::Tree, @@ -398,7 +342,13 @@ where ) -> event::Status { let menu = tree.state.downcast_mut::>(); - let started_focused = self.state.is_focused(); + let started_focused = { + let text_input_state = tree.children[0] + .state + .downcast_ref::>(); + + text_input_state.is_focused() + }; // This is intended to check whether or not the message buffer was empty, // since `Shell` does not expose such functionality. let mut published_message_to_shell = false; @@ -408,9 +358,8 @@ where let mut local_shell = Shell::new(&mut local_messages); // Provide it to the widget - let mut tree = self.state.text_input_tree(); let mut event_status = self.text_input.on_event( - &mut tree, + &mut tree.children[0], event.clone(), layout, cursor, @@ -419,7 +368,6 @@ where &mut local_shell, viewport, ); - self.state.update_text_input(tree); // Then finally react to them here for message in local_messages { @@ -450,7 +398,15 @@ where shell.invalidate_layout(); } - if self.state.is_focused() { + let is_focused = { + let text_input_state = tree.children[0] + .state + .downcast_ref::>(); + + text_input_state.is_focused() + }; + + if is_focused { self.state.with_inner(|state| { if !started_focused { if let Some(on_option_hovered) = &mut self.on_option_hovered @@ -589,9 +545,8 @@ where published_message_to_shell = true; // Unfocus the input - let mut tree = state.text_input_tree(); let _ = self.text_input.on_event( - &mut tree, + &mut tree.children[0], Event::Mouse(mouse::Event::ButtonPressed( mouse::Button::Left, )), @@ -602,21 +557,25 @@ where &mut Shell::new(&mut vec![]), viewport, ); - state.update_text_input(tree); } }); - if started_focused - && !self.state.is_focused() - && !published_message_to_shell - { + let is_focused = { + let text_input_state = tree.children[0] + .state + .downcast_ref::>(); + + text_input_state.is_focused() + }; + + if started_focused && !is_focused && !published_message_to_shell { if let Some(message) = self.on_close.take() { shell.publish(message); } } // Focus changed, invalidate widget tree to force a fresh `view` - if started_focused != self.state.is_focused() { + if started_focused != is_focused { shell.invalidate_widgets(); } @@ -625,20 +584,24 @@ where fn mouse_interaction( &self, - _tree: &widget::Tree, + tree: &widget::Tree, layout: Layout<'_>, cursor: mouse::Cursor, viewport: &Rectangle, renderer: &Renderer, ) -> mouse::Interaction { - let tree = self.state.text_input_tree(); - self.text_input - .mouse_interaction(&tree, layout, cursor, viewport, renderer) + self.text_input.mouse_interaction( + &tree.children[0], + layout, + cursor, + viewport, + renderer, + ) } fn draw( &self, - _tree: &widget::Tree, + tree: &widget::Tree, renderer: &mut Renderer, theme: &Renderer::Theme, _style: &renderer::Style, @@ -646,16 +609,28 @@ where cursor: mouse::Cursor, _viewport: &Rectangle, ) { - let selection = if self.state.is_focused() || self.selection.is_empty() - { + let is_focused = { + let text_input_state = tree.children[0] + .state + .downcast_ref::>(); + + text_input_state.is_focused() + }; + + let selection = if is_focused || self.selection.is_empty() { None } else { Some(&self.selection) }; - let tree = self.state.text_input_tree(); - self.text_input - .draw(&tree, renderer, theme, layout, cursor, selection); + self.text_input.draw( + &tree.children[0], + renderer, + theme, + layout, + cursor, + selection, + ); } fn overlay<'b>( @@ -664,14 +639,22 @@ where layout: Layout<'_>, _renderer: &Renderer, ) -> Option> { - let Menu { - menu, - filtered_options, - hovered_option, - .. - } = tree.state.downcast_mut::>(); + let is_focused = { + let text_input_state = tree.children[0] + .state + .downcast_ref::>(); + + text_input_state.is_focused() + }; + + if is_focused { + let Menu { + menu, + filtered_options, + hovered_option, + .. + } = tree.state.downcast_mut::>(); - if self.state.is_focused() { let bounds = layout.bounds(); self.state.sync_filtered_options(filtered_options); diff --git a/widget/src/container.rs b/widget/src/container.rs index 1f1df861..c16c1117 100644 --- a/widget/src/container.rs +++ b/widget/src/container.rs @@ -5,7 +5,8 @@ use crate::core::layout; use crate::core::mouse; use crate::core::overlay; use crate::core::renderer; -use crate::core::widget::{self, Operation, Tree}; +use crate::core::widget::tree::{self, Tree}; +use crate::core::widget::{self, Operation}; use crate::core::{ Background, Clipboard, Color, Element, Layout, Length, Padding, Pixels, Point, Rectangle, Shell, Size, Vector, Widget, @@ -135,12 +136,20 @@ where Renderer: crate::core::Renderer, Renderer::Theme: StyleSheet, { + fn tag(&self) -> tree::Tag { + self.content.as_widget().tag() + } + + fn state(&self) -> tree::State { + self.content.as_widget().state() + } + fn children(&self) -> Vec { - vec![Tree::new(&self.content)] + self.content.as_widget().children() } fn diff(&self, tree: &mut Tree) { - tree.diff_children(std::slice::from_ref(&self.content)) + self.content.as_widget().diff(tree); } fn width(&self) -> Length { @@ -153,11 +162,11 @@ where fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { layout( - renderer, limits, self.width, self.height, @@ -166,9 +175,7 @@ where self.padding, self.horizontal_alignment, self.vertical_alignment, - |renderer, limits| { - self.content.as_widget().layout(renderer, limits) - }, + |limits| self.content.as_widget().layout(tree, renderer, limits), ) } @@ -184,7 +191,7 @@ where layout.bounds(), &mut |operation| { self.content.as_widget().operate( - &mut tree.children[0], + tree, layout.children().next().unwrap(), renderer, operation, @@ -205,7 +212,7 @@ where viewport: &Rectangle, ) -> event::Status { self.content.as_widget_mut().on_event( - &mut tree.children[0], + tree, event, layout.children().next().unwrap(), cursor, @@ -225,7 +232,7 @@ where renderer: &Renderer, ) -> mouse::Interaction { self.content.as_widget().mouse_interaction( - &tree.children[0], + tree, layout.children().next().unwrap(), cursor, viewport, @@ -248,7 +255,7 @@ where draw_background(renderer, &style, layout.bounds()); self.content.as_widget().draw( - &tree.children[0], + tree, renderer, theme, &renderer::Style { @@ -269,7 +276,7 @@ where renderer: &Renderer, ) -> Option> { self.content.as_widget_mut().overlay( - &mut tree.children[0], + tree, layout.children().next().unwrap(), renderer, ) @@ -291,8 +298,7 @@ where } /// Computes the layout of a [`Container`]. -pub fn layout( - renderer: &Renderer, +pub fn layout( limits: &layout::Limits, width: Length, height: Length, @@ -301,7 +307,7 @@ pub fn layout( padding: Padding, horizontal_alignment: alignment::Horizontal, vertical_alignment: alignment::Vertical, - layout_content: impl FnOnce(&Renderer, &layout::Limits) -> layout::Node, + layout_content: impl FnOnce(&layout::Limits) -> layout::Node, ) -> layout::Node { let limits = limits .loose() @@ -310,7 +316,7 @@ pub fn layout( .width(width) .height(height); - let mut content = layout_content(renderer, &limits.pad(padding).loose()); + let mut content = layout_content(&limits.pad(padding).loose()); let padding = padding.fit(content.size(), limits.max()); let size = limits.pad(padding).resolve(content.size()); diff --git a/widget/src/image.rs b/widget/src/image.rs index 66bf2156..f73ee5d7 100644 --- a/widget/src/image.rs +++ b/widget/src/image.rs @@ -167,6 +167,7 @@ where fn layout( &self, + _tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/image/viewer.rs b/widget/src/image/viewer.rs index 6e095667..1f52bf2f 100644 --- a/widget/src/image/viewer.rs +++ b/widget/src/image/viewer.rs @@ -105,6 +105,7 @@ where fn layout( &self, + _tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { diff --git a/widget/src/lazy.rs b/widget/src/lazy.rs index 761f45ad..412254f5 100644 --- a/widget/src/lazy.rs +++ b/widget/src/lazy.rs @@ -152,11 +152,12 @@ where fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { self.with_element(|element| { - element.as_widget().layout(renderer, limits) + element.as_widget().layout(tree, renderer, limits) }) } diff --git a/widget/src/lazy/component.rs b/widget/src/lazy/component.rs index 19df2792..9b3b13b2 100644 --- a/widget/src/lazy/component.rs +++ b/widget/src/lazy/component.rs @@ -254,11 +254,12 @@ where fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { self.with_element(|element| { - element.as_widget().layout(renderer, limits) + element.as_widget().layout(tree, renderer, limits) }) } diff --git a/widget/src/lazy/responsive.rs b/widget/src/lazy/responsive.rs index b56545c8..5ab8ed1a 100644 --- a/widget/src/lazy/responsive.rs +++ b/widget/src/lazy/responsive.rs @@ -60,13 +60,13 @@ impl<'a, Message, Renderer> Content<'a, Message, Renderer> where Renderer: core::Renderer, { - fn layout(&mut self, renderer: &Renderer) { + fn layout(&mut self, tree: &Tree, renderer: &Renderer) { if self.layout.is_none() { - self.layout = - Some(self.element.as_widget().layout( - renderer, - &layout::Limits::new(Size::ZERO, self.size), - )); + self.layout = Some(self.element.as_widget().layout( + tree, + renderer, + &layout::Limits::new(Size::ZERO, self.size), + )); } } @@ -104,7 +104,7 @@ where R: Deref, { self.update(tree, layout.bounds().size(), view); - self.layout(renderer.deref()); + self.layout(tree, renderer.deref()); let content_layout = Layout::with_offset( layout.position() - Point::ORIGIN, @@ -144,6 +144,7 @@ where fn layout( &self, + _tree: &Tree, _renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -285,7 +286,7 @@ where overlay_builder: |content: &mut RefMut<'_, Content<'_, _, _>>, tree| { content.update(tree, layout.bounds().size(), &self.view); - content.layout(renderer); + content.layout(tree, renderer); let Content { element, diff --git a/widget/src/mouse_area.rs b/widget/src/mouse_area.rs index 490f7c48..95b45b02 100644 --- a/widget/src/mouse_area.rs +++ b/widget/src/mouse_area.rs @@ -120,10 +120,11 @@ where fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - self.content.as_widget().layout(renderer, limits) + self.content.as_widget().layout(tree, renderer, limits) } fn operate( diff --git a/widget/src/overlay/menu.rs b/widget/src/overlay/menu.rs index f7bdeef6..71703e71 100644 --- a/widget/src/overlay/menu.rs +++ b/widget/src/overlay/menu.rs @@ -31,7 +31,7 @@ where on_option_hovered: Option<&'a dyn Fn(T) -> Message>, width: f32, padding: Padding, - text_size: Option, + text_size: Option, text_line_height: text::LineHeight, text_shaping: text::Shaping, font: Option, @@ -85,7 +85,7 @@ where /// Sets the text size of the [`Menu`]. pub fn text_size(mut self, text_size: impl Into) -> Self { - self.text_size = Some(text_size.into().0); + self.text_size = Some(text_size.into()); self } @@ -253,7 +253,7 @@ where ) .width(self.width); - let mut node = self.container.layout(renderer, &limits); + let mut node = self.container.layout(self.state, renderer, &limits); node.move_to(if space_below > space_above { position + Vector::new(0.0, self.target_height) @@ -328,7 +328,7 @@ where on_selected: Box Message + 'a>, on_option_hovered: Option<&'a dyn Fn(T) -> Message>, padding: Padding, - text_size: Option, + text_size: Option, text_line_height: text::LineHeight, text_shaping: text::Shaping, font: Option, @@ -352,6 +352,7 @@ where fn layout( &self, + _tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { @@ -361,8 +362,7 @@ where let text_size = self.text_size.unwrap_or_else(|| renderer.default_size()); - let text_line_height = - self.text_line_height.to_absolute(Pixels(text_size)); + let text_line_height = self.text_line_height.to_absolute(text_size); let size = { let intrinsic = Size::new( @@ -407,9 +407,9 @@ where .text_size .unwrap_or_else(|| renderer.default_size()); - let option_height = f32::from( - self.text_line_height.to_absolute(Pixels(text_size)), - ) + self.padding.vertical(); + let option_height = + f32::from(self.text_line_height.to_absolute(text_size)) + + self.padding.vertical(); let new_hovered_option = (cursor_position.y / option_height) as usize; @@ -436,9 +436,9 @@ where .text_size .unwrap_or_else(|| renderer.default_size()); - let option_height = f32::from( - self.text_line_height.to_absolute(Pixels(text_size)), - ) + self.padding.vertical(); + let option_height = + f32::from(self.text_line_height.to_absolute(text_size)) + + self.padding.vertical(); *self.hovered_option = Some((cursor_position.y / option_height) as usize); @@ -490,7 +490,7 @@ where let text_size = self.text_size.unwrap_or_else(|| renderer.default_size()); let option_height = - f32::from(self.text_line_height.to_absolute(Pixels(text_size))) + f32::from(self.text_line_height.to_absolute(text_size)) + self.padding.vertical(); let offset = viewport.y - bounds.y; @@ -526,26 +526,24 @@ where ); } - renderer.fill_text(Text { - content: &option.to_string(), - bounds: Rectangle { - x: bounds.x + self.padding.left, - y: bounds.center_y(), - width: f32::INFINITY, - ..bounds + renderer.fill_text( + Text { + content: &option.to_string(), + bounds: Size::new(f32::INFINITY, bounds.height), + size: text_size, + line_height: self.text_line_height, + font: self.font.unwrap_or_else(|| renderer.default_font()), + horizontal_alignment: alignment::Horizontal::Left, + vertical_alignment: alignment::Vertical::Center, + shaping: self.text_shaping, }, - size: text_size, - line_height: self.text_line_height, - font: self.font.unwrap_or_else(|| renderer.default_font()), - color: if is_selected { + Point::new(bounds.x + self.padding.left, bounds.center_y()), + if is_selected { appearance.selected_text_color } else { appearance.text_color }, - horizontal_alignment: alignment::Horizontal::Left, - vertical_alignment: alignment::Vertical::Center, - shaping: self.text_shaping, - }); + ); } } } diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs index d8c98858..366d9a66 100644 --- a/widget/src/pane_grid.rs +++ b/widget/src/pane_grid.rs @@ -275,10 +275,12 @@ where fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { layout( + tree, renderer, limits, self.contents.layout(), @@ -286,7 +288,9 @@ where self.height, self.spacing, self.contents.iter(), - |content, renderer, limits| content.layout(renderer, limits), + |content, tree, renderer, limits| { + content.layout(tree, renderer, limits) + }, ) } @@ -471,6 +475,7 @@ where /// Calculates the [`Layout`] of a [`PaneGrid`]. pub fn layout( + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, node: &Node, @@ -478,19 +483,21 @@ pub fn layout( height: Length, spacing: f32, contents: impl Iterator, - layout_content: impl Fn(T, &Renderer, &layout::Limits) -> layout::Node, + layout_content: impl Fn(T, &Tree, &Renderer, &layout::Limits) -> layout::Node, ) -> layout::Node { let limits = limits.width(width).height(height); let size = limits.resolve(Size::ZERO); let regions = node.pane_regions(spacing, size); let children = contents - .filter_map(|(pane, content)| { + .zip(tree.children.iter()) + .filter_map(|((pane, content), tree)| { let region = regions.get(&pane)?; let size = Size::new(region.width, region.height); let mut node = layout_content( content, + tree, renderer, &layout::Limits::new(size, size), ); diff --git a/widget/src/pane_grid/content.rs b/widget/src/pane_grid/content.rs index e890e41a..8a74b4b9 100644 --- a/widget/src/pane_grid/content.rs +++ b/widget/src/pane_grid/content.rs @@ -150,18 +150,23 @@ where pub(crate) fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { if let Some(title_bar) = &self.title_bar { let max_size = limits.max(); - let title_bar_layout = title_bar - .layout(renderer, &layout::Limits::new(Size::ZERO, max_size)); + let title_bar_layout = title_bar.layout( + &tree.children[1], + renderer, + &layout::Limits::new(Size::ZERO, max_size), + ); let title_bar_size = title_bar_layout.size(); let mut body_layout = self.body.as_widget().layout( + &tree.children[0], renderer, &layout::Limits::new( Size::ZERO, @@ -179,7 +184,9 @@ where vec![title_bar_layout, body_layout], ) } else { - self.body.as_widget().layout(renderer, limits) + self.body + .as_widget() + .layout(&tree.children[0], renderer, limits) } } diff --git a/widget/src/pane_grid/title_bar.rs b/widget/src/pane_grid/title_bar.rs index cac24e68..c0fb9936 100644 --- a/widget/src/pane_grid/title_bar.rs +++ b/widget/src/pane_grid/title_bar.rs @@ -213,23 +213,27 @@ where pub(crate) fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { let limits = limits.pad(self.padding); let max_size = limits.max(); - let title_layout = self - .content - .as_widget() - .layout(renderer, &layout::Limits::new(Size::ZERO, max_size)); + let title_layout = self.content.as_widget().layout( + &tree.children[0], + renderer, + &layout::Limits::new(Size::ZERO, max_size), + ); let title_size = title_layout.size(); let mut node = if let Some(controls) = &self.controls { - let mut controls_layout = controls - .as_widget() - .layout(renderer, &layout::Limits::new(Size::ZERO, max_size)); + let mut controls_layout = controls.as_widget().layout( + &tree.children[1], + renderer, + &layout::Limits::new(Size::ZERO, max_size), + ); let controls_size = controls_layout.size(); let space_before_controls = max_size.width - controls_size.width; diff --git a/widget/src/pick_list.rs b/widget/src/pick_list.rs index 0a1e2a99..719aa066 100644 --- a/widget/src/pick_list.rs +++ b/widget/src/pick_list.rs @@ -7,17 +7,18 @@ use crate::core::layout; use crate::core::mouse; use crate::core::overlay; use crate::core::renderer; -use crate::core::text::{self, Text}; +use crate::core::text::{self, Paragraph as _, Text}; use crate::core::touch; use crate::core::widget::tree::{self, Tree}; use crate::core::{ - Clipboard, Element, Layout, Length, Padding, Pixels, Rectangle, Shell, - Size, Widget, + Clipboard, Element, Layout, Length, Padding, Pixels, Point, Rectangle, + Shell, Size, Widget, }; use crate::overlay::menu::{self, Menu}; use crate::scrollable; use std::borrow::Cow; +use std::cell::RefCell; pub use crate::style::pick_list::{Appearance, StyleSheet}; @@ -35,7 +36,7 @@ where selected: Option, width: Length, padding: Padding, - text_size: Option, + text_size: Option, text_line_height: text::LineHeight, text_shaping: text::Shaping, font: Option, @@ -101,7 +102,7 @@ where /// Sets the text size of the [`PickList`]. pub fn text_size(mut self, size: impl Into) -> Self { - self.text_size = Some(size.into().0); + self.text_size = Some(size.into()); self } @@ -157,11 +158,11 @@ where From<::Style>, { fn tag(&self) -> tree::Tag { - tree::Tag::of::() + tree::Tag::of::>() } fn state(&self) -> tree::State { - tree::State::new(State::new()) + tree::State::new(State::::new()) } fn width(&self) -> Length { @@ -174,10 +175,12 @@ where fn layout( &self, + tree: &Tree, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { layout( + tree.state.downcast_ref::>(), renderer, limits, self.width, @@ -210,7 +213,7 @@ where self.on_selected.as_ref(), self.selected.as_ref(), &self.options, - || tree.state.downcast_mut::(), + || tree.state.downcast_mut::>(), ) } @@ -250,7 +253,7 @@ where self.selected.as_ref(), &self.handle, &self.style, - || tree.state.downcast_ref::(), + || tree.state.downcast_ref::>(), ) } @@ -260,7 +263,7 @@ where layout: Layout<'_>, renderer: &Renderer, ) -> Option> { - let state = tree.state.downcast_mut::(); + let state = tree.state.downcast_mut::>(); overlay( layout, @@ -295,28 +298,32 @@ where } } -/// The local state of a [`PickList`]. +/// The state of a [`PickList`]. #[derive(Debug)] -pub struct State { +pub struct State { menu: menu::State, keyboard_modifiers: keyboard::Modifiers, is_open: bool, hovered_option: Option, + option_paragraphs: RefCell>, + placeholder_paragraph: RefCell

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