From ee9c2ac044cc77b80f30420c8f0788cad4281084 Mon Sep 17 00:00:00 2001 From: nsensfel Date: Wed, 6 Jun 2018 15:54:18 +0200 Subject: Figuring out how to organize the src folder(s)... --- src/shared/struct/sh_attributes.erl | 108 ++++++++++++++++++++ src/shared/struct/sh_db_item.erl | 70 +++++++++++++ src/shared/struct/sh_db_query.erl | 59 +++++++++++ src/shared/struct/sh_db_user.erl | 28 ++++++ src/shared/struct/sh_statistics.erl | 193 ++++++++++++++++++++++++++++++++++++ 5 files changed, 458 insertions(+) create mode 100644 src/shared/struct/sh_attributes.erl create mode 100644 src/shared/struct/sh_db_item.erl create mode 100644 src/shared/struct/sh_db_query.erl create mode 100644 src/shared/struct/sh_db_user.erl create mode 100644 src/shared/struct/sh_statistics.erl (limited to 'src/shared/struct') diff --git a/src/shared/struct/sh_attributes.erl b/src/shared/struct/sh_attributes.erl new file mode 100644 index 0000000..93dcfc6 --- /dev/null +++ b/src/shared/struct/sh_attributes.erl @@ -0,0 +1,108 @@ +-module(sh_attributes). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-record +( + attributes, + { + constitution :: integer(), + dexterity :: integer(), + intelligence :: integer(), + mind :: integer(), + speed :: integer(), + strength :: integer() + } +). + +-opaque type() :: #attributes{}. + +-export_type([type/0]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-export +( + [ + get_constitution/1, + get_dexterity/1, + get_intelligence/1, + get_mind/1, + get_speed/1, + get_strength/1, + + set_constitution/2, + set_dexterity/2, + set_intelligence/2, + set_mind/2, + set_speed/2, + set_strength/2 + ] +). + +%%%% Accessors +-export +( + [ + random/0 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-spec get_constitution (type()) -> integer(). +get_constitution (Att) -> Att#attributes.constitution. + +-spec get_dexterity (type()) -> integer(). +get_dexterity (Att) -> Att#attributes.dexterity. + +-spec get_intelligence (type()) -> integer(). +get_intelligence (Att) -> Att#attributes.intelligence. + +-spec get_mind (type()) -> integer(). +get_mind (Att) -> Att#attributes.mind. + +-spec get_speed (type()) -> integer(). +get_speed (Att) -> Att#attributes.speed. + +-spec get_strength (type()) -> integer(). +get_strength (Att) -> Att#attributes.strength. + +-spec set_constitution (integer(), type()) -> type(). +set_constitution (Val, Att) -> Att#attributes{ constitution = Val }. + +-spec set_dexterity (integer(), type()) -> type(). +set_dexterity (Val, Att) -> Att#attributes{ dexterity = Val }. + +-spec set_intelligence (integer(), type()) -> type(). +set_intelligence (Val, Att) -> Att#attributes{ intelligence = Val }. + +-spec set_mind (integer(), type()) -> type(). +set_mind (Val, Att) -> Att#attributes{ mind = Val }. + +-spec set_speed (integer(), type()) -> type(). +set_speed (Val, Att) -> Att#attributes{ speed = Val }. + +-spec set_strength (integer(), type()) -> type(). +set_strength (Val, Att) -> Att#attributes{ strength = Val }. + +-spec random () -> type(). +random () -> + #attributes + { + constitution = sh_roll:percentage(), + dexterity = sh_roll:percentage(), + intelligence = sh_roll:percentage(), + mind = sh_roll:percentage(), + speed = sh_roll:percentage(), + strength = sh_roll:percentage() + }. diff --git a/src/shared/struct/sh_db_item.erl b/src/shared/struct/sh_db_item.erl new file mode 100644 index 0000000..e499634 --- /dev/null +++ b/src/shared/struct/sh_db_item.erl @@ -0,0 +1,70 @@ +-module(sh_db_item). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-include("../include/db_item.hrl"). + +-type type() :: db_item(). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export_type([type/0]). + +-export +( + [ + new/3, + + get_id/1, + get_permission/1, + get_value/1, + + set_permission/2, + set_value/2, + + get_id_field/0, + get_record_info/0, + get_record_name/0 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec new (any(), db_user:permission(), any()) -> type(). +new (ID, Permission, Value) -> + #db_item + { + id = ID, + perm = Permission, + val = Value + }. + +-spec get_id (type()) -> any(). +get_id (#db_item { id = Result }) -> Result. + +-spec get_permission (type()) -> db_user:permission(). +get_permission (#db_item { perm = Result }) -> Result. + +-spec get_value (type()) -> any(). +get_value (#db_item { val = Result }) -> Result. + +-spec set_permission (db_user:permission(), type()) -> type(). +set_permission (Perm, Item) -> Item#db_item{ perm = Perm }. + +-spec set_value (any(), type()) -> type(). +set_value (Value, Item) -> Item#db_item{ val = Value }. + +-spec get_id_field () -> non_neg_integer(). +get_id_field () -> #db_item.id. + +get_record_info () -> record_info(fields, db_item). + +get_record_name () -> db_item. + diff --git a/src/shared/struct/sh_db_query.erl b/src/shared/struct/sh_db_query.erl new file mode 100644 index 0000000..998568e --- /dev/null +++ b/src/shared/struct/sh_db_query.erl @@ -0,0 +1,59 @@ +-module(sh_db_query). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-include("../include/db_query.hrl"). + +-opaque op() :: db_query_op(). +-opaque type() :: db_query(). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export_type([type/0, op/0]). + +-export +( + [ + new/4, + set_field/2, + add_to_field/2, + update_indexed/3 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec new (atom(), any(), sh_db_user:user(), list(op())) -> type(). +new (DBName, ObjectID, User, Ops) -> + #db_query + { + db = DBName, + id = ObjectID, + user = User, + ops = Ops + }. + +-spec set_field (non_neg_integer(), any()) -> op(). +set_field (Field, Value) -> + #set_field { field = Field, value = Value }. + +-spec add_to_field (non_neg_integer(), list(any())) -> op(). +add_to_field (Field, Values) -> + #add_to_field { field = Field, values = Values }. + +-spec update_indexed + ( + non_neg_integer(), + non_neg_integer(), + list(op()) + ) + -> op(). +update_indexed (Field, IX, Updates) -> + #update_indexed { field = Field, ix = IX, ops = Updates}. diff --git a/src/shared/struct/sh_db_user.erl b/src/shared/struct/sh_db_user.erl new file mode 100644 index 0000000..40a46d3 --- /dev/null +++ b/src/shared/struct/sh_db_user.erl @@ -0,0 +1,28 @@ +-module(sh_db_user). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-include("../include/db_user.hrl"). + +-type user() :: db_user(). +-type permission() :: db_permission(). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export_type([user/0, permission/0]). + +-export([can_access/2]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec can_access (permission(), user()) -> boolean(). +can_access (_, admin) -> true; +can_access (any, _) -> true; +can_access (List, {'user', User}) -> + lists:member(User, List). diff --git a/src/shared/struct/sh_statistics.erl b/src/shared/struct/sh_statistics.erl new file mode 100644 index 0000000..7cf2b06 --- /dev/null +++ b/src/shared/struct/sh_statistics.erl @@ -0,0 +1,193 @@ +-module(sh_statistics). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-record +( + statistics, + { + movement_points :: non_neg_integer(), + health :: non_neg_integer(), + dodges :: non_neg_integer(), + parries :: non_neg_integer(), + damage_min :: non_neg_integer(), + damage_max :: non_neg_integer(), + accuracy :: non_neg_integer(), + double_hits :: non_neg_integer(), + critical_hits :: non_neg_integer() + } +). + +-opaque type() :: #statistics{}. + +-export_type([type/0]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-export +( + [ + get_movement_points/1, + get_health/1, + get_dodges/1, + get_parries/1, + get_damage_min/1, + get_damage_max/1, + get_accuracy/1, + get_double_hits/1, + get_critical_hits/1, + + get_damages/1 + ] +). + +-export +( + [ + new/2 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec ceil (float()) -> integer(). +ceil (F) -> + I = trunc(F), + case (F > I) of + true -> (I + 1); + _ -> I + end. + +-spec float_to_int (float()) -> integer(). +float_to_int (F) -> ceil(F). + +-spec min_max (number(), number(), number()) -> number(). +min_max (Min, Max, V) -> min(Max, max(Min, V)). + +-spec average (list(number())) -> number(). +%average ([]) -> 0; +average (L) -> lists:sum(L) / length(L). + +% V | 010 | 030 | 050 | 070 | 100 | +% F | 004 | 023 | 058 | 104 | 200 | +-spec gentle_squared_growth (number()) -> non_neg_integer(). +gentle_squared_growth (V) -> float_to_int(math:pow(V, 1.8) / 20). + +% V | 010 | 030 | 050 | 070 | 100 | +% F | 001 | 005 | 018 | 041 | 100 | +-spec sudden_squared_growth (number()) -> non_neg_integer(). +sudden_squared_growth (V) -> float_to_int(math:pow(V, 2.5) / 1000). + +% V | 010 | 030 | 050 | 070 | 100 | +% F | 002 | 006 | 016 | 049 | 256 | +-spec sudden_exp_growth (number()) -> non_neg_integer(). +sudden_exp_growth (V) -> float_to_int(math:pow(4, V / 25)). + +% V | 010 | 030 | 050 | 070 | 100 | +% F | 040 | 066 | 079 | 088 | 099 | +% Seems too generous, values for attributes below 50 should dip faster and +% lower. +%-spec already_high_slow_growth (non_neg_integer()) -> non_neg_integer(). +%already_high_slow_growth (V) -> float_to_int(30 * math:log((V + 5)/4)). + +-spec damage_base_modifier (non_neg_integer()) -> float(). +damage_base_modifier (Strength) -> ((math:pow(Strength, 1.8) / 2000.0) - 0.75). + +-spec apply_damage_base_modifier + ( + float(), + non_neg_integer() + ) + -> non_neg_integer(). +apply_damage_base_modifier (Modifier, BaseValue) -> + max(0, float_to_int(BaseValue + (BaseValue * Modifier))). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-spec get_movement_points (type()) -> non_neg_integer(). +get_movement_points (Stats) -> Stats#statistics.movement_points. + +-spec get_health (type()) -> non_neg_integer(). +get_health (Stats) -> Stats#statistics.health. + +-spec get_dodges (type()) -> non_neg_integer(). +get_dodges (Stats) -> Stats#statistics.dodges. + +-spec get_parries (type()) -> non_neg_integer(). +get_parries (Stats) -> Stats#statistics.parries. + +-spec get_damage_min (type()) -> non_neg_integer(). +get_damage_min (Stats) -> Stats#statistics.damage_min. + +-spec get_damage_max (type()) -> non_neg_integer(). +get_damage_max (Stats) -> Stats#statistics.damage_max. + +-spec get_accuracy (type()) -> non_neg_integer(). +get_accuracy (Stats) -> Stats#statistics.accuracy. + +-spec get_double_hits (type()) -> non_neg_integer(). +get_double_hits (Stats) -> Stats#statistics.double_hits. + +-spec get_critical_hits (type()) -> non_neg_integer(). +get_critical_hits (Stats) -> Stats#statistics.critical_hits. + +-spec get_damages (type()) -> {non_neg_integer(), non_neg_integer()}. +get_damages (Stats) -> + { + Stats#statistics.damage_min, + Stats#statistics.damage_max + }. + +-spec new + ( + attributes:type(), + {weapon:id(), weapon:id()} + ) + -> type(). +new (BaseAttributes, WeaponIDs) -> + {ActiveWeaponID, _} = WeaponIDs, + ActiveWeapon = weapon:from_id(ActiveWeaponID), + {MinDamage, MaxDamage} = weapon:get_damages(ActiveWeapon), + Attributes = weapon:apply_to_attributes(BaseAttributes, ActiveWeapon), + Constitution = attributes:get_constitution(Attributes), + Dexterity = attributes:get_dexterity(Attributes), + Intelligence = attributes:get_intelligence(Attributes), + Mind = attributes:get_mind(Attributes), + Speed = attributes:get_speed(Attributes), + Strength = attributes:get_strength(Attributes), + DamageBaseModifier = damage_base_modifier(Strength), + + #statistics + { + movement_points = + gentle_squared_growth + ( + average([Mind, Constitution, Constitution, Speed, Speed, Speed]) + ), + health = + gentle_squared_growth(average([Mind, Constitution, Constitution])), + dodges = + min_max(0, 100, sudden_exp_growth(average([Dexterity, Mind, Speed]))), + parries = + min_max + ( + 0, + 75, + sudden_exp_growth + ( + average([Dexterity, Intelligence, Speed, Strength]) + ) + ), + damage_min = apply_damage_base_modifier(DamageBaseModifier, MinDamage), + damage_max = apply_damage_base_modifier(DamageBaseModifier, MaxDamage), + accuracy = min_max(0, 100, sudden_squared_growth(Dexterity)), + double_hits = + min_max(0, 100, sudden_squared_growth(average([Mind, Speed]))), + critical_hits = min_max(0, 100, sudden_squared_growth(Intelligence)) + }. -- cgit v1.2.3-70-g09d2