refactor(Blenvy:Bevy): more examples restructure & cleanup
This commit is contained in:
parent
7acb1f3a57
commit
0938a1d10c
|
@ -1,21 +0,0 @@
|
|||
[package]
|
||||
name = "bevy_gltf_worlflow_examples_common"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
[features]
|
||||
blueprints = ["dep:bevy_gltf_blueprints"]
|
||||
physics_rapier = ["dep:bevy_rapier3d"]
|
||||
physics_xpbd = ["dep:bevy_xpbd_3d"]
|
||||
default = ["blueprints", "physics_rapier"]
|
||||
|
||||
|
||||
[dependencies]
|
||||
bevy = { version = "0.13", features = ["dynamic_linking"] }
|
||||
bevy_gltf_blueprints = { path = "../../crates/bevy_gltf_blueprints", optional = true }
|
||||
bevy_rapier3d = { version = "0.25", features = ["serde-serialize", "debug-render-3d", "enhanced-determinism"], optional = true }
|
||||
bevy_xpbd_3d = { version = "0.4", optional = true }
|
||||
bevy_asset_loader = { version = "0.20", features = ["standard_dynamic_assets"] }
|
||||
bevy_editor_pls = { version = "0.8" }
|
||||
rand = "0.8.5"
|
|
@ -1,5 +0,0 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy_asset_loader::prelude::*;
|
||||
|
||||
#[derive(AssetCollection, Resource)]
|
||||
pub struct CoreAssets {}
|
|
@ -1,24 +0,0 @@
|
|||
use bevy::gltf::Gltf;
|
||||
use bevy::prelude::*;
|
||||
use bevy::utils::HashMap;
|
||||
use bevy_asset_loader::prelude::*;
|
||||
|
||||
#[derive(AssetCollection, Resource)]
|
||||
pub struct GameAssets {
|
||||
#[asset(key = "world", optional)]
|
||||
pub world: Option<Handle<Gltf>>,
|
||||
|
||||
#[asset(key = "world_dynamic", optional)]
|
||||
pub world_dynamic: Option<Handle<Gltf>>,
|
||||
|
||||
#[asset(key = "level1", optional)]
|
||||
pub level1: Option<Handle<Gltf>>,
|
||||
#[asset(key = "level2", optional)]
|
||||
pub level2: Option<Handle<Gltf>>,
|
||||
|
||||
#[asset(key = "models", collection(typed, mapped), optional)]
|
||||
pub models: Option<HashMap<String, Handle<Gltf>>>,
|
||||
|
||||
#[asset(key = "materials", collection(typed, mapped), optional)]
|
||||
pub materials: Option<HashMap<String, Handle<Gltf>>>,
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
pub mod assets_core;
|
||||
pub use assets_core::*;
|
||||
|
||||
pub mod assets_game;
|
||||
pub use assets_game::*;
|
||||
|
||||
use bevy::prelude::*;
|
||||
use bevy_asset_loader::prelude::*;
|
||||
|
||||
use crate::state::AppState;
|
||||
|
||||
pub struct AssetsPlugin;
|
||||
impl Plugin for AssetsPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app
|
||||
// load core assets (ie assets needed in the main menu, and everywhere else before loading more assets in game)
|
||||
.add_loading_state(
|
||||
LoadingState::new(AppState::CoreLoading)
|
||||
.continue_to_state(AppState::MenuRunning)
|
||||
.with_dynamic_assets_file::<StandardDynamicAssetCollection>(
|
||||
"assets_core.assets.ron",
|
||||
)
|
||||
.load_collection::<CoreAssets>(),
|
||||
)
|
||||
// load game assets
|
||||
.add_loading_state(
|
||||
LoadingState::new(AppState::AppLoading)
|
||||
.continue_to_state(AppState::AppRunning)
|
||||
.with_dynamic_assets_file::<StandardDynamicAssetCollection>(
|
||||
"assets_game.assets.ron",
|
||||
)
|
||||
.load_collection::<GameAssets>(),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
pub mod camera;
|
||||
pub use camera::*;
|
||||
|
||||
//pub mod relationships;
|
||||
//pub use relationships::*;
|
||||
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub struct CorePlugin;
|
||||
impl Plugin for CorePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_plugins(CameraPlugin);
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*pub mod in_game;
|
||||
pub use in_game::*;
|
||||
|
||||
pub mod in_main_menu;
|
||||
pub use in_main_menu::*;*/
|
||||
|
||||
pub mod player;
|
||||
pub use player::*;
|
||||
|
||||
pub mod picking;
|
||||
pub use picking::*;
|
||||
|
||||
/*
|
||||
use crate::{
|
||||
state::{AppState, GameState},
|
||||
};*/
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub struct GamePlugin;
|
||||
impl Plugin for GamePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_plugins((
|
||||
PlayerPlugin,
|
||||
PickingPlugin
|
||||
))
|
||||
/* .register_type::<Interactible>()
|
||||
.register_type::<SoundMaterial>()
|
||||
.register_type::<Player>()
|
||||
|
||||
.add_systems(OnEnter(AppState::MenuRunning), setup_main_menu)
|
||||
.add_systems(OnExit(AppState::MenuRunning), teardown_main_menu)
|
||||
.add_systems(Update, main_menu.run_if(in_state(AppState::MenuRunning)))
|
||||
.add_systems(OnEnter(AppState::AppRunning), setup_game);*/
|
||||
;
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
pub mod state;
|
||||
pub use state::*;
|
||||
|
||||
pub mod assets;
|
||||
use assets::*;
|
||||
|
||||
pub mod core;
|
||||
pub use core::*;
|
||||
|
||||
pub mod game;
|
||||
pub use game::*;
|
||||
|
||||
use bevy::prelude::*;
|
||||
use bevy_editor_pls::prelude::*;
|
||||
|
||||
pub struct CommonPlugin;
|
||||
impl Plugin for CommonPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_plugins((
|
||||
StatePlugin,
|
||||
AssetsPlugin,
|
||||
CorePlugin,
|
||||
GamePlugin,
|
||||
EditorPlugin::default(),
|
||||
));
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
[package]
|
||||
name = "bevy_gltf_worlflow_examples_common_rapier"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
[features]
|
||||
blueprints = ["dep:bevy_gltf_blueprints"]
|
||||
default = ["blueprints"]
|
||||
|
||||
|
||||
[dependencies]
|
||||
bevy = { version = "0.13", features = ["dynamic_linking"] }
|
||||
bevy_gltf_worlflow_examples_common = { path = "../common" }
|
||||
bevy_gltf_blueprints = { path = "../../crates/bevy_gltf_blueprints", optional = true }
|
||||
bevy_rapier3d = { version = "0.25", features = ["serde-serialize", "debug-render-3d", "enhanced-determinism"] }
|
||||
bevy_asset_loader = { version = "0.20", features = ["standard_dynamic_assets"] }
|
||||
bevy_editor_pls = { version = "0.8" }
|
||||
rand = "0.8.5"
|
|
@ -1,13 +0,0 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy_gltf_worlflow_examples_common::CommonPlugin as CommonBasePlugin;
|
||||
|
||||
pub use bevy_gltf_worlflow_examples_common::*;
|
||||
|
||||
mod physics;
|
||||
|
||||
pub struct CommonPlugin;
|
||||
impl Plugin for CommonPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_plugins((physics::plugin, CommonBasePlugin));
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
[package]
|
||||
name = "bevy_gltf_worlflow_examples_common_xpbd"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
[features]
|
||||
blueprints = ["dep:bevy_gltf_blueprints"]
|
||||
default = ["blueprints"]
|
||||
|
||||
|
||||
[dependencies]
|
||||
bevy = { version = "0.13", features = ["dynamic_linking"] }
|
||||
bevy_gltf_worlflow_examples_common = { path = "../common" }
|
||||
bevy_gltf_blueprints = { path = "../../crates/bevy_gltf_blueprints", optional = true }
|
||||
bevy_xpbd_3d = { version = "0.4" }
|
||||
bevy_asset_loader = { version = "0.20", features = ["standard_dynamic_assets"] }
|
||||
bevy_editor_pls = { version = "0.8" }
|
||||
rand = "0.8.5"
|
|
@ -1,13 +0,0 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy_gltf_worlflow_examples_common::CommonPlugin as CommonBasePlugin;
|
||||
|
||||
pub use bevy_gltf_worlflow_examples_common::*;
|
||||
|
||||
mod physics;
|
||||
|
||||
pub struct CommonPlugin;
|
||||
impl Plugin for CommonPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_plugins((physics::plugin, CommonBasePlugin));
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
[package]
|
||||
name = "bevy_gltf_blueprints_basic_xpbd_physics_example"
|
||||
version = "0.3.0"
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
[dependencies]
|
||||
bevy = { version = "0.13", features = ["dynamic_linking"] }
|
||||
bevy_gltf_blueprints = { path = "../../../crates/bevy_gltf_blueprints" }
|
||||
bevy_gltf_worlflow_examples_common_xpbd = { path = "../../common_xpbd" }
|
||||
bevy_xpbd_3d = "0.4"
|
||||
rand = "0.8.5"
|
|
@ -1,15 +0,0 @@
|
|||
|
||||
# Basic xpbd physics example/demo
|
||||
|
||||
Same as the basic example but using [xpbd](https://github.com/Jondolf/bevy_xpbd) instead of Rapier [rapier](https://github.com/dimforge/bevy_rapier)
|
||||
|
||||
## Running this example
|
||||
|
||||
```
|
||||
cargo run --features bevy/dynamic_linking
|
||||
```
|
||||
|
||||
### Additional notes
|
||||
|
||||
* You usually define either the Components directly or use ```Proxy components``` that get replaced in Bevy systems with the actual Components that you want (usually when for some reason, ie external crates with unregistered components etc) you cannot use the components directly.
|
||||
* this example contains code for future features, not finished yet ! please disregard anything related to saving & loading
|
Binary file not shown.
|
@ -1,6 +0,0 @@
|
|||
({
|
||||
"world":File (path: "models/World.glb"),
|
||||
"models": Folder (
|
||||
path: "models/library",
|
||||
),
|
||||
})
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,11 +0,0 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy_gltf_blueprints::*;
|
||||
|
||||
pub struct CorePlugin;
|
||||
impl Plugin for CorePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_plugins((BlueprintsPlugin {
|
||||
..Default::default()
|
||||
},));
|
||||
}
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy_gltf_blueprints::{BluePrintBundle, BlueprintName, GameWorldTag};
|
||||
use bevy_gltf_worlflow_examples_common_xpbd::{assets::GameAssets, GameState, InAppRunning};
|
||||
use bevy_xpbd_3d::prelude::*;
|
||||
use rand::Rng;
|
||||
|
||||
pub fn setup_game(
|
||||
mut commands: Commands,
|
||||
game_assets: Res<GameAssets>,
|
||||
models: Res<Assets<bevy::gltf::Gltf>>,
|
||||
mut next_game_state: ResMut<NextState<GameState>>,
|
||||
) {
|
||||
commands.insert_resource(AmbientLight {
|
||||
color: Color::WHITE,
|
||||
brightness: 0.2,
|
||||
});
|
||||
// here we actually spawn our game world/level
|
||||
|
||||
commands.spawn((
|
||||
SceneBundle {
|
||||
// note: because of this issue https://github.com/bevyengine/bevy/issues/10436, "world" is now a gltf file instead of a scene
|
||||
scene: models
|
||||
.get(game_assets.world.clone().unwrap().id())
|
||||
.expect("main level should have been loaded")
|
||||
.scenes[0]
|
||||
.clone(),
|
||||
..default()
|
||||
},
|
||||
bevy::prelude::Name::from("world"),
|
||||
GameWorldTag,
|
||||
InAppRunning,
|
||||
));
|
||||
|
||||
next_game_state.set(GameState::InGame)
|
||||
}
|
||||
|
||||
pub fn spawn_test(
|
||||
keycode: Res<ButtonInput<KeyCode>>,
|
||||
mut commands: Commands,
|
||||
|
||||
mut game_world: Query<(Entity, &Children), With<GameWorldTag>>,
|
||||
) {
|
||||
if keycode.just_pressed(KeyCode::KeyT) {
|
||||
let world = game_world.single_mut();
|
||||
let world = world.1[0];
|
||||
|
||||
let mut rng = rand::thread_rng();
|
||||
let range = 5.5;
|
||||
let x: f32 = rng.gen_range(-range..range);
|
||||
let y: f32 = rng.gen_range(-range..range);
|
||||
|
||||
let mut rng = rand::thread_rng();
|
||||
let range = 0.8;
|
||||
let vel_x: f32 = rng.gen_range(-range..range);
|
||||
let vel_y: f32 = rng.gen_range(2.0..2.5);
|
||||
let vel_z: f32 = rng.gen_range(-range..range);
|
||||
|
||||
let name_index: u64 = rng.gen();
|
||||
|
||||
let new_entity = commands
|
||||
.spawn((
|
||||
BluePrintBundle {
|
||||
blueprint: BlueprintName("Health_Pickup".to_string()),
|
||||
..Default::default()
|
||||
},
|
||||
bevy::prelude::Name::from(format!("test{}", name_index)),
|
||||
// BlueprintName("Health_Pickup".to_string()),
|
||||
// SpawnHere,
|
||||
TransformBundle::from_transform(Transform::from_xyz(x, 2.0, y)),
|
||||
LinearVelocity(Vec3::new(vel_x, vel_y, vel_z)),
|
||||
AngularVelocity::ZERO,
|
||||
))
|
||||
.id();
|
||||
commands.entity(world).add_child(new_entity);
|
||||
}
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy_gltf_worlflow_examples_common_xpbd::{AppState, InMainMenu};
|
||||
|
||||
pub fn setup_main_menu(mut commands: Commands) {
|
||||
commands.spawn((
|
||||
Camera2dBundle {
|
||||
camera: Camera {
|
||||
order: 102, // needed because of this: https://github.com/jakobhellermann/bevy_editor_pls/blob/crates/bevy_editor_pls_default_windows/src/cameras/mod.rs#L213C9-L213C28
|
||||
..default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
InMainMenu,
|
||||
));
|
||||
|
||||
commands.spawn((
|
||||
TextBundle::from_section(
|
||||
"SOME GAME TITLE !!",
|
||||
TextStyle {
|
||||
//font: asset_server.load("fonts/FiraMono-Medium.ttf"),
|
||||
font_size: 18.0,
|
||||
color: Color::WHITE,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.with_style(Style {
|
||||
position_type: PositionType::Absolute,
|
||||
top: Val::Px(100.0),
|
||||
left: Val::Px(200.0),
|
||||
..default()
|
||||
}),
|
||||
InMainMenu,
|
||||
));
|
||||
|
||||
commands.spawn((
|
||||
TextBundle::from_section(
|
||||
"New Game (press Enter to start, press T once the game is started for demo spawning)",
|
||||
TextStyle {
|
||||
//font: asset_server.load("fonts/FiraMono-Medium.ttf"),
|
||||
font_size: 18.0,
|
||||
color: Color::WHITE,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.with_style(Style {
|
||||
position_type: PositionType::Absolute,
|
||||
top: Val::Px(200.0),
|
||||
left: Val::Px(200.0),
|
||||
..default()
|
||||
}),
|
||||
InMainMenu,
|
||||
));
|
||||
|
||||
/*
|
||||
commands.spawn((
|
||||
TextBundle::from_section(
|
||||
"Load Game",
|
||||
TextStyle {
|
||||
//font: asset_server.load("fonts/FiraMono-Medium.ttf"),
|
||||
font_size: 18.0,
|
||||
color: Color::WHITE,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.with_style(Style {
|
||||
position_type: PositionType::Absolute,
|
||||
top: Val::Px(250.0),
|
||||
left: Val::Px(200.0),
|
||||
..default()
|
||||
}),
|
||||
InMainMenu
|
||||
));
|
||||
|
||||
commands.spawn((
|
||||
TextBundle::from_section(
|
||||
"Exit Game",
|
||||
TextStyle {
|
||||
//font: asset_server.load("fonts/FiraMono-Medium.ttf"),
|
||||
font_size: 18.0,
|
||||
color: Color::WHITE,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.with_style(Style {
|
||||
position_type: PositionType::Absolute,
|
||||
top: Val::Px(300.0),
|
||||
left: Val::Px(200.0),
|
||||
..default()
|
||||
}),
|
||||
InMainMenu
|
||||
));*/
|
||||
}
|
||||
|
||||
pub fn teardown_main_menu(bla: Query<Entity, With<InMainMenu>>, mut commands: Commands) {
|
||||
for bli in bla.iter() {
|
||||
commands.entity(bli).despawn_recursive();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main_menu(
|
||||
keycode: Res<ButtonInput<KeyCode>>,
|
||||
mut next_app_state: ResMut<NextState<AppState>>,
|
||||
) {
|
||||
if keycode.just_pressed(KeyCode::Enter) {
|
||||
next_app_state.set(AppState::AppLoading);
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
pub mod in_game;
|
||||
pub use in_game::*;
|
||||
|
||||
pub mod in_main_menu;
|
||||
pub use in_main_menu::*;
|
||||
|
||||
use bevy::prelude::*;
|
||||
use bevy_gltf_worlflow_examples_common_xpbd::{AppState, GameState};
|
||||
|
||||
pub struct GamePlugin;
|
||||
impl Plugin for GamePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(Update, (spawn_test,).run_if(in_state(GameState::InGame)))
|
||||
.add_systems(OnEnter(AppState::MenuRunning), setup_main_menu)
|
||||
.add_systems(OnExit(AppState::MenuRunning), teardown_main_menu)
|
||||
.add_systems(Update, main_menu.run_if(in_state(AppState::MenuRunning)))
|
||||
.add_systems(OnEnter(AppState::AppRunning), setup_game);
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy_gltf_worlflow_examples_common_xpbd::CommonPlugin;
|
||||
|
||||
mod core;
|
||||
use crate::core::*;
|
||||
|
||||
mod game;
|
||||
use game::*;
|
||||
|
||||
mod test_components;
|
||||
use test_components::*;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins((
|
||||
DefaultPlugins.set(AssetPlugin::default()),
|
||||
// our custom plugins
|
||||
CommonPlugin,
|
||||
CorePlugin, // reusable plugins
|
||||
GamePlugin, // specific to our game
|
||||
ComponentsTestPlugin, // Showcases different type of components /structs
|
||||
))
|
||||
.run();
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
({})
|
|
@ -1,80 +0,0 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
#[derive(Component, Reflect, Default, Debug)]
|
||||
#[reflect(Component)]
|
||||
struct UnitTest;
|
||||
|
||||
#[derive(Component, Reflect, Default, Debug, Deref, DerefMut)]
|
||||
#[reflect(Component)]
|
||||
struct TupleTestF32(f32);
|
||||
|
||||
#[derive(Component, Reflect, Default, Debug, Deref, DerefMut)]
|
||||
#[reflect(Component)]
|
||||
struct TupleTestU64(u64);
|
||||
|
||||
#[derive(Component, Reflect, Default, Debug, Deref, DerefMut)]
|
||||
#[reflect(Component)]
|
||||
pub struct TupleTestStr(String);
|
||||
|
||||
#[derive(Component, Reflect, Default, Debug)]
|
||||
#[reflect(Component)]
|
||||
struct TupleTest2(f32, u64, String);
|
||||
|
||||
#[derive(Component, Reflect, Default, Debug)]
|
||||
#[reflect(Component)]
|
||||
struct TupleTestBool(bool);
|
||||
|
||||
#[derive(Component, Reflect, Default, Debug)]
|
||||
#[reflect(Component)]
|
||||
struct TupleVec2(Vec2);
|
||||
|
||||
#[derive(Component, Reflect, Default, Debug)]
|
||||
#[reflect(Component)]
|
||||
struct TupleVec3(Vec3);
|
||||
|
||||
#[derive(Component, Reflect, Default, Debug)]
|
||||
#[reflect(Component)]
|
||||
struct TupleVec(Vec<String>);
|
||||
|
||||
#[derive(Component, Reflect, Default, Debug)]
|
||||
#[reflect(Component)]
|
||||
struct TupleTestColor(Color);
|
||||
|
||||
#[derive(Component, Reflect, Default, Debug)]
|
||||
#[reflect(Component)]
|
||||
struct BasicTest {
|
||||
a: f32,
|
||||
b: u64,
|
||||
c: String,
|
||||
}
|
||||
|
||||
#[derive(Component, Reflect, Default, Debug)]
|
||||
#[reflect(Component)]
|
||||
pub enum EnumTest {
|
||||
Metal,
|
||||
Wood,
|
||||
Rock,
|
||||
Cloth,
|
||||
Squishy,
|
||||
#[default]
|
||||
None,
|
||||
}
|
||||
|
||||
pub struct ComponentsTestPlugin;
|
||||
impl Plugin for ComponentsTestPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.register_type::<BasicTest>()
|
||||
.register_type::<UnitTest>()
|
||||
.register_type::<TupleTestF32>()
|
||||
.register_type::<TupleTestU64>()
|
||||
.register_type::<TupleTestStr>()
|
||||
.register_type::<TupleTestBool>()
|
||||
.register_type::<TupleTest2>()
|
||||
.register_type::<TupleVec2>()
|
||||
.register_type::<TupleVec3>()
|
||||
.register_type::<EnumTest>()
|
||||
.register_type::<TupleTestColor>()
|
||||
.register_type::<TupleVec>()
|
||||
.register_type::<Vec<String>>();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue