···11//! Events that effect gameplay and aren't purely visual.
2233-use crate::{impl_timed, loose_enum};
33+use crate::impl_timed;
44+use loose_enum::loose_enum;
45use serde::{Deserialize, Serialize};
5667/// Controls the rotation that interactable objects spawn in 90/360 degree difficulties.
···25262627loose_enum!(
2728 /// Determines when a [`LaneRotationEvent`] will be applied to objects.
2828- #[derive(Default, Copy)]
2929- ExecutionTime: i32 {
2929+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
3030+ #[cfg_attr(
3131+ feature = "bevy_reflect",
3232+ derive(bevy_reflect::Reflect),
3333+ reflect(Debug, Clone, PartialEq)
3434+ )]
3535+ pub enum ExecutionTime: i32 {
3036 /// The [`LaneRotationEvent`] will affect objects with a beat *greater than or equal to* the event's beat.
3137 #[default]
3238 Early = 0,
+23-8
src/difficulty/lightshow.rs
···1414#[doc(hidden)]
1515pub use group::*;
16161717-use crate::loose_enum;
1717+use loose_enum::loose_enum;
18181919loose_enum! {
2020 /// The way that the distribution value is used.
2121- #[derive(Default, Copy)]
2222- DistributionType: i32 {
2121+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
2222+ #[cfg_attr(
2323+ feature = "bevy_reflect",
2424+ derive(bevy_reflect::Reflect),
2525+ reflect(Debug, Clone, PartialEq)
2626+ )]
2727+ pub enum DistributionType: i32 {
2328 /// The distribution value represents the difference between *the last and first step*.
2429 #[default]
2530 Wave = 1,
···171176172177loose_enum! {
173178 /// Controls how the state is changed relative to the previous event.
174174- #[derive(Default, Copy)]
175175- TransitionType: i32 {
179179+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
180180+ #[cfg_attr(
181181+ feature = "bevy_reflect",
182182+ derive(bevy_reflect::Reflect),
183183+ reflect(Debug, Clone, PartialEq)
184184+ )]
185185+ pub enum TransitionType: i32 {
176186 /// The state will blend from the previous event's state, using the events [easing](Easing).
177187 #[default]
178188 Transition = 0,
···183193184194loose_enum! {
185195 /// The axis that a rotation/translation event effects.
186186- #[derive(Default, Copy)]
187187- EventAxis: i32 {
196196+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
197197+ #[cfg_attr(
198198+ feature = "bevy_reflect",
199199+ derive(bevy_reflect::Reflect),
200200+ reflect(Debug, Clone, PartialEq)
201201+ )]
202202+ pub enum EventAxis: i32 {
188203 #[default]
189204 X = 0,
190205 Y = 1,
···198213mod tests {
199214 use super::*;
200215 use crate::difficulty::lightshow::filter::FilterType;
201201- use crate::utils::LooseBool;
216216+ use loose_enum::LooseBool;
202217203218 #[test]
204219 fn wave() {
+8-3
src/difficulty/lightshow/easing.rs
···11//! The easing that a [transition](crate::lightshow::TransitionType::Transition) event will use.
2233-use crate::loose_enum;
33+use loose_enum::loose_enum;
44use simple_easing::*;
5566loose_enum! {
77 /// The easing that a [transition](crate::lightshow::TransitionType::Transition) event will use.
88- #[derive(Default, Copy)]
99- Easing: i32 {
88+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
99+ #[cfg_attr(
1010+ feature = "bevy_reflect",
1111+ derive(bevy_reflect::Reflect),
1212+ reflect(Debug, Clone, PartialEq)
1313+ )]
1414+ pub enum Easing: i32 {
1015 #[default]
1116 None = -1,
1217
+23-9
src/difficulty/lightshow/filter.rs
···11//! Controls which light IDs are affected by an event.
2233-use crate::loose_enum;
44-use crate::utils::LooseBool;
33+use loose_enum::{LooseBool, loose_enum};
54use serde::{Deserialize, Serialize};
6576/// Controls which light IDs are affected by an event.
···2423 pub parameter2: i32,
2524 /// If true, the filter will start at the end of a group and work backwards.
2625 #[serde(rename = "r")]
2727- pub reverse: LooseBool,
2626+ pub reverse: LooseBool<i32>,
2827 // V3.1:
2928 /// > Only present in difficulty file V3.1 or higher.
3029 ///
···208207loose_enum! {
209208 /// Controls how a [`Filter`]'s [`parameter1`](Filter::parameter1)
210209 /// and [`parameter2`](Filter::parameter2) values are used.
211211- #[derive(Default, Copy)]
212212- FilterType: i32 {
210210+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
211211+ #[cfg_attr(
212212+ feature = "bevy_reflect",
213213+ derive(bevy_reflect::Reflect),
214214+ reflect(Debug, Clone, PartialEq)
215215+ )]
216216+ pub enum FilterType: i32 {
213217 /// Splits the group up into equal sections and selects one.
214218 /// - [`parameter1`](Filter::parameter1) determines the number of sections.
215219 /// It will be rounded up to the nearest multiple of the group size.
···224228}
225229226230loose_enum!(
227227- #[derive(Default, Copy)]
228228- RandomBehaviour: i32 {
231231+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
232232+ #[cfg_attr(
233233+ feature = "bevy_reflect",
234234+ derive(bevy_reflect::Reflect),
235235+ reflect(Debug, Clone, PartialEq)
236236+ )]
237237+ pub enum RandomBehaviour: i32 {
229238 #[default]
230239 None = 0,
231240 KeepOrder = 1,
···239248 /// To see this in practice, check out [this video](https://youtube.com/watch?v=NJPPBvyHJjg&t=338).
240249 ///
241250 /// Includes the option to only enable for beat distribution and not value distribution, and vice versa.
242242- #[derive(Default, Copy)]
243243- LimitBehaviour: i32 {
251251+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
252252+ #[cfg_attr(
253253+ feature = "bevy_reflect",
254254+ derive(bevy_reflect::Reflect),
255255+ reflect(Debug, Clone, PartialEq)
256256+ )]
257257+ pub enum LimitBehaviour: i32 {
244258 #[default]
245259 None = 0,
246260 Beat = 1,
+18-8
src/difficulty/lightshow/group/color.rs
···33use crate::difficulty::lightshow::DistributionType;
44use crate::difficulty::lightshow::easing::Easing;
55use crate::difficulty::lightshow::filter::Filter;
66-use crate::utils::LooseBool;
77-use crate::{impl_event_box, impl_event_data, impl_event_group, impl_timed, loose_enum};
66+use crate::{impl_event_box, impl_event_data, impl_event_group, impl_timed};
77+use loose_enum::{LooseBool, loose_enum};
88use serde::{Deserialize, Serialize};
991010/// A collection of [`ColorEventGroup`]s that share the same group ID and beat.
···6565 pub bright_dist_value: f32,
6666 /// Whether the first [`ColorEventData`] of the group will be effected by brightness distribution.
6767 #[serde(rename = "b")]
6868- pub bright_dist_effect_first: LooseBool,
6868+ pub bright_dist_effect_first: LooseBool<i32>,
6969 /// > Only present in difficulty file V3.2 or higher.
7070 #[serde(rename = "i")]
7171 pub bright_dist_easing: Option<Easing>,
···140140 ///
141141 /// Whether to fade between strobe states or not.
142142 #[serde(rename = "sf")]
143143- pub strobe_fade: Option<LooseBool>,
143143+ pub strobe_fade: Option<LooseBool<i32>>,
144144}
145145146146impl Default for ColorEventData {
···161161162162loose_enum! {
163163 /// Controls how the state is changed relative to the previous event.
164164- #[derive(Default, Copy)]
165165- ColorTransitionType: i32 {
164164+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
165165+ #[cfg_attr(
166166+ feature = "bevy_reflect",
167167+ derive(bevy_reflect::Reflect),
168168+ reflect(Debug, Clone, PartialEq)
169169+ )]
170170+ pub enum ColorTransitionType: i32 {
166171 /// Unique to color events.
167172 /// Has the same effect as using [`TransitionType::Transition`](crate::lightshow::TransitionType::Transition)
168173 /// and [`Easing::None`] in rotation/translation events.
···177182178183loose_enum! {
179184 /// Controls which color to display, based on a map or environment's [color scheme](crate::info::color_scheme::ColorScheme).
180180- #[derive(Default, Copy)]
181181- LightColor: i32 {
185185+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
186186+ #[cfg_attr(
187187+ feature = "bevy_reflect",
188188+ derive(bevy_reflect::Reflect),
189189+ reflect(Debug, Clone, PartialEq)
190190+ )]
191191+ pub enum LightColor: i32 {
182192 #[default]
183193 Primary = 0,
184194 Secondary = 1,
+4-3
src/difficulty/lightshow/group/fx.rs
···77use crate::difficulty::lightshow::DistributionType;
88use crate::difficulty::lightshow::easing::Easing;
99use crate::difficulty::lightshow::filter::Filter;
1010-use crate::utils::LooseBool;
1110use crate::{TransitionType, impl_event_box, impl_event_data, impl_event_group, impl_timed};
1211use indexmap::IndexSet;
1212+use loose_enum::LooseBool;
1313use ordered_float::OrderedFloat;
1414use serde::ser::SerializeStruct;
1515use serde::{Deserialize, Deserializer, Serialize, Serializer};
···237237 /// A value of zero will have no effect.
238238 pub fx_dist_value: f32,
239239 /// Whether the first [`FxEventData`] of the group will be effected by brightness distribution.
240240- pub fx_dist_effect_first: LooseBool,
240240+ pub fx_dist_effect_first: LooseBool<i32>,
241241 pub fx_dist_easing: Option<Easing>,
242242 /// In the actual JSON structure, this is a list of indexes to a separate list of event data.
243243 /// For consistency, this is merged during parsing.
···258258 #[serde(rename = "s")]
259259 fx_dist_value: f32,
260260 #[serde(rename = "b")]
261261- fx_dist_effect_first: LooseBool,
261261+ fx_dist_effect_first: LooseBool<i32>,
262262 #[serde(rename = "i")]
263263 fx_dist_easing: Option<Easing>,
264264 #[serde(rename = "l")]
···367367#[cfg(test)]
368368mod tests {
369369 use super::*;
370370+ use loose_enum::LooseBool;
370371 use serde_json::{Value, json};
371372372373 fn get_test_container() -> FxEventContainer {
+11-6
src/difficulty/lightshow/group/rotation.rs
···44use crate::difficulty::lightshow::filter::Filter;
55use crate::difficulty::lightshow::group::EventData;
66use crate::difficulty::lightshow::{DistributionType, EventAxis, TransitionType};
77-use crate::utils::LooseBool;
88-use crate::{impl_event_box, impl_event_group, impl_timed, loose_enum};
77+use crate::{impl_event_box, impl_event_group, impl_timed};
88+use loose_enum::{LooseBool, loose_enum};
99use serde::{Deserialize, Serialize};
10101111/// A collection of [`RotationEventGroup`]s that share the same group ID and beat.
···6565 pub rotation_dist_value: f32,
6666 /// Whether the first [`RotationEventData`] of the group will be effected by rotation distribution.
6767 #[serde(rename = "b")]
6868- pub rotation_dist_effect_first: LooseBool,
6868+ pub rotation_dist_effect_first: LooseBool<i32>,
6969 /// > Only present in difficulty file V3.2 or higher.
7070 #[serde(rename = "i")]
7171 pub rotation_dist_easing: Option<Easing>,
···7373 pub axis: EventAxis,
7474 /// If true, the rotation will be mirrored.
7575 #[serde(rename = "r")]
7676- pub invert_axis: LooseBool,
7676+ pub invert_axis: LooseBool<i32>,
7777 #[serde(rename = "l")]
7878 pub data: Vec<RotationEventData>,
7979}
···149149loose_enum! {
150150 /// Determines the direction that the rotation event will rotate.
151151 /// Automatic will choose the shortest distance.
152152- #[derive(Default, Copy)]
153153- RotationDirection: i32 {
152152+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
153153+ #[cfg_attr(
154154+ feature = "bevy_reflect",
155155+ derive(bevy_reflect::Reflect),
156156+ reflect(Debug, Clone, PartialEq)
157157+ )]
158158+ pub enum RotationDirection: i32 {
154159 #[default]
155160 Automatic = 0,
156161 Clockwise = 1,
+3-3
src/difficulty/lightshow/group/translation.rs
···44use crate::difficulty::lightshow::filter::Filter;
55use crate::difficulty::lightshow::group::EventData;
66use crate::difficulty::lightshow::{DistributionType, EventAxis, TransitionType};
77-use crate::utils::LooseBool;
87use crate::{impl_event_box, impl_event_group, impl_timed};
88+use loose_enum::LooseBool;
99use serde::{Deserialize, Serialize};
10101111/// A collection of [`TranslationEventGroup`]s that share the same group ID and beat.
···6969 pub translation_dist_value: f32,
7070 /// Whether the first [`TranslationEventData`] of the group will be effected by translation distribution.
7171 #[serde(rename = "b")]
7272- pub translation_dist_effect_first: LooseBool,
7272+ pub translation_dist_effect_first: LooseBool<i32>,
7373 #[serde(rename = "i")]
7474 pub translation_dist_easing: Easing,
7575 #[serde(rename = "a")]
7676 pub axis: EventAxis,
7777 /// If true, the translation will be mirrored.
7878 #[serde(rename = "r")]
7979- pub invert_axis: LooseBool,
7979+ pub invert_axis: LooseBool<i32>,
8080 #[serde(rename = "l")]
8181 pub data: Vec<TranslationEventData>,
8282}
+23-7
src/difficulty/playfield.rs
···11//! The interactable objects of a difficulty.
2233-use crate::{impl_duration, impl_timed, loose_enum};
33+use crate::{impl_duration, impl_timed};
44+use loose_enum::loose_enum;
45use serde::{Deserialize, Serialize};
5667/// The standard block/note that a player cuts.
···38393940loose_enum! {
4041 /// The color of a note, which determines which saber should be used to cut it.
4141- #[derive(Default, Copy)]
4242- NoteColor: i32 {
4242+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
4343+ #[cfg_attr(
4444+ feature = "bevy_reflect",
4545+ derive(bevy_reflect::Reflect),
4646+ reflect(Debug, Clone, PartialEq)
4747+ )]
4848+ pub enum NoteColor: i32 {
4349 #[default]
4450 Left = 0,
4551 Right = 1,
···48544955loose_enum! {
5056 /// The direction a note should be cut.
5151- #[derive(Default, Copy)]
5252- CutDirection: i32 {
5757+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
5858+ #[cfg_attr(
5959+ feature = "bevy_reflect",
6060+ derive(bevy_reflect::Reflect),
6161+ reflect(Debug, Clone, PartialEq)
6262+ )]
6363+ pub enum CutDirection: i32 {
5364 #[default]
5465 Up = 0,
5566 Down = 1,
···231242232243loose_enum! {
233244 /// Controls how an arc curves from its head to its tail.
234234- #[derive(Default, Copy)]
235235- MidAnchorMode: i32 {
245245+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
246246+ #[cfg_attr(
247247+ feature = "bevy_reflect",
248248+ derive(bevy_reflect::Reflect),
249249+ reflect(Debug, Clone, PartialEq)
250250+ )]
251251+ pub enum MidAnchorMode: i32 {
236252 #[default]
237253 Straight = 0,
238254 Clockwise = 1,
+29-9
src/info.rs
···4455#[doc(hidden)]
66pub use color_scheme::*;
77+use loose_enum::loose_enum;
7888-use crate::loose_enum;
99use serde::{Deserialize, Serialize};
10101111/// A map's `Info.dat` file.
···6767 /// The world that surrounds the player and defines which lights are available.
6868 ///
6969 /// For 90/360 degree mode, see [`AllDirectionEnvironment`].
7070- #[derive(Default)]
7171- Environment: String {
7070+ #[derive(Default, Debug, Clone, Eq, PartialEq, Hash)]
7171+ #[cfg_attr(
7272+ feature = "bevy_reflect",
7373+ derive(bevy_reflect::Reflect),
7474+ reflect(Debug, Clone, PartialEq)
7575+ )]
7676+ pub enum Environment: String {
7277 #[default]
7378 #[doc(alias = "Default")]
7479 TheFirst = "DefaultEnvironment",
···124129 /// The world that surrounds the player while playing 90/360 degree mode.
125130 ///
126131 /// For standard mode, see [`Environment`].
127127- #[derive(Default)]
128128- AllDirectionEnvironment: String {
132132+ #[derive(Default, Debug, Clone, Eq, PartialEq, Hash)]
133133+ #[cfg_attr(
134134+ feature = "bevy_reflect",
135135+ derive(bevy_reflect::Reflect),
136136+ reflect(Debug, Clone, PartialEq)
137137+ )]
138138+ pub enum AllDirectionEnvironment: String {
129139 #[default]
130140 GlassDesert = "GlassDesertEnvironment",
131141 }
···150160 ///
151161 /// Note that [`Lawless`](Self::Lawless) and [`Lightshow`](Self::Lightshow) are modded characteristics,
152162 /// and may cause problems in un-modded versions of the game.
153153- #[derive(Default)]
154154- Characteristic: String {
163163+ #[derive(Default, Debug, Clone, Eq, PartialEq, Hash)]
164164+ #[cfg_attr(
165165+ feature = "bevy_reflect",
166166+ derive(bevy_reflect::Reflect),
167167+ reflect(Debug, Clone, PartialEq)
168168+ )]
169169+ pub enum Characteristic: String {
155170 #[default]
156171 Standard = "Standard",
157172 NoArrows = "NoArrows",
···202217}
203218204219loose_enum! {
205205- #[derive(Default, Copy)]
206206- DifficultyRank: i32 {
220220+ #[derive(Default, Debug, Clone, Copy, Eq, PartialEq, Hash)]
221221+ #[cfg_attr(
222222+ feature = "bevy_reflect",
223223+ derive(bevy_reflect::Reflect),
224224+ reflect(Debug, Clone, PartialEq)
225225+ )]
226226+ pub enum DifficultyRank: i32 {
207227 Easy = 1,
208228 Normal = 3,
209229 Hard = 5,
-4
src/lib.rs
···44pub mod info;
55pub mod timing_traits;
6677-mod utils;
88-97#[doc(hidden)]
108pub use difficulty::*;
119#[doc(hidden)]
1210pub use info::*;
1311#[doc(hidden)]
1412pub use timing_traits::*;
1515-/// An integer repr bool, with 0 being false and 1 being true. Any other value will be saved as `Unknown`.
1616-pub use utils::LooseBool;
-180
src/utils.rs
···11-/// Defines a repr enum that supports any value. If a value does not match any case, it will be parsed as `Unknown`.
22-#[macro_export]
33-#[doc(hidden)]
44-macro_rules! loose_enum {
55- // Special case for strings:
66- (
77- $(#[$outer:meta])*
88- $name:ident: String
99- {
1010- $(
1111- $(#[$meta:meta])*
1212- $variant:ident = $value:expr
1313- ),+ $(,)?
1414- }
1515- ) => {
1616- #[derive(Debug, Clone, Eq, PartialEq, Hash)]
1717- #[cfg_attr(
1818- feature = "bevy_reflect",
1919- derive(bevy_reflect::Reflect),
2020- reflect(Debug, Clone, PartialEq)
2121- )]
2222- $(#[$outer])*
2323- pub enum $name {
2424- $(
2525- $(#[$meta])*
2626- $variant
2727- ),+,
2828- Unknown(String),
2929- }
3030-3131- impl<'de> serde::Deserialize<'de> for $name {
3232- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
3333- where
3434- D: serde::Deserializer<'de>,
3535- {
3636- let val = String::deserialize(deserializer)?;
3737- Ok(match val.as_str() {
3838- $( $value => $name::$variant, )+
3939- other => $name::Unknown(other.to_string()),
4040- })
4141- }
4242- }
4343-4444- impl serde::Serialize for $name {
4545- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
4646- where
4747- S: serde::Serializer,
4848- {
4949- match self {
5050- $( $name::$variant => str::serialize($value, serializer), )+
5151- $name::Unknown(val) => str::serialize(val, serializer),
5252- }
5353- }
5454- }
5555-5656- impl From<String> for $name {
5757- fn from(value: String) -> Self {
5858- match value.as_str() {
5959- $( $value => $name::$variant, )+
6060- other => $name::Unknown(other.to_string()),
6161- }
6262- }
6363- }
6464-6565- impl From<$name> for String {
6666- fn from(value: $name) -> Self {
6767- match value {
6868- $( $name::$variant => $value.to_string(), )+
6969- $name::Unknown(val) => val,
7070- }
7171- }
7272- }
7373- };
7474- // All other types:
7575- (
7676- $(#[$outer:meta])*
7777- $name:ident: $ty:ident
7878- {
7979- $(
8080- $(#[$meta:meta])*
8181- $variant:ident = $value:expr
8282- ),+ $(,)?
8383- }
8484- ) => {
8585- #[derive(Debug, Clone, Eq, PartialEq, Hash)]
8686- #[cfg_attr(
8787- feature = "bevy_reflect",
8888- derive(bevy_reflect::Reflect),
8989- reflect(Debug, Clone, PartialEq)
9090- )]
9191- $(#[$outer])*
9292- pub enum $name {
9393- $(
9494- $(#[$meta])*
9595- $variant
9696- ),+,
9797- Unknown($ty),
9898- }
9999-100100- impl<'de> serde::Deserialize<'de> for $name {
101101- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
102102- where
103103- D: serde::Deserializer<'de>,
104104- {
105105- let val = $ty::deserialize(deserializer)?;
106106- Ok(match val {
107107- $( $value => $name::$variant, )+
108108- other => $name::Unknown(other),
109109- })
110110- }
111111- }
112112-113113- impl serde::Serialize for $name {
114114- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
115115- where
116116- S: serde::Serializer,
117117- {
118118- match self {
119119- $( $name::$variant => $ty::serialize(&$value, serializer), )+
120120- $name::Unknown(val) => $ty::serialize(val, serializer),
121121- }
122122- }
123123- }
124124-125125- impl From<$ty> for $name {
126126- fn from(value: $ty) -> Self {
127127- match value {
128128- $( $value => $name::$variant, )+
129129- other => $name::Unknown(other),
130130- }
131131- }
132132- }
133133-134134- impl From<$name> for $ty {
135135- fn from(value: $name) -> Self {
136136- match value {
137137- $( $name::$variant => $value, )+
138138- $name::Unknown(val) => val,
139139- }
140140- }
141141- }
142142- };
143143-}
144144-145145-loose_enum! {
146146- /// An integer repr bool, with 0 being false and 1 being true. Any other value will be saved as `Unknown`.
147147- #[derive(Default, Copy)]
148148- LooseBool: i32 {
149149- #[default]
150150- False = 0,
151151- True = 1,
152152- }
153153-}
154154-155155-impl LooseBool {
156156- pub fn is_true(&self) -> bool {
157157- match self {
158158- LooseBool::False => false,
159159- LooseBool::True => true,
160160- LooseBool::Unknown(_) => false,
161161- }
162162- }
163163-164164- pub fn is_false(&self) -> bool {
165165- match self {
166166- LooseBool::False => true,
167167- LooseBool::True => false,
168168- LooseBool::Unknown(_) => false,
169169- }
170170- }
171171-}
172172-173173-impl From<bool> for LooseBool {
174174- fn from(value: bool) -> Self {
175175- match value {
176176- true => Self::True,
177177- false => Self::False,
178178- }
179179- }
180180-}