1
0
Fork 0
mirror of https://github.com/Nioux/AideDeJeu.git synced 2025-10-30 15:06:06 +00:00

Clean BuildContext

This commit is contained in:
Yan Maniez 2020-03-13 09:46:17 +01:00
parent 25da74dfd2
commit f93587c745
10 changed files with 89 additions and 82 deletions

View file

@ -1,21 +1,13 @@
import 'package:aidedejeu_flutter/blocs/player_character/player_character_event.dart'; import 'package:aidedejeu_flutter/blocs/player_character/player_character_event.dart';
import 'package:aidedejeu_flutter/blocs/player_character/player_character_state.dart'; import 'package:aidedejeu_flutter/blocs/player_character/player_character_state.dart';
import 'package:aidedejeu_flutter/database.dart'; import 'package:aidedejeu_flutter/database.dart';
import 'package:aidedejeu_flutter/models/items.dart';
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/cupertino.dart';
class PlayerCharacterBloc class PlayerCharacterBloc
extends Bloc<PlayerCharacterEvent, PlayerCharacterState> { extends Bloc<PlayerCharacterEvent, PlayerCharacterState> {
BuildContext context;
PlayerCharacterBloc(BuildContext context) {
this.context = context;
}
@override @override
PlayerCharacterState get initialState => PlayerCharacterState(context: context); PlayerCharacterState get initialState => PlayerCharacterState();
@override @override
Stream<PlayerCharacterState> mapEventToState( Stream<PlayerCharacterState> mapEventToState(
@ -35,7 +27,7 @@ class PlayerCharacterBloc
} }
Stream<PlayerCharacterState> _mapRaceEventToState( Stream<PlayerCharacterState> _mapRaceEventToState(
RaceEvent event) async* { RaceEvent event) async* {
var subRaces = await loadSubRaces(context, event.item); var subRaces = await loadSubRaces(event.item);
yield state.copyWithClean(race: event.item, subRaces: subRaces); yield state.copyWithClean(race: event.item, subRaces: subRaces);
} }
@ -45,7 +37,7 @@ class PlayerCharacterBloc
} }
Stream<PlayerCharacterState> _mapBackgroundEventToState( Stream<PlayerCharacterState> _mapBackgroundEventToState(
BackgroundEvent event) async* { BackgroundEvent event) async* {
var subBackgrounds = await loadSubBackgrounds(context, event.item); var subBackgrounds = await loadSubBackgrounds(event.item);
yield state.copyWithClean(background: event.item,subBackgrounds: subBackgrounds); yield state.copyWithClean(background: event.item,subBackgrounds: subBackgrounds);
} }
Stream<PlayerCharacterState> _mapSubBackgroundEventToState( Stream<PlayerCharacterState> _mapSubBackgroundEventToState(
@ -54,8 +46,8 @@ class PlayerCharacterBloc
} }
Stream<PlayerCharacterState> _mapLoadEventToState( Stream<PlayerCharacterState> _mapLoadEventToState(
LoadEvent event) async* { LoadEvent event) async* {
var races = await loadRaces(context); var races = await loadRaces();
var backgrounds = await loadBackgrounds(context); var backgrounds = await loadBackgrounds();
yield state.copyWith(races: races, backgrounds: backgrounds); // state; yield state.copyWith(races: races, backgrounds: backgrounds); // state;
} }
} }

View file

@ -3,14 +3,6 @@ import 'package:equatable/equatable.dart';
abstract class PlayerCharacterEvent extends Equatable {} abstract class PlayerCharacterEvent extends Equatable {}
class RaceEvent extends SetItemEvent<RaceItem> {
RaceEvent(RaceItem item) : super(item);
}
class SubRaceEvent extends SetItemEvent<SubRaceItem> {
SubRaceEvent(SubRaceItem item) : super(item);
}
class SetItemEvent<T> extends PlayerCharacterEvent { class SetItemEvent<T> extends PlayerCharacterEvent {
final T item; final T item;
@ -20,6 +12,14 @@ class SetItemEvent<T> extends PlayerCharacterEvent {
SetItemEvent(T item) : this.item = item; SetItemEvent(T item) : this.item = item;
} }
class RaceEvent extends SetItemEvent<RaceItem> {
RaceEvent(RaceItem item) : super(item);
}
class SubRaceEvent extends SetItemEvent<SubRaceItem> {
SubRaceEvent(SubRaceItem item) : super(item);
}
class BackgroundEvent extends SetItemEvent<BackgroundItem> { class BackgroundEvent extends SetItemEvent<BackgroundItem> {
BackgroundEvent(BackgroundItem item) : super(item); BackgroundEvent(BackgroundItem item) : super(item);
} }

View file

@ -1,9 +1,7 @@
import 'package:aidedejeu_flutter/models/items.dart'; import 'package:aidedejeu_flutter/models/items.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flutter/cupertino.dart';
class PlayerCharacterState extends Equatable { class PlayerCharacterState extends Equatable {
final BuildContext context;
final RaceItem race; final RaceItem race;
final SubRaceItem subRace; final SubRaceItem subRace;
@ -16,7 +14,6 @@ class PlayerCharacterState extends Equatable {
final List<SubBackgroundItem> subBackgrounds; final List<SubBackgroundItem> subBackgrounds;
PlayerCharacterState({ PlayerCharacterState({
this.context,
this.race, this.race,
this.races, this.races,
this.subRace, this.subRace,
@ -28,7 +25,6 @@ class PlayerCharacterState extends Equatable {
}); });
PlayerCharacterState copyWith({ PlayerCharacterState copyWith({
BuildContext context,
RaceItem race, RaceItem race,
List<RaceItem> races, List<RaceItem> races,
SubRaceItem subRace, SubRaceItem subRace,
@ -39,7 +35,6 @@ class PlayerCharacterState extends Equatable {
List<SubBackgroundItem> subBackgrounds, List<SubBackgroundItem> subBackgrounds,
}) { }) {
return PlayerCharacterState( return PlayerCharacterState(
context: context ?? this.context,
race: race ?? this.race, race: race ?? this.race,
races: races ?? this.races, races: races ?? this.races,
subRace: subRace ?? this.subRace, subRace: subRace ?? this.subRace,
@ -52,7 +47,6 @@ class PlayerCharacterState extends Equatable {
} }
PlayerCharacterState copyWithClean({ PlayerCharacterState copyWithClean({
BuildContext context,
RaceItem race, RaceItem race,
List<RaceItem> races, List<RaceItem> races,
SubRaceItem subRace, SubRaceItem subRace,
@ -63,7 +57,6 @@ class PlayerCharacterState extends Equatable {
List<SubBackgroundItem> subBackgrounds, List<SubBackgroundItem> subBackgrounds,
}) { }) {
return PlayerCharacterState( return PlayerCharacterState(
context: context ?? this.context,
race: race ?? this.race, race: race ?? this.race,
races: races ?? this.races, races: races ?? this.races,
subRace: race != null ? null : subRace ?? this.subRace, subRace: race != null ? null : subRace ?? this.subRace,

View file

@ -1,7 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'package:aidedejeu_flutter/models/items.dart'; import 'package:aidedejeu_flutter/models/items.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:path/path.dart'; import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart'; import 'package:sqflite/sqflite.dart';
@ -41,7 +40,7 @@ Future<Database> getDatabaseInstance() async {
return await openDatabase(path, readOnly: true); return await openDatabase(path, readOnly: true);
} }
Future<Item> getItemWithId(BuildContext context, String id) async { Future<Item> getItemWithId(String id) async {
print("getItemWithId " + id); print("getItemWithId " + id);
final db = await database; final db = await database;
var response = await db.query( var response = await db.query(
@ -52,10 +51,10 @@ Future<Item> getItemWithId(BuildContext context, String id) async {
if (response.isEmpty) { if (response.isEmpty) {
print("Id not found"); print("Id not found");
} }
return response.isNotEmpty ? itemFromMap(context, response.first) : null; return response.isNotEmpty ? itemFromMap(response.first) : null;
} }
Future<Item> loadChildrenItems(BuildContext context, Item item, List<Filter> filters) async { Future<Item> loadChildrenItems(Item item, List<Filter> filters) async {
print("getChildrenItems " + (item?.itemType ?? "")); print("getChildrenItems " + (item?.itemType ?? ""));
if (item.itemType.endsWith("Items")) { if (item.itemType.endsWith("Items")) {
String itemType = String itemType =
@ -87,13 +86,13 @@ Future<Item> loadChildrenItems(BuildContext context, Item item, List<Filter> fil
print("Children not found"); print("Children not found");
} }
item.children = response.isNotEmpty item.children = response.isNotEmpty
? itemsFromMapList(context, response) ? itemsFromMapList(response)
: null; : null;
} }
return item; return item;
} }
Future<List<RaceItem>> loadRaces(BuildContext context) async { Future<List<RaceItem>> loadRaces() async {
final db = await database; final db = await database;
var response = await db.query( var response = await db.query(
"Items", "Items",
@ -101,12 +100,12 @@ Future<List<RaceItem>> loadRaces(BuildContext context) async {
orderBy: "NormalizedName" orderBy: "NormalizedName"
); );
if (response.isNotEmpty) { if (response.isNotEmpty) {
return itemsFromMapList(context, response); return itemsFromMapList(response);
} }
return null; return null;
} }
Future<List<SubRaceItem>> loadSubRaces(BuildContext context, RaceItem race) async { Future<List<SubRaceItem>> loadSubRaces(RaceItem race) async {
final db = await database; final db = await database;
var response = await db.query( var response = await db.query(
"Items", "Items",
@ -115,12 +114,12 @@ Future<List<SubRaceItem>> loadSubRaces(BuildContext context, RaceItem race) asyn
orderBy: "NormalizedName" orderBy: "NormalizedName"
); );
if (response.isNotEmpty) { if (response.isNotEmpty) {
return itemsFromMapList(context, response); return itemsFromMapList(response);
} }
return null; return null;
} }
Future<List<T>> loadTypedItems<T extends Item>(BuildContext context, {String itemType, Item item}) async { Future<List<T>> loadTypedItems<T extends Item>({String itemType, Item item}) async {
final db = await database; final db = await database;
var response = await db.query( var response = await db.query(
"Items", "Items",
@ -129,16 +128,16 @@ Future<List<T>> loadTypedItems<T extends Item>(BuildContext context, {String ite
orderBy: "NormalizedName" orderBy: "NormalizedName"
); );
if (response.isNotEmpty) { if (response.isNotEmpty) {
return itemsFromMapList(context, response); return itemsFromMapList(response);
} }
return null; return null;
} }
Future<List<BackgroundItem>> loadBackgrounds(BuildContext context) async { Future<List<BackgroundItem>> loadBackgrounds() async {
return loadTypedItems<BackgroundItem>(context, itemType: "BackgroundItem"); return loadTypedItems<BackgroundItem>(itemType: "BackgroundItem");
} }
Future<List<SubBackgroundItem>> loadSubBackgrounds(BuildContext context, Item item) async { Future<List<SubBackgroundItem>> loadSubBackgrounds(Item item) async {
return loadTypedItems<SubBackgroundItem>(context, itemType: "SubBackgroundItem", item: item); return loadTypedItems<SubBackgroundItem>(itemType: "SubBackgroundItem", item: item);
} }

View file

@ -19,6 +19,15 @@ class AppLocalizations {
return Localizations.of<AppLocalizations>(context, AppLocalizations); return Localizations.of<AppLocalizations>(context, AppLocalizations);
} }
String translate(name) {
return Intl.message(
name,
name: name,
desc: name,
locale: localeName,
);
}
final String localeName; final String localeName;
String get appTitle { String get appTitle {

View file

@ -6,12 +6,13 @@ enum FilterType {
} }
class Filter { class Filter {
String name; String name;
String displayName;
FilterType type; FilterType type;
List<String> values; List<String> values;
Set<String> selectedValues = Set<String>(); Set<String> selectedValues = Set<String>();
RangeValues rangeValues; RangeValues rangeValues;
Filter({this.name, this.type, this.values}) { Filter({this.name, this.type, this.values, this.displayName}) {
rangeValues = RangeValues(0, values.length.toDouble() - 1); rangeValues = RangeValues(0, values.length.toDouble() - 1);
} }
} }

View file

@ -1,6 +1,4 @@
import 'package:aidedejeu_flutter/localization.dart';
import 'package:aidedejeu_flutter/models/filters.dart'; import 'package:aidedejeu_flutter/models/filters.dart';
import 'package:flutter/cupertino.dart';
class Item { class Item {
String id; String id;
@ -139,25 +137,30 @@ class MonsterItems extends FilteredItems {
Filter sources; Filter sources;
Filter terrains; Filter terrains;
MonsterItems(BuildContext context, Map<String, dynamic> map) : super(map) { MonsterItems(Map<String, dynamic> map) : super(map) {
this.types = Filter( this.types = Filter(
name: AppLocalizations.of(context).monstersTypes, name: "Types",
displayName: "monstersTypes",
type: FilterType.Choices, type: FilterType.Choices,
values: map["Types"].toString().split("|")); values: map["Types"].toString().split("|"));
this.challenges = Filter( this.challenges = Filter(
name: AppLocalizations.of(context).monstersChallenges, name: "Challenges",
displayName: "monstersChallenges",
type: FilterType.Range, type: FilterType.Range,
values: map["Challenges"].toString().split("|")); values: map["Challenges"].toString().split("|"));
this.sizes = Filter( this.sizes = Filter(
name: AppLocalizations.of(context).monstersSizes, name: "Sizes",
displayName: "monstersSizes",
type: FilterType.Range, type: FilterType.Range,
values: map["Sizes"].toString().split("|")); values: map["Sizes"].toString().split("|"));
this.sources = Filter( this.sources = Filter(
name: AppLocalizations.of(context).monstersSources, name: "Sources",
displayName: "monstersSources",
type: FilterType.Choices, type: FilterType.Choices,
values: map["Sources"].toString().split("|")); values: map["Sources"].toString().split("|"));
this.terrains = Filter( this.terrains = Filter(
name: AppLocalizations.of(context).monstersTerrains, name: "Terrains",
displayName: "monstersTerrains",
type: FilterType.Choices, type: FilterType.Choices,
values: map["Terrains"].toString().split("|")); values: map["Terrains"].toString().split("|"));
} }
@ -185,53 +188,65 @@ class SpellItems extends FilteredItems {
Filter durations; Filter durations;
Filter sources; Filter sources;
SpellItems(BuildContext context, Map<String, dynamic> map) : super(map) { SpellItems(Map<String, dynamic> map) : super(map) {
this.classes = Filter( this.classes = Filter(
name: AppLocalizations.of(context).spellsClasses, name: "Classes",
displayName: "spellsClasses",
type: FilterType.Choices, type: FilterType.Choices,
values: map["Classes"].toString().split("|")); values: map["Classes"].toString().split("|"));
this.levels = Filter( this.levels = Filter(
name: AppLocalizations.of(context).spellsLevels, name: "Levels",
displayName: "spellsLevels",
type: FilterType.Choices, type: FilterType.Choices,
values: map["Levels"].toString().split("|")); values: map["Levels"].toString().split("|"));
this.schools = Filter( this.schools = Filter(
name: AppLocalizations.of(context).spellsSchools, name: "Schools",
displayName: "spellsSchools",
type: FilterType.Choices, type: FilterType.Choices,
values: map["Schools"].toString().split("|")); values: map["Schools"].toString().split("|"));
this.rituals = Filter( this.rituals = Filter(
name: AppLocalizations.of(context).spellsRituals, name: "Rituals",
displayName: "spellsRituals",
type: FilterType.Choices, type: FilterType.Choices,
values: map["Rituals"].toString().split("|")); values: map["Rituals"].toString().split("|"));
this.castingTimes = Filter( this.castingTimes = Filter(
name: AppLocalizations.of(context).spellsCastingTimes, name: "CastingTimes",
displayName: "spellsCastingTimes",
type: FilterType.Choices, type: FilterType.Choices,
values: map["CastingTimes"].toString().split("|")); values: map["CastingTimes"].toString().split("|"));
this.ranges = Filter( this.ranges = Filter(
name: AppLocalizations.of(context).spellsRanges, name: "Ranges",
displayName: "spellsRanges",
type: FilterType.Choices, type: FilterType.Choices,
values: map["Ranges"].toString().split("|")); values: map["Ranges"].toString().split("|"));
this.verbalComponents = Filter( this.verbalComponents = Filter(
name: AppLocalizations.of(context).spellsVerbalComponents, name: "VerbalComponents",
displayName: "spellsVerbalComponents",
type: FilterType.Choices, type: FilterType.Choices,
values: map["VerbalComponents"].toString().split("|")); values: map["VerbalComponents"].toString().split("|"));
this.somaticComponents = Filter( this.somaticComponents = Filter(
name: AppLocalizations.of(context).spellsSomaticComponents, name: "SomaticComponents",
displayName: "spellsSomaticComponents",
type: FilterType.Choices, type: FilterType.Choices,
values: map["SomaticComponents"].toString().split("|")); values: map["SomaticComponents"].toString().split("|"));
this.materialComponents = Filter( this.materialComponents = Filter(
name: AppLocalizations.of(context).spellsMaterialComponents, name: "MaterialComponents",
displayName: "spellsMaterialComponents",
type: FilterType.Choices, type: FilterType.Choices,
values: map["MaterialComponents"].toString().split("|")); values: map["MaterialComponents"].toString().split("|"));
this.concentrations = Filter( this.concentrations = Filter(
name: AppLocalizations.of(context).spellsConcentrations, name: "Concentrations",
displayName: "spellsConcentrations",
type: FilterType.Choices, type: FilterType.Choices,
values: map["Concentrations"].toString().split("|")); values: map["Concentrations"].toString().split("|"));
this.durations = Filter( this.durations = Filter(
name: AppLocalizations.of(context).spellsDurations, name: "Durations",
displayName: "spellsDurations",
type: FilterType.Choices, type: FilterType.Choices,
values: map["Durations"].toString().split("|")); values: map["Durations"].toString().split("|"));
this.sources = Filter( this.sources = Filter(
name: AppLocalizations.of(context).spellsSources, name: "Sources",
displayName: "spellsSources",
type: FilterType.Choices, type: FilterType.Choices,
values: map["Sources"].toString().split("|")); values: map["Sources"].toString().split("|"));
} }
@ -337,7 +352,7 @@ class SubBackgroundItem extends BackgroundItem {
SubBackgroundItem(Map<String, dynamic> map) : super(map); SubBackgroundItem(Map<String, dynamic> map) : super(map);
} }
Item itemFromMap(BuildContext context, Map<String, dynamic> map) { Item itemFromMap(Map<String, dynamic> map) {
switch (map["ItemType"]) { switch (map["ItemType"]) {
case "RaceItem": case "RaceItem":
return RaceItem(map); return RaceItem(map);
@ -352,17 +367,17 @@ Item itemFromMap(BuildContext context, Map<String, dynamic> map) {
case "MonsterItem": case "MonsterItem":
return MonsterItem(map); return MonsterItem(map);
case "MonsterItems": case "MonsterItems":
return MonsterItems(context, map); return MonsterItems(map);
case "SpellItem": case "SpellItem":
return SpellItem(map); return SpellItem(map);
case "SpellItems": case "SpellItems":
return SpellItems(context, map); return SpellItems(map);
} }
return Item(map); return Item(map);
} }
List<T> itemsFromMapList<T extends Item>(BuildContext context, List<Map<String, dynamic>> mapList) { List<T> itemsFromMapList<T extends Item>(List<Map<String, dynamic>> mapList) {
return List.generate(mapList.length, (i) { return List.generate(mapList.length, (i) {
return itemFromMap(context, mapList[i]); return itemFromMap(mapList[i]);
}); });
} }

View file

@ -54,9 +54,8 @@ class _LibraryPageState extends State<LibraryPage> {
} }
Future<Item> _loadItem() async { Future<Item> _loadItem() async {
var item = await getItemWithId(context, this.widget.id); var item = await getItemWithId(this.widget.id);
var items = await loadChildrenItems(context, item, filters); await loadChildrenItems(item, filters);
//setItem(item);
return item; return item;
} }
@ -177,7 +176,7 @@ class _LibraryPageState extends State<LibraryPage> {
setState(() { setState(() {
filter.selectedValues = choices; filter.selectedValues = choices;
}); });
loadChildrenItems(context, item, filters).then((value) => { loadChildrenItems(item, filters).then((value) => {
setState(() { setState(() {
this.item = item; this.item = item;
this.filters = filters; this.filters = filters;
@ -195,7 +194,7 @@ class _LibraryPageState extends State<LibraryPage> {
setState(() { setState(() {
filter.rangeValues = values; filter.rangeValues = values;
}); });
loadChildrenItems(context, item, filters).then((value) => { loadChildrenItems(item, filters).then((value) => {
setState(() { setState(() {
this.item = item; this.item = item;
this.filters = filters; this.filters = filters;
@ -214,7 +213,7 @@ class _LibraryPageState extends State<LibraryPage> {
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: Padding( child: Padding(
padding: const EdgeInsets.fromLTRB(8.0,1.0,8.0,1.0), padding: const EdgeInsets.fromLTRB(8.0,1.0,8.0,1.0),
child: Text(filter.name, style: TextStyle(fontFamily: "Cinzel"),), child: Text(AppLocalizations.of(context).translate(filter.name), style: TextStyle(fontFamily: "Cinzel"),),
), ),
), ),
Container( Container(
@ -280,7 +279,7 @@ class _LibraryPageState extends State<LibraryPage> {
height: 30.0, height: 30.0,
width: 30.0, width: 30.0,
allowDrawingOutsideViewBox: true, allowDrawingOutsideViewBox: true,
), //Icon(Icons.filter), ),
onPressed: () => Scaffold.of(context).openEndDrawer(), onPressed: () => Scaffold.of(context).openEndDrawer(),
tooltip: tooltip:
MaterialLocalizations.of(context).openAppDrawerTooltip, MaterialLocalizations.of(context).openAppDrawerTooltip,

View file

@ -3,6 +3,7 @@ import 'package:aidedejeu_flutter/blocs/player_character/player_character_event.
import 'package:aidedejeu_flutter/blocs/player_character/player_character_state.dart'; import 'package:aidedejeu_flutter/blocs/player_character/player_character_state.dart';
import 'package:aidedejeu_flutter/localization.dart'; import 'package:aidedejeu_flutter/localization.dart';
import 'package:aidedejeu_flutter/models/items.dart'; import 'package:aidedejeu_flutter/models/items.dart';
import 'package:aidedejeu_flutter/theme.dart';
import 'package:aidedejeu_flutter/widgets/library.dart'; import 'package:aidedejeu_flutter/widgets/library.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
@ -10,15 +11,13 @@ import 'package:flutter_markdown/flutter_markdown.dart';
class PCEditorPage extends StatelessWidget { class PCEditorPage extends StatelessWidget {
MarkdownStyleSheet styleSheet;
// widgets generics // widgets generics
Widget _buildMarkdown( Widget _buildMarkdown(
BuildContext context, PlayerCharacterState state, String markdown) { BuildContext context, PlayerCharacterState state, String markdown) {
return MarkdownBody( return MarkdownBody(
data: markdown ?? "", data: markdown ?? "",
styleSheet: styleSheet, styleSheet: mainMarkdownStyleSheet(context),
onTapLink: (link) => Navigator.push( onTapLink: (link) => Navigator.push(
context, context,
MaterialPageRoute(builder: (context) => LibraryPage(id: link)), MaterialPageRoute(builder: (context) => LibraryPage(id: link)),
@ -176,7 +175,7 @@ class PCEditorPage extends StatelessWidget {
providers: [ providers: [
BlocProvider<PlayerCharacterBloc>( BlocProvider<PlayerCharacterBloc>(
create: (context) { create: (context) {
return PlayerCharacterBloc(context) return PlayerCharacterBloc()
..add( ..add(
LoadEvent(), LoadEvent(),
); );

View file

@ -169,7 +169,7 @@ packages:
name: intl name: intl
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.16.0" version: "0.16.1"
intl_translation: intl_translation:
dependency: "direct main" dependency: "direct main"
description: description: