From 5661632540501cb7b00524acc628c78840f84007 Mon Sep 17 00:00:00 2001 From: Teddy Middleton-Smith Date: Mon, 16 Feb 2026 19:30:31 +0000 Subject: [PATCH] Feat: Decks page. --- business_objects/base.py | 1 + business_objects/tcg/mtg_deck.py | 7 + .../tcg/mtg_deck_commander_bracket.py | 12 +- .../tcg/mtg_game_round_player_damage.py | 34 +- business_objects/tcg/statistic.py | 287 + controllers/tcg/mtg_game.py | 29 +- datastores/datastore_mtg.py | 56 +- forms/tcg/game.py | 8 +- models/model_view_base.py | 4 + models/model_view_mtg_base.py | 30 +- models/model_view_mtg_decks.py | 85 + static/PostgreSQL/11208_tbl_TCG_MTG_Game.sql | 2 +- ...0_tbl_TCG_MTG_Game_Round_Player_Damage.sql | 4 +- ..._TCG_MTG_Game_Round_Player_Damage_Temp.sql | 4 +- static/PostgreSQL/11300_tbl_TCG_Statistic.sql | 32 + .../11301_tbl_TCG_Statistic_Audit.sql | 15 + ...0_tri_TCG_MTG_Game_Round_Player_Damage.sql | 10 +- static/PostgreSQL/31300_tri_TCG_Statistic.sql | 96 + .../PostgreSQL/70505_usp_TCG_User_Login.sql | 2 +- ...G_Deck_Commander_Bracket_Get_Many copy.sql | 128 + ..._MTG_Game_Round_Player_Damage_Get_Many.sql | 8 +- ...221_usp_TCG_MTG_Game_Round_Damage_Save.sql | 54 +- .../71300_fn_TCG_Statistic_Get_Many.sql | 144 + .../71301_usp_TCG_Statistic_Calc.sql | 9521 +++++++++++++++++ static/css/components/button.css | 6 +- static/css/components/form.css | 2 +- static/css/components/overlay.css | 18 +- static/css/components/table.css | 4 +- static/css/layouts/footer.css | 17 +- static/css/layouts/header.css | 6 +- static/css/layouts/table-main.css | 87 +- static/css/main.css | 15 +- static/css/pages/tcg/base.css | 12 +- static/css/pages/tcg/decks.css | 38 + static/css/pages/tcg/game.css | 42 +- static/css/pages/tcg/games.css | 57 +- static/css/pages/user/user.css | 4 +- static/css/sections/tcg.css | 2 +- static/css/themes/dark.css | 4 +- static/css/themes/icons.css | 4 +- static/css/themes/light.css | 8 +- static/dist/css/main.bundle.css | 235 +- static/dist/css/main.bundle.css.map | 2 +- static/dist/css/tcg_decks.bundle.css | 106 + static/dist/css/tcg_decks.bundle.css.map | 1 + static/dist/css/tcg_game.bundle.css | 44 +- static/dist/css/tcg_game.bundle.css.map | 2 +- static/dist/css/tcg_games.bundle.css | 59 +- static/dist/css/tcg_games.bundle.css.map | 2 +- static/dist/css/tcg_home.bundle.css | 2 +- static/dist/css/tcg_home.bundle.css.map | 2 +- static/dist/css/user_account.bundle.css | 6 +- static/dist/css/user_account.bundle.css.map | 2 +- static/dist/css/user_accounts.bundle.css | 2 +- static/dist/css/user_accounts.bundle.css.map | 2 +- static/dist/js/main.bundle.js | 302 +- static/dist/js/main.bundle.js.map | 2 +- static/dist/js/tcg_decks.bundle.js | 17 + static/dist/js/tcg_decks.bundle.js.map | 1 + static/js/pages/base.js | 1 + static/js/pages/base_table.js | 11 +- static/js/pages/tcg/mtg_decks.js | 110 + static/js/pages/tcg/mtg_game.js | 204 +- static/js/pages/tcg/mtg_games.js | 36 +- static/js/router.js | 3 + .../tcg/_preview_ddl_commander_bracket.html | 5 + templates/components/tcg/_row_deck.html | 44 + templates/layouts/_shared_mtg_scripts.html | 27 +- templates/layouts/_shared_scripts.html | 1 + templates/layouts/layout_tcg.html | 18 +- templates/pages/tcg/mtg/_decks.html | 111 + templates/pages/tcg/mtg/_game.html | 6 +- templates/pages/tcg/mtg/_games.html | 111 +- todo.txt | 4 + webpack.config.js | 6 +- 75 files changed, 11850 insertions(+), 536 deletions(-) create mode 100644 business_objects/tcg/statistic.py create mode 100644 models/model_view_mtg_decks.py create mode 100644 static/PostgreSQL/11300_tbl_TCG_Statistic.sql create mode 100644 static/PostgreSQL/11301_tbl_TCG_Statistic_Audit.sql create mode 100644 static/PostgreSQL/31300_tri_TCG_Statistic.sql create mode 100644 static/PostgreSQL/71196_fn_TCG_MTG_Deck_Commander_Bracket_Get_Many copy.sql create mode 100644 static/PostgreSQL/71300_fn_TCG_Statistic_Get_Many.sql create mode 100644 static/PostgreSQL/71301_usp_TCG_Statistic_Calc.sql create mode 100644 static/css/pages/tcg/decks.css create mode 100644 static/dist/css/tcg_decks.bundle.css create mode 100644 static/dist/css/tcg_decks.bundle.css.map create mode 100644 static/dist/js/tcg_decks.bundle.js create mode 100644 static/dist/js/tcg_decks.bundle.js.map create mode 100644 static/js/pages/tcg/mtg_decks.js create mode 100644 templates/components/tcg/_preview_ddl_commander_bracket.html create mode 100644 templates/components/tcg/_row_deck.html create mode 100644 templates/pages/tcg/mtg/_decks.html diff --git a/business_objects/base.py b/business_objects/base.py index e27546c..e664245 100644 --- a/business_objects/base.py +++ b/business_objects/base.py @@ -76,6 +76,7 @@ class Base(): FLAG_TEXT_COLOUR: ClassVar[str] = 'text_colour' FLAG_URL: ClassVar[str] = 'url' FLAG_USER: ClassVar[str] = 'authorisedUser' # 'user' already used + FLAG_VALUE: ClassVar[str] = 'value' FLAG_VALUE_LOCAL_VAT_EXCL: ClassVar[str] = 'value_local_vat_excl' FLAG_VALUE_LOCAL_VAT_INCL: ClassVar[str] = 'value_local_vat_incl' FLAG_WEBSITE: ClassVar[str] = 'website' diff --git a/business_objects/tcg/mtg_deck.py b/business_objects/tcg/mtg_deck.py index 02c0ba9..56db93e 100644 --- a/business_objects/tcg/mtg_deck.py +++ b/business_objects/tcg/mtg_deck.py @@ -10,6 +10,7 @@ Feature: MTG Deck Business Object # internal from business_objects.base import Base from business_objects.db_base import SQLAlchemy_ABC, Get_Many_Parameters_Base +from business_objects.tcg.mtg_deck_commander_bracket import MTG_Deck_Commander_Bracket import lib.argument_validation as av from extensions import db from helpers.helper_app import Helper_App @@ -24,6 +25,7 @@ class MTG_Deck(SQLAlchemy_ABC, Base): ATTR_COMMANDER_BRACKET_ID: ClassVar[str] = 'commander_bracket_id' FLAG_DECK: ClassVar[str] = 'deck' FLAG_IS_COMMANDER: ClassVar[str] = 'is_commander' + FLAG_STATISTICS: ClassVar[str] = 'statistics' NAME_ATTR_OPTION_VALUE: ClassVar[str] = ATTR_DECK_ID NAME_ATTR_OPTION_TEXT: ClassVar[str] = Base.FLAG_NAME @@ -41,9 +43,13 @@ class MTG_Deck(SQLAlchemy_ABC, Base): updated_last_by_user_id = db.Column(db.Integer) change_set_id = db.Column(db.Integer) + # commander_bracket: MTG_Deck_Commander_Bracket + def __init__(self): self.deck_id = 0 self.is_new = False + self.commander_bracket = None + self.statistics = None super().__init__() @classmethod @@ -83,6 +89,7 @@ class MTG_Deck(SQLAlchemy_ABC, Base): , self.FLAG_ACTIVE: self.active , self.FLAG_CREATED_ON: self.created_on , Base.ATTR_USER_ID: self.created_by_user_id + , self.FLAG_STATISTICS: self.statistics } return as_json diff --git a/business_objects/tcg/mtg_deck_commander_bracket.py b/business_objects/tcg/mtg_deck_commander_bracket.py index b34fa02..224a146 100644 --- a/business_objects/tcg/mtg_deck_commander_bracket.py +++ b/business_objects/tcg/mtg_deck_commander_bracket.py @@ -104,21 +104,19 @@ class Parameters_MTG_Deck_Commander_Bracket(Get_Many_Parameters_Base): get_inactive_commander_bracket: bool commander_bracket_ids: str commander_bracket_names: str - user_ids: str require_all_id_filters_met: bool require_any_id_filters_met: bool require_all_non_id_filters_met: bool require_any_non_id_filters_met: bool @classmethod - def get_default(cls, user_id_session): + def get_default(cls): return cls( get_all_commander_bracket = True , get_inactive_commander_bracket = False , commander_bracket_ids = '' , commander_bracket_names = '' - , user_ids = str(user_id_session) - , require_all_id_filters_met = True + , require_all_id_filters_met = False , require_any_id_filters_met = True , require_all_non_id_filters_met = False , require_any_non_id_filters_met = True @@ -127,12 +125,11 @@ class Parameters_MTG_Deck_Commander_Bracket(Get_Many_Parameters_Base): @classmethod def from_json(cls, json): return cls( - get_all_commander_bracket = json.get('a_get_all_commander_bracket', False) + get_all_commander_bracket = json.get('a_get_all_commander_bracket', True) , get_inactive_commander_bracket = json.get('a_get_inactive_commander_bracket', False) , commander_bracket_ids = json.get('a_commander_bracket_ids', '') , commander_bracket_names = json.get('a_commander_bracket_names', '') - , user_ids = json.get('a_user_ids', '') - , require_all_id_filters_met = json.get('a_require_all_id_filters_met', True) + , require_all_id_filters_met = json.get('a_require_all_id_filters_met', False) , require_any_id_filters_met = json.get('a_require_any_id_filters_met', True) , require_all_non_id_filters_met = json.get('a_require_all_non_id_filters_met', False) , require_any_non_id_filters_met = json.get('a_require_any_non_id_filters_met', True) @@ -144,7 +141,6 @@ class Parameters_MTG_Deck_Commander_Bracket(Get_Many_Parameters_Base): , 'a_get_inactive_commander_bracket': self.get_inactive_commander_bracket , 'a_commander_bracket_ids': self.commander_bracket_ids , 'a_commander_bracket_names': self.commander_bracket_names - , 'a_user_ids': self.user_ids , 'a_require_all_id_filters_met': self.require_all_id_filters_met , 'a_require_any_id_filters_met': self.require_any_id_filters_met , 'a_require_all_non_id_filters_met': self.require_all_non_id_filters_met diff --git a/business_objects/tcg/mtg_game_round_player_damage.py b/business_objects/tcg/mtg_game_round_player_damage.py index 040a887..135c48f 100644 --- a/business_objects/tcg/mtg_game_round_player_damage.py +++ b/business_objects/tcg/mtg_game_round_player_damage.py @@ -27,8 +27,9 @@ class MTG_Game_Round_Player_Damage(SQLAlchemy_ABC, Base): ATTR_RECEIVED_FROM_COMMANDER_PLAYER_ID: ClassVar[str] = 'received_from_commander_player_id' FLAG_COMMANDER_DEATHS: ClassVar[str] = 'commander_deaths' FLAG_DAMAGE: ClassVar[str] = 'damage' - FLAG_HEALTH_CHANGE: ClassVar[str] = 'health_change' FLAG_IS_ELIMINATED: ClassVar[str] = 'is_eliminated' + FLAG_LIFE_GAIN: ClassVar[str] = 'life_gain' + FLAG_LIFE_LOSS: ClassVar[str] = 'life_loss' NAME_ATTR_OPTION_VALUE: ClassVar[str] = ATTR_DAMAGE_ID NAME_ATTR_OPTION_TEXT: ClassVar[str] = ATTR_DAMAGE_ID @@ -39,7 +40,8 @@ class MTG_Game_Round_Player_Damage(SQLAlchemy_ABC, Base): round_id = db.Column(db.Integer) player_id = db.Column(db.Integer) received_from_commander_player_id = db.Column(db.Integer) - health_change = db.Column(db.Integer) + life_gain = db.Column(db.Integer) + life_loss = db.Column(db.Integer) commander_deaths = db.Column(db.Integer) is_eliminated = db.Column(db.Boolean) active = db.Column(db.Boolean) @@ -62,12 +64,13 @@ class MTG_Game_Round_Player_Damage(SQLAlchemy_ABC, Base): damage.round_id = query_row[1] damage.player_id = query_row[2] damage.received_from_commander_player_id = query_row[3] - damage.health_change = query_row[4] - damage.commander_deaths = query_row[5] - damage.is_eliminated = av.input_bool(query_row[6], cls.FLAG_IS_ELIMINATED, _m) - damage.active = av.input_bool(query_row[7], cls.FLAG_ACTIVE, _m) - damage.created_on = query_row[8] - damage.created_by_user_id = query_row[9] + damage.life_gain = query_row[4] + damage.life_loss = query_row[5] + damage.commander_deaths = query_row[6] + damage.is_eliminated = av.input_bool(query_row[7], cls.FLAG_IS_ELIMINATED, _m) + damage.active = av.input_bool(query_row[8], cls.FLAG_ACTIVE, _m) + damage.created_on = query_row[9] + damage.created_by_user_id = query_row[10] return damage @classmethod @@ -79,7 +82,8 @@ class MTG_Game_Round_Player_Damage(SQLAlchemy_ABC, Base): damage.round_id = json.get(cls.ATTR_ROUND_ID, None) damage.player_id = json.get(cls.ATTR_PLAYER_ID, None) damage.received_from_commander_player_id = json.get(cls.ATTR_RECEIVED_FROM_COMMANDER_PLAYER_ID, None) - damage.health_change = json.get(cls.FLAG_HEALTH_CHANGE, 0) + damage.life_gain = json.get(cls.FLAG_LIFE_GAIN, 0) + damage.life_loss = json.get(cls.FLAG_LIFE_LOSS, 0) damage.commander_deaths = json.get(cls.FLAG_COMMANDER_DEATHS, 0) damage.is_eliminated = json.get(cls.FLAG_IS_ELIMINATED, False) damage.active = av.input_bool(json.get(cls.FLAG_ACTIVE, True), cls.FLAG_ACTIVE, _m) @@ -94,7 +98,8 @@ class MTG_Game_Round_Player_Damage(SQLAlchemy_ABC, Base): , self.ATTR_ROUND_ID: self.round_id , self.ATTR_PLAYER_ID: self.player_id , self.ATTR_RECEIVED_FROM_COMMANDER_PLAYER_ID: self.received_from_commander_player_id - , self.FLAG_HEALTH_CHANGE: self.health_change + , self.FLAG_LIFE_GAIN: self.life_gain + , self.FLAG_LIFE_LOSS: self.life_loss , self.FLAG_COMMANDER_DEATHS: self.commander_deaths , self.FLAG_IS_ELIMINATED: self.is_eliminated , self.FLAG_ACTIVE: self.active @@ -110,7 +115,8 @@ class MTG_Game_Round_Player_Damage(SQLAlchemy_ABC, Base): {self.ATTR_ROUND_ID}: {self.round_id} {self.ATTR_PLAYER_ID}: {self.player_id} {self.ATTR_RECEIVED_FROM_COMMANDER_PLAYER_ID}: {self.received_from_commander_player_id} - {self.FLAG_HEALTH_CHANGE}: {self.health_change} + {self.FLAG_LIFE_GAIN}: {self.life_gain} + {self.FLAG_LIFE_LOSS}: {self.life_loss} {self.FLAG_COMMANDER_DEATHS}: {self.commander_deaths} {self.FLAG_IS_ELIMINATED}: {self.is_eliminated} {self.FLAG_ACTIVE}: {self.active} @@ -127,7 +133,8 @@ class MTG_Game_Round_Player_Damage_Temp(db.Model, Base): round_id = db.Column(db.Integer) player_id = db.Column(db.Integer) received_from_commander_player_id = db.Column(db.Integer) - health_change = db.Column(db.Integer) + life_gain = db.Column(db.Integer) + life_loss = db.Column(db.Integer) commander_deaths = db.Column(db.Integer) is_eliminated = db.Column(db.Boolean) active = db.Column(db.Boolean) @@ -145,7 +152,8 @@ class MTG_Game_Round_Player_Damage_Temp(db.Model, Base): temp.round_id = damage.round_id temp.player_id = damage.player_id temp.received_from_commander_player_id = damage.received_from_commander_player_id - temp.health_change = damage.health_change + temp.life_gain = damage.life_gain + temp.life_loss = damage.life_loss temp.commander_deaths = damage.commander_deaths temp.is_eliminated = damage.is_eliminated temp.active = damage.active diff --git a/business_objects/tcg/statistic.py b/business_objects/tcg/statistic.py new file mode 100644 index 0000000..b4cb248 --- /dev/null +++ b/business_objects/tcg/statistic.py @@ -0,0 +1,287 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Business Objects +Feature: Statistic Business Object +""" + +# internal +from business_objects.base import Base +from business_objects.db_base import SQLAlchemy_ABC, Get_Many_Parameters_Base +import lib.argument_validation as av +from extensions import db +from helpers.helper_app import Helper_App +# external +from dataclasses import dataclass +from typing import ClassVar +from sqlalchemy import Uuid, Interval +from sqlalchemy.types import Text, Boolean + + +class Statistic(SQLAlchemy_ABC, Base): + ATTR_ENTITY_RECORD_ID: ClassVar[str] = 'entity_record_id' + ATTR_STATISTIC_ID: ClassVar[str] = 'statistic_id' + FLAG_ENTITY_TYPE_CODE: ClassVar[str] = 'entity_type_code' + FLAG_IS_BOOL: ClassVar[str] = 'is_bool' + FLAG_IS_FLOAT: ClassVar[str] = 'is_float' + FLAG_IS_INTERVAL: ClassVar[str] = 'is_interval' + FLAG_IS_TEXT: ClassVar[str] = 'is_text' + FLAG_IS_TIMESTAMP: ClassVar[str] = 'is_timestamp' + FLAG_VALUE_BOOL: ClassVar[str] = 'value_bool' + FLAG_VALUE_FLOAT: ClassVar[str] = 'value_float' + FLAG_VALUE_INTERVAL: ClassVar[str] = 'value_interval' + FLAG_VALUE_TEXT: ClassVar[str] = 'value_text' + FLAG_VALUE_TIMESTAMP: ClassVar[str] = 'value_timestamp' + NAME_ATTR_OPTION_VALUE: ClassVar[str] = ATTR_STATISTIC_ID + NAME_ATTR_OPTION_TEXT: ClassVar[str] = Base.FLAG_NAME + + __tablename__ = 'tcg_statistic' + __table_args__ = { 'extend_existing': True } + + statistic_id = db.Column(db.Integer, primary_key=True) + entity_type_code = db.Column(db.Text) # replace with lookup table later + entity_record_id = db.Column(db.Text) + name = db.Column(db.Text) + value_bool = db.Column(db.Boolean) + value_float = db.Column(db.Float) + value_interval = db.Column(Interval) + value_text = db.Column(db.Text) + value_timestamp = db.Column(db.DateTime) + is_bool = db.Column(db.Boolean) + is_float = db.Column(db.Boolean) + is_interval = db.Column(db.Boolean) + is_text = db.Column(db.Boolean) + is_timestamp = db.Column(db.Boolean) + display_order = db.Column(db.Integer) + active = db.Column(db.Boolean) + created_on = db.Column(db.DateTime) + created_by_user_id = db.Column(db.Integer) + updated_last_on = db.Column(db.DateTime) + updated_last_by_user_id = db.Column(db.Integer) + change_set_id = db.Column(db.Integer) + + def __init__(self): + self.statistic_id = 0 + self.is_new = False + super().__init__() + + @classmethod + def from_db_statistic(cls, query_row): + _m = f'{cls.__qualname__}.from_db_statistic' + statistic = cls() + statistic.statistic_id = query_row[0] + statistic.entity_type_code = query_row[1] + statistic.entity_record_id = query_row[2] + statistic.name = query_row[3] + statistic.value_bool = query_row[4] + statistic.value_float = query_row[5] + statistic.value_interval = query_row[6] + statistic.value_text = query_row[7] + statistic.value_timestamp = query_row[8] + statistic.is_bool = query_row[9] + statistic.is_float = query_row[10] + statistic.is_interval = query_row[11] + statistic.is_text = query_row[12] + statistic.is_timestamp = query_row[13] + statistic.display_order = query_row[14] + statistic.active = av.input_bool(query_row[15], cls.FLAG_ACTIVE, _m) + statistic.created_on = query_row[16] + statistic.created_by_user_id = query_row[17] + return statistic + + @classmethod + def from_json(cls, json): + _m = f'{cls.__qualname__}.from_json' + statistic = cls() + if json is None: return statistic + statistic.statistic_id = json.get(cls.ATTR_STATISTIC_ID, -1) + statistic.entity_type_code = json.get(cls.FLAG_ENTITY_TYPE_CODE, None) + statistic.entity_record_id = json.get(cls.ATTR_ENTITY_RECORD_ID, None) + statistic.name = json.get(cls.FLAG_NAME, '') + statistic.value_bool = json.get(cls.FLAG_VALUE_BOOL, None) + statistic.value_float = json.get(cls.FLAG_VALUE_FLOAT, None) + statistic.value_interval = json.get(cls.FLAG_VALUE_INTERVAL, None) + statistic.value_text = json.get(cls.FLAG_VALUE_TEXT, None) + statistic.value_timestamp = json.get(cls.FLAG_VALUE_TIMESTAMP, None) + statistic.is_bool = json.get(cls.FLAG_IS_BOOL, False) + statistic.is_float = json.get(cls.FLAG_IS_FLOAT, False) + statistic.is_interval = json.get(cls.FLAG_IS_INTERVAL, False) + statistic.is_text = json.get(cls.FLAG_IS_TEXT, False) + statistic.is_timestamp = json.get(cls.FLAG_IS_TIMESTAMP, False) + statistic.display_order = json.get(cls.FLAG_DISPLAY_ORDER, -1) + statistic.active = av.input_bool(json.get(cls.FLAG_ACTIVE, True), cls.FLAG_ACTIVE, _m) + statistic.created_on = json.get(cls.FLAG_CREATED_ON, None) + statistic.created_by_user_id = json.get(Base.ATTR_USER_ID, None) + return statistic + + def to_json(self): + as_json = { + **self.get_shared_json_attributes(self) + , self.ATTR_STATISTIC_ID: self.statistic_id + , self.FLAG_ENTITY_TYPE_CODE: self.entity_type_code + , self.ATTR_ENTITY_RECORD_ID: self.entity_record_id + , self.FLAG_NAME: self.name + , self.FLAG_VALUE_BOOL: self.value_bool + , self.FLAG_VALUE_FLOAT: self.value_float + , self.FLAG_VALUE_INTERVAL: self.value_interval + , self.FLAG_VALUE_TEXT: self.value_text + , self.FLAG_VALUE_TIMESTAMP: self.value_timestamp + , self.FLAG_IS_BOOL: self.is_bool + , self.FLAG_IS_FLOAT: self.is_float + , self.FLAG_IS_INTERVAL: self.is_interval + , self.FLAG_IS_TEXT: self.is_text + , self.FLAG_IS_TIMESTAMP: self.is_timestamp + , self.FLAG_DISPLAY_ORDER: self.display_order + , self.FLAG_ACTIVE: self.active + , self.FLAG_CREATED_ON: self.created_on + , Base.ATTR_USER_ID: self.created_by_user_id + } + return as_json + + def __repr__(self): + return f''' +{self.__class__.__name__}( + {self.ATTR_STATISTIC_ID}: {self.statistic_id} + {self.FLAG_ENTITY_TYPE_CODE}: {self.entity_type_code} + {self.ATTR_ENTITY_RECORD_ID}: {self.entity_record_id} + {self.FLAG_NAME}: {self.name} + {self.FLAG_VALUE_BOOL}: {self.value_bool} + {self.FLAG_VALUE_FLOAT}: {self.value_float} + {self.FLAG_VALUE_INTERVAL}: {self.value_interval} + {self.FLAG_VALUE_TEXT}: {self.value_text} + {self.FLAG_VALUE_TIMESTAMP}: {self.value_timestamp} + {self.FLAG_IS_BOOL}: {self.is_bool} + {self.FLAG_IS_FLOAT}: {self.is_float} + {self.FLAG_IS_INTERVAL}: {self.is_interval} + {self.FLAG_IS_TEXT}: {self.is_text} + {self.FLAG_IS_TIMESTAMP}: {self.is_timestamp} + {self.FLAG_DISPLAY_ORDER}: {self.display_order} + {self.FLAG_ACTIVE}: {self.active} + {self.FLAG_CREATED_ON}: {self.created_on} + {Base.ATTR_USER_ID}: {self.created_by_user_id} +) + ''' + + def get_formatted_value(self): + if self.is_bool: + return self.value_bool + elif self.is_float: + return self.value_float + elif self.is_interval: + return self.value_interval + elif self.is_text: + return self.value_text + elif self.is_timestamp: + return self.value_timestamp + else: + return None + +class Statistic_Temp(db.Model, Base): + __tablename__ = 'tcg_statistic_temp' + __table_args__ = { 'extend_existing': True } + temp_id = db.Column(db.Integer, primary_key=True) + statistic_id = db.Column(db.Integer) + entity_type_code = db.Column(db.Text) + entity_record_id = db.Column(db.Integer) + name = db.Column(db.Integer) + value_bool = db.Column(db.Boolean) + value_float = db.Column(db.Float) + value_interval = db.Column(Interval) + value_text = db.Column(db.Text) + value_timestamp = db.Column(db.DateTime) + is_bool = db.Column(db.Boolean) + is_float = db.Column(db.Boolean) + is_interval = db.Column(db.Boolean) + is_text = db.Column(db.Boolean) + is_timestamp = db.Column(db.Boolean) + display_order = db.Column(db.Integer) + active = db.Column(db.Boolean) + created_on = db.Column(db.DateTime) + guid = db.Column(Uuid) + + def __init__(self): + self.entity_record_name = None + super().__init__() + + @classmethod + def from_statistic(cls, statistic, guid): + _m = 'Statistic_Temp.from_statistic' + temp = cls() + temp.statistic_id = statistic.statistic_id + temp.entity_type_code = statistic.entity_type_code + temp.entity_record_id = statistic.entity_record_id + temp.name = statistic.name + temp.value_bool = statistic.value_bool + temp.value_float = statistic.value_float + temp.value_interval = statistic.value_interval + temp.value_text = statistic.value_text + temp.value_timestamp = statistic.value_timestamp + temp.is_bool = statistic.is_bool + temp.is_float = statistic.is_float + temp.is_interval = statistic.is_interval + temp.is_text = statistic.is_text + temp.is_timestamp = statistic.is_timestamp + temp.display_order = statistic.display_order + temp.active = statistic.active + temp.created_on = statistic.created_on + temp.guid = guid + return temp + + +class Parameters_Statistic(Get_Many_Parameters_Base): + get_all_statistic: bool + get_inactive_statistic: bool + statistic_ids: str + entity_type_codes: str + entity_record_ids: str + require_all_id_filters_met: bool + require_any_id_filters_met: bool + + @classmethod + def get_default(cls): + return cls( + get_all_statistic = True + , get_inactive_statistic = False + , statistic_ids = '' + , entity_type_codes = '' + , entity_record_ids = '' + , require_all_id_filters_met = True + , require_any_id_filters_met = True + ) + + @classmethod + def from_json(cls, json): + return cls( + get_all_statistic = json.get('a_get_all_statistic', False) + , get_inactive_statistic = json.get('a_get_inactive_statistic', False) + , statistic_ids = json.get('a_statistic_ids', '') + , entity_type_codes = json.get('a_entity_type_codes', '') + , entity_record_ids = json.get('a_entity_record_ids', '') + , require_all_id_filters_met = json.get('a_require_all_id_filters_met', True) + , require_any_id_filters_met = json.get('a_require_any_id_filters_met', True) + ) + + def to_json(self): + return { + 'a_get_all_statistic': self.get_all_statistic + , 'a_get_inactive_statistic': self.get_inactive_statistic + , 'a_statistic_ids': self.statistic_ids + , 'a_entity_type_codes': self.entity_type_codes + , 'a_entity_record_ids': self.entity_record_ids + , 'a_require_all_id_filters_met': self.require_all_id_filters_met + , 'a_require_any_id_filters_met': self.require_any_id_filters_met + } + + @staticmethod + def get_type_hints(): + return { + 'a_get_all_statistic': Boolean + , 'a_get_inactive_statistic': Boolean + , 'a_statistic_ids': Text + , 'a_entity_type_codes': Text + , 'a_entity_record_ids': Text + , 'a_require_all_id_filters_met': Boolean + , 'a_require_any_id_filters_met': Boolean + } diff --git a/controllers/tcg/mtg_game.py b/controllers/tcg/mtg_game.py index 99d40e2..a4e1dbb 100644 --- a/controllers/tcg/mtg_game.py +++ b/controllers/tcg/mtg_game.py @@ -13,6 +13,7 @@ MTG Game Page Controller. # IMPORTS # internal from business_objects.api import API +from business_objects.tcg.mtg_deck import MTG_Deck from business_objects.tcg.mtg_game import MTG_Game from business_objects.tcg.mtg_game_player import MTG_Game_Player, Parameters_MTG_Game_Player from business_objects.tcg.mtg_game_round import MTG_Game_Round, Parameters_MTG_Game_Round @@ -21,9 +22,10 @@ from business_objects.tcg.mtg_deck import MTG_Deck, Parameters_MTG_Deck from business_objects.tcg.user import User, Parameters_User from datastores.datastore_mtg import DataStore_MTG from datastores.datastore_user import DataStore_User -from forms.tcg.game import Filters_MTG_Game +from forms.tcg.game import Filters_MTG_Game, Filters_MTG_Deck from helpers.helper_app import Helper_App from models.model_view_mtg_base import Model_View_MTG_Base +from models.model_view_mtg_decks import Model_View_MTG_Decks from models.model_view_mtg_game import Model_View_MTG_Game from models.model_view_mtg_games import Model_View_MTG_Games from models.model_view_mtg_home import Model_View_MTG_Home @@ -373,3 +375,28 @@ def save_game_round_player_damage(): Model_View_MTG_Base.FLAG_STATUS: Model_View_MTG_Base.FLAG_FAILURE , Model_View_MTG_Base.FLAG_MESSAGE: f'Bad data received by controller.\n{e}' }) + + +@routes_mtg_game.route(Model_View_MTG_Base.HASH_PAGE_MTG_DECKS, methods=['GET']) +def decks(): + Helper_App.console_log('mtg decks') + Helper_App.console_log(f'request_args: {request.args}') + try: + form_filters = Filters_MTG_Deck.from_json(request.args) + except Exception as e: + Helper_App.console_log(f'Error: {e}') + form_filters = Filters_MTG_Deck() + Helper_App.console_log(f'form_filters={form_filters}') + + datastore = DataStore_MTG() + user_session = datastore.get_user_session() + if not user_session.get_is_logged_in(): + return redirect(url_for('routes_mtg_game.home')) + + parameters_deck = form_filters.to_parameters() + + model = Model_View_MTG_Decks(parameters_deck = parameters_deck) + model.form_filters = form_filters + Helper_App.console_log(f'form_filters={form_filters}') + return render_template('pages/tcg/mtg/_decks.html', model=model) + diff --git a/datastores/datastore_mtg.py b/datastores/datastore_mtg.py index 4888947..95428a8 100644 --- a/datastores/datastore_mtg.py +++ b/datastores/datastore_mtg.py @@ -12,11 +12,13 @@ Datastore for MTG game data # internal import lib.argument_validation as av +from business_objects.tcg.mtg_deck import MTG_Deck, Parameters_MTG_Deck +from business_objects.tcg.mtg_deck_commander_bracket import MTG_Deck_Commander_Bracket, Parameters_MTG_Deck_Commander_Bracket from business_objects.tcg.mtg_game import MTG_Game, Parameters_MTG_Game from business_objects.tcg.mtg_game_player import MTG_Game_Player, Parameters_MTG_Game_Player, MTG_Game_Player_Temp from business_objects.tcg.mtg_game_round import MTG_Game_Round, Parameters_MTG_Game_Round, MTG_Game_Round_Temp from business_objects.tcg.mtg_game_round_player_damage import MTG_Game_Round_Player_Damage, Parameters_MTG_Game_Round_Player_Damage, MTG_Game_Round_Player_Damage_Temp -from business_objects.tcg.mtg_deck import MTG_Deck, Parameters_MTG_Deck +from business_objects.tcg.statistic import Statistic, Statistic_Temp, Parameters_Statistic from business_objects.sql_error import SQL_Error, Parameters_SQL_Error from datastores.datastore_base import DataStore_Base from helpers.helper_app import Helper_App @@ -339,3 +341,55 @@ class DataStore_MTG(DataStore_Base): cls.clear_error(guid = guid) return success, errors + + + @classmethod + def get_many_mtg_deck_commander_bracket(cls, parameters_commander_bracket): + _m = f'{cls.__qualname__}.get_many_mtg_deck_commander_bracket' + argument_dict = parameters_commander_bracket.to_json() + argument_types = Parameters_MTG_Deck.get_type_hints() + Helper_App.console_log(f'{_m}\nargument_dict: {argument_dict}') + + commander_brackets = [] + errors = [] + try: + result = cls.db_function_execute('tcg.public.FN_TCG_MTG_Deck_Commander_Bracket_Get_Many', argument_dict, argument_types) + result_set = result.fetchall() + Helper_App.console_log(f'raw commander brackets: {result_set}') + for row in result_set: + new_commander_bracket = MTG_Deck_Commander_Bracket.from_db_mtg_deck_commander_bracket(row) + commander_brackets.append(new_commander_bracket) + Helper_App.console_log(f'commander bracket {str(type(new_commander_bracket))}: {new_commander_bracket}') + except Exception as e: + Helper_App.console_log(f'Error: {str(e)}') + error = SQL_Error() + error.msg = str(e) + errors.append(error) + + return commander_brackets, errors + + + @classmethod + def get_many_statistic(cls, parameters_statistic): + _m = f'{cls.__qualname__}.get_many_statistic' + argument_dict = parameters_statistic.to_json() + argument_types = Parameters_MTG_Deck.get_type_hints() + Helper_App.console_log(f'{_m}\nargument_dict: {argument_dict}') + + statistics = [] + errors = [] + try: + result = cls.db_function_execute('tcg.public.FN_TCG_Statistic_Get_Many', argument_dict, argument_types) + result_set = result.fetchall() + Helper_App.console_log(f'raw commander brackets: {result_set}') + for row in result_set: + new_statistic = Statistic.from_db_statistic(row) + statistics.append(new_statistic) + Helper_App.console_log(f'statistic {str(type(new_statistic))}: {new_statistic}') + except Exception as e: + Helper_App.console_log(f'Error: {str(e)}') + error = SQL_Error() + error.msg = str(e) + errors.append(error) + + return statistics, errors diff --git a/forms/tcg/game.py b/forms/tcg/game.py index 5703b89..3a0fe46 100644 --- a/forms/tcg/game.py +++ b/forms/tcg/game.py @@ -170,15 +170,15 @@ class Filters_MTG_Deck(Form_Base): , MTG_Deck.FLAG_IS_COMMANDER: self.is_commander.data } - def to_parameters(self, user_id_session): + def to_parameters(self): return Parameters_MTG_Deck( get_all_deck = True , get_inactive_deck = not self.active_only.data , deck_ids = '' - , deck_names = '' + , deck_names = self.search.data + , include_commander_option = True , commander_bracket_ids = '' - , user_ids = str(user_id_session) if user_id_session else '' - , require_all_id_filters_met = True + , require_all_id_filters_met = False , require_any_id_filters_met = True , require_all_non_id_filters_met = False , require_any_non_id_filters_met = True diff --git a/models/model_view_base.py b/models/model_view_base.py index dff951e..617ead6 100644 --- a/models/model_view_base.py +++ b/models/model_view_base.py @@ -51,6 +51,7 @@ class Model_View_Base(BaseModel, ABC): COLOUR_TEXT_LINK_VISITED: ClassVar[str] = '#551A8B' COMPANY_ADDRESS_SHORT: ClassVar[str] = 'Russet, Sawbridge Road, Grandborough, United Kingdom, CV23 8DN' COMPANY_NUMBER: ClassVar[str] = '13587499' + DECK_ENTITY_TYPE_CODE: ClassVar[str] = 'deck' ENDPOINT_GET_ALTCHA_CHALLENGE: ClassVar[str] = 'routes_core_contact.create_altcha_challenge' ENDPOINT_PAGE_ACCESSIBILITY_REPORT: ClassVar[str] = 'routes_legal.accessibility_report' ENDPOINT_PAGE_ACCESSIBILITY_STATEMENT: ClassVar[str] = 'routes_legal.accessibility_statement' @@ -162,6 +163,7 @@ class Model_View_Base(BaseModel, ABC): FLAG_TEMPORARY_ELEMENT: ClassVar[str] = 'temporary-element' FLAG_TESTIMONIAL: ClassVar[str] = 'testimonial' FLAG_USER: ClassVar[str] = User.FLAG_USER + FLAG_VALUE: ClassVar[str] = Base.FLAG_VALUE # FLAG_VALUE_PROPOSITION: ClassVar[str] = 'value-proposition' FLAG_WEBSITE: ClassVar[str] = Base.FLAG_WEBSITE HASH_GET_ALTCHA_CHALLENGE: ClassVar[str] = '/altcha/create-challenge' @@ -222,6 +224,8 @@ class Model_View_Base(BaseModel, ABC): URL_REDDIT: ClassVar[str] = f'https://www.reddit.com/u/{USERNAME_REDDIT}/s/gZKEz2ZwHN' URL_TIKTOK: ClassVar[str] = f'https://www.tiktok.com/@{USERNAME_TIKTOK}' URL_TWITTER: ClassVar[str] = f'https://x.com/{USERNAME_TWITTER}' + USER_ENTITY_TYPE_CODE: ClassVar[str] = 'user' + USER_DECK_LINK_ENTITY_TYPE_CODE: ClassVar[str] = 'user_deck_link' _title: str hash_page_current: str diff --git a/models/model_view_mtg_base.py b/models/model_view_mtg_base.py index 7d3f380..44f14ae 100644 --- a/models/model_view_mtg_base.py +++ b/models/model_view_mtg_base.py @@ -12,11 +12,13 @@ Parent data model for MTG views # internal +from business_objects.tcg.mtg_deck import MTG_Deck, Parameters_MTG_Deck +from business_objects.tcg.mtg_deck_commander_bracket import MTG_Deck_Commander_Bracket from business_objects.tcg.mtg_game import MTG_Game, Parameters_MTG_Game from business_objects.tcg.mtg_game_player import MTG_Game_Player, Parameters_MTG_Game_Player from business_objects.tcg.mtg_game_round import MTG_Game_Round, Parameters_MTG_Game_Round from business_objects.tcg.mtg_game_round_player_damage import MTG_Game_Round_Player_Damage, Parameters_MTG_Game_Round_Player_Damage -from business_objects.tcg.mtg_deck import MTG_Deck, Parameters_MTG_Deck +from business_objects.tcg.statistic import Statistic from helpers.helper_app import Helper_App import lib.argument_validation as av from models.model_view_base import Model_View_Base @@ -29,32 +31,46 @@ from abc import abstractmethod class Model_View_MTG_Base(Model_View_Base): + ATTR_COMMANDER_BRACKET_ID: ClassVar[str] = MTG_Deck_Commander_Bracket.ATTR_COMMANDER_BRACKET_ID + ATTR_DAMAGE_ID: ClassVar[str] = MTG_Game_Round_Player_Damage.ATTR_DAMAGE_ID + ATTR_DECK_ID: ClassVar[str] = MTG_Deck.ATTR_DECK_ID + ATTR_ENTITY_RECORD_ID: ClassVar[str] = Statistic.ATTR_ENTITY_RECORD_ID ATTR_GAME_ID: ClassVar[str] = MTG_Game.ATTR_GAME_ID ATTR_PLAYER_ID: ClassVar[str] = MTG_Game_Player.ATTR_PLAYER_ID ATTR_ROUND_ID: ClassVar[str] = MTG_Game_Round.ATTR_ROUND_ID - ATTR_DAMAGE_ID: ClassVar[str] = MTG_Game_Round_Player_Damage.ATTR_DAMAGE_ID - ATTR_DECK_ID: ClassVar[str] = MTG_Deck.ATTR_DECK_ID FLAG_COMMANDER_DEATHS: ClassVar[str] = MTG_Game_Round_Player_Damage.FLAG_COMMANDER_DEATHS FLAG_DAMAGE: ClassVar[str] = MTG_Game_Round_Player_Damage.FLAG_DAMAGE FLAG_DECK: ClassVar[str] = MTG_Deck.FLAG_DECK + FLAG_ENTITY_TYPE_CODE: ClassVar[str] = Statistic.FLAG_ENTITY_TYPE_CODE FLAG_GAME: ClassVar[str] = MTG_Game.FLAG_GAME - FLAG_HEALTH_CHANGE: ClassVar[str] = MTG_Game_Round_Player_Damage.FLAG_HEALTH_CHANGE + FLAG_IS_BOOL: ClassVar[str] = Statistic.FLAG_IS_BOOL + FLAG_IS_FLOAT: ClassVar[str] = Statistic.FLAG_IS_FLOAT + FLAG_IS_INTERVAL: ClassVar[str] = Statistic.FLAG_IS_INTERVAL + FLAG_IS_TEXT: ClassVar[str] = Statistic.FLAG_IS_TEXT + FLAG_IS_TIMESTAMP: ClassVar[str] = Statistic.FLAG_IS_TIMESTAMP FLAG_IS_COMMANDER: ClassVar[str] = MTG_Game.FLAG_IS_COMMANDER FLAG_IS_DRAFT: ClassVar[str] = MTG_Game.FLAG_IS_DRAFT FLAG_IS_SEALED: ClassVar[str] = MTG_Game.FLAG_IS_SEALED + FLAG_LIFE_GAIN: ClassVar[str] = MTG_Game_Round_Player_Damage.FLAG_LIFE_GAIN + FLAG_LIFE_LOSS: ClassVar[str] = MTG_Game_Round_Player_Damage.FLAG_LIFE_LOSS FLAG_LOCATION_NAME: ClassVar[str] = MTG_Game.FLAG_LOCATION_NAME FLAG_PLAYER: ClassVar[str] = MTG_Game_Player.FLAG_PLAYER FLAG_ROUND: ClassVar[str] = MTG_Game_Round.FLAG_ROUND FLAG_STARTING_LIFE: ClassVar[str] = MTG_Game.FLAG_STARTING_LIFE + FLAG_VALUE_BOOL: ClassVar[str] = Statistic.FLAG_VALUE_BOOL + FLAG_VALUE_FLOAT: ClassVar[str] = Statistic.FLAG_VALUE_FLOAT + FLAG_VALUE_INTERVAL: ClassVar[str] = Statistic.FLAG_VALUE_INTERVAL + FLAG_VALUE_TEXT: ClassVar[str] = Statistic.FLAG_VALUE_TEXT + FLAG_VALUE_TIMESTAMP: ClassVar[str] = Statistic.FLAG_VALUE_TIMESTAMP + HASH_GET_MTG_GAME_DAMAGE_RECORDS: ClassVar[str] = '/mtg/api/game//damage-records' HASH_GET_MTG_GAME_PLAYERS: ClassVar[str] = '/mtg/api/game//players' HASH_GET_MTG_GAME_ROUNDS: ClassVar[str] = '/mtg/api/game//rounds' - HASH_GET_MTG_GAME_DAMAGE_RECORDS: ClassVar[str] = '/mtg/api/game//damage-records' + HASH_SAVE_MTG_DECK: ClassVar[str] = '/mtg/save-deck' HASH_SAVE_MTG_GAME: ClassVar[str] = '/mtg/save-game' HASH_SAVE_MTG_GAME_PLAYER: ClassVar[str] = '/mtg/save-game-player' HASH_SAVE_MTG_GAME_ROUND: ClassVar[str] = '/mtg/save-game-round' HASH_SAVE_MTG_GAME_ROUND_PLAYER_DAMAGE: ClassVar[str] = '/mtg/save-game-round-player-damage' - HASH_SAVE_MTG_DECK: ClassVar[str] = '/mtg/save-deck' - + is_page_mtg: bool = True def __init__(self, hash_page_current, **kwargs): diff --git a/models/model_view_mtg_decks.py b/models/model_view_mtg_decks.py new file mode 100644 index 0000000..d3f6de8 --- /dev/null +++ b/models/model_view_mtg_decks.py @@ -0,0 +1,85 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: View Models +Feature: MTG Decks View Model + +Description: +Data model for MTG decks view +""" + +# internal +from business_objects.tcg.mtg_deck_commander_bracket import MTG_Deck_Commander_Bracket, Parameters_MTG_Deck_Commander_Bracket +from business_objects.tcg.mtg_deck import MTG_Deck, Parameters_MTG_Deck +from business_objects.tcg.statistic import Statistic, Parameters_Statistic +from datastores.datastore_mtg import DataStore_MTG +from models.model_view_mtg_base import Model_View_MTG_Base +from helpers.helper_app import Helper_App +import lib.argument_validation as av + +# external +from pydantic import BaseModel +from typing import ClassVar + + +class Model_View_MTG_Decks(Model_View_MTG_Base): + FLAG_STATISTICS: ClassVar[str] = 'statistics' + commander_brackets: list = None + decks: list = None + form_filters: object = None + parameters_deck: Parameters_MTG_Deck = None + statistics: list = None + + def __init__(self, parameters_deck=None, hash_page_current=Model_View_MTG_Base.HASH_PAGE_MTG_DECKS): + _m = 'Model_View_MTG_Decks.__init__' + Helper_App.console_log(f'{_m}\nstarting...') + super().__init__(hash_page_current=hash_page_current) + self._title = 'MTG Decks' + datastore = DataStore_MTG() + + # Get all decks + parameters_deck = Parameters_MTG_Deck.get_default() + parameters_deck.get_all_deck = True + parameters_deck.require_all_id_filters_met = False + parameters_deck.require_any_id_filters_met = False + parameters_deck.require_all_non_id_filters_met = False + parameters_deck.require_any_non_id_filters_met = False + self.decks, errors = datastore.get_many_mtg_deck(parameters_deck) + + Helper_App.console_log(f'Decks IDs: {self.decks}') + # Get all commander brackets + parameters_commander_bracket = Parameters_MTG_Deck_Commander_Bracket.get_default() + parameters_commander_bracket.get_all_commander_bracket = True + parameters_commander_bracket.require_all_id_filters_met = False + parameters_commander_bracket.require_any_id_filters_met = False + self.commander_brackets, errors = datastore.get_many_mtg_deck_commander_bracket(parameters_commander_bracket = parameters_commander_bracket) + + Helper_App.console_log(f'Brackets: {self.commander_brackets}') + commander_bracket_index = {} + for index_commander_bracket in range(len(self.commander_brackets)): + bracket = self.commander_brackets[index_commander_bracket] + commander_bracket_index[bracket.commander_bracket_id] = bracket + Helper_App.console_log(f'Bracket IDs: {commander_bracket_index}') + + deck_index = {} + for index_deck in range(len(self.decks)): + bracket = commander_bracket_index[self.decks[index_deck].commander_bracket_id] + self.decks[index_deck].commander_bracket = bracket + deck_index[self.decks[index_deck].deck_id] = self.decks[index_deck] + + # Get all statistics + parameters_statistic = Parameters_Statistic.get_default() + parameters_statistic.get_all_statistic = False + parameters_statistic.entity_type_codes = Model_View_MTG_Decks.DECK_ENTITY_TYPE_CODE + parameters_statistic.entity_record_ids = ','.join([str(d.deck_id) for d in self.decks]) + parameters_statistic.require_all_id_filters_met = True + parameters_statistic.require_any_id_filters_met = True + self.statistics, errors = datastore.get_many_statistic(parameters_statistic = parameters_statistic) + + for index_statistic in range(len(self.statistics)): + deck = deck_index[int(self.statistics[index_statistic].entity_record_id)] + self.statistics[index_statistic].entity_record_name = deck.name + + diff --git a/static/PostgreSQL/11208_tbl_TCG_MTG_Game.sql b/static/PostgreSQL/11208_tbl_TCG_MTG_Game.sql index 832b013..dbee141 100644 --- a/static/PostgreSQL/11208_tbl_TCG_MTG_Game.sql +++ b/static/PostgreSQL/11208_tbl_TCG_MTG_Game.sql @@ -8,7 +8,7 @@ CREATE TABLE tcg.public.TCG_MTG_Game ( , location_name TEXT , start_on TIMESTAMP , end_on TIMESTAMP - , starting_life INT + , starting_life INT NOT NULL , active BOOLEAN NOT NULL DEFAULT TRUE , created_on TIMESTAMP NOT NULL , created_by_user_id INT NOT NULL diff --git a/static/PostgreSQL/11220_tbl_TCG_MTG_Game_Round_Player_Damage.sql b/static/PostgreSQL/11220_tbl_TCG_MTG_Game_Round_Player_Damage.sql index 56a8128..d02fbc0 100644 --- a/static/PostgreSQL/11220_tbl_TCG_MTG_Game_Round_Player_Damage.sql +++ b/static/PostgreSQL/11220_tbl_TCG_MTG_Game_Round_Player_Damage.sql @@ -1,3 +1,4 @@ + CREATE TABLE tcg.public.TCG_MTG_Game_Round_Player_Damage ( damage_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY , round_id INT NOT NULL @@ -12,7 +13,8 @@ CREATE TABLE tcg.public.TCG_MTG_Game_Round_Player_Damage ( , CONSTRAINT FK_TCG_MTG_Game_Round_Player_Damage_received_from_commander_player_id FOREIGN KEY (received_from_commander_player_id) REFERENCES tcg.public.TCG_MTG_Game_Player(player_id) - , health_change INT NOT NULL + , life_gain INT NOT NULL + , life_loss INT NOT NULL , commander_deaths INT NOT NULL , is_eliminated BOOLEAN NOT NULL DEFAULT FALSE , active BOOLEAN NOT NULL DEFAULT TRUE diff --git a/static/PostgreSQL/11222_tbl_TCG_MTG_Game_Round_Player_Damage_Temp.sql b/static/PostgreSQL/11222_tbl_TCG_MTG_Game_Round_Player_Damage_Temp.sql index 02c5869..d801bac 100644 --- a/static/PostgreSQL/11222_tbl_TCG_MTG_Game_Round_Player_Damage_Temp.sql +++ b/static/PostgreSQL/11222_tbl_TCG_MTG_Game_Round_Player_Damage_Temp.sql @@ -6,8 +6,10 @@ CREATE TABLE tcg.public.TCG_MTG_Game_Round_Player_Damage_Temp ( , round_id INT , player_id INT , received_from_commander_player_id INT - , health_change INT + , life_gain INT + , life_loss INT , commander_deaths INT + , is_eliminated BOOLEAN , active BOOLEAN , created_on TIMESTAMP , created_by_user_id INT diff --git a/static/PostgreSQL/11300_tbl_TCG_Statistic.sql b/static/PostgreSQL/11300_tbl_TCG_Statistic.sql new file mode 100644 index 0000000..f6d4628 --- /dev/null +++ b/static/PostgreSQL/11300_tbl_TCG_Statistic.sql @@ -0,0 +1,32 @@ +CREATE TABLE tcg.public.TCG_Statistic ( + statistic_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY + , entity_type_code TEXT NOT NULL + , entity_record_id TEXT NOT NULL + , name TEXT NOT NULL + , value_bool BOOLEAN + , value_float DOUBLE PRECISION + , value_interval INTERVAL + , value_text TEXT + , value_timestamp TIMESTAMP + , is_bool BOOLEAN + , is_float BOOLEAN + , is_interval BOOLEAN + , is_text BOOLEAN + , is_timestamp BOOLEAN + , display_order INT NOT NULL + , active BOOLEAN NOT NULL DEFAULT TRUE + , created_on TIMESTAMP NOT NULL + , created_by_user_id INT NOT NULL + , CONSTRAINT FK_TCG_Statistic_created_by_user_id + FOREIGN KEY (created_by_user_id) + REFERENCES tcg.public.TCG_User(user_id) + , updated_last_on TIMESTAMP NOT NULL + , updated_last_by_user_id INT NOT NULL + , CONSTRAINT FK_TCG_Statistic_updated_last_by_user_id + FOREIGN KEY (updated_last_by_user_id) + REFERENCES tcg.public.TCG_User(user_id) + , change_set_id INT NOT NULL + , CONSTRAINT FK_TCG_Statistic_change_set_id + FOREIGN KEY (change_set_id) + REFERENCES tcg.public.TCG_Change_Set(change_set_id) +); diff --git a/static/PostgreSQL/11301_tbl_TCG_Statistic_Audit.sql b/static/PostgreSQL/11301_tbl_TCG_Statistic_Audit.sql new file mode 100644 index 0000000..e3bffa4 --- /dev/null +++ b/static/PostgreSQL/11301_tbl_TCG_Statistic_Audit.sql @@ -0,0 +1,15 @@ + +CREATE TABLE tcg.public.TCG_Statistic_Audit ( + audit_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY + , statistic_id INT NOT NULL + , CONSTRAINT FK_TCG_Statistic_Audit_statistic_id + FOREIGN KEY (statistic_id) + REFERENCES tcg.public.TCG_Statistic(statistic_id) + , name_field TEXT NOT NULL + , value_prev TEXT + , value_new TEXT + , change_set_id INT NOT NULL + , CONSTRAINT FK_TCG_Statistic_Audit_change_set_id + FOREIGN KEY (change_set_id) + REFERENCES tcg.public.TCG_Change_Set(change_set_id) +); diff --git a/static/PostgreSQL/31220_tri_TCG_MTG_Game_Round_Player_Damage.sql b/static/PostgreSQL/31220_tri_TCG_MTG_Game_Round_Player_Damage.sql index b4c2085..05f79c8 100644 --- a/static/PostgreSQL/31220_tri_TCG_MTG_Game_Round_Player_Damage.sql +++ b/static/PostgreSQL/31220_tri_TCG_MTG_Game_Round_Player_Damage.sql @@ -58,9 +58,13 @@ BEGIN SELECT NEW.damage_id, 'received_from_commander_player_id', OLD.received_from_commander_player_id::TEXT, NEW.received_from_commander_player_id::TEXT, NEW.change_set_id WHERE OLD.received_from_commander_player_id IS NOT DISTINCT FROM NEW.received_from_commander_player_id UNION - -- Changed health_change - SELECT NEW.damage_id, 'health_change', OLD.health_change::TEXT, NEW.health_change::TEXT, NEW.change_set_id - WHERE OLD.health_change IS NOT DISTINCT FROM NEW.health_change + -- Changed life_gain + SELECT NEW.damage_id, 'life_gain', OLD.life_gain::TEXT, NEW.life_gain::TEXT, NEW.change_set_id + WHERE OLD.life_gain IS NOT DISTINCT FROM NEW.life_gain + UNION + -- Changed life_loss + SELECT NEW.damage_id, 'life_loss', OLD.life_loss::TEXT, NEW.life_loss::TEXT, NEW.change_set_id + WHERE OLD.life_loss IS NOT DISTINCT FROM NEW.life_loss UNION -- Changed commander_deaths SELECT NEW.damage_id, 'commander_deaths', OLD.commander_deaths::TEXT, NEW.commander_deaths::TEXT, NEW.change_set_id diff --git a/static/PostgreSQL/31300_tri_TCG_Statistic.sql b/static/PostgreSQL/31300_tri_TCG_Statistic.sql new file mode 100644 index 0000000..72e80fd --- /dev/null +++ b/static/PostgreSQL/31300_tri_TCG_Statistic.sql @@ -0,0 +1,96 @@ + +CREATE OR REPLACE FUNCTION tcg.public.FN_before_insert_TCG_Statistic() +RETURNS TRIGGER AS $$ +DECLARE + r_change_set RECORD; +BEGIN + NEW.created_on = COALESCE(NEW.created_on, CURRENT_TIMESTAMP); + NEW.updated_last_on = COALESCE(NEW.updated_last_on, CURRENT_TIMESTAMP); + + IF NEW.change_set_id IS NULL THEN + RAISE EXCEPTION 'Change Set ID must be provided.'; + END IF; + + SELECT * + INTO r_change_set + FROM tcg.public.TCG_Change_Set CHANGE_SET + WHERE NEW.change_set_id = CHANGE_SET.change_set_id + ; + + IF FOUND THEN + NEW.created_by_user_id := COALESCE(NEW.created_by_user_id, r_change_set.updated_last_by_user_id); + NEW.updated_last_by_user_id := COALESCE(NEW.updated_last_by_user_id, r_change_set.updated_last_by_user_id); + NEW.created_on := COALESCE(NEW.created_on, r_change_set.updated_last_on); + ELSE + RAISE EXCEPTION 'Change Set % not found.', NEW.change_set_id; + END IF; + + RETURN NEW; +END; +$$ LANGUAGE plpgsql +; + +CREATE OR REPLACE FUNCTION tcg.public.FN_before_update_TCG_Statistic() +RETURNS TRIGGER AS $$ +BEGIN + NEW.updated_last_on = CURRENT_TIMESTAMP; + + IF OLD.change_set_id IS NOT DISTINCT FROM NEW.change_set_id THEN + RAISE EXCEPTION 'New Change Set ID must be provided.'; + END IF; + + INSERT INTO tcg.public.TCG_Statistic_Audit ( + statistic_id + , name_field + , value_prev + , value_new + , change_set_id + ) + -- Changed entity_type_code + SELECT NEW.statistic_id, 'entity_type_code', OLD.entity_type_code, NEW.entity_type_code, NEW.change_set_id + WHERE OLD.entity_type_code IS NOT DISTINCT FROM NEW.entity_type_code + UNION + -- Changed entity_record_id + SELECT NEW.statistic_id, 'entity_record_id', OLD.entity_record_id::TEXT, NEW.entity_record_id::TEXT, NEW.change_set_id + WHERE OLD.entity_record_id IS NOT DISTINCT FROM NEW.entity_record_id + UNION + -- Changed name + SELECT NEW.statistic_id, 'name', OLD.name, NEW.name, NEW.change_set_id + WHERE OLD.name IS NOT DISTINCT FROM NEW.name + UNION + -- Changed value_bool + SELECT NEW.statistic_id, 'value_bool', OLD.value_bool::TEXT, NEW.value_bool::TEXT, NEW.change_set_id + WHERE OLD.value_bool IS NOT DISTINCT FROM NEW.value_bool + UNION + -- Changed value_float + SELECT NEW.statistic_id, 'value_float', OLD.value_float::TEXT, NEW.value_float::TEXT, NEW.change_set_id + WHERE OLD.value_float IS NOT DISTINCT FROM NEW.value_float + UNION + -- Changed value_text + SELECT NEW.statistic_id, 'value_text', OLD.value_text, NEW.value_text, NEW.change_set_id + WHERE OLD.value_text IS NOT DISTINCT FROM NEW.value_text + UNION + -- Changed value_timestamp + SELECT NEW.statistic_id, 'value_timestamp', OLD.value_timestamp::TEXT, NEW.value_timestamp::TEXT, NEW.change_set_id + WHERE OLD.value_timestamp IS NOT DISTINCT FROM NEW.value_timestamp + UNION + -- Changed active + SELECT NEW.statistic_id, 'active', OLD.active::TEXT, NEW.active::TEXT, NEW.change_set_id + WHERE OLD.active IS NOT DISTINCT FROM NEW.active + ; + + RETURN NEW; +END; +$$ LANGUAGE plpgsql +; + +CREATE TRIGGER TRI_before_insert_TCG_Statistic + BEFORE INSERT ON tcg.public.TCG_Statistic + FOR EACH ROW + EXECUTE FUNCTION tcg.public.FN_before_insert_TCG_Statistic() +; +CREATE TRIGGER TRI_before_update_TCG_Statistic + BEFORE UPDATE ON tcg.public.TCG_Statistic + FOR EACH ROW + EXECUTE FUNCTION tcg.public.FN_before_update_TCG_Statistic() +; \ No newline at end of file diff --git a/static/PostgreSQL/70505_usp_TCG_User_Login.sql b/static/PostgreSQL/70505_usp_TCG_User_Login.sql index 99b4398..afb38d4 100644 --- a/static/PostgreSQL/70505_usp_TCG_User_Login.sql +++ b/static/PostgreSQL/70505_usp_TCG_User_Login.sql @@ -35,7 +35,7 @@ BEGIN DROP TABLE IF EXISTS Temp_User_Save_User; DROP TABLE IF EXISTS Temp_User_Save_Error; - CREATE TABLE Temp_User_Save_User ( + CREATE TEMP TABLE Temp_User_Save_User ( user_id INT NOT NULL , user_auth0_id TEXT , firstname TEXT diff --git a/static/PostgreSQL/71196_fn_TCG_MTG_Deck_Commander_Bracket_Get_Many copy.sql b/static/PostgreSQL/71196_fn_TCG_MTG_Deck_Commander_Bracket_Get_Many copy.sql new file mode 100644 index 0000000..2ab0aea --- /dev/null +++ b/static/PostgreSQL/71196_fn_TCG_MTG_Deck_Commander_Bracket_Get_Many copy.sql @@ -0,0 +1,128 @@ + +CREATE OR REPLACE FUNCTION tcg.public.FN_TCG_MTG_Deck_Commander_Bracket_Get_Many ( + a_get_all_commander_bracket BOOLEAN + , a_get_inactive_commander_bracket BOOLEAN + , a_commander_bracket_ids TEXT + , a_commander_bracket_names TEXT + , a_require_all_id_filters_met BOOLEAN + , a_require_any_id_filters_met BOOLEAN + , a_require_all_non_id_filters_met BOOLEAN + , a_require_any_non_id_filters_met BOOLEAN +) +RETURNS TABLE ( + commander_bracket_id INT + , name TEXT + , description TEXT + , display_order INT + , active BOOLEAN + , created_on TIMESTAMP + , created_by_user_id INT + , updated_last_on TIMESTAMP + , updated_last_by_user_id INT + , change_set_id INT +) +LANGUAGE plpgsql +AS $$ +DECLARE + v_get_all_commander_bracket BOOLEAN; + v_get_inactive_commander_bracket BOOLEAN; + v_commander_bracket_ids TEXT; + v_commander_bracket_names TEXT; + v_require_all_id_filters_met BOOLEAN; + v_require_any_id_filters_met BOOLEAN; + v_require_all_non_id_filters_met BOOLEAN; + v_require_any_non_id_filters_met BOOLEAN; +BEGIN + v_get_all_commander_bracket := COALESCE(a_get_all_commander_bracket, TRUE); + v_get_inactive_commander_bracket := COALESCE(a_get_inactive_commander_bracket, FALSE); + v_commander_bracket_ids := TRIM(COALESCE(a_commander_bracket_ids, '')); + v_commander_bracket_names := TRIM(COALESCE(a_commander_bracket_names, '')); + v_require_all_id_filters_met := COALESCE(a_require_all_id_filters_met, FALSE); + v_require_any_id_filters_met := COALESCE(a_require_any_id_filters_met, TRUE); + v_require_all_non_id_filters_met := COALESCE(a_require_all_non_id_filters_met, FALSE); + v_require_any_non_id_filters_met := COALESCE(a_require_any_non_id_filters_met, TRUE); + + -- Outputs + RETURN QUERY SELECT + COMMANDER_BRACKET.commander_bracket_id + , COMMANDER_BRACKET.name + , COMMANDER_BRACKET.description + , COMMANDER_BRACKET.display_order + , COMMANDER_BRACKET.active + , COMMANDER_BRACKET.created_on + , COMMANDER_BRACKET.created_by_user_id + , COMMANDER_BRACKET.updated_last_on + , COMMANDER_BRACKET.updated_last_by_user_id + , COMMANDER_BRACKET.change_set_id + FROM tcg.public.TCG_MTG_Deck_Commander_Bracket COMMANDER_BRACKET + WHERE + ( + ( + NOT v_require_all_id_filters_met + AND NOT v_require_any_id_filters_met + ) + OR ( + v_require_all_id_filters_met + AND ( + v_get_all_commander_bracket + OR COMMANDER_BRACKET.commander_bracket_id = ANY(string_to_array(v_commander_bracket_ids, ',')::INT[]) + ) + ) + OR ( + NOT v_require_all_id_filters_met + AND v_require_any_id_filters_met + AND ( + v_get_all_commander_bracket + OR COMMANDER_BRACKET.commander_bracket_id = ANY(string_to_array(v_commander_bracket_ids, ',')::INT[]) + ) + ) + ) + AND ( + ( + NOT v_require_all_non_id_filters_met + AND NOT v_require_any_non_id_filters_met + ) + OR ( + v_require_all_non_id_filters_met + AND ( + v_get_all_commander_bracket + OR COMMANDER_BRACKET.name LIKE ANY (SELECT '%' || TRIM(s) || '%' FROM unnest(string_to_array(v_commander_bracket_names, ',')) s) + ) + ) + OR ( + NOT v_require_all_non_id_filters_met + AND v_require_any_non_id_filters_met + AND ( + v_get_all_commander_bracket + OR COMMANDER_BRACKET.name LIKE ANY (SELECT '%' || TRIM(s) || '%' FROM unnest(string_to_array(v_commander_bracket_names, ',')) s) + ) + ) + ) + AND ( + v_get_inactive_commander_bracket + OR COMMANDER_BRACKET.active + ) + ORDER BY COMMANDER_BRACKET.display_order + ; +END; +$$; + + +SELECT * +FROM tcg.public.FN_TCG_MTG_Deck_Commander_Bracket_Get_Many ( + a_get_all_commander_bracket := TRUE + , a_get_inactive_commander_bracket := FALSE + , a_commander_bracket_ids := CAST(NULL AS TEXT) + , a_commander_bracket_names := CAST(NULL AS TEXT) + , a_require_all_id_filters_met := FALSE + , a_require_any_id_filters_met := FALSE + , a_require_all_non_id_filters_met := FALSE + , a_require_any_non_id_filters_met := FALSE +) +; + +SELECT * +FROM tcg.public.TCG_MTG_Deck_Commander_Bracket +; + + diff --git a/static/PostgreSQL/71220_fn_TCG_MTG_Game_Round_Player_Damage_Get_Many.sql b/static/PostgreSQL/71220_fn_TCG_MTG_Game_Round_Player_Damage_Get_Many.sql index 1de1c00..df94614 100644 --- a/static/PostgreSQL/71220_fn_TCG_MTG_Game_Round_Player_Damage_Get_Many.sql +++ b/static/PostgreSQL/71220_fn_TCG_MTG_Game_Round_Player_Damage_Get_Many.sql @@ -11,7 +11,8 @@ RETURNS TABLE ( , round_id INT , player_id INT , received_from_commander_player_id INT - , health_change INT + , life_gain INT + , life_loss INT , commander_deaths INT , is_eliminated BOOLEAN , active BOOLEAN @@ -42,7 +43,8 @@ BEGIN , PLAYER_DAMAGE.round_id , PLAYER_DAMAGE.player_id , PLAYER_DAMAGE.received_from_commander_player_id - , PLAYER_DAMAGE.health_change + , PLAYER_DAMAGE.life_gain + , PLAYER_DAMAGE.life_loss , PLAYER_DAMAGE.commander_deaths , PLAYER_DAMAGE.is_eliminated , PLAYER_DAMAGE.active @@ -95,7 +97,7 @@ SELECT * FROM tcg.public.FN_TCG_MTG_Game_Round_Player_Damage_Get_Many ( a_get_all_game := FALSE , a_get_inactive_game := FALSE - , a_game_ids := '11' + , a_game_ids := '30' , a_require_all_id_filters_met := TRUE , a_require_any_id_filters_met := FALSE ) diff --git a/static/PostgreSQL/71221_usp_TCG_MTG_Game_Round_Damage_Save.sql b/static/PostgreSQL/71221_usp_TCG_MTG_Game_Round_Damage_Save.sql index dcee56a..c29d247 100644 --- a/static/PostgreSQL/71221_usp_TCG_MTG_Game_Round_Damage_Save.sql +++ b/static/PostgreSQL/71221_usp_TCG_MTG_Game_Round_Damage_Save.sql @@ -84,7 +84,8 @@ BEGIN , round_id INT , player_id INT , received_from_commander_player_id INT - , health_change INT + , life_gain INT + , life_loss INT , commander_deaths INT , is_eliminated BOOLEAN , active BOOLEAN @@ -177,7 +178,8 @@ BEGIN , round_id , player_id , received_from_commander_player_id - , health_change + , life_gain + , life_loss , commander_deaths , is_eliminated , active @@ -199,7 +201,8 @@ BEGIN , PLAYER_DAMAGE_T.round_id , PLAYER_DAMAGE_T.player_id , PLAYER_DAMAGE_T.received_from_commander_player_id - , COALESCE(PLAYER_DAMAGE_T.health_change, 0) -- health_change + , ABS(COALESCE(PLAYER_DAMAGE_T.life_gain, 0)) -- life_gain + , ABS(COALESCE(PLAYER_DAMAGE_T.life_loss, 0)) -- life_loss , COALESCE(PLAYER_DAMAGE_T.commander_deaths, 0) -- commander_deaths , COALESCE(PLAYER_DAMAGE_T.is_eliminated, FALSE) -- is_eliminated , COALESCE(PLAYER_DAMAGE_T.active, TRUE) -- active @@ -220,8 +223,10 @@ BEGIN , CAST(PLAYER_DAMAGE_T.player_id AS VARCHAR) , ', received from commander player id: ' , CAST(PLAYER_DAMAGE_T.received_from_commander_player_id AS VARCHAR) - , ', health change: ' - , CAST(PLAYER_DAMAGE_T.health_change AS VARCHAR) + , ', life gain: ' + , CAST(PLAYER_DAMAGE_T.life_gain AS VARCHAR) + , ', life loss: ' + , CAST(PLAYER_DAMAGE_T.life_loss AS VARCHAR) , ' }' ) -- error_name FROM tcg.public.TCG_MTG_Game_Round_Player_Damage_Temp PLAYER_DAMAGE_T @@ -625,18 +630,32 @@ BEGIN , 'player_id' AS field FROM Temp_MTG_Round_Damage_Save_Round_Player_Damage T_PLAYER_DAMAGE WHERE T_PLAYER_DAMAGE.player_id IS NULL + /* UNION SELECT T_PLAYER_DAMAGE.temp_id , 'health_change' AS field FROM Temp_MTG_Round_Damage_Save_Round_Player_Damage T_PLAYER_DAMAGE WHERE T_PLAYER_DAMAGE.health_change IS NULL + UNION + SELECT + T_PLAYER_DAMAGE.temp_id + , 'life_gain' AS field + FROM Temp_MTG_Round_Damage_Save_Round_Player_Damage T_PLAYER_DAMAGE + WHERE T_PLAYER_DAMAGE.life_gain IS NULL + UNION + SELECT + T_PLAYER_DAMAGE.temp_id + , 'life_loss' AS field + FROM Temp_MTG_Round_Damage_Save_Round_Player_Damage T_PLAYER_DAMAGE + WHERE T_PLAYER_DAMAGE.life_loss IS NULL UNION SELECT T_PLAYER_DAMAGE.temp_id , 'commander_deaths' AS field FROM Temp_MTG_Round_Damage_Save_Round_Player_Damage T_PLAYER_DAMAGE WHERE T_PLAYER_DAMAGE.commander_deaths IS NULL + */ ) INSERT INTO Temp_MTG_Round_Damage_Save_Error ( error_type_id @@ -910,7 +929,8 @@ BEGIN round_id , player_id , received_from_commander_player_id - , health_change + , life_gain + , life_loss , commander_deaths , is_eliminated , active @@ -924,7 +944,8 @@ BEGIN T_ROUND.round_id , T_PLAYER_DAMAGE.player_id , T_PLAYER_DAMAGE.received_from_commander_player_id - , T_PLAYER_DAMAGE.health_change + , T_PLAYER_DAMAGE.life_gain + , T_PLAYER_DAMAGE.life_loss , T_PLAYER_DAMAGE.commander_deaths , T_PLAYER_DAMAGE.is_eliminated , T_PLAYER_DAMAGE.active @@ -951,7 +972,8 @@ BEGIN round_id = T_ROUND.round_id , player_id = T_PLAYER_DAMAGE.player_id , received_from_commander_player_id = T_PLAYER_DAMAGE.received_from_commander_player_id - , health_change = T_PLAYER_DAMAGE.health_change + , life_gain = T_PLAYER_DAMAGE.life_gain + , life_loss = T_PLAYER_DAMAGE.life_loss , commander_deaths = T_PLAYER_DAMAGE.commander_deaths , is_eliminated = T_PLAYER_DAMAGE.is_eliminated , active = T_PLAYER_DAMAGE.active @@ -1098,7 +1120,9 @@ LEFT JOIN tcg.public.TCG_MTG_Game GAME ON TCG_ROUND.game_id = GAME.game_id , round_id , player_id , received_from_commander_player_id - , health_change + -- , health_change + , life_gain + , life_loss , commander_deaths , active ) @@ -1109,7 +1133,9 @@ LEFT JOIN tcg.public.TCG_MTG_Game GAME ON TCG_ROUND.game_id = GAME.game_id , -1 -- round_id , 3 -- player_id , NULL -- received_from_commander_player_id - , -4 -- health_change + -- , -4 -- health_change + , 0 -- life_gain + , 4 -- life_loss , 1 -- commander_deaths , TRUE -- active ) @@ -1119,7 +1145,9 @@ LEFT JOIN tcg.public.TCG_MTG_Game GAME ON TCG_ROUND.game_id = GAME.game_id , -1 -- round_id , 3 -- player_id , 2 -- received_from_commander_player_id - , -5 -- health_change + -- , -5 -- health_change + , 0 -- life_gain + , 5 -- life_loss , NULL -- commander_deaths , TRUE -- active ) @@ -1129,7 +1157,9 @@ LEFT JOIN tcg.public.TCG_MTG_Game GAME ON TCG_ROUND.game_id = GAME.game_id , -1 -- round_id , 3 -- player_id , 5 -- received_from_commander_player_id - , -6 -- health_change + -- , -6 -- health_change + , 0 -- life_gain + , 6 -- life_loss , NULL -- commander_deaths , TRUE -- active ) diff --git a/static/PostgreSQL/71300_fn_TCG_Statistic_Get_Many.sql b/static/PostgreSQL/71300_fn_TCG_Statistic_Get_Many.sql new file mode 100644 index 0000000..111bf66 --- /dev/null +++ b/static/PostgreSQL/71300_fn_TCG_Statistic_Get_Many.sql @@ -0,0 +1,144 @@ + +CREATE OR REPLACE FUNCTION tcg.public.FN_TCG_Statistic_Get_Many ( + a_get_all_statistic BOOLEAN + , a_get_inactive_statistic BOOLEAN + , a_statistic_ids TEXT + , a_entity_type_codes TEXT + , a_entity_record_ids TEXT + , a_require_all_id_filters_met BOOLEAN + , a_require_any_id_filters_met BOOLEAN +) +RETURNS TABLE ( + statistic_id INT + , entity_type_code TEXT + , entity_record_id TEXT + , name TEXT + , value_bool BOOLEAN + , value_float DOUBLE PRECISION + , value_interval INTERVAL + , value_text TEXT + , value_timestamp TIMESTAMP + , is_bool BOOLEAN + , is_float BOOLEAN + , is_interval BOOLEAN + , is_text BOOLEAN + , is_timestamp BOOLEAN + , display_order INT + , active BOOLEAN + , created_on TIMESTAMP + , created_by_user_id INT + , updated_last_on TIMESTAMP + , updated_last_by_user_id INT + , change_set_id INT +) +LANGUAGE plpgsql +AS $$ +DECLARE + v_get_all_statistic BOOLEAN; + v_get_inactive_statistic BOOLEAN; + v_statistic_ids TEXT; + v_entity_type_codes TEXT; + v_entity_record_ids TEXT; + v_require_all_id_filters_met BOOLEAN; + v_require_any_id_filters_met BOOLEAN; +BEGIN + v_get_all_statistic := COALESCE(a_get_all_statistic, FALSE); + v_get_inactive_statistic := COALESCE(a_get_inactive_statistic, FALSE); + v_statistic_ids := TRIM(COALESCE(a_statistic_ids, '')); + v_entity_type_codes := TRIM(COALESCE(a_entity_type_codes, '')); + v_entity_record_ids := TRIM(COALESCE(a_entity_record_ids, '')); + v_require_all_id_filters_met := COALESCE(a_require_all_id_filters_met, FALSE); + v_require_any_id_filters_met := COALESCE(a_require_any_id_filters_met, FALSE); + + -- Outputs + RETURN QUERY SELECT + STATISTIC.statistic_id + , STATISTIC.entity_type_code + , STATISTIC.entity_record_id + , STATISTIC.name + , STATISTIC.value_bool + , STATISTIC.value_float + , STATISTIC.value_interval + , STATISTIC.value_text + , STATISTIC.value_timestamp + , STATISTIC.is_bool + , STATISTIC.is_float + , STATISTIC.is_interval + , STATISTIC.is_text + , STATISTIC.is_timestamp + , STATISTIC.display_order + , STATISTIC.active + , STATISTIC.created_on + , STATISTIC.created_by_user_id + , STATISTIC.updated_last_on + , STATISTIC.updated_last_by_user_id + , STATISTIC.change_set_id + FROM tcg.public.TCG_Statistic STATISTIC + WHERE + ( + ( + NOT v_require_all_id_filters_met + AND NOT v_require_any_id_filters_met + ) + OR ( + v_require_all_id_filters_met + AND (v_get_all_statistic OR v_statistic_ids = '' OR STATISTIC.statistic_id = ANY(string_to_array(v_statistic_ids, ',')::INT[])) + AND (v_get_all_statistic OR v_entity_type_codes = '' OR STATISTIC.entity_type_code = ANY(string_to_array(v_entity_type_codes, ','))) + AND (v_get_all_statistic OR v_entity_record_ids = '' OR STATISTIC.entity_record_id = ANY(string_to_array(v_entity_record_ids, ','))) + ) + OR ( + NOT v_require_all_id_filters_met + AND v_require_any_id_filters_met + AND ( + v_get_all_statistic + OR STATISTIC.statistic_id = ANY(string_to_array(v_statistic_ids, ',')::INT[]) + OR STATISTIC.entity_type_code = ANY(string_to_array(v_entity_type_codes, ',')) + OR STATISTIC.entity_record_id = ANY(string_to_array(v_entity_record_ids, ',')) + ) + ) + ) + AND ( + v_get_inactive_statistic + OR STATISTIC.active + ) + ORDER BY + STATISTIC.entity_type_code + , STATISTIC.entity_record_id + , STATISTIC.display_order + , STATISTIC.statistic_id + ; +END; +$$; + + +SELECT * +FROM tcg.public.FN_TCG_Statistic_Get_Many ( + a_get_all_statistic := FALSE + , a_get_inactive_statistic := FALSE + , a_statistic_ids := '' + , a_entity_type_codes := 'deck' + , a_entity_record_ids := '1,2' + , a_require_all_id_filters_met := TRUE + , a_require_any_id_filters_met := TRUE +) +; + + +SELECT * +FROM tcg.public.TCG_Statistic +; + +SELECT COUNT(*) +FROM tcg.public.TCG_Statistic S +WHERE S.entity_type_code = 'deck' +; + +SELECT COUNT(*) +FROM tcg.public.TCG_Statistic S +WHERE S.entity_type_code = 'user' +; + +SELECT COUNT(*) +FROM tcg.public.TCG_Statistic S +WHERE S.entity_type_code = 'user_deck_link' +; diff --git a/static/PostgreSQL/71301_usp_TCG_Statistic_Calc.sql b/static/PostgreSQL/71301_usp_TCG_Statistic_Calc.sql new file mode 100644 index 0000000..5a12031 --- /dev/null +++ b/static/PostgreSQL/71301_usp_TCG_Statistic_Calc.sql @@ -0,0 +1,9521 @@ + +CREATE OR REPLACE PROCEDURE tcg.public.USP_TCG_Statistic_Calc ( + a_comment TEXT + , a_guid UUID + , a_user_id INT + , OUT o_success BOOLEAN +) +LANGUAGE plpgsql +AS $$ +DECLARE + v_change_set_id INT; + v_commander_damage_limit INT := 21; + v_comment TEXT; + v_deck_entity_type_code TEXT := 'deck'; + v_guid UUID; + v_no_permission_error_type_id INT; + v_time_start TIMESTAMP; + v_user_deck_link_entity_type_code TEXT := 'user_deck_link'; + v_user_entity_type_code TEXT := 'user'; + v_user_id INT; + v_warning_error_type_id INT; +BEGIN + v_comment = TRIM(COALESCE(a_comment, '')); + v_guid = a_guid; + v_user_id = a_user_id; + + v_no_permission_error_type_id := (SELECT ERROR_TYPE.error_type_id FROM tcg.public.Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = 'NO_PERMISSION' LIMIT 1); + v_time_start := CURRENT_TIMESTAMP; + v_warning_error_type_id := (SELECT ERROR_TYPE.error_type_id FROM tcg.public.Error_Type ERROR_TYPE WHERE ERROR_TYPE.code = 'WARNING' LIMIT 1); + + DROP TABLE IF EXISTS Temp_Statistic_Calc_Statistic; + DROP TABLE IF EXISTS Temp_Statistic_Calc_Deck; + DROP TABLE IF EXISTS Temp_Statistic_Calc_Game; + DROP TABLE IF EXISTS Temp_Statistic_Calc_Player; + DROP TABLE IF EXISTS Temp_Statistic_Calc_User; + DROP TABLE IF EXISTS Temp_Statistic_Calc_User_Deck_Link; + DROP TABLE IF EXISTS Temp_Statistic_Calc_Round; + DROP TABLE IF EXISTS Temp_Statistic_Calc_Round_Player_Damage; + DROP TABLE IF EXISTS Temp_Statistic_Calc_Player_Round_Link; + DROP TABLE IF EXISTS Temp_Statistic_Calc_Error; + + CREATE TEMP TABLE Temp_Statistic_Calc_Statistic ( + temp_statistic_id INT GENERATED ALWAYS AS IDENTITY + , entity_type_code TEXT + , entity_record_id TEXT + , name TEXT NOT NULL + , value_bool BOOLEAN + , value_float DOUBLE PRECISION + , value_interval INTERVAL + , value_text TEXT + , value_timestamp TIMESTAMP + , is_bool BOOLEAN + , is_float BOOLEAN + , is_interval BOOLEAN + , is_text BOOLEAN + , is_timestamp BOOLEAN + , active BOOLEAN + ); + + CREATE TEMP TABLE Temp_Statistic_Calc_Deck ( + deck_id INT NOT NULL + , name TEXT + , is_commander BOOLEAN + , commander_bracket_id INT + , active BOOLEAN + , created_on TIMESTAMP + , created_by_user_id INT + , updated_last_on TIMESTAMP + , updated_last_by_user_id INT + , change_set_id INT + + , count_games INT + , count_games_won INT + , count_games_lost INT + , win_lose_ratio FLOAT + , best_position INT + , worst_position INT + , total_damage_received INT + , mean_total_damage_received FLOAT + , max_total_damage_received INT + , min_total_damage_received INT + , total_damage_received_game_win INT + , mean_total_damage_received_game_win FLOAT + , max_total_damage_received_game_win INT + , min_total_damage_received_game_win INT + , total_damage_received_game_lose INT + , mean_total_damage_received_game_lose FLOAT + , max_total_damage_received_game_lose INT + , min_total_damage_received_game_lose INT + , total_commander_damage_dealt INT + , mean_total_commander_damage_dealt FLOAT + , max_total_commander_damage_dealt INT + , min_total_commander_damage_dealt INT + , total_commander_damage_dealt_game_won INT + , mean_total_commander_damage_dealt_won FLOAT + , max_total_commander_damage_dealt_won INT + , min_total_commander_damage_dealt_won INT + , total_commander_damage_dealt_game_lost INT + , mean_total_commander_damage_dealt_lost FLOAT + , max_total_commander_damage_dealt_lost INT + , min_total_commander_damage_dealt_lost INT + , total_commander_damage_received INT + , mean_total_commander_damage_received FLOAT + , max_total_commander_damage_received INT + , min_total_commander_damage_received INT + , total_commander_damage_received_game_won INT + , mean_total_commander_damage_received_won FLOAT + , max_total_commander_damage_received_won INT + , min_total_commander_damage_received_won INT + , total_commander_damage_received_game_lost INT + , mean_total_commander_damage_received_lost FLOAT + , max_total_commander_damage_received_lost INT + , min_total_commander_damage_received_lost INT + , total_life_gained INT + , mean_total_life_gained FLOAT + , max_total_life_gained INT + , min_total_life_gained INT + , total_life_gained_game_won INT + , mean_total_life_gained_game_won FLOAT + , max_total_life_gained_game_won INT + , min_total_life_gained_game_won INT + , total_life_gained_game_lost INT + , mean_total_life_gained_game_lost FLOAT + , max_total_life_gained_game_lost INT + , min_total_life_gained_game_lost INT + , total_game_round_count INT + , mean_game_round_count FLOAT + , lowest_game_round_count INT + , highest_game_round_count INT + , total_game_win_round_count INT + , mean_game_win_round_count FLOAT + , lowest_game_win_round_count INT + , highest_game_win_round_count INT + , total_game_lose_round_count INT + , mean_game_lose_round_count FLOAT + , lowest_game_lose_round_count INT + , highest_game_lose_round_count INT + , total_game_round_survived_count INT + , mean_game_round_survived_count FLOAT + , lowest_game_round_survived_count INT + , highest_game_round_survived_count INT + , total_game_win_round_survived_count INT + , mean_game_win_round_survived_count FLOAT + , lowest_game_win_round_survived_count INT + , highest_game_win_round_survived_count INT + , total_game_lose_round_survived_count INT + , mean_game_lose_round_survived_count FLOAT + , lowest_game_lose_round_survived_count INT + , highest_game_lose_round_survived_count INT + , total_game_duration INTERVAL + , mean_game_duration INTERVAL + , shortest_game_duration INTERVAL + , longest_game_duration INTERVAL + , total_game_win_duration INTERVAL + , mean_game_win_duration INTERVAL + , shortest_game_win_duration INTERVAL + , longest_game_win_duration INTERVAL + , total_game_lose_duration INTERVAL + , mean_game_lose_duration INTERVAL + , shortest_game_lose_duration INTERVAL + , longest_game_lose_duration INTERVAL + , total_commander_deaths INT + , mean_commander_deaths FLOAT + , max_commander_deaths INT + , min_commander_deaths INT + , total_commander_deaths_game_won INT + , mean_commander_deaths_game_won FLOAT + , max_commander_deaths_game_won INT + , min_commander_deaths_game_won INT + , total_commander_deaths_game_lost INT + , mean_commander_deaths_game_lost FLOAT + , max_commander_deaths_game_lost INT + , min_commander_deaths_game_lost INT + , total_pod_sizes INT + , total_opponents_faced INT + , mean_pod_size FLOAT + , max_pod_size INT + , min_pod_size INT + , total_pod_sizes_won INT + , total_opponents_beaten INT + , mean_pod_size_won FLOAT + , max_pod_size_won INT + , min_pod_size_won INT + , total_pod_sizes_lost INT + , total_opponents_lost_to INT + , mean_pod_size_lost FLOAT + , max_pod_size_lost INT + , min_pod_size_lost INT + , latest_game_win_on TIMESTAMP + , latest_game_win_pod_size INT + , latest_game_lose_on TIMESTAMP + , latest_game_lose_pod_size INT + , archenemy_deck_id INT + , rival_deck_id INT + , archenemy_player_id INT + , rival_player_id INT + ); + + CREATE TEMP TABLE Temp_Statistic_Calc_Game ( + game_id INT NOT NULL + , notes TEXT + , is_commander BOOLEAN + , is_draft BOOLEAN + , is_sealed BOOLEAN + , location_name TEXT + , start_on TIMESTAMP + , end_on TIMESTAMP + , starting_life INT + , active BOOLEAN + , created_on TIMESTAMP + , created_by_user_id INT + , updated_last_on TIMESTAMP + , updated_last_by_user_id INT + , change_set_id INT + + , max_round_display_order INT + , count_players INT + , duration INTERVAL + ); + + CREATE TEMP TABLE Temp_Statistic_Calc_Player ( + player_id INT + , game_id INT + , user_id INT + , deck_id INT + , name TEXT + , notes TEXT + , display_order INT + , active BOOLEAN + + , round_display_order_eliminated INT + , final_player_damage_round_id INT + , placement INT + , max_total_commander_damage_received INT + , total_commander_damage_dealt INT + , total_damage_received INT + , total_life_gained INT + , total_commander_deaths INT + ); + + CREATE TEMP TABLE Temp_Statistic_Calc_User ( + user_id INT NOT NULL + , user_auth0_id TEXT + , firstname TEXT + , surname TEXT + , email TEXT + , is_email_verified BOOLEAN + , is_super_user BOOLEAN + , active BOOLEAN + , created_on TIMESTAMP + , created_by_user_id INT + , updated_last_on TIMESTAMP + , updated_last_by_user_id INT + , change_set_id INT + + , count_games INT + , count_games_won INT + , count_games_lost INT + , win_lose_ratio FLOAT + , best_position INT + , worst_position INT + , total_damage_received INT + , mean_total_damage_received FLOAT + , max_total_damage_received INT + , min_total_damage_received INT + , total_damage_received_game_win INT + , mean_total_damage_received_game_win FLOAT + , max_total_damage_received_game_win INT + , min_total_damage_received_game_win INT + , total_damage_received_game_lose INT + , mean_total_damage_received_game_lose FLOAT + , max_total_damage_received_game_lose INT + , min_total_damage_received_game_lose INT + , total_commander_damage_dealt INT + , mean_total_commander_damage_dealt FLOAT + , max_total_commander_damage_dealt INT + , min_total_commander_damage_dealt INT + , total_commander_damage_dealt_game_won INT + , mean_total_commander_damage_dealt_won FLOAT + , max_total_commander_damage_dealt_won INT + , min_total_commander_damage_dealt_won INT + , total_commander_damage_dealt_game_lost INT + , mean_total_commander_damage_dealt_lost FLOAT + , max_total_commander_damage_dealt_lost INT + , min_total_commander_damage_dealt_lost INT + , total_commander_damage_received INT + , mean_total_commander_damage_received FLOAT + , max_total_commander_damage_received INT + , min_total_commander_damage_received INT + , total_commander_damage_received_game_won INT + , mean_total_commander_damage_received_won FLOAT + , max_total_commander_damage_received_won INT + , min_total_commander_damage_received_won INT + , total_commander_damage_received_game_lost INT + , mean_total_commander_damage_received_lost FLOAT + , max_total_commander_damage_received_lost INT + , min_total_commander_damage_received_lost INT + , total_life_gained INT + , mean_total_life_gained FLOAT + , max_total_life_gained INT + , min_total_life_gained INT + , total_life_gained_game_won INT + , mean_total_life_gained_game_won FLOAT + , max_total_life_gained_game_won INT + , min_total_life_gained_game_won INT + , total_life_gained_game_lost INT + , mean_total_life_gained_game_lost FLOAT + , max_total_life_gained_game_lost INT + , min_total_life_gained_game_lost INT + , total_game_round_count INT + , mean_game_round_count FLOAT + , lowest_game_round_count INT + , highest_game_round_count INT + , total_game_win_round_count INT + , mean_game_win_round_count FLOAT + , lowest_game_win_round_count INT + , highest_game_win_round_count INT + , total_game_lose_round_count INT + , mean_game_lose_round_count FLOAT + , lowest_game_lose_round_count INT + , highest_game_lose_round_count INT + , total_game_round_survived_count INT + , mean_game_round_survived_count FLOAT + , lowest_game_round_survived_count INT + , highest_game_round_survived_count INT + , total_game_win_round_survived_count INT + , mean_game_win_round_survived_count FLOAT + , lowest_game_win_round_survived_count INT + , highest_game_win_round_survived_count INT + , total_game_lose_round_survived_count INT + , mean_game_lose_round_survived_count FLOAT + , lowest_game_lose_round_survived_count INT + , highest_game_lose_round_survived_count INT + , total_game_duration INTERVAL + , mean_game_duration INTERVAL + , shortest_game_duration INTERVAL + , longest_game_duration INTERVAL + , total_game_win_duration INTERVAL + , mean_game_win_duration INTERVAL + , shortest_game_win_duration INTERVAL + , longest_game_win_duration INTERVAL + , total_game_lose_duration INTERVAL + , mean_game_lose_duration INTERVAL + , shortest_game_lose_duration INTERVAL + , longest_game_lose_duration INTERVAL + , total_commander_deaths INT + , mean_commander_deaths FLOAT + , max_commander_deaths INT + , min_commander_deaths INT + , total_commander_deaths_game_won INT + , mean_commander_deaths_game_won FLOAT + , max_commander_deaths_game_won INT + , min_commander_deaths_game_won INT + , total_commander_deaths_game_lost INT + , mean_commander_deaths_game_lost FLOAT + , max_commander_deaths_game_lost INT + , min_commander_deaths_game_lost INT + , total_pod_sizes INT + , total_opponents_faced INT + , mean_pod_size FLOAT + , max_pod_size INT + , min_pod_size INT + , total_pod_sizes_won INT + , total_opponents_beaten INT + , mean_pod_size_won FLOAT + , max_pod_size_won INT + , min_pod_size_won INT + , total_pod_sizes_lost INT + , total_opponents_lost_to INT + , mean_pod_size_lost FLOAT + , max_pod_size_lost INT + , min_pod_size_lost INT + , latest_game_win_on TIMESTAMP + , latest_game_win_pod_size INT + , latest_game_lose_on TIMESTAMP + , latest_game_lose_pod_size INT + , archenemy_deck_id INT + , rival_deck_id INT + , archenemy_player_id INT + , rival_player_id INT + ); + + CREATE TEMP TABLE Temp_Statistic_Calc_User_Deck_Link ( + user_id INT NOT NULL + , deck_id INT NOT NULL + + , count_games INT + , count_games_won INT + , count_games_lost INT + , win_lose_ratio FLOAT + /* + , mean_mulligan_count INT + , max_mulligan_count INT + , min_mulligan_count INT + */ + , best_position INT + , worst_position INT + , total_damage_received INT + , mean_total_damage_received FLOAT + , max_total_damage_received INT + , min_total_damage_received INT + , total_damage_received_game_win INT + , mean_total_damage_received_game_win FLOAT + , max_total_damage_received_game_win INT + , min_total_damage_received_game_win INT + , total_damage_received_game_lose INT + , mean_total_damage_received_game_lose FLOAT + , max_total_damage_received_game_lose INT + , min_total_damage_received_game_lose INT + , total_commander_damage_dealt INT + , mean_total_commander_damage_dealt FLOAT + , max_total_commander_damage_dealt INT + , min_total_commander_damage_dealt INT + , total_commander_damage_dealt_game_won INT + , mean_total_commander_damage_dealt_won FLOAT + , max_total_commander_damage_dealt_won INT + , min_total_commander_damage_dealt_won INT + , total_commander_damage_dealt_game_lost INT + , mean_total_commander_damage_dealt_lost FLOAT + , max_total_commander_damage_dealt_lost INT + , min_total_commander_damage_dealt_lost INT + , total_commander_damage_received INT + , mean_total_commander_damage_received FLOAT + , max_total_commander_damage_received INT + , min_total_commander_damage_received INT + , total_commander_damage_received_game_won INT + , mean_total_commander_damage_received_won FLOAT + , max_total_commander_damage_received_won INT + , min_total_commander_damage_received_won INT + , total_commander_damage_received_game_lost INT + , mean_total_commander_damage_received_lost FLOAT + , max_total_commander_damage_received_lost INT + , min_total_commander_damage_received_lost INT + , total_life_gained INT + , mean_total_life_gained FLOAT + , max_total_life_gained INT + , min_total_life_gained INT + , total_life_gained_game_won INT + , mean_total_life_gained_game_won FLOAT + , max_total_life_gained_game_won INT + , min_total_life_gained_game_won INT + , total_life_gained_game_lost INT + , mean_total_life_gained_game_lost FLOAT + , max_total_life_gained_game_lost INT + , min_total_life_gained_game_lost INT + , total_game_round_count INT + , mean_game_round_count FLOAT + , lowest_game_round_count INT + , highest_game_round_count INT + , total_game_win_round_count INT + , mean_game_win_round_count FLOAT + , lowest_game_win_round_count INT + , highest_game_win_round_count INT + , total_game_lose_round_count INT + , mean_game_lose_round_count FLOAT + , lowest_game_lose_round_count INT + , highest_game_lose_round_count INT + , total_game_round_survived_count INT + , mean_game_round_survived_count FLOAT + , lowest_game_round_survived_count INT + , highest_game_round_survived_count INT + , total_game_win_round_survived_count INT + , mean_game_win_round_survived_count FLOAT + , lowest_game_win_round_survived_count INT + , highest_game_win_round_survived_count INT + , total_game_lose_round_survived_count INT + , mean_game_lose_round_survived_count FLOAT + , lowest_game_lose_round_survived_count INT + , highest_game_lose_round_survived_count INT + , total_game_duration INTERVAL + , mean_game_duration INTERVAL + , shortest_game_duration INTERVAL + , longest_game_duration INTERVAL + , total_game_win_duration INTERVAL + , mean_game_win_duration INTERVAL + , shortest_game_win_duration INTERVAL + , longest_game_win_duration INTERVAL + , total_game_lose_duration INTERVAL + , mean_game_lose_duration INTERVAL + , shortest_game_lose_duration INTERVAL + , longest_game_lose_duration INTERVAL + , total_commander_deaths INT + , mean_commander_deaths FLOAT + , max_commander_deaths INT + , min_commander_deaths INT + , total_commander_deaths_game_won INT + , mean_commander_deaths_game_won FLOAT + , max_commander_deaths_game_won INT + , min_commander_deaths_game_won INT + , total_commander_deaths_game_lost INT + , mean_commander_deaths_game_lost FLOAT + , max_commander_deaths_game_lost INT + , min_commander_deaths_game_lost INT + , total_pod_sizes INT + , total_opponents_faced INT + , mean_pod_size FLOAT + , max_pod_size INT + , min_pod_size INT + , total_pod_sizes_won INT + , total_opponents_beaten INT + , mean_pod_size_won FLOAT + , max_pod_size_won INT + , min_pod_size_won INT + , total_pod_sizes_lost INT + , total_opponents_lost_to INT + , mean_pod_size_lost FLOAT + , max_pod_size_lost INT + , min_pod_size_lost INT + , latest_game_win_on TIMESTAMP + , latest_game_win_pod_size INT + , latest_game_lose_on TIMESTAMP + , latest_game_lose_pod_size INT + , archenemy_deck_id INT + , rival_deck_id INT + , archenemy_player_id INT + , rival_player_id INT + -- total starting life + -- total different opponents, decks faced + ); + + CREATE TEMP TABLE Temp_Statistic_Calc_Round ( + round_id INT + , game_id INT + , notes TEXT + , display_order INT + , active BOOLEAN + , created_on TIMESTAMP + , created_by_user_id INT + , updated_last_on TIMESTAMP + , updated_last_by_user_id INT + , change_set_id INT + ); + + CREATE TEMP TABLE Temp_Statistic_Calc_Round_Player_Damage ( + damage_id INT + , temp_round_id INT + , round_id INT + , player_id INT + , received_from_commander_player_id INT + , life_gain INT + , life_loss INT + , commander_deaths INT + , is_eliminated BOOLEAN + , active BOOLEAN + , created_on TIMESTAMP + , created_by_user_id INT + , updated_last_on TIMESTAMP + , updated_last_by_user_id INT + , change_set_id INT + ); + + CREATE TEMP TABLE Temp_Statistic_Calc_Player_Round_Link ( + game_id INT + , player_id INT + , round_id INT + + , is_eliminated BOOLEAN + , max_total_commander_damage_received INT + , total_commander_damage_dealt INT + , total_damage_received INT + , total_commander_deaths INT + , total_life_gained INT + ); + + CREATE TEMP TABLE Temp_Statistic_Calc_Error ( + temp_id INT GENERATED ALWAYS AS IDENTITY + , error_type_id INT + , message TEXT + ); + + IF NOT EXISTS (SELECT * FROM tcg.public.TCG_User TCG_USER WHERE TCG_USER.user_id = v_user_id LIMIT 1) THEN + INSERT INTO Temp_Statistic_Calc_Error ( + error_type_id + , message + ) + VALUES ( + v_no_permission_error_type_id -- error_type_id + , CONCAT( + 'User does not exist: ' + , CAST(v_user_id AS VARCHAR) + , '.' + ) -- message + ); + END IF; + + IF v_user_id <> 3 THEN + INSERT INTO Temp_Statistic_Calc_Error ( + error_type_id + , message + ) + VALUES ( + v_no_permission_error_type_id -- error_type_id + , 'No access.' -- message + ); + END IF; + + INSERT INTO Temp_Statistic_Calc_Game ( + game_id + , notes + , is_commander + , is_draft + , is_sealed + , location_name + , start_on + , end_on + , starting_life + , active + , created_on + , created_by_user_id + , updated_last_on + , updated_last_by_user_id + , change_set_id + ) + SELECT + GAME.game_id + , GAME.notes + , GAME.is_commander + , GAME.is_draft + , GAME.is_sealed + , GAME.location_name + , GAME.start_on + , GAME.end_on + , GAME.starting_life + , GAME.active + , GAME.created_on + , GAME.created_by_user_id + , GAME.updated_last_on + , GAME.updated_last_by_user_id + , GAME.change_set_id + FROM tcg.public.TCG_MTG_Game GAME + WHERE GAME.active + ; + + INSERT INTO Temp_Statistic_Calc_Round ( + round_id + , game_id + , notes + , display_order + , active + , created_on + , created_by_user_id + , updated_last_on + , updated_last_by_user_id + , change_set_id + ) + SELECT + TCG_ROUND.round_id + , TCG_ROUND.game_id + , TCG_ROUND.notes + , TCG_ROUND.display_order + , TCG_ROUND.active + , TCG_ROUND.created_on + , TCG_ROUND.created_by_user_id + , TCG_ROUND.updated_last_on + , TCG_ROUND.updated_last_by_user_id + , TCG_ROUND.change_set_id + FROM tcg.public.TCG_MTG_Game_Round TCG_ROUND + INNER JOIN Temp_Statistic_Calc_Game T_GAME ON TCG_ROUND.game_id = T_GAME.game_id + WHERE TCG_ROUND.active + ; + + INSERT INTO Temp_Statistic_Calc_Player ( + player_id + , game_id + , user_id + , deck_id + , name + , notes + , display_order + , active + ) + SELECT + PLAYER.player_id + , PLAYER.game_id + , PLAYER.user_id + , PLAYER.deck_id + , PLAYER.name + , PLAYER.notes + , PLAYER.display_order + , PLAYER.active + FROM tcg.public.TCG_MTG_Game_Player PLAYER + INNER JOIN Temp_Statistic_Calc_Game T_GAME ON PLAYER.game_id = T_GAME.game_id + INNER JOIN tcg.public.TCG_User TCG_USER + ON PLAYER.user_id = TCG_USER.user_id + AND TCG_USER.active + WHERE PLAYER.active + ; + + INSERT INTO Temp_Statistic_Calc_Round_Player_Damage ( + damage_id + , round_id + , player_id + , received_from_commander_player_id + , life_gain + , life_loss + , commander_deaths + , is_eliminated + , active + , created_on + , created_by_user_id + , updated_last_on + , updated_last_by_user_id + , change_set_id + ) + SELECT + PLAYER_DAMAGE.damage_id + , PLAYER_DAMAGE.round_id + , PLAYER_DAMAGE.player_id + , PLAYER_DAMAGE.received_from_commander_player_id + , PLAYER_DAMAGE.life_gain + , PLAYER_DAMAGE.life_loss + , PLAYER_DAMAGE.commander_deaths + , PLAYER_DAMAGE.is_eliminated + , PLAYER_DAMAGE.active + , PLAYER_DAMAGE.created_on + , PLAYER_DAMAGE.created_by_user_id + , PLAYER_DAMAGE.updated_last_on + , PLAYER_DAMAGE.updated_last_by_user_id + , PLAYER_DAMAGE.change_set_id + FROM tcg.public.TCG_MTG_Game_Round_Player_Damage PLAYER_DAMAGE + INNER JOIN Temp_Statistic_Calc_Round T_ROUND ON PLAYER_DAMAGE.round_id = T_ROUND.round_id + INNER JOIN Temp_Statistic_Calc_Player T_PLAYER ON PLAYER_DAMAGE.player_id = T_PLAYER.player_id + WHERE PLAYER_DAMAGE.active + ; + + INSERT INTO Temp_Statistic_Calc_User ( + user_id + , user_auth0_id + , firstname + , surname + , email + , is_email_verified + , is_super_user + , active + , created_on + , created_by_user_id + , updated_last_on + , updated_last_by_user_id + , change_set_id + ) + SELECT DISTINCT + TCG_USER.user_id + , TCG_USER.user_auth0_id + , TCG_USER.firstname + , TCG_USER.surname + , TCG_USER.email + , TCG_USER.is_email_verified + , TCG_USER.is_super_user + , TCG_USER.active + , TCG_USER.created_on + , TCG_USER.created_by_user_id + , TCG_USER.updated_last_on + , TCG_USER.updated_last_by_user_id + , TCG_USER.change_set_id + FROM tcg.public.TCG_User TCG_USER + INNER JOIN Temp_Statistic_Calc_Player T_PLAYER ON TCG_USER.user_id = T_PLAYER.user_id + ; + + INSERT INTO Temp_Statistic_Calc_Deck ( + deck_id + , name + , is_commander + , commander_bracket_id + , active + , created_on + , created_by_user_id + , updated_last_on + , updated_last_by_user_id + , change_set_id + ) + SELECT DISTINCT + DECK.deck_id + , DECK.name + , DECK.is_commander + , DECK.commander_bracket_id + , DECK.active + , DECK.created_on + , DECK.created_by_user_id + , DECK.updated_last_on + , DECK.updated_last_by_user_id + , DECK.change_set_id + FROM tcg.public.TCG_MTG_Deck DECK + INNER JOIN Temp_Statistic_Calc_Player T_PLAYER ON DECK.deck_id = T_PLAYER.deck_id + WHERE DECK.active + ; + + -- Statistics + WITH + Game_Length AS ( + SELECT + T_GAME.game_id + , MAX(T_ROUND.display_order) AS max_round_display_order + FROM Temp_Statistic_Calc_Game T_GAME + INNER JOIN Temp_Statistic_Calc_Round T_ROUND + ON T_GAME.game_id = T_ROUND.game_id + AND T_ROUND.active + GROUP BY T_GAME.game_id + ) + , Game_Size AS ( + SELECT + T_GAME.game_id + , COUNT(*) AS count_players + FROM Temp_Statistic_Calc_Game T_GAME + INNER JOIN Temp_Statistic_Calc_Player T_PLAYER + ON T_GAME.game_id = T_PLAYER.game_id + AND T_PLAYER.active + GROUP BY T_GAME.game_id + ) + , Game_Combined AS ( + SELECT + T_GAME.game_id + , GAME_LENGTH.max_round_display_order + , GAME_SIZE.count_players + FROM Temp_Statistic_Calc_Game T_GAME + LEFT JOIN Game_Length GAME_LENGTH ON T_GAME.game_id = GAME_LENGTH.game_id + LEFT JOIN Game_Size GAME_SIZE ON T_GAME.game_id = GAME_SIZE.game_id + ) + UPDATE Temp_Statistic_Calc_Game T_GAME + SET + max_round_display_order = COALESCE(GAME_COMBINED.max_round_display_order, 0) + , count_players = COALESCE(GAME_COMBINED.count_players, 0) + , duration = CASE + WHEN + T_GAME.start_on IS NOT NULL + AND T_GAME.end_on IS NOT NULL + THEN T_GAME.end_on - T_GAME.start_on + ELSE NULL + END + FROM Game_Combined GAME_COMBINED + WHERE T_GAME.game_id = GAME_COMBINED.game_id + ; + + WITH + All_Player_Round AS ( + SELECT + T_ROUND.game_id + , T_PLAYER.player_id + , T_ROUND.round_id + FROM Temp_Statistic_Calc_Round T_ROUND + -- INNER JOIN Temp_Statistic_Calc_Game T_GAME ON T_ROUND.game_id = T_GAME.game_id + INNER JOIN Temp_Statistic_Calc_Player T_PLAYER ON T_ROUND.game_id = T_PLAYER.game_id + ) + , Player_Round_Commander_Damage_Received AS ( + SELECT + ALL_PLAYER_ROUND.game_id + , ALL_PLAYER_ROUND.player_id + , ALL_PLAYER_ROUND.round_id + + , SUM(T_PLAYER_DAMAGE.life_loss) AS total_commander_damage_received + FROM All_Player_Round ALL_PLAYER_ROUND + INNER JOIN Temp_Statistic_Calc_Round T_ROUND_PLAYER ON ALL_PLAYER_ROUND.round_id = T_ROUND_PLAYER.round_id + INNER JOIN Temp_Statistic_Calc_Round T_ROUND_DAMAGE + ON T_ROUND_PLAYER.game_id = T_ROUND_DAMAGE.game_id + AND T_ROUND_PLAYER.display_order >= T_ROUND_DAMAGE.display_order + INNER JOIN Temp_Statistic_Calc_Round_Player_Damage T_PLAYER_DAMAGE + ON T_ROUND_DAMAGE.round_id = T_PLAYER_DAMAGE.round_id + AND T_PLAYER_DAMAGE.received_from_commander_player_id IS NOT NULL + GROUP BY + ALL_PLAYER_ROUND.game_id + , ALL_PLAYER_ROUND.player_id + , ALL_PLAYER_ROUND.round_id + -- , ALL_PLAYER_ROUND.received_from_commander_player_id + ) + , Player_Round_Max_Commander_Damage_Received AS ( + SELECT + PLAYER_ROUND_COMMANDER_DAMAGE_IN.game_id + , PLAYER_ROUND_COMMANDER_DAMAGE_IN.player_id + , PLAYER_ROUND_COMMANDER_DAMAGE_IN.round_id + + , MAX(PLAYER_ROUND_COMMANDER_DAMAGE_IN.total_commander_damage_received) AS max_total_commander_damage_received + FROM Player_Round_Commander_Damage_Received PLAYER_ROUND_COMMANDER_DAMAGE_IN + GROUP BY + PLAYER_ROUND_COMMANDER_DAMAGE_IN.game_id + , PLAYER_ROUND_COMMANDER_DAMAGE_IN.player_id + , PLAYER_ROUND_COMMANDER_DAMAGE_IN.round_id + ) + , Player_Round_Total_Commander_Damage_Dealt AS ( + SELECT + ALL_PLAYER_ROUND.game_id + , ALL_PLAYER_ROUND.player_id + , ALL_PLAYER_ROUND.round_id + + , SUM(T_PLAYER_DAMAGE.life_loss) AS total_commander_damage_dealt + FROM All_Player_Round ALL_PLAYER_ROUND + INNER JOIN Temp_Statistic_Calc_Round T_ROUND_PLAYER ON ALL_PLAYER_ROUND.round_id = T_ROUND_PLAYER.round_id + INNER JOIN Temp_Statistic_Calc_Round T_ROUND_DAMAGE + -- ON ALL_PLAYER_ROUND.round_id = T_ROUND_DAMAGE.round_id + ON T_ROUND_PLAYER.game_id = T_ROUND_DAMAGE.game_id + AND T_ROUND_PLAYER.display_order >= T_ROUND_DAMAGE.display_order + INNER JOIN Temp_Statistic_Calc_Round_Player_Damage T_PLAYER_DAMAGE + ON T_ROUND_DAMAGE.round_id = T_PLAYER_DAMAGE.round_id + AND T_PLAYER_DAMAGE.received_from_commander_player_id = ALL_PLAYER_ROUND.player_id + GROUP BY + ALL_PLAYER_ROUND.game_id + , ALL_PLAYER_ROUND.player_id + , ALL_PLAYER_ROUND.round_id + ) + , Player_Round_Damage AS ( + SELECT + ALL_PLAYER_ROUND.game_id + , ALL_PLAYER_ROUND.player_id + , ALL_PLAYER_ROUND.round_id + + , SUM(T_PLAYER_DAMAGE.life_loss) AS total_damage_received + FROM All_Player_Round ALL_PLAYER_ROUND + INNER JOIN Temp_Statistic_Calc_Round T_ROUND_PLAYER ON ALL_PLAYER_ROUND.round_id = T_ROUND_PLAYER.round_id + INNER JOIN Temp_Statistic_Calc_Round T_ROUND_DAMAGE + -- ON ALL_PLAYER_ROUND.round_id = T_ROUND_DAMAGE.round_id + ON T_ROUND_PLAYER.game_id = T_ROUND_DAMAGE.game_id + AND T_ROUND_PLAYER.display_order >= T_ROUND_DAMAGE.display_order + INNER JOIN Temp_Statistic_Calc_Round_Player_Damage T_PLAYER_DAMAGE + ON T_ROUND_DAMAGE.round_id = T_PLAYER_DAMAGE.round_id + AND T_PLAYER_DAMAGE.life_loss > 0 + GROUP BY + ALL_PLAYER_ROUND.game_id + , ALL_PLAYER_ROUND.player_id + , ALL_PLAYER_ROUND.round_id + ) + , Player_Round_Eliminated AS ( + SELECT + ALL_PLAYER_ROUND.game_id + , ALL_PLAYER_ROUND.player_id + , ALL_PLAYER_ROUND.round_id + + , BOOL_OR(T_PLAYER_DAMAGE.is_eliminated) AS is_eliminated + , SUM(T_PLAYER_DAMAGE.commander_deaths) AS total_commander_deaths + FROM All_Player_Round ALL_PLAYER_ROUND + INNER JOIN Temp_Statistic_Calc_Round T_ROUND_PLAYER ON ALL_PLAYER_ROUND.round_id = T_ROUND_PLAYER.round_id + INNER JOIN Temp_Statistic_Calc_Round T_ROUND_DAMAGE + ON T_ROUND_PLAYER.game_id = T_ROUND_DAMAGE.game_id + AND T_ROUND_PLAYER.display_order >= T_ROUND_DAMAGE.display_order + INNER JOIN Temp_Statistic_Calc_Round_Player_Damage T_PLAYER_DAMAGE + ON T_ROUND_DAMAGE.round_id = T_PLAYER_DAMAGE.round_id + GROUP BY + ALL_PLAYER_ROUND.game_id + , ALL_PLAYER_ROUND.player_id + , ALL_PLAYER_ROUND.round_id + ) + , Player_Round_Total_Life AS ( + SELECT + ALL_PLAYER_ROUND.game_id + , ALL_PLAYER_ROUND.player_id + , ALL_PLAYER_ROUND.round_id + + , SUM(T_PLAYER_DAMAGE.life_gain) AS total_life_gained + FROM All_Player_Round ALL_PLAYER_ROUND + INNER JOIN Temp_Statistic_Calc_Round T_ROUND_PLAYER ON ALL_PLAYER_ROUND.round_id = T_ROUND_PLAYER.round_id + INNER JOIN Temp_Statistic_Calc_Round T_ROUND_DAMAGE + -- ON ALL_PLAYER_ROUND.round_id = T_ROUND_DAMAGE.round_id + ON T_ROUND_PLAYER.game_id = T_ROUND_DAMAGE.game_id + AND T_ROUND_PLAYER.display_order >= T_ROUND_DAMAGE.display_order + INNER JOIN Temp_Statistic_Calc_Round_Player_Damage T_PLAYER_DAMAGE + ON T_ROUND_DAMAGE.round_id = T_PLAYER_DAMAGE.round_id + AND T_PLAYER_DAMAGE.life_gain > 0 + GROUP BY + ALL_PLAYER_ROUND.game_id + , ALL_PLAYER_ROUND.player_id + , ALL_PLAYER_ROUND.round_id + ) + INSERT INTO Temp_Statistic_Calc_Player_Round_Link ( + game_id + , player_id + , round_id + + , max_total_commander_damage_received + , total_commander_damage_dealt + , total_damage_received + , is_eliminated + , total_commander_deaths + , total_life_gained + ) + SELECT + ALL_PLAYER_ROUND.game_id + , ALL_PLAYER_ROUND.player_id + , ALL_PLAYER_ROUND.round_id + + , PLAYER_ROUND_MAX_CDR_DAMAGE_IN.max_total_commander_damage_received + , PLAYER_ROUND_TOTAL_CDR_DAMAGE_OUT.total_commander_damage_dealt + , PLAYER_ROUND_TOTAL_DAMAGE.total_damage_received + , PLAYER_ROUND_ELIMINATED.is_eliminated + , PLAYER_ROUND_ELIMINATED.total_commander_deaths + , PLAYER_ROUND_TOTAL_LIFE.total_life_gained + FROM All_Player_Round ALL_PLAYER_ROUND + INNER JOIN Player_Round_Max_Commander_Damage_Received PLAYER_ROUND_MAX_CDR_DAMAGE_IN + ON ALL_PLAYER_ROUND.round_id = PLAYER_ROUND_MAX_CDR_DAMAGE_IN.round_id + AND ALL_PLAYER_ROUND.player_id = PLAYER_ROUND_MAX_CDR_DAMAGE_IN.player_id + INNER JOIN Player_Round_Total_Commander_Damage_Dealt PLAYER_ROUND_TOTAL_CDR_DAMAGE_OUT + ON ALL_PLAYER_ROUND.round_id = PLAYER_ROUND_TOTAL_CDR_DAMAGE_OUT.round_id + AND ALL_PLAYER_ROUND.player_id = PLAYER_ROUND_TOTAL_CDR_DAMAGE_OUT.player_id + INNER JOIN Player_Round_Damage PLAYER_ROUND_TOTAL_DAMAGE + ON ALL_PLAYER_ROUND.round_id = PLAYER_ROUND_TOTAL_DAMAGE.round_id + AND ALL_PLAYER_ROUND.player_id = PLAYER_ROUND_TOTAL_DAMAGE.player_id + INNER JOIN Player_Round_Eliminated PLAYER_ROUND_ELIMINATED + ON ALL_PLAYER_ROUND.round_id = PLAYER_ROUND_ELIMINATED.round_id + AND ALL_PLAYER_ROUND.player_id = PLAYER_ROUND_ELIMINATED.player_id + INNER JOIN Player_Round_Total_Life PLAYER_ROUND_TOTAL_LIFE + ON ALL_PLAYER_ROUND.round_id = PLAYER_ROUND_TOTAL_LIFE.round_id + AND ALL_PLAYER_ROUND.player_id = PLAYER_ROUND_TOTAL_LIFE.player_id + ; + + WITH + Player_Round_Eliminated AS ( + SELECT + T_PLAYER_ROUND_LINK.player_id + , T_GAME.game_id + , T_GAME.max_round_display_order AS game_max_round_display_order + , MIN(T_ROUND.display_order) AS round_display_order + FROM Temp_Statistic_Calc_Player_Round_Link T_PLAYER_ROUND_LINK + INNER JOIN Temp_Statistic_Calc_Round T_ROUND ON T_PLAYER_ROUND_LINK.round_id = T_ROUND.round_id + INNER JOIN Temp_Statistic_Calc_Game T_GAME ON T_PLAYER_ROUND_LINK.game_id = T_GAME.game_id + WHERE + T_PLAYER_ROUND_LINK.max_total_commander_damage_received >= v_commander_damage_limit + OR T_PLAYER_ROUND_LINK.total_damage_received >= T_GAME.starting_life + OR T_PLAYER_ROUND_LINK.is_eliminated + GROUP BY + T_PLAYER_ROUND_LINK.player_id + , T_GAME.game_id + , T_GAME.max_round_display_order + ) + , Player_Round_Final AS ( + SELECT + PLAYER_ROUND_ELIMINATED.player_id + , PLAYER_ROUND_ELIMINATED.round_display_order AS round_display_order_eliminated + , COALESCE( + PLAYER_ROUND_ELIMINATED.round_display_order + , PLAYER_ROUND_ELIMINATED.game_max_round_display_order + ) AS final_player_damage_round_display_order + , T_ROUND_FINAL.round_id AS final_player_damage_round_id + , RANK() OVER ( + PARTITION BY PLAYER_ROUND_ELIMINATED.game_id + ORDER BY COALESCE( + PLAYER_ROUND_ELIMINATED.round_display_order + , PLAYER_ROUND_ELIMINATED.game_max_round_display_order + 1 + ) + ) AS placement + FROM Player_Round_Eliminated PLAYER_ROUND_ELIMINATED + INNER JOIN Temp_Statistic_Calc_Round T_ROUND_FINAL + ON COALESCE( + PLAYER_ROUND_ELIMINATED.round_display_order + , PLAYER_ROUND_ELIMINATED.game_max_round_display_order + 1 + ) = T_ROUND_FINAL.display_order + AND PLAYER_ROUND_ELIMINATED.game_id = T_ROUND_FINAL.game_id + AND T_ROUND_FINAL.active + ) + /* + , Player_Placement AS ( + SELECT + PLAYER_ROUND_ELIMINATED.player_id + , PLAYER_ROUND_ELIMINATED.round_display_order_eliminated + , PLAYER_ROUND_ELIMINATED.final_player_damage_round_id + , RANK() OVER ( + PARTITION BY PLAYER_ROUND_ELIMINATED.game_id + ORDER BY COALESCE( + PLAYER_ROUND_ELIMINATED.round_display_order + , PLAYER_ROUND_ELIMINATED.game_max_round_display_order + 1 + ) + ) AS placement + FROM Player_Round_Eliminated PLAYER_ROUND_ELIMINATED + ) + */ + , Player_Final_Round_Aggregated AS ( + SELECT + PLAYER_ROUND_FINAL.player_id + , MAX(T_PLAYER_ROUND_LINK.max_total_commander_damage_received) AS max_total_commander_damage_received + , SUM(T_PLAYER_ROUND_LINK.total_commander_damage_dealt) AS total_commander_damage_dealt + , SUM(T_PLAYER_ROUND_LINK.total_damage_received) AS total_damage_received + , SUM(T_PLAYER_ROUND_LINK.total_commander_deaths) AS total_commander_deaths + , SUM(T_PLAYER_ROUND_LINK.total_life_gained) AS total_life_gained + FROM Player_Round_Final PLAYER_ROUND_FINAL -- Player_Round_Eliminated PLAYER_ROUND_ELIMINATED + INNER JOIN Temp_Statistic_Calc_Round T_ROUND ON PLAYER_ROUND_FINAL.final_player_damage_round_id = T_ROUND.round_id + INNER JOIN Temp_Statistic_Calc_Player_Round_Link T_PLAYER_ROUND_LINK + ON PLAYER_ROUND_FINAL.player_id = T_PLAYER_ROUND_LINK.player_id + AND PLAYER_ROUND_FINAL.final_player_damage_round_id = T_PLAYER_ROUND_LINK.round_id + GROUP BY PLAYER_ROUND_FINAL.player_id + ) + UPDATE Temp_Statistic_Calc_Player T_PLAYER + SET + round_display_order_eliminated = PLAYER_ROUND_FINAL.round_display_order_eliminated + , final_player_damage_round_id = PLAYER_ROUND_FINAL.final_player_damage_round_id + , placement = PLAYER_ROUND_FINAL.placement + , max_total_commander_damage_received = PLAYER_FINAL_ROUND_AGGREGATED.max_total_commander_damage_received + , total_commander_damage_dealt = PLAYER_FINAL_ROUND_AGGREGATED.total_commander_damage_dealt + , total_damage_received = PLAYER_FINAL_ROUND_AGGREGATED.total_damage_received + , total_life_gained = PLAYER_FINAL_ROUND_AGGREGATED.total_life_gained + /* + FROM Player_Placement PLAYER_PLACEMENT + INNER JOIN Player_Final_Round_Aggregated PLAYER_FINAL_ROUND_AGGREGATED ON PLAYER_PLACEMENT.player_id = PLAYER_FINAL_ROUND_AGGREGATED.player_id + WHERE T_PLAYER.player_id = PLAYER_PLACEMENT.player_id + */ + FROM Player_Round_Final PLAYER_ROUND_FINAL + INNER JOIN Player_Final_Round_Aggregated PLAYER_FINAL_ROUND_AGGREGATED ON PLAYER_ROUND_FINAL.player_id = PLAYER_FINAL_ROUND_AGGREGATED.player_id + WHERE T_PLAYER.player_id = PLAYER_ROUND_FINAL.player_id + ; + + WITH + Unique_User_Deck_Link AS ( + SELECT DISTINCT + T_PLAYER.user_id + , T_PLAYER.deck_id + FROM Temp_Statistic_Calc_Player T_PLAYER + ) + , User_Deck_Game_Aggregated_Raw AS ( + SELECT + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , COUNT(*) AS count_games + /* + , SUM(USER_DECK_LINK.count_mulligans) AS count_mulligans + , MAX(USER_DECK_LINK.count_mulligans) AS max_count_mulligans + , MIN(USER_DECK_LINK.count_mulligans) AS min_count_mulligans + */ + , SUM(T_PLAYER.round_display_order_eliminated) AS total_round_display_order_eliminated + , MAX(T_PLAYER.round_display_order_eliminated) AS max_round_display_order_eliminated + , MIN(T_PLAYER.round_display_order_eliminated) AS min_round_display_order_eliminated + , MAX(T_PLAYER.placement) AS worst_position + , MIN(T_PLAYER.placement) AS best_position + , SUM(T_PLAYER.max_total_commander_damage_received) AS total_commander_damage_received + , MAX(T_PLAYER.max_total_commander_damage_received) AS max_total_commander_damage_received + , MIN(T_PLAYER.max_total_commander_damage_received) AS min_total_commander_damage_received + , SUM(T_PLAYER.total_commander_damage_dealt) AS total_commander_damage_dealt + , MAX(T_PLAYER.total_commander_damage_dealt) AS max_total_commander_damage_dealt + , MIN(T_PLAYER.total_commander_damage_dealt) AS min_total_commander_damage_dealt + , SUM(T_PLAYER.total_damage_received) AS total_damage_received + , MAX(T_PLAYER.total_damage_received) AS max_total_damage_received + , MIN(T_PLAYER.total_damage_received) AS min_total_damage_received + , SUM(T_PLAYER.total_life_gained) AS total_life_gained + , MAX(T_PLAYER.total_life_gained) AS max_total_life_gained + , MIN(T_PLAYER.total_life_gained) AS min_total_life_gained + , SUM(T_PLAYER.total_commander_deaths) AS total_commander_deaths + , MAX(T_PLAYER.total_commander_deaths) AS max_total_commander_deaths + , MIN(T_PLAYER.total_commander_deaths) AS min_total_commander_deaths + , SUM(T_GAME.max_round_display_order) AS total_round_display_order + , MAX(T_GAME.max_round_display_order) AS max_round_display_order + , MIN(T_GAME.max_round_display_order) AS min_round_display_order + , SUM(T_GAME.count_players) AS total_pod_sizes + , SUM(T_GAME.count_players) - COUNT(*) AS total_opponents_faced + , MAX(T_GAME.count_players) AS max_pod_size + , MIN(T_GAME.count_players) AS min_pod_size + , SUM(T_GAME.duration) AS total_game_duration + , MAX(T_GAME.duration) AS longest_game_duration + , MIN(T_GAME.duration) AS shortest_game_duration + FROM Unique_User_Deck_Link USER_DECK_LINK + INNER JOIN Temp_Statistic_Calc_Player T_PLAYER + ON USER_DECK_LINK.user_id = T_PLAYER.user_id + AND USER_DECK_LINK.deck_id = T_PLAYER.deck_id + INNER JOIN Temp_Statistic_Calc_Game T_GAME ON T_PLAYER.game_id = T_GAME.game_id + GROUP BY + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + ) + , User_Deck_Game_Win_Aggregated AS ( + SELECT + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , COUNT(*) AS count_games + , SUM(T_PLAYER.round_display_order_eliminated) AS total_round_display_order_eliminated + , MAX(T_PLAYER.round_display_order_eliminated) AS max_round_display_order_eliminated + , MIN(T_PLAYER.round_display_order_eliminated) AS min_round_display_order_eliminated + , MAX(T_PLAYER.placement) AS worst_position + , MIN(T_PLAYER.placement) AS best_position + , SUM(T_PLAYER.max_total_commander_damage_received) AS total_commander_damage_received + , MAX(T_PLAYER.max_total_commander_damage_received) AS max_total_commander_damage_received + , MIN(T_PLAYER.max_total_commander_damage_received) AS min_total_commander_damage_received + , SUM(T_PLAYER.total_commander_damage_dealt) AS total_commander_damage_dealt + , MAX(T_PLAYER.total_commander_damage_dealt) AS max_total_commander_damage_dealt + , MIN(T_PLAYER.total_commander_damage_dealt) AS min_total_commander_damage_dealt + , SUM(T_PLAYER.total_damage_received) AS total_damage_received + , MAX(T_PLAYER.total_damage_received) AS max_total_damage_received + , MIN(T_PLAYER.total_damage_received) AS min_total_damage_received + , SUM(T_PLAYER.total_life_gained) AS total_life_gained + , MAX(T_PLAYER.total_life_gained) AS max_total_life_gained + , MIN(T_PLAYER.total_life_gained) AS min_total_life_gained + , SUM(T_PLAYER.total_commander_deaths) AS total_commander_deaths + , MAX(T_PLAYER.total_commander_deaths) AS max_total_commander_deaths + , MIN(T_PLAYER.total_commander_deaths) AS min_total_commander_deaths + , SUM(T_GAME.max_round_display_order) AS total_round_display_order + , MAX(T_GAME.max_round_display_order) AS max_round_display_order + , MIN(T_GAME.max_round_display_order) AS min_round_display_order + , SUM(T_GAME.count_players) AS total_pod_sizes + , SUM(T_GAME.count_players) - COUNT(*) AS total_opponents_faced + , MAX(T_GAME.count_players) AS max_pod_size + , MIN(T_GAME.count_players) AS min_pod_size + , SUM(T_GAME.duration) AS total_game_duration + , MAX(T_GAME.duration) AS longest_game_duration + , MIN(T_GAME.duration) AS shortest_game_duration + FROM Unique_User_Deck_Link USER_DECK_LINK + INNER JOIN Temp_Statistic_Calc_Player T_PLAYER + ON USER_DECK_LINK.user_id = T_PLAYER.user_id + AND USER_DECK_LINK.deck_id = T_PLAYER.deck_id + AND T_PLAYER.placement = 1 + INNER JOIN Temp_Statistic_Calc_Game T_GAME ON T_PLAYER.game_id = T_GAME.game_id + GROUP BY + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + ) + , User_Deck_Game_Lose_Aggregated AS ( + SELECT + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , COUNT(*) AS count_games + , SUM(T_PLAYER.round_display_order_eliminated) AS total_round_display_order_eliminated + , MAX(T_PLAYER.round_display_order_eliminated) AS max_round_display_order_eliminated + , MIN(T_PLAYER.round_display_order_eliminated) AS min_round_display_order_eliminated + , MAX(T_PLAYER.placement) AS worst_position + , MIN(T_PLAYER.placement) AS best_position + , SUM(T_PLAYER.max_total_commander_damage_received) AS total_commander_damage_received + , MAX(T_PLAYER.max_total_commander_damage_received) AS max_total_commander_damage_received + , MIN(T_PLAYER.max_total_commander_damage_received) AS min_total_commander_damage_received + , SUM(T_PLAYER.total_commander_damage_dealt) AS total_commander_damage_dealt + , MAX(T_PLAYER.total_commander_damage_dealt) AS max_total_commander_damage_dealt + , MIN(T_PLAYER.total_commander_damage_dealt) AS min_total_commander_damage_dealt + , SUM(T_PLAYER.total_damage_received) AS total_damage_received + , MAX(T_PLAYER.total_damage_received) AS max_total_damage_received + , MIN(T_PLAYER.total_damage_received) AS min_total_damage_received + , SUM(T_PLAYER.total_life_gained) AS total_life_gained + , MAX(T_PLAYER.total_life_gained) AS max_total_life_gained + , MIN(T_PLAYER.total_life_gained) AS min_total_life_gained + , SUM(T_PLAYER.total_commander_deaths) AS total_commander_deaths + , MAX(T_PLAYER.total_commander_deaths) AS max_total_commander_deaths + , MIN(T_PLAYER.total_commander_deaths) AS min_total_commander_deaths + , SUM(T_GAME.max_round_display_order) AS total_round_display_order + , MAX(T_GAME.max_round_display_order) AS max_round_display_order + , MIN(T_GAME.max_round_display_order) AS min_round_display_order + , SUM(T_GAME.count_players) AS total_pod_sizes + , SUM(T_GAME.count_players) - COUNT(*) AS total_opponents_faced + , MAX(T_GAME.count_players) AS max_pod_size + , MIN(T_GAME.count_players) AS min_pod_size + , SUM(T_GAME.duration) AS total_game_duration + , MAX(T_GAME.duration) AS longest_game_duration + , MIN(T_GAME.duration) AS shortest_game_duration + FROM Unique_User_Deck_Link USER_DECK_LINK + INNER JOIN Temp_Statistic_Calc_Player T_PLAYER + ON USER_DECK_LINK.user_id = T_PLAYER.user_id + AND USER_DECK_LINK.deck_id = T_PLAYER.deck_id + AND T_PLAYER.placement > 1 + INNER JOIN Temp_Statistic_Calc_Game T_GAME ON T_PLAYER.game_id = T_GAME.game_id + GROUP BY + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + ) + , Latest_User_Deck_Game_Win AS ( + SELECT + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , T_GAME.count_players AS pod_size + , COALESCE( + T_GAME.start_on + , T_GAME.created_on + ) AS start_on + , ROW_NUMBER() OVER ( + PARTITION BY + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + ORDER BY COALESCE( + T_GAME.start_on + , T_GAME.created_on + ) DESC + ) AS index_in_user_and_deck + FROM Unique_User_Deck_Link USER_DECK_LINK + INNER JOIN Temp_Statistic_Calc_Player T_PLAYER + ON USER_DECK_LINK.user_id = T_PLAYER.user_id + AND USER_DECK_LINK.deck_id = T_PLAYER.deck_id + AND T_PLAYER.placement = 1 + INNER JOIN Temp_Statistic_Calc_Game T_GAME ON T_PLAYER.game_id = T_GAME.game_id + ) + , Latest_User_Deck_Game_Lose AS ( + SELECT + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , T_GAME.count_players AS pod_size + , COALESCE( + T_GAME.start_on + , T_GAME.created_on + ) AS start_on + , ROW_NUMBER() OVER ( + PARTITION BY + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + ORDER BY COALESCE( + T_GAME.start_on + , T_GAME.created_on + ) DESC + ) AS index_in_user_and_deck + FROM Unique_User_Deck_Link USER_DECK_LINK + INNER JOIN Temp_Statistic_Calc_Player T_PLAYER + ON USER_DECK_LINK.user_id = T_PLAYER.user_id + AND USER_DECK_LINK.deck_id = T_PLAYER.deck_id + AND T_PLAYER.placement > 1 + INNER JOIN Temp_Statistic_Calc_Game T_GAME ON T_PLAYER.game_id = T_GAME.game_id + ) + /* + , Rival_Player AS ( + SELECT + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , T_PLAYER_OPPONENT.player_id AS opponent_player_id + , T_PLAYER_OPPONENT.user_id AS opponent_user_id + , T_PLAYER_OPPONENT.deck_id AS opponent_deck_id + FROM Unique_User_Deck_Link USER_DECK_LINK + INNER JOIN Temp_Statistic_Calc_Player T_PLAYER + ON USER_DECK_LINK.user_id = T_PLAYER.user_id + AND USER_DECK_LINK.deck_id = T_PLAYER.deck_id + INNER JOIN Temp_Statistic_Calc_Player T_PLAYER_OPPONENT + ON T_PLAYER.game_id = T_PLAYER_OPPONENT.game_id + AND T_PLAYER.player_id <> T_PLAYER_OPPONENT.player_id + ) + , Rival_User AS ( + SELECT + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , RIVAL_PLAYER.opponent_user_id + , COUNT(*) AS count_decks_faced + FROM Unique_User_Deck_Link USER_DECK_LINK + INNER JOIN Rival_Player RIVAL_PLAYER + ON USER_DECK_LINK.user_id = RIVAL_PLAYER.user_id + AND USER_DECK_LINK.deck_id = RIVAL_PLAYER.deck_id + GROUP BY + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , RIVAL_PLAYER.opponent_user_id + HAVING ROW_NUMBER() OVER ( + PARTITION BY + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , RIVAL_PLAYER.opponent_user_id + ORDER BY COUNT(*) DESC + ) = 1 + ) + , Rival_Deck AS ( + SELECT + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , ARCHENEMY_PLAYER.opponent_deck_id + , SUM(ARCHENEMY_PLAYER.placement_difference) AS total_placement_difference + FROM Unique_User_Deck_Link USER_DECK_LINK + INNER JOIN Archenemy_Player ARCHENEMY_PLAYER + ON USER_DECK_LINK.user_id = ARCHENEMY_PLAYER.user_id + AND USER_DECK_LINK.deck_id = ARCHENEMY_PLAYER.deck_id + GROUP BY + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , T_PLAYER_OPPONENT.deck_id AS opponent_deck_id + HAVING ROW_NUMBER() OVER ( + PARTITION BY + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , ARCHENEMY_PLAYER.opponent_deck_id + ORDER BY SUM(ARCHENEMY_PLAYER.placement_difference) DESC + ) = 1 + ) + , Archenemy_Player AS ( + SELECT + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , T_PLAYER_OPPONENT.player_id AS opponent_player_id + , T_PLAYER_OPPONENT.user_id AS opponent_user_id + , T_PLAYER_OPPONENT.deck_id AS opponent_deck_id + , T_PLAYER_OPPONENT.placement - T_PLAYER.placement AS placement_difference + FROM Unique_User_Deck_Link USER_DECK_LINK + INNER JOIN Temp_Statistic_Calc_Player T_PLAYER + ON USER_DECK_LINK.user_id = T_PLAYER.user_id + AND USER_DECK_LINK.deck_id = T_PLAYER.deck_id + INNER JOIN Temp_Statistic_Calc_Game T_GAME ON T_PLAYER.game_id = T_GAME.game_id + INNER JOIN Temp_Statistic_Calc_Player T_PLAYER_OPPONENT + ON T_GAME.game_id = T_PLAYER_OPPONENT.game_id + AND T_PLAYER.player_id <> T_PLAYER_OPPONENT.player_id + AND T_PLAYER.placement > T_PLAYER_OPPONENT.placement + ) + , Archenemy_User AS ( + SELECT + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , ARCHENEMY_PLAYER.opponent_user_id + , SUM(ARCHENEMY_PLAYER.placement_difference) + , COUNT(*) AS count_decks_faced + FROM Unique_User_Deck_Link USER_DECK_LINK + INNER JOIN Archenemy_Player ARCHENEMY_PLAYER + ON USER_DECK_LINK.user_id = ARCHENEMY_PLAYER.user_id + AND USER_DECK_LINK.deck_id = ARCHENEMY_PLAYER.deck_id + GROUP BY + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , ARCHENEMY_PLAYER.opponent_user_id + HAVING ROW_NUMBER() OVER ( + PARTITION BY + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , ARCHENEMY_PLAYER.opponent_user_id + ORDER BY SUM(ARCHENEMY_PLAYER.placement_difference) DESC + ) = 1 + ) + , Archenemy_User_Game AS ( + SELECT + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , ARCHENEMY_USER.opponent_user_id + , COUNT(*) AS count_games_faced + FROM Unique_User_Deck_Link USER_DECK_LINK + /* + INNER JOIN Temp_Statistic_Calc_Player T_PLAYER + ON USER_DECK_LINK.user_id = T_PLAYER.user_id + AND USER_DECK_LINK.deck_id = T_PLAYER.deck_id + */ + INNER JOIN Archenemy_User ARCHENEMY_USER + ON USER_DECK_LINK.user_id = ARCHENEMY_USER.user_id + AND USER_DECK_LINK.deck_id = ARCHENEMY_USER.deck_id + INNER JOIN ( + SELECT DISTINCT T_PLAYER_OPPONENT.game_id + FROM Temp_Statistic_Calc_Player T_PLAYER_OPPONENT + -- INNER JOIN Temp_Statistic_Calc_Player T_PLAYER_OPPONENT ON T_PLAYER_OPPONENT.user_id = ARCHENEMY_USER.opponent_user_id + WHERE T_PLAYER_OPPONENT.player_id = ARCHENEMY_USER.player_id + ) T_GAME_UNIQUE ON + GROUP BY + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , ARCHENEMY_PLAYER.opponent_user_id + ) + , Archenemy_Deck AS ( + SELECT + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , ARCHENEMY_PLAYER.opponent_deck_id + , SUM(ARCHENEMY_PLAYER.placement_difference) + FROM Unique_User_Deck_Link USER_DECK_LINK + INNER JOIN Archenemy_Player ARCHENEMY_PLAYER + ON USER_DECK_LINK.user_id = ARCHENEMY_PLAYER.user_id + AND USER_DECK_LINK.deck_id = ARCHENEMY_PLAYER.deck_id + GROUP BY + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , T_PLAYER_OPPONENT.deck_id AS opponent_deck_id + HAVING ROW_NUMBER() OVER ( + PARTITION BY + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , ARCHENEMY_PLAYER.opponent_deck_id + ORDER BY SUM(ARCHENEMY_PLAYER.placement_difference) DESC + ) = 1 + ) + , Archenemy_Deck_Game AS ( + SELECT + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , ARCHENEMY_PLAYER.opponent_user_id + , COUNT(*) AS count_games_faced + FROM Unique_User_Deck_Link USER_DECK_LINK + INNER JOIN Archenemy_Deck ARCHENEMY_DECK + ON USER_DECK_LINK.user_id = ARCHENEMY_DECK.user_id + AND USER_DECK_LINK.deck_id = ARCHENEMY_DECK.deck_id + -- INNER JOIN Temp_Statistic_Calc_Player T_PLAYER_OPPONENT ON T_PLAYER_OPPONENT.user_id = ARCHENEMY_USER.opponent_user_id + INNER JOIN Temp_Statistic_Calc_Game T_GAME ON T_GAME.game_id IN ( + SELECT DISTINCT T_PLAYER_OPPONENT.game_id + FROM Temp_Statistic_Calc_Player T_PLAYER_OPPONENT + WHERE T_PLAYER_OPPONENT.player_id = ARCHENEMY_PLAYER.player_id + ) + GROUP BY + USER_DECK_LINK.user_id + , USER_DECK_LINK.deck_id + , ARCHENEMY_PLAYER.opponent_user_id + ) + */ + INSERT INTO Temp_Statistic_Calc_User_Deck_Link ( + user_id + , deck_id + , count_games + , count_games_won + , count_games_lost + , win_lose_ratio + /* + , mean_mulligan_count + , max_mulligan_count + , min_mulligan_count + */ + , best_position + , worst_position + , total_damage_received + , mean_total_damage_received + , max_total_damage_received + , min_total_damage_received + , total_damage_received_game_win + , mean_total_damage_received_game_win + , max_total_damage_received_game_win + , min_total_damage_received_game_win + , total_damage_received_game_lose + , mean_total_damage_received_game_lose + , max_total_damage_received_game_lose + , min_total_damage_received_game_lose + , total_commander_damage_dealt + , mean_total_commander_damage_dealt + , max_total_commander_damage_dealt + , min_total_commander_damage_dealt + , total_commander_damage_dealt_game_won + , mean_total_commander_damage_dealt_won + , max_total_commander_damage_dealt_won + , min_total_commander_damage_dealt_won + , total_commander_damage_dealt_game_lost + , mean_total_commander_damage_dealt_lost + , max_total_commander_damage_dealt_lost + , min_total_commander_damage_dealt_lost + , total_commander_damage_received + , mean_total_commander_damage_received + , max_total_commander_damage_received + , min_total_commander_damage_received + , total_commander_damage_received_game_won + , mean_total_commander_damage_received_won + , max_total_commander_damage_received_won + , min_total_commander_damage_received_won + , total_commander_damage_received_game_lost + , mean_total_commander_damage_received_lost + , max_total_commander_damage_received_lost + , min_total_commander_damage_received_lost + , total_life_gained + , mean_total_life_gained + , max_total_life_gained + , min_total_life_gained + , total_life_gained_game_won + , mean_total_life_gained_game_won + , max_total_life_gained_game_won + , min_total_life_gained_game_won + , total_life_gained_game_lost + , mean_total_life_gained_game_lost + , max_total_life_gained_game_lost + , min_total_life_gained_game_lost + , total_game_round_count + , mean_game_round_count + , lowest_game_round_count + , highest_game_round_count + , total_game_win_round_count + , mean_game_win_round_count + , lowest_game_win_round_count + , highest_game_win_round_count + , total_game_lose_round_count + , mean_game_lose_round_count + , lowest_game_lose_round_count + , highest_game_lose_round_count + , total_game_round_survived_count + , mean_game_round_survived_count + , lowest_game_round_survived_count + , highest_game_round_survived_count + , total_game_win_round_survived_count + , mean_game_win_round_survived_count + , lowest_game_win_round_survived_count + , highest_game_win_round_survived_count + , total_game_lose_round_survived_count + , mean_game_lose_round_survived_count + , lowest_game_lose_round_survived_count + , highest_game_lose_round_survived_count + , total_game_duration + , mean_game_duration + , shortest_game_duration + , longest_game_duration + , total_game_win_duration + , mean_game_win_duration + , shortest_game_win_duration + , longest_game_win_duration + , total_game_lose_duration + , mean_game_lose_duration + , shortest_game_lose_duration + , longest_game_lose_duration + , total_commander_deaths + , mean_commander_deaths + , max_commander_deaths + , min_commander_deaths + , total_commander_deaths_game_won + , mean_commander_deaths_game_won + , max_commander_deaths_game_won + , min_commander_deaths_game_won + , total_commander_deaths_game_lost + , mean_commander_deaths_game_lost + , max_commander_deaths_game_lost + , min_commander_deaths_game_lost + , total_pod_sizes + , total_opponents_faced + , mean_pod_size + , max_pod_size + , min_pod_size + , total_pod_sizes_won + , total_opponents_beaten + , mean_pod_size_won + , max_pod_size_won + , min_pod_size_won + , total_pod_sizes_lost + , total_opponents_lost_to + , mean_pod_size_lost + , max_pod_size_lost + , min_pod_size_lost + , latest_game_win_on + , latest_game_win_pod_size + , latest_game_lose_on + , latest_game_lose_pod_size + /* + , archenemy_deck_id + , rival_deck_id + , archenemy_player_id + , rival_player_id + , count_games_against_self + , count_players_against_self + / * + , colours faced + , deck archetypes faced? + */ + ) + SELECT + USER_DECK_AGGREGATED_RAW.user_id + , USER_DECK_AGGREGATED_RAW.deck_id + , USER_DECK_AGGREGATED_RAW.count_games + , USER_DECK_WIN_AGGREGATED_RAW.count_games -- count_games_won + , USER_DECK_LOSE_AGGREGATED_RAW.count_games -- count_games_lost + , CASE + WHEN USER_DECK_LOSE_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_WIN_AGGREGATED_RAW.count_games / USER_DECK_LOSE_AGGREGATED_RAW.count_games + ELSE COALESCE(USER_DECK_WIN_AGGREGATED_RAW.count_games, 0) + END -- win_lose_ratio + /* + , mean_mulligan_count + , max_mulligan_count + , min_mulligan_count + */ + , USER_DECK_AGGREGATED_RAW.best_position + , USER_DECK_AGGREGATED_RAW.worst_position + , USER_DECK_AGGREGATED_RAW.total_damage_received + , CASE + WHEN USER_DECK_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_AGGREGATED_RAW.total_damage_received / USER_DECK_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_total_damage_received + , USER_DECK_AGGREGATED_RAW.max_total_damage_received + , USER_DECK_AGGREGATED_RAW.min_total_damage_received + , USER_DECK_WIN_AGGREGATED_RAW.total_damage_received -- total_damage_received_game_win + , CASE + WHEN USER_DECK_WIN_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_WIN_AGGREGATED_RAW.total_damage_received / USER_DECK_WIN_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_total_damage_received_game_win + , USER_DECK_WIN_AGGREGATED_RAW.max_total_damage_received -- max_total_damage_received_game_win + , USER_DECK_WIN_AGGREGATED_RAW.min_total_damage_received -- min_total_damage_received_game_win + , USER_DECK_LOSE_AGGREGATED_RAW.total_damage_received -- total_damage_received_game_lose + , CASE + WHEN USER_DECK_LOSE_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_LOSE_AGGREGATED_RAW.total_damage_received / USER_DECK_LOSE_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_total_damage_received_game_lose + , USER_DECK_LOSE_AGGREGATED_RAW.max_total_damage_received -- max_total_damage_received_game_lose + , USER_DECK_LOSE_AGGREGATED_RAW.min_total_damage_received -- min_total_damage_received_game_lose + , USER_DECK_AGGREGATED_RAW.total_commander_damage_dealt + , CASE + WHEN USER_DECK_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_AGGREGATED_RAW.total_commander_damage_dealt / USER_DECK_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_total_commander_damage_dealt + , USER_DECK_AGGREGATED_RAW.max_total_commander_damage_dealt + , USER_DECK_AGGREGATED_RAW.min_total_commander_damage_dealt + , USER_DECK_WIN_AGGREGATED_RAW.total_commander_damage_dealt -- total_commander_damage_dealt_game_won + , CASE + WHEN USER_DECK_WIN_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_WIN_AGGREGATED_RAW.total_commander_damage_dealt / USER_DECK_WIN_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_total_commander_damage_dealt_won + , USER_DECK_WIN_AGGREGATED_RAW.max_total_commander_damage_dealt -- max_total_commander_damage_dealt_won + , USER_DECK_WIN_AGGREGATED_RAW.min_total_commander_damage_dealt -- min_total_commander_damage_dealt_won + , USER_DECK_LOSE_AGGREGATED_RAW.total_commander_damage_dealt -- total_commander_damage_dealt_game_lost + , CASE + WHEN USER_DECK_LOSE_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_LOSE_AGGREGATED_RAW.total_commander_damage_dealt / USER_DECK_LOSE_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_total_commander_damage_dealt_lost + , USER_DECK_LOSE_AGGREGATED_RAW.max_total_commander_damage_dealt -- max_total_commander_damage_dealt_lost + , USER_DECK_LOSE_AGGREGATED_RAW.min_total_commander_damage_dealt -- min_total_commander_damage_dealt_lost + , USER_DECK_AGGREGATED_RAW.total_commander_damage_received + , CASE + WHEN USER_DECK_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_AGGREGATED_RAW.total_commander_damage_received / USER_DECK_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_total_commander_damage_received + , USER_DECK_AGGREGATED_RAW.max_total_commander_damage_received + , USER_DECK_AGGREGATED_RAW.min_total_commander_damage_received + , USER_DECK_WIN_AGGREGATED_RAW.total_commander_damage_received -- total_commander_damage_received_game_won + , CASE + WHEN USER_DECK_WIN_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_WIN_AGGREGATED_RAW.total_commander_damage_received / USER_DECK_WIN_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_total_commander_damage_received_won + , USER_DECK_WIN_AGGREGATED_RAW.max_total_commander_damage_received -- max_total_commander_damage_received_won + , USER_DECK_WIN_AGGREGATED_RAW.min_total_commander_damage_received -- min_total_commander_damage_received_won + , USER_DECK_LOSE_AGGREGATED_RAW.total_commander_damage_received -- total_commander_damage_received_game_lost + , CASE + WHEN USER_DECK_LOSE_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_LOSE_AGGREGATED_RAW.total_commander_damage_received / USER_DECK_LOSE_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_total_commander_damage_received_lost + , USER_DECK_LOSE_AGGREGATED_RAW.max_total_commander_damage_received -- max_total_commander_damage_received_lost + , USER_DECK_LOSE_AGGREGATED_RAW.min_total_commander_damage_received -- min_total_commander_damage_received_lost + , USER_DECK_AGGREGATED_RAW.total_life_gained + , CASE + WHEN USER_DECK_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_AGGREGATED_RAW.total_life_gained / USER_DECK_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_total_life_gained + , USER_DECK_AGGREGATED_RAW.max_total_life_gained + , USER_DECK_AGGREGATED_RAW.min_total_life_gained + , USER_DECK_WIN_AGGREGATED_RAW.total_life_gained -- total_life_gained_game_won + , CASE + WHEN USER_DECK_WIN_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_WIN_AGGREGATED_RAW.total_life_gained / USER_DECK_WIN_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_total_life_gained_game_won + , USER_DECK_WIN_AGGREGATED_RAW.max_total_life_gained -- max_total_life_gained_game_won + , USER_DECK_WIN_AGGREGATED_RAW.min_total_life_gained -- min_total_life_gained_game_won + , USER_DECK_LOSE_AGGREGATED_RAW.total_life_gained -- total_life_gained_game_lost + , CASE + WHEN USER_DECK_LOSE_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_LOSE_AGGREGATED_RAW.total_life_gained / USER_DECK_LOSE_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_total_life_gained_game_lost + , USER_DECK_LOSE_AGGREGATED_RAW.max_total_life_gained -- max_total_life_gained_game_lost + , USER_DECK_LOSE_AGGREGATED_RAW.min_total_life_gained -- min_total_life_gained_game_lost + , USER_DECK_AGGREGATED_RAW.total_round_display_order + , CASE + WHEN USER_DECK_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_AGGREGATED_RAW.total_round_display_order / USER_DECK_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_game_round_count + , USER_DECK_AGGREGATED_RAW.min_round_display_order -- lowest_game_round_count + , USER_DECK_AGGREGATED_RAW.max_round_display_order -- highest_game_round_count + , COALESCE(USER_DECK_WIN_AGGREGATED_RAW.total_round_display_order, 0) -- total_game_win_round_count + , CASE + WHEN USER_DECK_WIN_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_WIN_AGGREGATED_RAW.total_round_display_order / USER_DECK_WIN_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_game_win_round_count + , COALESCE(USER_DECK_WIN_AGGREGATED_RAW.min_round_display_order, 0) -- lowest_game_win_round_count + , COALESCE(USER_DECK_WIN_AGGREGATED_RAW.max_round_display_order, 0) -- highest_game_win_round_count + , USER_DECK_LOSE_AGGREGATED_RAW.total_round_display_order -- total_game_lose_round_count + , CASE + WHEN USER_DECK_LOSE_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_LOSE_AGGREGATED_RAW.total_round_display_order / USER_DECK_LOSE_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_game_lose_round_count + , COALESCE(USER_DECK_LOSE_AGGREGATED_RAW.min_round_display_order, 0) -- lowest_game_lose_round_count + , COALESCE(USER_DECK_LOSE_AGGREGATED_RAW.max_round_display_order, 0) -- highest_game_lose_round_count + , USER_DECK_AGGREGATED_RAW.total_round_display_order_eliminated -- total_game_round_survived_count + , CASE + WHEN USER_DECK_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_AGGREGATED_RAW.total_round_display_order_eliminated / USER_DECK_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_game_round_survived_count + , USER_DECK_AGGREGATED_RAW.min_round_display_order_eliminated -- lowest_game_round_survived_count + , USER_DECK_AGGREGATED_RAW.max_round_display_order_eliminated -- highest_game_round_survived_count + , USER_DECK_WIN_AGGREGATED_RAW.total_round_display_order_eliminated -- total_game_win_round_survived_count + , CASE + WHEN USER_DECK_WIN_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_WIN_AGGREGATED_RAW.total_round_display_order_eliminated / USER_DECK_WIN_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_game_win_round_survived_count + , USER_DECK_WIN_AGGREGATED_RAW.min_round_display_order_eliminated -- lowest_game_win_round_survived_count + , USER_DECK_WIN_AGGREGATED_RAW.max_round_display_order_eliminated -- highest_game_win_round_survived_count + , USER_DECK_LOSE_AGGREGATED_RAW.total_round_display_order_eliminated -- total_game_lose_round_survived_count + , CASE + WHEN USER_DECK_LOSE_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_LOSE_AGGREGATED_RAW.total_round_display_order_eliminated / USER_DECK_LOSE_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_game_lose_round_survived_count + , USER_DECK_LOSE_AGGREGATED_RAW.min_round_display_order_eliminated -- lowest_game_lose_round_survived_count + , USER_DECK_LOSE_AGGREGATED_RAW.max_round_display_order_eliminated -- highest_game_lose_round_survived_count + , USER_DECK_AGGREGATED_RAW.total_game_duration + , CASE + WHEN USER_DECK_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_AGGREGATED_RAW.total_game_duration / USER_DECK_AGGREGATED_RAW.count_games + ELSE INTERVAL '0' + END -- mean_game_duration + , USER_DECK_AGGREGATED_RAW.shortest_game_duration + , USER_DECK_AGGREGATED_RAW.longest_game_duration + , USER_DECK_WIN_AGGREGATED_RAW.total_game_duration -- total_game_win_duration + , CASE + WHEN USER_DECK_WIN_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_WIN_AGGREGATED_RAW.total_game_duration / USER_DECK_WIN_AGGREGATED_RAW.count_games + ELSE INTERVAL '0' + END -- mean_game_win_duration + , USER_DECK_WIN_AGGREGATED_RAW.shortest_game_duration -- shortest_game_win_duration + , USER_DECK_WIN_AGGREGATED_RAW.longest_game_duration -- longest_game_win_duration + , USER_DECK_LOSE_AGGREGATED_RAW.total_game_duration -- total_game_lose_duration + , CASE + WHEN USER_DECK_LOSE_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_LOSE_AGGREGATED_RAW.total_game_duration / USER_DECK_LOSE_AGGREGATED_RAW.count_games + ELSE INTERVAL '0' + END -- mean_game_lose_duration + , USER_DECK_LOSE_AGGREGATED_RAW.shortest_game_duration -- shortest_game_lose_duration + , USER_DECK_LOSE_AGGREGATED_RAW.longest_game_duration -- longest_game_lose_duration + , USER_DECK_AGGREGATED_RAW.total_commander_deaths + , CASE + WHEN USER_DECK_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_AGGREGATED_RAW.total_commander_deaths / USER_DECK_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_commander_deaths + , USER_DECK_AGGREGATED_RAW.max_total_commander_deaths -- max_commander_deaths + , USER_DECK_AGGREGATED_RAW.min_total_commander_deaths -- min_commander_deaths + , USER_DECK_WIN_AGGREGATED_RAW.total_commander_deaths -- total_commander_deaths_game_won + , CASE + WHEN USER_DECK_WIN_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_WIN_AGGREGATED_RAW.total_commander_deaths / USER_DECK_WIN_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_commander_deaths_game_won + , USER_DECK_WIN_AGGREGATED_RAW.max_total_commander_deaths -- max_commander_deaths_game_won + , USER_DECK_WIN_AGGREGATED_RAW.min_total_commander_deaths -- min_commander_deaths_game_won + , USER_DECK_LOSE_AGGREGATED_RAW.total_commander_deaths -- total_commander_deaths_game_lost + , CASE + WHEN USER_DECK_LOSE_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_LOSE_AGGREGATED_RAW.total_commander_deaths / USER_DECK_LOSE_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_commander_deaths_game_lost + , USER_DECK_LOSE_AGGREGATED_RAW.max_total_commander_deaths -- max_commander_deaths_game_lost + , USER_DECK_LOSE_AGGREGATED_RAW.min_total_commander_deaths -- min_commander_deaths_game_lost + , USER_DECK_AGGREGATED_RAW.total_pod_sizes + , USER_DECK_AGGREGATED_RAW.total_opponents_faced + , CASE + WHEN USER_DECK_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_AGGREGATED_RAW.total_pod_sizes / USER_DECK_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_pod_size + , USER_DECK_AGGREGATED_RAW.max_pod_size + , USER_DECK_AGGREGATED_RAW.min_pod_size + , USER_DECK_WIN_AGGREGATED_RAW.total_pod_sizes -- total_pod_sizes_won + , USER_DECK_WIN_AGGREGATED_RAW.total_opponents_faced -- total_opponents_beaten + , CASE + WHEN USER_DECK_WIN_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_WIN_AGGREGATED_RAW.total_pod_sizes / USER_DECK_WIN_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_pod_size_won + , USER_DECK_WIN_AGGREGATED_RAW.max_pod_size -- max_pod_size_won + , USER_DECK_WIN_AGGREGATED_RAW.min_pod_size -- min_pod_size_won + , USER_DECK_LOSE_AGGREGATED_RAW.total_pod_sizes -- total_pod_sizes_lost + , USER_DECK_LOSE_AGGREGATED_RAW.total_opponents_faced -- total_opponents_lost_to + , CASE + WHEN USER_DECK_LOSE_AGGREGATED_RAW.count_games > 0 + THEN USER_DECK_LOSE_AGGREGATED_RAW.total_pod_sizes / USER_DECK_LOSE_AGGREGATED_RAW.count_games + ELSE 0 + END -- mean_pod_size_lost + , USER_DECK_LOSE_AGGREGATED_RAW.max_pod_size -- max_pod_size_lost + , USER_DECK_LOSE_AGGREGATED_RAW.min_pod_size -- min_pod_size_lost + , LATEST_USER_DECK_WIN.start_on -- latest_game_win_on + , LATEST_USER_DECK_WIN.pod_size -- latest_game_win_pod_size + , LATEST_USER_DECK_LOSE.start_on -- latest_game_lose_on + , LATEST_USER_DECK_LOSE.pod_size -- latest_game_lose_pod_size + /* + , archenemy_deck_id -- !!! + , rival_deck_id -- !!! + , archenemy_player_id -- !!! + , rival_player_id -- !!! + */ + FROM User_Deck_Game_Aggregated_Raw USER_DECK_AGGREGATED_RAW -- Unique_User_Deck_Link UNIQUE_USER_DECK_LINK + LEFT JOIN User_Deck_Game_Win_Aggregated USER_DECK_WIN_AGGREGATED_RAW + ON USER_DECK_AGGREGATED_RAW.user_id = USER_DECK_WIN_AGGREGATED_RAW.user_id + AND USER_DECK_AGGREGATED_RAW.deck_id = USER_DECK_WIN_AGGREGATED_RAW.deck_id + LEFT JOIN User_Deck_Game_Lose_Aggregated USER_DECK_LOSE_AGGREGATED_RAW + ON USER_DECK_AGGREGATED_RAW.user_id = USER_DECK_LOSE_AGGREGATED_RAW.user_id + AND USER_DECK_AGGREGATED_RAW.deck_id = USER_DECK_LOSE_AGGREGATED_RAW.deck_id + LEFT JOIN Latest_User_Deck_Game_Win LATEST_USER_DECK_WIN + ON USER_DECK_AGGREGATED_RAW.user_id = LATEST_USER_DECK_WIN.user_id + AND USER_DECK_AGGREGATED_RAW.deck_id = LATEST_USER_DECK_WIN.deck_id + AND LATEST_USER_DECK_WIN.index_in_user_and_deck = 1 + LEFT JOIN Latest_User_Deck_Game_Lose LATEST_USER_DECK_LOSE + ON USER_DECK_AGGREGATED_RAW.user_id = LATEST_USER_DECK_LOSE.user_id + AND USER_DECK_AGGREGATED_RAW.deck_id = LATEST_USER_DECK_LOSE.deck_id + AND LATEST_USER_DECK_LOSE.index_in_user_and_deck = 1 + ; + + WITH + Latest_User_Win AS ( + SELECT + T_USER_DECK_LINK.user_id + , T_USER_DECK_LINK.latest_game_win_pod_size + , T_USER_DECK_LINK.latest_game_win_on + , ROW_NUMBER() OVER ( + PARTITION BY T_USER_DECK_LINK.user_id + ORDER BY T_USER_DECK_LINK.latest_game_win_on DESC + ) AS index_win_in_user + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + GROUP BY + T_USER_DECK_LINK.user_id + , T_USER_DECK_LINK.latest_game_win_pod_size + , T_USER_DECK_LINK.latest_game_win_on + ) + , Latest_User_Lose AS ( + SELECT + T_USER_DECK_LINK.user_id + , T_USER_DECK_LINK.latest_game_lose_pod_size + , T_USER_DECK_LINK.latest_game_lose_on + , ROW_NUMBER() OVER ( + PARTITION BY T_USER_DECK_LINK.user_id + ORDER BY T_USER_DECK_LINK.latest_game_lose_on DESC + ) AS index_lose_in_user + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + GROUP BY + T_USER_DECK_LINK.user_id + , T_USER_DECK_LINK.latest_game_lose_pod_size + , T_USER_DECK_LINK.latest_game_lose_on + ) + , User_Summary AS ( + SELECT + T_USER_DECK_LINK.user_id + , SUM(T_USER_DECK_LINK.count_games) AS count_games + , SUM(T_USER_DECK_LINK.count_games_won) AS count_games_won + , SUM(T_USER_DECK_LINK.count_games_lost) AS count_games_lost + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_lost) > 0 + THEN SUM(T_USER_DECK_LINK.count_games_won) / SUM(T_USER_DECK_LINK.count_games_lost) + ELSE COALESCE(SUM(T_USER_DECK_LINK.count_games_won), 0) + END AS win_lose_ratio + , MIN(T_USER_DECK_LINK.best_position) AS best_position + , MAX(T_USER_DECK_LINK.worst_position) AS worst_position + , SUM(T_USER_DECK_LINK.total_damage_received) AS total_damage_received + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_damage_received) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_total_damage_received + , MAX(T_USER_DECK_LINK.max_total_damage_received) AS max_total_damage_received + , MIN(T_USER_DECK_LINK.min_total_damage_received) AS min_total_damage_received + , SUM(T_USER_DECK_LINK.total_damage_received_game_win) AS total_damage_received_game_win + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_won) > 0 + THEN SUM(T_USER_DECK_LINK.total_damage_received_game_win) / SUM(T_USER_DECK_LINK.count_games_won) + ELSE 0 + END AS mean_total_damage_received_game_win + , MAX(T_USER_DECK_LINK.max_total_damage_received_game_win) AS max_total_damage_received_game_win + , MIN(T_USER_DECK_LINK.min_total_damage_received_game_win) AS min_total_damage_received_game_win + , SUM(T_USER_DECK_LINK.total_damage_received_game_lose) AS total_damage_received_game_lose + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_lost) > 0 + THEN SUM(T_USER_DECK_LINK.total_damage_received_game_lose) / SUM(T_USER_DECK_LINK.count_games_lost) + ELSE 0 + END AS mean_total_damage_received_game_lose + , MAX(T_USER_DECK_LINK.max_total_damage_received_game_lose) AS max_total_damage_received_game_lose + , MIN(T_USER_DECK_LINK.min_total_damage_received_game_lose) AS min_total_damage_received_game_lose + , SUM(T_USER_DECK_LINK.total_commander_damage_dealt) AS total_commander_damage_dealt + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_commander_damage_dealt) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_total_commander_damage_dealt + , MAX(T_USER_DECK_LINK.max_total_commander_damage_dealt) AS max_total_commander_damage_dealt + , MIN(T_USER_DECK_LINK.min_total_commander_damage_dealt) AS min_total_commander_damage_dealt + , SUM(T_USER_DECK_LINK.total_commander_damage_dealt_game_won) AS total_commander_damage_dealt_game_won + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_won) > 0 + THEN SUM(T_USER_DECK_LINK.total_commander_damage_dealt_game_won) / SUM(T_USER_DECK_LINK.count_games_won) + ELSE 0 + END AS mean_total_commander_damage_dealt_won + , MAX(T_USER_DECK_LINK.max_total_commander_damage_dealt_won) AS max_total_commander_damage_dealt_won + , MIN(T_USER_DECK_LINK.min_total_commander_damage_dealt_won) AS min_total_commander_damage_dealt_won + , SUM(T_USER_DECK_LINK.total_commander_damage_dealt_game_lost) AS total_commander_damage_dealt_game_lost + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_lost) > 0 + THEN SUM(T_USER_DECK_LINK.total_commander_damage_dealt_game_lost) / SUM(T_USER_DECK_LINK.count_games_lost) + ELSE 0 + END AS mean_total_commander_damage_dealt_lost + , MAX(T_USER_DECK_LINK.max_total_commander_damage_dealt_lost) AS max_total_commander_damage_dealt_lost + , MIN(T_USER_DECK_LINK.min_total_commander_damage_dealt_lost) AS min_total_commander_damage_dealt_lost + , SUM(T_USER_DECK_LINK.total_commander_damage_received) AS total_commander_damage_received + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_commander_damage_received) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_total_commander_damage_received + , MAX(T_USER_DECK_LINK.max_total_commander_damage_received) AS max_total_commander_damage_received + , MIN(T_USER_DECK_LINK.min_total_commander_damage_received) AS min_total_commander_damage_received + , SUM(T_USER_DECK_LINK.total_commander_damage_received_game_won) AS total_commander_damage_received_game_won + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_won) > 0 + THEN SUM(T_USER_DECK_LINK.total_commander_damage_received_game_won) / SUM(T_USER_DECK_LINK.count_games_won) + ELSE 0 + END AS mean_total_commander_damage_received_won + , MAX(T_USER_DECK_LINK.max_total_commander_damage_received_won) AS max_total_commander_damage_received_won + , MIN(T_USER_DECK_LINK.min_total_commander_damage_received_won) AS min_total_commander_damage_received_won + , SUM(T_USER_DECK_LINK.total_commander_damage_received_game_lost) AS total_commander_damage_received_game_lost + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_lost) > 0 + THEN SUM(T_USER_DECK_LINK.total_commander_damage_received_game_lost) / SUM(T_USER_DECK_LINK.count_games_lost) + ELSE 0 + END AS mean_total_commander_damage_received_lost + , MAX(T_USER_DECK_LINK.max_total_commander_damage_received_lost) AS max_total_commander_damage_received_lost + , MIN(T_USER_DECK_LINK.min_total_commander_damage_received_lost) AS min_total_commander_damage_received_lost + , SUM(T_USER_DECK_LINK.total_life_gained) AS total_life_gained + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_life_gained) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_total_life_gained + , MAX(T_USER_DECK_LINK.max_total_life_gained) AS max_total_life_gained + , MIN(T_USER_DECK_LINK.min_total_life_gained) AS min_total_life_gained + , SUM(T_USER_DECK_LINK.total_life_gained_game_won) AS total_life_gained_game_won + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_won) > 0 + THEN SUM(T_USER_DECK_LINK.total_life_gained_game_won) / SUM(T_USER_DECK_LINK.count_games_won) + ELSE 0 + END AS mean_total_life_gained_game_won + , MAX(T_USER_DECK_LINK.max_total_life_gained_game_won) AS max_total_life_gained_game_won + , MIN(T_USER_DECK_LINK.min_total_life_gained_game_won) AS min_total_life_gained_game_won + , SUM(T_USER_DECK_LINK.total_life_gained_game_lost) AS total_life_gained_game_lost + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_lost) > 0 + THEN SUM(T_USER_DECK_LINK.total_life_gained_game_lost) / SUM(T_USER_DECK_LINK.count_games_lost) + ELSE 0 + END AS mean_total_life_gained_game_lost + , MAX(T_USER_DECK_LINK.max_total_life_gained_game_lost) AS max_total_life_gained_game_lost + , MIN(T_USER_DECK_LINK.min_total_life_gained_game_lost) AS min_total_life_gained_game_lost + , SUM(T_USER_DECK_LINK.total_game_round_count) AS total_game_round_count + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_game_round_count) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_game_round_count + , MIN(T_USER_DECK_LINK.lowest_game_round_count) AS lowest_game_round_count + , MAX(T_USER_DECK_LINK.highest_game_round_count) AS highest_game_round_count + , SUM(T_USER_DECK_LINK.total_game_win_round_count) AS total_game_win_round_count + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_won) > 0 + THEN SUM(T_USER_DECK_LINK.total_game_win_round_count) / SUM(T_USER_DECK_LINK.count_games_won) + ELSE 0 + END AS mean_game_win_round_count + , MIN(T_USER_DECK_LINK.lowest_game_win_round_count) AS lowest_game_win_round_count + , MAX(T_USER_DECK_LINK.highest_game_win_round_count) AS highest_game_win_round_count + , SUM(T_USER_DECK_LINK.total_game_lose_round_count) AS total_game_lose_round_count + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_lost) > 0 + THEN SUM(T_USER_DECK_LINK.total_game_lose_round_count) / SUM(T_USER_DECK_LINK.count_games_lost) + ELSE 0 + END AS mean_game_lose_round_count + , MIN(T_USER_DECK_LINK.lowest_game_lose_round_count) AS lowest_game_lose_round_count + , MAX(T_USER_DECK_LINK.highest_game_lose_round_count) AS highest_game_lose_round_count + , SUM(T_USER_DECK_LINK.total_game_round_survived_count) AS total_game_round_survived_count + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_game_round_survived_count) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_game_round_survived_count + , MIN(T_USER_DECK_LINK.lowest_game_round_survived_count) AS lowest_game_round_survived_count + , MAX(T_USER_DECK_LINK.highest_game_round_survived_count) AS highest_game_round_survived_count + , SUM(T_USER_DECK_LINK.total_game_win_round_survived_count) AS total_game_win_round_survived_count + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_won) > 0 + THEN SUM(T_USER_DECK_LINK.total_game_win_round_survived_count) / SUM(T_USER_DECK_LINK.count_games_won) + ELSE 0 + END AS mean_game_win_round_survived_count + , MIN(T_USER_DECK_LINK.lowest_game_win_round_survived_count) AS lowest_game_win_round_survived_count + , MAX(T_USER_DECK_LINK.highest_game_win_round_survived_count) AS highest_game_win_round_survived_count + , SUM(T_USER_DECK_LINK.total_game_lose_round_survived_count) AS total_game_lose_round_survived_count + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_game_lose_round_survived_count) / SUM(T_USER_DECK_LINK.count_games_lost) + ELSE 0 + END AS mean_game_lose_round_survived_count + , MIN(T_USER_DECK_LINK.lowest_game_lose_round_survived_count) AS lowest_game_lose_round_survived_count + , MAX(T_USER_DECK_LINK.highest_game_lose_round_survived_count) AS highest_game_lose_round_survived_count + , SUM(T_USER_DECK_LINK.total_game_duration) AS total_game_duration + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_game_duration) / SUM(T_USER_DECK_LINK.count_games) + ELSE INTERVAL '0' + END AS mean_game_duration + , MIN(T_USER_DECK_LINK.shortest_game_duration) AS shortest_game_duration + , MAX(T_USER_DECK_LINK.longest_game_duration) AS longest_game_duration + , SUM(T_USER_DECK_LINK.total_game_win_duration) AS total_game_win_duration + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_won) > 0 + THEN SUM(T_USER_DECK_LINK.total_game_win_duration) / SUM(T_USER_DECK_LINK.count_games_won) + ELSE INTERVAL '0' + END AS mean_game_win_duration + , MIN(T_USER_DECK_LINK.shortest_game_win_duration) AS shortest_game_win_duration + , MAX(T_USER_DECK_LINK.longest_game_win_duration) AS longest_game_win_duration + , SUM(T_USER_DECK_LINK.total_game_lose_duration) AS total_game_lose_duration + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_lost) > 0 + THEN SUM(T_USER_DECK_LINK.total_game_lose_duration) / SUM(T_USER_DECK_LINK.count_games_lost) + ELSE INTERVAL '0' + END AS mean_game_lose_duration + , MIN(T_USER_DECK_LINK.shortest_game_lose_duration) AS shortest_game_lose_duration + , MAX(T_USER_DECK_LINK.longest_game_lose_duration) AS longest_game_lose_duration + , SUM(T_USER_DECK_LINK.total_commander_deaths) AS total_commander_deaths + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_commander_deaths) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_commander_deaths + , MAX(T_USER_DECK_LINK.max_commander_deaths) AS max_commander_deaths + , MIN(T_USER_DECK_LINK.min_commander_deaths) AS min_commander_deaths + , SUM(T_USER_DECK_LINK.total_commander_deaths_game_won) AS total_commander_deaths_game_won + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_won) > 0 + THEN SUM(T_USER_DECK_LINK.total_commander_deaths_game_won) / SUM(T_USER_DECK_LINK.count_games_won) + ELSE 0 + END AS mean_commander_deaths_game_won + , MAX(T_USER_DECK_LINK.max_commander_deaths_game_won) AS max_commander_deaths_game_won + , MIN(T_USER_DECK_LINK.min_commander_deaths_game_won) AS min_commander_deaths_game_won + , SUM(T_USER_DECK_LINK.total_commander_deaths_game_lost) AS total_commander_deaths_game_lost + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_commander_deaths_game_lost) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_commander_deaths_game_lost + , MAX(T_USER_DECK_LINK.max_commander_deaths_game_lost) AS max_commander_deaths_game_lost + , MIN(T_USER_DECK_LINK.min_commander_deaths_game_lost) AS min_commander_deaths_game_lost + , SUM(T_USER_DECK_LINK.total_pod_sizes) AS total_pod_sizes + , SUM(T_USER_DECK_LINK.total_opponents_faced) AS total_opponents_faced + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_pod_sizes) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_pod_size + , MAX(T_USER_DECK_LINK.max_pod_size) AS max_pod_size + , MIN(T_USER_DECK_LINK.min_pod_size) AS min_pod_size + , SUM(T_USER_DECK_LINK.total_pod_sizes_won) AS total_pod_sizes_won + , SUM(T_USER_DECK_LINK.total_opponents_beaten) AS total_opponents_beaten + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_pod_sizes_won) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_pod_size_won + , MAX(T_USER_DECK_LINK.max_pod_size_won) AS max_pod_size_won + , MIN(T_USER_DECK_LINK.min_pod_size_won) AS min_pod_size_won + , SUM(T_USER_DECK_LINK.total_pod_sizes_lost) AS total_pod_sizes_lost + , SUM(T_USER_DECK_LINK.total_opponents_lost_to) AS total_opponents_lost_to + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_pod_sizes_lost) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_pod_size_lost + , MAX(T_USER_DECK_LINK.max_pod_size_lost) AS max_pod_size_lost + , MIN(T_USER_DECK_LINK.min_pod_size_lost) AS min_pod_size_lost + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + GROUP BY T_USER_DECK_LINK.user_id + ) + UPDATE Temp_Statistic_Calc_User T_USER + SET + count_games = USER_SUMMARY.count_games + , count_games_won = USER_SUMMARY.count_games_won + , count_games_lost = USER_SUMMARY.count_games_lost + , win_lose_ratio = USER_SUMMARY.win_lose_ratio + , best_position = USER_SUMMARY.best_position + , worst_position = USER_SUMMARY.worst_position + , total_damage_received = USER_SUMMARY.total_damage_received + , mean_total_damage_received = USER_SUMMARY.mean_total_damage_received + , max_total_damage_received = USER_SUMMARY.max_total_damage_received + , min_total_damage_received = USER_SUMMARY.min_total_damage_received + , total_damage_received_game_win = USER_SUMMARY.total_damage_received_game_win + , mean_total_damage_received_game_win = USER_SUMMARY.mean_total_damage_received_game_win + , max_total_damage_received_game_win = USER_SUMMARY.max_total_damage_received_game_win + , min_total_damage_received_game_win = USER_SUMMARY.min_total_damage_received_game_win + , total_damage_received_game_lose = USER_SUMMARY.total_damage_received_game_lose + , mean_total_damage_received_game_lose = USER_SUMMARY.mean_total_damage_received_game_lose + , max_total_damage_received_game_lose = USER_SUMMARY.max_total_damage_received_game_lose + , min_total_damage_received_game_lose = USER_SUMMARY.min_total_damage_received_game_lose + , total_commander_damage_dealt = USER_SUMMARY.total_commander_damage_dealt + , mean_total_commander_damage_dealt = USER_SUMMARY.mean_total_commander_damage_dealt + , max_total_commander_damage_dealt = USER_SUMMARY.max_total_commander_damage_dealt + , min_total_commander_damage_dealt = USER_SUMMARY.min_total_commander_damage_dealt + , total_commander_damage_dealt_game_won = USER_SUMMARY.total_commander_damage_dealt_game_won + , mean_total_commander_damage_dealt_won = USER_SUMMARY.mean_total_commander_damage_dealt_won + , max_total_commander_damage_dealt_won = USER_SUMMARY.max_total_commander_damage_dealt_won + , min_total_commander_damage_dealt_won = USER_SUMMARY.min_total_commander_damage_dealt_won + , total_commander_damage_dealt_game_lost = USER_SUMMARY.total_commander_damage_dealt_game_lost + , mean_total_commander_damage_dealt_lost = USER_SUMMARY.mean_total_commander_damage_dealt_lost + , max_total_commander_damage_dealt_lost = USER_SUMMARY.max_total_commander_damage_dealt_lost + , min_total_commander_damage_dealt_lost = USER_SUMMARY.min_total_commander_damage_dealt_lost + , total_commander_damage_received = USER_SUMMARY.total_commander_damage_received + , mean_total_commander_damage_received = USER_SUMMARY.mean_total_commander_damage_received + , max_total_commander_damage_received = USER_SUMMARY.max_total_commander_damage_received + , min_total_commander_damage_received = USER_SUMMARY.min_total_commander_damage_received + , total_commander_damage_received_game_won = USER_SUMMARY.total_commander_damage_received_game_won + , mean_total_commander_damage_received_won = USER_SUMMARY.mean_total_commander_damage_received_won + , max_total_commander_damage_received_won = USER_SUMMARY.max_total_commander_damage_received_won + , min_total_commander_damage_received_won = USER_SUMMARY.min_total_commander_damage_received_won + , total_commander_damage_received_game_lost = USER_SUMMARY.total_commander_damage_received_game_lost + , mean_total_commander_damage_received_lost = USER_SUMMARY.mean_total_commander_damage_received_lost + , max_total_commander_damage_received_lost = USER_SUMMARY.max_total_commander_damage_received_lost + , min_total_commander_damage_received_lost = USER_SUMMARY.min_total_commander_damage_received_lost + , total_life_gained = USER_SUMMARY.total_life_gained + , mean_total_life_gained = USER_SUMMARY.mean_total_life_gained + , max_total_life_gained = USER_SUMMARY.max_total_life_gained + , min_total_life_gained = USER_SUMMARY.min_total_life_gained + , total_life_gained_game_won = USER_SUMMARY.total_life_gained_game_won + , mean_total_life_gained_game_won = USER_SUMMARY.mean_total_life_gained_game_won + , max_total_life_gained_game_won = USER_SUMMARY.max_total_life_gained_game_won + , min_total_life_gained_game_won = USER_SUMMARY.min_total_life_gained_game_won + , total_life_gained_game_lost = USER_SUMMARY.total_life_gained_game_lost + , mean_total_life_gained_game_lost = USER_SUMMARY.mean_total_life_gained_game_lost + , max_total_life_gained_game_lost = USER_SUMMARY.max_total_life_gained_game_lost + , min_total_life_gained_game_lost = USER_SUMMARY.min_total_life_gained_game_lost + , total_game_round_count = USER_SUMMARY.total_game_round_count + , mean_game_round_count = USER_SUMMARY.mean_game_round_count + , lowest_game_round_count = USER_SUMMARY.lowest_game_round_count + , highest_game_round_count = USER_SUMMARY.highest_game_round_count + , total_game_win_round_count = USER_SUMMARY.total_game_win_round_count + , mean_game_win_round_count = USER_SUMMARY.mean_game_win_round_count + , lowest_game_win_round_count = USER_SUMMARY.lowest_game_win_round_count + , highest_game_win_round_count = USER_SUMMARY.highest_game_win_round_count + , total_game_lose_round_count = USER_SUMMARY.total_game_lose_round_count + , mean_game_lose_round_count = USER_SUMMARY.mean_game_lose_round_count + , lowest_game_lose_round_count = USER_SUMMARY.lowest_game_lose_round_count + , highest_game_lose_round_count = USER_SUMMARY.highest_game_lose_round_count + , total_game_round_survived_count = USER_SUMMARY.total_game_round_survived_count + , mean_game_round_survived_count = USER_SUMMARY.mean_game_round_survived_count + , lowest_game_round_survived_count = USER_SUMMARY.lowest_game_round_survived_count + , highest_game_round_survived_count = USER_SUMMARY.highest_game_round_survived_count + , total_game_win_round_survived_count = USER_SUMMARY.total_game_win_round_survived_count + , mean_game_win_round_survived_count = USER_SUMMARY.mean_game_win_round_survived_count + , lowest_game_win_round_survived_count = USER_SUMMARY.lowest_game_win_round_survived_count + , highest_game_win_round_survived_count = USER_SUMMARY.highest_game_win_round_survived_count + , total_game_lose_round_survived_count = USER_SUMMARY.total_game_lose_round_survived_count + , mean_game_lose_round_survived_count = USER_SUMMARY.mean_game_lose_round_survived_count + , lowest_game_lose_round_survived_count = USER_SUMMARY.lowest_game_lose_round_survived_count + , highest_game_lose_round_survived_count = USER_SUMMARY.highest_game_lose_round_survived_count + , total_game_duration = USER_SUMMARY.total_game_duration + , mean_game_duration = USER_SUMMARY.mean_game_duration + , shortest_game_duration = USER_SUMMARY.shortest_game_duration + , longest_game_duration = USER_SUMMARY.longest_game_duration + , total_game_win_duration = USER_SUMMARY.total_game_win_duration + , mean_game_win_duration = USER_SUMMARY.mean_game_win_duration + , shortest_game_win_duration = USER_SUMMARY.shortest_game_win_duration + , longest_game_win_duration = USER_SUMMARY.longest_game_win_duration + , total_game_lose_duration = USER_SUMMARY.total_game_lose_duration + , mean_game_lose_duration = USER_SUMMARY.mean_game_lose_duration + , shortest_game_lose_duration = USER_SUMMARY.shortest_game_lose_duration + , longest_game_lose_duration = USER_SUMMARY.longest_game_lose_duration + , total_commander_deaths = USER_SUMMARY.total_commander_deaths + , mean_commander_deaths = USER_SUMMARY.mean_commander_deaths + , max_commander_deaths = USER_SUMMARY.max_commander_deaths + , min_commander_deaths = USER_SUMMARY.min_commander_deaths + , total_commander_deaths_game_won = USER_SUMMARY.total_commander_deaths_game_won + , mean_commander_deaths_game_won = USER_SUMMARY.mean_commander_deaths_game_won + , max_commander_deaths_game_won = USER_SUMMARY.max_commander_deaths_game_won + , min_commander_deaths_game_won = USER_SUMMARY.min_commander_deaths_game_won + , total_commander_deaths_game_lost = USER_SUMMARY.total_commander_deaths_game_lost + , mean_commander_deaths_game_lost = USER_SUMMARY.mean_commander_deaths_game_lost + , max_commander_deaths_game_lost = USER_SUMMARY.max_commander_deaths_game_lost + , min_commander_deaths_game_lost = USER_SUMMARY.min_commander_deaths_game_lost + , total_pod_sizes = USER_SUMMARY.total_pod_sizes + , total_opponents_faced = USER_SUMMARY.total_opponents_faced + , mean_pod_size = USER_SUMMARY.mean_pod_size + , max_pod_size = USER_SUMMARY.max_pod_size + , min_pod_size = USER_SUMMARY.min_pod_size + , total_pod_sizes_won = USER_SUMMARY.total_pod_sizes_won + , total_opponents_beaten = USER_SUMMARY.total_opponents_beaten + , mean_pod_size_won = USER_SUMMARY.mean_pod_size_won + , max_pod_size_won = USER_SUMMARY.max_pod_size_won + , min_pod_size_won = USER_SUMMARY.min_pod_size_won + , total_pod_sizes_lost = USER_SUMMARY.total_pod_sizes_lost + , total_opponents_lost_to = USER_SUMMARY.total_opponents_lost_to + , mean_pod_size_lost = USER_SUMMARY.mean_pod_size_lost + , max_pod_size_lost = USER_SUMMARY.max_pod_size_lost + , min_pod_size_lost = USER_SUMMARY.min_pod_size_lost + , latest_game_win_on = LATEST_USER_WIN.latest_game_win_on + , latest_game_win_pod_size = LATEST_USER_WIN.latest_game_win_pod_size + , latest_game_lose_on = LATEST_USER_LOSE.latest_game_lose_on + , latest_game_lose_pod_size = LATEST_USER_LOSE.latest_game_lose_pod_size + FROM User_Summary USER_SUMMARY + INNER JOIN Latest_User_Win LATEST_USER_WIN + ON USER_SUMMARY.user_id = LATEST_USER_WIN.user_id + AND LATEST_USER_WIN.index_win_in_user = 1 + INNER JOIN Latest_User_Lose LATEST_USER_LOSE + ON USER_SUMMARY.user_id = LATEST_USER_LOSE.user_id + AND LATEST_USER_LOSE.index_lose_in_user = 1 + WHERE USER_SUMMARY.user_id = T_USER.user_id + ; + + -- Decks + WITH + Latest_Deck_Win AS ( + SELECT + T_USER_DECK_LINK.deck_id + , T_USER_DECK_LINK.latest_game_win_pod_size + , T_USER_DECK_LINK.latest_game_win_on + , ROW_NUMBER() OVER ( + PARTITION BY T_USER_DECK_LINK.deck_id + ORDER BY T_USER_DECK_LINK.latest_game_win_on DESC + ) AS index_win_in_deck + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + GROUP BY + T_USER_DECK_LINK.deck_id + , T_USER_DECK_LINK.latest_game_win_pod_size + , T_USER_DECK_LINK.latest_game_win_on + ) + , Latest_Deck_Lose AS ( + SELECT + T_USER_DECK_LINK.deck_id + , T_USER_DECK_LINK.latest_game_lose_pod_size + , T_USER_DECK_LINK.latest_game_lose_on + , ROW_NUMBER() OVER ( + PARTITION BY T_USER_DECK_LINK.deck_id + ORDER BY T_USER_DECK_LINK.latest_game_lose_on DESC + ) AS index_lose_in_deck + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + GROUP BY + T_USER_DECK_LINK.deck_id + , T_USER_DECK_LINK.latest_game_lose_pod_size + , T_USER_DECK_LINK.latest_game_lose_on + ) + , Deck_Summary AS ( + SELECT + T_USER_DECK_LINK.deck_id + , SUM(T_USER_DECK_LINK.count_games) AS count_games + , SUM(T_USER_DECK_LINK.count_games_won) AS count_games_won + , SUM(T_USER_DECK_LINK.count_games_lost) AS count_games_lost + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_lost) > 0 + THEN SUM(T_USER_DECK_LINK.count_games_won) / SUM(T_USER_DECK_LINK.count_games_lost) + ELSE COALESCE(SUM(T_USER_DECK_LINK.count_games_won), 0) + END AS win_lose_ratio + , MIN(T_USER_DECK_LINK.best_position) AS best_position + , MAX(T_USER_DECK_LINK.worst_position) AS worst_position + , SUM(T_USER_DECK_LINK.total_damage_received) AS total_damage_received + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_damage_received) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_total_damage_received + , MAX(T_USER_DECK_LINK.max_total_damage_received) AS max_total_damage_received + , MIN(T_USER_DECK_LINK.min_total_damage_received) AS min_total_damage_received + , SUM(T_USER_DECK_LINK.total_damage_received_game_win) AS total_damage_received_game_win + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_won) > 0 + THEN SUM(T_USER_DECK_LINK.total_damage_received_game_win) / SUM(T_USER_DECK_LINK.count_games_won) + ELSE 0 + END AS mean_total_damage_received_game_win + , MAX(T_USER_DECK_LINK.max_total_damage_received_game_win) AS max_total_damage_received_game_win + , MIN(T_USER_DECK_LINK.min_total_damage_received_game_win) AS min_total_damage_received_game_win + , SUM(T_USER_DECK_LINK.total_damage_received_game_lose) AS total_damage_received_game_lose + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_lost) > 0 + THEN SUM(T_USER_DECK_LINK.total_damage_received_game_lose) / SUM(T_USER_DECK_LINK.count_games_lost) + ELSE 0 + END AS mean_total_damage_received_game_lose + , MAX(T_USER_DECK_LINK.max_total_damage_received_game_lose) AS max_total_damage_received_game_lose + , MIN(T_USER_DECK_LINK.min_total_damage_received_game_lose) AS min_total_damage_received_game_lose + , SUM(T_USER_DECK_LINK.total_commander_damage_dealt) AS total_commander_damage_dealt + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_commander_damage_dealt) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_total_commander_damage_dealt + , MAX(T_USER_DECK_LINK.max_total_commander_damage_dealt) AS max_total_commander_damage_dealt + , MIN(T_USER_DECK_LINK.min_total_commander_damage_dealt) AS min_total_commander_damage_dealt + , SUM(T_USER_DECK_LINK.total_commander_damage_dealt_game_won) AS total_commander_damage_dealt_game_won + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_won) > 0 + THEN SUM(T_USER_DECK_LINK.total_commander_damage_dealt_game_won) / SUM(T_USER_DECK_LINK.count_games_won) + ELSE 0 + END AS mean_total_commander_damage_dealt_won + , MAX(T_USER_DECK_LINK.max_total_commander_damage_dealt_won) AS max_total_commander_damage_dealt_won + , MIN(T_USER_DECK_LINK.min_total_commander_damage_dealt_won) AS min_total_commander_damage_dealt_won + , SUM(T_USER_DECK_LINK.total_commander_damage_dealt_game_lost) AS total_commander_damage_dealt_game_lost + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_lost) > 0 + THEN SUM(T_USER_DECK_LINK.total_commander_damage_dealt_game_lost) / SUM(T_USER_DECK_LINK.count_games_lost) + ELSE 0 + END AS mean_total_commander_damage_dealt_lost + , MAX(T_USER_DECK_LINK.max_total_commander_damage_dealt_lost) AS max_total_commander_damage_dealt_lost + , MIN(T_USER_DECK_LINK.min_total_commander_damage_dealt_lost) AS min_total_commander_damage_dealt_lost + , SUM(T_USER_DECK_LINK.total_commander_damage_received) AS total_commander_damage_received + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_commander_damage_received) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_total_commander_damage_received + , MAX(T_USER_DECK_LINK.max_total_commander_damage_received) AS max_total_commander_damage_received + , MIN(T_USER_DECK_LINK.min_total_commander_damage_received) AS min_total_commander_damage_received + , SUM(T_USER_DECK_LINK.total_commander_damage_received_game_won) AS total_commander_damage_received_game_won + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_won) > 0 + THEN SUM(T_USER_DECK_LINK.total_commander_damage_received_game_won) / SUM(T_USER_DECK_LINK.count_games_won) + ELSE 0 + END AS mean_total_commander_damage_received_won + , MAX(T_USER_DECK_LINK.max_total_commander_damage_received_won) AS max_total_commander_damage_received_won + , MIN(T_USER_DECK_LINK.min_total_commander_damage_received_won) AS min_total_commander_damage_received_won + , SUM(T_USER_DECK_LINK.total_commander_damage_received_game_lost) AS total_commander_damage_received_game_lost + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_lost) > 0 + THEN SUM(T_USER_DECK_LINK.total_commander_damage_received_game_lost) / SUM(T_USER_DECK_LINK.count_games_lost) + ELSE 0 + END AS mean_total_commander_damage_received_lost + , MAX(T_USER_DECK_LINK.max_total_commander_damage_received_lost) AS max_total_commander_damage_received_lost + , MIN(T_USER_DECK_LINK.min_total_commander_damage_received_lost) AS min_total_commander_damage_received_lost + , SUM(T_USER_DECK_LINK.total_life_gained) AS total_life_gained + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_life_gained) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_total_life_gained + , MAX(T_USER_DECK_LINK.max_total_life_gained) AS max_total_life_gained + , MIN(T_USER_DECK_LINK.min_total_life_gained) AS min_total_life_gained + , SUM(T_USER_DECK_LINK.total_life_gained_game_won) AS total_life_gained_game_won + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_won) > 0 + THEN SUM(T_USER_DECK_LINK.total_life_gained_game_won) / SUM(T_USER_DECK_LINK.count_games_won) + ELSE 0 + END AS mean_total_life_gained_game_won + , MAX(T_USER_DECK_LINK.max_total_life_gained_game_won) AS max_total_life_gained_game_won + , MIN(T_USER_DECK_LINK.min_total_life_gained_game_won) AS min_total_life_gained_game_won + , SUM(T_USER_DECK_LINK.total_life_gained_game_lost) AS total_life_gained_game_lost + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_lost) > 0 + THEN SUM(T_USER_DECK_LINK.total_life_gained_game_lost) / SUM(T_USER_DECK_LINK.count_games_lost) + ELSE 0 + END AS mean_total_life_gained_game_lost + , MAX(T_USER_DECK_LINK.max_total_life_gained_game_lost) AS max_total_life_gained_game_lost + , MIN(T_USER_DECK_LINK.min_total_life_gained_game_lost) AS min_total_life_gained_game_lost + , SUM(T_USER_DECK_LINK.total_game_round_count) AS total_game_round_count + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_game_round_count) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_game_round_count + , MIN(T_USER_DECK_LINK.lowest_game_round_count) AS lowest_game_round_count + , MAX(T_USER_DECK_LINK.highest_game_round_count) AS highest_game_round_count + , SUM(T_USER_DECK_LINK.total_game_win_round_count) AS total_game_win_round_count + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_won) > 0 + THEN SUM(T_USER_DECK_LINK.total_game_win_round_count) / SUM(T_USER_DECK_LINK.count_games_won) + ELSE 0 + END AS mean_game_win_round_count + , MIN(T_USER_DECK_LINK.lowest_game_win_round_count) AS lowest_game_win_round_count + , MAX(T_USER_DECK_LINK.highest_game_win_round_count) AS highest_game_win_round_count + , SUM(T_USER_DECK_LINK.total_game_lose_round_count) AS total_game_lose_round_count + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_lost) > 0 + THEN SUM(T_USER_DECK_LINK.total_game_lose_round_count) / SUM(T_USER_DECK_LINK.count_games_lost) + ELSE 0 + END AS mean_game_lose_round_count + , MIN(T_USER_DECK_LINK.lowest_game_lose_round_count) AS lowest_game_lose_round_count + , MAX(T_USER_DECK_LINK.highest_game_lose_round_count) AS highest_game_lose_round_count + , SUM(T_USER_DECK_LINK.total_game_round_survived_count) AS total_game_round_survived_count + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_game_round_survived_count) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_game_round_survived_count + , MIN(T_USER_DECK_LINK.lowest_game_round_survived_count) AS lowest_game_round_survived_count + , MAX(T_USER_DECK_LINK.highest_game_round_survived_count) AS highest_game_round_survived_count + , SUM(T_USER_DECK_LINK.total_game_win_round_survived_count) AS total_game_win_round_survived_count + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_won) > 0 + THEN SUM(T_USER_DECK_LINK.total_game_win_round_survived_count) / SUM(T_USER_DECK_LINK.count_games_won) + ELSE 0 + END AS mean_game_win_round_survived_count + , MIN(T_USER_DECK_LINK.lowest_game_win_round_survived_count) AS lowest_game_win_round_survived_count + , MAX(T_USER_DECK_LINK.highest_game_win_round_survived_count) AS highest_game_win_round_survived_count + , SUM(T_USER_DECK_LINK.total_game_lose_round_survived_count) AS total_game_lose_round_survived_count + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_game_lose_round_survived_count) / SUM(T_USER_DECK_LINK.count_games_lost) + ELSE 0 + END AS mean_game_lose_round_survived_count + , MIN(T_USER_DECK_LINK.lowest_game_lose_round_survived_count) AS lowest_game_lose_round_survived_count + , MAX(T_USER_DECK_LINK.highest_game_lose_round_survived_count) AS highest_game_lose_round_survived_count + , SUM(T_USER_DECK_LINK.total_game_duration) AS total_game_duration + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_game_duration) / SUM(T_USER_DECK_LINK.count_games) + ELSE INTERVAL '0' + END AS mean_game_duration + , MIN(T_USER_DECK_LINK.shortest_game_duration) AS shortest_game_duration + , MAX(T_USER_DECK_LINK.longest_game_duration) AS longest_game_duration + , SUM(T_USER_DECK_LINK.total_game_win_duration) AS total_game_win_duration + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_won) > 0 + THEN SUM(T_USER_DECK_LINK.total_game_win_duration) / SUM(T_USER_DECK_LINK.count_games_won) + ELSE INTERVAL '0' + END AS mean_game_win_duration + , MIN(T_USER_DECK_LINK.shortest_game_win_duration) AS shortest_game_win_duration + , MAX(T_USER_DECK_LINK.longest_game_win_duration) AS longest_game_win_duration + , SUM(T_USER_DECK_LINK.total_game_lose_duration) AS total_game_lose_duration + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_lost) > 0 + THEN SUM(T_USER_DECK_LINK.total_game_lose_duration) / SUM(T_USER_DECK_LINK.count_games_lost) + ELSE INTERVAL '0' + END AS mean_game_lose_duration + , MIN(T_USER_DECK_LINK.shortest_game_lose_duration) AS shortest_game_lose_duration + , MAX(T_USER_DECK_LINK.longest_game_lose_duration) AS longest_game_lose_duration + , SUM(T_USER_DECK_LINK.total_commander_deaths) AS total_commander_deaths + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_commander_deaths) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_commander_deaths + , MAX(T_USER_DECK_LINK.max_commander_deaths) AS max_commander_deaths + , MIN(T_USER_DECK_LINK.min_commander_deaths) AS min_commander_deaths + , SUM(T_USER_DECK_LINK.total_commander_deaths_game_won) AS total_commander_deaths_game_won + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games_won) > 0 + THEN SUM(T_USER_DECK_LINK.total_commander_deaths_game_won) / SUM(T_USER_DECK_LINK.count_games_won) + ELSE 0 + END AS mean_commander_deaths_game_won + , MAX(T_USER_DECK_LINK.max_commander_deaths_game_won) AS max_commander_deaths_game_won + , MIN(T_USER_DECK_LINK.min_commander_deaths_game_won) AS min_commander_deaths_game_won + , SUM(T_USER_DECK_LINK.total_commander_deaths_game_lost) AS total_commander_deaths_game_lost + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_commander_deaths_game_lost) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_commander_deaths_game_lost + , MAX(T_USER_DECK_LINK.max_commander_deaths_game_lost) AS max_commander_deaths_game_lost + , MIN(T_USER_DECK_LINK.min_commander_deaths_game_lost) AS min_commander_deaths_game_lost + , SUM(T_USER_DECK_LINK.total_pod_sizes) AS total_pod_sizes + , SUM(T_USER_DECK_LINK.total_opponents_faced) AS total_opponents_faced + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_pod_sizes) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_pod_size + , MAX(T_USER_DECK_LINK.max_pod_size) AS max_pod_size + , MIN(T_USER_DECK_LINK.min_pod_size) AS min_pod_size + , SUM(T_USER_DECK_LINK.total_pod_sizes_won) AS total_pod_sizes_won + , SUM(T_USER_DECK_LINK.total_opponents_beaten) AS total_opponents_beaten + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_pod_sizes_won) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_pod_size_won + , MAX(T_USER_DECK_LINK.max_pod_size_won) AS max_pod_size_won + , MIN(T_USER_DECK_LINK.min_pod_size_won) AS min_pod_size_won + , SUM(T_USER_DECK_LINK.total_pod_sizes_lost) AS total_pod_sizes_lost + , SUM(T_USER_DECK_LINK.total_opponents_lost_to) AS total_opponents_lost_to + , CASE + WHEN SUM(T_USER_DECK_LINK.count_games) > 0 + THEN SUM(T_USER_DECK_LINK.total_pod_sizes_lost) / SUM(T_USER_DECK_LINK.count_games) + ELSE 0 + END AS mean_pod_size_lost + , MAX(T_USER_DECK_LINK.max_pod_size_lost) AS max_pod_size_lost + , MIN(T_USER_DECK_LINK.min_pod_size_lost) AS min_pod_size_lost + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + GROUP BY T_USER_DECK_LINK.deck_id + ) + UPDATE Temp_Statistic_Calc_Deck T_DECK + SET + count_games = DECK_SUMMARY.count_games + , count_games_won = DECK_SUMMARY.count_games_won + , count_games_lost = DECK_SUMMARY.count_games_lost + , win_lose_ratio = DECK_SUMMARY.win_lose_ratio + , best_position = DECK_SUMMARY.best_position + , worst_position = DECK_SUMMARY.worst_position + , total_damage_received = DECK_SUMMARY.total_damage_received + , mean_total_damage_received = DECK_SUMMARY.mean_total_damage_received + , max_total_damage_received = DECK_SUMMARY.max_total_damage_received + , min_total_damage_received = DECK_SUMMARY.min_total_damage_received + , total_damage_received_game_win = DECK_SUMMARY.total_damage_received_game_win + , mean_total_damage_received_game_win = DECK_SUMMARY.mean_total_damage_received_game_win + , max_total_damage_received_game_win = DECK_SUMMARY.max_total_damage_received_game_win + , min_total_damage_received_game_win = DECK_SUMMARY.min_total_damage_received_game_win + , total_damage_received_game_lose = DECK_SUMMARY.total_damage_received_game_lose + , mean_total_damage_received_game_lose = DECK_SUMMARY.mean_total_damage_received_game_lose + , max_total_damage_received_game_lose = DECK_SUMMARY.max_total_damage_received_game_lose + , min_total_damage_received_game_lose = DECK_SUMMARY.min_total_damage_received_game_lose + , total_commander_damage_dealt = DECK_SUMMARY.total_commander_damage_dealt + , mean_total_commander_damage_dealt = DECK_SUMMARY.mean_total_commander_damage_dealt + , max_total_commander_damage_dealt = DECK_SUMMARY.max_total_commander_damage_dealt + , min_total_commander_damage_dealt = DECK_SUMMARY.min_total_commander_damage_dealt + , total_commander_damage_dealt_game_won = DECK_SUMMARY.total_commander_damage_dealt_game_won + , mean_total_commander_damage_dealt_won = DECK_SUMMARY.mean_total_commander_damage_dealt_won + , max_total_commander_damage_dealt_won = DECK_SUMMARY.max_total_commander_damage_dealt_won + , min_total_commander_damage_dealt_won = DECK_SUMMARY.min_total_commander_damage_dealt_won + , total_commander_damage_dealt_game_lost = DECK_SUMMARY.total_commander_damage_dealt_game_lost + , mean_total_commander_damage_dealt_lost = DECK_SUMMARY.mean_total_commander_damage_dealt_lost + , max_total_commander_damage_dealt_lost = DECK_SUMMARY.max_total_commander_damage_dealt_lost + , min_total_commander_damage_dealt_lost = DECK_SUMMARY.min_total_commander_damage_dealt_lost + , total_commander_damage_received = DECK_SUMMARY.total_commander_damage_received + , mean_total_commander_damage_received = DECK_SUMMARY.mean_total_commander_damage_received + , max_total_commander_damage_received = DECK_SUMMARY.max_total_commander_damage_received + , min_total_commander_damage_received = DECK_SUMMARY.min_total_commander_damage_received + , total_commander_damage_received_game_won = DECK_SUMMARY.total_commander_damage_received_game_won + , mean_total_commander_damage_received_won = DECK_SUMMARY.mean_total_commander_damage_received_won + , max_total_commander_damage_received_won = DECK_SUMMARY.max_total_commander_damage_received_won + , min_total_commander_damage_received_won = DECK_SUMMARY.min_total_commander_damage_received_won + , total_commander_damage_received_game_lost = DECK_SUMMARY.total_commander_damage_received_game_lost + , mean_total_commander_damage_received_lost = DECK_SUMMARY.mean_total_commander_damage_received_lost + , max_total_commander_damage_received_lost = DECK_SUMMARY.max_total_commander_damage_received_lost + , min_total_commander_damage_received_lost = DECK_SUMMARY.min_total_commander_damage_received_lost + , total_life_gained = DECK_SUMMARY.total_life_gained + , mean_total_life_gained = DECK_SUMMARY.mean_total_life_gained + , max_total_life_gained = DECK_SUMMARY.max_total_life_gained + , min_total_life_gained = DECK_SUMMARY.min_total_life_gained + , total_life_gained_game_won = DECK_SUMMARY.total_life_gained_game_won + , mean_total_life_gained_game_won = DECK_SUMMARY.mean_total_life_gained_game_won + , max_total_life_gained_game_won = DECK_SUMMARY.max_total_life_gained_game_won + , min_total_life_gained_game_won = DECK_SUMMARY.min_total_life_gained_game_won + , total_life_gained_game_lost = DECK_SUMMARY.total_life_gained_game_lost + , mean_total_life_gained_game_lost = DECK_SUMMARY.mean_total_life_gained_game_lost + , max_total_life_gained_game_lost = DECK_SUMMARY.max_total_life_gained_game_lost + , min_total_life_gained_game_lost = DECK_SUMMARY.min_total_life_gained_game_lost + , total_game_round_count = DECK_SUMMARY.total_game_round_count + , mean_game_round_count = DECK_SUMMARY.mean_game_round_count + , lowest_game_round_count = DECK_SUMMARY.lowest_game_round_count + , highest_game_round_count = DECK_SUMMARY.highest_game_round_count + , total_game_win_round_count = DECK_SUMMARY.total_game_win_round_count + , mean_game_win_round_count = DECK_SUMMARY.mean_game_win_round_count + , lowest_game_win_round_count = DECK_SUMMARY.lowest_game_win_round_count + , highest_game_win_round_count = DECK_SUMMARY.highest_game_win_round_count + , total_game_lose_round_count = DECK_SUMMARY.total_game_lose_round_count + , mean_game_lose_round_count = DECK_SUMMARY.mean_game_lose_round_count + , lowest_game_lose_round_count = DECK_SUMMARY.lowest_game_lose_round_count + , highest_game_lose_round_count = DECK_SUMMARY.highest_game_lose_round_count + , total_game_round_survived_count = DECK_SUMMARY.total_game_round_survived_count + , mean_game_round_survived_count = DECK_SUMMARY.mean_game_round_survived_count + , lowest_game_round_survived_count = DECK_SUMMARY.lowest_game_round_survived_count + , highest_game_round_survived_count = DECK_SUMMARY.highest_game_round_survived_count + , total_game_win_round_survived_count = DECK_SUMMARY.total_game_win_round_survived_count + , mean_game_win_round_survived_count = DECK_SUMMARY.mean_game_win_round_survived_count + , lowest_game_win_round_survived_count = DECK_SUMMARY.lowest_game_win_round_survived_count + , highest_game_win_round_survived_count = DECK_SUMMARY.highest_game_win_round_survived_count + , total_game_lose_round_survived_count = DECK_SUMMARY.total_game_lose_round_survived_count + , mean_game_lose_round_survived_count = DECK_SUMMARY.mean_game_lose_round_survived_count + , lowest_game_lose_round_survived_count = DECK_SUMMARY.lowest_game_lose_round_survived_count + , highest_game_lose_round_survived_count = DECK_SUMMARY.highest_game_lose_round_survived_count + , total_game_duration = DECK_SUMMARY.total_game_duration + , mean_game_duration = DECK_SUMMARY.mean_game_duration + , shortest_game_duration = DECK_SUMMARY.shortest_game_duration + , longest_game_duration = DECK_SUMMARY.longest_game_duration + , total_game_win_duration = DECK_SUMMARY.total_game_win_duration + , mean_game_win_duration = DECK_SUMMARY.mean_game_win_duration + , shortest_game_win_duration = DECK_SUMMARY.shortest_game_win_duration + , longest_game_win_duration = DECK_SUMMARY.longest_game_win_duration + , total_game_lose_duration = DECK_SUMMARY.total_game_lose_duration + , mean_game_lose_duration = DECK_SUMMARY.mean_game_lose_duration + , shortest_game_lose_duration = DECK_SUMMARY.shortest_game_lose_duration + , longest_game_lose_duration = DECK_SUMMARY.longest_game_lose_duration + , total_commander_deaths = DECK_SUMMARY.total_commander_deaths + , mean_commander_deaths = DECK_SUMMARY.mean_commander_deaths + , max_commander_deaths = DECK_SUMMARY.max_commander_deaths + , min_commander_deaths = DECK_SUMMARY.min_commander_deaths + , total_commander_deaths_game_won = DECK_SUMMARY.total_commander_deaths_game_won + , mean_commander_deaths_game_won = DECK_SUMMARY.mean_commander_deaths_game_won + , max_commander_deaths_game_won = DECK_SUMMARY.max_commander_deaths_game_won + , min_commander_deaths_game_won = DECK_SUMMARY.min_commander_deaths_game_won + , total_commander_deaths_game_lost = DECK_SUMMARY.total_commander_deaths_game_lost + , mean_commander_deaths_game_lost = DECK_SUMMARY.mean_commander_deaths_game_lost + , max_commander_deaths_game_lost = DECK_SUMMARY.max_commander_deaths_game_lost + , min_commander_deaths_game_lost = DECK_SUMMARY.min_commander_deaths_game_lost + , total_pod_sizes = DECK_SUMMARY.total_pod_sizes + , total_opponents_faced = DECK_SUMMARY.total_opponents_faced + , mean_pod_size = DECK_SUMMARY.mean_pod_size + , max_pod_size = DECK_SUMMARY.max_pod_size + , min_pod_size = DECK_SUMMARY.min_pod_size + , total_pod_sizes_won = DECK_SUMMARY.total_pod_sizes_won + , total_opponents_beaten = DECK_SUMMARY.total_opponents_beaten + , mean_pod_size_won = DECK_SUMMARY.mean_pod_size_won + , max_pod_size_won = DECK_SUMMARY.max_pod_size_won + , min_pod_size_won = DECK_SUMMARY.min_pod_size_won + , total_pod_sizes_lost = DECK_SUMMARY.total_pod_sizes_lost + , total_opponents_lost_to = DECK_SUMMARY.total_opponents_lost_to + , mean_pod_size_lost = DECK_SUMMARY.mean_pod_size_lost + , max_pod_size_lost = DECK_SUMMARY.max_pod_size_lost + , min_pod_size_lost = DECK_SUMMARY.min_pod_size_lost + , latest_game_win_on = LATEST_DECK_WIN.latest_game_win_on + , latest_game_win_pod_size = LATEST_DECK_WIN.latest_game_win_pod_size + , latest_game_lose_on = LATEST_DECK_LOSE.latest_game_lose_on + , latest_game_lose_pod_size = LATEST_DECK_LOSE.latest_game_lose_pod_size + FROM Deck_Summary DECK_SUMMARY + INNER JOIN Latest_Deck_Win LATEST_DECK_WIN + ON DECK_SUMMARY.deck_id = LATEST_DECK_WIN.deck_id + AND LATEST_DECK_WIN.index_win_in_deck = 1 + INNER JOIN Latest_Deck_Lose LATEST_DECK_LOSE + ON DECK_SUMMARY.deck_id = LATEST_DECK_LOSE.deck_id + AND LATEST_DECK_LOSE.index_lose_in_deck = 1 + WHERE DECK_SUMMARY.deck_id = T_DECK.deck_id + ; + + INSERT INTO Temp_Statistic_Calc_Statistic ( + entity_type_code + , entity_record_id + , name + , value_bool + , value_float + , value_interval + , value_text + , value_timestamp + , is_bool + , is_float + , is_interval + , is_text + , is_timestamp + , active + ) + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Count games' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.count_games -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Count games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.count_games_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Count games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.count_games_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Win / lose ratio' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.win_lose_ratio -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Best position' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.best_position -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Worst position' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.worst_position -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean total damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_total_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max total damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.max_total_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min total damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.min_total_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_damage_received_game_win -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean total damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_total_damage_received_game_win -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max total damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.max_total_damage_received_game_win -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min total damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.min_total_damage_received_game_win -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_damage_received_game_lose -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean total damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_total_damage_received_game_lose -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max total damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.max_total_damage_received_game_lose -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min total damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.min_total_damage_received_game_lose -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total commander damage dealt' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_commander_damage_dealt -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean total commander damage dealt' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_total_commander_damage_dealt -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max total commander damage dealt' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.max_total_commander_damage_dealt -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min total commander damage dealt' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.min_total_commander_damage_dealt -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total commander damage dealt in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_commander_damage_dealt_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean total commander damage dealt in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_total_commander_damage_dealt_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max total commander damage dealt in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.max_total_commander_damage_dealt_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min total commander damage dealt in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.min_total_commander_damage_dealt_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total commander damage dealt in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_commander_damage_dealt_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean total commander damage dealt in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_total_commander_damage_dealt_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max total commander damage dealt in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.max_total_commander_damage_dealt_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min total commander damage dealt in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.min_total_commander_damage_dealt_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total commander damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_commander_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean total commander damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_total_commander_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max total commander damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.max_total_commander_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min total commander damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.min_total_commander_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total commander damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_commander_damage_received_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean total commander damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_total_commander_damage_received_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max total commander damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.max_total_commander_damage_received_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min total commander damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.min_total_commander_damage_received_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total commander damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_commander_damage_received_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean total commander damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_total_commander_damage_received_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max total commander damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.max_total_commander_damage_received_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min total commander damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.min_total_commander_damage_received_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total life gained' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_life_gained -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean total life gained' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_total_life_gained -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max total life gained' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.max_total_life_gained -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min total life gained' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.min_total_life_gained -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total life gained in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_life_gained_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean total life gained in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_total_life_gained_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max total life gained in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.max_total_life_gained_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min total life gained in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.min_total_life_gained_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total life gained in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_life_gained_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean total life gained in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_total_life_gained_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max total life gained in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.max_total_life_gained_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min total life gained in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.min_total_life_gained_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total game round count' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_game_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean total game round count' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_game_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min total game round count' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.lowest_game_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max total game round count' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.highest_game_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total game round count in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_game_win_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean total game round count in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_game_win_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min total game round count in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.lowest_game_win_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max total game round count in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.highest_game_win_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total game round count in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_game_lose_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean total game round count in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_game_lose_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min total game round count in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.lowest_game_lose_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max total game round count in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.highest_game_lose_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total game round count survived' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_game_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean total game round count survived' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_game_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min total game round count survived' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.lowest_game_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max total game round count survived' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.highest_game_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total game round count survived in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_game_win_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean total game round count survived in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_game_win_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min total game round count survived in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.lowest_game_win_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max total game round count survived in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.highest_game_win_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total game round count survived in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_game_lose_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean total game round count survived in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_game_lose_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min total game round count survived in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.lowest_game_lose_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max total game round count survived in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.highest_game_lose_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total game duration' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER_DECK_LINK.total_game_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean game duration' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER_DECK_LINK.mean_game_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min game duration' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER_DECK_LINK.shortest_game_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max game duration' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER_DECK_LINK.longest_game_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total game duration in games won' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER_DECK_LINK.total_game_win_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean game duration in games won' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER_DECK_LINK.mean_game_win_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min game duration in games won' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER_DECK_LINK.shortest_game_win_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max game duration in games won' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER_DECK_LINK.longest_game_win_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total game duration in games lost' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER_DECK_LINK.total_game_lose_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean game duration in games lost' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER_DECK_LINK.mean_game_lose_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min game duration in games lost' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER_DECK_LINK.shortest_game_lose_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max game duration in games lost' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER_DECK_LINK.longest_game_lose_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total commander deaths' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_commander_deaths -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean commander deaths' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_commander_deaths -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max commander deaths' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.max_commander_deaths -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min commander deaths' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.min_commander_deaths -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total commander deaths in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_commander_deaths_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean commander deaths in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_commander_deaths_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max commander deaths in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.max_commander_deaths_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min commander deaths in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.min_commander_deaths_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total commander deaths in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_commander_deaths_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean commander deaths in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_commander_deaths_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max commander deaths in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.max_commander_deaths_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min commander deaths in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.min_commander_deaths_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total pod sizes' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_pod_sizes -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total opponents faced' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_opponents_faced -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean pod size' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_pod_size -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max pod size' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.max_pod_size -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min pod size' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.min_pod_size -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total pod sizes in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_pod_sizes_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total opponents beaten' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_opponents_beaten -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean pod size in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_pod_size_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max pod size in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.max_pod_size_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min pod size in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.min_pod_size_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total pod sizes in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_pod_sizes_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Total opponents lost to' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.total_opponents_lost_to -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Mean pod size in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.mean_pod_size_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Max pod size in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.max_pod_size_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_user_deck_link_entity_type_code -- entity_type_code + , CONCAT( + '{ user_id: ' + , CAST(T_USER_DECK_LINK.user_id AS VARCHAR) + , ', deck_id: ' + , CAST(T_USER_DECK_LINK.deck_id AS VARCHAR) + , '}' + ) -- entity_record_id + , 'Min pod size in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER_DECK_LINK.min_pod_size_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User_Deck_Link T_USER_DECK_LINK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Count games' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.count_games -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Count games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.count_games_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Count games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.count_games_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Win / lose ratio' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.win_lose_ratio -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Best position' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.best_position -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Worst position' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.worst_position -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean total damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_total_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max total damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.max_total_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min total damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.min_total_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_damage_received_game_win -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean total damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_total_damage_received_game_win -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max total damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.max_total_damage_received_game_win -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min total damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.min_total_damage_received_game_win -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_damage_received_game_lose -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean total damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_total_damage_received_game_lose -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max total damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.max_total_damage_received_game_lose -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min total damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.min_total_damage_received_game_lose -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total commander damage dealt' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_commander_damage_dealt -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean total commander damage dealt' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_total_commander_damage_dealt -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max total commander damage dealt' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.max_total_commander_damage_dealt -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min total commander damage dealt' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.min_total_commander_damage_dealt -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total commander damage dealt in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_commander_damage_dealt_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean total commander damage dealt in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_total_commander_damage_dealt_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max total commander damage dealt in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.max_total_commander_damage_dealt_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min total commander damage dealt in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.min_total_commander_damage_dealt_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total commander damage dealt in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_commander_damage_dealt_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean total commander damage dealt in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_total_commander_damage_dealt_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max total commander damage dealt in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.max_total_commander_damage_dealt_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min total commander damage dealt in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.min_total_commander_damage_dealt_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total commander damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_commander_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean total commander damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_total_commander_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max total commander damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.max_total_commander_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min total commander damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.min_total_commander_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total commander damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_commander_damage_received_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean total commander damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_total_commander_damage_received_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max total commander damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.max_total_commander_damage_received_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min total commander damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.min_total_commander_damage_received_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total commander damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_commander_damage_received_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean total commander damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_total_commander_damage_received_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max total commander damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.max_total_commander_damage_received_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min total commander damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.min_total_commander_damage_received_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total life gained' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_life_gained -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean total life gained' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_total_life_gained -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max total life gained' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.max_total_life_gained -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min total life gained' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.min_total_life_gained -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total life gained in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_life_gained_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean total life gained in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_total_life_gained_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max total life gained in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.max_total_life_gained_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min total life gained in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.min_total_life_gained_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total life gained in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_life_gained_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean total life gained in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_total_life_gained_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max total life gained in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.max_total_life_gained_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min total life gained in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.min_total_life_gained_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total game round count' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_game_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean total game round count' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_game_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min total game round count' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.lowest_game_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max total game round count' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.highest_game_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total game round count in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_game_win_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean total game round count in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_game_win_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min total game round count in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.lowest_game_win_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max total game round count in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.highest_game_win_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total game round count in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_game_lose_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean total game round count in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_game_lose_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min total game round count in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.lowest_game_lose_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max total game round count in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.highest_game_lose_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total game round count survived' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_game_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean total game round count survived' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_game_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min total game round count survived' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.lowest_game_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max total game round count survived' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.highest_game_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total game round count survived in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_game_win_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean total game round count survived in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_game_win_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min total game round count survived in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.lowest_game_win_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max total game round count survived in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.highest_game_win_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total game round count survived in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_game_lose_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean total game round count survived in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_game_lose_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min total game round count survived in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.lowest_game_lose_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max total game round count survived in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.highest_game_lose_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total game duration' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_DECK.total_game_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean game duration' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_DECK.mean_game_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min game duration' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_DECK.shortest_game_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max game duration' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_DECK.longest_game_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total game duration in games won' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_DECK.total_game_win_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean game duration in games won' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_DECK.mean_game_win_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min game duration in games won' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_DECK.shortest_game_win_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max game duration in games won' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_DECK.longest_game_win_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total game duration in games lost' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_DECK.total_game_lose_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean game duration in games lost' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_DECK.mean_game_lose_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min game duration in games lost' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_DECK.shortest_game_lose_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max game duration in games lost' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_DECK.longest_game_lose_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total commander deaths' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_commander_deaths -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean commander deaths' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_commander_deaths -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max commander deaths' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.max_commander_deaths -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min commander deaths' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.min_commander_deaths -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total commander deaths in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_commander_deaths_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean commander deaths in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_commander_deaths_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max commander deaths in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.max_commander_deaths_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min commander deaths in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.min_commander_deaths_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total commander deaths in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_commander_deaths_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean commander deaths in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_commander_deaths_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max commander deaths in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.max_commander_deaths_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min commander deaths in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.min_commander_deaths_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total pod sizes' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_pod_sizes -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total opponents faced' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_opponents_faced -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean pod size' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_pod_size -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max pod size' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.max_pod_size -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min pod size' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.min_pod_size -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total pod sizes in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_pod_sizes_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total opponents beaten' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_opponents_beaten -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean pod size in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_pod_size_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max pod size in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.max_pod_size_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min pod size in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.min_pod_size_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total pod sizes in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_pod_sizes_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Total opponents lost to' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.total_opponents_lost_to -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Mean pod size in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.mean_pod_size_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Max pod size in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.max_pod_size_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_deck_entity_type_code -- entity_type_code + , T_DECK.deck_id::TEXT -- entity_record_id + , 'Min pod size in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_DECK.min_pod_size_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_Deck T_DECK + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Count games' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.count_games -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Count games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.count_games_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Count games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.count_games_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Win / lose ratio' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.win_lose_ratio -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Best position' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.best_position -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Worst position' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.worst_position -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean total damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_total_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max total damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.max_total_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min total damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.min_total_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_damage_received_game_win -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean total damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_total_damage_received_game_win -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max total damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.max_total_damage_received_game_win -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min total damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.min_total_damage_received_game_win -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_damage_received_game_lose -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean total damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_total_damage_received_game_lose -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max total damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.max_total_damage_received_game_lose -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min total damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.min_total_damage_received_game_lose -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total commander damage dealt' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_commander_damage_dealt -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean total commander damage dealt' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_total_commander_damage_dealt -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max total commander damage dealt' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.max_total_commander_damage_dealt -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min total commander damage dealt' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.min_total_commander_damage_dealt -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total commander damage dealt in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_commander_damage_dealt_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean total commander damage dealt in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_total_commander_damage_dealt_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max total commander damage dealt in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.max_total_commander_damage_dealt_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min total commander damage dealt in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.min_total_commander_damage_dealt_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total commander damage dealt in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_commander_damage_dealt_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean total commander damage dealt in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_total_commander_damage_dealt_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max total commander damage dealt in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.max_total_commander_damage_dealt_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min total commander damage dealt in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.min_total_commander_damage_dealt_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total commander damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_commander_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean total commander damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_total_commander_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max total commander damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.max_total_commander_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min total commander damage received' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.min_total_commander_damage_received -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total commander damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_commander_damage_received_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean total commander damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_total_commander_damage_received_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max total commander damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.max_total_commander_damage_received_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min total commander damage received in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.min_total_commander_damage_received_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total commander damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_commander_damage_received_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean total commander damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_total_commander_damage_received_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max total commander damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.max_total_commander_damage_received_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min total commander damage received in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.min_total_commander_damage_received_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total life gained' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_life_gained -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean total life gained' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_total_life_gained -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max total life gained' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.max_total_life_gained -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min total life gained' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.min_total_life_gained -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total life gained in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_life_gained_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean total life gained in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_total_life_gained_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max total life gained in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.max_total_life_gained_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min total life gained in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.min_total_life_gained_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total life gained in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_life_gained_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean total life gained in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_total_life_gained_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max total life gained in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.max_total_life_gained_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min total life gained in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.min_total_life_gained_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total game round count' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_game_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean total game round count' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_game_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min total game round count' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.lowest_game_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max total game round count' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.highest_game_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total game round count in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_game_win_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean total game round count in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_game_win_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min total game round count in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.lowest_game_win_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max total game round count in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.highest_game_win_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total game round count in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_game_lose_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean total game round count in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_game_lose_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min total game round count in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.lowest_game_lose_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max total game round count in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.highest_game_lose_round_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total game round count survived' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_game_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean total game round count survived' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_game_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min total game round count survived' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.lowest_game_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max total game round count survived' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.highest_game_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total game round count survived in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_game_win_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean total game round count survived in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_game_win_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min total game round count survived in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.lowest_game_win_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max total game round count survived in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.highest_game_win_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total game round count survived in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_game_lose_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean total game round count survived in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_game_lose_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min total game round count survived in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.lowest_game_lose_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max total game round count survived in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.highest_game_lose_round_survived_count -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total game duration' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER.total_game_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean game duration' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER.mean_game_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min game duration' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER.shortest_game_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max game duration' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER.longest_game_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total game duration in games won' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER.total_game_win_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean game duration in games won' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER.mean_game_win_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min game duration in games won' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER.shortest_game_win_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max game duration in games won' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER.longest_game_win_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total game duration in games lost' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER.total_game_lose_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean game duration in games lost' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER.mean_game_lose_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min game duration in games lost' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER.shortest_game_lose_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max game duration in games lost' -- name + , NULL::BOOLEAN -- value_bool + , NULL::DOUBLE PRECISION -- value_float + , T_USER.longest_game_lose_duration -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , FALSE -- is_float + , TRUE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total commander deaths' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_commander_deaths -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean commander deaths' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_commander_deaths -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max commander deaths' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.max_commander_deaths -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min commander deaths' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.min_commander_deaths -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total commander deaths in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_commander_deaths_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean commander deaths in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_commander_deaths_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max commander deaths in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.max_commander_deaths_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min commander deaths in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.min_commander_deaths_game_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total commander deaths in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_commander_deaths_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean commander deaths in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_commander_deaths_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max commander deaths in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.max_commander_deaths_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min commander deaths in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.min_commander_deaths_game_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total pod sizes' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_pod_sizes -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total opponents faced' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_opponents_faced -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean pod size' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_pod_size -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max pod size' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.max_pod_size -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min pod size' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.min_pod_size -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total pod sizes in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_pod_sizes_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total opponents beaten' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_opponents_beaten -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean pod size in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_pod_size_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max pod size in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.max_pod_size_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min pod size in games won' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.min_pod_size_won -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total pod sizes in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_pod_sizes_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Total opponents lost to' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.total_opponents_lost_to -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Mean pod size in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.mean_pod_size_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Max pod size in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.max_pod_size_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + UNION + SELECT + v_user_entity_type_code -- entity_type_code + , T_USER.user_id::TEXT -- entity_record_id + , 'Min pod size in games lost' -- name + , NULL::BOOLEAN -- value_bool + , T_USER.min_pod_size_lost -- value_float + , NULL::INTERVAL -- value_interval + , NULL::TEXT -- value_text + , NULL::TIMESTAMP -- value_timestamp + , FALSE -- is_bool + , TRUE -- is_float + , FALSE -- is_interval + , FALSE -- is_text + , FALSE -- is_timestamp + , TRUE -- active + FROM Temp_Statistic_Calc_User T_USER + ; + + -- Nothing to save + IF NOT EXISTS (SELECT * FROM Temp_Statistic_Calc_Statistic LIMIT 1) THEN + INSERT INTO Temp_Statistic_Calc_Error ( + error_type_id + , message + ) + VALUES ( + v_warning_error_type_id + , 'Nothing to save.' + ); + END IF; + + -- Outputs + -- Change Set + INSERT INTO tcg.public.TCG_Change_Set ( + comment + , updated_last_by_user_id + ) + VALUES ( + v_comment + , v_user_id + ) + RETURNING change_set_id INTO v_change_set_id + ; + + IF NOT EXISTS (SELECT * FROM Temp_Statistic_Calc_Error T_ERROR WHERE T_ERROR.error_type_id <> v_warning_error_type_id LIMIT 1) THEN + + -- Statistic + INSERT INTO tcg.public.TCG_Statistic ( + entity_type_code + , entity_record_id + , name + , value_bool + , value_float + , value_interval + , value_text + , value_timestamp + , is_bool + , is_float + , is_interval + , is_text + , is_timestamp + , display_order + , active + , created_on + , created_by_user_id + , updated_last_on + , updated_last_by_user_id + , change_set_id + ) + SELECT + T_STATISTIC.entity_type_code + , T_STATISTIC.entity_record_id + , T_STATISTIC.name + , T_STATISTIC.value_bool + , T_STATISTIC.value_float + , T_STATISTIC.value_interval + , T_STATISTIC.value_text + , T_STATISTIC.value_timestamp + , T_STATISTIC.is_bool + , T_STATISTIC.is_float + , T_STATISTIC.is_interval + , T_STATISTIC.is_text + , T_STATISTIC.is_timestamp + , T_STATISTIC.temp_statistic_id -- display_order + , T_STATISTIC.active + , v_time_start -- created_on + , v_user_id -- created_by_user_id + , v_time_start -- updated_last_on + , v_user_id -- updated_last_by_user_id + , v_change_set_id -- change_set_id + FROM Temp_Statistic_Calc_Statistic T_STATISTIC + WHERE T_STATISTIC.active = TRUE + ; + + ELSE + -- Error + INSERT INTO tcg.public.Error ( + guid + , error_type_id + , message + , display_order + , created_on + , created_by_user_id + , updated_last_on + , updated_last_by_user_id + , change_set_id + ) + SELECT + v_guid + , T_ERROR.error_type_id + , T_ERROR.message + , T_ERROR.temp_id + , v_time_start + , v_user_id + , v_time_start + , v_user_id + , v_change_set_id + FROM Temp_Statistic_Calc_Error T_ERROR + LEFT JOIN tcg.public.Error_Type ERROR_TYPE ON T_ERROR.error_type_id = ERROR_TYPE.error_type_id + ORDER BY T_ERROR.temp_id + ; + END IF; + + COMMIT; + + o_success := NOT EXISTS ( + SELECT * + FROM Temp_Statistic_Calc_Error T_ERROR + WHERE T_ERROR.error_type_id <> v_warning_error_type_id + LIMIT 1 + ); + + DROP TABLE IF EXISTS Temp_Statistic_Calc_Statistic; + DROP TABLE IF EXISTS Temp_Statistic_Calc_Deck; + DROP TABLE IF EXISTS Temp_Statistic_Calc_Game; + DROP TABLE IF EXISTS Temp_Statistic_Calc_Player; + DROP TABLE IF EXISTS Temp_Statistic_Calc_User; + DROP TABLE IF EXISTS Temp_Statistic_Calc_User_Deck_Link; + DROP TABLE IF EXISTS Temp_Statistic_Calc_Round; + DROP TABLE IF EXISTS Temp_Statistic_Calc_Round_Player_Damage; + DROP TABLE IF EXISTS Temp_Statistic_Calc_Player_Round_Link; + DROP TABLE IF EXISTS Temp_Statistic_Calc_Error; +END; +$$; + +-- Call it with: +DO $$ +DECLARE + v_comment TEXT := 'MTG Statistic Calc.'; + v_guid UUID; + v_user_id INT := 3; + v_success BOOLEAN; +BEGIN + v_guid := '6307bed6-73a1-41ab-9a90-79e18e14dd81'::UUID; -- gen_random_uuid(); + + CALL tcg.public.USP_TCG_Statistic_Calc ( + a_comment := v_comment -- a_comment + , a_guid := v_guid -- a_guid + , a_user_id := v_user_id -- a_user_id + , o_success := v_success -- o_success + ); + RAISE NOTICE 'Success: %', CASE WHEN v_success THEN 'TRUE' ELSE 'FALSE' END; +END; +$$; + +/* +SELECT * +FROM tcg.public.TCG_Statistic +; +; +SELECT INTERVAL '0' +* / +SELECT COUNT(*) +FROM tcg.public.TCG_Statistic STATISTIC +; +SELECT * +FROM tcg.public.TCG_User TCG_USER +; +SELECT * +-- DELETE +FROM tcg.public.TCG_Statistic STATISTIC +where + STATISTIC.NAME like '%life%' + and STATISTIC.entity_record_id in ('3', '4') +ORDER BY + STATISTIC.entity_type_code ASC + , STATISTIC.entity_record_id asc + , STATISTIC.NAME +*/ diff --git a/static/css/components/button.css b/static/css/components/button.css index f50a6a5..c6e4d1d 100644 --- a/static/css/components/button.css +++ b/static/css/components/button.css @@ -17,8 +17,8 @@ .button-primary { background: var(--colour-accent); - color: var(--colour-primary); - border: 2px solid var(--colour-primary); + color: var(--primary-color); + border: 2px solid var(--primary-color); } .button-primary:hover { @@ -28,7 +28,7 @@ .button-light { background: white; - color: var(--colour-primary); + color: var(--primary-color); } .button-light:hover { diff --git a/static/css/components/form.css b/static/css/components/form.css index f0eda36..e8b5449 100644 --- a/static/css/components/form.css +++ b/static/css/components/form.css @@ -2,5 +2,5 @@ select { border: 1px solid var(--colour-accent); - background-color: var(--colour-page-background-1); + background-color: var(--background-color-1); } \ No newline at end of file diff --git a/static/css/components/overlay.css b/static/css/components/overlay.css index b779e10..b3fe1b0 100644 --- a/static/css/components/overlay.css +++ b/static/css/components/overlay.css @@ -8,7 +8,7 @@ position: fixed; width: 100px; /* height: 50%; */ - background: var(--colour-page-background); + background: var(--background-color); justify-content: right; align-items: right; align-self: right; @@ -73,11 +73,11 @@ border-bottom-right-radius: 12px; } #overlayHamburger > :hover { - color: var(--colour-page-background); - background-color: var(--colour-primary); + color: var(--background-color); + background-color: var(--primary-color); } #overlayHamburger .container { - background-color: var(--colour-page-background); + background-color: var(--tcg-accent-purple); display: flex; flex-wrap: wrap; align-items: center; @@ -93,8 +93,8 @@ height: fit-content; } #overlayHamburger .container:hover { - color: var(--colour-page-background); - background-color: var(--colour-primary); + color: var(--background-color); + background-color: var(--primary-color); } #overlayHamburger > .container { /* @@ -105,13 +105,13 @@ #overlayHamburger .container a { width: 100%; padding: 4.5px 0; - color: var(--colour-text); + color: var(--tcg-text-primary); text-decoration: none; line-height: initial; } #overlayHamburger .container a:hover { - color: var(--colour-page-background); - background-color: var(--colour-primary); + color: var(--background-color); + background-color: var(--primary-color); } @media screen and (max-width: 400px) { diff --git a/static/css/components/table.css b/static/css/components/table.css index 55cdd60..73cac71 100644 --- a/static/css/components/table.css +++ b/static/css/components/table.css @@ -28,7 +28,7 @@ th.is_collapsed, td.is_collapsed { display: table-cell !important; } td.dirty { - background-color: var(--colour-primary); + background-color: var(--primary-color); } td:not(.dirty) { background-color: transparent; @@ -48,7 +48,7 @@ table button { } table button.active { - background-color: var(--colour-page-background); + background-color: var(--background-color); } tr.delete, tr.delete > td { diff --git a/static/css/layouts/footer.css b/static/css/layouts/footer.css index a039be0..c2fe811 100644 --- a/static/css/layouts/footer.css +++ b/static/css/layouts/footer.css @@ -1 +1,16 @@ -/* In sections */ \ No newline at end of file + +/* In sections */ +.tcg.footer { + display: flex; +} +.tcg.footer > .container { + /* display: flex; */ +} +.footer-content { + display: flex; + margin: 0 auto; +} +.footer-section { + /* display: flex; */ + margin: auto auto; +} diff --git a/static/css/layouts/header.css b/static/css/layouts/header.css index 00ecbb2..27433d8 100644 --- a/static/css/layouts/header.css +++ b/static/css/layouts/header.css @@ -31,7 +31,7 @@ color: var(--colour-text-link-visited); } .topnav a:hover { - background-color: var(--colour-page-background); + background-color: var(--background-color); color: var(--colour-text) } .topnav > .container { @@ -149,10 +149,10 @@ #formFilters button { padding: 0.5vh 0.75vh; background-color: var(--colour-accent); - color: var(--colour-primary); + color: var(--primary-color); font-weight: bold; border-radius: 0.75vh; - border: 2px solid var(--colour-primary); + border: 2px solid var(--primary-color); } #formFilters button.is_collapsed { diff --git a/static/css/layouts/table-main.css b/static/css/layouts/table-main.css index f6e2664..cb6ef77 100644 --- a/static/css/layouts/table-main.css +++ b/static/css/layouts/table-main.css @@ -4,38 +4,39 @@ margin-top: 1vh; } -table.table-main { +.table-main { overflow-x: auto; - padding: 1vh 1vw; - max-width: 88vw; /* min(calc(1vh * 80), calc(1vw * 90)); */ + padding: 0; /*1vh 1vw;*/ + max-width: 80vw; /* min(calc(1vh * 80), calc(1vw * 90)); */ width: min-content; align-items: normal; justify-content: normal; + margin: 0 auto; } -table.table-main * { +.table-main * { padding: 0.25vh 0.5vh; } -table.table-main thead { +.table-main thead { max-height: 4vh; overflow-y: visible; - background-color: var(--colour-text-background); + background-color: var(--background-color); } -table.table-main tbody { +.table-main tbody { max-height: 75vh; overflow-y: auto; min-width: fit-content; max-width: fit-content; overflow-x: visible; } -table.table-main tbody.is_collapsed { +.table-main tbody.is_collapsed { display: block; } -table.table-main:has(tbody > div) tbody { +.table-main:has(tbody > div) tbody { } -table.table-main tbody > div { +.table-main tbody > div { margin-left: auto; margin-right: auto; text-align: center; @@ -50,72 +51,72 @@ table.table-main tbody > div { width: 100%; /* min(calc(90vh), calc(70vw)); */ } -table.table-main select, -table.table-main input:not([type="checkbox"]), -table.table-main textarea, -table.table-main div { +.table-main select, +.table-main input:not([type="checkbox"]), +.table-main textarea, +.table-main div { box-sizing: border-box; width: 100%; max-width: 100%; height: 100%; - border: 1px solid var(--colour-accent); + border: 1px solid var(--border-color); border-radius: 0.5vh; text-align: center; - background-color: var(--colour-text-background); + background-color: var(--background-color); font-size: 16px; } -table.table-main thead tr th, -table.table-main tbody tr td { +.table-main thead tr th, +.table-main tbody tr td { max-width: 20vh; min-width: 20vh; padding: 0 0.5vh; } -table.table-main tbody tr td { +.table-main tbody tr td { height: 3vh; /* padding-top: 0.5vh; */ } -table.table-main thead tr th.notes, -table.table-main tbody tr td.notes { +.table-main thead tr th.notes, +.table-main tbody tr td.notes { max-width: fit-content; } -table.table-main tbody tr td:has(.dirty) { - background-color: var(--colour-primary); +.table-main tbody tr td:has(.dirty) { + background-color: var(--primary-color); } -table.table-main tbody tr td:has(.dirty) table tr:not(:has(.dirty)) { +.table-main tbody tr td:has(.dirty) table tr:not(:has(.dirty)) { background-color: var(--colour-text-background); } -table.table-main tbody tr:not(:last-of-type) td { +.table-main tbody tr:not(:last-of-type) td { padding-bottom: 0.25vh; } -table.table-main tbody tr td.ddl-preview div { +.table-main tbody tr td.ddl-preview div { cursor: pointer; } -table.table-main tbody tr td.ddl-preview div, -table.table-main tbody tr td.ddl-preview select { +.table-main tbody tr td.ddl-preview div, +.table-main tbody tr td.ddl-preview select { padding-left: 2vh; padding-right: 2vh; } -table.table-main thead tr th.active, -table.table-main tbody tr td.active { +.table-main thead tr th.active, +.table-main tbody tr td.active { max-width: 6vh; min-width: 6vh; } -table.table-main thead tr th.active svg.active.add { - fill: var(--colour-primary); - background-color: var(--colour-accent); - border: 2px solid var(--colour-accent); +.table-main thead tr th.active svg.active.add { + fill: var(--primary-color); + background-color: var(--background-color); + border: 2px solid var(--border-color); padding: 0; border-radius: 1vh; } -table.table-main tbody tr td.active svg.active.add { - fill: var(--colour-primary); +.table-main tbody tr td.active svg.active.add { + fill: var(--primary-color); } -table.table-main tbody tr td.active svg.active.delete { - fill: var(--colour-error); +.table-main tbody tr td.active svg.active.delete { + fill: var(--tcg-accent-red); } -table.table-main tbody tr td.display_order, -table.table-main thead tr th.display_order { +.table-main tbody tr td.display_order, +.table-main thead tr th.display_order { max-width: 5vh; min-width: 5vh; } @@ -141,13 +142,13 @@ table.table-main thead tr th.display_order { .company-name { font-size: 1.2rem; } - table.table-main { + .table-main { max-height: 61vh; } - table.table-main thead { + .table-main thead { font-size: 0.8rem; } - table.table-main tbody { + .table-main tbody { max-height: 53vh; } } \ No newline at end of file diff --git a/static/css/main.css b/static/css/main.css index 3336157..4473429 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -38,14 +38,13 @@ html { } body { - background-color: var(--colour-page-background); - color: var(--colour-text); + background-color: var(--background-color); + color: var(--text-color); font-family: var(--font-family-base); font-family: Arial; padding: 0; margin: 0; border: 0; - background: linear-gradient(to bottom right, var(--colour-page-background-1), var(--colour-page-background-2)); /* var(--c_purple); */ height: 100vh; /* max-height: 100vh; overflow-y: clip; */ @@ -53,6 +52,7 @@ body { * { margin: 0; + color: var(--text-color); } script, link { @@ -88,7 +88,7 @@ script, link { width: 100%; align-self: center; font-size: 1rem; - color: var(--colour-text); + color: var(--text-color); } #pageBody > * > * { align-self: center; @@ -104,7 +104,6 @@ script, link { /* Add a card effect for articles */ .card { - background-color: var(--colour-text-background); padding: 1vh 2.5vw; margin: 1vh 1vw; display: flex; @@ -182,7 +181,7 @@ script, link { .container-input > input, .container-input > textarea { - border: 2px solid var(--colour-accent); + border: 2px solid var(--border-color); border-radius: 0.5vh; padding: 1vh 1vw; } @@ -205,10 +204,10 @@ li { :not(input,textarea,select,button).dirty { - background-color: var(--colour-accent); + background-color: var(--border-color); } input.dirty, textarea.dirty, select.dirty { - border-color: var(--colour-primary); + border-color: var(--primary-color); } .is-collapsed { diff --git a/static/css/pages/tcg/base.css b/static/css/pages/tcg/base.css index d8019e4..c28a967 100644 --- a/static/css/pages/tcg/base.css +++ b/static/css/pages/tcg/base.css @@ -24,6 +24,9 @@ body.tcg-theme { } /* Top Nav TCG Style */ +#buttonHamburger { + display: none; +} .topnav.tcg { background: var(--tcg-bg-secondary); border-bottom: 2px solid var(--tcg-border-color); @@ -88,7 +91,8 @@ body.tcg-theme { .footer.tcg h3 { font-family: 'Cinzel', serif; color: var(--tcg-accent-gold); - margin-bottom: 1rem; + /* margin-bottom: 1vh; */ + margin-top: 0; } .footer.tcg a { @@ -174,9 +178,10 @@ body.tcg-theme { font-family: 'Cinzel', serif; font-size: 1.5rem; color: var(--tcg-accent-gold); - margin-bottom: 1.5rem; letter-spacing: 0.05em; text-transform: uppercase; + margin: 1.5rem auto 0; + text-align: center; } /* TCG Form Elements */ @@ -244,6 +249,9 @@ body.tcg-theme { .nav-links.tcg { display: none; } + #buttonHamburger { + display: block; + } .topnav.tcg { padding-right: 30vw; } diff --git a/static/css/pages/tcg/decks.css b/static/css/pages/tcg/decks.css new file mode 100644 index 0000000..32355f1 --- /dev/null +++ b/static/css/pages/tcg/decks.css @@ -0,0 +1,38 @@ + + +.tcg-card { + margin-top: 1vh; + margin-bottom: 0; +} + + +table.table-main tbody { + max-height: 30vh; + overflow-y: auto; +} + +table.statistics { + margin-top: 0; +} +table.statistics thead { + background-color: var(--background-color); +} +table.statistics tbody { + max-height: 30vh; + overflow-y: auto; +} +table.statistics thead tr th.deck, +table.statistics tbody tr td.deck_id { + min-width: 20vh; + max-width: 20vh; +} +table.statistics thead tr th.name, +table.statistics tbody tr td.name { + min-width: 40vh; + max-width: 40vh; +} +table.statistics thead tr th.value, +table.statistics tbody tr td.value { + min-width: 10vh; + max-width: 10vh; +} \ No newline at end of file diff --git a/static/css/pages/tcg/game.css b/static/css/pages/tcg/game.css index 35bfcd5..35ab82c 100644 --- a/static/css/pages/tcg/game.css +++ b/static/css/pages/tcg/game.css @@ -147,6 +147,9 @@ } /* Game Section */ +#gameSection { + margin: 0 auto; +} #gameSection .row.round { display: flex; align-items: center; @@ -347,13 +350,16 @@ text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5); } -.life-controls { +.life-gain-controls, +.life-loss-controls { display: flex; gap: 1rem; justify-content: center; + margin-bottom: 1vh; } -.life-btn { +.life-gain-btn, +.life-loss-btn { background: var(--tcg-bg-card); border: 2px solid var(--tcg-border-color); color: var(--tcg-text-primary); @@ -370,17 +376,31 @@ justify-content: center; } -.life-btn:hover { - border-color: var(--tcg-accent-purple); - background: var(--tcg-accent-purple); +.life-gain-btn:hover, +.life-loss-btn:hover { + border-color: green; /*var(--tcg-accent-purple);*/ + background: green; /*var(--tcg-accent-purple);*/ color: var(--tcg-bg-primary); transform: scale(1.1); } -.life-btn:active { +.life-loss-btn:hover { + border-color: red; + background: red; +} + +.life-gain-btn:active, +.life-loss-btn:active { transform: scale(0.95); } +.life-total label { + color: var(--tcg-text-primary); + width: 100%; + margin-bottom: 1vh; + display: inline-block; +} + /* Commander Damage Section */ .commander-damage-section { border-top: 1px solid var(--tcg-border-color); @@ -420,6 +440,7 @@ .damage-source { font-size: 1rem; color: var(--tcg-text-secondary); + padding-right: 1vh; } .damage-controls { @@ -478,8 +499,10 @@ .damage-log.container table tbody tr td.received_from_commander_player_id { width: 20vw; } -.damage-log.container table thead tr th.health_change, -.damage-log.container table tbody tr td.health_change { +.damage-log.container table thead tr th.life_gain, +.damage-log.container table tbody tr td.life_gain, +.damage-log.container table thead tr th.life_loss, +.damage-log.container table tbody tr td.life_loss { width: 7vw; } .damage-log.container table thead tr th.commander-deaths, @@ -583,7 +606,8 @@ font-size: 3rem; } - .life-btn { + .life-gain-btn, + .life-loss-btn { width: 50px; height: 50px; font-size: 1.5rem; diff --git a/static/css/pages/tcg/games.css b/static/css/pages/tcg/games.css index 9a4839c..b9b71b2 100644 --- a/static/css/pages/tcg/games.css +++ b/static/css/pages/tcg/games.css @@ -33,15 +33,18 @@ position: relative; animation: tcg-fadeIn 0.8s ease-out 0.2s backwards; margin: 2vh auto; + display: flex; + flex-wrap: wrap; } .section-header { display: flex; justify-content: space-between; align-items: center; - margin-bottom: 2rem; + margin-bottom: 1rem; flex-wrap: wrap; gap: 1rem; + width: 100%; } /* Filters Form */ @@ -88,8 +91,7 @@ overflow-x: auto; } -.games-table { - width: 100%; +#tableMain.games-table { border-collapse: collapse; font-size: 1rem; } @@ -98,7 +100,6 @@ background: var(--tcg-bg-card); border-bottom: 2px solid var(--tcg-accent-purple); } - .games-table th { font-family: 'Cinzel', serif; font-size: 0.95rem; @@ -107,18 +108,22 @@ text-transform: uppercase; letter-spacing: 0.05em; padding: 1rem; - text-align: left; +} +.games-table thead tr { + height: 4vh; } +#tableMain.games-table tbody { + max-height: 59vh; +} .games-table tbody tr { border-bottom: 1px solid var(--tcg-border-color); transition: all 0.3s ease; + height: 4vh; } - .games-table tbody tr:hover { background: rgba(139, 92, 246, 0.1); } - .games-table tbody tr.inactive { opacity: 0.5; } @@ -132,7 +137,38 @@ color: white; } -.game-id { +.games-table thead tr th.game_id, +.games-table tbody tr td.game_id { + min-width: 10vh; + max-width: 10vh; +} +.games-table thead tr th.is_commander, +.games-table tbody tr td.is_commander { + min-width: 12vh; + max-width: 12vh; +} +.games-table thead tr th.location_name, +.games-table tbody tr td.location_name { + min-width: 20vh; + max-width: 20vh; +} +.games-table thead tr th.start_on, +.games-table tbody tr td.start_on { + min-width: 14vh; + max-width: 14vh; +} +#tableMain.games-table thead tr th.active, +#tableMain.games-table tbody tr td.active { + min-width: 8vh; + max-width: 8vh; +} +.games-table thead tr th.navMtgGame, +.games-table tbody tr td.navMtgGame { + min-width: 13vh; + max-width: 13vh; +} + +.game_id { font-family: 'Cinzel', serif; font-weight: 600; color: var(--tcg-text-secondary); @@ -223,7 +259,7 @@ /* Join Button */ .btn-join { - padding: 0.5rem 1.25rem; + padding: 0.5vh 1vw; font-size: 0.9rem; } @@ -265,7 +301,7 @@ animation: tcg-fadeIn 0.3s ease-out; } -.modal-overlay.hidden { +.modal-overlay.is_collapsed { display: none; } @@ -338,7 +374,6 @@ } .section-header { - flex-direction: column; align-items: stretch; } diff --git a/static/css/pages/user/user.css b/static/css/pages/user/user.css index 3062fe6..54ff900 100644 --- a/static/css/pages/user/user.css +++ b/static/css/pages/user/user.css @@ -22,6 +22,6 @@ label { input.dirty, textarea.dirty, select.dirty { - border-color: var(--colour-primary); - background-color: var(--colour-page-background-2); + border-color: var(--primary-color); + background-color: var(--background-color-2); } \ No newline at end of file diff --git a/static/css/sections/tcg.css b/static/css/sections/tcg.css index 7182182..cf0015d 100644 --- a/static/css/sections/tcg.css +++ b/static/css/sections/tcg.css @@ -14,7 +14,7 @@ /* Main Table */ #pageBody { - max-height: 77vh; + max-height: 82vh; padding: 0 5vw; margin: 0; border: 0; diff --git a/static/css/themes/dark.css b/static/css/themes/dark.css index 689631a..f46ba7a 100644 --- a/static/css/themes/dark.css +++ b/static/css/themes/dark.css @@ -1,4 +1,4 @@ -/* + :root { --background-color: #121212; --text-color: #e0e0e0; @@ -43,5 +43,5 @@ --card-bg: #1f1f1f; --card-border: #333333; --card-shadow: 0 0.125rem 0.25rem rgba(255, 255, 255, 0.05); + */ } -*/ \ No newline at end of file diff --git a/static/css/themes/icons.css b/static/css/themes/icons.css index b487b27..8ec169b 100644 --- a/static/css/themes/icons.css +++ b/static/css/themes/icons.css @@ -15,7 +15,7 @@ border-radius: 2vh; } .theme-switch:hover { - background-color: var(--colour-primary); + background-color: var(--primary-color); } .theme-switch img.theme-icon, .theme-switch svg.theme-icon { @@ -40,7 +40,7 @@ svg.theme-icon.light-mode-icon .background { fill: var(--colour-secondary); } .theme-switch:hover svg.theme-icon.light-mode-icon .background { - fill: var(--colour-primary); + fill: var(--primary-color); } svg.theme-icon.light-mode-icon .sun { fill: var(--colour-text); diff --git a/static/css/themes/light.css b/static/css/themes/light.css index c422639..c92892b 100644 --- a/static/css/themes/light.css +++ b/static/css/themes/light.css @@ -6,10 +6,10 @@ --colour-error-accent: #fc8181; --colour-error-highlight: #fff5f5; --colour-error-title: #c53030; - --colour-page-background: #E0AAFF; - --colour-page-background-1: #F5ECFE; - --colour-page-background-2: #FAE0E2; - --colour-primary: #240046; + --background-color: #E0AAFF; + --background-color-1: #F5ECFE; + --background-color-2: #FAE0E2; + --primary-color: #240046; --colour-secondary: #3C096C; --colour-success: #38a169; --colour-success-highlight: #f0fff4; diff --git a/static/dist/css/main.bundle.css b/static/dist/css/main.bundle.css index ad9b086..42d463a 100644 --- a/static/dist/css/main.bundle.css +++ b/static/dist/css/main.bundle.css @@ -38,14 +38,13 @@ html { } body { - background-color: var(--colour-page-background); - color: var(--colour-text); + background-color: var(--background-color); + color: var(--text-color); font-family: var(--font-family-base); font-family: Arial; padding: 0; margin: 0; border: 0; - background: linear-gradient(to bottom right, var(--colour-page-background-1), var(--colour-page-background-2)); /* var(--c_purple); */ height: 100vh; /* max-height: 100vh; overflow-y: clip; */ @@ -53,6 +52,7 @@ body { * { margin: 0; + color: var(--text-color); } script, link { @@ -88,7 +88,7 @@ script, link { width: 100%; align-self: center; font-size: 1rem; - color: var(--colour-text); + color: var(--text-color); } #pageBody > * > * { align-self: center; @@ -104,7 +104,6 @@ script, link { /* Add a card effect for articles */ .card { - background-color: var(--colour-text-background); padding: 1vh 2.5vw; margin: 1vh 1vw; display: flex; @@ -182,7 +181,7 @@ script, link { .container-input > input, .container-input > textarea { - border: 2px solid var(--colour-accent); + border: 2px solid var(--border-color); border-radius: 0.5vh; padding: 1vh 1vw; } @@ -205,10 +204,10 @@ li { :not(input,textarea,select,button).dirty { - background-color: var(--colour-accent); + background-color: var(--border-color); } input.dirty, textarea.dirty, select.dirty { - border-color: var(--colour-primary); + border-color: var(--primary-color); } .is-collapsed { @@ -234,8 +233,8 @@ input.dirty, textarea.dirty, select.dirty { .button-primary { background: var(--colour-accent); - color: var(--colour-primary); - border: 2px solid var(--colour-primary); + color: var(--primary-color); + border: 2px solid var(--primary-color); } .button-primary:hover { @@ -245,7 +244,7 @@ input.dirty, textarea.dirty, select.dirty { .button-light { background: white; - color: var(--colour-primary); + color: var(--primary-color); } .button-light:hover { @@ -267,7 +266,7 @@ input.dirty, textarea.dirty, select.dirty { select { border: 1px solid var(--colour-accent); - background-color: var(--colour-page-background-1); + background-color: var(--background-color-1); } img, video { @@ -321,7 +320,7 @@ h5 { position: fixed; width: 100px; /* height: 50%; */ - background: var(--colour-page-background); + background: var(--background-color); justify-content: right; align-items: right; align-self: right; @@ -386,11 +385,11 @@ h5 { border-bottom-right-radius: 12px; } #overlayHamburger > :hover { - color: var(--colour-page-background); - background-color: var(--colour-primary); + color: var(--background-color); + background-color: var(--primary-color); } #overlayHamburger .container { - background-color: var(--colour-page-background); + background-color: var(--tcg-accent-purple); display: flex; flex-wrap: wrap; align-items: center; @@ -406,8 +405,8 @@ h5 { height: fit-content; } #overlayHamburger .container:hover { - color: var(--colour-page-background); - background-color: var(--colour-primary); + color: var(--background-color); + background-color: var(--primary-color); } #overlayHamburger > .container { /* @@ -418,13 +417,13 @@ h5 { #overlayHamburger .container a { width: 100%; padding: 4.5px 0; - color: var(--colour-text); + color: var(--tcg-text-primary); text-decoration: none; line-height: initial; } #overlayHamburger .container a:hover { - color: var(--colour-page-background); - background-color: var(--colour-primary); + color: var(--background-color); + background-color: var(--primary-color); } @media screen and (max-width: 400px) { @@ -497,7 +496,7 @@ th.is_collapsed, td.is_collapsed { display: table-cell !important; } td.dirty { - background-color: var(--colour-primary); + background-color: var(--primary-color); } td:not(.dirty) { background-color: transparent; @@ -517,7 +516,7 @@ table button { } table button.active { - background-color: var(--colour-page-background); + background-color: var(--background-color); } tr.delete, tr.delete > td { @@ -560,7 +559,7 @@ table div { color: var(--colour-text-link-visited); } .topnav a:hover { - background-color: var(--colour-page-background); + background-color: var(--background-color); color: var(--colour-text) } .topnav > .container { @@ -678,10 +677,10 @@ table div { #formFilters button { padding: 0.5vh 0.75vh; background-color: var(--colour-accent); - color: var(--colour-primary); + color: var(--primary-color); font-weight: bold; border-radius: 0.75vh; - border: 2px solid var(--colour-primary); + border: 2px solid var(--primary-color); } #formFilters button.is_collapsed { @@ -725,45 +724,62 @@ form.filter button.save, form.filter button.button-cancel { padding-right: 30vw; } } + /* In sections */ +.tcg.footer { + display: flex; +} +.tcg.footer > .container { + /* display: flex; */ +} +.footer-content { + display: flex; + margin: 0 auto; +} +.footer-section { + /* display: flex; */ + margin: auto auto; +} + #formFilters { padding: 0.5vh 1vw; margin-top: 1vh; } -table.table-main { +.table-main { overflow-x: auto; - padding: 1vh 1vw; - max-width: 88vw; /* min(calc(1vh * 80), calc(1vw * 90)); */ + padding: 0; /*1vh 1vw;*/ + max-width: 80vw; /* min(calc(1vh * 80), calc(1vw * 90)); */ width: min-content; align-items: normal; justify-content: normal; + margin: 0 auto; } -table.table-main * { +.table-main * { padding: 0.25vh 0.5vh; } -table.table-main thead { +.table-main thead { max-height: 4vh; overflow-y: visible; - background-color: var(--colour-text-background); + background-color: var(--background-color); } -table.table-main tbody { +.table-main tbody { max-height: 75vh; overflow-y: auto; min-width: fit-content; max-width: fit-content; overflow-x: visible; } -table.table-main tbody.is_collapsed { +.table-main tbody.is_collapsed { display: block; } -table.table-main:has(tbody > div) tbody { +.table-main:has(tbody > div) tbody { } -table.table-main tbody > div { +.table-main tbody > div { margin-left: auto; margin-right: auto; text-align: center; @@ -778,72 +794,72 @@ table.table-main tbody > div { width: 100%; /* min(calc(90vh), calc(70vw)); */ } -table.table-main select, -table.table-main input:not([type="checkbox"]), -table.table-main textarea, -table.table-main div { +.table-main select, +.table-main input:not([type="checkbox"]), +.table-main textarea, +.table-main div { box-sizing: border-box; width: 100%; max-width: 100%; height: 100%; - border: 1px solid var(--colour-accent); + border: 1px solid var(--border-color); border-radius: 0.5vh; text-align: center; - background-color: var(--colour-text-background); + background-color: var(--background-color); font-size: 16px; } -table.table-main thead tr th, -table.table-main tbody tr td { +.table-main thead tr th, +.table-main tbody tr td { max-width: 20vh; min-width: 20vh; padding: 0 0.5vh; } -table.table-main tbody tr td { +.table-main tbody tr td { height: 3vh; /* padding-top: 0.5vh; */ } -table.table-main thead tr th.notes, -table.table-main tbody tr td.notes { +.table-main thead tr th.notes, +.table-main tbody tr td.notes { max-width: fit-content; } -table.table-main tbody tr td:has(.dirty) { - background-color: var(--colour-primary); +.table-main tbody tr td:has(.dirty) { + background-color: var(--primary-color); } -table.table-main tbody tr td:has(.dirty) table tr:not(:has(.dirty)) { +.table-main tbody tr td:has(.dirty) table tr:not(:has(.dirty)) { background-color: var(--colour-text-background); } -table.table-main tbody tr:not(:last-of-type) td { +.table-main tbody tr:not(:last-of-type) td { padding-bottom: 0.25vh; } -table.table-main tbody tr td.ddl-preview div { +.table-main tbody tr td.ddl-preview div { cursor: pointer; } -table.table-main tbody tr td.ddl-preview div, -table.table-main tbody tr td.ddl-preview select { +.table-main tbody tr td.ddl-preview div, +.table-main tbody tr td.ddl-preview select { padding-left: 2vh; padding-right: 2vh; } -table.table-main thead tr th.active, -table.table-main tbody tr td.active { +.table-main thead tr th.active, +.table-main tbody tr td.active { max-width: 6vh; min-width: 6vh; } -table.table-main thead tr th.active svg.active.add { - fill: var(--colour-primary); - background-color: var(--colour-accent); - border: 2px solid var(--colour-accent); +.table-main thead tr th.active svg.active.add { + fill: var(--primary-color); + background-color: var(--background-color); + border: 2px solid var(--border-color); padding: 0; border-radius: 1vh; } -table.table-main tbody tr td.active svg.active.add { - fill: var(--colour-primary); +.table-main tbody tr td.active svg.active.add { + fill: var(--primary-color); } -table.table-main tbody tr td.active svg.active.delete { - fill: var(--colour-error); +.table-main tbody tr td.active svg.active.delete { + fill: var(--tcg-accent-red); } -table.table-main tbody tr td.display_order, -table.table-main thead tr th.display_order { +.table-main tbody tr td.display_order, +.table-main thead tr th.display_order { max-width: 5vh; min-width: 5vh; } @@ -869,13 +885,13 @@ table.table-main thead tr th.display_order { .company-name { font-size: 1.2rem; } - table.table-main { + .table-main { max-height: 61vh; } - table.table-main thead { + .table-main thead { font-size: 0.8rem; } - table.table-main tbody { + .table-main tbody { max-height: 53vh; } } @@ -883,44 +899,53 @@ table.table-main thead tr th.display_order { -/* Default */ + :root { - /* Claude dark blue / grey theme */ - --colour-accent: #C77DFF; - --colour-error: red; - --colour-error-accent: #fc8181; - --colour-error-highlight: #fff5f5; - --colour-error-title: #c53030; - --colour-page-background: #E0AAFF; - --colour-page-background-1: #F5ECFE; - --colour-page-background-2: #FAE0E2; - --colour-primary: #240046; - --colour-secondary: #3C096C; - --colour-success: #38a169; - --colour-success-highlight: #f0fff4; - --colour-success-title: #16a34a; - --colour-text: #10002B; - --colour-text-background: white; - --colour-text-link-unvisited: #0000EE; - --colour-text-link-visited: #551A8B; + --background-color: #121212; + --text-color: #e0e0e0; + --primary-color: #bb86fc; + --secondary-color: #03dac6; + --success-color: #00c853; + --danger-color: #cf6679; + --warning-color: #ffab00; + --info-color: #2196f3; + --light-color: #2c2c2c; + --dark-color: #1f1f1f; + --border-color: #333333; + --shadow-color: rgba(255, 255, 255, 0.1); + + /* Header * / + --header-bg: #1f1f1f; + --header-text: #e0e0e0; + + /* Footer * / + --footer-bg: #1f1f1f; + --footer-text: #a0a0a0; + + /* Navigation * / + --nav-bg: #1f1f1f; + --nav-text: #e0e0e0; + --nav-hover-bg: #2c2c2c; + --nav-hover-text: #bb86fc; + + /* Buttons * / + --Button-primary-bg: #bb86fc; + --Button-primary-text: #121212; + --Button-secondary-bg: #03dac6; + --Button-secondary-text: #121212; + + /* Forms * / + --input-bg: #2c2c2c; + --input-border: #454545; + --input-text: #e0e0e0; + --input-focus-border: #bb86fc; + + /* Cards * / + --card-bg: #1f1f1f; + --card-border: #333333; + --card-shadow: 0 0.125rem 0.25rem rgba(255, 255, 255, 0.05); + */ } -/* ---c_purple_darker: #310055; ---c_purple_dark: #4A0A77; ---c_purple: #6818A5; ---c_purple_light: #CBAFFE; ---c_purple_lighter: #F5ECFE; - ---c_blue: #0044FF; ---c_blue_pastel: #B8E0FF; ---c_blue_light: #73E8FF; ---c_blue_dark: #003ADB; -/* --c_red: * / ---c-red: #FF0000; ---c_red_pastel: #FAE0E2; ---c_red_lighter: #FAE0E2; -} -*/ /*# sourceMappingURL=main.bundle.css.map*/ \ No newline at end of file diff --git a/static/dist/css/main.bundle.css.map b/static/dist/css/main.bundle.css.map index b09b449..3fa7a97 100644 --- a/static/dist/css/main.bundle.css.map +++ b/static/dist/css/main.bundle.css.map @@ -1 +1 @@ -{"version":3,"file":"css/main.bundle.css","mappings":"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","sources":["webpack://app/./static/css/main.css","webpack://app/./static/css/components/button.css","webpack://app/./static/css/components/form.css","webpack://app/./static/css/components/image.css","webpack://app/./static/css/components/label.css","webpack://app/./static/css/components/overlay.css","webpack://app/./static/css/components/table.css","webpack://app/./static/css/layouts/header.css","webpack://app/./static/css/layouts/footer.css","webpack://app/./static/css/layouts/table-main.css","webpack://app/./static/css/themes/light.css"],"sourcesContent":["\n:root {\n --font-family-base: 'Open Sans', Arial, sans-serif;\n /* Declare global variables */\n /*\n --c_purple: #5B29FF;\n --c_purple_pastel: #D1D1FF;\n --c_purple_lighter: #E8E1FF;\n --c_purple_light: #C6BDFF;\n --c_purple_dark: #4700B3;\n */\n /* purple theme\n - light https://coolors.co/palette/a172fd-a77afe-ac82fe-b691fe-c1a0fe-cbaffe-d6bffe-e0cefe-ebddfe-f5ecfe\n - dark https://coolors.co/palette/310055-3c0663-4a0a77-5a108f-6818a5-8b2fc9-ab51e3-bd68ee-d283ff-dc97ff\n */\n /*\n --c_purple_darker: #310055;\n --c_purple_dark: #4A0A77;\n --c_purple: #6818A5;\n --c_purple_light: #CBAFFE;\n --c_purple_lighter: #F5ECFE;\n\n --c_blue: #0044FF;\n --c_blue_pastel: #B8E0FF;\n --c_blue_light: #73E8FF;\n --c_blue_dark: #003ADB;\n */\n /* --c_red: * /\n --c-red: #FF0000;\n --c_red_pastel: #FAE0E2;\n --c_red_lighter: #FAE0E2;\n */\n}\n\nhtml {\n height: 100vh;\n /* overflow-y: clip; */\n}\n\nbody {\n background-color: var(--colour-page-background);\n color: var(--colour-text);\n font-family: var(--font-family-base);\n font-family: Arial;\n padding: 0;\n margin: 0;\n border: 0;\n background: linear-gradient(to bottom right, var(--colour-page-background-1), var(--colour-page-background-2)); /* var(--c_purple); */\n height: 100vh;\n /* max-height: 100vh;\n overflow-y: clip; */\n}\n\n* {\n margin: 0;\n}\n\nscript, link {\n display: none !important;\n}\n\n/*\n#pageBody {\n / * height: 69vh !important; * /\n max-height: 79vh;\n padding: 0 5vw;\n margin: 0;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n position: absolute;\n width: 90vw;\n color: var(--colour-text);\n}\n*/\n\n.page-body > * {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n text-align: center;\n width: 100%;\n align-self: center;\n font-size: 1rem;\n color: var(--colour-text);\n}\n#pageBody > * > * {\n align-self: center;\n padding-top: 0.5vh 0.5vw;\n padding-bottom: 0.5vh 0.5vw;\n}\n#pageBody > .card {\n height: fit-content;\n margin: 0.5vh auto;\n}\n\n\n\n/* Add a card effect for articles */\n.card {\n background-color: var(--colour-text-background);\n padding: 1vh 2.5vw;\n margin: 1vh 1vw;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n text-align: center;\n border-radius: 1.5vh;\n position: relative;\n height: fit-content;\n max-width: 80vw;\n}\n\n.container {\n flex: 1;\n margin: 0;\n align-items: flex-start;\n justify-content: flex-start;\n text-align: flex-start;\n /* max-width: 100%; */\n /* min-width: fit-content; */\n}\n\n.column {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin: auto 0;\n}\n\n.row {\n display: flex; \n flex-direction: row;\n width: 100%;\n flex-wrap: wrap;\n}\n\n.container > .card:first-of-type {\n margin-top: none;\n}\n\n\n/*\n/* Responsive layout - when the screen is less than 800px wide, make the two columns stack on top of each other instead of next to each other *\n@media screen and (max-width: 800px) {\n .leftcolumn, .rightcolumn { \n width: 100%;\n /* padding: 0; *\n }\n}\n\n/* Responsive layout - when the screen is less than 400px wide, make the navigation links stack on top of each other instead of next to each other *\n@media screen and (max-width: 400px) {\n .topnav a {\n float: none;\n width: 100%;\n }\n}\n*/\n\n.container-input {\n padding: 1vh 1vw;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n text-align: center;\n}\n\n.container-input > label {\n width: 100%;\n margin-bottom: 1vh;\n margin-top: 0;\n}\n\n.container-input > input,\n.container-input > textarea {\n border: 2px solid var(--colour-accent);\n border-radius: 0.5vh;\n padding: 1vh 1vw;\n}\n\n.label-title {\n width: 100%;\n}\n\n\nul {\n max-width: 90%;\n padding: 5px 0 10px 0;\n width: fit-content;\n margin: auto;\n}\nli {\n text-align: left;\n font-size: 18px;\n}\n\n\n:not(input,textarea,select,button).dirty {\n background-color: var(--colour-accent);\n}\ninput.dirty, textarea.dirty, select.dirty {\n border-color: var(--colour-primary);\n}\n\n.is-collapsed {\n display: none;\n}\n",".button {\n display: inline-block;\n padding: 0.5vh 0.75vh;\n border-radius: 0.75vh;\n text-decoration: none;\n font-weight: bold;\n transition: all 0.3s ease;\n width: fit-content;\n}\n.button:not(.is_collapsed) {\n cursor: pointer;\n}\n.button.is_collapsed {\n display: block;\n opacity: 0;\n}\n\n.button-primary {\n background: var(--colour-accent);\n color: var(--colour-primary);\n border: 2px solid var(--colour-primary);\n}\n\n.button-primary:hover {\n background: var(--colour-secondary);\n color: var(--colour-accent);\n}\n\n.button-light {\n background: white;\n color: var(--colour-primary);\n}\n\n.button-light:hover {\n background: var(--colour-accent);\n}\n\n.logo:hover{\n cursor: pointer;\n}\n\n\n.button.icon.active.delete, \n.button.icon.active.add {\n height: 2vh;\n}","\n\nselect {\n border: 1px solid var(--colour-accent);\n background-color: var(--colour-page-background-1);\n}","\nimg, video {\n border-radius: 3vh;\n}\n","\nh1 {\n font-size: 2.5rem;\n}\nh2 {\n font-size: 1.8rem;\n}\nh3 {\n font-size: 1.2rem;\n margin-top: 1vh;\n}\nh4 {\n font-size: 13px;\n margin: 1vh;\n text-align: center;\n margin-left: auto;\n margin-right: auto;\n}\nh5 {\n font-size: 11px;\n margin: 1vh;\n}\n\n\n.text-center {\n text-align: center;\n}\n.section-title {\n font-size: 1.8rem;\n margin-bottom: 1rem;\n}\n.section-subtitle {\n font-size: 1.2rem;\n margin-bottom: 2rem;\n}","\n\n/* Overlay modal */\n.overlay {\n /*\n display: none;\n */\n position: fixed;\n width: 100px;\n /* height: 50%; */ \n background: var(--colour-page-background);\n justify-content: right;\n align-items: right;\n align-self: right;\n z-index: 999;\n}\n.is_collapsed {\n display: none;\n}\n\n/* Hamburger menu overlay */\n#buttonHamburger {\n cursor: pointer;\n position: fixed;\n right: 1vh;\n min-height: 3.5vh;\n max-height: 3.5vh;\n min-width: 4vh;\n max-width: 4vh;\n z-index: 10;\n padding: 0;\n}\n#buttonHamburger.expanded {\n min-width: 100px;\n max-width: 100px;\n min-height: 5vh;\n max-height: 5vh;\n padding-left: calc(100 * 1px - 5 * 1vh);\n padding-bottom: 1vh;\n}\n#buttonHamburger .icon.hamburger {\n min-height: 2.5vh;\n max-height: 2.5vh;\n min-width: 2.5vh;\n max-width: 2.5vh;\n padding: 0.5vh 0.75vh;\n}\n/*\n#buttonHamburger:hover {\n text-decoration: none;\n cursor: pointer;\n}\n*/\n#overlayHamburger {\n top: 7vh;\n right: 1vh;\n overflow-x: hidden;\n overflow-y: auto;\n max-height: 60vh;\n background-color: var(--colour-accent);\n border: 2px solid var(--border-colour);\n border-radius: 0.75vh;\n width: 100px;\n z-index: 2;\n padding-top: 3.5vh;\n}\n#overlayHamburger:first-child {\n border-top-left-radius: 12px;\n border-top-right-radius: 12px;\n}\n#overlayHamburger:last-child {\n border-bottom-left-radius: 12px;\n border-bottom-right-radius: 12px;\n}\n#overlayHamburger > :hover {\n color: var(--colour-page-background);\n background-color: var(--colour-primary);\n}\n#overlayHamburger .container {\n background-color: var(--colour-page-background);\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n text-align: center;\n width: 100%;\n /* color: var(--colour-text); */\n font-weight: bold;\n font-size: 15px;\n /* height: 18px; */\n cursor: pointer;\n padding: 0;\n height: fit-content;\n}\n#overlayHamburger .container:hover {\n color: var(--colour-page-background);\n background-color: var(--colour-primary);\n}\n#overlayHamburger > .container {\n /*\n padding-top: 4.5px;\n padding-bottom: 4.5px;\n */\n}\n#overlayHamburger .container a {\n width: 100%;\n padding: 4.5px 0;\n color: var(--colour-text);\n text-decoration: none;\n line-height: initial;\n}\n#overlayHamburger .container a:hover {\n color: var(--colour-page-background);\n background-color: var(--colour-primary);\n}\n\n@media screen and (max-width: 400px) {\n #buttonHamburger {\n min-height: 5vh;\n max-height: 5vh;\n min-width: 5.5vh;\n max-width: 5.5vh;\n }\n #buttonHamburger .icon.hamburger {\n min-height: 4vh;\n max-height: 4vh;\n min-width: 4vh;\n max-width: 4vh;\n }\n #overlayHamburger {\n padding-top: 5vh;\n }\n}\n\n/* Confirm overlay */\n#overlayConfirm {\n position: absolute;\n left: 25vw;\n width: 50vw;\n height: 50vh;\n}\n\n#overlayConfirm .row > * {\n margin-left: auto;\n margin-right: auto;\n}\n\n#overlayConfirm .row .button.button-cancel {\n margin-right: 0.5vh;\n}\n#overlayConfirm .row .button.submit {\n margin-left: 0.5vh;\n}\n\n\n","\n#formFilters .container {\n max-width: fit-content;\n}\n\nthead, tbody {\n padding-top: 0px !important;\n padding-bottom: 0px !important;\n}\n\nth {\n background-color: transparent;\n}\ntd {\n font-size: min(16px, calc(1vh * 3));\n}\n\nth, td {\n min-width: fit-content;\n}\ntr:not(:last-child) > td {\n border-bottom: 1px dashed var(--border-colour);\n}\ntd > table > tbody > tr > td {\n border: none !important;\n}\nth.is_collapsed, td.is_collapsed {\n display: table-cell !important;\n}\ntd.dirty {\n background-color: var(--colour-primary);\n}\ntd:not(.dirty) {\n background-color: transparent;\n}\n\ntr {\n min-height: 1px;\n border-bottom: 1px solid;\n border-top: 1px solid;\n border-color: var(--border-colour);\n background-color: transparent;\n}\n\ntable button {\n margin: 0.25vh;\n padding: 0.5vh 1vh;\n}\n\ntable button.active {\n background-color: var(--colour-page-background);\n}\n\ntr.delete, tr.delete > td {\n background-color: var(--colour-error);\n}\n\ntable div {\n align-content: center;\n}","\n\n/* Navigation */\n.topnav {\n display: flex;\n flex-wrap: wrap;\n flex: 1;\n flex-direction: row;\n font-weight: bold;\n font-size: 1vh;\n max-height: 7vh;\n height: 7vh;\n align-items: flex-start;\n background: var(--colour-text-background);\n justify-content: center; /* space-between */\n align-items: center;\n}\n.topnav a,\n.topnav label,\n.topnav p,\n.topnav h1 {\n float: left;\n display: flex;\n text-align: center;\n text-decoration: none;\n width: 100%;\n max-height: 7vh;\n justify-content: center;\n}\n.topnav h1 {\n color: var(--colour-text-link-visited);\n}\n.topnav a:hover {\n background-color: var(--colour-page-background);\n color: var(--colour-text)\n}\n.topnav > .container {\n width: 30vw;\n min-width: 30vw;\n max-width: 30vw;\n height: 100%;\n align-items: center;\n align-self: center;\n display: flex;\n}\n.topnav .container.logo {\n cursor: pointer;\n}\n.topnav .container .logo {\n /* min-width: 35vh; */\n max-width: 30vw;\n /* width: 30vw; */\n /* min-height: 6vh; */\n max-height: 6vh;\n margin: 0.5vh;\n margin-right: auto;\n}\n.topnav .container.company-name {\n min-width: 30vw;\n max-width: 30vw;\n}\n.company-name {\n font-size: 1.6rem;\n}\n.nav-links {\n display: flex;\n gap: 0 2rem;\n display: flex;\n flex-wrap: wrap;\n max-width: calc(1vw * 100 - 1vh * 35);\n align-items: center;\n margin: 0 0.5vw;\n}\n.nav-links a {\n text-decoration: none;\n color: var(--colour-text);\n font-weight: normal;\n align-content: center;\n font-size: 1.2rem;\n width: fit-content;\n padding: 0.5vh 0.5vw;\n border-radius: 0.5vh;\n}\n.nav-links a.button {\n color: var(--colour-text-background);\n margin: 0 auto;\n font-weight: bold;\n}\n\n\n/* Page Filters */\n#formFilters {\n width: fit-content;\n margin-left: auto;\n margin-right: auto;\n \n}\n#formFilters * {\n font-size: 1rem;\n}\n\n#formFilters .container {\n}\n#formFilters .container-input {\n max-width: fit-content;\n padding: 0 0.5vh;\n}\n#formFilters .container-input:has(.dirty) {\n background-color: var(--colour-accent);\n} \n\n#formFilters .container-input input {\n width: 10vh;\n max-width: 10vh;\n height: 20px;\n}\n/*\n#formFilters .container-input input {\n height: 1.7vh;\n}\n#formFilters .container-input select {\n height: 2vh;\n}\n*/\n\n#formFilters .container-input.filter.active_only {\n width: 8vh;\n}\n#formFilters .container-input.filter.active_only input {\n display: none;\n}\n#formFilters .container-input.filter.active_only svg.active_only {\n height: 25px;\n fill: var(--colour-text-background);\n background-color: var(--colour-accent);\n /* border: 1px solid var(--colour-accent);\n border-radius: 0.5vh; */\n width: 25px;\n}\n#formFilters .container-input.filter.active_only svg.active_only.is_checked {\n fill: var(--colour-accent);\n background-color: var(--colour-text-background);\n}\n#formFilters .container-input.filter.is_not_empty {\n width: 12vh;\n}\n\n/*\n#formFilters button {\n padding: 0.5vh 0.75vh;\n background-color: var(--colour-accent);\n color: var(--colour-primary);\n font-weight: bold;\n border-radius: 0.75vh;\n border: 2px solid var(--colour-primary);\n}\n\n#formFilters button.is_collapsed {\n display: block;\n opacity: 0;\n}\n*/\n\nform.filter button.save, form.filter button.button-cancel {\n margin-top: 0;\n margin-bottom: 0;\n}\nform.filter button.save, form.filter button.button-cancel {\n margin-top: 0;\n margin-bottom: 1px;\n}\n\n/*\n@media screen and (max-width: 400px) {\n .topnav h1 {\n font-size: 16px;\n }\n}\n*/\n\n@media screen and (max-width: 980px) {\n /*\n .hero h1 {\n font-size: 2.5rem;\n }\n */\n .nav-links,\n .nav-links.tcg {\n display: none;\n }\n .topnav {\n justify-content: flex-start;\n align-items: start;\n }\n .topnav.tcg {\n padding-right: 30vw;\n }\n}","/* In sections */","\n#formFilters {\n padding: 0.5vh 1vw;\n margin-top: 1vh;\n}\n\ntable.table-main {\n overflow-x: auto;\n padding: 1vh 1vw;\n max-width: 88vw; /* min(calc(1vh * 80), calc(1vw * 90)); */\n width: min-content;\n align-items: normal;\n justify-content: normal;\n}\n\ntable.table-main * {\n padding: 0.25vh 0.5vh;\n}\n\ntable.table-main thead {\n max-height: 4vh;\n overflow-y: visible;\n background-color: var(--colour-text-background);\n}\n\ntable.table-main tbody {\n max-height: 75vh;\n overflow-y: auto;\n min-width: fit-content;\n max-width: fit-content;\n overflow-x: visible;\n}\ntable.table-main tbody.is_collapsed {\n display: block;\n}\ntable.table-main:has(tbody > div) tbody {\n}\ntable.table-main tbody > div {\n margin-left: auto;\n margin-right: auto;\n text-align: center;\n justify-content: center;\n justify-items: center;\n justify-self: center;\n align-content: center;\n align-items: center;\n align-self: center;\n position: relative;\n display: block;\n width: 100%; /* min(calc(90vh), calc(70vw)); */\n}\n\ntable.table-main select, \ntable.table-main input:not([type=\"checkbox\"]), \ntable.table-main textarea, \ntable.table-main div {\n box-sizing: border-box;\n width: 100%;\n max-width: 100%;\n height: 100%;\n border: 1px solid var(--colour-accent);\n border-radius: 0.5vh;\n text-align: center;\n background-color: var(--colour-text-background);\n font-size: 16px;\n}\n\ntable.table-main thead tr th, \ntable.table-main tbody tr td {\n max-width: 20vh;\n min-width: 20vh;\n padding: 0 0.5vh;\n}\ntable.table-main tbody tr td {\n height: 3vh;\n /* padding-top: 0.5vh; */\n}\ntable.table-main thead tr th.notes, \ntable.table-main tbody tr td.notes {\n max-width: fit-content;\n}\ntable.table-main tbody tr td:has(.dirty) {\n background-color: var(--colour-primary);\n}\ntable.table-main tbody tr td:has(.dirty) table tr:not(:has(.dirty)) {\n background-color: var(--colour-text-background);\n}\ntable.table-main tbody tr:not(:last-of-type) td {\n padding-bottom: 0.25vh;\n}\ntable.table-main tbody tr td.ddl-preview div {\n cursor: pointer;\n}\ntable.table-main tbody tr td.ddl-preview div,\ntable.table-main tbody tr td.ddl-preview select {\n padding-left: 2vh;\n padding-right: 2vh;\n}\ntable.table-main thead tr th.active, \ntable.table-main tbody tr td.active {\n max-width: 6vh;\n min-width: 6vh;\n}\ntable.table-main thead tr th.active svg.active.add {\n fill: var(--colour-primary);\n background-color: var(--colour-accent);\n border: 2px solid var(--colour-accent);\n padding: 0;\n border-radius: 1vh;\n}\ntable.table-main tbody tr td.active svg.active.add {\n fill: var(--colour-primary);\n}\ntable.table-main tbody tr td.active svg.active.delete {\n fill: var(--colour-error);\n}\ntable.table-main tbody tr td.display_order, \ntable.table-main thead tr th.display_order {\n max-width: 5vh;\n min-width: 5vh;\n}\n\n#container-template-elements {\n display: none;\n}\n\n\n@media screen and (max-width: 850px) {\n}\n@media screen and (max-width: 400px) {\n #formFilters input[type=\"text\"],\n #formFilters select {\n width: 15vh;\n /* height: 3vh; */\n }\n .topnav .container.company-name {\n margin: 0 auto;\n min-width: 40vw;\n max-width: 64vw;\n }\n .company-name {\n font-size: 1.2rem;\n }\n table.table-main {\n max-height: 61vh;\n }\n table.table-main thead {\n font-size: 0.8rem;\n }\n table.table-main tbody {\n max-height: 53vh;\n }\n}","/* Default */\n:root {\n /* Claude dark blue / grey theme */\n --colour-accent: #C77DFF;\n --colour-error: red;\n --colour-error-accent: #fc8181;\n --colour-error-highlight: #fff5f5;\n --colour-error-title: #c53030;\n --colour-page-background: #E0AAFF;\n --colour-page-background-1: #F5ECFE;\n --colour-page-background-2: #FAE0E2;\n --colour-primary: #240046;\n --colour-secondary: #3C096C;\n --colour-success: #38a169;\n --colour-success-highlight: #f0fff4;\n --colour-success-title: #16a34a;\n --colour-text: #10002B;\n --colour-text-background: white;\n --colour-text-link-unvisited: #0000EE;\n --colour-text-link-visited: #551A8B;\n}\n\n/*\n--c_purple_darker: #310055;\n--c_purple_dark: #4A0A77;\n--c_purple: #6818A5;\n--c_purple_light: #CBAFFE;\n--c_purple_lighter: #F5ECFE;\n\n--c_blue: #0044FF;\n--c_blue_pastel: #B8E0FF;\n--c_blue_light: #73E8FF;\n--c_blue_dark: #003ADB;\n/* --c_red: * /\n--c-red: #FF0000;\n--c_red_pastel: #FAE0E2;\n--c_red_lighter: #FAE0E2;\n}\n*/"],"names":[],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"css/main.bundle.css","mappings":"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","sources":["webpack://app/./static/css/main.css","webpack://app/./static/css/components/button.css","webpack://app/./static/css/components/form.css","webpack://app/./static/css/components/image.css","webpack://app/./static/css/components/label.css","webpack://app/./static/css/components/overlay.css","webpack://app/./static/css/components/table.css","webpack://app/./static/css/layouts/header.css","webpack://app/./static/css/layouts/footer.css","webpack://app/./static/css/layouts/table-main.css","webpack://app/./static/css/themes/dark.css"],"sourcesContent":["\n:root {\n --font-family-base: 'Open Sans', Arial, sans-serif;\n /* Declare global variables */\n /*\n --c_purple: #5B29FF;\n --c_purple_pastel: #D1D1FF;\n --c_purple_lighter: #E8E1FF;\n --c_purple_light: #C6BDFF;\n --c_purple_dark: #4700B3;\n */\n /* purple theme\n - light https://coolors.co/palette/a172fd-a77afe-ac82fe-b691fe-c1a0fe-cbaffe-d6bffe-e0cefe-ebddfe-f5ecfe\n - dark https://coolors.co/palette/310055-3c0663-4a0a77-5a108f-6818a5-8b2fc9-ab51e3-bd68ee-d283ff-dc97ff\n */\n /*\n --c_purple_darker: #310055;\n --c_purple_dark: #4A0A77;\n --c_purple: #6818A5;\n --c_purple_light: #CBAFFE;\n --c_purple_lighter: #F5ECFE;\n\n --c_blue: #0044FF;\n --c_blue_pastel: #B8E0FF;\n --c_blue_light: #73E8FF;\n --c_blue_dark: #003ADB;\n */\n /* --c_red: * /\n --c-red: #FF0000;\n --c_red_pastel: #FAE0E2;\n --c_red_lighter: #FAE0E2;\n */\n}\n\nhtml {\n height: 100vh;\n /* overflow-y: clip; */\n}\n\nbody {\n background-color: var(--background-color);\n color: var(--text-color);\n font-family: var(--font-family-base);\n font-family: Arial;\n padding: 0;\n margin: 0;\n border: 0;\n height: 100vh;\n /* max-height: 100vh;\n overflow-y: clip; */\n}\n\n* {\n margin: 0;\n color: var(--text-color);\n}\n\nscript, link {\n display: none !important;\n}\n\n/*\n#pageBody {\n / * height: 69vh !important; * /\n max-height: 79vh;\n padding: 0 5vw;\n margin: 0;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n position: absolute;\n width: 90vw;\n color: var(--colour-text);\n}\n*/\n\n.page-body > * {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n text-align: center;\n width: 100%;\n align-self: center;\n font-size: 1rem;\n color: var(--text-color);\n}\n#pageBody > * > * {\n align-self: center;\n padding-top: 0.5vh 0.5vw;\n padding-bottom: 0.5vh 0.5vw;\n}\n#pageBody > .card {\n height: fit-content;\n margin: 0.5vh auto;\n}\n\n\n\n/* Add a card effect for articles */\n.card {\n padding: 1vh 2.5vw;\n margin: 1vh 1vw;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n text-align: center;\n border-radius: 1.5vh;\n position: relative;\n height: fit-content;\n max-width: 80vw;\n}\n\n.container {\n flex: 1;\n margin: 0;\n align-items: flex-start;\n justify-content: flex-start;\n text-align: flex-start;\n /* max-width: 100%; */\n /* min-width: fit-content; */\n}\n\n.column {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin: auto 0;\n}\n\n.row {\n display: flex; \n flex-direction: row;\n width: 100%;\n flex-wrap: wrap;\n}\n\n.container > .card:first-of-type {\n margin-top: none;\n}\n\n\n/*\n/* Responsive layout - when the screen is less than 800px wide, make the two columns stack on top of each other instead of next to each other *\n@media screen and (max-width: 800px) {\n .leftcolumn, .rightcolumn { \n width: 100%;\n /* padding: 0; *\n }\n}\n\n/* Responsive layout - when the screen is less than 400px wide, make the navigation links stack on top of each other instead of next to each other *\n@media screen and (max-width: 400px) {\n .topnav a {\n float: none;\n width: 100%;\n }\n}\n*/\n\n.container-input {\n padding: 1vh 1vw;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n text-align: center;\n}\n\n.container-input > label {\n width: 100%;\n margin-bottom: 1vh;\n margin-top: 0;\n}\n\n.container-input > input,\n.container-input > textarea {\n border: 2px solid var(--border-color);\n border-radius: 0.5vh;\n padding: 1vh 1vw;\n}\n\n.label-title {\n width: 100%;\n}\n\n\nul {\n max-width: 90%;\n padding: 5px 0 10px 0;\n width: fit-content;\n margin: auto;\n}\nli {\n text-align: left;\n font-size: 18px;\n}\n\n\n:not(input,textarea,select,button).dirty {\n background-color: var(--border-color);\n}\ninput.dirty, textarea.dirty, select.dirty {\n border-color: var(--primary-color);\n}\n\n.is-collapsed {\n display: none;\n}\n",".button {\n display: inline-block;\n padding: 0.5vh 0.75vh;\n border-radius: 0.75vh;\n text-decoration: none;\n font-weight: bold;\n transition: all 0.3s ease;\n width: fit-content;\n}\n.button:not(.is_collapsed) {\n cursor: pointer;\n}\n.button.is_collapsed {\n display: block;\n opacity: 0;\n}\n\n.button-primary {\n background: var(--colour-accent);\n color: var(--primary-color);\n border: 2px solid var(--primary-color);\n}\n\n.button-primary:hover {\n background: var(--colour-secondary);\n color: var(--colour-accent);\n}\n\n.button-light {\n background: white;\n color: var(--primary-color);\n}\n\n.button-light:hover {\n background: var(--colour-accent);\n}\n\n.logo:hover{\n cursor: pointer;\n}\n\n\n.button.icon.active.delete, \n.button.icon.active.add {\n height: 2vh;\n}","\n\nselect {\n border: 1px solid var(--colour-accent);\n background-color: var(--background-color-1);\n}","\nimg, video {\n border-radius: 3vh;\n}\n","\nh1 {\n font-size: 2.5rem;\n}\nh2 {\n font-size: 1.8rem;\n}\nh3 {\n font-size: 1.2rem;\n margin-top: 1vh;\n}\nh4 {\n font-size: 13px;\n margin: 1vh;\n text-align: center;\n margin-left: auto;\n margin-right: auto;\n}\nh5 {\n font-size: 11px;\n margin: 1vh;\n}\n\n\n.text-center {\n text-align: center;\n}\n.section-title {\n font-size: 1.8rem;\n margin-bottom: 1rem;\n}\n.section-subtitle {\n font-size: 1.2rem;\n margin-bottom: 2rem;\n}","\n\n/* Overlay modal */\n.overlay {\n /*\n display: none;\n */\n position: fixed;\n width: 100px;\n /* height: 50%; */ \n background: var(--background-color);\n justify-content: right;\n align-items: right;\n align-self: right;\n z-index: 999;\n}\n.is_collapsed {\n display: none;\n}\n\n/* Hamburger menu overlay */\n#buttonHamburger {\n cursor: pointer;\n position: fixed;\n right: 1vh;\n min-height: 3.5vh;\n max-height: 3.5vh;\n min-width: 4vh;\n max-width: 4vh;\n z-index: 10;\n padding: 0;\n}\n#buttonHamburger.expanded {\n min-width: 100px;\n max-width: 100px;\n min-height: 5vh;\n max-height: 5vh;\n padding-left: calc(100 * 1px - 5 * 1vh);\n padding-bottom: 1vh;\n}\n#buttonHamburger .icon.hamburger {\n min-height: 2.5vh;\n max-height: 2.5vh;\n min-width: 2.5vh;\n max-width: 2.5vh;\n padding: 0.5vh 0.75vh;\n}\n/*\n#buttonHamburger:hover {\n text-decoration: none;\n cursor: pointer;\n}\n*/\n#overlayHamburger {\n top: 7vh;\n right: 1vh;\n overflow-x: hidden;\n overflow-y: auto;\n max-height: 60vh;\n background-color: var(--colour-accent);\n border: 2px solid var(--border-colour);\n border-radius: 0.75vh;\n width: 100px;\n z-index: 2;\n padding-top: 3.5vh;\n}\n#overlayHamburger:first-child {\n border-top-left-radius: 12px;\n border-top-right-radius: 12px;\n}\n#overlayHamburger:last-child {\n border-bottom-left-radius: 12px;\n border-bottom-right-radius: 12px;\n}\n#overlayHamburger > :hover {\n color: var(--background-color);\n background-color: var(--primary-color);\n}\n#overlayHamburger .container {\n background-color: var(--tcg-accent-purple);\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n text-align: center;\n width: 100%;\n /* color: var(--colour-text); */\n font-weight: bold;\n font-size: 15px;\n /* height: 18px; */\n cursor: pointer;\n padding: 0;\n height: fit-content;\n}\n#overlayHamburger .container:hover {\n color: var(--background-color);\n background-color: var(--primary-color);\n}\n#overlayHamburger > .container {\n /*\n padding-top: 4.5px;\n padding-bottom: 4.5px;\n */\n}\n#overlayHamburger .container a {\n width: 100%;\n padding: 4.5px 0;\n color: var(--tcg-text-primary);\n text-decoration: none;\n line-height: initial;\n}\n#overlayHamburger .container a:hover {\n color: var(--background-color);\n background-color: var(--primary-color);\n}\n\n@media screen and (max-width: 400px) {\n #buttonHamburger {\n min-height: 5vh;\n max-height: 5vh;\n min-width: 5.5vh;\n max-width: 5.5vh;\n }\n #buttonHamburger .icon.hamburger {\n min-height: 4vh;\n max-height: 4vh;\n min-width: 4vh;\n max-width: 4vh;\n }\n #overlayHamburger {\n padding-top: 5vh;\n }\n}\n\n/* Confirm overlay */\n#overlayConfirm {\n position: absolute;\n left: 25vw;\n width: 50vw;\n height: 50vh;\n}\n\n#overlayConfirm .row > * {\n margin-left: auto;\n margin-right: auto;\n}\n\n#overlayConfirm .row .button.button-cancel {\n margin-right: 0.5vh;\n}\n#overlayConfirm .row .button.submit {\n margin-left: 0.5vh;\n}\n\n\n","\n#formFilters .container {\n max-width: fit-content;\n}\n\nthead, tbody {\n padding-top: 0px !important;\n padding-bottom: 0px !important;\n}\n\nth {\n background-color: transparent;\n}\ntd {\n font-size: min(16px, calc(1vh * 3));\n}\n\nth, td {\n min-width: fit-content;\n}\ntr:not(:last-child) > td {\n border-bottom: 1px dashed var(--border-colour);\n}\ntd > table > tbody > tr > td {\n border: none !important;\n}\nth.is_collapsed, td.is_collapsed {\n display: table-cell !important;\n}\ntd.dirty {\n background-color: var(--primary-color);\n}\ntd:not(.dirty) {\n background-color: transparent;\n}\n\ntr {\n min-height: 1px;\n border-bottom: 1px solid;\n border-top: 1px solid;\n border-color: var(--border-colour);\n background-color: transparent;\n}\n\ntable button {\n margin: 0.25vh;\n padding: 0.5vh 1vh;\n}\n\ntable button.active {\n background-color: var(--background-color);\n}\n\ntr.delete, tr.delete > td {\n background-color: var(--colour-error);\n}\n\ntable div {\n align-content: center;\n}","\n\n/* Navigation */\n.topnav {\n display: flex;\n flex-wrap: wrap;\n flex: 1;\n flex-direction: row;\n font-weight: bold;\n font-size: 1vh;\n max-height: 7vh;\n height: 7vh;\n align-items: flex-start;\n background: var(--colour-text-background);\n justify-content: center; /* space-between */\n align-items: center;\n}\n.topnav a,\n.topnav label,\n.topnav p,\n.topnav h1 {\n float: left;\n display: flex;\n text-align: center;\n text-decoration: none;\n width: 100%;\n max-height: 7vh;\n justify-content: center;\n}\n.topnav h1 {\n color: var(--colour-text-link-visited);\n}\n.topnav a:hover {\n background-color: var(--background-color);\n color: var(--colour-text)\n}\n.topnav > .container {\n width: 30vw;\n min-width: 30vw;\n max-width: 30vw;\n height: 100%;\n align-items: center;\n align-self: center;\n display: flex;\n}\n.topnav .container.logo {\n cursor: pointer;\n}\n.topnav .container .logo {\n /* min-width: 35vh; */\n max-width: 30vw;\n /* width: 30vw; */\n /* min-height: 6vh; */\n max-height: 6vh;\n margin: 0.5vh;\n margin-right: auto;\n}\n.topnav .container.company-name {\n min-width: 30vw;\n max-width: 30vw;\n}\n.company-name {\n font-size: 1.6rem;\n}\n.nav-links {\n display: flex;\n gap: 0 2rem;\n display: flex;\n flex-wrap: wrap;\n max-width: calc(1vw * 100 - 1vh * 35);\n align-items: center;\n margin: 0 0.5vw;\n}\n.nav-links a {\n text-decoration: none;\n color: var(--colour-text);\n font-weight: normal;\n align-content: center;\n font-size: 1.2rem;\n width: fit-content;\n padding: 0.5vh 0.5vw;\n border-radius: 0.5vh;\n}\n.nav-links a.button {\n color: var(--colour-text-background);\n margin: 0 auto;\n font-weight: bold;\n}\n\n\n/* Page Filters */\n#formFilters {\n width: fit-content;\n margin-left: auto;\n margin-right: auto;\n \n}\n#formFilters * {\n font-size: 1rem;\n}\n\n#formFilters .container {\n}\n#formFilters .container-input {\n max-width: fit-content;\n padding: 0 0.5vh;\n}\n#formFilters .container-input:has(.dirty) {\n background-color: var(--colour-accent);\n} \n\n#formFilters .container-input input {\n width: 10vh;\n max-width: 10vh;\n height: 20px;\n}\n/*\n#formFilters .container-input input {\n height: 1.7vh;\n}\n#formFilters .container-input select {\n height: 2vh;\n}\n*/\n\n#formFilters .container-input.filter.active_only {\n width: 8vh;\n}\n#formFilters .container-input.filter.active_only input {\n display: none;\n}\n#formFilters .container-input.filter.active_only svg.active_only {\n height: 25px;\n fill: var(--colour-text-background);\n background-color: var(--colour-accent);\n /* border: 1px solid var(--colour-accent);\n border-radius: 0.5vh; */\n width: 25px;\n}\n#formFilters .container-input.filter.active_only svg.active_only.is_checked {\n fill: var(--colour-accent);\n background-color: var(--colour-text-background);\n}\n#formFilters .container-input.filter.is_not_empty {\n width: 12vh;\n}\n\n/*\n#formFilters button {\n padding: 0.5vh 0.75vh;\n background-color: var(--colour-accent);\n color: var(--primary-color);\n font-weight: bold;\n border-radius: 0.75vh;\n border: 2px solid var(--primary-color);\n}\n\n#formFilters button.is_collapsed {\n display: block;\n opacity: 0;\n}\n*/\n\nform.filter button.save, form.filter button.button-cancel {\n margin-top: 0;\n margin-bottom: 0;\n}\nform.filter button.save, form.filter button.button-cancel {\n margin-top: 0;\n margin-bottom: 1px;\n}\n\n/*\n@media screen and (max-width: 400px) {\n .topnav h1 {\n font-size: 16px;\n }\n}\n*/\n\n@media screen and (max-width: 980px) {\n /*\n .hero h1 {\n font-size: 2.5rem;\n }\n */\n .nav-links,\n .nav-links.tcg {\n display: none;\n }\n .topnav {\n justify-content: flex-start;\n align-items: start;\n }\n .topnav.tcg {\n padding-right: 30vw;\n }\n}","\n/* In sections */\n.tcg.footer {\n display: flex;\n}\n.tcg.footer > .container {\n /* display: flex; */\n}\n.footer-content {\n display: flex;\n margin: 0 auto;\n}\n.footer-section {\n /* display: flex; */\n margin: auto auto;\n}\n","\n#formFilters {\n padding: 0.5vh 1vw;\n margin-top: 1vh;\n}\n\n.table-main {\n overflow-x: auto;\n padding: 0; /*1vh 1vw;*/\n max-width: 80vw; /* min(calc(1vh * 80), calc(1vw * 90)); */\n width: min-content;\n align-items: normal;\n justify-content: normal;\n margin: 0 auto;\n}\n\n.table-main * {\n padding: 0.25vh 0.5vh;\n}\n\n.table-main thead {\n max-height: 4vh;\n overflow-y: visible;\n background-color: var(--background-color);\n}\n\n.table-main tbody {\n max-height: 75vh;\n overflow-y: auto;\n min-width: fit-content;\n max-width: fit-content;\n overflow-x: visible;\n}\n.table-main tbody.is_collapsed {\n display: block;\n}\n.table-main:has(tbody > div) tbody {\n}\n.table-main tbody > div {\n margin-left: auto;\n margin-right: auto;\n text-align: center;\n justify-content: center;\n justify-items: center;\n justify-self: center;\n align-content: center;\n align-items: center;\n align-self: center;\n position: relative;\n display: block;\n width: 100%; /* min(calc(90vh), calc(70vw)); */\n}\n\n.table-main select, \n.table-main input:not([type=\"checkbox\"]), \n.table-main textarea, \n.table-main div {\n box-sizing: border-box;\n width: 100%;\n max-width: 100%;\n height: 100%;\n border: 1px solid var(--border-color);\n border-radius: 0.5vh;\n text-align: center;\n background-color: var(--background-color);\n font-size: 16px;\n}\n\n.table-main thead tr th, \n.table-main tbody tr td {\n max-width: 20vh;\n min-width: 20vh;\n padding: 0 0.5vh;\n}\n.table-main tbody tr td {\n height: 3vh;\n /* padding-top: 0.5vh; */\n}\n.table-main thead tr th.notes, \n.table-main tbody tr td.notes {\n max-width: fit-content;\n}\n.table-main tbody tr td:has(.dirty) {\n background-color: var(--primary-color);\n}\n.table-main tbody tr td:has(.dirty) table tr:not(:has(.dirty)) {\n background-color: var(--colour-text-background);\n}\n.table-main tbody tr:not(:last-of-type) td {\n padding-bottom: 0.25vh;\n}\n.table-main tbody tr td.ddl-preview div {\n cursor: pointer;\n}\n.table-main tbody tr td.ddl-preview div,\n.table-main tbody tr td.ddl-preview select {\n padding-left: 2vh;\n padding-right: 2vh;\n}\n.table-main thead tr th.active, \n.table-main tbody tr td.active {\n max-width: 6vh;\n min-width: 6vh;\n}\n.table-main thead tr th.active svg.active.add {\n fill: var(--primary-color);\n background-color: var(--background-color);\n border: 2px solid var(--border-color);\n padding: 0;\n border-radius: 1vh;\n}\n.table-main tbody tr td.active svg.active.add {\n fill: var(--primary-color);\n}\n.table-main tbody tr td.active svg.active.delete {\n fill: var(--tcg-accent-red);\n}\n.table-main tbody tr td.display_order, \n.table-main thead tr th.display_order {\n max-width: 5vh;\n min-width: 5vh;\n}\n\n#container-template-elements {\n display: none;\n}\n\n\n@media screen and (max-width: 850px) {\n}\n@media screen and (max-width: 400px) {\n #formFilters input[type=\"text\"],\n #formFilters select {\n width: 15vh;\n /* height: 3vh; */\n }\n .topnav .container.company-name {\n margin: 0 auto;\n min-width: 40vw;\n max-width: 64vw;\n }\n .company-name {\n font-size: 1.2rem;\n }\n .table-main {\n max-height: 61vh;\n }\n .table-main thead {\n font-size: 0.8rem;\n }\n .table-main tbody {\n max-height: 53vh;\n }\n}","\n:root {\n --background-color: #121212;\n --text-color: #e0e0e0;\n --primary-color: #bb86fc;\n --secondary-color: #03dac6;\n --success-color: #00c853;\n --danger-color: #cf6679;\n --warning-color: #ffab00;\n --info-color: #2196f3;\n --light-color: #2c2c2c;\n --dark-color: #1f1f1f;\n --border-color: #333333;\n --shadow-color: rgba(255, 255, 255, 0.1);\n \n /* Header * /\n --header-bg: #1f1f1f;\n --header-text: #e0e0e0;\n \n /* Footer * /\n --footer-bg: #1f1f1f;\n --footer-text: #a0a0a0;\n \n /* Navigation * /\n --nav-bg: #1f1f1f;\n --nav-text: #e0e0e0;\n --nav-hover-bg: #2c2c2c;\n --nav-hover-text: #bb86fc;\n \n /* Buttons * /\n --Button-primary-bg: #bb86fc;\n --Button-primary-text: #121212;\n --Button-secondary-bg: #03dac6;\n --Button-secondary-text: #121212;\n \n /* Forms * /\n --input-bg: #2c2c2c;\n --input-border: #454545;\n --input-text: #e0e0e0;\n --input-focus-border: #bb86fc;\n \n /* Cards * /\n --card-bg: #1f1f1f;\n --card-border: #333333;\n --card-shadow: 0 0.125rem 0.25rem rgba(255, 255, 255, 0.05);\n */\n}\n"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/static/dist/css/tcg_decks.bundle.css b/static/dist/css/tcg_decks.bundle.css new file mode 100644 index 0000000..dbee99f --- /dev/null +++ b/static/dist/css/tcg_decks.bundle.css @@ -0,0 +1,106 @@ + + +.container-input > input { + padding: 0vh 1vh; + border-radius: 0.5vh; + max-width: 7vh; +} + + +/* Right column */ +.rightcolumn { + min-width: fit-content; +} + +/* Main Table */ +#pageBody { + max-height: 82vh; + padding: 0 5vw; + margin: 0; + border: 0; + align-content: center; + justify-content: flex-start; + display: flex; + flex-direction: column; + align-items: flex-start; + overflow-y: auto; + overflow-x: hidden; + position: absolute; + width: 90vw; + color: var(--colour-text); +} + + +/* Footer */ +.footer { + padding: 1vh 1vw; + text-align: center; + margin: 0; + max-height: 5vh; + overflow-y: auto; + background-color: var(--colour-accent); + position: absolute; + bottom: 0; + width: 98vw; +} + +@media screen and (max-width: 400px) { + .footer { + max-height: 8vh; + padding: 0.75vh 2vw; + font-size: 10px; + width: 96vw; + max-width: 96vw; + } + .footer > h4 { + font-size: 10px; + } + .footer > h5 { + font-size: 9px; + } +} + +.footer > h4, h5 { + padding: 0; + margin: 0; +} + + +.tcg-card { + margin-top: 1vh; + margin-bottom: 0; +} + + +table.table-main tbody { + max-height: 30vh; + overflow-y: auto; +} + +table.statistics { + margin-top: 0; +} +table.statistics thead { + background-color: var(--background-color); +} +table.statistics tbody { + max-height: 30vh; + overflow-y: auto; +} +table.statistics thead tr th.deck, +table.statistics tbody tr td.deck_id { + min-width: 20vh; + max-width: 20vh; +} +table.statistics thead tr th.name, +table.statistics tbody tr td.name { + min-width: 40vh; + max-width: 40vh; +} +table.statistics thead tr th.value, +table.statistics tbody tr td.value { + min-width: 10vh; + max-width: 10vh; +} + +/*# sourceMappingURL=tcg_decks.bundle.css.map*/ \ No newline at end of file diff --git a/static/dist/css/tcg_decks.bundle.css.map b/static/dist/css/tcg_decks.bundle.css.map new file mode 100644 index 0000000..1433190 --- /dev/null +++ b/static/dist/css/tcg_decks.bundle.css.map @@ -0,0 +1 @@ +{"version":3,"file":"css/tcg_decks.bundle.css","mappings":";;AAEA;IACI,gBAAgB;IAChB,oBAAoB;IACpB,cAAc;AAClB;;;AAGA,iBAAiB;AACjB;IACI,sBAAsB;AAC1B;;AAEA,eAAe;AACf;IACI,gBAAgB;IAChB,cAAc;IACd,SAAS;IACT,SAAS;IACT,qBAAqB;IACrB,2BAA2B;IAC3B,aAAa;IACb,sBAAsB;IACtB,uBAAuB;IACvB,gBAAgB;IAChB,kBAAkB;IAClB,kBAAkB;IAClB,WAAW;IACX,yBAAyB;AAC7B;;;AAGA,WAAW;AACX;IACI,gBAAgB;IAChB,kBAAkB;IAClB,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,sCAAsC;IACtC,kBAAkB;IAClB,SAAS;IACT,WAAW;AACf;;AAEA;IACI;QACI,eAAe;QACf,mBAAmB;QACnB,eAAe;QACf,WAAW;QACX,eAAe;IACnB;IACA;QACI,eAAe;IACnB;IACA;QACI,cAAc;IAClB;AACJ;;AAEA;IACI,UAAU;IACV,SAAS;AACb,C;;;AC/DA;IACI,eAAe;IACf,gBAAgB;AACpB;;;AAGA;IACI,gBAAgB;IAChB,gBAAgB;AACpB;;AAEA;IACI,aAAa;AACjB;AACA;IACI,yCAAyC;AAC7C;AACA;IACI,gBAAgB;IAChB,gBAAgB;AACpB;AACA;;IAEI,eAAe;IACf,eAAe;AACnB;AACA;;IAEI,eAAe;IACf,eAAe;AACnB;AACA;;IAEI,eAAe;IACf,eAAe;AACnB,C","sources":["webpack://app/./static/css/sections/tcg.css","webpack://app/./static/css/pages/tcg/decks.css"],"sourcesContent":["\n\n.container-input > input {\n padding: 0vh 1vh;\n border-radius: 0.5vh;\n max-width: 7vh;\n}\n\n\n/* Right column */\n.rightcolumn {\n min-width: fit-content;\n}\n\n/* Main Table */\n#pageBody {\n max-height: 82vh;\n padding: 0 5vw;\n margin: 0;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n position: absolute;\n width: 90vw;\n color: var(--colour-text);\n}\n\n\n/* Footer */\n.footer {\n padding: 1vh 1vw;\n text-align: center;\n margin: 0;\n max-height: 5vh;\n overflow-y: auto;\n background-color: var(--colour-accent);\n position: absolute;\n bottom: 0;\n width: 98vw;\n}\n\n@media screen and (max-width: 400px) {\n .footer {\n max-height: 8vh;\n padding: 0.75vh 2vw;\n font-size: 10px; \n width: 96vw;\n max-width: 96vw;\n }\n .footer > h4 {\n font-size: 10px;\n }\n .footer > h5 {\n font-size: 9px;\n }\n}\n\n.footer > h4, h5 {\n padding: 0;\n margin: 0;\n}","\n\n.tcg-card {\n margin-top: 1vh;\n margin-bottom: 0;\n}\n\n\ntable.table-main tbody {\n max-height: 30vh;\n overflow-y: auto;\n}\n\ntable.statistics {\n margin-top: 0;\n}\ntable.statistics thead {\n background-color: var(--background-color);\n}\ntable.statistics tbody {\n max-height: 30vh;\n overflow-y: auto;\n}\ntable.statistics thead tr th.deck,\ntable.statistics tbody tr td.deck_id {\n min-width: 20vh;\n max-width: 20vh;\n}\ntable.statistics thead tr th.name,\ntable.statistics tbody tr td.name {\n min-width: 40vh;\n max-width: 40vh;\n}\ntable.statistics thead tr th.value,\ntable.statistics tbody tr td.value {\n min-width: 10vh;\n max-width: 10vh;\n}"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/static/dist/css/tcg_game.bundle.css b/static/dist/css/tcg_game.bundle.css index c23a2f2..7093907 100644 --- a/static/dist/css/tcg_game.bundle.css +++ b/static/dist/css/tcg_game.bundle.css @@ -14,7 +14,7 @@ /* Main Table */ #pageBody { - max-height: 77vh; + max-height: 82vh; padding: 0 5vw; margin: 0; border: 0; @@ -213,6 +213,9 @@ } /* Game Section */ +#gameSection { + margin: 0 auto; +} #gameSection .row.round { display: flex; align-items: center; @@ -413,13 +416,16 @@ text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5); } -.life-controls { +.life-gain-controls, +.life-loss-controls { display: flex; gap: 1rem; justify-content: center; + margin-bottom: 1vh; } -.life-btn { +.life-gain-btn, +.life-loss-btn { background: var(--tcg-bg-card); border: 2px solid var(--tcg-border-color); color: var(--tcg-text-primary); @@ -436,17 +442,31 @@ justify-content: center; } -.life-btn:hover { - border-color: var(--tcg-accent-purple); - background: var(--tcg-accent-purple); +.life-gain-btn:hover, +.life-loss-btn:hover { + border-color: green; /*var(--tcg-accent-purple);*/ + background: green; /*var(--tcg-accent-purple);*/ color: var(--tcg-bg-primary); transform: scale(1.1); } -.life-btn:active { +.life-loss-btn:hover { + border-color: red; + background: red; +} + +.life-gain-btn:active, +.life-loss-btn:active { transform: scale(0.95); } +.life-total label { + color: var(--tcg-text-primary); + width: 100%; + margin-bottom: 1vh; + display: inline-block; +} + /* Commander Damage Section */ .commander-damage-section { border-top: 1px solid var(--tcg-border-color); @@ -486,6 +506,7 @@ .damage-source { font-size: 1rem; color: var(--tcg-text-secondary); + padding-right: 1vh; } .damage-controls { @@ -544,8 +565,10 @@ .damage-log.container table tbody tr td.received_from_commander_player_id { width: 20vw; } -.damage-log.container table thead tr th.health_change, -.damage-log.container table tbody tr td.health_change { +.damage-log.container table thead tr th.life_gain, +.damage-log.container table tbody tr td.life_gain, +.damage-log.container table thead tr th.life_loss, +.damage-log.container table tbody tr td.life_loss { width: 7vw; } .damage-log.container table thead tr th.commander-deaths, @@ -649,7 +672,8 @@ font-size: 3rem; } - .life-btn { + .life-gain-btn, + .life-loss-btn { width: 50px; height: 50px; font-size: 1.5rem; diff --git a/static/dist/css/tcg_game.bundle.css.map b/static/dist/css/tcg_game.bundle.css.map index 894a171..a9e50d8 100644 --- a/static/dist/css/tcg_game.bundle.css.map +++ b/static/dist/css/tcg_game.bundle.css.map @@ -1 +1 @@ -{"version":3,"file":"css/tcg_game.bundle.css","mappings":"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","sources":["webpack://app/./static/css/sections/tcg.css","webpack://app/./static/css/pages/tcg/game.css"],"sourcesContent":["\n\n.container-input > input {\n padding: 0vh 1vh;\n border-radius: 0.5vh;\n max-width: 7vh;\n}\n\n\n/* Right column */\n.rightcolumn {\n min-width: fit-content;\n}\n\n/* Main Table */\n#pageBody {\n max-height: 77vh;\n padding: 0 5vw;\n margin: 0;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n position: absolute;\n width: 90vw;\n color: var(--colour-text);\n}\n\n\n/* Footer */\n.footer {\n padding: 1vh 1vw;\n text-align: center;\n margin: 0;\n max-height: 5vh;\n overflow-y: auto;\n background-color: var(--colour-accent);\n position: absolute;\n bottom: 0;\n width: 98vw;\n}\n\n@media screen and (max-width: 400px) {\n .footer {\n max-height: 8vh;\n padding: 0.75vh 2vw;\n font-size: 10px; \n width: 96vw;\n max-width: 96vw;\n }\n .footer > h4 {\n font-size: 10px;\n }\n .footer > h5 {\n font-size: 9px;\n }\n}\n\n.footer > h4, h5 {\n padding: 0;\n margin: 0;\n}","/* MTG Single Game Page Styles */\n\n#buttonHamburger {\n display: none;\n}\n\n/* Game Header */\n.game-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin: 1vh auto;\n flex-wrap: wrap;\n gap: 0;\n animation: tcg-fadeInDown 0.8s ease-out;\n}\n\n.header-left, .header-right {\n flex: 1;\n color: var(--tcg-text-secondary);\n font-size: 1rem;\n margin: 0 auto;\n}\n\n.header-left {\n padding-left: 15vw;\n width: 30vw;\n}\n\n.header-right {\n text-align: right;\n min-width: 15vw;\n width: 15vw;\n}\n\n.header-center {\n text-align: center;\n flex: 2;\n padding-left: 4vw;\n}\n\n.game-header .container.save.button-cancel {\n width: 15vw;\n max-width: 15vw;\n}\n\n.back-link {\n color: var(--tcg-text-secondary);\n text-decoration: none;\n font-family: 'Cinzel', serif;\n font-size: 1rem;\n transition: color 0.3s ease;\n}\n\n.back-link:hover {\n color: var(--tcg-accent-gold);\n}\n\n.game-title {\n font-family: 'Cinzel', serif;\n font-size: 2.5rem;\n font-weight: 700;\n background: linear-gradient(135deg, var(--tcg-accent-gold), var(--tcg-accent-purple));\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n margin-bottom: 0.5rem;\n letter-spacing: 0.05em;\n}\n\n.game-meta {\n display: flex;\n gap: 0;\n justify-content: center;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.game-meta .location {\n color: var(--tcg-text-secondary);\n font-size: 1rem;\n width: 4vw;\n}\n\n/* Setup Section */\n.setup-section {\n max-width: 800px;\n margin: 0 auto 2rem;\n animation: tcg-fadeIn 0.8s ease-out 0.2s backwards;\n}\n\n.setup-controls {\n display: flex;\n gap: 2rem;\n justify-content: center;\n flex-wrap: wrap;\n margin-bottom: 2rem;\n}\n\n.control-group {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.control-group .tcg-input {\n width: 80px;\n text-align: center;\n font-family: 'Cinzel', serif;\n font-size: 1.2rem;\n}\n\n.player-names-grid {\n display: flex;\n flex-wrap: wrap;\n gap: 1rem;\n max-width: 800px;\n margin: 0 auto 2rem;\n justify-content: center;\n}\n\n.player-name-input-wrapper {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n border: 1px solid gray;\n border-radius: 0.5vh;\n padding: 1vh;\n width: fit-content;\n}\n.player-name-input-wrapper.is_collapsed {\n display: none;\n}\n\n.player-name-heading-label,\n.player-name-label {\n font-size: 0.9rem;\n color: var(--tcg-text-secondary);\n letter-spacing: 0.05em;\n}\n.player-name-label {\n font-size: 0.8rem;\n}\n\n.setup-actions {\n text-align: center;\n}\n\n/* Game Section */\n#gameSection .row.round {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.9rem;\n color: var(--tcg-text-secondary);\n margin: 0 auto 0.5vh;\n width: fit-content;\n}\n#gameSection .row.round .row.round .round.display_order {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n background: var(--tcg-bg-card);\n border: 1px solid var(--tcg-border-color);\n border-radius: 6px;\n padding: 0.25rem 0.5rem;\n}\n/*\n#gameSection .row.round label {\n margin-left: 30vw;\n color: var(--tcg-text-secondary);\n font-size: 1rem;\n width: 4vw;\n}\n#gameSection .row.round input {\n width: 10vw;\n margin: 0 3vw 1vh;\n}\n*/\n#gameSection .row.round .row.round span.round.display_order {\n font-family: 'Cinzel', serif;\n font-weight: 600;\n color: var(--tcg-text-primary);\n min-width: 20px;\n justify-content: center;\n}\n#gameSection .row.round .row.round button.btn-round-display-order {\n background: transparent;\n border: none;\n color: var(--tcg-text-secondary);\n cursor: pointer;\n font-size: 1rem;\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n}\n#gameSection .row.round .row.round button.btn-round-display-order:hover {\n color: var(--tcg-accent-red);\n transform: scale(1.2);\n}\n\n/* Players Grid */\n.players-grid {\n display: flex; /* grid;\n grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));\n */\n gap: 2rem;\n margin-bottom: 2rem;\n max-width: 90vw;\n flex-wrap: wrap;\n margin: 0 auto;\n width: fit-content;\n\n}\n\n/* Player Card */\n.player-card {\n background: var(--tcg-bg-secondary);\n border: 2px solid var(--tcg-border-color);\n border-radius: 16px;\n padding: 1.5rem;\n position: relative;\n overflow: hidden;\n transition: all 0.4s ease;\n animation: tcg-scaleIn 0.5s ease-out backwards;\n width: fit-content;\n max-width: 38vw;\n min-width: 20vw;\n margin: 0 auto;\n}\n\n.player-card::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 4px;\n background: linear-gradient(90deg, var(--tcg-accent-purple), var(--tcg-accent-gold));\n}\n\n.player-card.eliminated {\n opacity: 0.5;\n filter: grayscale(0.8);\n}\n\n.player-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 1.5rem;\n flex-wrap: wrap;\n gap: 1rem;\n}\n\n.player-info {\n flex: 1;\n min-width: 150px;\n}\n\n.player-name {\n font-family: 'Cinzel', serif;\n font-size: 1.5rem;\n font-weight: 600;\n color: var(--tcg-accent-gold);\n letter-spacing: 0.05em;\n margin-bottom: 0.5rem;\n}\n\n.commander-deaths {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.9rem;\n color: var(--tcg-text-secondary);\n}\n\n.death-counter {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n background: var(--tcg-bg-card);\n border: 1px solid var(--tcg-border-color);\n border-radius: 6px;\n padding: 0.25rem 0.5rem;\n}\n\n.death-display {\n font-family: 'Cinzel', serif;\n font-weight: 600;\n color: var(--tcg-text-primary);\n min-width: 20px;\n text-align: center;\n}\n\n.death-btn {\n background: transparent;\n border: none;\n color: var(--tcg-text-secondary);\n cursor: pointer;\n font-size: 1rem;\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n}\n\n.death-btn:hover {\n color: var(--tcg-accent-red);\n transform: scale(1.2);\n}\n\n.eliminate-btn {\n background: var(--tcg-accent-red);\n color: white;\n border: none;\n padding: 0.5rem 1rem;\n border-radius: 6px;\n font-size: 0.9rem;\n cursor: pointer;\n font-family: 'Cinzel', serif;\n transition: all 0.3s ease;\n}\n\n.eliminate-btn:hover {\n background: #b91c1c;\n transform: scale(1.05);\n}\n\n/* Life Total */\n.life-total {\n text-align: center;\n margin-bottom: 2rem;\n}\n\n.life-display {\n font-family: 'Cinzel', serif;\n font-size: 4rem;\n font-weight: 700;\n color: var(--tcg-text-primary);\n margin-bottom: 1rem;\n text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);\n}\n\n.life-controls {\n display: flex;\n gap: 1rem;\n justify-content: center;\n}\n\n.life-btn {\n background: var(--tcg-bg-card);\n border: 2px solid var(--tcg-border-color);\n color: var(--tcg-text-primary);\n width: 60px;\n height: 60px;\n border-radius: 12px;\n font-family: 'Cinzel', serif;\n font-size: 1.8rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.life-btn:hover {\n border-color: var(--tcg-accent-purple);\n background: var(--tcg-accent-purple);\n color: var(--tcg-bg-primary);\n transform: scale(1.1);\n}\n\n.life-btn:active {\n transform: scale(0.95);\n}\n\n/* Commander Damage Section */\n.commander-damage-section {\n border-top: 1px solid var(--tcg-border-color);\n padding-top: 1.5rem;\n}\n\n.section-title {\n font-family: 'Cinzel', serif;\n font-size: 1.1rem;\n color: var(--tcg-accent-purple);\n margin-bottom: 1rem;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n}\n\n.damage-grid {\n display: grid;\n gap: 0.75rem;\n}\n\n.damage-row {\n background: var(--tcg-bg-card);\n border: 1px solid var(--tcg-border-color);\n border-radius: 8px;\n padding: 0.75rem;\n display: flex;\n justify-content: space-between;\n align-items: center;\n transition: all 0.3s ease;\n}\n\n.damage-row:hover {\n border-color: var(--tcg-accent-purple);\n background: rgba(139, 92, 246, 0.1);\n}\n\n.damage-source {\n font-size: 1rem;\n color: var(--tcg-text-secondary);\n}\n\n.damage-controls {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n}\n\n.damage-display {\n font-family: 'Cinzel', serif;\n font-size: 1.5rem;\n font-weight: 600;\n color: var(--tcg-text-primary);\n min-width: 40px;\n text-align: center;\n}\n\n.damage-display.lethal {\n color: var(--tcg-accent-red);\n animation: pulse 1s ease-in-out infinite;\n}\n\n.damage-btn {\n background: var(--tcg-bg-primary);\n border: 1px solid var(--tcg-border-color);\n color: var(--tcg-text-primary);\n width: 36px;\n height: 36px;\n border-radius: 6px;\n font-size: 1.2rem;\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.damage-btn:hover {\n border-color: var(--tcg-accent-purple);\n background: var(--tcg-accent-purple);\n color: var(--tcg-bg-primary);\n}\n\n.damage-log.container {\n color: white;\n margin: 2vh auto 0;\n text-align: center;\n}\n.damage-log.container table thead tr th.round_id,\n.damage-log.container table tbody tr td.round_id {\n width: 7vw;\n}\n.damage-log.container table thead tr th.player_id,\n.damage-log.container table tbody tr td.player_id,\n.damage-log.container table thead tr th.received_from_commander_player_id,\n.damage-log.container table tbody tr td.received_from_commander_player_id {\n width: 20vw;\n}\n.damage-log.container table thead tr th.health_change,\n.damage-log.container table tbody tr td.health_change {\n width: 7vw;\n}\n.damage-log.container table thead tr th.commander-deaths,\n.damage-log.container table tbody tr td.commander-deaths {\n width: 7vw;\n}\n.damage-log.container table thead tr th.is_eliminated,\n.damage-log.container table tbody tr td.is_eliminated {\n width: 7vw;\n}\n\n/* Save Indicator */\n.save-indicator {\n position: fixed;\n bottom: 2rem;\n right: 2rem;\n background: var(--tcg-bg-secondary);\n border: 2px solid var(--tcg-accent-gold);\n border-radius: 8px;\n padding: 0.75rem 1.5rem;\n font-family: 'Cinzel', serif;\n color: var(--tcg-accent-gold);\n font-size: 0.9rem;\n opacity: 0;\n transform: translateY(20px);\n transition: all 0.3s ease;\n pointer-events: none;\n z-index: 1000;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);\n}\n\n.save-indicator.show {\n opacity: 1;\n transform: translateY(0);\n}\n\n/* Badges (same as games page) */\n.badge {\n display: inline-block;\n padding: 0.35rem 0.75rem;\n border-radius: 20px;\n font-family: 'Cinzel', serif;\n font-size: 0.8rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.badge-commander {\n background: linear-gradient(135deg, var(--tcg-accent-purple), rgba(139, 92, 246, 0.5));\n color: white;\n margin: 0 auto;\n}\n\n.badge-draft {\n background: linear-gradient(135deg, #2563eb, rgba(37, 99, 235, 0.5));\n color: white;\n}\n\n.badge-sealed {\n background: linear-gradient(135deg, #059669, rgba(5, 150, 105, 0.5));\n color: white;\n}\n\n.badge-standard {\n background: linear-gradient(135deg, var(--tcg-accent-gold), rgba(212, 175, 55, 0.5));\n color: var(--tcg-bg-primary);\n}\n\n/* Hidden Class */\n.hidden {\n display: none !important;\n}\n\n/* Animations */\n@keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.6; }\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .game-header {\n flex-direction: column;\n text-align: center;\n }\n\n .header-left, .header-right {\n text-align: center;\n }\n\n .game-title {\n font-size: 1.8rem;\n }\n\n .players-grid {\n grid-template-columns: 1fr;\n }\n\n .life-display {\n font-size: 3rem;\n }\n\n .life-btn {\n width: 50px;\n height: 50px;\n font-size: 1.5rem;\n }\n\n .setup-controls {\n flex-direction: column;\n align-items: center;\n }\n}\n@media (max-width: 1260px) {\n #buttonHamburger {\n display: block;\n }\n}"],"names":[],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"css/tcg_game.bundle.css","mappings":";;AAEA;IACI,gBAAgB;IAChB,oBAAoB;IACpB,cAAc;AAClB;;;AAGA,iBAAiB;AACjB;IACI,sBAAsB;AAC1B;;AAEA,eAAe;AACf;IACI,gBAAgB;IAChB,cAAc;IACd,SAAS;IACT,SAAS;IACT,qBAAqB;IACrB,2BAA2B;IAC3B,aAAa;IACb,sBAAsB;IACtB,uBAAuB;IACvB,gBAAgB;IAChB,kBAAkB;IAClB,kBAAkB;IAClB,WAAW;IACX,yBAAyB;AAC7B;;;AAGA,WAAW;AACX;IACI,gBAAgB;IAChB,kBAAkB;IAClB,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,sCAAsC;IACtC,kBAAkB;IAClB,SAAS;IACT,WAAW;AACf;;AAEA;IACI;QACI,eAAe;QACf,mBAAmB;QACnB,eAAe;QACf,WAAW;QACX,eAAe;IACnB;IACA;QACI,eAAe;IACnB;IACA;QACI,cAAc;IAClB;AACJ;;AAEA;IACI,UAAU;IACV,SAAS;AACb,C;ACjEA,gCAAgC;;AAEhC;IACI,aAAa;AACjB;;AAEA,gBAAgB;AAChB;IACI,aAAa;IACb,8BAA8B;IAC9B,mBAAmB;IACnB,gBAAgB;IAChB,eAAe;IACf,MAAM;IACN,uCAAuC;AAC3C;;AAEA;IACI,OAAO;IACP,gCAAgC;IAChC,eAAe;IACf,cAAc;AAClB;;AAEA;IACI,kBAAkB;IAClB,WAAW;AACf;;AAEA;IACI,iBAAiB;IACjB,eAAe;IACf,WAAW;AACf;;AAEA;IACI,kBAAkB;IAClB,OAAO;IACP,iBAAiB;AACrB;;AAEA;IACI,WAAW;IACX,eAAe;AACnB;;AAEA;IACI,gCAAgC;IAChC,qBAAqB;IACrB,4BAA4B;IAC5B,eAAe;IACf,2BAA2B;AAC/B;;AAEA;IACI,6BAA6B;AACjC;;AAEA;IACI,4BAA4B;IAC5B,iBAAiB;IACjB,gBAAgB;IAChB,qFAAqF;IACrF,6BAA6B;IAC7B,oCAAoC;IACpC,qBAAqB;IACrB,qBAAqB;IACrB,sBAAsB;AAC1B;;AAEA;IACI,aAAa;IACb,MAAM;IACN,uBAAuB;IACvB,mBAAmB;IACnB,eAAe;AACnB;;AAEA;IACI,gCAAgC;IAChC,eAAe;IACf,UAAU;AACd;;AAEA,kBAAkB;AAClB;IACI,gBAAgB;IAChB,mBAAmB;IACnB,kDAAkD;AACtD;;AAEA;IACI,aAAa;IACb,SAAS;IACT,uBAAuB;IACvB,eAAe;IACf,mBAAmB;AACvB;;AAEA;IACI,aAAa;IACb,mBAAmB;IACnB,SAAS;AACb;;AAEA;IACI,WAAW;IACX,kBAAkB;IAClB,4BAA4B;IAC5B,iBAAiB;AACrB;;AAEA;IACI,aAAa;IACb,eAAe;IACf,SAAS;IACT,gBAAgB;IAChB,mBAAmB;IACnB,uBAAuB;AAC3B;;AAEA;IACI,aAAa;IACb,sBAAsB;IACtB,WAAW;IACX,sBAAsB;IACtB,oBAAoB;IACpB,YAAY;IACZ,kBAAkB;AACtB;AACA;IACI,aAAa;AACjB;;AAEA;;IAEI,iBAAiB;IACjB,gCAAgC;IAChC,sBAAsB;AAC1B;AACA;IACI,iBAAiB;AACrB;;AAEA;IACI,kBAAkB;AACtB;;AAEA,iBAAiB;AACjB;IACI,cAAc;AAClB;AACA;IACI,aAAa;IACb,mBAAmB;IACnB,WAAW;IACX,iBAAiB;IACjB,gCAAgC;IAChC,oBAAoB;IACpB,kBAAkB;AACtB;AACA;IACI,aAAa;IACb,mBAAmB;IACnB,WAAW;IACX,8BAA8B;IAC9B,yCAAyC;IACzC,kBAAkB;IAClB,uBAAuB;AAC3B;AACA;;;;;;;;;;;CAWC;AACD;IACI,4BAA4B;IAC5B,gBAAgB;IAChB,8BAA8B;IAC9B,eAAe;IACf,uBAAuB;AAC3B;AACA;IACI,uBAAuB;IACvB,YAAY;IACZ,gCAAgC;IAChC,eAAe;IACf,eAAe;IACf,WAAW;IACX,YAAY;IACZ,aAAa;IACb,mBAAmB;IACnB,uBAAuB;IACvB,yBAAyB;AAC7B;AACA;IACI,4BAA4B;IAC5B,qBAAqB;AACzB;;AAEA,iBAAiB;AACjB;IACI,aAAa,EAAE;;KAEd;EACH,SAAS;EACT,mBAAmB;EACnB,eAAe;EACf,eAAe;EACf,cAAc;EACd,kBAAkB;;AAEpB;;AAEA,gBAAgB;AAChB;IACI,mCAAmC;IACnC,yCAAyC;IACzC,mBAAmB;IACnB,eAAe;IACf,kBAAkB;IAClB,gBAAgB;IAChB,yBAAyB;IACzB,8CAA8C;IAC9C,kBAAkB;IAClB,eAAe;IACf,eAAe;IACf,cAAc;AAClB;;AAEA;IACI,WAAW;IACX,kBAAkB;IAClB,MAAM;IACN,OAAO;IACP,QAAQ;IACR,WAAW;IACX,oFAAoF;AACxF;;AAEA;IACI,YAAY;IACZ,sBAAsB;AAC1B;;AAEA;IACI,aAAa;IACb,8BAA8B;IAC9B,mBAAmB;IACnB,qBAAqB;IACrB,eAAe;IACf,SAAS;AACb;;AAEA;IACI,OAAO;IACP,gBAAgB;AACpB;;AAEA;IACI,4BAA4B;IAC5B,iBAAiB;IACjB,gBAAgB;IAChB,6BAA6B;IAC7B,sBAAsB;IACtB,qBAAqB;AACzB;;AAEA;IACI,aAAa;IACb,mBAAmB;IACnB,WAAW;IACX,iBAAiB;IACjB,gCAAgC;AACpC;;AAEA;IACI,aAAa;IACb,mBAAmB;IACnB,WAAW;IACX,8BAA8B;IAC9B,yCAAyC;IACzC,kBAAkB;IAClB,uBAAuB;AAC3B;;AAEA;IACI,4BAA4B;IAC5B,gBAAgB;IAChB,8BAA8B;IAC9B,eAAe;IACf,kBAAkB;AACtB;;AAEA;IACI,uBAAuB;IACvB,YAAY;IACZ,gCAAgC;IAChC,eAAe;IACf,eAAe;IACf,WAAW;IACX,YAAY;IACZ,aAAa;IACb,mBAAmB;IACnB,uBAAuB;IACvB,yBAAyB;AAC7B;;AAEA;IACI,4BAA4B;IAC5B,qBAAqB;AACzB;;AAEA;IACI,iCAAiC;IACjC,YAAY;IACZ,YAAY;IACZ,oBAAoB;IACpB,kBAAkB;IAClB,iBAAiB;IACjB,eAAe;IACf,4BAA4B;IAC5B,yBAAyB;AAC7B;;AAEA;IACI,mBAAmB;IACnB,sBAAsB;AAC1B;;AAEA,eAAe;AACf;IACI,kBAAkB;IAClB,mBAAmB;AACvB;;AAEA;IACI,4BAA4B;IAC5B,eAAe;IACf,gBAAgB;IAChB,8BAA8B;IAC9B,mBAAmB;IACnB,yCAAyC;AAC7C;;AAEA;;IAEI,aAAa;IACb,SAAS;IACT,uBAAuB;IACvB,kBAAkB;AACtB;;AAEA;;IAEI,8BAA8B;IAC9B,yCAAyC;IACzC,8BAA8B;IAC9B,WAAW;IACX,YAAY;IACZ,mBAAmB;IACnB,4BAA4B;IAC5B,iBAAiB;IACjB,gBAAgB;IAChB,eAAe;IACf,yBAAyB;IACzB,aAAa;IACb,mBAAmB;IACnB,uBAAuB;AAC3B;;AAEA;;IAEI,mBAAmB,EAAE,4BAA4B;IACjD,iBAAiB,EAAE,4BAA4B;IAC/C,4BAA4B;IAC5B,qBAAqB;AACzB;;AAEA;IACI,iBAAiB;IACjB,eAAe;AACnB;;AAEA;;IAEI,sBAAsB;AAC1B;;AAEA;IACI,8BAA8B;IAC9B,WAAW;IACX,kBAAkB;IAClB,qBAAqB;AACzB;;AAEA,6BAA6B;AAC7B;IACI,6CAA6C;IAC7C,mBAAmB;AACvB;;AAEA;IACI,4BAA4B;IAC5B,iBAAiB;IACjB,+BAA+B;IAC/B,mBAAmB;IACnB,sBAAsB;IACtB,yBAAyB;AAC7B;;AAEA;IACI,aAAa;IACb,YAAY;AAChB;;AAEA;IACI,8BAA8B;IAC9B,yCAAyC;IACzC,kBAAkB;IAClB,gBAAgB;IAChB,aAAa;IACb,8BAA8B;IAC9B,mBAAmB;IACnB,yBAAyB;AAC7B;;AAEA;IACI,sCAAsC;IACtC,mCAAmC;AACvC;;AAEA;IACI,eAAe;IACf,gCAAgC;IAChC,kBAAkB;AACtB;;AAEA;IACI,aAAa;IACb,WAAW;IACX,mBAAmB;AACvB;;AAEA;IACI,4BAA4B;IAC5B,iBAAiB;IACjB,gBAAgB;IAChB,8BAA8B;IAC9B,eAAe;IACf,kBAAkB;AACtB;;AAEA;IACI,4BAA4B;IAC5B,wCAAwC;AAC5C;;AAEA;IACI,iCAAiC;IACjC,yCAAyC;IACzC,8BAA8B;IAC9B,WAAW;IACX,YAAY;IACZ,kBAAkB;IAClB,iBAAiB;IACjB,eAAe;IACf,yBAAyB;IACzB,aAAa;IACb,mBAAmB;IACnB,uBAAuB;AAC3B;;AAEA;IACI,sCAAsC;IACtC,oCAAoC;IACpC,4BAA4B;AAChC;;AAEA;IACI,YAAY;IACZ,kBAAkB;IAClB,kBAAkB;AACtB;AACA;;IAEI,UAAU;AACd;AACA;;;;IAII,WAAW;AACf;AACA;;;;IAII,UAAU;AACd;AACA;;IAEI,UAAU;AACd;AACA;;IAEI,UAAU;AACd;;AAEA,mBAAmB;AACnB;IACI,eAAe;IACf,YAAY;IACZ,WAAW;IACX,mCAAmC;IACnC,wCAAwC;IACxC,kBAAkB;IAClB,uBAAuB;IACvB,4BAA4B;IAC5B,6BAA6B;IAC7B,iBAAiB;IACjB,UAAU;IACV,2BAA2B;IAC3B,yBAAyB;IACzB,oBAAoB;IACpB,aAAa;IACb,yCAAyC;AAC7C;;AAEA;IACI,UAAU;IACV,wBAAwB;AAC5B;;AAEA,gCAAgC;AAChC;IACI,qBAAqB;IACrB,wBAAwB;IACxB,mBAAmB;IACnB,4BAA4B;IAC5B,iBAAiB;IACjB,gBAAgB;IAChB,yBAAyB;IACzB,sBAAsB;AAC1B;;AAEA;IACI,sFAAsF;IACtF,YAAY;IACZ,cAAc;AAClB;;AAEA;IACI,oEAAoE;IACpE,YAAY;AAChB;;AAEA;IACI,oEAAoE;IACpE,YAAY;AAChB;;AAEA;IACI,oFAAoF;IACpF,4BAA4B;AAChC;;AAEA,iBAAiB;AACjB;IACI,wBAAwB;AAC5B;;AAEA,eAAe;AACf;IACI,WAAW,UAAU,EAAE;IACvB,MAAM,YAAY,EAAE;AACxB;;AAEA,eAAe;AACf;IACI;QACI,sBAAsB;QACtB,kBAAkB;IACtB;;IAEA;QACI,kBAAkB;IACtB;;IAEA;QACI,iBAAiB;IACrB;;IAEA;QACI,0BAA0B;IAC9B;;IAEA;QACI,eAAe;IACnB;;IAEA;;QAEI,WAAW;QACX,YAAY;QACZ,iBAAiB;IACrB;;IAEA;QACI,sBAAsB;QACtB,mBAAmB;IACvB;AACJ;AACA;IACI;QACI,cAAc;IAClB;AACJ,C","sources":["webpack://app/./static/css/sections/tcg.css","webpack://app/./static/css/pages/tcg/game.css"],"sourcesContent":["\n\n.container-input > input {\n padding: 0vh 1vh;\n border-radius: 0.5vh;\n max-width: 7vh;\n}\n\n\n/* Right column */\n.rightcolumn {\n min-width: fit-content;\n}\n\n/* Main Table */\n#pageBody {\n max-height: 82vh;\n padding: 0 5vw;\n margin: 0;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n position: absolute;\n width: 90vw;\n color: var(--colour-text);\n}\n\n\n/* Footer */\n.footer {\n padding: 1vh 1vw;\n text-align: center;\n margin: 0;\n max-height: 5vh;\n overflow-y: auto;\n background-color: var(--colour-accent);\n position: absolute;\n bottom: 0;\n width: 98vw;\n}\n\n@media screen and (max-width: 400px) {\n .footer {\n max-height: 8vh;\n padding: 0.75vh 2vw;\n font-size: 10px; \n width: 96vw;\n max-width: 96vw;\n }\n .footer > h4 {\n font-size: 10px;\n }\n .footer > h5 {\n font-size: 9px;\n }\n}\n\n.footer > h4, h5 {\n padding: 0;\n margin: 0;\n}","/* MTG Single Game Page Styles */\n\n#buttonHamburger {\n display: none;\n}\n\n/* Game Header */\n.game-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin: 1vh auto;\n flex-wrap: wrap;\n gap: 0;\n animation: tcg-fadeInDown 0.8s ease-out;\n}\n\n.header-left, .header-right {\n flex: 1;\n color: var(--tcg-text-secondary);\n font-size: 1rem;\n margin: 0 auto;\n}\n\n.header-left {\n padding-left: 15vw;\n width: 30vw;\n}\n\n.header-right {\n text-align: right;\n min-width: 15vw;\n width: 15vw;\n}\n\n.header-center {\n text-align: center;\n flex: 2;\n padding-left: 4vw;\n}\n\n.game-header .container.save.button-cancel {\n width: 15vw;\n max-width: 15vw;\n}\n\n.back-link {\n color: var(--tcg-text-secondary);\n text-decoration: none;\n font-family: 'Cinzel', serif;\n font-size: 1rem;\n transition: color 0.3s ease;\n}\n\n.back-link:hover {\n color: var(--tcg-accent-gold);\n}\n\n.game-title {\n font-family: 'Cinzel', serif;\n font-size: 2.5rem;\n font-weight: 700;\n background: linear-gradient(135deg, var(--tcg-accent-gold), var(--tcg-accent-purple));\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n margin-bottom: 0.5rem;\n letter-spacing: 0.05em;\n}\n\n.game-meta {\n display: flex;\n gap: 0;\n justify-content: center;\n align-items: center;\n flex-wrap: wrap;\n}\n\n.game-meta .location {\n color: var(--tcg-text-secondary);\n font-size: 1rem;\n width: 4vw;\n}\n\n/* Setup Section */\n.setup-section {\n max-width: 800px;\n margin: 0 auto 2rem;\n animation: tcg-fadeIn 0.8s ease-out 0.2s backwards;\n}\n\n.setup-controls {\n display: flex;\n gap: 2rem;\n justify-content: center;\n flex-wrap: wrap;\n margin-bottom: 2rem;\n}\n\n.control-group {\n display: flex;\n align-items: center;\n gap: 1rem;\n}\n\n.control-group .tcg-input {\n width: 80px;\n text-align: center;\n font-family: 'Cinzel', serif;\n font-size: 1.2rem;\n}\n\n.player-names-grid {\n display: flex;\n flex-wrap: wrap;\n gap: 1rem;\n max-width: 800px;\n margin: 0 auto 2rem;\n justify-content: center;\n}\n\n.player-name-input-wrapper {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n border: 1px solid gray;\n border-radius: 0.5vh;\n padding: 1vh;\n width: fit-content;\n}\n.player-name-input-wrapper.is_collapsed {\n display: none;\n}\n\n.player-name-heading-label,\n.player-name-label {\n font-size: 0.9rem;\n color: var(--tcg-text-secondary);\n letter-spacing: 0.05em;\n}\n.player-name-label {\n font-size: 0.8rem;\n}\n\n.setup-actions {\n text-align: center;\n}\n\n/* Game Section */\n#gameSection {\n margin: 0 auto;\n}\n#gameSection .row.round {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.9rem;\n color: var(--tcg-text-secondary);\n margin: 0 auto 0.5vh;\n width: fit-content;\n}\n#gameSection .row.round .row.round .round.display_order {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n background: var(--tcg-bg-card);\n border: 1px solid var(--tcg-border-color);\n border-radius: 6px;\n padding: 0.25rem 0.5rem;\n}\n/*\n#gameSection .row.round label {\n margin-left: 30vw;\n color: var(--tcg-text-secondary);\n font-size: 1rem;\n width: 4vw;\n}\n#gameSection .row.round input {\n width: 10vw;\n margin: 0 3vw 1vh;\n}\n*/\n#gameSection .row.round .row.round span.round.display_order {\n font-family: 'Cinzel', serif;\n font-weight: 600;\n color: var(--tcg-text-primary);\n min-width: 20px;\n justify-content: center;\n}\n#gameSection .row.round .row.round button.btn-round-display-order {\n background: transparent;\n border: none;\n color: var(--tcg-text-secondary);\n cursor: pointer;\n font-size: 1rem;\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n}\n#gameSection .row.round .row.round button.btn-round-display-order:hover {\n color: var(--tcg-accent-red);\n transform: scale(1.2);\n}\n\n/* Players Grid */\n.players-grid {\n display: flex; /* grid;\n grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));\n */\n gap: 2rem;\n margin-bottom: 2rem;\n max-width: 90vw;\n flex-wrap: wrap;\n margin: 0 auto;\n width: fit-content;\n\n}\n\n/* Player Card */\n.player-card {\n background: var(--tcg-bg-secondary);\n border: 2px solid var(--tcg-border-color);\n border-radius: 16px;\n padding: 1.5rem;\n position: relative;\n overflow: hidden;\n transition: all 0.4s ease;\n animation: tcg-scaleIn 0.5s ease-out backwards;\n width: fit-content;\n max-width: 38vw;\n min-width: 20vw;\n margin: 0 auto;\n}\n\n.player-card::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 4px;\n background: linear-gradient(90deg, var(--tcg-accent-purple), var(--tcg-accent-gold));\n}\n\n.player-card.eliminated {\n opacity: 0.5;\n filter: grayscale(0.8);\n}\n\n.player-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 1.5rem;\n flex-wrap: wrap;\n gap: 1rem;\n}\n\n.player-info {\n flex: 1;\n min-width: 150px;\n}\n\n.player-name {\n font-family: 'Cinzel', serif;\n font-size: 1.5rem;\n font-weight: 600;\n color: var(--tcg-accent-gold);\n letter-spacing: 0.05em;\n margin-bottom: 0.5rem;\n}\n\n.commander-deaths {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.9rem;\n color: var(--tcg-text-secondary);\n}\n\n.death-counter {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n background: var(--tcg-bg-card);\n border: 1px solid var(--tcg-border-color);\n border-radius: 6px;\n padding: 0.25rem 0.5rem;\n}\n\n.death-display {\n font-family: 'Cinzel', serif;\n font-weight: 600;\n color: var(--tcg-text-primary);\n min-width: 20px;\n text-align: center;\n}\n\n.death-btn {\n background: transparent;\n border: none;\n color: var(--tcg-text-secondary);\n cursor: pointer;\n font-size: 1rem;\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n}\n\n.death-btn:hover {\n color: var(--tcg-accent-red);\n transform: scale(1.2);\n}\n\n.eliminate-btn {\n background: var(--tcg-accent-red);\n color: white;\n border: none;\n padding: 0.5rem 1rem;\n border-radius: 6px;\n font-size: 0.9rem;\n cursor: pointer;\n font-family: 'Cinzel', serif;\n transition: all 0.3s ease;\n}\n\n.eliminate-btn:hover {\n background: #b91c1c;\n transform: scale(1.05);\n}\n\n/* Life Total */\n.life-total {\n text-align: center;\n margin-bottom: 2rem;\n}\n\n.life-display {\n font-family: 'Cinzel', serif;\n font-size: 4rem;\n font-weight: 700;\n color: var(--tcg-text-primary);\n margin-bottom: 1rem;\n text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);\n}\n\n.life-gain-controls,\n.life-loss-controls {\n display: flex;\n gap: 1rem;\n justify-content: center;\n margin-bottom: 1vh;\n}\n\n.life-gain-btn,\n.life-loss-btn {\n background: var(--tcg-bg-card);\n border: 2px solid var(--tcg-border-color);\n color: var(--tcg-text-primary);\n width: 60px;\n height: 60px;\n border-radius: 12px;\n font-family: 'Cinzel', serif;\n font-size: 1.8rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.life-gain-btn:hover,\n.life-loss-btn:hover {\n border-color: green; /*var(--tcg-accent-purple);*/\n background: green; /*var(--tcg-accent-purple);*/\n color: var(--tcg-bg-primary);\n transform: scale(1.1);\n}\n\n.life-loss-btn:hover {\n border-color: red;\n background: red;\n}\n\n.life-gain-btn:active,\n.life-loss-btn:active {\n transform: scale(0.95);\n}\n\n.life-total label {\n color: var(--tcg-text-primary);\n width: 100%;\n margin-bottom: 1vh;\n display: inline-block;\n}\n\n/* Commander Damage Section */\n.commander-damage-section {\n border-top: 1px solid var(--tcg-border-color);\n padding-top: 1.5rem;\n}\n\n.section-title {\n font-family: 'Cinzel', serif;\n font-size: 1.1rem;\n color: var(--tcg-accent-purple);\n margin-bottom: 1rem;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n}\n\n.damage-grid {\n display: grid;\n gap: 0.75rem;\n}\n\n.damage-row {\n background: var(--tcg-bg-card);\n border: 1px solid var(--tcg-border-color);\n border-radius: 8px;\n padding: 0.75rem;\n display: flex;\n justify-content: space-between;\n align-items: center;\n transition: all 0.3s ease;\n}\n\n.damage-row:hover {\n border-color: var(--tcg-accent-purple);\n background: rgba(139, 92, 246, 0.1);\n}\n\n.damage-source {\n font-size: 1rem;\n color: var(--tcg-text-secondary);\n padding-right: 1vh;\n}\n\n.damage-controls {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n}\n\n.damage-display {\n font-family: 'Cinzel', serif;\n font-size: 1.5rem;\n font-weight: 600;\n color: var(--tcg-text-primary);\n min-width: 40px;\n text-align: center;\n}\n\n.damage-display.lethal {\n color: var(--tcg-accent-red);\n animation: pulse 1s ease-in-out infinite;\n}\n\n.damage-btn {\n background: var(--tcg-bg-primary);\n border: 1px solid var(--tcg-border-color);\n color: var(--tcg-text-primary);\n width: 36px;\n height: 36px;\n border-radius: 6px;\n font-size: 1.2rem;\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.damage-btn:hover {\n border-color: var(--tcg-accent-purple);\n background: var(--tcg-accent-purple);\n color: var(--tcg-bg-primary);\n}\n\n.damage-log.container {\n color: white;\n margin: 2vh auto 0;\n text-align: center;\n}\n.damage-log.container table thead tr th.round_id,\n.damage-log.container table tbody tr td.round_id {\n width: 7vw;\n}\n.damage-log.container table thead tr th.player_id,\n.damage-log.container table tbody tr td.player_id,\n.damage-log.container table thead tr th.received_from_commander_player_id,\n.damage-log.container table tbody tr td.received_from_commander_player_id {\n width: 20vw;\n}\n.damage-log.container table thead tr th.life_gain,\n.damage-log.container table tbody tr td.life_gain,\n.damage-log.container table thead tr th.life_loss,\n.damage-log.container table tbody tr td.life_loss {\n width: 7vw;\n}\n.damage-log.container table thead tr th.commander-deaths,\n.damage-log.container table tbody tr td.commander-deaths {\n width: 7vw;\n}\n.damage-log.container table thead tr th.is_eliminated,\n.damage-log.container table tbody tr td.is_eliminated {\n width: 7vw;\n}\n\n/* Save Indicator */\n.save-indicator {\n position: fixed;\n bottom: 2rem;\n right: 2rem;\n background: var(--tcg-bg-secondary);\n border: 2px solid var(--tcg-accent-gold);\n border-radius: 8px;\n padding: 0.75rem 1.5rem;\n font-family: 'Cinzel', serif;\n color: var(--tcg-accent-gold);\n font-size: 0.9rem;\n opacity: 0;\n transform: translateY(20px);\n transition: all 0.3s ease;\n pointer-events: none;\n z-index: 1000;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);\n}\n\n.save-indicator.show {\n opacity: 1;\n transform: translateY(0);\n}\n\n/* Badges (same as games page) */\n.badge {\n display: inline-block;\n padding: 0.35rem 0.75rem;\n border-radius: 20px;\n font-family: 'Cinzel', serif;\n font-size: 0.8rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.badge-commander {\n background: linear-gradient(135deg, var(--tcg-accent-purple), rgba(139, 92, 246, 0.5));\n color: white;\n margin: 0 auto;\n}\n\n.badge-draft {\n background: linear-gradient(135deg, #2563eb, rgba(37, 99, 235, 0.5));\n color: white;\n}\n\n.badge-sealed {\n background: linear-gradient(135deg, #059669, rgba(5, 150, 105, 0.5));\n color: white;\n}\n\n.badge-standard {\n background: linear-gradient(135deg, var(--tcg-accent-gold), rgba(212, 175, 55, 0.5));\n color: var(--tcg-bg-primary);\n}\n\n/* Hidden Class */\n.hidden {\n display: none !important;\n}\n\n/* Animations */\n@keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.6; }\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .game-header {\n flex-direction: column;\n text-align: center;\n }\n\n .header-left, .header-right {\n text-align: center;\n }\n\n .game-title {\n font-size: 1.8rem;\n }\n\n .players-grid {\n grid-template-columns: 1fr;\n }\n\n .life-display {\n font-size: 3rem;\n }\n\n .life-gain-btn,\n .life-loss-btn {\n width: 50px;\n height: 50px;\n font-size: 1.5rem;\n }\n\n .setup-controls {\n flex-direction: column;\n align-items: center;\n }\n}\n@media (max-width: 1260px) {\n #buttonHamburger {\n display: block;\n }\n}"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/static/dist/css/tcg_games.bundle.css b/static/dist/css/tcg_games.bundle.css index 859d1a9..181eec4 100644 --- a/static/dist/css/tcg_games.bundle.css +++ b/static/dist/css/tcg_games.bundle.css @@ -14,7 +14,7 @@ /* Main Table */ #pageBody { - max-height: 77vh; + max-height: 82vh; padding: 0 5vw; margin: 0; border: 0; @@ -99,15 +99,18 @@ position: relative; animation: tcg-fadeIn 0.8s ease-out 0.2s backwards; margin: 2vh auto; + display: flex; + flex-wrap: wrap; } .section-header { display: flex; justify-content: space-between; align-items: center; - margin-bottom: 2rem; + margin-bottom: 1rem; flex-wrap: wrap; gap: 1rem; + width: 100%; } /* Filters Form */ @@ -154,8 +157,7 @@ overflow-x: auto; } -.games-table { - width: 100%; +#tableMain.games-table { border-collapse: collapse; font-size: 1rem; } @@ -164,7 +166,6 @@ background: var(--tcg-bg-card); border-bottom: 2px solid var(--tcg-accent-purple); } - .games-table th { font-family: 'Cinzel', serif; font-size: 0.95rem; @@ -173,18 +174,22 @@ text-transform: uppercase; letter-spacing: 0.05em; padding: 1rem; - text-align: left; +} +.games-table thead tr { + height: 4vh; } +#tableMain.games-table tbody { + max-height: 59vh; +} .games-table tbody tr { border-bottom: 1px solid var(--tcg-border-color); transition: all 0.3s ease; + height: 4vh; } - .games-table tbody tr:hover { background: rgba(139, 92, 246, 0.1); } - .games-table tbody tr.inactive { opacity: 0.5; } @@ -198,7 +203,38 @@ color: white; } -.game-id { +.games-table thead tr th.game_id, +.games-table tbody tr td.game_id { + min-width: 10vh; + max-width: 10vh; +} +.games-table thead tr th.is_commander, +.games-table tbody tr td.is_commander { + min-width: 12vh; + max-width: 12vh; +} +.games-table thead tr th.location_name, +.games-table tbody tr td.location_name { + min-width: 20vh; + max-width: 20vh; +} +.games-table thead tr th.start_on, +.games-table tbody tr td.start_on { + min-width: 14vh; + max-width: 14vh; +} +#tableMain.games-table thead tr th.active, +#tableMain.games-table tbody tr td.active { + min-width: 8vh; + max-width: 8vh; +} +.games-table thead tr th.navMtgGame, +.games-table tbody tr td.navMtgGame { + min-width: 13vh; + max-width: 13vh; +} + +.game_id { font-family: 'Cinzel', serif; font-weight: 600; color: var(--tcg-text-secondary); @@ -289,7 +325,7 @@ /* Join Button */ .btn-join { - padding: 0.5rem 1.25rem; + padding: 0.5vh 1vw; font-size: 0.9rem; } @@ -331,7 +367,7 @@ animation: tcg-fadeIn 0.3s ease-out; } -.modal-overlay.hidden { +.modal-overlay.is_collapsed { display: none; } @@ -404,7 +440,6 @@ } .section-header { - flex-direction: column; align-items: stretch; } diff --git a/static/dist/css/tcg_games.bundle.css.map b/static/dist/css/tcg_games.bundle.css.map index 2e3ba0a..e7773e2 100644 --- a/static/dist/css/tcg_games.bundle.css.map +++ b/static/dist/css/tcg_games.bundle.css.map @@ -1 +1 @@ -{"version":3,"file":"css/tcg_games.bundle.css","mappings":";;AAEA;IACI,gBAAgB;IAChB,oBAAoB;IACpB,cAAc;AAClB;;;AAGA,iBAAiB;AACjB;IACI,sBAAsB;AAC1B;;AAEA,eAAe;AACf;IACI,gBAAgB;IAChB,cAAc;IACd,SAAS;IACT,SAAS;IACT,qBAAqB;IACrB,2BAA2B;IAC3B,aAAa;IACb,sBAAsB;IACtB,uBAAuB;IACvB,gBAAgB;IAChB,kBAAkB;IAClB,kBAAkB;IAClB,WAAW;IACX,yBAAyB;AAC7B;;;AAGA,WAAW;AACX;IACI,gBAAgB;IAChB,kBAAkB;IAClB,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,sCAAsC;IACtC,kBAAkB;IAClB,SAAS;IACT,WAAW;AACf;;AAEA;IACI;QACI,eAAe;QACf,mBAAmB;QACnB,eAAe;QACf,WAAW;QACX,eAAe;IACnB;IACA;QACI,eAAe;IACnB;IACA;QACI,cAAc;IAClB;AACJ;;AAEA;IACI,UAAU;IACV,SAAS;AACb,C;ACjEA,0BAA0B;;AAE1B,gBAAgB;AAChB;IACI,kBAAkB;IAClB,mBAAmB;IACnB,uCAAuC;IACvC,cAAc;AAClB;;AAEA;IACI,4BAA4B;IAC5B,eAAe;IACf,gBAAgB;IAChB,qFAAqF;IACrF,6BAA6B;IAC7B,oCAAoC;IACpC,qBAAqB;IACrB,qBAAqB;IACrB,sBAAsB;IACtB,yBAAyB;AAC7B;;AAEA;IACI,iBAAiB;IACjB,gCAAgC;IAChC,sBAAsB;IACtB,yBAAyB;AAC7B;;AAEA,kBAAkB;AAClB;IACI,kBAAkB;IAClB,kDAAkD;IAClD,gBAAgB;AACpB;;AAEA;IACI,aAAa;IACb,8BAA8B;IAC9B,mBAAmB;IACnB,mBAAmB;IACnB,eAAe;IACf,SAAS;AACb;;AAEA,iBAAiB;AACjB;IACI,mBAAmB;IACnB,eAAe;IACf,8BAA8B;IAC9B,yCAAyC;IACzC,mBAAmB;AACvB;;AAEA;IACI,aAAa;IACb,WAAW;IACX,qBAAqB;IACrB,eAAe;AACnB;;AAEA;IACI,aAAa;IACb,sBAAsB;IACtB,WAAW;IACX,gBAAgB;AACpB;;AAEA;IACI,mBAAmB;IACnB,mBAAmB;IACnB,YAAY;AAChB;;AAEA;IACI,WAAW;IACX,YAAY;IACZ,sCAAsC;AAC1C;;AAEA;IACI,gBAAgB;AACpB;;AAEA,gBAAgB;AAChB;IACI,gBAAgB;AACpB;;AAEA;IACI,WAAW;IACX,yBAAyB;IACzB,eAAe;AACnB;;AAEA;IACI,8BAA8B;IAC9B,iDAAiD;AACrD;;AAEA;IACI,4BAA4B;IAC5B,kBAAkB;IAClB,gBAAgB;IAChB,6BAA6B;IAC7B,yBAAyB;IACzB,sBAAsB;IACtB,aAAa;IACb,gBAAgB;AACpB;;AAEA;IACI,gDAAgD;IAChD,yBAAyB;AAC7B;;AAEA;IACI,mCAAmC;AACvC;;AAEA;IACI,YAAY;AAChB;;AAEA;IACI,aAAa;IACb,sBAAsB;AAC1B;AACA;;IAEI,YAAY;AAChB;;AAEA;IACI,4BAA4B;IAC5B,gBAAgB;IAChB,gCAAgC;AACpC;;AAEA,WAAW;AACX;IACI,qBAAqB;IACrB,wBAAwB;IACxB,mBAAmB;IACnB,4BAA4B;IAC5B,iBAAiB;IACjB,gBAAgB;IAChB,yBAAyB;IACzB,sBAAsB;AAC1B;;AAEA;IACI,sFAAsF;IACtF,YAAY;AAChB;;AAEA;IACI,oEAAoE;IACpE,YAAY;AAChB;;AAEA;IACI,oEAAoE;IACpE,YAAY;AAChB;;AAEA;IACI,oFAAoF;IACpF,4BAA4B;AAChC;;AAEA,sBAAsB;AACtB;IACI,oBAAoB;IACpB,mBAAmB;IACnB,WAAW;IACX,wBAAwB;IACxB,mBAAmB;IACnB,kBAAkB;IAClB,gBAAgB;AACpB;;AAEA;IACI,WAAW;IACX,UAAU;IACV,WAAW;IACX,kBAAkB;AACtB;;AAEA;IACI,kCAAkC;IAClC,cAAc;AAClB;;AAEA;IACI,mBAAmB;IACnB,+CAA+C;AACnD;;AAEA;IACI,oCAAoC;IACpC,cAAc;AAClB;;AAEA;IACI,mBAAmB;AACvB;;AAEA;IACI,kCAAkC;IAClC,cAAc;AAClB;;AAEA;IACI,mBAAmB;AACvB;;AAEA;IACI,WAAW,UAAU,EAAE;IACvB,MAAM,YAAY,EAAE;AACxB;;AAEA,gBAAgB;AAChB;IACI,uBAAuB;IACvB,iBAAiB;AACrB;;AAEA,qBAAqB;AACrB;IACI,kBAAkB;IAClB,wBAAwB;AAC5B;;AAEA;IACI,aAAa;IACb,sBAAsB;IACtB,mBAAmB;IACnB,SAAS;AACb;;AAEA;IACI,eAAe;IACf,YAAY;AAChB;;AAEA;IACI,gCAAgC;IAChC,iBAAiB;AACrB;;AAEA,UAAU;AACV;IACI,eAAe;IACf,MAAM;IACN,OAAO;IACP,QAAQ;IACR,SAAS;IACT,8BAA8B;IAC9B,aAAa;IACb,mBAAmB;IACnB,uBAAuB;IACvB,aAAa;IACb,mCAAmC;AACvC;;AAEA;IACI,aAAa;AACjB;;AAEA;IACI,UAAU;IACV,gBAAgB;IAChB,gBAAgB;IAChB,gBAAgB;IAChB,oCAAoC;AACxC;;AAEA;IACI,aAAa;IACb,8BAA8B;IAC9B,mBAAmB;IACnB,qBAAqB;AACzB;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,gBAAgB;IAChB,YAAY;IACZ,gCAAgC;IAChC,eAAe;IACf,eAAe;IACf,2BAA2B;IAC3B,cAAc;AAClB;;AAEA;IACI,4BAA4B;AAChC;;AAEA,kBAAkB;AAClB;IACI,aAAa;IACb,sBAAsB;IACtB,YAAY;AAChB;;AAEA;IACI,aAAa;IACb,sBAAsB;IACtB,WAAW;AACf;;AAEA;IACI,gBAAgB;IAChB,gBAAgB;AACpB;;AAEA;IACI,eAAe;AACnB;;AAEA;IACI,aAAa;IACb,SAAS;IACT,yBAAyB;IACzB,gBAAgB;AACpB;;AAEA,eAAe;AACf;IACI;QACI,eAAe;IACnB;;IAEA;QACI,sBAAsB;QACtB,oBAAoB;IACxB;;IAEA;QACI,sBAAsB;IAC1B;;IAEA;QACI,WAAW;IACf;;IAEA;;QAEI,uBAAuB;QACvB,iBAAiB;IACrB;;IAEA;QACI,uBAAuB;QACvB,iBAAiB;IACrB;;IAEA;QACI,UAAU;QACV,eAAe;IACnB;AACJ","sources":["webpack://app/./static/css/sections/tcg.css","webpack://app/./static/css/pages/tcg/games.css"],"sourcesContent":["\n\n.container-input > input {\n padding: 0vh 1vh;\n border-radius: 0.5vh;\n max-width: 7vh;\n}\n\n\n/* Right column */\n.rightcolumn {\n min-width: fit-content;\n}\n\n/* Main Table */\n#pageBody {\n max-height: 77vh;\n padding: 0 5vw;\n margin: 0;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n position: absolute;\n width: 90vw;\n color: var(--colour-text);\n}\n\n\n/* Footer */\n.footer {\n padding: 1vh 1vw;\n text-align: center;\n margin: 0;\n max-height: 5vh;\n overflow-y: auto;\n background-color: var(--colour-accent);\n position: absolute;\n bottom: 0;\n width: 98vw;\n}\n\n@media screen and (max-width: 400px) {\n .footer {\n max-height: 8vh;\n padding: 0.75vh 2vw;\n font-size: 10px; \n width: 96vw;\n max-width: 96vw;\n }\n .footer > h4 {\n font-size: 10px;\n }\n .footer > h5 {\n font-size: 9px;\n }\n}\n\n.footer > h4, h5 {\n padding: 0;\n margin: 0;\n}","/* MTG Games Page Styles */\n\n/* Page Header */\n.page-header {\n text-align: center;\n margin-bottom: 3rem;\n animation: tcg-fadeInDown 0.8s ease-out;\n margin: 0 auto;\n}\n\n.page-title {\n font-family: 'Cinzel', serif;\n font-size: 3rem;\n font-weight: 700;\n background: linear-gradient(135deg, var(--tcg-accent-gold), var(--tcg-accent-purple));\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n margin-bottom: 0.5rem;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n}\n\n.page-subtitle {\n font-size: 1.2rem;\n color: var(--tcg-text-secondary);\n letter-spacing: 0.15em;\n text-transform: uppercase;\n}\n\n/* Games Section */\n.games-section {\n position: relative;\n animation: tcg-fadeIn 0.8s ease-out 0.2s backwards;\n margin: 2vh auto;\n}\n\n.section-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 2rem;\n flex-wrap: wrap;\n gap: 1rem;\n}\n\n/* Filters Form */\n.filters-form {\n margin-bottom: 2rem;\n padding: 1.5rem;\n background: var(--tcg-bg-card);\n border: 1px solid var(--tcg-border-color);\n border-radius: 12px;\n}\n\n.filters-row {\n display: flex;\n gap: 1.5rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n min-width: 150px;\n}\n\n.filter-group.checkbox-group {\n flex-direction: row;\n align-items: center;\n gap: 0.75rem;\n}\n\n.filter-group.checkbox-group input[type=\"checkbox\"] {\n width: 20px;\n height: 20px;\n accent-color: var(--tcg-accent-purple);\n}\n\n.filter-group.checkbox-group .tcg-label {\n margin-bottom: 0;\n}\n\n/* Games Table */\n.games-table-container {\n overflow-x: auto;\n}\n\n.games-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 1rem;\n}\n\n.games-table thead {\n background: var(--tcg-bg-card);\n border-bottom: 2px solid var(--tcg-accent-purple);\n}\n\n.games-table th {\n font-family: 'Cinzel', serif;\n font-size: 0.95rem;\n font-weight: 600;\n color: var(--tcg-accent-gold);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n padding: 1rem;\n text-align: left;\n}\n\n.games-table tbody tr {\n border-bottom: 1px solid var(--tcg-border-color);\n transition: all 0.3s ease;\n}\n\n.games-table tbody tr:hover {\n background: rgba(139, 92, 246, 0.1);\n}\n\n.games-table tbody tr.inactive {\n opacity: 0.5;\n}\n\n.games-table td {\n padding: 1rem;\n vertical-align: middle;\n}\n.games-table tbody td.game-location,\n.games-table tbody td.game-date {\n color: white;\n}\n\n.game-id {\n font-family: 'Cinzel', serif;\n font-weight: 600;\n color: var(--tcg-text-secondary);\n}\n\n/* Badges */\n.badge {\n display: inline-block;\n padding: 0.35rem 0.75rem;\n border-radius: 20px;\n font-family: 'Cinzel', serif;\n font-size: 0.8rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.badge-commander {\n background: linear-gradient(135deg, var(--tcg-accent-purple), rgba(139, 92, 246, 0.5));\n color: white;\n}\n\n.badge-draft {\n background: linear-gradient(135deg, #2563eb, rgba(37, 99, 235, 0.5));\n color: white;\n}\n\n.badge-sealed {\n background: linear-gradient(135deg, #059669, rgba(5, 150, 105, 0.5));\n color: white;\n}\n\n.badge-standard {\n background: linear-gradient(135deg, var(--tcg-accent-gold), rgba(212, 175, 55, 0.5));\n color: var(--tcg-bg-primary);\n}\n\n/* Status Indicators */\n.status {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.35rem 0.75rem;\n border-radius: 20px;\n font-size: 0.85rem;\n font-weight: 500;\n}\n\n.status::before {\n content: '';\n width: 8px;\n height: 8px;\n border-radius: 50%;\n}\n\n.status-active {\n background: rgba(34, 197, 94, 0.2);\n color: #22c55e;\n}\n\n.status-active::before {\n background: #22c55e;\n animation: pulse-status 2s ease-in-out infinite;\n}\n\n.status-ended {\n background: rgba(107, 114, 128, 0.2);\n color: #9ca3af;\n}\n\n.status-ended::before {\n background: #9ca3af;\n}\n\n.status-inactive {\n background: rgba(220, 38, 38, 0.2);\n color: #dc2626;\n}\n\n.status-inactive::before {\n background: #dc2626;\n}\n\n@keyframes pulse-status {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n}\n\n/* Join Button */\n.btn-join {\n padding: 0.5rem 1.25rem;\n font-size: 0.9rem;\n}\n\n/* No Games Message */\n.no-games {\n text-align: center;\n padding: 3rem !important;\n}\n\n.no-games-message {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.no-games-icon {\n font-size: 3rem;\n opacity: 0.5;\n}\n\n.no-games-message p {\n color: var(--tcg-text-secondary);\n font-size: 1.1rem;\n}\n\n/* Modal */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.8);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: tcg-fadeIn 0.3s ease-out;\n}\n\n.modal-overlay.hidden {\n display: none;\n}\n\n.modal-content {\n width: 90%;\n max-width: 500px;\n max-height: 90vh;\n overflow-y: auto;\n animation: tcg-scaleIn 0.3s ease-out;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 1.5rem;\n}\n\n.modal-header .tcg-section-title {\n margin-bottom: 0;\n}\n\n.modal-close {\n background: none;\n border: none;\n color: var(--tcg-text-secondary);\n font-size: 2rem;\n cursor: pointer;\n transition: color 0.3s ease;\n line-height: 1;\n}\n\n.modal-close:hover {\n color: var(--tcg-accent-red);\n}\n\n/* New Game Form */\n.new-game-form {\n display: flex;\n flex-direction: column;\n gap: 1.25rem;\n}\n\n.form-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.form-group textarea.tcg-input {\n resize: vertical;\n min-height: 80px;\n}\n\n.form-group select.tcg-input {\n cursor: pointer;\n}\n\n.form-actions {\n display: flex;\n gap: 1rem;\n justify-content: flex-end;\n margin-top: 1rem;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .page-title {\n font-size: 2rem;\n }\n\n .section-header {\n flex-direction: column;\n align-items: stretch;\n }\n\n .filters-row {\n flex-direction: column;\n }\n\n .filter-group {\n width: 100%;\n }\n\n .games-table th,\n .games-table td {\n padding: 0.75rem 0.5rem;\n font-size: 0.9rem;\n }\n\n .btn-join {\n padding: 0.4rem 0.75rem;\n font-size: 0.8rem;\n }\n\n .modal-content {\n width: 95%;\n padding: 1.5rem;\n }\n}\n"],"names":[],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"css/tcg_games.bundle.css","mappings":"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","sources":["webpack://app/./static/css/sections/tcg.css","webpack://app/./static/css/pages/tcg/games.css"],"sourcesContent":["\n\n.container-input > input {\n padding: 0vh 1vh;\n border-radius: 0.5vh;\n max-width: 7vh;\n}\n\n\n/* Right column */\n.rightcolumn {\n min-width: fit-content;\n}\n\n/* Main Table */\n#pageBody {\n max-height: 82vh;\n padding: 0 5vw;\n margin: 0;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n position: absolute;\n width: 90vw;\n color: var(--colour-text);\n}\n\n\n/* Footer */\n.footer {\n padding: 1vh 1vw;\n text-align: center;\n margin: 0;\n max-height: 5vh;\n overflow-y: auto;\n background-color: var(--colour-accent);\n position: absolute;\n bottom: 0;\n width: 98vw;\n}\n\n@media screen and (max-width: 400px) {\n .footer {\n max-height: 8vh;\n padding: 0.75vh 2vw;\n font-size: 10px; \n width: 96vw;\n max-width: 96vw;\n }\n .footer > h4 {\n font-size: 10px;\n }\n .footer > h5 {\n font-size: 9px;\n }\n}\n\n.footer > h4, h5 {\n padding: 0;\n margin: 0;\n}","/* MTG Games Page Styles */\n\n/* Page Header */\n.page-header {\n text-align: center;\n margin-bottom: 3rem;\n animation: tcg-fadeInDown 0.8s ease-out;\n margin: 0 auto;\n}\n\n.page-title {\n font-family: 'Cinzel', serif;\n font-size: 3rem;\n font-weight: 700;\n background: linear-gradient(135deg, var(--tcg-accent-gold), var(--tcg-accent-purple));\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n margin-bottom: 0.5rem;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n}\n\n.page-subtitle {\n font-size: 1.2rem;\n color: var(--tcg-text-secondary);\n letter-spacing: 0.15em;\n text-transform: uppercase;\n}\n\n/* Games Section */\n.games-section {\n position: relative;\n animation: tcg-fadeIn 0.8s ease-out 0.2s backwards;\n margin: 2vh auto;\n display: flex;\n flex-wrap: wrap;\n}\n\n.section-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 1rem;\n flex-wrap: wrap;\n gap: 1rem;\n width: 100%;\n}\n\n/* Filters Form */\n.filters-form {\n margin-bottom: 2rem;\n padding: 1.5rem;\n background: var(--tcg-bg-card);\n border: 1px solid var(--tcg-border-color);\n border-radius: 12px;\n}\n\n.filters-row {\n display: flex;\n gap: 1.5rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n min-width: 150px;\n}\n\n.filter-group.checkbox-group {\n flex-direction: row;\n align-items: center;\n gap: 0.75rem;\n}\n\n.filter-group.checkbox-group input[type=\"checkbox\"] {\n width: 20px;\n height: 20px;\n accent-color: var(--tcg-accent-purple);\n}\n\n.filter-group.checkbox-group .tcg-label {\n margin-bottom: 0;\n}\n\n/* Games Table */\n.games-table-container {\n overflow-x: auto;\n}\n\n#tableMain.games-table {\n border-collapse: collapse;\n font-size: 1rem;\n}\n\n.games-table thead {\n background: var(--tcg-bg-card);\n border-bottom: 2px solid var(--tcg-accent-purple);\n}\n.games-table th {\n font-family: 'Cinzel', serif;\n font-size: 0.95rem;\n font-weight: 600;\n color: var(--tcg-accent-gold);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n padding: 1rem;\n}\n.games-table thead tr {\n height: 4vh;\n}\n\n#tableMain.games-table tbody {\n max-height: 59vh;\n}\n.games-table tbody tr {\n border-bottom: 1px solid var(--tcg-border-color);\n transition: all 0.3s ease;\n height: 4vh;\n}\n.games-table tbody tr:hover {\n background: rgba(139, 92, 246, 0.1);\n}\n.games-table tbody tr.inactive {\n opacity: 0.5;\n}\n\n.games-table td {\n padding: 1rem;\n vertical-align: middle;\n}\n.games-table tbody td.game-location,\n.games-table tbody td.game-date {\n color: white;\n}\n\n.games-table thead tr th.game_id,\n.games-table tbody tr td.game_id {\n min-width: 10vh;\n max-width: 10vh;\n}\n.games-table thead tr th.is_commander,\n.games-table tbody tr td.is_commander {\n min-width: 12vh;\n max-width: 12vh;\n}\n.games-table thead tr th.location_name,\n.games-table tbody tr td.location_name {\n min-width: 20vh;\n max-width: 20vh;\n}\n.games-table thead tr th.start_on,\n.games-table tbody tr td.start_on {\n min-width: 14vh;\n max-width: 14vh;\n}\n#tableMain.games-table thead tr th.active,\n#tableMain.games-table tbody tr td.active {\n min-width: 8vh;\n max-width: 8vh;\n}\n.games-table thead tr th.navMtgGame,\n.games-table tbody tr td.navMtgGame {\n min-width: 13vh;\n max-width: 13vh;\n}\n\n.game_id {\n font-family: 'Cinzel', serif;\n font-weight: 600;\n color: var(--tcg-text-secondary);\n}\n\n/* Badges */\n.badge {\n display: inline-block;\n padding: 0.35rem 0.75rem;\n border-radius: 20px;\n font-family: 'Cinzel', serif;\n font-size: 0.8rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.badge-commander {\n background: linear-gradient(135deg, var(--tcg-accent-purple), rgba(139, 92, 246, 0.5));\n color: white;\n}\n\n.badge-draft {\n background: linear-gradient(135deg, #2563eb, rgba(37, 99, 235, 0.5));\n color: white;\n}\n\n.badge-sealed {\n background: linear-gradient(135deg, #059669, rgba(5, 150, 105, 0.5));\n color: white;\n}\n\n.badge-standard {\n background: linear-gradient(135deg, var(--tcg-accent-gold), rgba(212, 175, 55, 0.5));\n color: var(--tcg-bg-primary);\n}\n\n/* Status Indicators */\n.status {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.35rem 0.75rem;\n border-radius: 20px;\n font-size: 0.85rem;\n font-weight: 500;\n}\n\n.status::before {\n content: '';\n width: 8px;\n height: 8px;\n border-radius: 50%;\n}\n\n.status-active {\n background: rgba(34, 197, 94, 0.2);\n color: #22c55e;\n}\n\n.status-active::before {\n background: #22c55e;\n animation: pulse-status 2s ease-in-out infinite;\n}\n\n.status-ended {\n background: rgba(107, 114, 128, 0.2);\n color: #9ca3af;\n}\n\n.status-ended::before {\n background: #9ca3af;\n}\n\n.status-inactive {\n background: rgba(220, 38, 38, 0.2);\n color: #dc2626;\n}\n\n.status-inactive::before {\n background: #dc2626;\n}\n\n@keyframes pulse-status {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n}\n\n/* Join Button */\n.btn-join {\n padding: 0.5vh 1vw;\n font-size: 0.9rem;\n}\n\n/* No Games Message */\n.no-games {\n text-align: center;\n padding: 3rem !important;\n}\n\n.no-games-message {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.no-games-icon {\n font-size: 3rem;\n opacity: 0.5;\n}\n\n.no-games-message p {\n color: var(--tcg-text-secondary);\n font-size: 1.1rem;\n}\n\n/* Modal */\n.modal-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.8);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: tcg-fadeIn 0.3s ease-out;\n}\n\n.modal-overlay.is_collapsed {\n display: none;\n}\n\n.modal-content {\n width: 90%;\n max-width: 500px;\n max-height: 90vh;\n overflow-y: auto;\n animation: tcg-scaleIn 0.3s ease-out;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 1.5rem;\n}\n\n.modal-header .tcg-section-title {\n margin-bottom: 0;\n}\n\n.modal-close {\n background: none;\n border: none;\n color: var(--tcg-text-secondary);\n font-size: 2rem;\n cursor: pointer;\n transition: color 0.3s ease;\n line-height: 1;\n}\n\n.modal-close:hover {\n color: var(--tcg-accent-red);\n}\n\n/* New Game Form */\n.new-game-form {\n display: flex;\n flex-direction: column;\n gap: 1.25rem;\n}\n\n.form-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.form-group textarea.tcg-input {\n resize: vertical;\n min-height: 80px;\n}\n\n.form-group select.tcg-input {\n cursor: pointer;\n}\n\n.form-actions {\n display: flex;\n gap: 1rem;\n justify-content: flex-end;\n margin-top: 1rem;\n}\n\n/* Responsive */\n@media (max-width: 768px) {\n .page-title {\n font-size: 2rem;\n }\n\n .section-header {\n align-items: stretch;\n }\n\n .filters-row {\n flex-direction: column;\n }\n\n .filter-group {\n width: 100%;\n }\n\n .games-table th,\n .games-table td {\n padding: 0.75rem 0.5rem;\n font-size: 0.9rem;\n }\n\n .btn-join {\n padding: 0.4rem 0.75rem;\n font-size: 0.8rem;\n }\n\n .modal-content {\n width: 95%;\n padding: 1.5rem;\n }\n}\n"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/static/dist/css/tcg_home.bundle.css b/static/dist/css/tcg_home.bundle.css index b068109..1885227 100644 --- a/static/dist/css/tcg_home.bundle.css +++ b/static/dist/css/tcg_home.bundle.css @@ -14,7 +14,7 @@ /* Main Table */ #pageBody { - max-height: 77vh; + max-height: 82vh; padding: 0 5vw; margin: 0; border: 0; diff --git a/static/dist/css/tcg_home.bundle.css.map b/static/dist/css/tcg_home.bundle.css.map index 9e37cff..5fbef78 100644 --- a/static/dist/css/tcg_home.bundle.css.map +++ b/static/dist/css/tcg_home.bundle.css.map @@ -1 +1 @@ -{"version":3,"file":"css/tcg_home.bundle.css","mappings":";;AAEA;IACI,gBAAgB;IAChB,oBAAoB;IACpB,cAAc;AAClB;;;AAGA,iBAAiB;AACjB;IACI,sBAAsB;AAC1B;;AAEA,eAAe;AACf;IACI,gBAAgB;IAChB,cAAc;IACd,SAAS;IACT,SAAS;IACT,qBAAqB;IACrB,2BAA2B;IAC3B,aAAa;IACb,sBAAsB;IACtB,uBAAuB;IACvB,gBAAgB;IAChB,kBAAkB;IAClB,kBAAkB;IAClB,WAAW;IACX,yBAAyB;AAC7B;;;AAGA,WAAW;AACX;IACI,gBAAgB;IAChB,kBAAkB;IAClB,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,sCAAsC;IACtC,kBAAkB;IAClB,SAAS;IACT,WAAW;AACf;;AAEA;IACI;QACI,eAAe;QACf,mBAAmB;QACnB,eAAe;QACf,WAAW;QACX,eAAe;IACnB;IACA;QACI,eAAe;IACnB;IACA;QACI,cAAc;IAClB;AACJ;;AAEA;IACI,UAAU;IACV,SAAS;AACb,C;ACjEA;IACI,iBAAiB;AACrB;AACA;IACI,iBAAiB;IACjB,kBAAkB;AACtB,C","sources":["webpack://app/./static/css/sections/tcg.css","webpack://app/./static/css/pages/tcg/home.css"],"sourcesContent":["\n\n.container-input > input {\n padding: 0vh 1vh;\n border-radius: 0.5vh;\n max-width: 7vh;\n}\n\n\n/* Right column */\n.rightcolumn {\n min-width: fit-content;\n}\n\n/* Main Table */\n#pageBody {\n max-height: 77vh;\n padding: 0 5vw;\n margin: 0;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n position: absolute;\n width: 90vw;\n color: var(--colour-text);\n}\n\n\n/* Footer */\n.footer {\n padding: 1vh 1vw;\n text-align: center;\n margin: 0;\n max-height: 5vh;\n overflow-y: auto;\n background-color: var(--colour-accent);\n position: absolute;\n bottom: 0;\n width: 98vw;\n}\n\n@media screen and (max-width: 400px) {\n .footer {\n max-height: 8vh;\n padding: 0.75vh 2vw;\n font-size: 10px; \n width: 96vw;\n max-width: 96vw;\n }\n .footer > h4 {\n font-size: 10px;\n }\n .footer > h5 {\n font-size: 9px;\n }\n}\n\n.footer > h4, h5 {\n padding: 0;\n margin: 0;\n}","#pageBody .column .row {\n margin-top: 0.5vh;\n}\n#pageBody .column .row .button {\n margin-left: auto;\n margin-right: auto;\n}"],"names":[],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"css/tcg_home.bundle.css","mappings":";;AAEA;IACI,gBAAgB;IAChB,oBAAoB;IACpB,cAAc;AAClB;;;AAGA,iBAAiB;AACjB;IACI,sBAAsB;AAC1B;;AAEA,eAAe;AACf;IACI,gBAAgB;IAChB,cAAc;IACd,SAAS;IACT,SAAS;IACT,qBAAqB;IACrB,2BAA2B;IAC3B,aAAa;IACb,sBAAsB;IACtB,uBAAuB;IACvB,gBAAgB;IAChB,kBAAkB;IAClB,kBAAkB;IAClB,WAAW;IACX,yBAAyB;AAC7B;;;AAGA,WAAW;AACX;IACI,gBAAgB;IAChB,kBAAkB;IAClB,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,sCAAsC;IACtC,kBAAkB;IAClB,SAAS;IACT,WAAW;AACf;;AAEA;IACI;QACI,eAAe;QACf,mBAAmB;QACnB,eAAe;QACf,WAAW;QACX,eAAe;IACnB;IACA;QACI,eAAe;IACnB;IACA;QACI,cAAc;IAClB;AACJ;;AAEA;IACI,UAAU;IACV,SAAS;AACb,C;ACjEA;IACI,iBAAiB;AACrB;AACA;IACI,iBAAiB;IACjB,kBAAkB;AACtB,C","sources":["webpack://app/./static/css/sections/tcg.css","webpack://app/./static/css/pages/tcg/home.css"],"sourcesContent":["\n\n.container-input > input {\n padding: 0vh 1vh;\n border-radius: 0.5vh;\n max-width: 7vh;\n}\n\n\n/* Right column */\n.rightcolumn {\n min-width: fit-content;\n}\n\n/* Main Table */\n#pageBody {\n max-height: 82vh;\n padding: 0 5vw;\n margin: 0;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n position: absolute;\n width: 90vw;\n color: var(--colour-text);\n}\n\n\n/* Footer */\n.footer {\n padding: 1vh 1vw;\n text-align: center;\n margin: 0;\n max-height: 5vh;\n overflow-y: auto;\n background-color: var(--colour-accent);\n position: absolute;\n bottom: 0;\n width: 98vw;\n}\n\n@media screen and (max-width: 400px) {\n .footer {\n max-height: 8vh;\n padding: 0.75vh 2vw;\n font-size: 10px; \n width: 96vw;\n max-width: 96vw;\n }\n .footer > h4 {\n font-size: 10px;\n }\n .footer > h5 {\n font-size: 9px;\n }\n}\n\n.footer > h4, h5 {\n padding: 0;\n margin: 0;\n}","#pageBody .column .row {\n margin-top: 0.5vh;\n}\n#pageBody .column .row .button {\n margin-left: auto;\n margin-right: auto;\n}"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/static/dist/css/user_account.bundle.css b/static/dist/css/user_account.bundle.css index e047c84..aaf66f3 100644 --- a/static/dist/css/user_account.bundle.css +++ b/static/dist/css/user_account.bundle.css @@ -14,7 +14,7 @@ /* Main Table */ #pageBody { - max-height: 77vh; + max-height: 82vh; padding: 0 5vw; margin: 0; border: 0; @@ -89,8 +89,8 @@ label { input.dirty, textarea.dirty, select.dirty { - border-color: var(--colour-primary); - background-color: var(--colour-page-background-2); + border-color: var(--primary-color); + background-color: var(--background-color-2); } /*# sourceMappingURL=user_account.bundle.css.map*/ \ No newline at end of file diff --git a/static/dist/css/user_account.bundle.css.map b/static/dist/css/user_account.bundle.css.map index 31d95d2..12c04d7 100644 --- a/static/dist/css/user_account.bundle.css.map +++ b/static/dist/css/user_account.bundle.css.map @@ -1 +1 @@ -{"version":3,"file":"css/user_account.bundle.css","mappings":";;AAEA;IACI,gBAAgB;IAChB,oBAAoB;IACpB,cAAc;AAClB;;;AAGA,iBAAiB;AACjB;IACI,sBAAsB;AAC1B;;AAEA,eAAe;AACf;IACI,gBAAgB;IAChB,cAAc;IACd,SAAS;IACT,SAAS;IACT,qBAAqB;IACrB,2BAA2B;IAC3B,aAAa;IACb,sBAAsB;IACtB,uBAAuB;IACvB,gBAAgB;IAChB,kBAAkB;IAClB,kBAAkB;IAClB,WAAW;IACX,yBAAyB;AAC7B;;;AAGA,WAAW;AACX;IACI,gBAAgB;IAChB,kBAAkB;IAClB,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,sCAAsC;IACtC,kBAAkB;IAClB,SAAS;IACT,WAAW;AACf;;AAEA;IACI;QACI,eAAe;QACf,mBAAmB;QACnB,eAAe;QACf,WAAW;QACX,eAAe;IACnB;IACA;QACI,eAAe;IACnB;IACA;QACI,cAAc;IAClB;AACJ;;AAEA;IACI,UAAU;IACV,SAAS;AACb,C;;;AChEA;IACI,aAAa;AACjB;;AAEA;IACI,eAAe;IACf,SAAS;IACT,WAAW;AACf;;AAEA;IACI,cAAc;AAClB;AACA;IACI,iBAAiB;AACrB;AACA;IACI,gBAAgB;AACpB;;AAEA;;;IAGI,mCAAmC;IACnC,iDAAiD;AACrD,C","sources":["webpack://app/./static/css/sections/tcg.css","webpack://app/./static/css/pages/user/user.css"],"sourcesContent":["\n\n.container-input > input {\n padding: 0vh 1vh;\n border-radius: 0.5vh;\n max-width: 7vh;\n}\n\n\n/* Right column */\n.rightcolumn {\n min-width: fit-content;\n}\n\n/* Main Table */\n#pageBody {\n max-height: 77vh;\n padding: 0 5vw;\n margin: 0;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n position: absolute;\n width: 90vw;\n color: var(--colour-text);\n}\n\n\n/* Footer */\n.footer {\n padding: 1vh 1vw;\n text-align: center;\n margin: 0;\n max-height: 5vh;\n overflow-y: auto;\n background-color: var(--colour-accent);\n position: absolute;\n bottom: 0;\n width: 98vw;\n}\n\n@media screen and (max-width: 400px) {\n .footer {\n max-height: 8vh;\n padding: 0.75vh 2vw;\n font-size: 10px; \n width: 96vw;\n max-width: 96vw;\n }\n .footer > h4 {\n font-size: 10px;\n }\n .footer > h5 {\n font-size: 9px;\n }\n}\n\n.footer > h4, h5 {\n padding: 0;\n margin: 0;\n}","\n#formFilters {\n display: none;\n}\n\n.container.save.button-cancel {\n position: fixed;\n top: 10vh;\n right: 10vh;\n}\n\n.container-input {\n margin: 0 auto;\n}\nlabel {\n font-weight: bold;\n}\n.container-input input {\n max-width: 250px;\n}\n\ninput.dirty, \ntextarea.dirty, \nselect.dirty {\n border-color: var(--colour-primary);\n background-color: var(--colour-page-background-2);\n}"],"names":[],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"css/user_account.bundle.css","mappings":";;AAEA;IACI,gBAAgB;IAChB,oBAAoB;IACpB,cAAc;AAClB;;;AAGA,iBAAiB;AACjB;IACI,sBAAsB;AAC1B;;AAEA,eAAe;AACf;IACI,gBAAgB;IAChB,cAAc;IACd,SAAS;IACT,SAAS;IACT,qBAAqB;IACrB,2BAA2B;IAC3B,aAAa;IACb,sBAAsB;IACtB,uBAAuB;IACvB,gBAAgB;IAChB,kBAAkB;IAClB,kBAAkB;IAClB,WAAW;IACX,yBAAyB;AAC7B;;;AAGA,WAAW;AACX;IACI,gBAAgB;IAChB,kBAAkB;IAClB,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,sCAAsC;IACtC,kBAAkB;IAClB,SAAS;IACT,WAAW;AACf;;AAEA;IACI;QACI,eAAe;QACf,mBAAmB;QACnB,eAAe;QACf,WAAW;QACX,eAAe;IACnB;IACA;QACI,eAAe;IACnB;IACA;QACI,cAAc;IAClB;AACJ;;AAEA;IACI,UAAU;IACV,SAAS;AACb,C;;;AChEA;IACI,aAAa;AACjB;;AAEA;IACI,eAAe;IACf,SAAS;IACT,WAAW;AACf;;AAEA;IACI,cAAc;AAClB;AACA;IACI,iBAAiB;AACrB;AACA;IACI,gBAAgB;AACpB;;AAEA;;;IAGI,kCAAkC;IAClC,2CAA2C;AAC/C,C","sources":["webpack://app/./static/css/sections/tcg.css","webpack://app/./static/css/pages/user/user.css"],"sourcesContent":["\n\n.container-input > input {\n padding: 0vh 1vh;\n border-radius: 0.5vh;\n max-width: 7vh;\n}\n\n\n/* Right column */\n.rightcolumn {\n min-width: fit-content;\n}\n\n/* Main Table */\n#pageBody {\n max-height: 82vh;\n padding: 0 5vw;\n margin: 0;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n position: absolute;\n width: 90vw;\n color: var(--colour-text);\n}\n\n\n/* Footer */\n.footer {\n padding: 1vh 1vw;\n text-align: center;\n margin: 0;\n max-height: 5vh;\n overflow-y: auto;\n background-color: var(--colour-accent);\n position: absolute;\n bottom: 0;\n width: 98vw;\n}\n\n@media screen and (max-width: 400px) {\n .footer {\n max-height: 8vh;\n padding: 0.75vh 2vw;\n font-size: 10px; \n width: 96vw;\n max-width: 96vw;\n }\n .footer > h4 {\n font-size: 10px;\n }\n .footer > h5 {\n font-size: 9px;\n }\n}\n\n.footer > h4, h5 {\n padding: 0;\n margin: 0;\n}","\n#formFilters {\n display: none;\n}\n\n.container.save.button-cancel {\n position: fixed;\n top: 10vh;\n right: 10vh;\n}\n\n.container-input {\n margin: 0 auto;\n}\nlabel {\n font-weight: bold;\n}\n.container-input input {\n max-width: 250px;\n}\n\ninput.dirty, \ntextarea.dirty, \nselect.dirty {\n border-color: var(--primary-color);\n background-color: var(--background-color-2);\n}"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/static/dist/css/user_accounts.bundle.css b/static/dist/css/user_accounts.bundle.css index 9b398b1..bebc749 100644 --- a/static/dist/css/user_accounts.bundle.css +++ b/static/dist/css/user_accounts.bundle.css @@ -15,7 +15,7 @@ /* Main Table */ #pageBody { - max-height: 77vh; + max-height: 82vh; padding: 0 5vw; margin: 0; border: 0; diff --git a/static/dist/css/user_accounts.bundle.css.map b/static/dist/css/user_accounts.bundle.css.map index d9c0e77..1096ff7 100644 --- a/static/dist/css/user_accounts.bundle.css.map +++ b/static/dist/css/user_accounts.bundle.css.map @@ -1 +1 @@ -{"version":3,"file":"css/user_accounts.bundle.css","mappings":";;;AAEA;IACI,gBAAgB;IAChB,oBAAoB;IACpB,cAAc;AAClB;;;AAGA,iBAAiB;AACjB;IACI,sBAAsB;AAC1B;;AAEA,eAAe;AACf;IACI,gBAAgB;IAChB,cAAc;IACd,SAAS;IACT,SAAS;IACT,qBAAqB;IACrB,2BAA2B;IAC3B,aAAa;IACb,sBAAsB;IACtB,uBAAuB;IACvB,gBAAgB;IAChB,kBAAkB;IAClB,kBAAkB;IAClB,WAAW;IACX,yBAAyB;AAC7B;;;AAGA,WAAW;AACX;IACI,gBAAgB;IAChB,kBAAkB;IAClB,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,sCAAsC;IACtC,kBAAkB;IAClB,SAAS;IACT,WAAW;AACf;;AAEA;IACI;QACI,eAAe;QACf,mBAAmB;QACnB,eAAe;QACf,WAAW;QACX,eAAe;IACnB;IACA;QACI,eAAe;IACnB;IACA;QACI,cAAc;IAClB;AACJ;;AAEA;IACI,UAAU;IACV,SAAS;AACb,C","sources":["webpack://app/./static/css/sections/tcg.css"],"sourcesContent":["\n\n.container-input > input {\n padding: 0vh 1vh;\n border-radius: 0.5vh;\n max-width: 7vh;\n}\n\n\n/* Right column */\n.rightcolumn {\n min-width: fit-content;\n}\n\n/* Main Table */\n#pageBody {\n max-height: 77vh;\n padding: 0 5vw;\n margin: 0;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n position: absolute;\n width: 90vw;\n color: var(--colour-text);\n}\n\n\n/* Footer */\n.footer {\n padding: 1vh 1vw;\n text-align: center;\n margin: 0;\n max-height: 5vh;\n overflow-y: auto;\n background-color: var(--colour-accent);\n position: absolute;\n bottom: 0;\n width: 98vw;\n}\n\n@media screen and (max-width: 400px) {\n .footer {\n max-height: 8vh;\n padding: 0.75vh 2vw;\n font-size: 10px; \n width: 96vw;\n max-width: 96vw;\n }\n .footer > h4 {\n font-size: 10px;\n }\n .footer > h5 {\n font-size: 9px;\n }\n}\n\n.footer > h4, h5 {\n padding: 0;\n margin: 0;\n}"],"names":[],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"css/user_accounts.bundle.css","mappings":";;;AAEA;IACI,gBAAgB;IAChB,oBAAoB;IACpB,cAAc;AAClB;;;AAGA,iBAAiB;AACjB;IACI,sBAAsB;AAC1B;;AAEA,eAAe;AACf;IACI,gBAAgB;IAChB,cAAc;IACd,SAAS;IACT,SAAS;IACT,qBAAqB;IACrB,2BAA2B;IAC3B,aAAa;IACb,sBAAsB;IACtB,uBAAuB;IACvB,gBAAgB;IAChB,kBAAkB;IAClB,kBAAkB;IAClB,WAAW;IACX,yBAAyB;AAC7B;;;AAGA,WAAW;AACX;IACI,gBAAgB;IAChB,kBAAkB;IAClB,SAAS;IACT,eAAe;IACf,gBAAgB;IAChB,sCAAsC;IACtC,kBAAkB;IAClB,SAAS;IACT,WAAW;AACf;;AAEA;IACI;QACI,eAAe;QACf,mBAAmB;QACnB,eAAe;QACf,WAAW;QACX,eAAe;IACnB;IACA;QACI,eAAe;IACnB;IACA;QACI,cAAc;IAClB;AACJ;;AAEA;IACI,UAAU;IACV,SAAS;AACb,C","sources":["webpack://app/./static/css/sections/tcg.css"],"sourcesContent":["\n\n.container-input > input {\n padding: 0vh 1vh;\n border-radius: 0.5vh;\n max-width: 7vh;\n}\n\n\n/* Right column */\n.rightcolumn {\n min-width: fit-content;\n}\n\n/* Main Table */\n#pageBody {\n max-height: 82vh;\n padding: 0 5vw;\n margin: 0;\n border: 0;\n align-content: center;\n justify-content: flex-start;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n overflow-y: auto;\n overflow-x: hidden;\n position: absolute;\n width: 90vw;\n color: var(--colour-text);\n}\n\n\n/* Footer */\n.footer {\n padding: 1vh 1vw;\n text-align: center;\n margin: 0;\n max-height: 5vh;\n overflow-y: auto;\n background-color: var(--colour-accent);\n position: absolute;\n bottom: 0;\n width: 98vw;\n}\n\n@media screen and (max-width: 400px) {\n .footer {\n max-height: 8vh;\n padding: 0.75vh 2vw;\n font-size: 10px; \n width: 96vw;\n max-width: 96vw;\n }\n .footer > h4 {\n font-size: 10px;\n }\n .footer > h5 {\n font-size: 9px;\n }\n}\n\n.footer > h4, h5 {\n padding: 0;\n margin: 0;\n}"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/static/dist/js/main.bundle.js b/static/dist/js/main.bundle.js index 24c08d9..1839dc1 100644 --- a/static/dist/js/main.bundle.js +++ b/static/dist/js/main.bundle.js @@ -746,6 +746,7 @@ class BasePage { // , buttonSave = null, buttonCancel = null if (Validation.isEmpty(buttonContainerSelector)) buttonContainerSelector = '.' + flagContainer + '.' + flagSave + '.' + flagCancel; let buttonSave = document.querySelector(buttonContainerSelector + ' ' + idButtonSave); + if (buttonSave == null) return; let buttonCancel = document.querySelector(buttonContainerSelector + ' ' + idButtonCancel); utils_Utils.consoleLogIfNotProductionEnvironment({ show, @@ -1116,6 +1117,7 @@ class TableBasePage extends BasePage { cacheRowBlank() { let selectorRowNew = idTableMain + ' tbody tr.' + flagRowNew; let rowBlankTemp = document.querySelector(selectorRowNew); + if (rowBlankTemp == null) return; utils_Utils.consoleLogIfNotProductionEnvironment("row blank temp: ", rowBlankTemp); let countRows = document.querySelectorAll(idTableMain + ' > tbody > tr').length; _rowBlank = rowBlankTemp.cloneNode(true); @@ -1524,13 +1526,89 @@ class TableBasePage extends BasePage { DOM.toggleElementHasClassnameFlag(columnTh, isRequiredFlag, classnameFlag); } updateAndToggleShowButtonsSaveCancel() { - let pageBody = document.querySelector(idPageBody); + // let pageBody = document.querySelector(idPageBody); let isDirty = DOM.hasDirtyChildrenContainer(pageBody); + let buttonContainerSelector = '.' + flagContainer + '.' + flagSave + '.' + flagCancel; + let buttonSave = document.querySelector(buttonContainerSelector + ' ' + idButtonSave); + let areVisibleSaveCancelButtons = !buttonSave.classList.contains(flagIsCollapsed); console.log({ pageBody, - isDirty + isDirty, + areVisibleSaveCancelButtons }); - this.toggleShowButtonsSaveCancel(isDirty); + this.toggleShowButtonsSaveCancel(isDirty || areVisibleSaveCancelButtons); + } +} +;// ./static/js/pages/tcg/mtg_decks.js + + + + +class PageMtgDecks extends TableBasePage { + static hash = hashPageMtgDecks; + static attrIdRowObject = attrDeckId; + callSaveTableContent = API.saveDeck; + constructor(router) { + super(router); + } + initialize() { + this.sharedInitialize(); + } + hookupFilters() { + /* + this.sharedHookupFilters(); + this.hookupFilterActive(); + */ + } + loadRowTable(rowJson) { + if (rowJson == null) return; + if (_verbose) { + utils_Utils.consoleLogIfNotProductionEnvironment("applying data row: ", rowJson); + } + } + getJsonRow(row) { + return; + } + initialiseRowNew(tbody, row) {} + postInitialiseRowNewCallback(tbody) { + let newRows = tbody.querySelectorAll('tr.' + flagRowNew); + let newestRow = newRows[0]; + let clickableElementsSelector = ['td.' + attrCommanderBracketId + ' div.' + attrCommanderBracketId].join(''); + newestRow.querySelectorAll(clickableElementsSelector).forEach(clickableElement => { + clickableElement.click(); + }); + } + hookupTableMain() { + super.hookupTableMain(); + this.hookupTableMainRows(); + this.hookupFieldsNameTable(); + this.hookupTableMainIsCommanderCheckboxes(); + this.hookupTableMainCommanderBracketPreviews(); + this.hookupFieldsActive(); + } + hookupTableMainRows() { + return; + // removed by dead control flow + + // removed by dead control flow + + } + static toggleShowDeckStatisticsSection(showSection) { + let statisticsSectionTableBody = document.querySelector('table.' + flagStatistics + ' tbody'); + if (showSection) { + statisticsSectionTableBody.classList.remove(flagIsCollapsed); + } else { + statisticsSectionTableBody.classList.add(flagIsCollapsed); + } + } + hookupTableMainIsCommanderCheckboxes() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagIsCommander + ' .' + flagIsCommander); + } + hookupTableMainCommanderBracketPreviews() { + this.hookupTableCellDdlPreviews(attrCommanderBracketId, utils_Utils.getListFromDict(commanderBrackets)); + } + leave() { + super.leave(); } } ;// ./static/js/pages/tcg/mtg_game.js @@ -1698,28 +1776,16 @@ class PageMtgGame extends TableBasePage { const grid = document.getElementById('playersGrid'); grid.innerHTML = ''; - // Build a damage lookup: { playerId: { fromPlayerId: damageAmount } } - /* - const damageLookup = {}; - damageRecords.forEach(damage => { - if (!damageLookup[damage.player_id]) { - damageLookup[damage.player_id] = {}; - } - if (damage.received_from_commander_player_id) { - damageLookup[damage.player_id][damage.received_from_commander_player_id] = damage.health_change || 0; - } - }); - */ - - let activeRoundId = PageMtgGame.getActiveRoundId(); + // let activeRoundId = PageMtgGame.getActiveRoundId(); const roundDisplayOrderLabel = PageMtgGame.getRoundDisplayOrderLabel(); - if (activeRoundId < 0) { - const currentRoundDisplayOrder = Number(DOM.getElementValueCurrent(roundDisplayOrderLabel)); - rounds.push(PageMtgGame.makeDefaultGameRound(currentRoundDisplayOrder)); - activeRoundId = PageMtgGame.getActiveRoundId(); + const currentRoundDisplayOrder = Number(DOM.getElementValueCurrent(roundDisplayOrderLabel)); + let activeRound = rounds.filter(round => round[flagDisplayOrder] == currentRoundDisplayOrder)[0]; + if (activeRound == null) { + activeRound = PageMtgGame.makeDefaultGameRound(currentRoundDisplayOrder); + rounds.push(activeRound); } - const latestRound = rounds.filter(round => round[attrRoundId] == activeRoundId)[0]; - DOM.setElementValueCurrent(roundDisplayOrderLabel, latestRound[flagDisplayOrder]); + DOM.setElementValueCurrent(roundDisplayOrderLabel, activeRound[flagDisplayOrder]); + const previousRoundIds = rounds.filter(round => round[flagDisplayOrder] <= currentRoundDisplayOrder).map(round => round[attrRoundId]); players.forEach((player, index) => { // Build display name: prefer user_name + deck_name, fallback to player name const playerId = player[attrPlayerId]; @@ -1730,17 +1796,26 @@ class PageMtgGame extends TableBasePage { let maxCommanderDamageReceived = 0; damagePlayerPairs.forEach(damagePlayerPair => { const sourceId = damagePlayerPair[attrPlayerId]; - const filteredPlayerDamages = damageRecords.filter(damage => damage[attrRoundId] == activeRoundId && damage[attrPlayerId] == playerId && damage[attrReceivedFromCommanderPlayerId] == sourceId); //[playerId] || {}; + const filteredPlayerDamages = damageRecords.filter(damage => damage[attrRoundId] == activeRound[attrRoundId] + // previousRoundIds.includes(damage[attrRoundId]) + && damage[attrPlayerId] == playerId && damage[attrReceivedFromCommanderPlayerId] == sourceId); //[playerId] || {}; if (filteredPlayerDamages.length == 0) { damageRecords.push(PageMtgGame.makeDefaultGameRoundPlayerDamage(playerId, sourceId)); } - maxCommanderDamageReceived = Math.max(maxCommanderDamageReceived, damageRecords.filter(damage => damage[attrPlayerId] == playerId && damage[attrReceivedFromCommanderPlayerId] == sourceId).map(damage => damage[flagHealthChange]).reduce((acc, curr) => acc + curr, 0)); + maxCommanderDamageReceived = Math.max(maxCommanderDamageReceived, damageRecords.filter(damage => damage[attrPlayerId] == playerId && damage[attrReceivedFromCommanderPlayerId] == sourceId && damage[attrReceivedFromCommanderPlayerId] != null && previousRoundIds.includes(damage[attrRoundId])).map(damage => damage[flagLifeLoss]).reduce((a, b) => a + b, 0)); + }); + const totalDamage = damageRecords.filter(damage => damage[attrPlayerId] == playerId && previousRoundIds.includes(damage[attrRoundId])).map(damage => damage[flagLifeLoss] - damage[flagLifeGain]).reduce((a, b) => a + b, 0); + let life = startingLife - totalDamage; + let isEliminatedByForce = damageRecords.filter(damage => damage[attrPlayerId] == playerId && previousRoundIds.includes(damage[attrRoundId])).map(damage => damage[flagIsEliminated]).some(Boolean); + console.log("renderPlayers"); + console.log({ + isEliminatedByForce, + player, + life, + maxCommanderDamageReceived }); - const totalDamage = damageRecords.filter(damage => damage[attrPlayerId] == playerId).map(damage => damage[flagHealthChange]).reduce((acc, curr) => acc + curr, 0); - let life = startingLife + totalDamage; - let isEliminatedByForce = damageRecords.filter(damage => damage[attrPlayerId] == playerId).map(damage => damage[flagIsEliminated]).some(Boolean); const isEliminated = isEliminatedByForce || !player[flagActive] || life < 1 || maxCommanderDamageReceived >= 21; - const playerOwnDamage = damageRecords.filter(damage => damage[attrPlayerId] == playerId && damage[attrReceivedFromCommanderPlayerId] == null && damage[attrRoundId] == activeRoundId)[0]; + const totalCommanderDeaths = damageRecords.filter(damage => damage[attrPlayerId] == playerId && damage[attrReceivedFromCommanderPlayerId] == null && damage[attrRoundId] == activeRound[attrRoundId]).map(damage => damage[flagCommanderDeaths]).reduce((a, b) => a + b, 0); const card = document.createElement('div'); card.className = `player-card ${isEliminated ? 'eliminated' : ''}`; card.style.animationDelay = `${index * 0.1}s`; @@ -1755,7 +1830,7 @@ class PageMtgGame extends TableBasePage { Commander Deaths:
- ${playerOwnDamage[flagCommanderDeaths]} + ${totalCommanderDeaths}
@@ -1768,11 +1843,19 @@ class PageMtgGame extends TableBasePage {
${life}
-
- - - - + +
+ + + + +
+ +
+ + + +
@@ -1795,13 +1878,15 @@ class PageMtgGame extends TableBasePage { this.hookupPlayerCardEvents(); } static renderCommanderDamageLog() { - const roundDisplayOrderLabel = PageMtgGame.getRoundDisplayOrderLabel(); - const currentRoundDisplayOrder = Number(DOM.getElementValueCurrent(roundDisplayOrderLabel)); + const currentRoundDisplayOrder = PageMtgGame.getActiveRoundDisplayOrder(); const damageTableBody = document.querySelector('.' + flagDamageLog + '.' + flagContainer + ' table tbody'); damageTableBody.innerHTML = ''; + const previousRoundIds = rounds.filter(round => round[flagDisplayOrder] <= currentRoundDisplayOrder).map(round => round[attrRoundId]); let newTableBodyHtml = ''; damageRecords.forEach(damage => { - if (damage[flagActive] && (damage[flagCommanderDeaths] > 0 || damage[flagHealthChange] != 0 || damage[flagIsEliminated]) && rounds.filter(r => r[attrRoundId] == damage[attrRoundId])[0][flagDisplayOrder] <= currentRoundDisplayOrder) { + if (damage[flagActive] && (damage[flagCommanderDeaths] > 0 || damage[flagLifeGain] != 0 || damage[flagLifeLoss] != 0 || damage[flagIsEliminated]) + // && rounds.filter(r => r[attrRoundId] == damage[attrRoundId])[0][flagDisplayOrder] <= currentRoundDisplayOrder + && previousRoundIds.includes(damage[attrRoundId])) { let round = rounds.filter(r => r[attrRoundId] == damage[attrRoundId])[0]; let player = players.filter(p => p[attrPlayerId] == damage[attrPlayerId])[0]; let receivedFromPlayer = damage[attrReceivedFromCommanderPlayerId] == null ? { @@ -1812,7 +1897,8 @@ class PageMtgGame extends TableBasePage { ${round[flagDisplayOrder]} ${player[flagName]} ${receivedFromPlayer[flagName]} - ${damage[flagHealthChange]} + ${damage[flagLifeGain]} + ${damage[flagLifeLoss]} ${damage[flagCommanderDeaths]} ${damage[flagIsEliminated]} @@ -1828,8 +1914,10 @@ class PageMtgGame extends TableBasePage { [attrRoundId]: roundId, [attrPlayerId]: playerId, [attrReceivedFromCommanderPlayerId]: receivedFromCommanderPlayerId, - [flagHealthChange]: 0, + [flagLifeGain]: 0, + [flagLifeLoss]: 0, [flagCommanderDeaths]: 0, + [flagIsEliminated]: false, [flagActive]: true }; } @@ -1852,10 +1940,13 @@ class PageMtgGame extends TableBasePage { } return roundId; } - static getActiveRoundId() { + static getActiveRoundDisplayOrder() { const roundDisplayOrderLabel = PageMtgGame.getRoundDisplayOrderLabel(); - const currentRoundDisplayOrder = Number(DOM.getElementValueCurrent(roundDisplayOrderLabel)); - let roundId = -1; + return Number(DOM.getElementValueCurrent(roundDisplayOrderLabel)); + } + static getActiveRoundId() { + const currentRoundDisplayOrder = PageMtgGame.getActiveRoundDisplayOrder(); + let roundId = 0; if (rounds.length > 0) { let filteredRounds = rounds.filter(round => round[flagDisplayOrder] == currentRoundDisplayOrder); if (filteredRounds.length > 0) roundId = filteredRounds[0][attrRoundId]; @@ -1878,11 +1969,14 @@ class PageMtgGame extends TableBasePage { return player[flagName] || `${user == null ? 'Error' : user[flagName]} - ${deck == null ? 'Error' : deck[flagName]}`; } static renderCommanderDamageRows(playerId) { - // const roundId = PageMtgGame.getLatestRoundId(); + const activeRoundDisplayOrder = PageMtgGame.getActiveRoundDisplayOrder(); + const previousRoundIds = rounds.filter(round => round[flagDisplayOrder] <= activeRoundDisplayOrder).map(round => round[attrRoundId]); return players.filter(otherPlayer => otherPlayer[attrPlayerId] !== playerId).map(otherPlayer => { const sourceId = otherPlayer[attrPlayerId]; let otherPlayerDisplayName = PageMtgGame.makePlayerDisplayName(sourceId); - const totalDamage = damageRecords.filter(damage => damage[attrPlayerId] == playerId && damage[attrReceivedFromCommanderPlayerId] == sourceId).map(damage => -damage[flagHealthChange]).reduce((acc, curr) => acc + curr, 0); + const totalDamage = damageRecords.filter(damage => damage[attrPlayerId] == playerId && damage[attrReceivedFromCommanderPlayerId] == sourceId + // && damage[attrRoundId] == roundId + && previousRoundIds.includes(damage[attrRoundId])).map(damage => damage[flagLifeLoss]).reduce((acc, curr) => acc + curr, 0); const isLethal = totalDamage >= 21; return `
@@ -1922,15 +2016,31 @@ class PageMtgGame extends TableBasePage { }; } hookupPlayerCardEvents() { - // Life buttons - let lifeButtonSelector = '.life-btn'; - Events.hookupEventHandler("click", lifeButtonSelector, (event, button) => { + // Life gain buttons + let lifeGainButtonSelector = '.life-gain-btn'; + Events.hookupEventHandler("click", lifeGainButtonSelector, (event, button) => { const playerId = button.dataset.playerId; const amount = parseInt(button.dataset.amount); const activeRoundId = PageMtgGame.getActiveRoundId(); const damageIndex = damageRecords.findIndex(damage => damage[attrRoundId] == activeRoundId && damage[attrPlayerId] == playerId && damage[attrReceivedFromCommanderPlayerId] == null); this.changeLife(playerId // playerId , amount // amount + , true // isLifeGainNotLoss + , true // updateDamage + , damageIndex // damageIndex + ); + }); + + // Life loss buttons + let lifeLossButtonSelector = '.life-loss-btn'; + Events.hookupEventHandler("click", lifeLossButtonSelector, (event, button) => { + const playerId = button.dataset.playerId; + const amount = parseInt(button.dataset.amount); + const activeRoundId = PageMtgGame.getActiveRoundId(); + const damageIndex = damageRecords.findIndex(damage => damage[attrRoundId] == activeRoundId && damage[attrPlayerId] == playerId && damage[attrReceivedFromCommanderPlayerId] == null); + this.changeLife(playerId // playerId + , amount // amount + , false // isLifeGainNotLoss , true // updateDamage , damageIndex // damageIndex ); @@ -1962,19 +2072,21 @@ class PageMtgGame extends TableBasePage { this.toggleEliminate(playerId); }); } - changeLife(playerId, amount, updateDamage = false, damageIndex = null) { + changeLife(playerId, amount, isLifeGainNotLoss = false, updateDamage = false, damageIndex = null) { const card = document.querySelector(`.player-card[data-player-id="${playerId}"]`); - if (!card || card.classList.contains('eliminated')) return; + // if (!card || card.classList.contains('eliminated')) return; + const lifeInput = card.querySelector(`.life-value[data-player-id="${playerId}"]`); const lifeDisplay = card.querySelector(`.life-display[data-player-id="${playerId}"]`); const currentLife = parseInt(lifeInput.value) || 0; - const newLife = Math.max(0, currentLife + amount); + const newLife = currentLife + amount * (isLifeGainNotLoss ? 1 : -1); DOM.setElementAttributeValueCurrent(lifeDisplay, newLife); DOM.isElementDirty(lifeDisplay); lifeInput.value = newLife; lifeDisplay.textContent = newLife; if (updateDamage) { - damageRecords[damageIndex][flagHealthChange] += amount; + let fieldFlag = isLifeGainNotLoss ? flagLifeGain : flagLifeLoss; + damageRecords[damageIndex][fieldFlag] += amount; } PageMtgGame.renderCommanderDamageLog(); @@ -1983,7 +2095,8 @@ class PageMtgGame extends TableBasePage { } changeCommanderDamage(playerId, sourceId, amount) { const card = document.querySelector(`.player-card[data-player-id="${playerId}"]`); - if (!card || card.classList.contains('eliminated')) return; + // if (!card || card.classList.contains('eliminated')) return; + const damageInput = card.querySelector(`.damage-value[data-player-id="${playerId}"][data-source-id="${sourceId}"]`); const damageDisplay = card.querySelector(`.damage-display[data-player-id="${playerId}"][data-source-id="${sourceId}"]`); const currentDamage = parseInt(damageInput.value) || 0; @@ -2002,9 +2115,11 @@ class PageMtgGame extends TableBasePage { } const activeRoundId = PageMtgGame.getActiveRoundId(); const damageIndex = damageRecords.findIndex(damageRecord => damageRecord[attrRoundId] == activeRoundId && damageRecord[attrPlayerId] == playerId && damageRecord[attrReceivedFromCommanderPlayerId] == sourceId); - damageRecords[damageIndex][flagHealthChange] -= amount; + damageRecords[damageIndex][flagLifeLoss] += amount; + let isLifeGainNotLoss = false; this.changeLife(playerId // playerId , -amount // amount + , isLifeGainNotLoss // isLifeGainNotLoss , false // updateDamage , damageIndex // damageIndex ); @@ -2012,7 +2127,8 @@ class PageMtgGame extends TableBasePage { } changeCommanderDeaths(playerId, amount) { const card = document.querySelector(`.player-card[data-player-id="${playerId}"]`); - if (!card || card.classList.contains('eliminated')) return; + // if (!card || card.classList.contains('eliminated')) return; + const deathDisplay = card.querySelector(`.death-display[data-player-id="${playerId}"]`); const currentDeaths = parseInt(deathDisplay.textContent) || 0; const newDeaths = Math.max(0, currentDeaths + amount); @@ -2064,14 +2180,14 @@ class PageMtgGame extends TableBasePage { [flagDisplayOrder]: index }); }); - let activeRoundId = PageMtgGame.getActiveRoundId(); + let activeRoundDisplayOrder = PageMtgGame.getActiveRoundDisplayOrder(); let newPlayerGridInnerHTML = ''; let playerIdA, playerIdB, isEliminatedAsIntA, isEliminatedAsIntB, playerA, playerB, indexPlayerCard; playerCardMetas.sort((a, b) => { playerIdA = a[attrPlayerId]; playerIdB = b[attrPlayerId]; - isEliminatedAsIntA = PageMtgGame.isPlayerEliminated(playerIdA, activeRoundId) ? 1 : 0; - isEliminatedAsIntB = PageMtgGame.isPlayerEliminated(playerIdB, activeRoundId) ? 1 : 0; + isEliminatedAsIntA = PageMtgGame.isPlayerEliminated(playerIdA, activeRoundDisplayOrder) ? 1 : 0; + isEliminatedAsIntB = PageMtgGame.isPlayerEliminated(playerIdB, activeRoundDisplayOrder) ? 1 : 0; playerA = players.filter(p => p[attrPlayerId] == playerIdA)[0]; playerB = players.filter(p => p[attrPlayerId] == playerIdB)[0]; return players.length * isEliminatedAsIntA + playerA[flagDisplayOrder] - (players.length * isEliminatedAsIntB + playerB[flagDisplayOrder]); @@ -2085,18 +2201,31 @@ class PageMtgGame extends TableBasePage { }); this.hookupPlayerCardEvents(); } - static isPlayerEliminated(playerId, roundId = null) { - if (roundId == null) roundId = PageMtgGame.getActiveRoundId(); - let hasDamageWithIsEliminated = damageRecords.filter(damage => damage[attrRoundId] <= roundId && damage[attrPlayerId] == playerId && damage[flagIsEliminated]).length > 0; + static isPlayerEliminated(playerId, roundDisplayOrder = null) { + if (roundDisplayOrder == null) roundDisplayOrder = PageMtgGame.getActiveRoundDisplayOrder(); + const filteredRoundIds = rounds.filter(round => round[flagDisplayOrder] <= roundDisplayOrder).map(round => round[attrRoundId]); + let hasDamageWithIsEliminated = damageRecords.filter(damage => + // damage[attrRoundId] <= roundDisplayOrder + filteredRoundIds.includes(damage[attrRoundId]) && damage[attrPlayerId] == playerId && damage[flagIsEliminated]).length > 0; let damageFromOtherPlayers = {}; let otherPlayerId; - damageRecords.filter(damage => damage[attrRoundId] <= roundId && damage[attrPlayerId] == playerId && damage[attrReceivedFromCommanderPlayerId] != null).forEach(damage => { + damageRecords.filter(damage => + // damage[attrRoundId] <= roundId + filteredRoundIds.includes(damage[attrRoundId]) && damage[attrPlayerId] == playerId && damage[attrReceivedFromCommanderPlayerId] != null).forEach(damage => { otherPlayerId = damage[attrReceivedFromCommanderPlayerId]; - damageFromOtherPlayers[otherPlayerId] = damage[flagHealthChange] + (damageFromOtherPlayers[otherPlayerId] == null ? 0 : damageFromOtherPlayers[otherPlayerId]); + damageFromOtherPlayers[otherPlayerId] = damage[flagLifeLoss] + (damageFromOtherPlayers[otherPlayerId] == null ? 0 : damageFromOtherPlayers[otherPlayerId]); + }); + let maxDamageFromOtherCommander = Object.keys(damageFromOtherPlayers).map(playerId => damageFromOtherPlayers[playerId]).reduce((acc, cur) => Math.max(acc, cur), 0); + let totalDamageTaken = damageRecords.filter(damage => + // damage[attrRoundId] <= roundId + filteredRoundIds.includes(damage[attrRoundId]) && damage[attrPlayerId] == playerId).map(damage => damage[flagLifeLoss] - damage[flagLifeGain]).reduce((a, b) => a + b, 0); + console.log({ + roundDisplayOrder, + filteredRoundIds, + hasDamageWithIsEliminated, + maxDamageFromOtherCommander, + totalDamageTaken }); - let maxDamageFromOtherCommander = Math.max(Object.keys(damageFromOtherPlayers).map(playerId => damageFromOtherPlayers[playerId])); - // .reduce((acc, cur) => acc + cur, 0); - let totalDamageTaken = damageRecords.filter(damage => damage[attrRoundId] <= roundId && damage[attrPlayerId] == playerId).map(damage => damage[flagHealthChange]).reduce((acc, cur) => acc + cur, 0); return hasDamageWithIsEliminated || maxDamageFromOtherCommander >= 21 || totalDamageTaken >= startingLife; } static updatePlayerSetup() { @@ -2156,7 +2285,8 @@ class PageMtgGame extends TableBasePage { nameInput = playerSetupWrapper.querySelector('.playerName input'); userId = DOM.getElementValueCurrent(userDdl); deckId = DOM.getElementValueCurrent(deckDdl); - name = nameInput ? nameInput.value.trim() || `Player ${i + 1}` : `Player ${i + 1}`; + name = nameInput ? nameInput.value.trim() || null : null; // `Player ${i + 1}` : `Player ${i + 1}`; + playerId = playerSetupWrapper.getAttribute(attrPlayerId); player = players.filter(p => p[attrPlayerId] == playerId)[0]; playersToSave.push({ @@ -2272,12 +2402,32 @@ class PageMtgGames extends TableBasePage { } initialize() { this.sharedInitialize(); + } + hookupFilters() { + /* + this.sharedHookupFilters(); + this.hookupFilterActive(); + */ + } + loadRowTable(rowJson) { + if (rowJson == null) return; + if (_verbose) { + utils_Utils.consoleLogIfNotProductionEnvironment("applying data row: ", rowJson); + } + } + getJsonRow(row) { + return; + } + initialiseRowNew(tbody, row) {} + postInitialiseRowNewCallback(tbody) {} + hookupTableMain() { + super.hookupTableMain(); + // this.hookupTableMainRows(); this.hookupTcgGames(); + // PageMtgGames.hideNewGameForm(); } hookupTcgGames() { - this.initGamesPage(); - } - initGamesPage() { + console.log("hookupTableMain PageMtgGames"); // Initialize form submission const newGameForm = document.getElementById('newGameForm'); if (newGameForm) { @@ -2322,7 +2472,7 @@ class PageMtgGames extends TableBasePage { static showNewGameForm() { const modal = document.getElementById('newGameModal'); if (modal) { - modal.classList.remove('hidden'); + modal.classList.remove(flagIsCollapsed); document.body.style.overflow = 'hidden'; // Focus on first input @@ -2335,7 +2485,7 @@ class PageMtgGames extends TableBasePage { static hideNewGameForm() { const modal = document.getElementById('newGameModal'); if (modal) { - modal.classList.add('hidden'); + modal.classList.add(flagIsCollapsed); document.body.style.overflow = ''; // Reset form @@ -2425,7 +2575,7 @@ class PageMtgGames extends TableBasePage { if (errorLabel) { errorLabel.textContent = message; } - errorOverlay.classList.remove('hidden'); + errorOverlay.classList.remove(flagIsCollapsed); errorOverlay.style.display = 'flex'; } else { // Fallback to alert @@ -2754,6 +2904,7 @@ class PageUsers extends TableBasePage { + // Legal @@ -2774,6 +2925,10 @@ class Router { this.pages = {}; // Core // TCG + this.pages[hashPageMtgDecks] = { + name: 'PageMtgDecks', + module: PageMtgDecks + }; this.pages[hashPageMtgGame] = { name: 'PageMtgGame', module: PageMtgGame @@ -2818,6 +2973,7 @@ class Router { this.routes = {}; // Core // TCG + this.routes[hashPageMtgDecks] = (isPopState = false) => this.navigateToHash(hashPageMtgDecks, isPopState); this.routes[hashPageMtgGame] = (isPopState = false) => this.navigateToHash(hashPageMtgGame, isPopState); this.routes[hashPageMtgGames] = (isPopState = false) => this.navigateToHash(hashPageMtgGames, isPopState); this.routes[hashPageMtgHome] = (isPopState = false) => this.navigateToHash(hashPageMtgHome, isPopState); diff --git a/static/dist/js/main.bundle.js.map b/static/dist/js/main.bundle.js.map index f5d21da..cabd274 100644 --- a/static/dist/js/main.bundle.js.map +++ b/static/dist/js/main.bundle.js.map @@ -1 +1 @@ -{"version":3,"file":"js/main.bundle.js","mappings":"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","sources":["webpack://app/./static/js/lib/validation.js","webpack://app/./static/js/dom.js","webpack://app/./static/js/api.js","webpack://app/./static/js/lib/business_objects/business_objects.js","webpack://app/./static/js/lib/events.js","webpack://app/./static/js/lib/local_storage.js","webpack://app/./static/js/lib/utils.js","webpack://app/./static/js/components/common/temporary/overlay_confirm.js","webpack://app/./static/js/pages/base.js","webpack://app/./static/js/components/common/temporary/overlay_error.js","webpack://app/./static/js/pages/base_table.js","webpack://app/./static/js/pages/tcg/mtg_game.js","webpack://app/./static/js/pages/tcg/mtg_games.js","webpack://app/./static/js/pages/tcg/mtg_home.js","webpack://app/./static/js/pages/legal/accessibility_report.js","webpack://app/./static/js/pages/legal/accessibility_statement.js","webpack://app/./static/js/pages/legal/license.js","webpack://app/./static/js/pages/legal/privacy_policy.js","webpack://app/./static/js/pages/legal/retention_schedule.js","webpack://app/./static/js/pages/mixin.js","webpack://app/./static/js/pages/mixin_table.js","webpack://app/./static/js/pages/user/user.js","webpack://app/./static/js/pages/user/users.js","webpack://app/./static/js/router.js","webpack://app/./static/js/app.js","webpack://app/./static/css/main.css?0a91","webpack://app/./static/css/components/button.css?0e0b","webpack://app/./static/css/components/card.css","webpack://app/./static/css/components/dialog.css","webpack://app/./static/css/components/form.css?94e1","webpack://app/./static/css/components/image.css?9f9c","webpack://app/./static/css/components/label.css?b78f","webpack://app/./static/css/components/modal.css","webpack://app/./static/css/components/navigation.css","webpack://app/./static/css/components/overlay.css?6dfd","webpack://app/./static/css/components/table.css?e553","webpack://app/./static/css/layouts/header.css?da75","webpack://app/./static/css/layouts/footer.css?65e3","webpack://app/./static/css/layouts/table-main.css?8c15","webpack://app/./static/css/lib/reset.css","webpack://app/./static/css/lib/typography.css","webpack://app/./static/css/lib/utils.css","webpack://app/./static/css/lib/variables.css","webpack://app/./static/css/themes/light.css?855e"],"sourcesContent":["\nexport default class Validation {\n /*\n isNullOrWhitespace(v) {\n let txt = JSON.stringify(v).replace('/\\s\\g', '');\n return (txt == '' || 'null');\n }\n */\n\n static isEmpty(object) {\n\n let isEmpty = true;\n\n if (object !== null && object !== \"null\" && object !== undefined && object !== \"undefined\") {\n\n if (object.length == undefined) {\n isEmpty = false; // object exists but isn't a collection\n }\n else if (typeof object === \"function\") {\n isEmpty = false; // object is reference\n }\n else { // string or collection\n\n let isString = (typeof object == \"string\");\n\n if (isString) object = object.trim();\n\n if (object.length > 0) {\n\n if (isString) {\n isEmpty = false; // String greater than length 0\n }\n else {\n\n if (typeof object[0] != \"string\") {\n isEmpty = false;\n }\n else {\n for(let i = 0; i < object.length; i++) {\n if (object[i] != \"\") {\n isEmpty = false;\n break\n }\n }\n }\n }\n }\n }\n }\n\n return isEmpty;\n }\n\n static isValidNumber(value, positiveOnly) {\n return !Validation.isEmpty(value) && !isNaN(value) && (!positiveOnly || parseFloat(value) > 0);\n }\n\n static getDataContentType(params) {\n\n var data = null;\n var contentType = '';\n\n if (!Validation.isEmpty(params)) {\n\n if (typeof params === \"string\") {\n data = params;\n contentType = \"application/x-www-form-urlencoded; charset=UTF-8\";\n }\n else {\n data = JSON.stringify(params);\n contentType = \"application/json; charset=UTF-8\";\n }\n }\n\n return { Data: data, ContentType: contentType };\n }\n\n static arrayContainsItem(array, itemValue) {\n\n var hasItem = false;\n\n if (!Validation.isEmpty(array) && !Validation.isEmpty(itemValue)) {\n\n var isJQueryElementArray = array[0] instanceof jQuery;\n\n if (isJQueryElementArray) {\n\n for (let i = 0; i < array.length; i++) {\n\n if (document.querySelectorAll(array[i]).is(itemValue)) {\n hasItem = true;\n break;\n }\n }\n }\n else {\n\n var isDate = array[0] instanceof Date;\n\n if (isDate) {\n \n for (let i = 0; i < array.length; i++) {\n\n if (array[i].getTime() === itemValue.getTime()) {\n hasItem = true;\n break;\n }\n }\n }\n else {\n\n for (let i = 0; i < array.length; i++) {\n\n if (array[i] == itemValue) {\n hasItem = true;\n break;\n }\n }\n }\n }\n }\n\n return hasItem;\n }\n\n static dictHasKey(d, k) {\n return (k in d);\n }\n static areEqualDicts(dict1, dict2) {\n const keys1 = Object.keys(dict1);\n const keys2 = Object.keys(dict2);\n \n if (keys1.length !== keys2.length) {\n return false;\n }\n \n for (let key of keys1) {\n if (dict1[key] !== dict2[key]) {\n return false;\n }\n }\n \n return true;\n }\n\n static imageExists(url, callback) {\n\n var img = new Image();\n\n img.onload = function() { callback(true); };\n img.onerror = function() { callback(false); };\n img.src = url;\n }\n\n static toFixedOrDefault(value, decimalPlaces, defaultValue = null) {\n return Validation.isValidNumber(value) ? parseFloat(value).toFixed(decimalPlaces) : defaultValue;\n }\n}\n","\nimport Utils from \"./lib/utils.js\";\nimport Validation from \"./lib/validation.js\";\n\nexport default class DOM {\n static setElementAttributesValuesCurrentAndPrevious(element, data) {\n DOM.setElementAttributeValueCurrent(element, data);\n DOM.setElementAttributeValuePrevious(element, data);\n }\n static setElementAttributeValueCurrent(element, data) {\n element.setAttribute(attrValueCurrent, data);\n }\n static setElementAttributeValuePrevious(element, data) {\n element.setAttribute(attrValuePrevious, data);\n }\n static setElementValuesCurrentAndPrevious(element, data) {\n DOM.setElementValueCurrent(element, data);\n DOM.setElementAttributeValuePrevious(element, data);\n }\n static setElementValueCurrent(element, data) {\n DOM.setElementAttributeValueCurrent(element, data);\n let tagName = element.tagName.toUpperCase();\n if (element.type === \"checkbox\") {\n element.checked = data;\n }\n else if (tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT') {\n element.value = data;\n }\n else {\n element.textContent = data;\n }\n }\n static setElementValueCurrentIfEmpty(element, data) {\n if (Validation.isEmpty(DOM.getElementValueCurrent(element))) {\n DOM.setElementValueCurrent(element, data);\n }\n }\n static getCellFromElement(element) {\n return element.closest('td');\n }\n static getRowFromElement(element, flagRow) {\n let selector = Validation.isEmpty(flagRow) ? 'tr' : 'tr.' + flagRow;\n return element.closest(selector);\n }\n static getClosestParent(element, parentSelector) {\n let parent = element.parentElement;\n while (parent) {\n if (parent.matches(parentSelector)) {\n return parent;\n }\n parent = parent.parentElement;\n }\n return null;\n }\n static convertForm2JSON(elementForm) {\n let dataForm = {};\n if (Validation.isEmpty(elementForm)) {\n return dataForm;\n }\n let containersFilter = elementForm.querySelectorAll('.' + flagContainerInput + '.' + flagFilter);\n let containerFilter, labelFilter, keyFilter, filter;\n for (let indexFilter = 0; indexFilter < containersFilter.length; indexFilter++) {\n containerFilter = containersFilter[indexFilter];\n labelFilter = containerFilter.querySelector('label');\n keyFilter = labelFilter.getAttribute('for');\n filter = containerFilter.querySelector(`#${keyFilter}`);\n dataForm[keyFilter] = DOM.getElementValueCurrent(filter);\n }\n return dataForm;\n }\n static loadPageBody(contentNew) {\n let pageBody = document.querySelector(idPageBody);\n pageBody.innerHTML = contentNew;\n }\n static getHashPageCurrent() {\n const hashPageCurrent = document.body.dataset.page;\n return hashPageCurrent;\n }\n static updateAndCheckIsElementDirty(element) {\n element.setAttribute(attrValueCurrent, DOM.getElementValueCurrent(element));\n return DOM.isElementDirty(element);\n }\n static isElementDirty(element) {\n let isDirty = element.getAttribute(attrValuePrevious) != element.getAttribute(attrValueCurrent);\n DOM.handleDirtyElement(element, isDirty);\n return isDirty;\n }\n static handleDirtyElement(element, isDirty) {\n DOM.toggleElementHasClassnameFlag(element, isDirty, flagDirty);\n }\n static toggleElementHasClassnameFlag(element, elementHasFlag, flag) {\n let elementAlreadyHasFlag = element.classList.contains(flag);\n if (elementHasFlag == elementAlreadyHasFlag) return;\n if (elementHasFlag) {\n element.classList.add(flag);\n } else {\n element.classList.remove(flag);\n }\n }\n static hasDirtyChildrenContainer(container) {\n if (container == null) return false;\n return container.querySelector('.' + flagDirty) != null;\n }\n static hasDirtyChildrenNotDeletedContainer(container) {\n if (container == null || container.classList.contains(flagDelete)) return false;\n return container.querySelector('.' + flagDirty + ':not(.' + flagDelete + ', .' + flagDelete + ' *)') != null;\n }\n static getElementValueCurrent(element) {\n let returnVal = '';\n \n if (!Validation.isEmpty(element)) {\n \n let tagName = element.tagName.toUpperCase();\n if (element.type === \"checkbox\") {\n returnVal = element.checked;\n }\n /*\n else if (element.classList.contains(flagIsDatePicker)) {\n returnVal = getDatePickerDate(element, adjust4DayLightSavings);\n }\n */\n else if (tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT') {\n returnVal = element.value;\n }\n else if (element.classList.contains(flagButton) && element.classList.contains(flagActive)) { // tagName === 'BUTTON'\n returnVal = element.classList.contains(flagDelete);\n }\n else if (tagName === 'TD') {\n returnVal = DOM.getElementAttributeValueCurrent(element);\n }\n else if (tagName == 'SVG' && element.classList.contains(flagCheckbox)) {\n returnVal = (element.classList.contains(flagIsChecked))\n }\n else {\n returnVal = element.textContent;\n }\n }\n \n if (Validation.isEmpty(returnVal)) returnVal = '';\n \n return returnVal;\n }\n static getElementAttributeValueCurrent(element) {\n if (Validation.isEmpty(element)) return null;\n return element.getAttribute(attrValueCurrent);\n }\n static getElementAttributeValuePrevious(element) {\n if (Validation.isEmpty(element)) return null;\n return element.getAttribute(attrValuePrevious);\n }\n /* base_table.handleChangeElementCellTable\n static updateAndCheckIsTableElementDirty(element) {\n let wasDirty = DOM.isElementDirty(element);\n let row = DOM.getRowFromElement(element);\n let wasDirtyRow = DOM.hasDirtyChildrenNotDeletedContainer(row);\n let isDirty = DOM.updateAndCheckIsElementDirty(element);\n let cell = DOM.getCellFromElement(element);\n Utils.consoleLogIfNotProductionEnvironment({element, row, cell, isDirty, wasDirty});\n if (isDirty != wasDirty) {\n DOM.handleDirtyElement(cell, isDirty);\n let isDirtyRow = DOM.hasDirtyChildrenNotDeletedContainer(row);\n Utils.consoleLogIfNotProductionEnvironment({isDirtyRow, wasDirtyRow});\n if (isDirtyRow != wasDirtyRow) {\n DOM.handleDirtyElement(row, isDirtyRow);\n }\n }\n }\n */\n static scrollToElement(parent, element) {\n // REQUIRED: parent has scroll-bar\n parent.scrollTop(parent.scrollTop() + (element.offset().top - parent.offset().top));\n }\n static isElementInContainer(container, element) {\n\n if (typeof jQuery === 'function') {\n if (container instanceof jQuery) container = container[0];\n if (element instanceof jQuery) element = element[0];\n }\n\n var containerBounds = container.getBoundingClientRect();\n var elementBounds = element.getBoundingClientRect();\n\n return (\n containerBounds.top <= elementBounds.top &&\n containerBounds.left <= elementBounds.left &&\n ((elementBounds.top + elementBounds.height) <= (containerBounds.top + containerBounds.height)) &&\n ((elementBounds.left + elementBounds.width) <= (containerBounds.left + containerBounds.width))\n );\n }\n static alertError(errorType, errorText) {\n alert(errorType + '\\n' + errorText);\n }\n static createOptionUnselectedProductVariation() {\n return {\n [flagProductVariationType]: {\n [flagNameAttrOptionText]: [flagName],\n [flagNameAttrOptionValue]: [attrIdProductVariationType],\n [flagName]: 'Select Variation Type',\n [attrIdProductVariationType]: 0,\n },\n [flagProductVariation]: {\n [flagNameAttrOptionText]: [flagName],\n [flagNameAttrOptionValue]: [attrIdProductVariation],\n [flagName]: 'Select Variation',\n [attrIdProductVariation]: 0,\n },\n };\n }\n static createOption(optionJson) {\n if (Validation.isEmpty(optionJson)) optionJson = {\n text: 'Select',\n value: 0,\n };\n let option = document.createElement('option');\n option.value = optionJson.value;\n option.textContent = optionJson.text;\n option.selected = optionJson.selected;\n return option;\n }\n\n static escapeHtml(text) {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n }\n static unescapeHtml(html) {\n const div = document.createElement('div');\n div.innerHTML = html;\n return div.textContent || div.innerText || '';\n }\n}\n","import DOM from './dom.js';\n\nexport default class API {\n \n static getCsrfToken() {\n return document.querySelector(idCSRFToken).getAttribute('content');\n }\n \n static async request(hashEndpoint, method = 'GET', data = null, params = null) {\n const url = API.getUrlFromHash(hashEndpoint, params);\n const csrfToken = API.getCsrfToken();\n const options = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n [flagCsrfToken]: csrfToken,\n }\n };\n\n if (data && (method === 'POST' || method === 'PUT' || method === 'PATCH')) {\n data = { \n ...data, \n [flagCsrfToken]: csrfToken,\n };\n options.body = JSON.stringify(data);\n }\n\n try {\n const response = await fetch(url, options);\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n return await response.json();\n } catch (error) {\n console.error('API request failed:', error);\n throw error;\n }\n }\n \n static getUrlFromHash(hash, params = null) {\n if (hash == null) hash = hashPageHome;\n let url = API.parameteriseUrl(_pathHost + hash, params);\n return url;\n }\n static parameteriseUrl(url, params) {\n if (params) {\n url += '?' + new URLSearchParams(params).toString();\n }\n return url;\n }\n static goToUrl(url) {\n window.location.href = url;\n }\n static goToHash(hash, params = null) {\n const url = API.getUrlFromHash(hash, params);\n API.goToUrl(url);\n }\n\n // specific api calls\n /* Example:\n getUsers: () => request('/users'),\n getUserById: (id) => request(`/users/${id}`),\n createUser: (userData) => request('/users', 'POST', userData),\n updateUser: (id, userData) => request(`/users/${id}`, 'PUT', userData),\n deleteUser: (id) => request(`/users/${id}`, 'DELETE'),\n */\n\n // User\n // user\n static async loginUser() {\n let callback = {};\n callback[flagCallback] = DOM.getHashPageCurrent();\n return await API.request(hashPageUserLogin, 'POST', callback);\n }\n static async saveUsers(users, formFilters, comment) {\n let dataRequest = {};\n dataRequest[flagFormFilters] = DOM.convertForm2JSON(formFilters);\n dataRequest[flagUser] = users;\n dataRequest[flagComment] = comment;\n return await API.request(hashSaveUserUser, 'POST', dataRequest);\n }\n\n // MTG Game API methods\n static async saveGame(game, formFilters, comment) {\n let dataRequest = {};\n dataRequest[flagFormFilters] = DOM.convertForm2JSON(formFilters);\n dataRequest[flagGame] = game;\n dataRequest[flagComment] = comment;\n return await API.request(hashSaveGame, 'POST', dataRequest);\n }\n\n static async getGamePlayers(gameId) {\n const url = `/mtg/api/game/${gameId}/players`;\n return await API.request(url, 'GET');\n }\n static async saveGamePlayers(players, formFilters, comment) {\n let dataRequest = {};\n dataRequest[flagFormFilters] = DOM.convertForm2JSON(formFilters);\n dataRequest[flagPlayer] = players;\n dataRequest[flagComment] = comment;\n return await API.request(hashSaveGamePlayer, 'POST', dataRequest);\n }\n\n static async getGameRounds(gameId) {\n const url = `/mtg/api/game/${gameId}/rounds`;\n return await API.request(url, 'GET');\n }\n\n static async getGameDamageRecords(gameId) {\n const url = `/mtg/api/game/${gameId}/damage-records`;\n return await API.request(url, 'GET');\n }\n static async saveGameRoundPlayerDamages(rounds, damages, formFilters, comment) {\n let dataRequest = {};\n dataRequest[flagFormFilters] = DOM.convertForm2JSON(formFilters);\n dataRequest[flagDamage] = damages;\n dataRequest[flagRound] = rounds;\n dataRequest[flagComment] = comment;\n return await API.request(hashSaveGameRoundPlayerDamage, 'POST', dataRequest);\n }\n\n\n}\n","\nimport Utils from '../utils.js';\n\nexport default class BusinessObjects {\n static getOptionJsonFromObjectJsonAndKeys(objectJson, keyText, keyValue, valueSelected = null) {\n return {\n text: objectJson[keyText],\n value: objectJson[keyValue],\n selected: (objectJson[keyValue] == valueSelected),\n };\n }\n static getOptionJsonFromObjectJson(objectJson, valueSelected = null) {\n let keyText = objectJson[flagNameAttrOptionText];\n let keyValue = objectJson[flagNameAttrOptionValue];\n // Utils.consoleLogIfNotProductionEnvironment({objectJson, keyText, keyValue});\n return BusinessObjects.getOptionJsonFromObjectJsonAndKeys(objectJson, keyText, keyValue, valueSelected);\n }\n static getObjectText(objectJson) {\n return objectJson == null ? '' : objectJson[objectJson[flagNameAttrOptionText]];\n }\n static getListObjectsFromIdDictAndCsv(idDict, idCsv) {\n let listObjects = [];\n let ids = idCsv.split(',');\n for (let id of ids) {\n listObjects.push(idDict[id]);\n }\n return listObjects;\n }\n}","\nexport default class Events {\n static initialiseEventHandler(selectorElement, classInitialised, eventHandler) {\n document.querySelectorAll(selectorElement).forEach(function(element) {\n if (element.classList.contains(classInitialised)) return;\n eventHandler(element);\n element.classList.add(classInitialised);\n });\n }\n static hookupEventHandler(eventType, selector, callback) {\n Events.initialiseEventHandler(selector, flagInitialised, (element) => {\n element.addEventListener(eventType, (event) => {\n event.stopPropagation();\n callback(event, element);\n });\n });\n }\n}","\nimport Validation from \"./validation.js\";\n\nexport default class LocalStorage {\n/*\nfunction getPageLocalStorage(pageHash) {\n\n let ls;\n try {\n ls = JSON.parse(localStorage.getItem(pageHash));\n } catch {\n\n }\n\n if (Validation.isEmpty(ls)) return {}\n\n return ls;\n}\nfunction getPageLocalStorageCurrent() {\n\n return JSON.parse(localStorage.getItem(hashPageCurrent));\n}\n\nfunction setPageLocalStorage(pageHash, newLS) {\n\n localStorage.setItem(pageHash, JSON.stringify(newLS));\n}\n\nfunction clearPageLocalStorage(pageHash) {\n localStorage.removeItem(pageHash);\n}\n\nfunction setupPageLocalStorage(pageHash) {\n\n let ls = getPageLocalStorage(pageHash);\n\n if (Validation.isEmpty(ls)) ls = {};\n\n setPageLocalStorage(pageHash, ls);\n}\n*/\n\n static getLocalStorage(key) {\n return JSON.parse(localStorage.getItem(key));\n }\n\n static setLocalStorage(key, newLS) {\n localStorage.setItem(key, JSON.stringify(newLS));\n }\n\n/*\nfunction setupPageLocalStorageNext(pageHashNext) {\n let lsOld = getPageLocalStorage(hashPageCurrent);\n hashPageCurrent = pageHashNext;\n clearPageLocalStorage(hashPageCurrent);\n setupPageLocalStorage(hashPageCurrent);\n let lsNew = getPageLocalStorage(hashPageCurrent);\n lsNew[keyBasket] = (keyBasket in lsOld) ? lsOld[keyBasket] : {'items': []};\n setPageLocalStorage(hashPageCurrent, lsNew);\n}\n*/\n}","// Utility functions\n/*\nfunction $(selector) {\n return document.querySelector(selector);\n}\n\nfunction $$(selector) {\n return document.querySelectorAll(selector);\n}\n*/\nexport default class Utils {\n static getListFromDict(dict) {\n let list = [];\n for (let key in dict) {\n list.push(dict[key]);\n }\n return list;\n }\n static consoleLogIfNotProductionEnvironment(message) {\n if (environment.is_production != \"true\") {\n console.log(message);\n }\n }\n}","\nimport Events from \"../../../lib/events.js\";\n\nexport default class OverlayConfirm {\n static hookup(callbackSuccess) {\n Events.initialiseEventHandler(idOverlayConfirm + ' button.' + flagCancel, flagInitialised, (buttonCancel) => {\n buttonCancel.addEventListener('click', () => {\n let overlay = document.querySelector(idOverlayConfirm);\n overlay.style.visibility = 'hidden';\n });\n });\n Events.initialiseEventHandler(idOverlayConfirm + ' button.' + flagSubmit, flagInitialised, (buttonConfirm) => {\n buttonConfirm.addEventListener('click', () => {\n let overlay = document.querySelector(idOverlayConfirm);\n let textarea = overlay.querySelector('textarea');\n overlay.style.visibility = 'hidden';\n callbackSuccess(textarea.value);\n });\n });\n }\n static show() {\n let overlay = document.querySelector(idOverlayConfirm);\n overlay.classList.remove(flagIsCollapsed);\n overlay.style.visibility = 'visible';\n }\n}","\nimport BusinessObjects from \"../lib/business_objects/business_objects.js\";\nimport Events from \"../lib/events.js\";\nimport LocalStorage from \"../lib/local_storage.js\";\nimport API from \"../api.js\";\nimport DOM from \"../dom.js\";\nimport Utils from \"../lib/utils.js\";\n\nimport OverlayConfirm from \"../components/common/temporary/overlay_confirm.js\";\nimport OverlayError from \"../components/common/temporary/overlay_error.js\";\nimport Validation from \"../lib/validation.js\";\n\nexport default class BasePage {\n constructor(router) {\n if (!router) {\n throw new Error(\"Router is required\");\n }\n else {\n Utils.consoleLogIfNotProductionEnvironment(\"initialising with router: \", router);\n }\n this.router = router;\n this.title = titlePageCurrent;\n if (this.constructor === BasePage) {\n throw new Error(\"Cannot instantiate abstract class\");\n }\n \n if (!this.constructor.hash) {\n throw new Error(`Class ${this.constructor.name} must have a static hash attribute.`);\n }\n }\n\n initialize() {\n throw new Error(\"Method 'initialize()' must be implemented.\");\n }\n\n sharedInitialize() {\n this.logInitialisation();\n this.hookupCommonElements();\n }\n\n logInitialisation() {\n Utils.consoleLogIfNotProductionEnvironment('Initialising ' + this.title + ' page');\n }\n \n hookupCommonElements() {\n // hookupVideos();\n this.hookupLogos();\n this.hookupNavigation();\n this.hookupOverlays();\n }\n hookupLogos() {\n Events.hookupEventHandler(\"click\", \".\" + flagImageLogo + \",\" + \".\" + flagLogo, (event, element) => {\n Utils.consoleLogIfNotProductionEnvironment('clicking logo');\n this.router.navigateToHash(hashPageHome);\n });\n }\n /*\n hookupEventHandler(eventType, selector, callback) {\n Events.initialiseEventHandler(selector, flagInitialised, (element) => {\n element.addEventListener(eventType, (event) => {\n event.stopPropagation();\n callback(event, element);\n });\n });\n }\n */\n hookupNavigation() {\n Events.hookupEventHandler(\"click\", idButtonHamburger, (event, element) => {\n let overlayHamburger = document.querySelector(idOverlayHamburger);\n if (overlayHamburger.classList.contains(flagIsCollapsed)) {\n overlayHamburger.classList.remove(flagIsCollapsed);\n overlayHamburger.classList.add(flagExpanded);\n } else {\n overlayHamburger.classList.remove(flagExpanded);\n overlayHamburger.classList.add(flagIsCollapsed);\n }\n });\n\n this.hookupButtonsNavUserAccount();\n this.hookupButtonsNavUserLogout();\n this.hookupButtonsNavUserLogin();\n }\n hookupButtonsNav(buttonSelector) {\n Events.hookupEventHandler(\"click\", buttonSelector, (event, button) => {\n let pageHash = buttonSelector.getAttribute('href');\n this.router.navigateToHash(pageHash); \n });\n }\n hookupButtonsNavUserAccount() {\n // this.hookupButtonsNav('.' + flagNavUserAccount);\n }\n hookupButtonsNavUserLogout() {\n // this.hookupButtonsNav('.' + flagNavUserLogout);\n }\n hookupButtonsNavUserLogin() {\n Events.hookupEventHandler(\"click\", '.' + flagNavUserLogin, (event, navigator) => {\n event.preventDefault();\n event.stopPropagation();\n this.leave();\n API.loginUser()\n .then((response) => {\n if (response.Success) {\n window.location.href = response[flagCallback];\n } else {\n DOM.alertError(\"Error\", response.Message);\n }\n });\n });\n }\n\n hookupOverlays() {\n this.hookupOverlayFromId(idOverlayConfirm);\n this.hookupOverlayFromId(idOverlayError);\n }\n\n hookupOverlayFromId(idOverlay) {\n Events.initialiseEventHandler(idOverlay, flagInitialised, (overlay) => {\n overlay.querySelector('button.' + flagCancel).addEventListener(\"click\", (event) => {\n event.stopPropagation();\n overlay.style.display = 'none';\n });\n });\n }\n\n hookupButtonSave() {\n Events.initialiseEventHandler('.' + flagContainer + '.' + flagSave + '.' + flagCancel + ' button.' + flagSave, flagInitialised, (button) => {\n button.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n button = event.target;\n if (button.classList.contains(flagIsCollapsed)) return;\n Utils.consoleLogIfNotProductionEnvironment('saving page: ', this.title);\n OverlayConfirm.show();\n });\n });\n }\n\n leave() {\n Utils.consoleLogIfNotProductionEnvironment('Leaving ' + this.title + ' page');\n if (this.constructor === BasePage) {\n throw new Error(\"Must implement leave() method.\");\n }\n }\n setLocalStoragePage(dataPage) {\n LocalStorage.setLocalStorage(this.hash, dataPage);\n }\n getLocalStoragePage() {\n return LocalStorage.getLocalStorage(this.hash);\n }\n\n toggleShowButtonsSaveCancel(show, buttonContainerSelector = null) { // , buttonSave = null, buttonCancel = null\n if (Validation.isEmpty(buttonContainerSelector)) buttonContainerSelector = '.' + flagContainer + '.' + flagSave + '.' + flagCancel;\n let buttonSave = document.querySelector(buttonContainerSelector + ' ' + idButtonSave);\n let buttonCancel = document.querySelector(buttonContainerSelector + ' ' + idButtonCancel);\n Utils.consoleLogIfNotProductionEnvironment({ show, buttonContainerSelector, buttonCancel, buttonSave });\n if (show) {\n buttonCancel.classList.remove(flagIsCollapsed);\n buttonSave.classList.remove(flagIsCollapsed);\n Utils.consoleLogIfNotProductionEnvironment('showing buttons');\n } else {\n buttonCancel.classList.add(flagIsCollapsed);\n buttonSave.classList.add(flagIsCollapsed);\n Utils.consoleLogIfNotProductionEnvironment('hiding buttons');\n }\n }\n\n static isDirtyFilter(filter) {\n let isDirty = DOM.updateAndCheckIsElementDirty(filter);\n if (isDirty) document.querySelectorAll(idTableMain + ' tbody tr').remove();\n return isDirty;\n }\n\n}","\nimport Events from \"../../../lib/events.js\";\n\nexport default class OverlayError {\n static hookup() {\n Events.initialiseEventHandler(idOverlayError + ' button.' + flagCancel, flagInitialised, (buttonCancel) => {\n buttonCancel.addEventListener('click', () => {\n let overlay = document.querySelector(idOverlayError);\n overlay.style.visibility = 'hidden';\n });\n });\n }\n static show(msgError) {\n let overlay = document.querySelector(idOverlayError);\n let labelError = overlay.querySelector(idLabelError);\n labelError.innerText = msgError;\n overlay.style.visibility = 'visible';\n }\n}","\nimport BusinessObjects from \"../lib/business_objects/business_objects.js\";\nimport Events from \"../lib/events.js\";\nimport LocalStorage from \"../lib/local_storage.js\";\nimport Validation from \"../lib/validation.js\";\nimport BasePage from \"./base.js\";\nimport API from \"../api.js\";\nimport DOM from \"../dom.js\";\nimport Utils from \"../lib/utils.js\";\n\nimport OverlayConfirm from \"../components/common/temporary/overlay_confirm.js\";\nimport OverlayError from \"../components/common/temporary/overlay_error.js\";\n\nexport default class TableBasePage extends BasePage {\n // static hash\n // static attrIdRowObject\n // callSaveTableContent\n\n constructor(router) {\n super(router);\n this.cursorYInitial = null;\n this.rowInitial = null;\n this.placeholder = null;\n this.dragSrcEl = null;\n this.dragSrcRow = null;\n\n this.hookupTableCellDdls = this.hookupTableCellDdls.bind(this);\n }\n \n initialize(isPopState = false) {\n throw new Error(\"Must implement initialize() method.\");\n }\n sharedInitialize(isPopState = false, isSinglePageApp = false) {\n if (!isPopState) {\n super.sharedInitialize();\n this.hookupFilters();\n this.hookupButtonsSaveCancel();\n this.hookupTableMain();\n OverlayConfirm.hookup(() => {\n if (isSinglePageApp) {\n this.saveRecordsTableDirtySinglePageApp();\n }\n else {\n this.saveRecordsTableDirty();\n }\n });\n } else {\n let dataPage = this.getLocalStoragePage();\n let filters = dataPage[flagFormFilters];\n let formFilters = TableBasePage.getFormFilters();\n let filtersDefault = DOM.convertForm2JSON(formFilters);\n if (!Validation.areEqualDicts(filters, filtersDefault)) {\n this.callFilterTableContent();\n }\n }\n }\n hookupFilters() {\n if (this.constructor === TableBasePage) {\n throw new Error(\"Subclass of TableBasePage must implement method hookupFilters().\");\n }\n }\n sharedHookupFilters() {\n this.hookupButtonApplyFilters();\n this.hookupSearchTextFilter();\n }\n hookupFilterActive() {\n let filterSelector = idFormFilters + ' #' + flagActiveOnly;\n let filterActiveOld = document.querySelector(filterSelector);\n filterActiveOld.removeAttribute('id');\n let parentDiv = filterActiveOld.parentElement;\n let isChecked = (DOM.getElementAttributeValuePrevious(parentDiv) == \"True\");\n let filterActiveNew = document.querySelector(idFormFilters + ' div.' + flagActiveOnly + '.' + flagContainerInput + ' svg.' + flagActiveOnly);\n filterActiveNew.setAttribute('id', flagActiveOnly);\n if (isChecked) filterActiveNew.classList.add(flagIsChecked);\n\n Events.hookupEventHandler(\"click\", filterSelector, (event, filterActive) => {\n Utils.consoleLogIfNotProductionEnvironment({ filterActive });\n Utils.consoleLogIfNotProductionEnvironment({ [filterActive.tagName]: filterActive.tagName });\n let svgElement = (filterActive.tagName.toUpperCase() == 'SVG') ? filterActive : filterActive.parentElement;\n let wasChecked = svgElement.classList.contains(flagIsChecked);\n if (wasChecked) {\n svgElement.classList.remove(flagIsChecked);\n }\n else {\n svgElement.classList.add(flagIsChecked);\n }\n return this.handleChangeFilter(event, filterActive);\n });\n let filter = document.querySelector(filterSelector);\n let filterValuePrevious = DOM.getElementValueCurrent(filter);\n filter.setAttribute(attrValueCurrent, filterValuePrevious);\n filter.setAttribute(attrValuePrevious, filterValuePrevious);\n }\n hookupFilter(filterFlag, handler = (event, filter) => { return this.handleChangeFilter(event, filter); }) {\n let filterSelector = idFormFilters + ' #' + filterFlag;\n Events.hookupEventHandler(\"change\", filterSelector, handler);\n let filter = document.querySelector(filterSelector);\n let filterValuePrevious = DOM.getElementValueCurrent(filter);\n filter.setAttribute(attrValueCurrent, filterValuePrevious);\n filter.setAttribute(attrValuePrevious, filterValuePrevious);\n }\n handleChangeFilter(event, filter) {\n let isDirtyFilter = DOM.updateAndCheckIsElementDirty(filter);\n let formFilters = TableBasePage.getFormFilters();\n let areDirtyFilters = isDirtyFilter || DOM.hasDirtyChildrenContainer(formFilters);\n let tbody = document.querySelector(idTableMain + ' tbody');\n let rows = tbody.querySelectorAll(':scope > tr');\n rows.forEach((row) => {\n if (areDirtyFilters && !row.classList.contains(flagIsCollapsed)) row.classList.add(flagIsCollapsed);\n if (!areDirtyFilters && row.classList.contains(flagIsCollapsed)) {\n row.classList.remove(flagIsCollapsed);\n let dirtyInputs = row.querySelectorAll('input.' + flagDirty);\n dirtyInputs.forEach((dirtyInput) => {\n dirtyInput.value = DOM.getElementAttributeValueCurrent(dirtyInput);\n });\n }\n });\n if (areDirtyFilters) {\n /*\n tbody.querySelectorAll('tr').forEach((tr) => { \n if (!DOM.hasDirtyChildrenContainer(tr)) tr.remove(); \n });\n */\n tbody.innerHTML = '
Press \"Apply Filters\" to refresh the table.
' + tbody.innerHTML;\n if (!tbody.classList.contains(flagIsCollapsed)) tbody.classList.add(flagIsCollapsed);\n }\n else {\n let isDirtyLabel = tbody.querySelector(\":scope > div\");\n if (isDirtyLabel != null) isDirtyLabel.remove();\n if (tbody.classList.contains(flagIsCollapsed)) tbody.classList.remove(flagIsCollapsed);\n let initialisedElements = tbody.querySelectorAll('.' + flagInitialised);\n initialisedElements.forEach((initialisedElement) => {\n initialisedElement.classList.remove(flagInitialised);\n });\n this.hookupTableMain();\n }\n this.updateAndToggleShowButtonsSaveCancel();\n }\n hookupFilterIsNotEmpty() {\n this.hookupFilter(flagIsNotEmpty);\n }\n hookupButtonApplyFilters() {\n Events.hookupEventHandler(\"click\", idButtonApplyFilters, (event, button) => {\n event.stopPropagation();\n this.callFilterTableContent();\n });\n }\n hookupSearchTextFilter() {\n this.hookupFilter(flagSearch);\n }\n hookupFilterCommandCategory() {\n this.hookupFilter(attrIdCommandCategory, (event, filterCommandCategory) => {\n this.handleChangeFilter();\n let isDirtyFilter = filterCommandCategory.classList.contains(flagDirty);\n let idCommandCategory = DOM.getElementValueCurrent(filterCommandCategory);\n console.log(\"filter commands unsorted\");\n console.log(Utils.getListFromDict(filterCommands));\n let commandsInCategory = Utils.getListFromDict(filterCommands).filter(command => command[attrIdCommandCategory] == idCommandCategory);\n let sortedCommands = commandsInCategory.sort((a, b) => a[flagName].localeCompare(b[flagName]));\n let filterCommand = document.querySelector(idFormFilters + ' .' + flagCommand);\n let idCommandPrevious = DOM.getElementAttributeValuePrevious(filterCommand);\n filterCommand.innerHTML = '';\n let optionJson, option;\n option = DOM.createOption(null);\n filterCommand.appendChild(option);\n sortedCommands.forEach((command) => {\n optionJson = BusinessObjects.getOptionJsonFromObjectJson(command, idCommandPrevious);\n option = DOM.createOption(optionJson);\n filterCommand.appendChild(option);\n });\n filterCommand.dispatchEvent(new Event('change'));\n return isDirtyFilter;\n });\n }\n hookupFilterCommand() {\n this.hookupFilter(attrIdCommand);\n }\n hookupFilterLocation() {\n this.hookupFilter(attrIdLocation);\n }\n /*\n getAndLoadFilteredTableContent = () => {\n this.callFilterTableContent()\n .catch(error => console.error('Error:', error));\n }\n */\n static getFormFilters() {\n return document.querySelector(idFormFilters);\n }\n callFilterTableContent() {\n let formFilters = TableBasePage.getFormFilters();\n let filtersJson = DOM.convertForm2JSON(formFilters);\n Utils.consoleLogIfNotProductionEnvironment(\"callFilterTableContent\");\n Utils.consoleLogIfNotProductionEnvironment(\"formFilters\");\n Utils.consoleLogIfNotProductionEnvironment(formFilters);\n Utils.consoleLogIfNotProductionEnvironment(\"filtersJson\");\n Utils.consoleLogIfNotProductionEnvironment(filtersJson);\n this.leave();\n API.goToHash(this.constructor.hash, filtersJson);\n }\n callbackLoadTableContent(response) {\n let table = TableBasePage.getTableMain();\n let bodyTable = table.querySelector('tbody');\n bodyTable.querySelectorAll('tr').forEach(function(row) { row.remove(); });\n let rowsJson = response.data[flagRows];\n if (!Validation.isEmpty(rowsJson) && rowsJson.every(row => row.hasOwnProperty('display_order'))) {\n rowsJson = rowsJson.sort((a, b) => a.display_order - b.display_order);\n }\n rowsJson.forEach(this.loadRowTable.bind(this));\n this.hookupTableMain();\n }\n static getTableMain() {\n return document.querySelector(idTableMain);\n }\n loadRowTable(rowJson) {\n throw new Error(\"Subclass of TableBasePage must implement method loadRowTable().\");\n }\n getAndLoadFilteredTableContentSinglePageApp() {\n this.callFilterTableContent()\n .then(data => {\n Utils.consoleLogIfNotProductionEnvironment('Table data received:', data);\n this.callbackLoadTableContent(data);\n })\n .catch(error => console.error('Error:', error));\n }\n hookupButtonsSaveCancel() {\n this.hookupButtonSave();\n this.hookupButtonCancel();\n this.toggleShowButtonsSaveCancel(false);\n }\n saveRecordsTableDirty() {\n let records = this.getTableRecords(true);\n if (records.length == 0) {\n OverlayError.show('No records to save');\n return;\n }\n let formElement = TableBasePage.getFormFilters();\n let comment = DOM.getElementValueCurrent(document.querySelector(idTextareaConfirm));\n this.callSaveTableContent(records, formElement, comment)\n .then(data => {\n if (data[flagStatus] == flagSuccess) {\n if (_verbose) { \n Utils.consoleLogIfNotProductionEnvironment('Records saved!');\n Utils.consoleLogIfNotProductionEnvironment('Data received:', data);\n }\n this.callFilterTableContent();\n }\n else {\n Utils.consoleLogIfNotProductionEnvironment(\"error: \", data[flagMessage]);\n OverlayError.show(data[flagMessage]);\n }\n })\n .catch(error => console.error('Error:', error));\n }\n getTableRecords(dirtyOnly = false) {\n let records = [];\n let record;\n document.querySelectorAll(idTableMain + ' > tbody > tr').forEach((row) => {\n if (dirtyOnly && !DOM.hasDirtyChildrenContainer(row)) return;\n record = this.getJsonRow(row);\n records.push(record);\n });\n return records;\n }\n getJsonRow(row) {\n throw new Error(\"Subclass of TableBasePage must implement method getJsonRow().\");\n }\n saveRecordsTableDirtySinglePageApp() {\n let records = this.getTableRecords(true);\n if (records.length == 0) {\n OverlayError.show('No records to save');\n return;\n }\n let formElement = TableBasePage.getFormFilters();\n let comment = DOM.getElementValueCurrent(document.querySelector(idTextareaConfirm));\n this.callSaveTableContent(records, formElement, comment)\n .then(data => {\n if (data[flagStatus] == flagSuccess) {\n if (_verbose) { \n Utils.consoleLogIfNotProductionEnvironment('Records saved!');\n Utils.consoleLogIfNotProductionEnvironment('Data received:', data);\n }\n this.callbackLoadTableContent(data);\n }\n else {\n Utils.consoleLogIfNotProductionEnvironment(\"error: \", data[flagMessage]);\n OverlayError.show(data[flagMessage]);\n }\n })\n .catch(error => console.error('Error:', error));\n }\n hookupButtonCancel() {\n Events.initialiseEventHandler('.' + flagContainer + '.' + flagSave + '.' + flagCancel + ' button.' + flagCancel, flagInitialised, (button) => {\n button.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n button = event.target;\n if (button.classList.contains(flagIsCollapsed)) return;\n this.callFilterTableContent();\n });\n button.classList.add(flagIsCollapsed);\n });\n }\n handleClickAddRowTable(event, button) {\n event.stopPropagation();\n _rowBlank.setAttribute(this.constructor.attrIdRowObject, -1 - _rowBlank.getAttribute(this.constructor.attrIdRowObject));\n let tbody = document.querySelector(idTableMain + ' tbody');\n if (tbody.classList.contains(flagIsCollapsed)) return;\n let row = _rowBlank.cloneNode(true);\n row.classList.remove(flagInitialised);\n row.querySelectorAll('.' + flagInitialised).forEach(function(element) {\n element.classList.remove(flagInitialised);\n });\n let countRows = document.querySelectorAll(idTableMain + ' > tbody > tr').length;\n row.setAttribute(this.constructor.attrIdRowObject, -1 - countRows);\n this.initialiseRowNew(tbody, row);\n tbody.prepend(row);\n tbody.scrollTop = 0;\n this.hookupTableMain();\n this.postInitialiseRowNewCallback(tbody);\n }\n initialiseRowNew(tbody, row) {\n if (this.constructor === TableBasePage) {\n throw new Error(\"Subclass of TableBasePage must implement method initialiseRowNew().\");\n }\n // row.classList.remove(flagRowNew);\n }\n hookupTableMain() {\n if (this.constructor === TableBasePage) {\n throw new Error(\"Must implement hookupTableMain() method.\");\n }\n Events.initialiseEventHandler(idTableMain, flagInitialised, (table) => {\n this.cacheRowBlank();\n });\n }\n cacheRowBlank() {\n let selectorRowNew = idTableMain + ' tbody tr.' + flagRowNew;\n let rowBlankTemp = document.querySelector(selectorRowNew);\n Utils.consoleLogIfNotProductionEnvironment(\"row blank temp: \", rowBlankTemp);\n let countRows = document.querySelectorAll(idTableMain + ' > tbody > tr').length;\n _rowBlank = rowBlankTemp.cloneNode(true);\n document.querySelectorAll(selectorRowNew).forEach(function(row) {\n row.remove();\n });\n _rowBlank.setAttribute(this.constructor.attrIdRowObject, -1 - countRows);\n }\n postInitialiseRowNewCallback(tbody) {\n if (this.constructor === TableBasePage) {\n throw new Error(\"Subclass of TableBasePage must implement method postInitialiseRowNewCallback(tbody).\");\n }\n }\n initialiseSliderDisplayOrderRowNew(tbody, row) {\n // let tdSelector = ':scope > tr > td.' + flagDisplayOrder;\n // let tbody = document.querySelector('table' + (Validation.isEmpty(flagTable) ? '' : '.' + flagTable) + ' > tbody');\n let slidersDisplayOrder = tbody.querySelectorAll(':scope > tr > td.' + flagDisplayOrder + ' input.' + flagSlider);\n let maxDisplayOrder = 0;\n slidersDisplayOrder.forEach((slider) => {\n maxDisplayOrder = Math.max(maxDisplayOrder, parseFloat(DOM.getElementValueCurrent(slider)));\n });\n let sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider);\n DOM.setElementValuesCurrentAndPrevious(sliderDisplayOrder, maxDisplayOrder + 1);\n }\n hookupSlidersDisplayOrderTable() {\n let selectorDisplayOrder = idTableMain + ' tbody tr td.' + flagDisplayOrder + ' input.' + flagSlider + '.' + flagDisplayOrder;\n this.hookupChangeHandlerTableCells(selectorDisplayOrder);\n }\n hookupChangeHandlerTableCells(inputSelector, handler = (event, element) => { this.handleChangeNestedElementCellTable(event, element); }) {\n Events.initialiseEventHandler(inputSelector, flagInitialised, (input) => {\n input.addEventListener(\"change\", (event) => {\n handler(event, input);\n });\n handler(null, input);\n });\n }\n handleChangeNestedElementCellTable(event, element) {\n let wasDirtyParentRows = this.getAllIsDirtyRowsInParentTree(element);\n let wasDirtyElement = element.classList.contains(flagDirty);\n let isDirtyElement = DOM.updateAndCheckIsElementDirty(element);\n // Utils.consoleLogIfNotProductionEnvironment({isDirtyElement, wasDirtyElement, wasDirtyParentRows});\n // let td = DOM.getCellFromElement(element);\n // DOM.setElementAttributeValueCurrent(td, DOM.getElementAttributeValueCurrent(element));\n if (isDirtyElement != wasDirtyElement) {\n // DOM.handleDirtyElement(td, isDirtyElement);\n this.updateAndToggleShowButtonsSaveCancel();\n this.cascadeChangedIsDirtyNestedElementCellTable(element, isDirtyElement, wasDirtyParentRows);\n }\n }\n getAllIsDirtyRowsInParentTree(element) {\n let rows = [];\n let parent = element;\n let isDirty;\n while (parent) {\n if (parent.tagName.toUpperCase() == 'TR') {\n isDirty = parent.classList.contains(flagDirty)\n rows.push(isDirty);\n }\n parent = parent.parentElement;\n }\n return rows;\n }\n cascadeChangedIsDirtyNestedElementCellTable(element, isDirtyElement, wasDirtyParentRows) {\n if (Validation.isEmpty(wasDirtyParentRows)) return;\n let tr = DOM.getRowFromElement(element);\n let isDirtyRow = isDirtyElement || DOM.hasDirtyChildrenContainer(tr);\n let wasDirtyRow = wasDirtyParentRows.shift();\n Utils.consoleLogIfNotProductionEnvironment({isDirtyRow, wasDirtyRow});\n if (isDirtyRow != wasDirtyRow) {\n DOM.handleDirtyElement(tr, isDirtyRow);\n this.updateAndToggleShowButtonsSaveCancel();\n this.cascadeChangedIsDirtyNestedElementCellTable(tr.parentElement, isDirtyRow, wasDirtyParentRows);\n }\n }\n hookupChangeHandlerTableCellsWhenNotCollapsed(inputSelector, handler = (event, element) => {\n if (!element.classList.contains(flagIsCollapsed)) this.handleChangeNestedElementCellTable(event, element);\n }) {\n Events.hookupEventHandler(\"change\", inputSelector, handler);\n }\n hookupFieldsCodeTable() {\n this.hookupChangeHandlerTableCells(idTableMain + ' > tbody > tr > td.' + flagCode + ' > .' + flagCode);\n }\n hookupFieldsNameTable() {\n this.hookupChangeHandlerTableCells(idTableMain + ' > tbody > tr > td.' + flagName + ' > .' + flagName);\n }\n hookupFieldsDescriptionTable() {\n this.hookupChangeHandlerTableCells(idTableMain + ' > tbody > tr > td.' + flagDescription + ' > .' + flagDescription);\n }\n hookupFieldsNotesTable() {\n this.hookupChangeHandlerTableCells(idTableMain + ' > tbody > tr > td.' + flagNotes + ' > .' + flagNotes);\n }\n hookupFieldsActive(flagTable = '', handleClickRowNew = (event, element) => { this.handleClickAddRowTable(event, element); }) {\n let selectorButton = 'table.table-main' + (Validation.isEmpty(flagTable) ? '' : '.' + flagTable) + ' > tbody > tr > td.' + flagActive + ' .' + flagButton + '.' + flagActive;\n let selectorButtonDelete = selectorButton + '.' + flagDelete;\n let selectorButtonUndelete = selectorButton + ':not(.' + flagDelete + ')';\n Utils.consoleLogIfNotProductionEnvironment(\"hookupFieldsActive: \", selectorButtonDelete, selectorButtonUndelete);\n this.hookupButtonsRowDelete(selectorButtonDelete, selectorButtonUndelete);\n this.hookupButtonsRowUndelete(selectorButtonDelete, selectorButtonUndelete);\n Events.hookupEventHandler(\n \"click\"\n , 'table.table-main' + (Validation.isEmpty(flagTable) ? '' : '.' + flagTable) + ' > thead > tr > th.' + flagActive + ' .' + flagButton + '.' + flagActive\n , (event, button) => { handleClickRowNew(event, button); }\n );\n }\n hookupButtonsRowDelete(selectorButtonDelete, selectorButtonUndelete, changeHandler = (event, element) => { this.handleChangeNestedElementCellTable(event, element); }) {\n Events.hookupEventHandler(\"click\", selectorButtonDelete, (event, element) => {\n this.handleClickButtonRowDelete(event, element, selectorButtonDelete, selectorButtonUndelete, (changeEvent, changeElement) => { changeHandler(changeEvent, changeElement); });\n });\n }\n handleClickButtonRowDelete(event, element, selectorButtonDelete, selectorButtonUndelete, changeHandler = (event, element) => { this.handleChangeNestedElementCellTable(event, element); }) {\n if (element.tagName.toUpperCase() != 'SVG') element = element.parentElement;\n let valuePrevious = DOM.getElementAttributeValuePrevious(element);\n let wasDirty = element.classList.contains(flagDirty);\n let row = DOM.getRowFromElement(element);\n if (row.classList.contains(flagRowNew) && !DOM.hasDirtyChildrenContainer(row)) {\n row.parentNode.removeChild(row);\n }\n else {\n let buttonAddTemplate = document.querySelector(idContainerTemplateElements + ' .' + flagButton + '.' + flagActive + '.' + flagAdd);\n let buttonAdd = buttonAddTemplate.cloneNode(true);\n DOM.setElementAttributeValuePrevious(buttonAdd, valuePrevious);\n DOM.setElementAttributeValueCurrent(buttonAdd, false);\n if (wasDirty) buttonAdd.classList.add(flagDirty);\n element.replaceWith(buttonAdd);\n changeHandler(null, buttonAdd);\n this.hookupButtonsRowUndelete(selectorButtonDelete, selectorButtonUndelete, (changeEvent, changeElement) => { changeHandler(changeEvent, changeElement); });\n }\n this.updateAndToggleShowButtonsSaveCancel();\n }\n hookupButtonsRowUndelete(selectorButtonDelete, selectorButtonUndelete, changeHandler = (event, element) => { this.handleChangeNestedElementCellTable(event, element); }) {\n Events.hookupEventHandler(\"click\", selectorButtonUndelete, (event, element) => {\n this.handleClickButtonRowUndelete(event, element, selectorButtonDelete, selectorButtonUndelete, (changeEvent, changeElement) => { changeHandler(changeEvent, changeElement); });\n });\n }\n handleClickButtonRowUndelete(event, element, selectorButtonDelete, selectorButtonUndelete, changeHandler = (event, element) => { this.handleChangeNestedElementCellTable(event, element); }) {\n if (element.tagName.toUpperCase() != 'SVG') element = element.parentElement;\n let valuePrevious = DOM.getElementAttributeValuePrevious(element);\n let wasDirty = DOM.isElementDirty(element);\n let buttonDeleteTemplate = document.querySelector(idContainerTemplateElements + ' .' + flagButton + '.' + flagActive + '.' + flagDelete);\n let buttonDelete = buttonDeleteTemplate.cloneNode(true);\n DOM.setElementAttributeValuePrevious(buttonDelete, valuePrevious);\n DOM.setElementAttributeValueCurrent(buttonDelete, true);\n if (wasDirty) buttonDelete.classList.add(flagDirty);\n element.replaceWith(buttonDelete);\n changeHandler(null, buttonDelete);\n this.hookupButtonsRowDelete(selectorButtonDelete, selectorButtonUndelete, (changeEvent, changeElement) => { changeHandler(changeEvent, changeElement); });\n this.updateAndToggleShowButtonsSaveCancel();\n }\n hookupTdsAccessLevel() {\n this.hookupTableCellDdlPreviews(flagAccessLevel, Utils.getListFromDict(accessLevels));\n }\n hookupTableCellDdlPreviews(\n fieldFlag\n , optionList\n , cellSelector = null\n , ddlHookup = (ddlSelector) => { this.hookupTableCellDdls(ddlSelector); }\n , changeHandler = (event, element) => { this.handleChangeNestedElementCellTable(event, element); }\n ) {\n if (cellSelector == null) cellSelector = idTableMain + ' > tbody > tr > td.' + fieldFlag;\n Events.hookupEventHandler(\"click\", cellSelector + ' div.' + fieldFlag, (event, div) => {\n this.handleClickTableCellDdlPreview(\n event\n , div\n , fieldFlag\n , optionList\n , cellSelector\n , (ddlSelector) => { ddlHookup(\n ddlSelector\n , (event, element) => { changeHandler(event, element); }\n ); }\n );\n });\n ddlHookup(cellSelector + ' select.' + fieldFlag);\n }\n hookupTableCellDdls(ddlSelector, changeHandler = (event, element) => { this.handleChangeNestedElementCellTable(event, element); }) {\n this.hookupChangeHandlerTableCells(ddlSelector, (event, element) => { changeHandler(event, element); });\n }\n handleClickTableCellDdlPreview(event, div, fieldFlag, optionObjectList, cellSelector = null, ddlHookup = (cellSelector) => { this.hookupTableCellDdls(cellSelector); }) {\n if (Validation.isEmpty(cellSelector)) cellSelector = idTableMain + ' > tbody > tr > td.' + fieldFlag;\n let idSelected = DOM.getElementAttributeValueCurrent(div);\n let td = DOM.getCellFromElement(div);\n td.innerHTML = '';\n let ddl = document.createElement('select');\n ddl.classList.add(fieldFlag);\n DOM.setElementValuesCurrentAndPrevious(ddl, idSelected);\n let optionJson, option;\n if (_verbose) { \n Utils.consoleLogIfNotProductionEnvironment(\"click table cell ddl preview\");\n Utils.consoleLogIfNotProductionEnvironment({optionObjectList, cellSelector});\n }\n option = DOM.createOption(null);\n ddl.appendChild(option);\n optionObjectList.forEach((optionObjectJson) => {\n optionJson = BusinessObjects.getOptionJsonFromObjectJson(optionObjectJson, idSelected);\n option = DOM.createOption(optionJson);\n ddl.appendChild(option);\n });\n td.appendChild(ddl);\n let ddlSelector = cellSelector + ' select.' + fieldFlag;\n ddlHookup(ddlSelector);\n }\n /*\n hookupTableCellDDlPreviewsWhenNotCollapsed(cellSelector, optionList, ddlHookup = (event, element) => { this.hookupTableCellDdls(event, element); }) {\n Events.hookupEventHandler(\"click\", cellSelector + ' div', (event, div) => {\n this.handleClickTableCellDdlPreview(event, div, optionList, cellSelector, (event, element) => { ddlHookup(event, element); });\n });\n }\n */\n toggleColumnCollapsed(flagColumn, isCollapsed) {\n this.toggleColumnHasClassnameFlag(flagColumn, isCollapsed, flagIsCollapsed);\n }\n toggleColumnHeaderCollapsed(flagColumn, isCollapsed) {\n this.toggleColumnHasClassnameFlag(flagColumn, isCollapsed, flagIsCollapsed);\n }\n\n hookupFieldsCommandCategory(idTable = null) {\n if (idTable == null) idTable = idTableMain;\n this.hookupTableCellDdlPreviews(\n flagCommandCategory\n , Utils.getListFromDict(filterCommandCategories).sort((a, b) => a[flagName].localeCompare(b[flagName]))\n , idTable + ' > tbody > tr > td.' + flagCommandCategory // + ' .' + flagCommandCategory\n , (cellSelector) => { this.hookupCommandCategoryDdls(cellSelector); }\n );\n }\n hookupCommandCategoryDdls(ddlSelector) {\n this.hookupChangeHandlerTableCells(ddlSelector, (event, element) => { this.handleChangeCommandCategoryDdl(event, element); });\n }\n handleChangeCommandCategoryDdl(event, ddlCategory) {\n let row = DOM.getRowFromElement(ddlCategory);\n let idCommandCategoryRowOld = this.getIdCommandCategoryRow(row); // DOM.getElementAttributeValueCurrent(ddlCategory);\n this.handleChangeNestedElementCellTable(event, ddlCategory);\n let idCommandCategoryRowNew = this.getIdCommandCategoryRow(row); // DOM.getElementAttributeValueCurrent(ddlCategory);\n if (\n idCommandCategoryRowOld == idCommandCategoryRowNew\n || idCommandCategoryRowNew == 0\n ) return;\n console.log({ idCommandCategoryRowNew, idCommandCategoryRowOld });\n let idCommandCategoryFilter = this.getIdCommandCategoryFilter();\n let tdCommand = row.querySelector('td.' + flagCommand);\n tdCommand.dispatchEvent(new Event('click'));\n let ddlCommand = row.querySelector('td.' + flagCommand + ' select.' + flagCommand);\n ddlCommand.innerHTML = '';\n ddlCommand.appendChild(DOM.createOption(null));\n let optionJson, option;\n let commandsInCategory = Utils.getListFromDict(filterCommands).filter(command => \n (\n command[attrIdCommandCategory] == idCommandCategoryRowNew\n || idCommandCategoryRowNew == 0\n )\n && (\n command[attrIdCommandCategory] == idCommandCategoryFilter\n || idCommandCategoryFilter == 0\n )\n );\n let sortedCommands = commandsInCategory.sort((a, b) => a[flagName].localeCompare(b[flagName]));\n sortedCommands.forEach((command) => {\n optionJson = BusinessObjects.getOptionJsonFromObjectJson(command);\n option = DOM.createOption(optionJson);\n ddlCommand.appendChild(option);\n });\n this.handleChangeNestedElementCellTable(event, ddlCommand);\n }\n hookupFieldsCommand(idTable = null) {\n if (idTable == null) idTable = idTableMain;\n Events.hookupEventHandler(\"click\", idTable + ' > tbody > tr > td.' + flagCommand + ' div.' + flagCommand, (event, div) => {\n Utils.consoleLogIfNotProductionEnvironment(div);\n let parentTr = DOM.getRowFromElement(div);\n Utils.consoleLogIfNotProductionEnvironment({ div, parentTr });\n let tdCommandCategory = parentTr.querySelector('td.' + flagCommandCategory);\n let idCommandCategoryRow = this.getIdCommandCategoryRow(parentTr); // DOM.getElementAttributeValueCurrent(tdCommandCategory);\n let idCommandCategoryFilter = this.getIdCommandCategoryFilter();\n let filterCommandList = Utils.getListFromDict(filterCommands);\n let commandsInCategory = filterCommandList.filter(command => \n (\n command[attrIdCommandCategory] == idCommandCategoryRow\n || idCommandCategoryRow == 0\n )\n && (\n command[attrIdCommandCategory] == idCommandCategoryFilter\n || idCommandCategoryFilter == 0\n )\n );\n let sortedCommands = commandsInCategory.sort((a, b) => a[flagName].localeCompare(b[flagName]));\n Utils.consoleLogIfNotProductionEnvironment({ tdCommandCategory, idCommandCategoryRow, idCommandCategoryFilter, filterCommandList, commandsInCategory });\n Utils.consoleLogIfNotProductionEnvironment(filterCommandList);\n this.handleClickTableCellDdlPreview(\n event\n , div\n , flagCommand // fieldFlag\n , sortedCommands // optionList\n , idTable + ' > tbody > tr > td.' + flagCommand // cellSelector\n , (cellSelector) => { this.hookupTableCellDdls(\n cellSelector\n , (event, element) => { this.handleChangeCommandDdl(event, element); }\n ); }\n );\n });\n this.hookupTableCellDdls(\n idTable + ' > tbody > tr > td.' + flagCommand + ' select.' + flagCommand\n , (event, element) => { this.handleChangeCommandDdl(event, element); }\n );\n }\n handleChangeCommandDdl(event, ddlCommand) {\n // console.log(\"handle change command ddl\");\n let row = DOM.getRowFromElement(ddlCommand);\n this.handleChangeNestedElementCellTable(event, ddlCommand);\n let idCommandCategoryRowOld = this.getIdCommandCategoryRow(row);\n let idCommandNew = this.getIdCommandRow(row);\n let commandNew = filterCommands[idCommandNew];\n // console.log({ idCommandCategoryRowOld, commandNew });\n if (commandNew == null || idCommandCategoryRowOld == commandNew[attrIdCommandCategory]) return;\n let divCommandCategory = row.querySelector('td.' + flagCommandCategory + ' div');\n if (divCommandCategory) divCommandCategory.dispatchEvent(new Event('click'));\n let ddlCommandCategory = row.querySelector('td.' + flagCommandCategory + ' select.' + flagCommandCategory);\n DOM.setElementValueCurrent(ddlCommandCategory, commandNew[attrIdCommandCategory]);\n // console.log({ ddlCommandCategory, commandNew });\n this.handleChangeNestedElementCellTable(event, ddlCommandCategory);\n }\n getIdCommandCategoryRow(tr) {\n let elementCommandCategory = tr.querySelector('td.' + flagCommandCategory + ' .' + flagCommandCategory);\n return DOM.getElementAttributeValueCurrent(elementCommandCategory);\n }\n getIdCommandCategoryFilter() {\n let formFilters = TableBasePage.getFormFilters();\n let idCommandCategory = 0;\n if (formFilters == null) return idCommandCategory;\n let commandCategoryFilter = formFilters.querySelector('#' + attrIdCommandCategory);\n let commandFilter = formFilters.querySelector('#' + attrIdCommand);\n let valueCurrentCommandCategoryFilter = DOM.getElementAttributeValueCurrent(commandCategoryFilter);\n Utils.consoleLogIfNotProductionEnvironment({ valueCurrentCommandCategoryFilter });\n if (valueCurrentCommandCategoryFilter == \"\") {\n let valueCurrentCommandFilter = DOM.getElementAttributeValueCurrent(commandFilter);\n Utils.consoleLogIfNotProductionEnvironment({ valueCurrentCommandFilter });\n if (valueCurrentCommandFilter != \"\") {\n let command = filterCommands[valueCurrentCommandFilter];\n idCommandCategory = command[attrIdCommandCategory];\n }\n } else {\n idCommandCategory = Number(valueCurrentCommandCategoryFilter);\n }\n return idCommandCategory;\n }\n getHasCommandCategoryFilter() {\n let idCommandCategoryFilter = this.getIdCommandCategoryFilter();\n return !(Validation.isEmpty(idCommandCategoryFilter) || idCommandCategoryFilter == 0);\n }\n getIdCommandRow(tr) {\n let elementCommand = tr.querySelector('td.' + flagCommand + ' .' + flagCommand);\n return DOM.getElementAttributeValueCurrent(elementCommand);\n }\n getIdCommandFilter() {\n let formFilters = TableBasePage.getFormFilters();\n let commandFilter = formFilters.querySelector('#' + attrIdCommand);\n let valueCurrentCommandFilter = DOM.getElementAttributeValueCurrent(commandFilter);\n let idCommand = Number(valueCurrentCommandFilter);\n return idCommand;\n }\n getHasCommandFilter() {\n let idCommandFilter = this.getIdCommandFilter();\n return !(Validation.isEmpty(idCommandFilter) || idCommandFilter == 0);\n }\n /*\n createTdActive(isActive) {\n let tdActive = document.createElement(\"td\");\n tdActive.classList.add(flagActive);\n let buttonActive = document.createElement(\"button\");\n buttonActive.classList.add(flagActive);\n buttonActive.classList.add(isActive ? flagDelete : flagAdd);\n buttonActive.textContent = isActive ? 'x' : '+';\n DOM.setElementAttributesValuesCurrentAndPrevious(buttonActive, isActive);\n tdActive.appendChild(buttonActive);\n return tdActive;\n }\n */\n leave() {\n if (this.constructor === TableBasePage) {\n throw new Error(\"Must implement leave() method.\");\n }\n super.leave();\n let formFilters = TableBasePage.getFormFilters();\n let dataPage = {};\n dataPage[flagFormFilters] = DOM.convertForm2JSON(formFilters);\n this.setLocalStoragePage(dataPage);\n }\n\n toggleColumnHasClassnameFlag(columnFlag, isRequiredFlag, classnameFlag) {\n let table = TableBasePage.getTableMain();\n let columnTh = table.querySelector('th.' + columnFlag);\n let columnThHasFlag = columnTh.classList.contains(classnameFlag);\n if (isRequiredFlag == columnThHasFlag) return;\n DOM.toggleElementHasClassnameFlag(columnTh, isRequiredFlag, classnameFlag);\n }\n toggleColumnHeaderHasClassnameFlag(columnFlag, isRequiredFlag, classnameFlag) {\n let table = TableBasePage.getTableMain();\n let columnTh = table.querySelector('th.' + columnFlag);\n DOM.toggleElementHasClassnameFlag(columnTh, isRequiredFlag, classnameFlag);\n }\n\n updateAndToggleShowButtonsSaveCancel() {\n let pageBody = document.querySelector(idPageBody);\n let isDirty = DOM.hasDirtyChildrenContainer(pageBody);\n\n console.log({ pageBody, isDirty });\n\n this.toggleShowButtonsSaveCancel(isDirty);\n }\n}\n","\n\nimport API from \"../../api.js\";\nimport TableBasePage from \"../base_table.js\";\nimport DOM from \"../../dom.js\";\nimport Events from \"../../lib/events.js\";\n\nexport default class PageMtgGame extends TableBasePage {\n static hash = hashPageMtgGame;\n static attrIdRowObject = attrGameId;\n callSaveTableContent = API.saveGame;\n\n constructor(router) {\n super(router);\n }\n\n initialize() {\n this.sharedInitialize();\n this.hookupTcgGame();\n }\n hookupFilters() {\n // this.sharedHookupFilters();\n }\n loadRowTable(rowJson) {\n return;\n }\n getJsonRow(row) {\n return;\n }\n initialiseRowNew(tbody, row) {\n \n }\n postInitialiseRowNewCallback(tbody) {\n \n }\n\n hookupTableMain() {\n super.hookupTableMain();\n }\n hookupTcgGame() {\n this.initGamePage();\n let pageHeading = document.querySelector('.container.company-name .tcg-title.company-name');\n pageHeading.innerText = `MTG Game #${gameId}`;\n }\n\n initGamePage() {\n // Load existing game state from API or show setup\n PageMtgGame.updatePlayerSetup();\n if (typeof gameId !== 'undefined' && gameId) {\n this.loadGameFromServer();\n }\n /*\n else {\n PageMtgGame.updatePlayerSetup();\n }\n */\n \n PageMtgGame.hookupResetButton();\n PageMtgGame.hookupPlayerCountInput();\n this.hookupStartGameButton();\n /*\n this.hookupCommanderDeathIncrementButtons();\n this.hookupEliminateCommanderButtons();\n this.hookupPlayerLifeIncrementButtons();\n this.hookupCommanderDamageIncrementButtons();\n */\n }\n static hookupResetButton() {\n const resetGameButton = document.querySelector('header.game-header .header-right .btn-tcg.btn-tcg-secondary');\n if (resetGameButton) {\n resetGameButton.addEventListener('click', PageMtgGame.resetGame);\n }\n }\n static hookupPlayerCountInput() {\n const playerCountInput = document.getElementById('playerCount');\n if (playerCountInput) {\n playerCountInput.addEventListener('change', PageMtgGame.updatePlayerSetup);\n }\n }\n hookupStartGameButton() {\n const startGameButton = document.querySelector('.setup-section .setup-actions .btn-tcg');\n if (startGameButton) {\n startGameButton.addEventListener('click', () => { this.startGame(); });\n }\n }\n /*\n hookupCommanderDeathIncrementButtons() {\n const commanderDeathIncremementButtons = document.querySelectorAll('#players-grid .player-card .commander-deaths .death-btn');\n if (commanderDeathIncremementButtons) {\n commanderDeathIncremementButtons.forEach((button) => {\n button.addEventListener('click', PageMtgGame.changeCommanderDeaths);\n });\n }\n }\n hookupEliminateCommanderButtons() {\n const eliminateCommanderButtons = document.querySelector('#players-grid .player-card .eliminate-btn');\n if (eliminateCommanderButtons) {\n eliminateCommanderButtons.forEach((button) => {\n button.addEventListener('click', PageMtgGame.toggleEliminate);\n });\n }\n }\n hookupPlayerLifeIncrementButtons() {\n const playerLifeIncrementButtons = document.querySelector('#players-grid .player-card .eliminate-btn');\n if (playerLifeIncrementButtons) {\n playerLifeIncrementButtons.forEach((button) => {\n button.addEventListener('click', PageMtgGame.changeLife);\n });\n }\n }\n hookupCommanderDamageIncrementButtons() {\n const commanderDamageIncrementButtons = document.querySelector('#players-grid .player-card .eliminate-btn');\n if (commanderDamageIncrementButtons) {\n commanderDamageIncrementButtons.forEach((button) => {\n button.addEventListener('click', PageMtgGame.changeCommanderDamage);\n });\n }\n }\n */\n\n async loadGameFromServer() {\n console.log(\"loading game from server\");\n try {\n // Fetch players, rounds, and damage records from API\n const [playersResponse, roundsResponse, damageResponse] = await Promise.all([\n API.getGamePlayers(gameId)\n , API.getGameRounds(gameId)\n , API.getGameDamageRecords(gameId)\n ]);\n console.log({ playersResponse, damageResponse });\n\n let setupSection = document.getElementById('setupSection');\n let gameSection = document.getElementById('gameSection');\n setupSection.classList.remove('hidden');\n gameSection.classList.add('hidden');\n\n if (playersResponse.status !== 'success') {\n console.error('Failed to load players:', playersResponse.message);\n return;\n }\n\n const savedPlayers = playersResponse.data || [];\n const savedRounds = roundsResponse.status === 'success' ? (roundsResponse.data || []) : [];\n const savedDamageRecords = damageResponse.status === 'success' ? (damageResponse.data || []) : [];\n \n players = savedPlayers;\n rounds = savedRounds;\n damageRecords = savedDamageRecords;\n\n if (savedPlayers.length === 0) {\n // No players yet, show setup section\n return;\n }\n\n // Hide setup, show game\n setupSection.classList.add('hidden');\n gameSection.classList.remove('hidden');\n\n console.log({ savedPlayers, damageRecords });\n\n // Render players to DOM\n const latestRoundId = PageMtgGame.getLatestRoundId();\n const latestRound = rounds.filter(round => round[attrRoundId] == latestRoundId)[0];\n const roundDisplayOrderLabel = PageMtgGame.getRoundDisplayOrderLabel();\n DOM.setElementValuesCurrentAndPrevious(roundDisplayOrderLabel, latestRound[flagDisplayOrder]);\n \n this.renderPlayers();\n\n } catch (error) {\n console.error('Error loading game from server:', error);\n }\n }\n static getRoundDisplayOrderLabel() {\n return document.querySelector([\n '#gameSection'\n , ' > .'\n , flagRow\n , '.'\n , flagRound\n , ' > .'\n , flagRow\n , '.'\n , flagRound\n , ' > .'\n , flagRound\n , '.'\n , flagDisplayOrder\n , ' > span.'\n , flagRound\n , '.'\n , flagDisplayOrder\n ].join(''));\n }\n\n renderPlayers() {\n const grid = document.getElementById('playersGrid');\n grid.innerHTML = '';\n\n // Build a damage lookup: { playerId: { fromPlayerId: damageAmount } }\n /*\n const damageLookup = {};\n damageRecords.forEach(damage => {\n if (!damageLookup[damage.player_id]) {\n damageLookup[damage.player_id] = {};\n }\n if (damage.received_from_commander_player_id) {\n damageLookup[damage.player_id][damage.received_from_commander_player_id] = damage.health_change || 0;\n }\n });\n */\n \n let activeRoundId = PageMtgGame.getActiveRoundId();\n const roundDisplayOrderLabel = PageMtgGame.getRoundDisplayOrderLabel();\n if (activeRoundId < 0) {\n const currentRoundDisplayOrder = Number(DOM.getElementValueCurrent(roundDisplayOrderLabel));\n rounds.push(PageMtgGame.makeDefaultGameRound(currentRoundDisplayOrder));\n activeRoundId = PageMtgGame.getActiveRoundId();\n }\n const latestRound = rounds.filter(round => round[attrRoundId] == activeRoundId)[0];\n DOM.setElementValueCurrent(roundDisplayOrderLabel, latestRound[flagDisplayOrder]);\n \n players.forEach((player, index) => {\n // Build display name: prefer user_name + deck_name, fallback to player name\n const playerId = player[attrPlayerId];\n let displayName = PageMtgGame.makePlayerDisplayName(playerId, index);\n let damagePlayerPairs = [...players, { [attrPlayerId]: null }];\n let maxCommanderDamageReceived = 0;\n damagePlayerPairs.forEach(damagePlayerPair => {\n const sourceId = damagePlayerPair[attrPlayerId];\n const filteredPlayerDamages = damageRecords.filter(damage => (\n damage[attrRoundId] == activeRoundId\n && damage[attrPlayerId] == playerId\n && damage[attrReceivedFromCommanderPlayerId] == sourceId\n )); //[playerId] || {};\n if (filteredPlayerDamages.length == 0) {\n damageRecords.push(PageMtgGame.makeDefaultGameRoundPlayerDamage(playerId, sourceId));\n }\n maxCommanderDamageReceived = Math.max(\n maxCommanderDamageReceived\n , damageRecords.filter(damage => (\n damage[attrPlayerId] == playerId\n && damage[attrReceivedFromCommanderPlayerId] == sourceId\n ))\n .map(damage => damage[flagHealthChange])\n .reduce((acc, curr) => acc + curr, 0)\n );\n });\n\n const totalDamage = damageRecords.filter(damage => ( damage[attrPlayerId] == playerId ))\n .map(damage => damage[flagHealthChange])\n .reduce((acc, curr) => acc + curr, 0);\n let life = startingLife + totalDamage;\n\n let isEliminatedByForce = damageRecords.filter(damage => ( damage[attrPlayerId] == playerId ))\n .map(damage => damage[flagIsEliminated])\n .some(Boolean);\n const isEliminated = (\n isEliminatedByForce\n || !player[flagActive]\n || life < 1\n || maxCommanderDamageReceived >= 21\n );\n\n const playerOwnDamage = damageRecords.filter(damage => (\n damage[attrPlayerId] == playerId\n && damage[attrReceivedFromCommanderPlayerId] == null\n && damage[attrRoundId] == activeRoundId\n ))[0];\n const card = document.createElement('div');\n card.className = `player-card ${isEliminated ? 'eliminated' : ''}`;\n card.style.animationDelay = `${index * 0.1}s`;\n card.dataset.playerId = playerId;\n card.dataset.userName = player.user_name || '';\n card.dataset.deckName = player.deck_name || '';\n\n card.innerHTML = `\n
\n
\n
${displayName}
\n
\n Commander Deaths:\n
\n \n ${playerOwnDamage[flagCommanderDeaths]}\n \n
\n
\n
\n \n
\n\n
\n \n
${life}
\n
\n \n \n \n \n
\n
\n\n
\n
Commander Damage Taken
\n
\n ${PageMtgGame.renderCommanderDamageRows(\n playerId // playerId\n , player[attrDeckId] // deckId\n )}\n
\n
\n `;\n\n grid.appendChild(card);\n });\n\n this.reorderPlayerCards();\n\n PageMtgGame.renderCommanderDamageLog();\n\n // Hookup all event handlers\n this.hookupGameRoundEvents();\n this.hookupPlayerCardEvents();\n }\n static renderCommanderDamageLog() {\n const roundDisplayOrderLabel = PageMtgGame.getRoundDisplayOrderLabel();\n const currentRoundDisplayOrder = Number(DOM.getElementValueCurrent(roundDisplayOrderLabel));\n\n const damageTableBody = document.querySelector('.' + flagDamageLog + '.' + flagContainer + ' table tbody');\n damageTableBody.innerHTML = '';\n \n let newTableBodyHtml = '';\n damageRecords.forEach((damage) => {\n if (\n damage[flagActive]\n && (\n damage[flagCommanderDeaths] > 0\n || damage[flagHealthChange] != 0\n || damage[flagIsEliminated]\n )\n && rounds.filter(r => r[attrRoundId] == damage[attrRoundId])[0][flagDisplayOrder] <= currentRoundDisplayOrder\n ) {\n let round = rounds.filter(r => r[attrRoundId] == damage[attrRoundId])[0];\n let player = players.filter(p => p[attrPlayerId] == damage[attrPlayerId])[0];\n let receivedFromPlayer = (damage[attrReceivedFromCommanderPlayerId] == null) ? { [flagName]: ''} : players.filter(p => p[attrPlayerId] == damage[attrReceivedFromCommanderPlayerId])[0];\n newTableBodyHtml += `\n \n ${round[flagDisplayOrder]}\n ${player[flagName]}\n ${receivedFromPlayer[flagName]}\n ${damage[flagHealthChange]}\n ${damage[flagCommanderDeaths]}\n ${damage[flagIsEliminated]}\n \n `;\n }\n });\n damageTableBody.innerHTML = newTableBodyHtml;\n }\n static makeDefaultGameRoundPlayerDamage(playerId, receivedFromCommanderPlayerId) {\n let roundId = PageMtgGame.getActiveRoundId();\n return {\n [attrDamageId]: -1 - damageRecords.length\n , [attrRoundId]: roundId\n , [attrPlayerId]: playerId\n , [attrReceivedFromCommanderPlayerId]: receivedFromCommanderPlayerId\n , [flagHealthChange]: 0\n , [flagCommanderDeaths]: 0\n , [flagActive]: true\n };\n }\n static getLatestRoundId() {\n let roundId = -1;\n if (rounds.length > 0) {\n const highestRoundDisplayOrder = rounds.map(round => { return round[flagDisplayOrder]; })\n .reduce((acc, cur) => Math.max(acc, cur), 0);\n const filteredRounds = rounds.filter(round => round[flagDisplayOrder] == highestRoundDisplayOrder);\n if (filteredRounds.length > 0) {\n roundId = filteredRounds[0][attrRoundId];\n }\n console.log({ \"method\": \"getLatestRoundId\", highestRoundDisplayOrder, filteredRounds, roundId });\n }\n return roundId;\n }\n static getActiveRoundId() {\n const roundDisplayOrderLabel = PageMtgGame.getRoundDisplayOrderLabel();\n const currentRoundDisplayOrder = Number(DOM.getElementValueCurrent(roundDisplayOrderLabel));\n let roundId = -1;\n if (rounds.length > 0) {\n let filteredRounds = rounds.filter(round => round[flagDisplayOrder] == currentRoundDisplayOrder);\n if (filteredRounds.length > 0) roundId = filteredRounds[0][attrRoundId];\n console.log({ \"method\": \"getActiveRoundId\", filteredRounds, roundId });\n }\n return roundId;\n }\n static makePlayerDisplayName(playerId, index) {\n if (playerId == null) {\n return `Player ${index + 1}`;\n }\n const player = players.filter(player => player[attrPlayerId] == playerId)[0];\n const deckId = player[attrDeckId];\n const deck = (deckId == null) ? null : decks.filter(deck => deck[attrDeckId] == deckId)[0];\n const user = (playerId == null) ? null : users[player[attrUserId]];\n return player[flagName] || `${(user == null) ? 'Error' : user[flagName]} - ${(deck == null) ? 'Error' : deck[flagName]}`;\n }\n static renderCommanderDamageRows(playerId) {\n // const roundId = PageMtgGame.getLatestRoundId();\n return players\n .filter(otherPlayer => otherPlayer[attrPlayerId] !== playerId)\n .map(otherPlayer => {\n const sourceId = otherPlayer[attrPlayerId];\n let otherPlayerDisplayName = PageMtgGame.makePlayerDisplayName(sourceId);\n const totalDamage = damageRecords.filter(damage => (\n damage[attrPlayerId] == playerId\n && damage[attrReceivedFromCommanderPlayerId] == sourceId\n ))\n .map(damage => -damage[flagHealthChange])\n .reduce((acc, curr) => acc + curr, 0);\n const isLethal = totalDamage >= 21;\n\n return `\n
\n from ${otherPlayerDisplayName}\n
\n \n \n ${totalDamage}\n \n
\n
\n `;\n })\n .join('');\n }\n\n hookupGameRoundEvents() {\n let incrementRoundButtonSelector = '#gameSection .' + flagRow + '.' + flagRound + ' button.' + flagRoundDisplayOrderButton;\n Events.hookupEventHandler(\"click\", incrementRoundButtonSelector, (event, button) => {\n const amount = button.classList.contains(flagRoundDisplayOrderPlus) ? 1 : -1;\n const roundDisplayOrderButtonContainer = button.parentElement;\n const roundDisplayOrderLabel = roundDisplayOrderButtonContainer.querySelector('span.' + flagRound + '.' + flagDisplayOrder);\n const currentRoundDisplayOrder = Number(DOM.getElementValueCurrent(roundDisplayOrderLabel));\n const newDisplayOrder = currentRoundDisplayOrder + amount;\n DOM.setElementValueCurrent(roundDisplayOrderLabel, newDisplayOrder);\n DOM.isElementDirty(roundDisplayOrderLabel);\n this.updateAndToggleShowButtonsSaveCancel();\n this.renderPlayers();\n });\n }\n static makeDefaultGameRound(displayOrder) {\n const newDisplayOrder = (displayOrder != null) ? displayOrder : 1 + Math.max(rounds.map(round => round[flagDisplayOrder]));\n return {\n [attrRoundId]: -newDisplayOrder\n , [attrGameId]: gameId\n , [flagNotes]: null\n , [flagDisplayOrder]: newDisplayOrder\n , [flagActive]: true\n };\n }\n hookupPlayerCardEvents() {\n // Life buttons\n let lifeButtonSelector = '.life-btn';\n Events.hookupEventHandler(\"click\", lifeButtonSelector, (event, button) => {\n const playerId = button.dataset.playerId;\n const amount = parseInt(button.dataset.amount);\n const activeRoundId = PageMtgGame.getActiveRoundId();\n const damageIndex = damageRecords.findIndex(damage => (\n damage[attrRoundId] == activeRoundId\n && damage[attrPlayerId] == playerId\n && damage[attrReceivedFromCommanderPlayerId] == null\n ));\n this.changeLife(\n playerId // playerId\n , amount // amount\n , true // updateDamage\n , damageIndex // damageIndex\n );\n });\n\n // Commander death buttons\n let commanderDeathButtonSelector = '.death-btn';\n Events.hookupEventHandler(\"click\", commanderDeathButtonSelector, (event, button) => {\n const playerId = button.dataset.playerId;\n const isMinusButton = button.classList.contains('death-minus');\n const amount = (isMinusButton) ? -1 : 1;\n this.changeCommanderDeaths(playerId, amount);\n });\n\n // Commander damage buttons\n let commmanderDamageButtonSelector = '.damage-btn';\n Events.hookupEventHandler(\"click\", commmanderDamageButtonSelector, (event, button) => {\n const playerId = button.dataset.playerId;\n const sourceId = button.dataset.sourceId;\n const isMinusButton = button.classList.contains('damage-minus');\n const amount = (isMinusButton) ? -1 : 1;\n this.changeCommanderDamage(playerId, sourceId, amount);\n });\n\n // Eliminate buttons\n let eliminatePlayerButtonSelector = '.eliminate-btn';\n Events.hookupEventHandler(\"click\", eliminatePlayerButtonSelector, (event, button) => {\n const playerId = button.dataset.playerId;\n this.toggleEliminate(playerId);\n });\n }\n\n changeLife(playerId, amount, updateDamage = false, damageIndex = null) {\n const card = document.querySelector(`.player-card[data-player-id=\"${playerId}\"]`);\n if (!card || card.classList.contains('eliminated')) return;\n\n const lifeInput = card.querySelector(`.life-value[data-player-id=\"${playerId}\"]`);\n const lifeDisplay = card.querySelector(`.life-display[data-player-id=\"${playerId}\"]`);\n\n const currentLife = parseInt(lifeInput.value) || 0;\n const newLife = Math.max(0, currentLife + amount);\n DOM.setElementAttributeValueCurrent(lifeDisplay, newLife);\n DOM.isElementDirty(lifeDisplay);\n lifeInput.value = newLife;\n lifeDisplay.textContent = newLife;\n\n if (updateDamage) {\n damageRecords[damageIndex][flagHealthChange] += amount;\n }\n\n PageMtgGame.renderCommanderDamageLog();\n\n // PageMtgGame.debouncedSave();\n this.updateAndToggleShowButtonsSaveCancel();\n }\n\n changeCommanderDamage(playerId, sourceId, amount) {\n const card = document.querySelector(`.player-card[data-player-id=\"${playerId}\"]`);\n if (!card || card.classList.contains('eliminated')) return;\n\n const damageInput = card.querySelector(`.damage-value[data-player-id=\"${playerId}\"][data-source-id=\"${sourceId}\"]`);\n const damageDisplay = card.querySelector(`.damage-display[data-player-id=\"${playerId}\"][data-source-id=\"${sourceId}\"]`);\n\n const currentDamage = parseInt(damageInput.value) || 0;\n const newDamage = Math.max(0, currentDamage + amount);\n amount = newDamage - currentDamage;\n DOM.setElementAttributeValueCurrent(damageDisplay, newDamage);\n DOM.isElementDirty(damageDisplay);\n damageInput.value = newDamage;\n damageDisplay.textContent = newDamage;\n\n // Update lethal class\n if (newDamage >= 21) {\n damageDisplay.classList.add('lethal');\n } else {\n damageDisplay.classList.remove('lethal');\n }\n\n const activeRoundId = PageMtgGame.getActiveRoundId();\n const damageIndex = damageRecords.findIndex(damageRecord => (\n damageRecord[attrRoundId] == activeRoundId\n && damageRecord[attrPlayerId] == playerId\n && damageRecord[attrReceivedFromCommanderPlayerId] == sourceId\n ));\n damageRecords[damageIndex][flagHealthChange] -= amount;\n \n this.changeLife(\n playerId // playerId\n , -amount // amount\n , false // updateDamage\n , damageIndex // damageIndex\n );\n // PageMtgGame.debouncedSave();\n }\n\n changeCommanderDeaths(playerId, amount) {\n const card = document.querySelector(`.player-card[data-player-id=\"${playerId}\"]`);\n if (!card || card.classList.contains('eliminated')) return;\n\n const deathDisplay = card.querySelector(`.death-display[data-player-id=\"${playerId}\"]`);\n const currentDeaths = parseInt(deathDisplay.textContent) || 0;\n const newDeaths = Math.max(0, currentDeaths + amount);\n\n deathDisplay.textContent = newDeaths;\n DOM.setElementAttributeValueCurrent(deathDisplay, newDeaths);\n DOM.isElementDirty(deathDisplay);\n\n const activeRoundId = PageMtgGame.getActiveRoundId();\n const damageIndex = damageRecords.findIndex(damage => (\n damage[attrRoundId] == activeRoundId\n && damage[attrPlayerId] == playerId\n && damage[attrReceivedFromCommanderPlayerId] == null\n ));\n damageRecords[damageIndex][flagCommanderDeaths] = newDeaths;\n\n PageMtgGame.renderCommanderDamageLog();\n\n // PageMtgGame.debouncedSave();\n this.updateAndToggleShowButtonsSaveCancel();\n }\n\n toggleEliminate(playerId) {\n const card = document.querySelector(`.player-card[data-player-id=\"${playerId}\"]`);\n if (!card) return;\n\n const eliminateBtn = card.querySelector(`.eliminate-btn[data-player-id=\"${playerId}\"]`);\n const wasEliminated = card.classList.contains('eliminated');\n\n if (wasEliminated) {\n card.classList.remove('eliminated');\n eliminateBtn.textContent = 'Eliminate';\n } else {\n card.classList.add('eliminated');\n eliminateBtn.textContent = 'Revive';\n }\n const isEliminated = card.classList.contains('eliminated');\n\n const activeRoundId = PageMtgGame.getActiveRoundId();\n const damageIndex = damageRecords.findIndex(damage => (\n damage[attrRoundId] == activeRoundId\n && damage[attrPlayerId] == playerId\n && damage[attrReceivedFromCommanderPlayerId] == null\n ));\n damageRecords[damageIndex][flagIsEliminated] = isEliminated;\n\n DOM.setElementAttributeValueCurrent(eliminateBtn, isEliminated);\n DOM.isElementDirty(eliminateBtn);\n\n this.reorderPlayerCards();\n PageMtgGame.renderCommanderDamageLog();\n\n // PageMtgGame.debouncedSave();\n this.updateAndToggleShowButtonsSaveCancel();\n }\n reorderPlayerCards() {\n let playerGrid = document.getElementById('playersGrid');\n let currentPlayerCards = playerGrid.querySelectorAll('.player-card');\n let newPlayerCards = [];\n let playerCardMetas = [];\n currentPlayerCards.forEach((playerCard, index) => {\n newPlayerCards.push(playerCard.cloneNode(true));\n playerCardMetas.push({\n [flagIsEliminated]: playerCard.classList.contains(flagIsEliminated)\n , [attrPlayerId]: playerCard.dataset[\"playerId\"]\n , [flagDisplayOrder]: index\n });\n });\n let activeRoundId = PageMtgGame.getActiveRoundId();\n let newPlayerGridInnerHTML = '';\n let playerIdA, playerIdB, isEliminatedAsIntA, isEliminatedAsIntB, playerA, playerB, indexPlayerCard;\n playerCardMetas.sort((a, b) => {\n playerIdA = a[attrPlayerId];\n playerIdB = b[attrPlayerId];\n isEliminatedAsIntA = PageMtgGame.isPlayerEliminated(playerIdA, activeRoundId) ? 1 : 0;\n isEliminatedAsIntB = PageMtgGame.isPlayerEliminated(playerIdB, activeRoundId) ? 1 : 0;\n playerA = players.filter(p => p[attrPlayerId] == playerIdA)[0];\n playerB = players.filter(p => p[attrPlayerId] == playerIdB)[0];\n return (\n players.length * isEliminatedAsIntA\n + playerA[flagDisplayOrder]\n ) - (\n players.length * isEliminatedAsIntB\n + playerB[flagDisplayOrder]\n );\n }).forEach((playerCardMeta) => {\n indexPlayerCard = playerCardMeta[flagDisplayOrder];\n newPlayerGridInnerHTML += newPlayerCards[indexPlayerCard].outerHTML;\n });\n\n playerGrid.innerHTML = newPlayerGridInnerHTML;\n\n playerGrid.querySelectorAll('.' + flagInitialised).forEach((initialisedElement) => {\n initialisedElement.classList.remove(flagInitialised);\n });\n\n this.hookupPlayerCardEvents();\n }\n static isPlayerEliminated(playerId, roundId = null) {\n if (roundId == null) roundId = PageMtgGame.getActiveRoundId();\n let hasDamageWithIsEliminated = damageRecords.filter(damage => (\n damage[attrRoundId] <= roundId\n && damage[attrPlayerId] == playerId\n && damage[flagIsEliminated]\n )).length > 0;\n let damageFromOtherPlayers = {};\n let otherPlayerId;\n damageRecords.filter(damage => (\n damage[attrRoundId] <= roundId\n && damage[attrPlayerId] == playerId\n && damage[attrReceivedFromCommanderPlayerId] != null\n ))\n .forEach((damage) => {\n otherPlayerId = damage[attrReceivedFromCommanderPlayerId];\n damageFromOtherPlayers[otherPlayerId] = \n damage[flagHealthChange]\n + ((damageFromOtherPlayers[otherPlayerId] == null) ? 0 : damageFromOtherPlayers[otherPlayerId]);\n });\n let maxDamageFromOtherCommander = Math.max(Object.keys(damageFromOtherPlayers)\n .map((playerId) => damageFromOtherPlayers[playerId]));\n // .reduce((acc, cur) => acc + cur, 0);\n let totalDamageTaken = damageRecords.filter(damage => (\n damage[attrRoundId] <= roundId\n && damage[attrPlayerId] == playerId\n ))\n .map((damage) => damage[flagHealthChange])\n .reduce((acc, cur) => acc + cur, 0);\n return (\n hasDamageWithIsEliminated\n || maxDamageFromOtherCommander >= 21\n || totalDamageTaken >= startingLife\n );\n }\n\n static updatePlayerSetup() {\n const playerCountInput = document.getElementById('playerCount');\n if (!playerCountInput) return;\n\n const playerCount = parseInt(playerCountInput.value);\n const grid = document.getElementById('playerSetupGrid');\n if (!grid) return;\n\n grid.innerHTML = '';\n const wrapperTemplate = document.getElementById(playerSetupWrapperTemplateId);\n let player, wrapper, wrapperHeading, userDdl, deckDdl, nameInput;\n for (let i = 0; i < playerCount; i++) {\n if (i < players.length) {\n player = players[i];\n }\n else {\n player = PageMtgGame.makeDefaultGamePlayer();\n players.push(player);\n }\n wrapper = wrapperTemplate.cloneNode(true);\n wrapper.removeAttribute(\"id\");\n wrapper.setAttribute(flagDisplayOrder, i + 1);\n wrapper.classList.remove(flagIsCollapsed);\n wrapperHeading = wrapper.querySelector('label');\n wrapperHeading.innerText = 'Player ' + (i + 1);\n userDdl = wrapper.querySelector('.playerUser select');\n DOM.setElementValuesCurrentAndPrevious(userDdl, player[attrUserId]);\n deckDdl = wrapper.querySelector('.playerDeck select');\n DOM.setElementValuesCurrentAndPrevious(deckDdl, player[attrDeckId]);\n nameInput = wrapper.querySelector('.playerName input');\n DOM.setElementValuesCurrentAndPrevious(nameInput, player[flagName]);\n console.log('player: ', player);\n grid.appendChild(wrapper);\n }\n }\n static makeDefaultGamePlayer() {\n return {\n [attrPlayerId]: -players.length\n , [attrGameId]: gameId\n , [attrUserId]: user[attrUserId]\n , [attrDeckId]: 0\n , [flagName]: \"\"\n , [flagNotes]: null\n , [flagDisplayOrder]: players.length\n , [flagActive]: true\n };\n }\n\n async startGame() {\n const playerCountInput = document.getElementById('playerCount');\n if (!playerCountInput) return;\n\n const playerCount = parseInt(playerCountInput.value);\n const playersToSave = [];\n\n let playerSetupWrapper, playerId, player, userDdl, userId, deckDdl, deckId, nameInput, name;\n for (let i = 0; i < playerCount; i++) {\n playerSetupWrapper = document.querySelector('.player-name-input-wrapper[' + flagDisplayOrder + '=\"' + (i + 1) + '\"]');\n userDdl = playerSetupWrapper.querySelector('.playerUser select');\n deckDdl = playerSetupWrapper.querySelector('.playerDeck select');\n nameInput = playerSetupWrapper.querySelector('.playerName input');\n \n userId = DOM.getElementValueCurrent(userDdl);\n deckId = DOM.getElementValueCurrent(deckDdl);\n name = nameInput ? nameInput.value.trim() || `Player ${i + 1}` : `Player ${i + 1}`;\n\n playerId = playerSetupWrapper.getAttribute(attrPlayerId);\n player = players.filter(p => p[attrPlayerId] == playerId)[0];\n playersToSave.push({\n ...player\n , [attrGameId]: gameId\n , [attrUserId]: userId\n , [attrDeckId]: deckId\n , [flagName]: name\n , [flagDisplayOrder]: i + 1\n , [flagActive]: true\n });\n }\n\n // Save players to server\n const comment = 'Save players';\n const self = this;\n API.saveGamePlayers(playersToSave, null, comment)\n .then(data => {\n if (data[flagStatus] == flagSuccess) {\n self.leave();\n window.location.reload();\n }\n else {\n console.error('Failed to save players:', data[flagMessage]);\n PageMtgGame.showError('An error occurred while creating the game');\n }\n })\n .catch(error => {\n console.error('Error creating game:', error);\n PageMtgGame.showError('An error occurred while creating the game');\n })\n .finally(() => {\n });\n }\n\n static resetGame() {\n if (confirm('Are you sure you want to start a new game? Current game will be lost.')) {\n localStorage.removeItem(`mtgGame_${gameId}`);\n window.location.href = hashPageGames;\n }\n }\n\n async saveGame() {\n /*\n const gameState = {\n [flagPlayer]: players\n , [flagRound]: rounds\n , [flagDamage]: damageRecords\n };\n if (gameState[flagPlayer].length > 0) {\n localStorage.setItem(`mtgGame_${gameId}`, JSON.stringify(gameState));\n PageMtgGame.showSaveIndicator();\n }\n */\n const comment = 'Save player damage';\n const self = this;\n API.saveGameRoundPlayerDamages(rounds, damageRecords, null, comment)\n .then(data => {\n if (data[flagStatus] == flagSuccess) {\n self.leave();\n window.location.reload();\n }\n else {\n console.error('Failed to save player damages:', data[flagMessage]);\n PageMtgGame.showError('An error occurred while saving player damages');\n }\n })\n .catch(error => {\n console.error('Error saving player damages:', error);\n PageMtgGame.showError('An error occurred while saving player damages');\n })\n .finally(() => {\n });\n }\n /*\n static debouncedSave() {\n clearTimeout(PageMtgGame._saveTimeout);\n PageMtgGame._saveTimeout = setTimeout(() => PageMtgGame.saveGame(), 500);\n }\n\n static showSaveIndicator() {\n const indicator = document.getElementById('saveIndicator');\n if (indicator) {\n indicator.classList.add('show');\n setTimeout(() => {\n indicator.classList.remove('show');\n }, 2000);\n }\n }\n */\n saveRecordsTableDirty() {\n this.saveGame();\n }\n static showError(message) {\n // Check if there's an overlay error element\n const errorOverlay = document.getElementById('overlayError');\n if (errorOverlay) {\n const errorLabel = errorOverlay.querySelector('.error-message, #labelError');\n if (errorLabel) {\n errorLabel.textContent = message;\n }\n errorOverlay.classList.remove('hidden');\n errorOverlay.style.display = 'flex';\n } else {\n // Fallback to alert\n alert(message);\n }\n }\n\n leave() {\n super.leave();\n }\n}\n\n// Static timeout reference for debouncing\nPageMtgGame._saveTimeout = null;\n","\nimport API from \"../../api.js\";\nimport TableBasePage from \"../base_table.js\";\nimport Utils from \"../../lib/utils.js\";\n\nexport default class PageMtgGames extends TableBasePage {\n static hash = hashPageMtgGames;\n static attrIdRowObject = attrGameId;\n callSaveTableContent = API.saveGame;\n\n constructor(router) {\n super(router);\n }\n\n initialize() {\n this.sharedInitialize();\n this.hookupTcgGames();\n }\n hookupTcgGames() {\n this.initGamesPage();\n }\n initGamesPage() {\n // Initialize form submission\n const newGameForm = document.getElementById('newGameForm');\n if (newGameForm) {\n newGameForm.addEventListener('submit', this.handleNewGameSubmit.bind(this)); // () => { this.handleNewGameSubmit.bind(this); });\n }\n\n // Initialize filter form\n const filterForm = document.getElementById('formFilters');\n if (filterForm) {\n filterForm.addEventListener('submit', PageMtgGames.handleFilterSubmit);\n }\n\n // Close modal on escape key\n document.addEventListener('keydown', function(e) {\n if (e.key === 'Escape') {\n PageMtgGames.hideNewGameForm();\n }\n });\n\n // Close modal on backdrop click\n const modal = document.getElementById('newGameModal');\n if (modal) {\n modal.addEventListener('click', function(e) {\n if (e.target === modal) {\n PageMtgGames.hideNewGameForm();\n }\n });\n }\n\n // Button onclicks\n const newGameButton = document.getElementById('btnNewGame');\n if (newGameButton) {\n newGameButton.addEventListener('click', PageMtgGames.showNewGameForm);\n }\n const cancelNewGameButtons = document.querySelectorAll(\n '#newGameForm .form-actions .btn-tcg.btn-tcg-secondary'\n + ','\n + '#newGameModal .modal-content .modal-header .modal-close'\n );\n if (cancelNewGameButtons.length > 0) {\n cancelNewGameButtons.forEach((button) => {\n button.addEventListener('click', PageMtgGames.hideNewGameForm);\n });\n }\n\n }\n static showNewGameForm() {\n const modal = document.getElementById('newGameModal');\n if (modal) {\n modal.classList.remove('hidden');\n document.body.style.overflow = 'hidden';\n\n // Focus on first input\n const firstInput = modal.querySelector('input, select');\n if (firstInput) {\n firstInput.focus();\n }\n }\n }\n static hideNewGameForm() {\n const modal = document.getElementById('newGameModal');\n if (modal) {\n modal.classList.add('hidden');\n document.body.style.overflow = '';\n\n // Reset form\n const form = document.getElementById('newGameForm');\n if (form) {\n form.reset();\n }\n }\n }\n async handleNewGameSubmit(e) {\n e.preventDefault();\n\n const form = e.target;\n const formData = new FormData(form);\n\n const gameType = formData.get('game_type');\n const gameData = {\n [attrGameId]: -1\n , [flagIsCommander]: gameType === 'commander'\n , [flagIsDraft]: gameType === 'draft'\n , [flagIsSealed]: gameType === 'sealed'\n , [flagLocationName]: formData.get(flagLocationName) || null\n , [flagNotes]: formData.get(flagNotes) || null\n , [flagStartOn]: new Date().toISOString()\n , [flagStartingLife]: formData.get(flagStartingLife) || 40\n , [flagActive]: true\n };\n\n const submitBtn = form.querySelector('button[type=\"submit\"]');\n const originalText = submitBtn.textContent;\n submitBtn.textContent = 'Creating...';\n submitBtn.disabled = true;\n\n const games = [gameData];\n const comment = 'Create new game';\n API.saveGame(games, form, comment)\n .then(data => {\n if (data[flagStatus] == flagSuccess) {\n if (_verbose) { \n Utils.consoleLogIfNotProductionEnvironment('Records saved!');\n Utils.consoleLogIfNotProductionEnvironment('Data received:', data);\n }\n const gamePageHash = `${hashPageGame}/${data[attrGameId]}`;\n let filtersJson = {};\n this.leave();\n API.goToHash(gamePageHash, filtersJson);\n }\n else {\n Utils.consoleLogIfNotProductionEnvironment(\"error: \" + data[flagMessage]);\n // OverlayError.show(data[flagMessage]);\n window.location.reload();\n }\n })\n .catch(error => {\n console.error('Error creating game:', error);\n PageMtgGames.showError('An error occurred while creating the game');\n })\n .finally(() => {\n submitBtn.textContent = originalText;\n submitBtn.disabled = false;\n });\n \n }\n static handleFilterSubmit(e) {\n // Let the form submit normally - it will reload with query params\n // You can add client-side filtering here if needed\n }\n static getCSRFToken() {\n // Try meta tag first\n const metaTag = document.querySelector('meta[name=\"csrf-token\"]');\n if (metaTag) {\n return metaTag.getAttribute('content');\n }\n\n // Try hidden input\n const hiddenInput = document.querySelector('input[name=\"csrf_token\"]');\n if (hiddenInput) {\n return hiddenInput.value;\n }\n\n // Try cookie\n const cookies = document.cookie.split(';');\n for (let cookie of cookies) {\n const [name, value] = cookie.trim().split('=');\n if (name === 'csrf_token') {\n return value;\n }\n }\n\n return '';\n }\n static showError(message) {\n // Check if there's an overlay error element\n const errorOverlay = document.getElementById('overlayError');\n if (errorOverlay) {\n const errorLabel = errorOverlay.querySelector('.error-message, #labelError');\n if (errorLabel) {\n errorLabel.textContent = message;\n }\n errorOverlay.classList.remove('hidden');\n errorOverlay.style.display = 'flex';\n } else {\n // Fallback to alert\n alert(message);\n }\n }\n static showSuccess(message) {\n // Could implement a toast notification here\n console.log('Success:', message);\n }\n static joinGame(gameId) {\n window.location.href = `${hashPageGame}/${gameId}`;\n }\n static async deleteGame(gameId) {\n if (!confirm('Are you sure you want to delete this game? This action cannot be undone.')) {\n return;\n }\n\n try {\n const gameData = {\n 'game_id': gameId,\n 'active': false\n };\n\n const response = await fetch(hashSaveGame, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-CSRFToken': PageMtgGames.getCSRFToken()\n },\n body: JSON.stringify({\n [flagGame]: [gameData],\n 'form-filters': {},\n 'comment': 'Game deleted'\n })\n });\n\n const result = await response.json();\n\n if (result.status === 'success') {\n // Remove the row from the table\n const row = document.querySelector(`tr[data-game-id=\"${gameId}\"]`);\n if (row) {\n row.style.animation = 'tcg-fadeOut 0.3s ease-out forwards';\n setTimeout(() => row.remove(), 300);\n }\n } else {\n PageMtgGames.showError(result.message || 'Failed to delete game');\n }\n } catch (error) {\n console.error('Error deleting game:', error);\n PageMtgGames.showError('An error occurred while deleting the game');\n }\n }\n\n toggleShowButtonsSaveCancel() {}\n leave() {\n super.leave();\n }\n}\n","\n\nimport API from \"../../api.js\";\nimport BasePage from \"../base.js\";\nimport DOM from \"../../dom.js\";\nimport Events from \"../../lib/events.js\";\n\nexport default class PageMtgHome extends BasePage {\n static hash = hashPageMtgHome;\n\n constructor(router) {\n super(router);\n }\n\n initialize() {\n this.sharedInitialize();\n this.hookupTcgHome();\n }\n\n hookupTcgHome() {\n }\n\n leave() {\n super.leave();\n }\n}\n","import BasePage from \"../base.js\";\n\nexport default class PageAccessibilityReport extends BasePage {\n static hash = hashPageAccessibilityReport;\n\n constructor(router) {\n super(router);\n }\n\n initialize() {\n this.sharedInitialize();\n }\n\n leave() {\n super.leave();\n }\n}\n","import BasePage from \"../base.js\";\n\nexport default class PageAccessibilityStatement extends BasePage {\n static hash = hashPageAccessibilityStatement;\n\n constructor(router) {\n super(router);\n }\n\n initialize() {\n this.sharedInitialize();\n }\n\n leave() {\n super.leave();\n }\n}\n","\nimport BasePage from \"../base.js\";\n\nexport default class PageLicense extends BasePage {\n static hash = hashPageLicense;\n\n constructor(router) {\n super(router);\n }\n\n initialize() {\n this.sharedInitialize();\n }\n\n leave() {\n super.leave();\n }\n}","\nimport BasePage from \"../base.js\";\n\nexport default class PagePrivacyPolicy extends BasePage {\n static hash = hashPagePrivacyPolicy;\n\n constructor(router) {\n super(router);\n }\n\n initialize() {\n this.sharedInitialize();\n }\n\n leave() {\n super.leave();\n }\n}","import BasePage from \"../base.js\";\n\nexport default class PageRetentionSchedule extends BasePage {\n static hash = hashPageDataRetentionSchedule;\n\n constructor(router) {\n super(router);\n }\n\n initialize() {\n this.sharedInitialize();\n }\n\n leave() {\n super.leave();\n }\n}\n","\n\nexport default class MixinPage {\n constructor(pageCurrent) {\n this.page = pageCurrent;\n }\n\n initialize() {\n Utils.consoleLogIfNotProductionEnvironment('hookup start for ', this.page.hash);\n this.hookupFilters();\n this.hookupLocalStorage();\n }\n hookupFilters() {\n }\n hookupLocalStorage() {\n \n }\n \n leave() {}\n}\n","\nimport MixinPage from \"./mixin.js\";\n\nexport default class TableMixinPage extends MixinPage {\n constructor(pageCurrent) {\n super(pageCurrent);\n }\n initialize() {\n super.initialize();\n this.hookupFilters();\n this.hookupTable();\n }\n hookupFilters() {\n // Implement filter-specific functionality here\n }\n hookupTable() {\n // Implement table-specific functionality here\n }\n}","\nimport API from \"../../api.js\";\nimport TableMixinPage from \"../mixin_table.js\";\nimport DOM from \"../../dom.js\";\nimport TableBasePage from \"../base_table.js\";\n\nexport default class PageUser extends TableBasePage {\n static hash = hashPageUserAccount;\n static attrIdRowObject = attrUserId;\n callSaveTableContent = API.saveUsers;\n\n constructor(router) {\n super(router);\n this.mixin = new TableMixinPage(this);\n }\n\n initialize() {\n this.sharedInitialize();\n this.hookupTableMain();\n }\n\n\n hookupFilters() {\n }\n\n loadRowTable(rowJson) {\n if (rowJson == null) return;\n if (_verbose) { Utils.consoleLogIfNotProductionEnvironment(\"applying data row: \", rowJson); }\n }\n getTableRecords(dirtyOnly = false) {\n dirtyOnly = true;\n let container = document.querySelector('.' + flagCard + '.' + flagUser);\n return [this.getJsonRow(container)];\n }\n getJsonRow(container) {\n console.log(\"getJsonRow: \", container);\n if (container == null) return;\n let inputFirstname = container.querySelector(' #' + flagFirstname);\n let inputSurname = container.querySelector(' #' + flagSurname);\n let inputEmail = container.querySelector(' #' + flagEmail);\n\n let idUser = container.getAttribute(attrUserId);\n \n let jsonRow = {\n [attrUserAuth0Id]: null\n , [flagEmail]: null\n , [flagIsEmailVerified]: null\n , [flagIsSuperUser]: null\n , [flagCanAdminUser]: null\n };\n\n jsonRow[attrUserId] = idUser;\n jsonRow[flagFirstname] = DOM.getElementAttributeValueCurrent(inputFirstname);\n jsonRow[flagSurname] = DOM.getElementAttributeValueCurrent(inputSurname);\n jsonRow[flagEmail] = DOM.getElementAttributeValueCurrent(inputEmail);\n return jsonRow;\n }\n \n initialiseRowNew(tbody, row) {\n }\n postInitialiseRowNewCallback(tbody) {\n }\n\n hookupTableMain() {\n super.hookupTableMain();\n this.hookupFieldsFirstname();\n this.hookupFieldsSurname();\n this.hookupFieldsEmail();\n }\n hookupFieldsFirstname() {\n this.hookupChangeHandlerTableCells('.' + flagCard + '.' + flagUser + ' #' + flagFirstname);\n }\n hookupFieldsSurname() {\n this.hookupChangeHandlerTableCells('.' + flagCard + '.' + flagUser + ' #' + flagSurname);\n }\n hookupFieldsEmail() {\n this.hookupChangeHandlerTableCells('.' + flagCard + '.' + flagUser + ' #' + flagEmail);\n }\n\n leave() {\n super.leave();\n }\n}\n","\nimport API from \"../../api\";\nimport TableMixinPage from \"../mixin_table\";\nimport DOM from \"../../dom\";\nimport TableBasePage from \"../base_table\";\nimport Utils from \"../../lib/utils\";\n\nexport default class PageUsers extends TableBasePage {\n static hash = hashPageUserAccounts;\n static attrIdRowObject = attrUserId;\n callSaveTableContent = API.saveUsers;\n\n constructor(router) {\n super(router);\n this.mixin = new TableMixinPage(this);\n }\n\n initialize() {\n this.sharedInitialize();\n }\n\n hookupFilters() {\n this.sharedHookupFilters();\n this.hookupFilterActive();\n }\n\n loadRowTable(rowJson) {\n if (rowJson == null) return;\n if (_verbose) { Utils.consoleLogIfNotProductionEnvironment(\"applying data row: \", rowJson); }\n }\n getJsonRow(row) {\n if (row == null) return;\n let inputFirstname = row.querySelector('td.' + flagFirstname + ' .' + flagFirstname);\n let inputSurname = row.querySelector('td.' + flagSurname + ' .' + flagSurname);\n let inputNotes = row.querySelector('td.' + flagNotes + ' .' + flagNotes);\n let buttonActive = row.querySelector('td.' + flagActive + ' .' + flagActive);\n\n let jsonRow = {\n [attrUserAuth0Id]: null\n , [flagEmail]: null\n , [flagIsEmailVerified]: null\n , [flagIsSuperUser]: null\n , [flagCanAdminUser]: null\n };\n jsonRow[attrUserId] = row.getAttribute(attrUserId);\n jsonRow[flagFirstname] = DOM.getElementAttributeValueCurrent(inputFirstname);\n jsonRow[flagSurname] = DOM.getElementAttributeValueCurrent(inputSurname);\n jsonRow[flagNotes] = DOM.getElementAttributeValueCurrent(inputNotes);\n jsonRow[flagActive] = buttonActive.classList.contains(flagDelete);\n\n console.log(\"jsonRow\");\n console.log(jsonRow);\n\n return jsonRow;\n }\n \n initialiseRowNew(tbody, row) {\n \n }\n postInitialiseRowNewCallback(tbody) {\n let newRows = tbody.querySelectorAll('tr.' + flagRowNew);\n let newestRow = newRows[0];\n let clickableElementsSelector = [].join('');\n newestRow.querySelectorAll(clickableElementsSelector).forEach((clickableElement) => {\n clickableElement.click();\n });\n }\n\n hookupTableMain() {\n super.hookupTableMain();\n this.hookupFieldsFirstname();\n this.hookupFieldsSurname();\n this.hookupFieldsNotesTable();\n this.hookupFieldsActive();\n }\n hookupFieldsFirstname() {\n this.hookupChangeHandlerTableCells(flagFirstname);\n }\n hookupFieldsSurname() {\n this.hookupChangeHandlerTableCells(flagSurname);\n }\n\n leave() {\n super.leave();\n }\n}\n","\n// Pages\n// Core\n// TCG\nimport PageMtgGame from './pages/tcg/mtg_game.js';\nimport PageMtgGames from './pages/tcg/mtg_games.js';\nimport PageMtgHome from './pages/tcg/mtg_home.js';\n// Legal\nimport PageAccessibilityReport from './pages/legal/accessibility_report.js';\nimport PageAccessibilityStatement from './pages/legal/accessibility_statement.js';\nimport PageLicense from './pages/legal/license.js';\nimport PagePrivacyPolicy from './pages/legal/privacy_policy.js';\nimport PageRetentionSchedule from './pages/legal/retention_schedule.js';\n// User\n// import PageUserLogin from './pages/user/login.js';\n// import PageUserLogout from './pages/user/logout.js';\nimport PageUser from './pages/user/user.js';\nimport PageUsers from './pages/user/users.js';\n\nimport API from './api.js';\nimport DOM from './dom.js';\nimport Utils from './lib/utils.js';\n\n\nexport default class Router {\n constructor() {\n // Pages\n this.pages = {};\n // Core\n // TCG\n this.pages[hashPageMtgGame] = { name: 'PageMtgGame', module: PageMtgGame };\n this.pages[hashPageMtgGames] = { name: 'PageMtgGames', module: PageMtgGames };\n this.pages[hashPageMtgHome] = { name: 'PageMtgGame', module: PageMtgHome };\n // Legal\n this.pages[hashPageAccessibilityStatement] = { name: 'PageAccessibilityStatement', module: PageAccessibilityStatement };\n this.pages[hashPageDataRetentionSchedule] = { name: 'PageDataRetentionSchedule', module: PageRetentionSchedule };\n this.pages[hashPageLicense] = { name: 'PageLicense', module: PageLicense };\n this.pages[hashPagePrivacyPolicy] = { name: 'PagePrivacyPolicy', module: PagePrivacyPolicy };\n // User\n // this.pages[hashPageUserLogin] = { name: 'PageUserLogin', module: PageUserLogin }; // pathModule: './pages/user/login.js' };\n // this.pages[hashPageUserLogout] = { name: 'PageUserLogout', module: PageUserLogout }; // pathModule: './pages/user/logout.js' };\n this.pages[hashPageUserAccount] = { name: 'PageUser', module: PageUser };\n this.pages[hashPageUserAccounts] = { name: 'PageUsers', module: PageUsers };\n // Routes\n this.routes = {};\n // Core\n // TCG\n this.routes[hashPageMtgGame] = (isPopState = false) => this.navigateToHash(hashPageMtgGame, isPopState);\n this.routes[hashPageMtgGames] = (isPopState = false) => this.navigateToHash(hashPageMtgGames, isPopState);\n this.routes[hashPageMtgHome] = (isPopState = false) => this.navigateToHash(hashPageMtgHome, isPopState);\n // Legal\n this.routes[hashPageAccessibilityStatement] = (isPopState = false) => this.navigateToHash(hashPageAccessibilityStatement, isPopState);\n this.routes[hashPageDataRetentionSchedule] = (isPopState = false) => this.navigateToHash(hashPageDataRetentionSchedule, isPopState);\n this.routes[hashPageLicense] = (isPopState = false) => this.navigateToHash(hashPageLicense, isPopState);\n this.routes[hashPagePrivacyPolicy] = (isPopState = false) => this.navigateToHash(hashPagePrivacyPolicy, isPopState);\n // User\n // this.routes[hashPageUserLogin] = (isPopState = false) => this.navigateToHash(hashPageUserLogin, isPopState);\n // this.routes[hashPageUserLogout] = (isPopState = false) => this.navigateToHash(hashPageUserLogout, isPopState);\n this.routes[hashPageUserAccount] = (isPopState = false) => this.navigateToHash(hashPageUserAccount, isPopState);\n this.routes[hashPageUserAccounts] = (isPopState = false) => this.navigateToHash(hashPageUserAccounts, isPopState);\n this.initialize();\n }\n loadPage(hashPage, isPopState = false) {\n const PageClass = this.getClassPageFromHash(hashPage);\n this.currentPage = new PageClass(this);\n this.currentPage.initialize(isPopState);\n window.addEventListener('beforeunload', () => this.currentPage.leave());\n }\n getClassPageFromHash(hashPage) {\n \n let pageJson = this.pages[hashPage];\n try {\n const module = pageJson.module;\n return module; \n }\n catch (error) {\n Utils.consoleLogIfNotProductionEnvironment(\"this.pages: \", this.pages);\n console.error('Page not found:', hashPage);\n throw error;\n }\n }\n initialize() {\n window.addEventListener('popstate', this.handlePopState.bind(this));\n }\n handlePopState(event) {\n this.loadPageCurrent();\n }\n loadPageCurrent() {\n const hashPageCurrent = DOM.getHashPageCurrent();\n this.loadPage(hashPageCurrent);\n }\n navigateToHash(hash, data = null, params = null, isPopState = false) {\n let url = API.getUrlFromHash(hash, params);\n history.pushState({data: data, params: params}, '', hash);\n API.goToUrl(url, data);\n }\n \n navigateToUrl(url, data = null, appendHistory = true) {\n // this.beforeLeave();\n if (appendHistory) history.pushState(data, '', url);\n url = API.parameteriseUrl(url, data);\n API.goToUrl(url);\n }\n\n static loadPageBodyFromResponse(response) {\n DOM.loadPageBody(response.data);\n }\n}\n\nexport const router = new Router();\n","\n'use strict';\n\nimport DOM from './dom.js';\nimport Router from './router.js';\n\n\nclass App {\n constructor() {\n this.dom = new DOM();\n this.router = new Router();\n }\n\n initialize() {\n this.setupEventListeners();\n this.start();\n }\n\n setupEventListeners() {\n // document.addEventListener('click', this.handleGlobalClick.bind(this));\n }\n\n handleGlobalClick(event) {\n }\n\n start() {\n this.initPageCurrent();\n }\n\n initPageCurrent() {\n this.router.loadPageCurrent();\n }\n \n}\n\nconst app = new App();\n\nfunction domReady(fn) {\n if (document.readyState !== 'loading') {\n fn();\n } else {\n document.addEventListener('DOMContentLoaded', fn);\n }\n}\n\ndomReady(() => {\n app.initialize();\n});\n\nwindow.app = app;\n\nexport default app;","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};"],"names":["Validation","isEmpty","object","undefined","length","isString","trim","i","isValidNumber","value","positiveOnly","isNaN","parseFloat","getDataContentType","params","data","contentType","JSON","stringify","Data","ContentType","arrayContainsItem","array","itemValue","hasItem","isJQueryElementArray","jQuery","document","querySelectorAll","is","isDate","Date","getTime","dictHasKey","d","k","areEqualDicts","dict1","dict2","keys1","Object","keys","keys2","key","imageExists","url","callback","img","Image","onload","onerror","src","toFixedOrDefault","decimalPlaces","defaultValue","toFixed","Utils","DOM","setElementAttributesValuesCurrentAndPrevious","element","setElementAttributeValueCurrent","setElementAttributeValuePrevious","setAttribute","attrValueCurrent","attrValuePrevious","setElementValuesCurrentAndPrevious","setElementValueCurrent","tagName","toUpperCase","type","checked","textContent","setElementValueCurrentIfEmpty","getElementValueCurrent","getCellFromElement","closest","getRowFromElement","flagRow","selector","getClosestParent","parentSelector","parent","parentElement","matches","convertForm2JSON","elementForm","dataForm","containersFilter","flagContainerInput","flagFilter","containerFilter","labelFilter","keyFilter","filter","indexFilter","querySelector","getAttribute","loadPageBody","contentNew","pageBody","idPageBody","innerHTML","getHashPageCurrent","hashPageCurrent","body","dataset","page","updateAndCheckIsElementDirty","isElementDirty","isDirty","handleDirtyElement","toggleElementHasClassnameFlag","flagDirty","elementHasFlag","flag","elementAlreadyHasFlag","classList","contains","add","remove","hasDirtyChildrenContainer","container","hasDirtyChildrenNotDeletedContainer","flagDelete","returnVal","flagButton","flagActive","getElementAttributeValueCurrent","flagCheckbox","flagIsChecked","getElementAttributeValuePrevious","scrollToElement","scrollTop","offset","top","isElementInContainer","containerBounds","getBoundingClientRect","elementBounds","left","height","width","alertError","errorType","errorText","alert","createOptionUnselectedProductVariation","flagProductVariationType","flagNameAttrOptionText","flagName","flagNameAttrOptionValue","attrIdProductVariationType","flagProductVariation","attrIdProductVariation","createOption","optionJson","text","option","createElement","selected","escapeHtml","div","unescapeHtml","html","innerText","API","getCsrfToken","idCSRFToken","request","hashEndpoint","method","getUrlFromHash","csrfToken","options","headers","flagCsrfToken","response","fetch","ok","Error","status","json","error","console","hash","hashPageHome","parameteriseUrl","_pathHost","URLSearchParams","toString","goToUrl","window","location","href","goToHash","loginUser","flagCallback","hashPageUserLogin","saveUsers","users","formFilters","comment","dataRequest","flagFormFilters","flagUser","flagComment","hashSaveUserUser","saveGame","game","flagGame","hashSaveGame","getGamePlayers","gameId","saveGamePlayers","players","flagPlayer","hashSaveGamePlayer","getGameRounds","getGameDamageRecords","saveGameRoundPlayerDamages","rounds","damages","flagDamage","flagRound","hashSaveGameRoundPlayerDamage","BusinessObjects","getOptionJsonFromObjectJsonAndKeys","objectJson","keyText","keyValue","valueSelected","getOptionJsonFromObjectJson","getObjectText","getListObjectsFromIdDictAndCsv","idDict","idCsv","listObjects","ids","split","id","push","Events","initialiseEventHandler","selectorElement","classInitialised","eventHandler","forEach","hookupEventHandler","eventType","flagInitialised","addEventListener","event","stopPropagation","LocalStorage","getLocalStorage","parse","localStorage","getItem","setLocalStorage","newLS","setItem","getListFromDict","dict","list","consoleLogIfNotProductionEnvironment","message","environment","is_production","log","OverlayConfirm","hookup","callbackSuccess","idOverlayConfirm","flagCancel","buttonCancel","overlay","style","visibility","flagSubmit","buttonConfirm","textarea","show","flagIsCollapsed","OverlayError","BasePage","constructor","router","title","titlePageCurrent","name","initialize","sharedInitialize","logInitialisation","hookupCommonElements","hookupLogos","hookupNavigation","hookupOverlays","flagImageLogo","flagLogo","navigateToHash","idButtonHamburger","overlayHamburger","idOverlayHamburger","flagExpanded","hookupButtonsNavUserAccount","hookupButtonsNavUserLogout","hookupButtonsNavUserLogin","hookupButtonsNav","buttonSelector","button","pageHash","flagNavUserLogin","navigator","preventDefault","leave","then","Success","Message","hookupOverlayFromId","idOverlayError","idOverlay","display","hookupButtonSave","flagContainer","flagSave","target","setLocalStoragePage","dataPage","getLocalStoragePage","toggleShowButtonsSaveCancel","buttonContainerSelector","buttonSave","idButtonSave","idButtonCancel","isDirtyFilter","idTableMain","msgError","labelError","idLabelError","TableBasePage","cursorYInitial","rowInitial","placeholder","dragSrcEl","dragSrcRow","hookupTableCellDdls","bind","isPopState","isSinglePageApp","hookupFilters","hookupButtonsSaveCancel","hookupTableMain","saveRecordsTableDirtySinglePageApp","saveRecordsTableDirty","filters","getFormFilters","filtersDefault","callFilterTableContent","sharedHookupFilters","hookupButtonApplyFilters","hookupSearchTextFilter","hookupFilterActive","filterSelector","idFormFilters","flagActiveOnly","filterActiveOld","removeAttribute","parentDiv","isChecked","filterActiveNew","filterActive","svgElement","wasChecked","handleChangeFilter","filterValuePrevious","hookupFilter","filterFlag","handler","areDirtyFilters","tbody","rows","row","dirtyInputs","dirtyInput","isDirtyLabel","initialisedElements","initialisedElement","updateAndToggleShowButtonsSaveCancel","hookupFilterIsNotEmpty","flagIsNotEmpty","idButtonApplyFilters","flagSearch","hookupFilterCommandCategory","attrIdCommandCategory","filterCommandCategory","idCommandCategory","filterCommands","commandsInCategory","command","sortedCommands","sort","a","b","localeCompare","filterCommand","flagCommand","idCommandPrevious","appendChild","dispatchEvent","Event","hookupFilterCommand","attrIdCommand","hookupFilterLocation","attrIdLocation","filtersJson","callbackLoadTableContent","table","getTableMain","bodyTable","rowsJson","flagRows","every","hasOwnProperty","display_order","loadRowTable","rowJson","getAndLoadFilteredTableContentSinglePageApp","catch","hookupButtonCancel","records","getTableRecords","formElement","idTextareaConfirm","callSaveTableContent","flagStatus","flagSuccess","_verbose","flagMessage","dirtyOnly","record","getJsonRow","handleClickAddRowTable","_rowBlank","attrIdRowObject","cloneNode","countRows","initialiseRowNew","prepend","postInitialiseRowNewCallback","cacheRowBlank","selectorRowNew","flagRowNew","rowBlankTemp","initialiseSliderDisplayOrderRowNew","slidersDisplayOrder","flagDisplayOrder","flagSlider","maxDisplayOrder","slider","Math","max","sliderDisplayOrder","hookupSlidersDisplayOrderTable","selectorDisplayOrder","hookupChangeHandlerTableCells","inputSelector","handleChangeNestedElementCellTable","input","wasDirtyParentRows","getAllIsDirtyRowsInParentTree","wasDirtyElement","isDirtyElement","cascadeChangedIsDirtyNestedElementCellTable","tr","isDirtyRow","wasDirtyRow","shift","hookupChangeHandlerTableCellsWhenNotCollapsed","hookupFieldsCodeTable","flagCode","hookupFieldsNameTable","hookupFieldsDescriptionTable","flagDescription","hookupFieldsNotesTable","flagNotes","hookupFieldsActive","flagTable","handleClickRowNew","selectorButton","selectorButtonDelete","selectorButtonUndelete","hookupButtonsRowDelete","hookupButtonsRowUndelete","changeHandler","handleClickButtonRowDelete","changeEvent","changeElement","valuePrevious","wasDirty","parentNode","removeChild","buttonAddTemplate","idContainerTemplateElements","flagAdd","buttonAdd","replaceWith","handleClickButtonRowUndelete","buttonDeleteTemplate","buttonDelete","hookupTdsAccessLevel","hookupTableCellDdlPreviews","flagAccessLevel","accessLevels","fieldFlag","optionList","cellSelector","ddlHookup","ddlSelector","handleClickTableCellDdlPreview","optionObjectList","idSelected","td","ddl","optionObjectJson","toggleColumnCollapsed","flagColumn","isCollapsed","toggleColumnHasClassnameFlag","toggleColumnHeaderCollapsed","hookupFieldsCommandCategory","idTable","flagCommandCategory","filterCommandCategories","hookupCommandCategoryDdls","handleChangeCommandCategoryDdl","ddlCategory","idCommandCategoryRowOld","getIdCommandCategoryRow","idCommandCategoryRowNew","idCommandCategoryFilter","getIdCommandCategoryFilter","tdCommand","ddlCommand","hookupFieldsCommand","parentTr","tdCommandCategory","idCommandCategoryRow","filterCommandList","handleChangeCommandDdl","idCommandNew","getIdCommandRow","commandNew","divCommandCategory","ddlCommandCategory","elementCommandCategory","commandCategoryFilter","commandFilter","valueCurrentCommandCategoryFilter","valueCurrentCommandFilter","Number","getHasCommandCategoryFilter","elementCommand","getIdCommandFilter","idCommand","getHasCommandFilter","idCommandFilter","columnFlag","isRequiredFlag","classnameFlag","columnTh","columnThHasFlag","toggleColumnHeaderHasClassnameFlag","PageMtgGame","hashPageMtgGame","attrGameId","hookupTcgGame","initGamePage","pageHeading","updatePlayerSetup","loadGameFromServer","hookupResetButton","hookupPlayerCountInput","hookupStartGameButton","resetGameButton","resetGame","playerCountInput","getElementById","startGameButton","startGame","playersResponse","roundsResponse","damageResponse","Promise","all","setupSection","gameSection","savedPlayers","savedRounds","savedDamageRecords","damageRecords","latestRoundId","getLatestRoundId","latestRound","round","attrRoundId","roundDisplayOrderLabel","getRoundDisplayOrderLabel","renderPlayers","join","grid","activeRoundId","getActiveRoundId","currentRoundDisplayOrder","makeDefaultGameRound","player","index","playerId","attrPlayerId","displayName","makePlayerDisplayName","damagePlayerPairs","maxCommanderDamageReceived","damagePlayerPair","sourceId","filteredPlayerDamages","damage","attrReceivedFromCommanderPlayerId","makeDefaultGameRoundPlayerDamage","map","flagHealthChange","reduce","acc","curr","totalDamage","life","startingLife","isEliminatedByForce","flagIsEliminated","some","Boolean","isEliminated","playerOwnDamage","card","className","animationDelay","userName","user_name","deckName","deck_name","flagCommanderDeaths","renderCommanderDamageRows","attrDeckId","reorderPlayerCards","renderCommanderDamageLog","hookupGameRoundEvents","hookupPlayerCardEvents","damageTableBody","flagDamageLog","newTableBodyHtml","r","p","receivedFromPlayer","attrDamageId","receivedFromCommanderPlayerId","roundId","highestRoundDisplayOrder","cur","filteredRounds","deckId","deck","decks","user","attrUserId","otherPlayer","otherPlayerDisplayName","isLethal","incrementRoundButtonSelector","flagRoundDisplayOrderButton","amount","flagRoundDisplayOrderPlus","roundDisplayOrderButtonContainer","newDisplayOrder","displayOrder","lifeButtonSelector","parseInt","damageIndex","findIndex","changeLife","commanderDeathButtonSelector","isMinusButton","changeCommanderDeaths","commmanderDamageButtonSelector","changeCommanderDamage","eliminatePlayerButtonSelector","toggleEliminate","updateDamage","lifeInput","lifeDisplay","currentLife","newLife","damageInput","damageDisplay","currentDamage","newDamage","damageRecord","deathDisplay","currentDeaths","newDeaths","eliminateBtn","wasEliminated","playerGrid","currentPlayerCards","newPlayerCards","playerCardMetas","playerCard","newPlayerGridInnerHTML","playerIdA","playerIdB","isEliminatedAsIntA","isEliminatedAsIntB","playerA","playerB","indexPlayerCard","isPlayerEliminated","playerCardMeta","outerHTML","hasDamageWithIsEliminated","damageFromOtherPlayers","otherPlayerId","maxDamageFromOtherCommander","totalDamageTaken","playerCount","wrapperTemplate","playerSetupWrapperTemplateId","wrapper","wrapperHeading","userDdl","deckDdl","nameInput","makeDefaultGamePlayer","playersToSave","playerSetupWrapper","userId","self","reload","showError","finally","confirm","removeItem","hashPageGames","errorOverlay","errorLabel","_saveTimeout","PageMtgGames","hashPageMtgGames","hookupTcgGames","initGamesPage","newGameForm","handleNewGameSubmit","filterForm","handleFilterSubmit","e","hideNewGameForm","modal","newGameButton","showNewGameForm","cancelNewGameButtons","overflow","firstInput","focus","form","reset","formData","FormData","gameType","get","gameData","flagIsCommander","flagIsDraft","flagIsSealed","flagLocationName","flagStartOn","toISOString","flagStartingLife","submitBtn","originalText","disabled","games","gamePageHash","hashPageGame","getCSRFToken","metaTag","hiddenInput","cookies","cookie","showSuccess","joinGame","deleteGame","result","animation","setTimeout","PageMtgHome","hashPageMtgHome","hookupTcgHome","PageAccessibilityReport","hashPageAccessibilityReport","PageAccessibilityStatement","hashPageAccessibilityStatement","PageLicense","hashPageLicense","PagePrivacyPolicy","hashPagePrivacyPolicy","PageRetentionSchedule","hashPageDataRetentionSchedule","MixinPage","pageCurrent","hookupLocalStorage","TableMixinPage","hookupTable","PageUser","hashPageUserAccount","mixin","flagCard","inputFirstname","flagFirstname","inputSurname","flagSurname","inputEmail","flagEmail","idUser","jsonRow","attrUserAuth0Id","flagIsEmailVerified","flagIsSuperUser","flagCanAdminUser","hookupFieldsFirstname","hookupFieldsSurname","hookupFieldsEmail","PageUsers","hashPageUserAccounts","inputNotes","buttonActive","newRows","newestRow","clickableElementsSelector","clickableElement","click","Router","pages","module","routes","loadPage","hashPage","PageClass","getClassPageFromHash","currentPage","pageJson","handlePopState","loadPageCurrent","history","pushState","navigateToUrl","appendHistory","loadPageBodyFromResponse","App","dom","setupEventListeners","start","handleGlobalClick","initPageCurrent","app","domReady","fn","readyState"],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"js/main.bundle.js","mappings":"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","sources":["webpack://app/./static/js/lib/validation.js","webpack://app/./static/js/dom.js","webpack://app/./static/js/api.js","webpack://app/./static/js/lib/business_objects/business_objects.js","webpack://app/./static/js/lib/events.js","webpack://app/./static/js/lib/local_storage.js","webpack://app/./static/js/lib/utils.js","webpack://app/./static/js/components/common/temporary/overlay_confirm.js","webpack://app/./static/js/pages/base.js","webpack://app/./static/js/components/common/temporary/overlay_error.js","webpack://app/./static/js/pages/base_table.js","webpack://app/./static/js/pages/tcg/mtg_decks.js","webpack://app/./static/js/pages/tcg/mtg_game.js","webpack://app/./static/js/pages/tcg/mtg_games.js","webpack://app/./static/js/pages/tcg/mtg_home.js","webpack://app/./static/js/pages/legal/accessibility_report.js","webpack://app/./static/js/pages/legal/accessibility_statement.js","webpack://app/./static/js/pages/legal/license.js","webpack://app/./static/js/pages/legal/privacy_policy.js","webpack://app/./static/js/pages/legal/retention_schedule.js","webpack://app/./static/js/pages/mixin.js","webpack://app/./static/js/pages/mixin_table.js","webpack://app/./static/js/pages/user/user.js","webpack://app/./static/js/pages/user/users.js","webpack://app/./static/js/router.js","webpack://app/./static/js/app.js","webpack://app/./static/css/main.css?0a91","webpack://app/./static/css/components/button.css?0e0b","webpack://app/./static/css/components/card.css","webpack://app/./static/css/components/dialog.css","webpack://app/./static/css/components/form.css?94e1","webpack://app/./static/css/components/image.css?9f9c","webpack://app/./static/css/components/label.css?b78f","webpack://app/./static/css/components/modal.css","webpack://app/./static/css/components/navigation.css","webpack://app/./static/css/components/overlay.css?6dfd","webpack://app/./static/css/components/table.css?e553","webpack://app/./static/css/layouts/header.css?da75","webpack://app/./static/css/layouts/footer.css?65e3","webpack://app/./static/css/layouts/table-main.css?8c15","webpack://app/./static/css/lib/reset.css","webpack://app/./static/css/lib/typography.css","webpack://app/./static/css/lib/utils.css","webpack://app/./static/css/lib/variables.css","webpack://app/./static/css/themes/dark.css?0cc3"],"sourcesContent":["\nexport default class Validation {\n /*\n isNullOrWhitespace(v) {\n let txt = JSON.stringify(v).replace('/\\s\\g', '');\n return (txt == '' || 'null');\n }\n */\n\n static isEmpty(object) {\n\n let isEmpty = true;\n\n if (object !== null && object !== \"null\" && object !== undefined && object !== \"undefined\") {\n\n if (object.length == undefined) {\n isEmpty = false; // object exists but isn't a collection\n }\n else if (typeof object === \"function\") {\n isEmpty = false; // object is reference\n }\n else { // string or collection\n\n let isString = (typeof object == \"string\");\n\n if (isString) object = object.trim();\n\n if (object.length > 0) {\n\n if (isString) {\n isEmpty = false; // String greater than length 0\n }\n else {\n\n if (typeof object[0] != \"string\") {\n isEmpty = false;\n }\n else {\n for(let i = 0; i < object.length; i++) {\n if (object[i] != \"\") {\n isEmpty = false;\n break\n }\n }\n }\n }\n }\n }\n }\n\n return isEmpty;\n }\n\n static isValidNumber(value, positiveOnly) {\n return !Validation.isEmpty(value) && !isNaN(value) && (!positiveOnly || parseFloat(value) > 0);\n }\n\n static getDataContentType(params) {\n\n var data = null;\n var contentType = '';\n\n if (!Validation.isEmpty(params)) {\n\n if (typeof params === \"string\") {\n data = params;\n contentType = \"application/x-www-form-urlencoded; charset=UTF-8\";\n }\n else {\n data = JSON.stringify(params);\n contentType = \"application/json; charset=UTF-8\";\n }\n }\n\n return { Data: data, ContentType: contentType };\n }\n\n static arrayContainsItem(array, itemValue) {\n\n var hasItem = false;\n\n if (!Validation.isEmpty(array) && !Validation.isEmpty(itemValue)) {\n\n var isJQueryElementArray = array[0] instanceof jQuery;\n\n if (isJQueryElementArray) {\n\n for (let i = 0; i < array.length; i++) {\n\n if (document.querySelectorAll(array[i]).is(itemValue)) {\n hasItem = true;\n break;\n }\n }\n }\n else {\n\n var isDate = array[0] instanceof Date;\n\n if (isDate) {\n \n for (let i = 0; i < array.length; i++) {\n\n if (array[i].getTime() === itemValue.getTime()) {\n hasItem = true;\n break;\n }\n }\n }\n else {\n\n for (let i = 0; i < array.length; i++) {\n\n if (array[i] == itemValue) {\n hasItem = true;\n break;\n }\n }\n }\n }\n }\n\n return hasItem;\n }\n\n static dictHasKey(d, k) {\n return (k in d);\n }\n static areEqualDicts(dict1, dict2) {\n const keys1 = Object.keys(dict1);\n const keys2 = Object.keys(dict2);\n \n if (keys1.length !== keys2.length) {\n return false;\n }\n \n for (let key of keys1) {\n if (dict1[key] !== dict2[key]) {\n return false;\n }\n }\n \n return true;\n }\n\n static imageExists(url, callback) {\n\n var img = new Image();\n\n img.onload = function() { callback(true); };\n img.onerror = function() { callback(false); };\n img.src = url;\n }\n\n static toFixedOrDefault(value, decimalPlaces, defaultValue = null) {\n return Validation.isValidNumber(value) ? parseFloat(value).toFixed(decimalPlaces) : defaultValue;\n }\n}\n","\nimport Utils from \"./lib/utils.js\";\nimport Validation from \"./lib/validation.js\";\n\nexport default class DOM {\n static setElementAttributesValuesCurrentAndPrevious(element, data) {\n DOM.setElementAttributeValueCurrent(element, data);\n DOM.setElementAttributeValuePrevious(element, data);\n }\n static setElementAttributeValueCurrent(element, data) {\n element.setAttribute(attrValueCurrent, data);\n }\n static setElementAttributeValuePrevious(element, data) {\n element.setAttribute(attrValuePrevious, data);\n }\n static setElementValuesCurrentAndPrevious(element, data) {\n DOM.setElementValueCurrent(element, data);\n DOM.setElementAttributeValuePrevious(element, data);\n }\n static setElementValueCurrent(element, data) {\n DOM.setElementAttributeValueCurrent(element, data);\n let tagName = element.tagName.toUpperCase();\n if (element.type === \"checkbox\") {\n element.checked = data;\n }\n else if (tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT') {\n element.value = data;\n }\n else {\n element.textContent = data;\n }\n }\n static setElementValueCurrentIfEmpty(element, data) {\n if (Validation.isEmpty(DOM.getElementValueCurrent(element))) {\n DOM.setElementValueCurrent(element, data);\n }\n }\n static getCellFromElement(element) {\n return element.closest('td');\n }\n static getRowFromElement(element, flagRow) {\n let selector = Validation.isEmpty(flagRow) ? 'tr' : 'tr.' + flagRow;\n return element.closest(selector);\n }\n static getClosestParent(element, parentSelector) {\n let parent = element.parentElement;\n while (parent) {\n if (parent.matches(parentSelector)) {\n return parent;\n }\n parent = parent.parentElement;\n }\n return null;\n }\n static convertForm2JSON(elementForm) {\n let dataForm = {};\n if (Validation.isEmpty(elementForm)) {\n return dataForm;\n }\n let containersFilter = elementForm.querySelectorAll('.' + flagContainerInput + '.' + flagFilter);\n let containerFilter, labelFilter, keyFilter, filter;\n for (let indexFilter = 0; indexFilter < containersFilter.length; indexFilter++) {\n containerFilter = containersFilter[indexFilter];\n labelFilter = containerFilter.querySelector('label');\n keyFilter = labelFilter.getAttribute('for');\n filter = containerFilter.querySelector(`#${keyFilter}`);\n dataForm[keyFilter] = DOM.getElementValueCurrent(filter);\n }\n return dataForm;\n }\n static loadPageBody(contentNew) {\n let pageBody = document.querySelector(idPageBody);\n pageBody.innerHTML = contentNew;\n }\n static getHashPageCurrent() {\n const hashPageCurrent = document.body.dataset.page;\n return hashPageCurrent;\n }\n static updateAndCheckIsElementDirty(element) {\n element.setAttribute(attrValueCurrent, DOM.getElementValueCurrent(element));\n return DOM.isElementDirty(element);\n }\n static isElementDirty(element) {\n let isDirty = element.getAttribute(attrValuePrevious) != element.getAttribute(attrValueCurrent);\n DOM.handleDirtyElement(element, isDirty);\n return isDirty;\n }\n static handleDirtyElement(element, isDirty) {\n DOM.toggleElementHasClassnameFlag(element, isDirty, flagDirty);\n }\n static toggleElementHasClassnameFlag(element, elementHasFlag, flag) {\n let elementAlreadyHasFlag = element.classList.contains(flag);\n if (elementHasFlag == elementAlreadyHasFlag) return;\n if (elementHasFlag) {\n element.classList.add(flag);\n } else {\n element.classList.remove(flag);\n }\n }\n static hasDirtyChildrenContainer(container) {\n if (container == null) return false;\n return container.querySelector('.' + flagDirty) != null;\n }\n static hasDirtyChildrenNotDeletedContainer(container) {\n if (container == null || container.classList.contains(flagDelete)) return false;\n return container.querySelector('.' + flagDirty + ':not(.' + flagDelete + ', .' + flagDelete + ' *)') != null;\n }\n static getElementValueCurrent(element) {\n let returnVal = '';\n \n if (!Validation.isEmpty(element)) {\n \n let tagName = element.tagName.toUpperCase();\n if (element.type === \"checkbox\") {\n returnVal = element.checked;\n }\n /*\n else if (element.classList.contains(flagIsDatePicker)) {\n returnVal = getDatePickerDate(element, adjust4DayLightSavings);\n }\n */\n else if (tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT') {\n returnVal = element.value;\n }\n else if (element.classList.contains(flagButton) && element.classList.contains(flagActive)) { // tagName === 'BUTTON'\n returnVal = element.classList.contains(flagDelete);\n }\n else if (tagName === 'TD') {\n returnVal = DOM.getElementAttributeValueCurrent(element);\n }\n else if (tagName == 'SVG' && element.classList.contains(flagCheckbox)) {\n returnVal = (element.classList.contains(flagIsChecked))\n }\n else {\n returnVal = element.textContent;\n }\n }\n \n if (Validation.isEmpty(returnVal)) returnVal = '';\n \n return returnVal;\n }\n static getElementAttributeValueCurrent(element) {\n if (Validation.isEmpty(element)) return null;\n return element.getAttribute(attrValueCurrent);\n }\n static getElementAttributeValuePrevious(element) {\n if (Validation.isEmpty(element)) return null;\n return element.getAttribute(attrValuePrevious);\n }\n /* base_table.handleChangeElementCellTable\n static updateAndCheckIsTableElementDirty(element) {\n let wasDirty = DOM.isElementDirty(element);\n let row = DOM.getRowFromElement(element);\n let wasDirtyRow = DOM.hasDirtyChildrenNotDeletedContainer(row);\n let isDirty = DOM.updateAndCheckIsElementDirty(element);\n let cell = DOM.getCellFromElement(element);\n Utils.consoleLogIfNotProductionEnvironment({element, row, cell, isDirty, wasDirty});\n if (isDirty != wasDirty) {\n DOM.handleDirtyElement(cell, isDirty);\n let isDirtyRow = DOM.hasDirtyChildrenNotDeletedContainer(row);\n Utils.consoleLogIfNotProductionEnvironment({isDirtyRow, wasDirtyRow});\n if (isDirtyRow != wasDirtyRow) {\n DOM.handleDirtyElement(row, isDirtyRow);\n }\n }\n }\n */\n static scrollToElement(parent, element) {\n // REQUIRED: parent has scroll-bar\n parent.scrollTop(parent.scrollTop() + (element.offset().top - parent.offset().top));\n }\n static isElementInContainer(container, element) {\n\n if (typeof jQuery === 'function') {\n if (container instanceof jQuery) container = container[0];\n if (element instanceof jQuery) element = element[0];\n }\n\n var containerBounds = container.getBoundingClientRect();\n var elementBounds = element.getBoundingClientRect();\n\n return (\n containerBounds.top <= elementBounds.top &&\n containerBounds.left <= elementBounds.left &&\n ((elementBounds.top + elementBounds.height) <= (containerBounds.top + containerBounds.height)) &&\n ((elementBounds.left + elementBounds.width) <= (containerBounds.left + containerBounds.width))\n );\n }\n static alertError(errorType, errorText) {\n alert(errorType + '\\n' + errorText);\n }\n static createOptionUnselectedProductVariation() {\n return {\n [flagProductVariationType]: {\n [flagNameAttrOptionText]: [flagName],\n [flagNameAttrOptionValue]: [attrIdProductVariationType],\n [flagName]: 'Select Variation Type',\n [attrIdProductVariationType]: 0,\n },\n [flagProductVariation]: {\n [flagNameAttrOptionText]: [flagName],\n [flagNameAttrOptionValue]: [attrIdProductVariation],\n [flagName]: 'Select Variation',\n [attrIdProductVariation]: 0,\n },\n };\n }\n static createOption(optionJson) {\n if (Validation.isEmpty(optionJson)) optionJson = {\n text: 'Select',\n value: 0,\n };\n let option = document.createElement('option');\n option.value = optionJson.value;\n option.textContent = optionJson.text;\n option.selected = optionJson.selected;\n return option;\n }\n\n static escapeHtml(text) {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n }\n static unescapeHtml(html) {\n const div = document.createElement('div');\n div.innerHTML = html;\n return div.textContent || div.innerText || '';\n }\n}\n","import DOM from './dom.js';\n\nexport default class API {\n \n static getCsrfToken() {\n return document.querySelector(idCSRFToken).getAttribute('content');\n }\n \n static async request(hashEndpoint, method = 'GET', data = null, params = null) {\n const url = API.getUrlFromHash(hashEndpoint, params);\n const csrfToken = API.getCsrfToken();\n const options = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n [flagCsrfToken]: csrfToken,\n }\n };\n\n if (data && (method === 'POST' || method === 'PUT' || method === 'PATCH')) {\n data = { \n ...data, \n [flagCsrfToken]: csrfToken,\n };\n options.body = JSON.stringify(data);\n }\n\n try {\n const response = await fetch(url, options);\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n return await response.json();\n } catch (error) {\n console.error('API request failed:', error);\n throw error;\n }\n }\n \n static getUrlFromHash(hash, params = null) {\n if (hash == null) hash = hashPageHome;\n let url = API.parameteriseUrl(_pathHost + hash, params);\n return url;\n }\n static parameteriseUrl(url, params) {\n if (params) {\n url += '?' + new URLSearchParams(params).toString();\n }\n return url;\n }\n static goToUrl(url) {\n window.location.href = url;\n }\n static goToHash(hash, params = null) {\n const url = API.getUrlFromHash(hash, params);\n API.goToUrl(url);\n }\n\n // specific api calls\n /* Example:\n getUsers: () => request('/users'),\n getUserById: (id) => request(`/users/${id}`),\n createUser: (userData) => request('/users', 'POST', userData),\n updateUser: (id, userData) => request(`/users/${id}`, 'PUT', userData),\n deleteUser: (id) => request(`/users/${id}`, 'DELETE'),\n */\n\n // User\n // user\n static async loginUser() {\n let callback = {};\n callback[flagCallback] = DOM.getHashPageCurrent();\n return await API.request(hashPageUserLogin, 'POST', callback);\n }\n static async saveUsers(users, formFilters, comment) {\n let dataRequest = {};\n dataRequest[flagFormFilters] = DOM.convertForm2JSON(formFilters);\n dataRequest[flagUser] = users;\n dataRequest[flagComment] = comment;\n return await API.request(hashSaveUserUser, 'POST', dataRequest);\n }\n\n // MTG Game API methods\n static async saveGame(game, formFilters, comment) {\n let dataRequest = {};\n dataRequest[flagFormFilters] = DOM.convertForm2JSON(formFilters);\n dataRequest[flagGame] = game;\n dataRequest[flagComment] = comment;\n return await API.request(hashSaveGame, 'POST', dataRequest);\n }\n\n static async getGamePlayers(gameId) {\n const url = `/mtg/api/game/${gameId}/players`;\n return await API.request(url, 'GET');\n }\n static async saveGamePlayers(players, formFilters, comment) {\n let dataRequest = {};\n dataRequest[flagFormFilters] = DOM.convertForm2JSON(formFilters);\n dataRequest[flagPlayer] = players;\n dataRequest[flagComment] = comment;\n return await API.request(hashSaveGamePlayer, 'POST', dataRequest);\n }\n\n static async getGameRounds(gameId) {\n const url = `/mtg/api/game/${gameId}/rounds`;\n return await API.request(url, 'GET');\n }\n\n static async getGameDamageRecords(gameId) {\n const url = `/mtg/api/game/${gameId}/damage-records`;\n return await API.request(url, 'GET');\n }\n static async saveGameRoundPlayerDamages(rounds, damages, formFilters, comment) {\n let dataRequest = {};\n dataRequest[flagFormFilters] = DOM.convertForm2JSON(formFilters);\n dataRequest[flagDamage] = damages;\n dataRequest[flagRound] = rounds;\n dataRequest[flagComment] = comment;\n return await API.request(hashSaveGameRoundPlayerDamage, 'POST', dataRequest);\n }\n\n\n}\n","\nimport Utils from '../utils.js';\n\nexport default class BusinessObjects {\n static getOptionJsonFromObjectJsonAndKeys(objectJson, keyText, keyValue, valueSelected = null) {\n return {\n text: objectJson[keyText],\n value: objectJson[keyValue],\n selected: (objectJson[keyValue] == valueSelected),\n };\n }\n static getOptionJsonFromObjectJson(objectJson, valueSelected = null) {\n let keyText = objectJson[flagNameAttrOptionText];\n let keyValue = objectJson[flagNameAttrOptionValue];\n // Utils.consoleLogIfNotProductionEnvironment({objectJson, keyText, keyValue});\n return BusinessObjects.getOptionJsonFromObjectJsonAndKeys(objectJson, keyText, keyValue, valueSelected);\n }\n static getObjectText(objectJson) {\n return objectJson == null ? '' : objectJson[objectJson[flagNameAttrOptionText]];\n }\n static getListObjectsFromIdDictAndCsv(idDict, idCsv) {\n let listObjects = [];\n let ids = idCsv.split(',');\n for (let id of ids) {\n listObjects.push(idDict[id]);\n }\n return listObjects;\n }\n}","\nexport default class Events {\n static initialiseEventHandler(selectorElement, classInitialised, eventHandler) {\n document.querySelectorAll(selectorElement).forEach(function(element) {\n if (element.classList.contains(classInitialised)) return;\n eventHandler(element);\n element.classList.add(classInitialised);\n });\n }\n static hookupEventHandler(eventType, selector, callback) {\n Events.initialiseEventHandler(selector, flagInitialised, (element) => {\n element.addEventListener(eventType, (event) => {\n event.stopPropagation();\n callback(event, element);\n });\n });\n }\n}","\nimport Validation from \"./validation.js\";\n\nexport default class LocalStorage {\n/*\nfunction getPageLocalStorage(pageHash) {\n\n let ls;\n try {\n ls = JSON.parse(localStorage.getItem(pageHash));\n } catch {\n\n }\n\n if (Validation.isEmpty(ls)) return {}\n\n return ls;\n}\nfunction getPageLocalStorageCurrent() {\n\n return JSON.parse(localStorage.getItem(hashPageCurrent));\n}\n\nfunction setPageLocalStorage(pageHash, newLS) {\n\n localStorage.setItem(pageHash, JSON.stringify(newLS));\n}\n\nfunction clearPageLocalStorage(pageHash) {\n localStorage.removeItem(pageHash);\n}\n\nfunction setupPageLocalStorage(pageHash) {\n\n let ls = getPageLocalStorage(pageHash);\n\n if (Validation.isEmpty(ls)) ls = {};\n\n setPageLocalStorage(pageHash, ls);\n}\n*/\n\n static getLocalStorage(key) {\n return JSON.parse(localStorage.getItem(key));\n }\n\n static setLocalStorage(key, newLS) {\n localStorage.setItem(key, JSON.stringify(newLS));\n }\n\n/*\nfunction setupPageLocalStorageNext(pageHashNext) {\n let lsOld = getPageLocalStorage(hashPageCurrent);\n hashPageCurrent = pageHashNext;\n clearPageLocalStorage(hashPageCurrent);\n setupPageLocalStorage(hashPageCurrent);\n let lsNew = getPageLocalStorage(hashPageCurrent);\n lsNew[keyBasket] = (keyBasket in lsOld) ? lsOld[keyBasket] : {'items': []};\n setPageLocalStorage(hashPageCurrent, lsNew);\n}\n*/\n}","// Utility functions\n/*\nfunction $(selector) {\n return document.querySelector(selector);\n}\n\nfunction $$(selector) {\n return document.querySelectorAll(selector);\n}\n*/\nexport default class Utils {\n static getListFromDict(dict) {\n let list = [];\n for (let key in dict) {\n list.push(dict[key]);\n }\n return list;\n }\n static consoleLogIfNotProductionEnvironment(message) {\n if (environment.is_production != \"true\") {\n console.log(message);\n }\n }\n}","\nimport Events from \"../../../lib/events.js\";\n\nexport default class OverlayConfirm {\n static hookup(callbackSuccess) {\n Events.initialiseEventHandler(idOverlayConfirm + ' button.' + flagCancel, flagInitialised, (buttonCancel) => {\n buttonCancel.addEventListener('click', () => {\n let overlay = document.querySelector(idOverlayConfirm);\n overlay.style.visibility = 'hidden';\n });\n });\n Events.initialiseEventHandler(idOverlayConfirm + ' button.' + flagSubmit, flagInitialised, (buttonConfirm) => {\n buttonConfirm.addEventListener('click', () => {\n let overlay = document.querySelector(idOverlayConfirm);\n let textarea = overlay.querySelector('textarea');\n overlay.style.visibility = 'hidden';\n callbackSuccess(textarea.value);\n });\n });\n }\n static show() {\n let overlay = document.querySelector(idOverlayConfirm);\n overlay.classList.remove(flagIsCollapsed);\n overlay.style.visibility = 'visible';\n }\n}","\nimport BusinessObjects from \"../lib/business_objects/business_objects.js\";\nimport Events from \"../lib/events.js\";\nimport LocalStorage from \"../lib/local_storage.js\";\nimport API from \"../api.js\";\nimport DOM from \"../dom.js\";\nimport Utils from \"../lib/utils.js\";\n\nimport OverlayConfirm from \"../components/common/temporary/overlay_confirm.js\";\nimport OverlayError from \"../components/common/temporary/overlay_error.js\";\nimport Validation from \"../lib/validation.js\";\n\nexport default class BasePage {\n constructor(router) {\n if (!router) {\n throw new Error(\"Router is required\");\n }\n else {\n Utils.consoleLogIfNotProductionEnvironment(\"initialising with router: \", router);\n }\n this.router = router;\n this.title = titlePageCurrent;\n if (this.constructor === BasePage) {\n throw new Error(\"Cannot instantiate abstract class\");\n }\n \n if (!this.constructor.hash) {\n throw new Error(`Class ${this.constructor.name} must have a static hash attribute.`);\n }\n }\n\n initialize() {\n throw new Error(\"Method 'initialize()' must be implemented.\");\n }\n\n sharedInitialize() {\n this.logInitialisation();\n this.hookupCommonElements();\n }\n\n logInitialisation() {\n Utils.consoleLogIfNotProductionEnvironment('Initialising ' + this.title + ' page');\n }\n \n hookupCommonElements() {\n // hookupVideos();\n this.hookupLogos();\n this.hookupNavigation();\n this.hookupOverlays();\n }\n hookupLogos() {\n Events.hookupEventHandler(\"click\", \".\" + flagImageLogo + \",\" + \".\" + flagLogo, (event, element) => {\n Utils.consoleLogIfNotProductionEnvironment('clicking logo');\n this.router.navigateToHash(hashPageHome);\n });\n }\n /*\n hookupEventHandler(eventType, selector, callback) {\n Events.initialiseEventHandler(selector, flagInitialised, (element) => {\n element.addEventListener(eventType, (event) => {\n event.stopPropagation();\n callback(event, element);\n });\n });\n }\n */\n hookupNavigation() {\n Events.hookupEventHandler(\"click\", idButtonHamburger, (event, element) => {\n let overlayHamburger = document.querySelector(idOverlayHamburger);\n if (overlayHamburger.classList.contains(flagIsCollapsed)) {\n overlayHamburger.classList.remove(flagIsCollapsed);\n overlayHamburger.classList.add(flagExpanded);\n } else {\n overlayHamburger.classList.remove(flagExpanded);\n overlayHamburger.classList.add(flagIsCollapsed);\n }\n });\n\n this.hookupButtonsNavUserAccount();\n this.hookupButtonsNavUserLogout();\n this.hookupButtonsNavUserLogin();\n }\n hookupButtonsNav(buttonSelector) {\n Events.hookupEventHandler(\"click\", buttonSelector, (event, button) => {\n let pageHash = buttonSelector.getAttribute('href');\n this.router.navigateToHash(pageHash); \n });\n }\n hookupButtonsNavUserAccount() {\n // this.hookupButtonsNav('.' + flagNavUserAccount);\n }\n hookupButtonsNavUserLogout() {\n // this.hookupButtonsNav('.' + flagNavUserLogout);\n }\n hookupButtonsNavUserLogin() {\n Events.hookupEventHandler(\"click\", '.' + flagNavUserLogin, (event, navigator) => {\n event.preventDefault();\n event.stopPropagation();\n this.leave();\n API.loginUser()\n .then((response) => {\n if (response.Success) {\n window.location.href = response[flagCallback];\n } else {\n DOM.alertError(\"Error\", response.Message);\n }\n });\n });\n }\n\n hookupOverlays() {\n this.hookupOverlayFromId(idOverlayConfirm);\n this.hookupOverlayFromId(idOverlayError);\n }\n\n hookupOverlayFromId(idOverlay) {\n Events.initialiseEventHandler(idOverlay, flagInitialised, (overlay) => {\n overlay.querySelector('button.' + flagCancel).addEventListener(\"click\", (event) => {\n event.stopPropagation();\n overlay.style.display = 'none';\n });\n });\n }\n\n hookupButtonSave() {\n Events.initialiseEventHandler('.' + flagContainer + '.' + flagSave + '.' + flagCancel + ' button.' + flagSave, flagInitialised, (button) => {\n button.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n button = event.target;\n if (button.classList.contains(flagIsCollapsed)) return;\n Utils.consoleLogIfNotProductionEnvironment('saving page: ', this.title);\n OverlayConfirm.show();\n });\n });\n }\n\n leave() {\n Utils.consoleLogIfNotProductionEnvironment('Leaving ' + this.title + ' page');\n if (this.constructor === BasePage) {\n throw new Error(\"Must implement leave() method.\");\n }\n }\n setLocalStoragePage(dataPage) {\n LocalStorage.setLocalStorage(this.hash, dataPage);\n }\n getLocalStoragePage() {\n return LocalStorage.getLocalStorage(this.hash);\n }\n\n toggleShowButtonsSaveCancel(show, buttonContainerSelector = null) { // , buttonSave = null, buttonCancel = null\n if (Validation.isEmpty(buttonContainerSelector)) buttonContainerSelector = '.' + flagContainer + '.' + flagSave + '.' + flagCancel;\n let buttonSave = document.querySelector(buttonContainerSelector + ' ' + idButtonSave);\n if (buttonSave == null) return;\n let buttonCancel = document.querySelector(buttonContainerSelector + ' ' + idButtonCancel);\n Utils.consoleLogIfNotProductionEnvironment({ show, buttonContainerSelector, buttonCancel, buttonSave });\n if (show) {\n buttonCancel.classList.remove(flagIsCollapsed);\n buttonSave.classList.remove(flagIsCollapsed);\n Utils.consoleLogIfNotProductionEnvironment('showing buttons');\n } else {\n buttonCancel.classList.add(flagIsCollapsed);\n buttonSave.classList.add(flagIsCollapsed);\n Utils.consoleLogIfNotProductionEnvironment('hiding buttons');\n }\n }\n\n static isDirtyFilter(filter) {\n let isDirty = DOM.updateAndCheckIsElementDirty(filter);\n if (isDirty) document.querySelectorAll(idTableMain + ' tbody tr').remove();\n return isDirty;\n }\n\n}","\nimport Events from \"../../../lib/events.js\";\n\nexport default class OverlayError {\n static hookup() {\n Events.initialiseEventHandler(idOverlayError + ' button.' + flagCancel, flagInitialised, (buttonCancel) => {\n buttonCancel.addEventListener('click', () => {\n let overlay = document.querySelector(idOverlayError);\n overlay.style.visibility = 'hidden';\n });\n });\n }\n static show(msgError) {\n let overlay = document.querySelector(idOverlayError);\n let labelError = overlay.querySelector(idLabelError);\n labelError.innerText = msgError;\n overlay.style.visibility = 'visible';\n }\n}","\nimport BusinessObjects from \"../lib/business_objects/business_objects.js\";\nimport Events from \"../lib/events.js\";\nimport LocalStorage from \"../lib/local_storage.js\";\nimport Validation from \"../lib/validation.js\";\nimport BasePage from \"./base.js\";\nimport API from \"../api.js\";\nimport DOM from \"../dom.js\";\nimport Utils from \"../lib/utils.js\";\n\nimport OverlayConfirm from \"../components/common/temporary/overlay_confirm.js\";\nimport OverlayError from \"../components/common/temporary/overlay_error.js\";\n\nexport default class TableBasePage extends BasePage {\n // static hash\n // static attrIdRowObject\n // callSaveTableContent\n\n constructor(router) {\n super(router);\n this.cursorYInitial = null;\n this.rowInitial = null;\n this.placeholder = null;\n this.dragSrcEl = null;\n this.dragSrcRow = null;\n\n this.hookupTableCellDdls = this.hookupTableCellDdls.bind(this);\n }\n \n initialize(isPopState = false) {\n throw new Error(\"Must implement initialize() method.\");\n }\n sharedInitialize(isPopState = false, isSinglePageApp = false) {\n if (!isPopState) {\n super.sharedInitialize();\n this.hookupFilters();\n this.hookupButtonsSaveCancel();\n this.hookupTableMain();\n OverlayConfirm.hookup(() => {\n if (isSinglePageApp) {\n this.saveRecordsTableDirtySinglePageApp();\n }\n else {\n this.saveRecordsTableDirty();\n }\n });\n } else {\n let dataPage = this.getLocalStoragePage();\n let filters = dataPage[flagFormFilters];\n let formFilters = TableBasePage.getFormFilters();\n let filtersDefault = DOM.convertForm2JSON(formFilters);\n if (!Validation.areEqualDicts(filters, filtersDefault)) {\n this.callFilterTableContent();\n }\n }\n }\n hookupFilters() {\n if (this.constructor === TableBasePage) {\n throw new Error(\"Subclass of TableBasePage must implement method hookupFilters().\");\n }\n }\n sharedHookupFilters() {\n this.hookupButtonApplyFilters();\n this.hookupSearchTextFilter();\n }\n hookupFilterActive() {\n let filterSelector = idFormFilters + ' #' + flagActiveOnly;\n let filterActiveOld = document.querySelector(filterSelector);\n filterActiveOld.removeAttribute('id');\n let parentDiv = filterActiveOld.parentElement;\n let isChecked = (DOM.getElementAttributeValuePrevious(parentDiv) == \"True\");\n let filterActiveNew = document.querySelector(idFormFilters + ' div.' + flagActiveOnly + '.' + flagContainerInput + ' svg.' + flagActiveOnly);\n filterActiveNew.setAttribute('id', flagActiveOnly);\n if (isChecked) filterActiveNew.classList.add(flagIsChecked);\n\n Events.hookupEventHandler(\"click\", filterSelector, (event, filterActive) => {\n Utils.consoleLogIfNotProductionEnvironment({ filterActive });\n Utils.consoleLogIfNotProductionEnvironment({ [filterActive.tagName]: filterActive.tagName });\n let svgElement = (filterActive.tagName.toUpperCase() == 'SVG') ? filterActive : filterActive.parentElement;\n let wasChecked = svgElement.classList.contains(flagIsChecked);\n if (wasChecked) {\n svgElement.classList.remove(flagIsChecked);\n }\n else {\n svgElement.classList.add(flagIsChecked);\n }\n return this.handleChangeFilter(event, filterActive);\n });\n let filter = document.querySelector(filterSelector);\n let filterValuePrevious = DOM.getElementValueCurrent(filter);\n filter.setAttribute(attrValueCurrent, filterValuePrevious);\n filter.setAttribute(attrValuePrevious, filterValuePrevious);\n }\n hookupFilter(filterFlag, handler = (event, filter) => { return this.handleChangeFilter(event, filter); }) {\n let filterSelector = idFormFilters + ' #' + filterFlag;\n Events.hookupEventHandler(\"change\", filterSelector, handler);\n let filter = document.querySelector(filterSelector);\n let filterValuePrevious = DOM.getElementValueCurrent(filter);\n filter.setAttribute(attrValueCurrent, filterValuePrevious);\n filter.setAttribute(attrValuePrevious, filterValuePrevious);\n }\n handleChangeFilter(event, filter) {\n let isDirtyFilter = DOM.updateAndCheckIsElementDirty(filter);\n let formFilters = TableBasePage.getFormFilters();\n let areDirtyFilters = isDirtyFilter || DOM.hasDirtyChildrenContainer(formFilters);\n let tbody = document.querySelector(idTableMain + ' tbody');\n let rows = tbody.querySelectorAll(':scope > tr');\n rows.forEach((row) => {\n if (areDirtyFilters && !row.classList.contains(flagIsCollapsed)) row.classList.add(flagIsCollapsed);\n if (!areDirtyFilters && row.classList.contains(flagIsCollapsed)) {\n row.classList.remove(flagIsCollapsed);\n let dirtyInputs = row.querySelectorAll('input.' + flagDirty);\n dirtyInputs.forEach((dirtyInput) => {\n dirtyInput.value = DOM.getElementAttributeValueCurrent(dirtyInput);\n });\n }\n });\n if (areDirtyFilters) {\n /*\n tbody.querySelectorAll('tr').forEach((tr) => { \n if (!DOM.hasDirtyChildrenContainer(tr)) tr.remove(); \n });\n */\n tbody.innerHTML = '
Press \"Apply Filters\" to refresh the table.
' + tbody.innerHTML;\n if (!tbody.classList.contains(flagIsCollapsed)) tbody.classList.add(flagIsCollapsed);\n }\n else {\n let isDirtyLabel = tbody.querySelector(\":scope > div\");\n if (isDirtyLabel != null) isDirtyLabel.remove();\n if (tbody.classList.contains(flagIsCollapsed)) tbody.classList.remove(flagIsCollapsed);\n let initialisedElements = tbody.querySelectorAll('.' + flagInitialised);\n initialisedElements.forEach((initialisedElement) => {\n initialisedElement.classList.remove(flagInitialised);\n });\n this.hookupTableMain();\n }\n this.updateAndToggleShowButtonsSaveCancel();\n }\n hookupFilterIsNotEmpty() {\n this.hookupFilter(flagIsNotEmpty);\n }\n hookupButtonApplyFilters() {\n Events.hookupEventHandler(\"click\", idButtonApplyFilters, (event, button) => {\n event.stopPropagation();\n this.callFilterTableContent();\n });\n }\n hookupSearchTextFilter() {\n this.hookupFilter(flagSearch);\n }\n hookupFilterCommandCategory() {\n this.hookupFilter(attrIdCommandCategory, (event, filterCommandCategory) => {\n this.handleChangeFilter();\n let isDirtyFilter = filterCommandCategory.classList.contains(flagDirty);\n let idCommandCategory = DOM.getElementValueCurrent(filterCommandCategory);\n console.log(\"filter commands unsorted\");\n console.log(Utils.getListFromDict(filterCommands));\n let commandsInCategory = Utils.getListFromDict(filterCommands).filter(command => command[attrIdCommandCategory] == idCommandCategory);\n let sortedCommands = commandsInCategory.sort((a, b) => a[flagName].localeCompare(b[flagName]));\n let filterCommand = document.querySelector(idFormFilters + ' .' + flagCommand);\n let idCommandPrevious = DOM.getElementAttributeValuePrevious(filterCommand);\n filterCommand.innerHTML = '';\n let optionJson, option;\n option = DOM.createOption(null);\n filterCommand.appendChild(option);\n sortedCommands.forEach((command) => {\n optionJson = BusinessObjects.getOptionJsonFromObjectJson(command, idCommandPrevious);\n option = DOM.createOption(optionJson);\n filterCommand.appendChild(option);\n });\n filterCommand.dispatchEvent(new Event('change'));\n return isDirtyFilter;\n });\n }\n hookupFilterCommand() {\n this.hookupFilter(attrIdCommand);\n }\n hookupFilterLocation() {\n this.hookupFilter(attrIdLocation);\n }\n /*\n getAndLoadFilteredTableContent = () => {\n this.callFilterTableContent()\n .catch(error => console.error('Error:', error));\n }\n */\n static getFormFilters() {\n return document.querySelector(idFormFilters);\n }\n callFilterTableContent() {\n let formFilters = TableBasePage.getFormFilters();\n let filtersJson = DOM.convertForm2JSON(formFilters);\n Utils.consoleLogIfNotProductionEnvironment(\"callFilterTableContent\");\n Utils.consoleLogIfNotProductionEnvironment(\"formFilters\");\n Utils.consoleLogIfNotProductionEnvironment(formFilters);\n Utils.consoleLogIfNotProductionEnvironment(\"filtersJson\");\n Utils.consoleLogIfNotProductionEnvironment(filtersJson);\n this.leave();\n API.goToHash(this.constructor.hash, filtersJson);\n }\n callbackLoadTableContent(response) {\n let table = TableBasePage.getTableMain();\n let bodyTable = table.querySelector('tbody');\n bodyTable.querySelectorAll('tr').forEach(function(row) { row.remove(); });\n let rowsJson = response.data[flagRows];\n if (!Validation.isEmpty(rowsJson) && rowsJson.every(row => row.hasOwnProperty('display_order'))) {\n rowsJson = rowsJson.sort((a, b) => a.display_order - b.display_order);\n }\n rowsJson.forEach(this.loadRowTable.bind(this));\n this.hookupTableMain();\n }\n static getTableMain() {\n return document.querySelector(idTableMain);\n }\n loadRowTable(rowJson) {\n throw new Error(\"Subclass of TableBasePage must implement method loadRowTable().\");\n }\n getAndLoadFilteredTableContentSinglePageApp() {\n this.callFilterTableContent()\n .then(data => {\n Utils.consoleLogIfNotProductionEnvironment('Table data received:', data);\n this.callbackLoadTableContent(data);\n })\n .catch(error => console.error('Error:', error));\n }\n hookupButtonsSaveCancel() {\n this.hookupButtonSave();\n this.hookupButtonCancel();\n this.toggleShowButtonsSaveCancel(false);\n }\n saveRecordsTableDirty() {\n let records = this.getTableRecords(true);\n if (records.length == 0) {\n OverlayError.show('No records to save');\n return;\n }\n let formElement = TableBasePage.getFormFilters();\n let comment = DOM.getElementValueCurrent(document.querySelector(idTextareaConfirm));\n this.callSaveTableContent(records, formElement, comment)\n .then(data => {\n if (data[flagStatus] == flagSuccess) {\n if (_verbose) { \n Utils.consoleLogIfNotProductionEnvironment('Records saved!');\n Utils.consoleLogIfNotProductionEnvironment('Data received:', data);\n }\n this.callFilterTableContent();\n }\n else {\n Utils.consoleLogIfNotProductionEnvironment(\"error: \", data[flagMessage]);\n OverlayError.show(data[flagMessage]);\n }\n })\n .catch(error => console.error('Error:', error));\n }\n getTableRecords(dirtyOnly = false) {\n let records = [];\n let record;\n document.querySelectorAll(idTableMain + ' > tbody > tr').forEach((row) => {\n if (dirtyOnly && !DOM.hasDirtyChildrenContainer(row)) return;\n record = this.getJsonRow(row);\n records.push(record);\n });\n return records;\n }\n getJsonRow(row) {\n throw new Error(\"Subclass of TableBasePage must implement method getJsonRow().\");\n }\n saveRecordsTableDirtySinglePageApp() {\n let records = this.getTableRecords(true);\n if (records.length == 0) {\n OverlayError.show('No records to save');\n return;\n }\n let formElement = TableBasePage.getFormFilters();\n let comment = DOM.getElementValueCurrent(document.querySelector(idTextareaConfirm));\n this.callSaveTableContent(records, formElement, comment)\n .then(data => {\n if (data[flagStatus] == flagSuccess) {\n if (_verbose) { \n Utils.consoleLogIfNotProductionEnvironment('Records saved!');\n Utils.consoleLogIfNotProductionEnvironment('Data received:', data);\n }\n this.callbackLoadTableContent(data);\n }\n else {\n Utils.consoleLogIfNotProductionEnvironment(\"error: \", data[flagMessage]);\n OverlayError.show(data[flagMessage]);\n }\n })\n .catch(error => console.error('Error:', error));\n }\n hookupButtonCancel() {\n Events.initialiseEventHandler('.' + flagContainer + '.' + flagSave + '.' + flagCancel + ' button.' + flagCancel, flagInitialised, (button) => {\n button.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n button = event.target;\n if (button.classList.contains(flagIsCollapsed)) return;\n this.callFilterTableContent();\n });\n button.classList.add(flagIsCollapsed);\n });\n }\n handleClickAddRowTable(event, button) {\n event.stopPropagation();\n _rowBlank.setAttribute(this.constructor.attrIdRowObject, -1 - _rowBlank.getAttribute(this.constructor.attrIdRowObject));\n let tbody = document.querySelector(idTableMain + ' tbody');\n if (tbody.classList.contains(flagIsCollapsed)) return;\n let row = _rowBlank.cloneNode(true);\n row.classList.remove(flagInitialised);\n row.querySelectorAll('.' + flagInitialised).forEach(function(element) {\n element.classList.remove(flagInitialised);\n });\n let countRows = document.querySelectorAll(idTableMain + ' > tbody > tr').length;\n row.setAttribute(this.constructor.attrIdRowObject, -1 - countRows);\n this.initialiseRowNew(tbody, row);\n tbody.prepend(row);\n tbody.scrollTop = 0;\n this.hookupTableMain();\n this.postInitialiseRowNewCallback(tbody);\n }\n initialiseRowNew(tbody, row) {\n if (this.constructor === TableBasePage) {\n throw new Error(\"Subclass of TableBasePage must implement method initialiseRowNew().\");\n }\n // row.classList.remove(flagRowNew);\n }\n hookupTableMain() {\n if (this.constructor === TableBasePage) {\n throw new Error(\"Must implement hookupTableMain() method.\");\n }\n Events.initialiseEventHandler(idTableMain, flagInitialised, (table) => {\n this.cacheRowBlank();\n });\n }\n cacheRowBlank() {\n let selectorRowNew = idTableMain + ' tbody tr.' + flagRowNew;\n let rowBlankTemp = document.querySelector(selectorRowNew);\n if (rowBlankTemp == null) return;\n Utils.consoleLogIfNotProductionEnvironment(\"row blank temp: \", rowBlankTemp);\n let countRows = document.querySelectorAll(idTableMain + ' > tbody > tr').length;\n _rowBlank = rowBlankTemp.cloneNode(true);\n document.querySelectorAll(selectorRowNew).forEach(function(row) {\n row.remove();\n });\n _rowBlank.setAttribute(this.constructor.attrIdRowObject, -1 - countRows);\n }\n postInitialiseRowNewCallback(tbody) {\n if (this.constructor === TableBasePage) {\n throw new Error(\"Subclass of TableBasePage must implement method postInitialiseRowNewCallback(tbody).\");\n }\n }\n initialiseSliderDisplayOrderRowNew(tbody, row) {\n // let tdSelector = ':scope > tr > td.' + flagDisplayOrder;\n // let tbody = document.querySelector('table' + (Validation.isEmpty(flagTable) ? '' : '.' + flagTable) + ' > tbody');\n let slidersDisplayOrder = tbody.querySelectorAll(':scope > tr > td.' + flagDisplayOrder + ' input.' + flagSlider);\n let maxDisplayOrder = 0;\n slidersDisplayOrder.forEach((slider) => {\n maxDisplayOrder = Math.max(maxDisplayOrder, parseFloat(DOM.getElementValueCurrent(slider)));\n });\n let sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider);\n DOM.setElementValuesCurrentAndPrevious(sliderDisplayOrder, maxDisplayOrder + 1);\n }\n hookupSlidersDisplayOrderTable() {\n let selectorDisplayOrder = idTableMain + ' tbody tr td.' + flagDisplayOrder + ' input.' + flagSlider + '.' + flagDisplayOrder;\n this.hookupChangeHandlerTableCells(selectorDisplayOrder);\n }\n hookupChangeHandlerTableCells(inputSelector, handler = (event, element) => { this.handleChangeNestedElementCellTable(event, element); }) {\n Events.initialiseEventHandler(inputSelector, flagInitialised, (input) => {\n input.addEventListener(\"change\", (event) => {\n handler(event, input);\n });\n handler(null, input);\n });\n }\n handleChangeNestedElementCellTable(event, element) {\n let wasDirtyParentRows = this.getAllIsDirtyRowsInParentTree(element);\n let wasDirtyElement = element.classList.contains(flagDirty);\n let isDirtyElement = DOM.updateAndCheckIsElementDirty(element);\n // Utils.consoleLogIfNotProductionEnvironment({isDirtyElement, wasDirtyElement, wasDirtyParentRows});\n // let td = DOM.getCellFromElement(element);\n // DOM.setElementAttributeValueCurrent(td, DOM.getElementAttributeValueCurrent(element));\n if (isDirtyElement != wasDirtyElement) {\n // DOM.handleDirtyElement(td, isDirtyElement);\n this.updateAndToggleShowButtonsSaveCancel();\n this.cascadeChangedIsDirtyNestedElementCellTable(element, isDirtyElement, wasDirtyParentRows);\n }\n }\n getAllIsDirtyRowsInParentTree(element) {\n let rows = [];\n let parent = element;\n let isDirty;\n while (parent) {\n if (parent.tagName.toUpperCase() == 'TR') {\n isDirty = parent.classList.contains(flagDirty)\n rows.push(isDirty);\n }\n parent = parent.parentElement;\n }\n return rows;\n }\n cascadeChangedIsDirtyNestedElementCellTable(element, isDirtyElement, wasDirtyParentRows) {\n if (Validation.isEmpty(wasDirtyParentRows)) return;\n let tr = DOM.getRowFromElement(element);\n let isDirtyRow = isDirtyElement || DOM.hasDirtyChildrenContainer(tr);\n let wasDirtyRow = wasDirtyParentRows.shift();\n Utils.consoleLogIfNotProductionEnvironment({isDirtyRow, wasDirtyRow});\n if (isDirtyRow != wasDirtyRow) {\n DOM.handleDirtyElement(tr, isDirtyRow);\n this.updateAndToggleShowButtonsSaveCancel();\n this.cascadeChangedIsDirtyNestedElementCellTable(tr.parentElement, isDirtyRow, wasDirtyParentRows);\n }\n }\n hookupChangeHandlerTableCellsWhenNotCollapsed(inputSelector, handler = (event, element) => {\n if (!element.classList.contains(flagIsCollapsed)) this.handleChangeNestedElementCellTable(event, element);\n }) {\n Events.hookupEventHandler(\"change\", inputSelector, handler);\n }\n hookupFieldsCodeTable() {\n this.hookupChangeHandlerTableCells(idTableMain + ' > tbody > tr > td.' + flagCode + ' > .' + flagCode);\n }\n hookupFieldsNameTable() {\n this.hookupChangeHandlerTableCells(idTableMain + ' > tbody > tr > td.' + flagName + ' > .' + flagName);\n }\n hookupFieldsDescriptionTable() {\n this.hookupChangeHandlerTableCells(idTableMain + ' > tbody > tr > td.' + flagDescription + ' > .' + flagDescription);\n }\n hookupFieldsNotesTable() {\n this.hookupChangeHandlerTableCells(idTableMain + ' > tbody > tr > td.' + flagNotes + ' > .' + flagNotes);\n }\n hookupFieldsActive(flagTable = '', handleClickRowNew = (event, element) => { this.handleClickAddRowTable(event, element); }) {\n let selectorButton = 'table.table-main' + (Validation.isEmpty(flagTable) ? '' : '.' + flagTable) + ' > tbody > tr > td.' + flagActive + ' .' + flagButton + '.' + flagActive;\n let selectorButtonDelete = selectorButton + '.' + flagDelete;\n let selectorButtonUndelete = selectorButton + ':not(.' + flagDelete + ')';\n Utils.consoleLogIfNotProductionEnvironment(\"hookupFieldsActive: \", selectorButtonDelete, selectorButtonUndelete);\n this.hookupButtonsRowDelete(selectorButtonDelete, selectorButtonUndelete);\n this.hookupButtonsRowUndelete(selectorButtonDelete, selectorButtonUndelete);\n Events.hookupEventHandler(\n \"click\"\n , 'table.table-main' + (Validation.isEmpty(flagTable) ? '' : '.' + flagTable) + ' > thead > tr > th.' + flagActive + ' .' + flagButton + '.' + flagActive\n , (event, button) => { handleClickRowNew(event, button); }\n );\n }\n hookupButtonsRowDelete(selectorButtonDelete, selectorButtonUndelete, changeHandler = (event, element) => { this.handleChangeNestedElementCellTable(event, element); }) {\n Events.hookupEventHandler(\"click\", selectorButtonDelete, (event, element) => {\n this.handleClickButtonRowDelete(event, element, selectorButtonDelete, selectorButtonUndelete, (changeEvent, changeElement) => { changeHandler(changeEvent, changeElement); });\n });\n }\n handleClickButtonRowDelete(event, element, selectorButtonDelete, selectorButtonUndelete, changeHandler = (event, element) => { this.handleChangeNestedElementCellTable(event, element); }) {\n if (element.tagName.toUpperCase() != 'SVG') element = element.parentElement;\n let valuePrevious = DOM.getElementAttributeValuePrevious(element);\n let wasDirty = element.classList.contains(flagDirty);\n let row = DOM.getRowFromElement(element);\n if (row.classList.contains(flagRowNew) && !DOM.hasDirtyChildrenContainer(row)) {\n row.parentNode.removeChild(row);\n }\n else {\n let buttonAddTemplate = document.querySelector(idContainerTemplateElements + ' .' + flagButton + '.' + flagActive + '.' + flagAdd);\n let buttonAdd = buttonAddTemplate.cloneNode(true);\n DOM.setElementAttributeValuePrevious(buttonAdd, valuePrevious);\n DOM.setElementAttributeValueCurrent(buttonAdd, false);\n if (wasDirty) buttonAdd.classList.add(flagDirty);\n element.replaceWith(buttonAdd);\n changeHandler(null, buttonAdd);\n this.hookupButtonsRowUndelete(selectorButtonDelete, selectorButtonUndelete, (changeEvent, changeElement) => { changeHandler(changeEvent, changeElement); });\n }\n this.updateAndToggleShowButtonsSaveCancel();\n }\n hookupButtonsRowUndelete(selectorButtonDelete, selectorButtonUndelete, changeHandler = (event, element) => { this.handleChangeNestedElementCellTable(event, element); }) {\n Events.hookupEventHandler(\"click\", selectorButtonUndelete, (event, element) => {\n this.handleClickButtonRowUndelete(event, element, selectorButtonDelete, selectorButtonUndelete, (changeEvent, changeElement) => { changeHandler(changeEvent, changeElement); });\n });\n }\n handleClickButtonRowUndelete(event, element, selectorButtonDelete, selectorButtonUndelete, changeHandler = (event, element) => { this.handleChangeNestedElementCellTable(event, element); }) {\n if (element.tagName.toUpperCase() != 'SVG') element = element.parentElement;\n let valuePrevious = DOM.getElementAttributeValuePrevious(element);\n let wasDirty = DOM.isElementDirty(element);\n let buttonDeleteTemplate = document.querySelector(idContainerTemplateElements + ' .' + flagButton + '.' + flagActive + '.' + flagDelete);\n let buttonDelete = buttonDeleteTemplate.cloneNode(true);\n DOM.setElementAttributeValuePrevious(buttonDelete, valuePrevious);\n DOM.setElementAttributeValueCurrent(buttonDelete, true);\n if (wasDirty) buttonDelete.classList.add(flagDirty);\n element.replaceWith(buttonDelete);\n changeHandler(null, buttonDelete);\n this.hookupButtonsRowDelete(selectorButtonDelete, selectorButtonUndelete, (changeEvent, changeElement) => { changeHandler(changeEvent, changeElement); });\n this.updateAndToggleShowButtonsSaveCancel();\n }\n hookupTdsAccessLevel() {\n this.hookupTableCellDdlPreviews(flagAccessLevel, Utils.getListFromDict(accessLevels));\n }\n hookupTableCellDdlPreviews(\n fieldFlag\n , optionList\n , cellSelector = null\n , ddlHookup = (ddlSelector) => { this.hookupTableCellDdls(ddlSelector); }\n , changeHandler = (event, element) => { this.handleChangeNestedElementCellTable(event, element); }\n ) {\n if (cellSelector == null) cellSelector = idTableMain + ' > tbody > tr > td.' + fieldFlag;\n Events.hookupEventHandler(\"click\", cellSelector + ' div.' + fieldFlag, (event, div) => {\n this.handleClickTableCellDdlPreview(\n event\n , div\n , fieldFlag\n , optionList\n , cellSelector\n , (ddlSelector) => { ddlHookup(\n ddlSelector\n , (event, element) => { changeHandler(event, element); }\n ); }\n );\n });\n ddlHookup(cellSelector + ' select.' + fieldFlag);\n }\n hookupTableCellDdls(ddlSelector, changeHandler = (event, element) => { this.handleChangeNestedElementCellTable(event, element); }) {\n this.hookupChangeHandlerTableCells(ddlSelector, (event, element) => { changeHandler(event, element); });\n }\n handleClickTableCellDdlPreview(event, div, fieldFlag, optionObjectList, cellSelector = null, ddlHookup = (cellSelector) => { this.hookupTableCellDdls(cellSelector); }) {\n if (Validation.isEmpty(cellSelector)) cellSelector = idTableMain + ' > tbody > tr > td.' + fieldFlag;\n let idSelected = DOM.getElementAttributeValueCurrent(div);\n let td = DOM.getCellFromElement(div);\n td.innerHTML = '';\n let ddl = document.createElement('select');\n ddl.classList.add(fieldFlag);\n DOM.setElementValuesCurrentAndPrevious(ddl, idSelected);\n let optionJson, option;\n if (_verbose) { \n Utils.consoleLogIfNotProductionEnvironment(\"click table cell ddl preview\");\n Utils.consoleLogIfNotProductionEnvironment({optionObjectList, cellSelector});\n }\n option = DOM.createOption(null);\n ddl.appendChild(option);\n optionObjectList.forEach((optionObjectJson) => {\n optionJson = BusinessObjects.getOptionJsonFromObjectJson(optionObjectJson, idSelected);\n option = DOM.createOption(optionJson);\n ddl.appendChild(option);\n });\n td.appendChild(ddl);\n let ddlSelector = cellSelector + ' select.' + fieldFlag;\n ddlHookup(ddlSelector);\n }\n /*\n hookupTableCellDDlPreviewsWhenNotCollapsed(cellSelector, optionList, ddlHookup = (event, element) => { this.hookupTableCellDdls(event, element); }) {\n Events.hookupEventHandler(\"click\", cellSelector + ' div', (event, div) => {\n this.handleClickTableCellDdlPreview(event, div, optionList, cellSelector, (event, element) => { ddlHookup(event, element); });\n });\n }\n */\n toggleColumnCollapsed(flagColumn, isCollapsed) {\n this.toggleColumnHasClassnameFlag(flagColumn, isCollapsed, flagIsCollapsed);\n }\n toggleColumnHeaderCollapsed(flagColumn, isCollapsed) {\n this.toggleColumnHasClassnameFlag(flagColumn, isCollapsed, flagIsCollapsed);\n }\n\n hookupFieldsCommandCategory(idTable = null) {\n if (idTable == null) idTable = idTableMain;\n this.hookupTableCellDdlPreviews(\n flagCommandCategory\n , Utils.getListFromDict(filterCommandCategories).sort((a, b) => a[flagName].localeCompare(b[flagName]))\n , idTable + ' > tbody > tr > td.' + flagCommandCategory // + ' .' + flagCommandCategory\n , (cellSelector) => { this.hookupCommandCategoryDdls(cellSelector); }\n );\n }\n hookupCommandCategoryDdls(ddlSelector) {\n this.hookupChangeHandlerTableCells(ddlSelector, (event, element) => { this.handleChangeCommandCategoryDdl(event, element); });\n }\n handleChangeCommandCategoryDdl(event, ddlCategory) {\n let row = DOM.getRowFromElement(ddlCategory);\n let idCommandCategoryRowOld = this.getIdCommandCategoryRow(row); // DOM.getElementAttributeValueCurrent(ddlCategory);\n this.handleChangeNestedElementCellTable(event, ddlCategory);\n let idCommandCategoryRowNew = this.getIdCommandCategoryRow(row); // DOM.getElementAttributeValueCurrent(ddlCategory);\n if (\n idCommandCategoryRowOld == idCommandCategoryRowNew\n || idCommandCategoryRowNew == 0\n ) return;\n console.log({ idCommandCategoryRowNew, idCommandCategoryRowOld });\n let idCommandCategoryFilter = this.getIdCommandCategoryFilter();\n let tdCommand = row.querySelector('td.' + flagCommand);\n tdCommand.dispatchEvent(new Event('click'));\n let ddlCommand = row.querySelector('td.' + flagCommand + ' select.' + flagCommand);\n ddlCommand.innerHTML = '';\n ddlCommand.appendChild(DOM.createOption(null));\n let optionJson, option;\n let commandsInCategory = Utils.getListFromDict(filterCommands).filter(command => \n (\n command[attrIdCommandCategory] == idCommandCategoryRowNew\n || idCommandCategoryRowNew == 0\n )\n && (\n command[attrIdCommandCategory] == idCommandCategoryFilter\n || idCommandCategoryFilter == 0\n )\n );\n let sortedCommands = commandsInCategory.sort((a, b) => a[flagName].localeCompare(b[flagName]));\n sortedCommands.forEach((command) => {\n optionJson = BusinessObjects.getOptionJsonFromObjectJson(command);\n option = DOM.createOption(optionJson);\n ddlCommand.appendChild(option);\n });\n this.handleChangeNestedElementCellTable(event, ddlCommand);\n }\n hookupFieldsCommand(idTable = null) {\n if (idTable == null) idTable = idTableMain;\n Events.hookupEventHandler(\"click\", idTable + ' > tbody > tr > td.' + flagCommand + ' div.' + flagCommand, (event, div) => {\n Utils.consoleLogIfNotProductionEnvironment(div);\n let parentTr = DOM.getRowFromElement(div);\n Utils.consoleLogIfNotProductionEnvironment({ div, parentTr });\n let tdCommandCategory = parentTr.querySelector('td.' + flagCommandCategory);\n let idCommandCategoryRow = this.getIdCommandCategoryRow(parentTr); // DOM.getElementAttributeValueCurrent(tdCommandCategory);\n let idCommandCategoryFilter = this.getIdCommandCategoryFilter();\n let filterCommandList = Utils.getListFromDict(filterCommands);\n let commandsInCategory = filterCommandList.filter(command => \n (\n command[attrIdCommandCategory] == idCommandCategoryRow\n || idCommandCategoryRow == 0\n )\n && (\n command[attrIdCommandCategory] == idCommandCategoryFilter\n || idCommandCategoryFilter == 0\n )\n );\n let sortedCommands = commandsInCategory.sort((a, b) => a[flagName].localeCompare(b[flagName]));\n Utils.consoleLogIfNotProductionEnvironment({ tdCommandCategory, idCommandCategoryRow, idCommandCategoryFilter, filterCommandList, commandsInCategory });\n Utils.consoleLogIfNotProductionEnvironment(filterCommandList);\n this.handleClickTableCellDdlPreview(\n event\n , div\n , flagCommand // fieldFlag\n , sortedCommands // optionList\n , idTable + ' > tbody > tr > td.' + flagCommand // cellSelector\n , (cellSelector) => { this.hookupTableCellDdls(\n cellSelector\n , (event, element) => { this.handleChangeCommandDdl(event, element); }\n ); }\n );\n });\n this.hookupTableCellDdls(\n idTable + ' > tbody > tr > td.' + flagCommand + ' select.' + flagCommand\n , (event, element) => { this.handleChangeCommandDdl(event, element); }\n );\n }\n handleChangeCommandDdl(event, ddlCommand) {\n // console.log(\"handle change command ddl\");\n let row = DOM.getRowFromElement(ddlCommand);\n this.handleChangeNestedElementCellTable(event, ddlCommand);\n let idCommandCategoryRowOld = this.getIdCommandCategoryRow(row);\n let idCommandNew = this.getIdCommandRow(row);\n let commandNew = filterCommands[idCommandNew];\n // console.log({ idCommandCategoryRowOld, commandNew });\n if (commandNew == null || idCommandCategoryRowOld == commandNew[attrIdCommandCategory]) return;\n let divCommandCategory = row.querySelector('td.' + flagCommandCategory + ' div');\n if (divCommandCategory) divCommandCategory.dispatchEvent(new Event('click'));\n let ddlCommandCategory = row.querySelector('td.' + flagCommandCategory + ' select.' + flagCommandCategory);\n DOM.setElementValueCurrent(ddlCommandCategory, commandNew[attrIdCommandCategory]);\n // console.log({ ddlCommandCategory, commandNew });\n this.handleChangeNestedElementCellTable(event, ddlCommandCategory);\n }\n getIdCommandCategoryRow(tr) {\n let elementCommandCategory = tr.querySelector('td.' + flagCommandCategory + ' .' + flagCommandCategory);\n return DOM.getElementAttributeValueCurrent(elementCommandCategory);\n }\n getIdCommandCategoryFilter() {\n let formFilters = TableBasePage.getFormFilters();\n let idCommandCategory = 0;\n if (formFilters == null) return idCommandCategory;\n let commandCategoryFilter = formFilters.querySelector('#' + attrIdCommandCategory);\n let commandFilter = formFilters.querySelector('#' + attrIdCommand);\n let valueCurrentCommandCategoryFilter = DOM.getElementAttributeValueCurrent(commandCategoryFilter);\n Utils.consoleLogIfNotProductionEnvironment({ valueCurrentCommandCategoryFilter });\n if (valueCurrentCommandCategoryFilter == \"\") {\n let valueCurrentCommandFilter = DOM.getElementAttributeValueCurrent(commandFilter);\n Utils.consoleLogIfNotProductionEnvironment({ valueCurrentCommandFilter });\n if (valueCurrentCommandFilter != \"\") {\n let command = filterCommands[valueCurrentCommandFilter];\n idCommandCategory = command[attrIdCommandCategory];\n }\n } else {\n idCommandCategory = Number(valueCurrentCommandCategoryFilter);\n }\n return idCommandCategory;\n }\n getHasCommandCategoryFilter() {\n let idCommandCategoryFilter = this.getIdCommandCategoryFilter();\n return !(Validation.isEmpty(idCommandCategoryFilter) || idCommandCategoryFilter == 0);\n }\n getIdCommandRow(tr) {\n let elementCommand = tr.querySelector('td.' + flagCommand + ' .' + flagCommand);\n return DOM.getElementAttributeValueCurrent(elementCommand);\n }\n getIdCommandFilter() {\n let formFilters = TableBasePage.getFormFilters();\n let commandFilter = formFilters.querySelector('#' + attrIdCommand);\n let valueCurrentCommandFilter = DOM.getElementAttributeValueCurrent(commandFilter);\n let idCommand = Number(valueCurrentCommandFilter);\n return idCommand;\n }\n getHasCommandFilter() {\n let idCommandFilter = this.getIdCommandFilter();\n return !(Validation.isEmpty(idCommandFilter) || idCommandFilter == 0);\n }\n /*\n createTdActive(isActive) {\n let tdActive = document.createElement(\"td\");\n tdActive.classList.add(flagActive);\n let buttonActive = document.createElement(\"button\");\n buttonActive.classList.add(flagActive);\n buttonActive.classList.add(isActive ? flagDelete : flagAdd);\n buttonActive.textContent = isActive ? 'x' : '+';\n DOM.setElementAttributesValuesCurrentAndPrevious(buttonActive, isActive);\n tdActive.appendChild(buttonActive);\n return tdActive;\n }\n */\n leave() {\n if (this.constructor === TableBasePage) {\n throw new Error(\"Must implement leave() method.\");\n }\n super.leave();\n let formFilters = TableBasePage.getFormFilters();\n let dataPage = {};\n dataPage[flagFormFilters] = DOM.convertForm2JSON(formFilters);\n this.setLocalStoragePage(dataPage);\n }\n\n toggleColumnHasClassnameFlag(columnFlag, isRequiredFlag, classnameFlag) {\n let table = TableBasePage.getTableMain();\n let columnTh = table.querySelector('th.' + columnFlag);\n let columnThHasFlag = columnTh.classList.contains(classnameFlag);\n if (isRequiredFlag == columnThHasFlag) return;\n DOM.toggleElementHasClassnameFlag(columnTh, isRequiredFlag, classnameFlag);\n }\n toggleColumnHeaderHasClassnameFlag(columnFlag, isRequiredFlag, classnameFlag) {\n let table = TableBasePage.getTableMain();\n let columnTh = table.querySelector('th.' + columnFlag);\n DOM.toggleElementHasClassnameFlag(columnTh, isRequiredFlag, classnameFlag);\n }\n\n updateAndToggleShowButtonsSaveCancel() {\n // let pageBody = document.querySelector(idPageBody);\n let isDirty = DOM.hasDirtyChildrenContainer(pageBody);\n\n let buttonContainerSelector = '.' + flagContainer + '.' + flagSave + '.' + flagCancel;\n let buttonSave = document.querySelector(buttonContainerSelector + ' ' + idButtonSave);\n let areVisibleSaveCancelButtons = !buttonSave.classList.contains(flagIsCollapsed);\n \n console.log({ pageBody, isDirty, areVisibleSaveCancelButtons });\n\n this.toggleShowButtonsSaveCancel(isDirty || areVisibleSaveCancelButtons);\n }\n}\n","\nimport API from \"../../api.js\";\nimport Events from \"../../lib/events.js\";\nimport TableBasePage from \"../base_table.js\";\nimport Utils from \"../../lib/utils.js\";\n\nexport default class PageMtgDecks extends TableBasePage {\n static hash = hashPageMtgDecks;\n static attrIdRowObject = attrDeckId;\n callSaveTableContent = API.saveDeck;\n\n constructor(router) {\n super(router);\n }\n\n initialize() {\n this.sharedInitialize();\n }\n hookupFilters() {\n /*\n this.sharedHookupFilters();\n this.hookupFilterActive();\n */\n }\n\n loadRowTable(rowJson) {\n if (rowJson == null) return;\n if (_verbose) { Utils.consoleLogIfNotProductionEnvironment(\"applying data row: \", rowJson); }\n }\n getJsonRow(row) {\n return;\n }\n initialiseRowNew(tbody, row) {\n }\n postInitialiseRowNewCallback(tbody) {\n let newRows = tbody.querySelectorAll('tr.' + flagRowNew);\n let newestRow = newRows[0];\n let clickableElementsSelector = [\n 'td.' + attrCommanderBracketId + ' div.' + attrCommanderBracketId\n ].join('');\n newestRow.querySelectorAll(clickableElementsSelector).forEach((clickableElement) => {\n clickableElement.click();\n });\n }\n\n hookupTableMain() {\n super.hookupTableMain();\n this.hookupTableMainRows();\n this.hookupFieldsNameTable();\n this.hookupTableMainIsCommanderCheckboxes();\n this.hookupTableMainCommanderBracketPreviews();\n this.hookupFieldsActive();\n }\n hookupTableMainRows() {\n return;\n let rowSelector = 'table.' + flagTableMain + ' tbody tr';\n Events.hookupEventHandler(\"click\", rowSelector, (event, row) => {\n let isRowExpanded = row.classList.contains(flagActive);\n let showSection;\n if (isRowExpanded) {\n showSection = false;\n PageMtgDecks.toggleShowDeckStatisticsSection(showSection);\n }\n else {\n showSection = true;\n let deckId = row.getAttribute(attrDeckId);\n let statisticsSectionTableBody = document.querySelector('table.' + flagStatistics + ' tbody');\n statisticsSectionTableBody.innerHTML = '';\n let deck = decks.filter(d => d[attrDeckId] == deckId)[0];\n if (deck[flagStatistics].length > 0) {\n let newStatisticRowsHtml = '';\n deck[flagStatistics]\n .sort((a, b) => a[flagDisplayOrder] - b[flagDisplayOrder])\n .forEach((statistic) => {\n newStatisticRowsHtml += `\n \n ${statistic[flagName]}\n ${statistic[flagValue]}\n \n `;\n });\n statisticsSectionTableBody.innerHTML = newStatisticRowsHtml;\n }\n PageMtgDecks.toggleShowDeckStatisticsSection(showSection);\n }\n });\n }\n static toggleShowDeckStatisticsSection(showSection) {\n let statisticsSectionTableBody = document.querySelector('table.' + flagStatistics + ' tbody');\n if (showSection) {\n statisticsSectionTableBody.classList.remove(flagIsCollapsed);\n }\n else {\n statisticsSectionTableBody.classList.add(flagIsCollapsed);\n }\n }\n hookupTableMainIsCommanderCheckboxes() {\n this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagIsCommander + ' .' + flagIsCommander);\n }\n hookupTableMainCommanderBracketPreviews() {\n this.hookupTableCellDdlPreviews(\n attrCommanderBracketId\n , Utils.getListFromDict(commanderBrackets)\n );\n }\n \n leave() {\n super.leave();\n }\n}\n","\n\nimport API from \"../../api.js\";\nimport TableBasePage from \"../base_table.js\";\nimport DOM from \"../../dom.js\";\nimport Events from \"../../lib/events.js\";\n\nexport default class PageMtgGame extends TableBasePage {\n static hash = hashPageMtgGame;\n static attrIdRowObject = attrGameId;\n callSaveTableContent = API.saveGame;\n\n constructor(router) {\n super(router);\n }\n\n initialize() {\n this.sharedInitialize();\n this.hookupTcgGame();\n }\n hookupFilters() {\n // this.sharedHookupFilters();\n }\n loadRowTable(rowJson) {\n return;\n }\n getJsonRow(row) {\n return;\n }\n initialiseRowNew(tbody, row) {\n \n }\n postInitialiseRowNewCallback(tbody) {\n \n }\n\n hookupTableMain() {\n super.hookupTableMain();\n }\n hookupTcgGame() {\n this.initGamePage();\n let pageHeading = document.querySelector('.container.company-name .tcg-title.company-name');\n pageHeading.innerText = `MTG Game #${gameId}`;\n }\n\n initGamePage() {\n // Load existing game state from API or show setup\n PageMtgGame.updatePlayerSetup();\n if (typeof gameId !== 'undefined' && gameId) {\n this.loadGameFromServer();\n }\n /*\n else {\n PageMtgGame.updatePlayerSetup();\n }\n */\n \n PageMtgGame.hookupResetButton();\n PageMtgGame.hookupPlayerCountInput();\n this.hookupStartGameButton();\n /*\n this.hookupCommanderDeathIncrementButtons();\n this.hookupEliminateCommanderButtons();\n this.hookupPlayerLifeIncrementButtons();\n this.hookupCommanderDamageIncrementButtons();\n */\n }\n static hookupResetButton() {\n const resetGameButton = document.querySelector('header.game-header .header-right .btn-tcg.btn-tcg-secondary');\n if (resetGameButton) {\n resetGameButton.addEventListener('click', PageMtgGame.resetGame);\n }\n }\n static hookupPlayerCountInput() {\n const playerCountInput = document.getElementById('playerCount');\n if (playerCountInput) {\n playerCountInput.addEventListener('change', PageMtgGame.updatePlayerSetup);\n }\n }\n hookupStartGameButton() {\n const startGameButton = document.querySelector('.setup-section .setup-actions .btn-tcg');\n if (startGameButton) {\n startGameButton.addEventListener('click', () => { this.startGame(); });\n }\n }\n /*\n hookupCommanderDeathIncrementButtons() {\n const commanderDeathIncremementButtons = document.querySelectorAll('#players-grid .player-card .commander-deaths .death-btn');\n if (commanderDeathIncremementButtons) {\n commanderDeathIncremementButtons.forEach((button) => {\n button.addEventListener('click', PageMtgGame.changeCommanderDeaths);\n });\n }\n }\n hookupEliminateCommanderButtons() {\n const eliminateCommanderButtons = document.querySelector('#players-grid .player-card .eliminate-btn');\n if (eliminateCommanderButtons) {\n eliminateCommanderButtons.forEach((button) => {\n button.addEventListener('click', PageMtgGame.toggleEliminate);\n });\n }\n }\n hookupPlayerLifeIncrementButtons() {\n const playerLifeIncrementButtons = document.querySelector('#players-grid .player-card .eliminate-btn');\n if (playerLifeIncrementButtons) {\n playerLifeIncrementButtons.forEach((button) => {\n button.addEventListener('click', PageMtgGame.changeLife);\n });\n }\n }\n hookupCommanderDamageIncrementButtons() {\n const commanderDamageIncrementButtons = document.querySelector('#players-grid .player-card .eliminate-btn');\n if (commanderDamageIncrementButtons) {\n commanderDamageIncrementButtons.forEach((button) => {\n button.addEventListener('click', PageMtgGame.changeCommanderDamage);\n });\n }\n }\n */\n\n async loadGameFromServer() {\n console.log(\"loading game from server\");\n try {\n // Fetch players, rounds, and damage records from API\n const [playersResponse, roundsResponse, damageResponse] = await Promise.all([\n API.getGamePlayers(gameId)\n , API.getGameRounds(gameId)\n , API.getGameDamageRecords(gameId)\n ]);\n console.log({ playersResponse, damageResponse });\n\n let setupSection = document.getElementById('setupSection');\n let gameSection = document.getElementById('gameSection');\n setupSection.classList.remove('hidden');\n gameSection.classList.add('hidden');\n\n if (playersResponse.status !== 'success') {\n console.error('Failed to load players:', playersResponse.message);\n return;\n }\n\n const savedPlayers = playersResponse.data || [];\n const savedRounds = roundsResponse.status === 'success' ? (roundsResponse.data || []) : [];\n const savedDamageRecords = damageResponse.status === 'success' ? (damageResponse.data || []) : [];\n \n players = savedPlayers;\n rounds = savedRounds;\n damageRecords = savedDamageRecords;\n\n if (savedPlayers.length === 0) {\n // No players yet, show setup section\n return;\n }\n\n // Hide setup, show game\n setupSection.classList.add('hidden');\n gameSection.classList.remove('hidden');\n\n console.log({ savedPlayers, damageRecords });\n\n // Render players to DOM\n const latestRoundId = PageMtgGame.getLatestRoundId();\n const latestRound = rounds.filter(round => round[attrRoundId] == latestRoundId)[0];\n const roundDisplayOrderLabel = PageMtgGame.getRoundDisplayOrderLabel();\n DOM.setElementValuesCurrentAndPrevious(roundDisplayOrderLabel, latestRound[flagDisplayOrder]);\n \n this.renderPlayers();\n\n } catch (error) {\n console.error('Error loading game from server:', error);\n }\n }\n static getRoundDisplayOrderLabel() {\n return document.querySelector([\n '#gameSection'\n , ' > .'\n , flagRow\n , '.'\n , flagRound\n , ' > .'\n , flagRow\n , '.'\n , flagRound\n , ' > .'\n , flagRound\n , '.'\n , flagDisplayOrder\n , ' > span.'\n , flagRound\n , '.'\n , flagDisplayOrder\n ].join(''));\n }\n\n renderPlayers() {\n const grid = document.getElementById('playersGrid');\n grid.innerHTML = '';\n \n // let activeRoundId = PageMtgGame.getActiveRoundId();\n const roundDisplayOrderLabel = PageMtgGame.getRoundDisplayOrderLabel();\n const currentRoundDisplayOrder = Number(DOM.getElementValueCurrent(roundDisplayOrderLabel));\n let activeRound = rounds.filter(round => round[flagDisplayOrder] == currentRoundDisplayOrder)[0];\n if (activeRound == null) {\n activeRound = PageMtgGame.makeDefaultGameRound(currentRoundDisplayOrder);\n rounds.push(activeRound);\n }\n DOM.setElementValueCurrent(roundDisplayOrderLabel, activeRound[flagDisplayOrder]);\n \n const previousRoundIds = rounds.filter(round => round[flagDisplayOrder] <= currentRoundDisplayOrder)\n .map(round => round[attrRoundId]);\n players.forEach((player, index) => {\n // Build display name: prefer user_name + deck_name, fallback to player name\n const playerId = player[attrPlayerId];\n let displayName = PageMtgGame.makePlayerDisplayName(playerId, index);\n let damagePlayerPairs = [...players, { [attrPlayerId]: null }];\n let maxCommanderDamageReceived = 0;\n damagePlayerPairs.forEach(damagePlayerPair => {\n const sourceId = damagePlayerPair[attrPlayerId];\n const filteredPlayerDamages = damageRecords.filter(damage => (\n damage[attrRoundId] == activeRound[attrRoundId]\n // previousRoundIds.includes(damage[attrRoundId])\n && damage[attrPlayerId] == playerId\n && damage[attrReceivedFromCommanderPlayerId] == sourceId\n )); //[playerId] || {};\n if (filteredPlayerDamages.length == 0) {\n damageRecords.push(PageMtgGame.makeDefaultGameRoundPlayerDamage(playerId, sourceId));\n }\n maxCommanderDamageReceived = Math.max(\n maxCommanderDamageReceived\n , damageRecords.filter(damage => (\n damage[attrPlayerId] == playerId\n && damage[attrReceivedFromCommanderPlayerId] == sourceId\n && damage[attrReceivedFromCommanderPlayerId] != null\n && previousRoundIds.includes(damage[attrRoundId])\n ))\n .map(damage => damage[flagLifeLoss])\n .reduce((a, b) => a + b, 0)\n );\n });\n\n const totalDamage = damageRecords.filter(damage => (\n damage[attrPlayerId] == playerId\n && previousRoundIds.includes(damage[attrRoundId])\n ))\n .map(damage => damage[flagLifeLoss] - damage[flagLifeGain])\n .reduce((a, b) => a + b, 0);\n let life = startingLife - totalDamage;\n\n let isEliminatedByForce = damageRecords.filter(damage => (\n damage[attrPlayerId] == playerId\n && previousRoundIds.includes(damage[attrRoundId])\n ))\n .map(damage => damage[flagIsEliminated])\n .some(Boolean);\n console.log(\"renderPlayers\");\n console.log({isEliminatedByForce, player, life, maxCommanderDamageReceived});\n const isEliminated = (\n isEliminatedByForce\n || !player[flagActive]\n || life < 1\n || maxCommanderDamageReceived >= 21\n );\n\n const totalCommanderDeaths = damageRecords.filter(damage => (\n damage[attrPlayerId] == playerId\n && damage[attrReceivedFromCommanderPlayerId] == null\n && damage[attrRoundId] == activeRound[attrRoundId]\n ))\n .map(damage => damage[flagCommanderDeaths])\n .reduce((a, b) => a + b, 0);\n const card = document.createElement('div');\n card.className = `player-card ${isEliminated ? 'eliminated' : ''}`;\n card.style.animationDelay = `${index * 0.1}s`;\n card.dataset.playerId = playerId;\n card.dataset.userName = player.user_name || '';\n card.dataset.deckName = player.deck_name || '';\n\n card.innerHTML = `\n
\n
\n
${displayName}
\n
\n Commander Deaths:\n
\n \n ${totalCommanderDeaths}\n \n
\n
\n
\n \n
\n\n
\n \n
${life}
\n \n
\n \n \n \n \n
\n \n
\n \n \n \n \n
\n
\n\n
\n
Commander Damage Taken
\n
\n ${PageMtgGame.renderCommanderDamageRows(\n playerId // playerId\n , player[attrDeckId] // deckId\n )}\n
\n
\n `;\n\n grid.appendChild(card);\n });\n\n this.reorderPlayerCards();\n\n PageMtgGame.renderCommanderDamageLog();\n\n // Hookup all event handlers\n this.hookupGameRoundEvents();\n this.hookupPlayerCardEvents();\n }\n static renderCommanderDamageLog() {\n const currentRoundDisplayOrder = PageMtgGame.getActiveRoundDisplayOrder();\n\n const damageTableBody = document.querySelector('.' + flagDamageLog + '.' + flagContainer + ' table tbody');\n damageTableBody.innerHTML = '';\n \n const previousRoundIds = rounds.filter(round => round[flagDisplayOrder] <= currentRoundDisplayOrder)\n .map(round => round[attrRoundId]);\n let newTableBodyHtml = '';\n damageRecords.forEach((damage) => {\n if (\n damage[flagActive]\n && (\n damage[flagCommanderDeaths] > 0\n || damage[flagLifeGain] != 0\n || damage[flagLifeLoss] != 0\n || damage[flagIsEliminated]\n )\n // && rounds.filter(r => r[attrRoundId] == damage[attrRoundId])[0][flagDisplayOrder] <= currentRoundDisplayOrder\n && previousRoundIds.includes(damage[attrRoundId])\n ) {\n let round = rounds.filter(r => r[attrRoundId] == damage[attrRoundId])[0];\n let player = players.filter(p => p[attrPlayerId] == damage[attrPlayerId])[0];\n let receivedFromPlayer = (damage[attrReceivedFromCommanderPlayerId] == null) ? { [flagName]: ''} : players.filter(p => p[attrPlayerId] == damage[attrReceivedFromCommanderPlayerId])[0];\n newTableBodyHtml += `\n \n ${round[flagDisplayOrder]}\n ${player[flagName]}\n ${receivedFromPlayer[flagName]}\n ${damage[flagLifeGain]}\n ${damage[flagLifeLoss]}\n ${damage[flagCommanderDeaths]}\n ${damage[flagIsEliminated]}\n \n `;\n }\n });\n damageTableBody.innerHTML = newTableBodyHtml;\n }\n static makeDefaultGameRoundPlayerDamage(playerId, receivedFromCommanderPlayerId) {\n let roundId = PageMtgGame.getActiveRoundId();\n return {\n [attrDamageId]: -1 - damageRecords.length\n , [attrRoundId]: roundId\n , [attrPlayerId]: playerId\n , [attrReceivedFromCommanderPlayerId]: receivedFromCommanderPlayerId\n , [flagLifeGain]: 0\n , [flagLifeLoss]: 0\n , [flagCommanderDeaths]: 0\n , [flagIsEliminated]: false\n , [flagActive]: true\n };\n }\n static getLatestRoundId() {\n let roundId = -1;\n if (rounds.length > 0) {\n const highestRoundDisplayOrder = rounds.map(round => { return round[flagDisplayOrder]; })\n .reduce((acc, cur) => Math.max(acc, cur), 0);\n const filteredRounds = rounds.filter(round => round[flagDisplayOrder] == highestRoundDisplayOrder);\n if (filteredRounds.length > 0) {\n roundId = filteredRounds[0][attrRoundId];\n }\n console.log({ \"method\": \"getLatestRoundId\", highestRoundDisplayOrder, filteredRounds, roundId });\n }\n return roundId;\n }\n static getActiveRoundDisplayOrder() {\n const roundDisplayOrderLabel = PageMtgGame.getRoundDisplayOrderLabel();\n return Number(DOM.getElementValueCurrent(roundDisplayOrderLabel));\n }\n static getActiveRoundId() {\n const currentRoundDisplayOrder = PageMtgGame.getActiveRoundDisplayOrder();\n let roundId = 0;\n if (rounds.length > 0) {\n let filteredRounds = rounds.filter(round => round[flagDisplayOrder] == currentRoundDisplayOrder);\n if (filteredRounds.length > 0) roundId = filteredRounds[0][attrRoundId];\n console.log({ \"method\": \"getActiveRoundId\", filteredRounds, roundId });\n }\n return roundId;\n }\n static makePlayerDisplayName(playerId, index) {\n if (playerId == null) {\n return `Player ${index + 1}`;\n }\n const player = players.filter(player => player[attrPlayerId] == playerId)[0];\n const deckId = player[attrDeckId];\n const deck = (deckId == null) ? null : decks.filter(deck => deck[attrDeckId] == deckId)[0];\n const user = (playerId == null) ? null : users[player[attrUserId]];\n return player[flagName] || `${(user == null) ? 'Error' : user[flagName]} - ${(deck == null) ? 'Error' : deck[flagName]}`;\n }\n static renderCommanderDamageRows(playerId) {\n const activeRoundDisplayOrder = PageMtgGame.getActiveRoundDisplayOrder();\n const previousRoundIds = rounds.filter(round => round[flagDisplayOrder] <= activeRoundDisplayOrder)\n .map(round => round[attrRoundId]);\n return players\n .filter(otherPlayer => otherPlayer[attrPlayerId] !== playerId)\n .map(otherPlayer => {\n const sourceId = otherPlayer[attrPlayerId];\n let otherPlayerDisplayName = PageMtgGame.makePlayerDisplayName(sourceId);\n const totalDamage = damageRecords.filter(damage => (\n damage[attrPlayerId] == playerId\n && damage[attrReceivedFromCommanderPlayerId] == sourceId\n // && damage[attrRoundId] == roundId\n && previousRoundIds.includes(damage[attrRoundId])\n ))\n .map(damage => damage[flagLifeLoss])\n .reduce((acc, curr) => acc + curr, 0);\n const isLethal = (totalDamage >= 21);\n\n return `\n
\n from ${otherPlayerDisplayName}\n
\n \n \n ${totalDamage}\n \n
\n
\n `;\n })\n .join('');\n }\n\n hookupGameRoundEvents() {\n let incrementRoundButtonSelector = '#gameSection .' + flagRow + '.' + flagRound + ' button.' + flagRoundDisplayOrderButton;\n Events.hookupEventHandler(\"click\", incrementRoundButtonSelector, (event, button) => {\n const amount = button.classList.contains(flagRoundDisplayOrderPlus) ? 1 : -1;\n const roundDisplayOrderButtonContainer = button.parentElement;\n const roundDisplayOrderLabel = roundDisplayOrderButtonContainer.querySelector('span.' + flagRound + '.' + flagDisplayOrder);\n const currentRoundDisplayOrder = Number(DOM.getElementValueCurrent(roundDisplayOrderLabel));\n const newDisplayOrder = currentRoundDisplayOrder + amount;\n DOM.setElementValueCurrent(roundDisplayOrderLabel, newDisplayOrder);\n DOM.isElementDirty(roundDisplayOrderLabel);\n this.updateAndToggleShowButtonsSaveCancel();\n this.renderPlayers();\n });\n }\n static makeDefaultGameRound(displayOrder) {\n const newDisplayOrder = (displayOrder != null) ? displayOrder : 1 + Math.max(rounds.map(round => round[flagDisplayOrder]));\n return {\n [attrRoundId]: -newDisplayOrder\n , [attrGameId]: gameId\n , [flagNotes]: null\n , [flagDisplayOrder]: newDisplayOrder\n , [flagActive]: true\n };\n }\n hookupPlayerCardEvents() {\n // Life gain buttons\n let lifeGainButtonSelector = '.life-gain-btn';\n Events.hookupEventHandler(\"click\", lifeGainButtonSelector, (event, button) => {\n const playerId = button.dataset.playerId;\n const amount = parseInt(button.dataset.amount);\n const activeRoundId = PageMtgGame.getActiveRoundId();\n const damageIndex = damageRecords.findIndex(damage => (\n damage[attrRoundId] == activeRoundId\n && damage[attrPlayerId] == playerId\n && damage[attrReceivedFromCommanderPlayerId] == null\n ));\n this.changeLife(\n playerId // playerId\n , amount // amount\n , true // isLifeGainNotLoss\n , true // updateDamage\n , damageIndex // damageIndex\n );\n });\n\n // Life loss buttons\n let lifeLossButtonSelector = '.life-loss-btn';\n Events.hookupEventHandler(\"click\", lifeLossButtonSelector, (event, button) => {\n const playerId = button.dataset.playerId;\n const amount = parseInt(button.dataset.amount);\n const activeRoundId = PageMtgGame.getActiveRoundId();\n const damageIndex = damageRecords.findIndex(damage => (\n damage[attrRoundId] == activeRoundId\n && damage[attrPlayerId] == playerId\n && damage[attrReceivedFromCommanderPlayerId] == null\n ));\n this.changeLife(\n playerId // playerId\n , amount // amount\n , false // isLifeGainNotLoss\n , true // updateDamage\n , damageIndex // damageIndex\n );\n });\n\n // Commander death buttons\n let commanderDeathButtonSelector = '.death-btn';\n Events.hookupEventHandler(\"click\", commanderDeathButtonSelector, (event, button) => {\n const playerId = button.dataset.playerId;\n const isMinusButton = button.classList.contains('death-minus');\n const amount = (isMinusButton) ? -1 : 1;\n this.changeCommanderDeaths(playerId, amount);\n });\n\n // Commander damage buttons\n let commmanderDamageButtonSelector = '.damage-btn';\n Events.hookupEventHandler(\"click\", commmanderDamageButtonSelector, (event, button) => {\n const playerId = button.dataset.playerId;\n const sourceId = button.dataset.sourceId;\n const isMinusButton = button.classList.contains('damage-minus');\n const amount = (isMinusButton) ? -1 : 1;\n this.changeCommanderDamage(playerId, sourceId, amount);\n });\n\n // Eliminate buttons\n let eliminatePlayerButtonSelector = '.eliminate-btn';\n Events.hookupEventHandler(\"click\", eliminatePlayerButtonSelector, (event, button) => {\n const playerId = button.dataset.playerId;\n this.toggleEliminate(playerId);\n });\n }\n\n changeLife(playerId, amount, isLifeGainNotLoss = false, updateDamage = false, damageIndex = null) {\n const card = document.querySelector(`.player-card[data-player-id=\"${playerId}\"]`);\n // if (!card || card.classList.contains('eliminated')) return;\n\n const lifeInput = card.querySelector(`.life-value[data-player-id=\"${playerId}\"]`);\n const lifeDisplay = card.querySelector(`.life-display[data-player-id=\"${playerId}\"]`);\n\n const currentLife = parseInt(lifeInput.value) || 0;\n const newLife = currentLife + amount * ((isLifeGainNotLoss) ? 1 : -1);\n\n DOM.setElementAttributeValueCurrent(lifeDisplay, newLife);\n DOM.isElementDirty(lifeDisplay);\n lifeInput.value = newLife;\n lifeDisplay.textContent = newLife;\n\n if (updateDamage) {\n let fieldFlag = (isLifeGainNotLoss) ? flagLifeGain : flagLifeLoss;\n damageRecords[damageIndex][fieldFlag] += amount;\n }\n\n PageMtgGame.renderCommanderDamageLog();\n\n // PageMtgGame.debouncedSave();\n this.updateAndToggleShowButtonsSaveCancel();\n }\n\n changeCommanderDamage(playerId, sourceId, amount) {\n const card = document.querySelector(`.player-card[data-player-id=\"${playerId}\"]`);\n // if (!card || card.classList.contains('eliminated')) return;\n\n const damageInput = card.querySelector(`.damage-value[data-player-id=\"${playerId}\"][data-source-id=\"${sourceId}\"]`);\n const damageDisplay = card.querySelector(`.damage-display[data-player-id=\"${playerId}\"][data-source-id=\"${sourceId}\"]`);\n\n const currentDamage = parseInt(damageInput.value) || 0;\n const newDamage = Math.max(0, currentDamage + amount);\n amount = newDamage - currentDamage;\n DOM.setElementAttributeValueCurrent(damageDisplay, newDamage);\n DOM.isElementDirty(damageDisplay);\n damageInput.value = newDamage;\n damageDisplay.textContent = newDamage;\n\n // Update lethal class\n if (newDamage >= 21) {\n damageDisplay.classList.add('lethal');\n } else {\n damageDisplay.classList.remove('lethal');\n }\n\n const activeRoundId = PageMtgGame.getActiveRoundId();\n const damageIndex = damageRecords.findIndex(damageRecord => (\n damageRecord[attrRoundId] == activeRoundId\n && damageRecord[attrPlayerId] == playerId\n && damageRecord[attrReceivedFromCommanderPlayerId] == sourceId\n ));\n damageRecords[damageIndex][flagLifeLoss] += amount;\n \n let isLifeGainNotLoss = false;\n this.changeLife(\n playerId // playerId\n , -amount // amount\n , isLifeGainNotLoss // isLifeGainNotLoss\n , false // updateDamage\n , damageIndex // damageIndex\n );\n // PageMtgGame.debouncedSave();\n }\n\n changeCommanderDeaths(playerId, amount) {\n const card = document.querySelector(`.player-card[data-player-id=\"${playerId}\"]`);\n // if (!card || card.classList.contains('eliminated')) return;\n\n const deathDisplay = card.querySelector(`.death-display[data-player-id=\"${playerId}\"]`);\n const currentDeaths = parseInt(deathDisplay.textContent) || 0;\n const newDeaths = Math.max(0, currentDeaths + amount);\n\n deathDisplay.textContent = newDeaths;\n DOM.setElementAttributeValueCurrent(deathDisplay, newDeaths);\n DOM.isElementDirty(deathDisplay);\n\n const activeRoundId = PageMtgGame.getActiveRoundId();\n const damageIndex = damageRecords.findIndex(damage => (\n damage[attrRoundId] == activeRoundId\n && damage[attrPlayerId] == playerId\n && damage[attrReceivedFromCommanderPlayerId] == null\n ));\n damageRecords[damageIndex][flagCommanderDeaths] = newDeaths;\n\n PageMtgGame.renderCommanderDamageLog();\n\n // PageMtgGame.debouncedSave();\n this.updateAndToggleShowButtonsSaveCancel();\n }\n\n toggleEliminate(playerId) {\n const card = document.querySelector(`.player-card[data-player-id=\"${playerId}\"]`);\n if (!card) return;\n\n const eliminateBtn = card.querySelector(`.eliminate-btn[data-player-id=\"${playerId}\"]`);\n const wasEliminated = card.classList.contains('eliminated');\n\n if (wasEliminated) {\n card.classList.remove('eliminated');\n eliminateBtn.textContent = 'Eliminate';\n } else {\n card.classList.add('eliminated');\n eliminateBtn.textContent = 'Revive';\n }\n const isEliminated = card.classList.contains('eliminated');\n\n const activeRoundId = PageMtgGame.getActiveRoundId();\n const damageIndex = damageRecords.findIndex(damage => (\n damage[attrRoundId] == activeRoundId\n && damage[attrPlayerId] == playerId\n && damage[attrReceivedFromCommanderPlayerId] == null\n ));\n damageRecords[damageIndex][flagIsEliminated] = isEliminated;\n\n DOM.setElementAttributeValueCurrent(eliminateBtn, isEliminated);\n DOM.isElementDirty(eliminateBtn);\n\n this.reorderPlayerCards();\n PageMtgGame.renderCommanderDamageLog();\n\n // PageMtgGame.debouncedSave();\n this.updateAndToggleShowButtonsSaveCancel();\n }\n reorderPlayerCards() {\n let playerGrid = document.getElementById('playersGrid');\n let currentPlayerCards = playerGrid.querySelectorAll('.player-card');\n let newPlayerCards = [];\n let playerCardMetas = [];\n currentPlayerCards.forEach((playerCard, index) => {\n newPlayerCards.push(playerCard.cloneNode(true));\n playerCardMetas.push({\n [flagIsEliminated]: playerCard.classList.contains(flagIsEliminated)\n , [attrPlayerId]: playerCard.dataset[\"playerId\"]\n , [flagDisplayOrder]: index\n });\n });\n let activeRoundDisplayOrder = PageMtgGame.getActiveRoundDisplayOrder();\n let newPlayerGridInnerHTML = '';\n let playerIdA, playerIdB, isEliminatedAsIntA, isEliminatedAsIntB, playerA, playerB, indexPlayerCard;\n playerCardMetas.sort((a, b) => {\n playerIdA = a[attrPlayerId];\n playerIdB = b[attrPlayerId];\n isEliminatedAsIntA = PageMtgGame.isPlayerEliminated(playerIdA, activeRoundDisplayOrder) ? 1 : 0;\n isEliminatedAsIntB = PageMtgGame.isPlayerEliminated(playerIdB, activeRoundDisplayOrder) ? 1 : 0;\n playerA = players.filter(p => p[attrPlayerId] == playerIdA)[0];\n playerB = players.filter(p => p[attrPlayerId] == playerIdB)[0];\n return (\n players.length * isEliminatedAsIntA\n + playerA[flagDisplayOrder]\n ) - (\n players.length * isEliminatedAsIntB\n + playerB[flagDisplayOrder]\n );\n }).forEach((playerCardMeta) => {\n indexPlayerCard = playerCardMeta[flagDisplayOrder];\n newPlayerGridInnerHTML += newPlayerCards[indexPlayerCard].outerHTML;\n });\n\n playerGrid.innerHTML = newPlayerGridInnerHTML;\n\n playerGrid.querySelectorAll('.' + flagInitialised).forEach((initialisedElement) => {\n initialisedElement.classList.remove(flagInitialised);\n });\n\n this.hookupPlayerCardEvents();\n }\n static isPlayerEliminated(playerId, roundDisplayOrder = null) {\n if (roundDisplayOrder == null) roundDisplayOrder = PageMtgGame.getActiveRoundDisplayOrder();\n const filteredRoundIds = rounds.filter(round => round[flagDisplayOrder] <= roundDisplayOrder)\n .map(round => round[attrRoundId]);\n let hasDamageWithIsEliminated = damageRecords.filter(damage => (\n // damage[attrRoundId] <= roundDisplayOrder\n filteredRoundIds.includes(damage[attrRoundId])\n && damage[attrPlayerId] == playerId\n && damage[flagIsEliminated]\n )).length > 0;\n let damageFromOtherPlayers = {};\n let otherPlayerId;\n damageRecords.filter(damage => (\n // damage[attrRoundId] <= roundId\n filteredRoundIds.includes(damage[attrRoundId])\n && damage[attrPlayerId] == playerId\n && damage[attrReceivedFromCommanderPlayerId] != null\n ))\n .forEach((damage) => {\n otherPlayerId = damage[attrReceivedFromCommanderPlayerId];\n damageFromOtherPlayers[otherPlayerId] = \n damage[flagLifeLoss]\n + ((damageFromOtherPlayers[otherPlayerId] == null) ? 0 : damageFromOtherPlayers[otherPlayerId]);\n });\n let maxDamageFromOtherCommander = Object.keys(damageFromOtherPlayers)\n .map((playerId) => damageFromOtherPlayers[playerId])\n .reduce((acc, cur) => Math.max(acc, cur), 0);\n let totalDamageTaken = damageRecords.filter(damage => (\n // damage[attrRoundId] <= roundId\n filteredRoundIds.includes(damage[attrRoundId])\n && damage[attrPlayerId] == playerId\n ))\n .map((damage) => damage[flagLifeLoss] - damage[flagLifeGain])\n .reduce((a, b) => a + b, 0);\n console.log({ roundDisplayOrder, filteredRoundIds, hasDamageWithIsEliminated, maxDamageFromOtherCommander, totalDamageTaken });\n return (\n hasDamageWithIsEliminated\n || maxDamageFromOtherCommander >= 21\n || totalDamageTaken >= startingLife\n );\n }\n\n static updatePlayerSetup() {\n const playerCountInput = document.getElementById('playerCount');\n if (!playerCountInput) return;\n\n const playerCount = parseInt(playerCountInput.value);\n const grid = document.getElementById('playerSetupGrid');\n if (!grid) return;\n\n grid.innerHTML = '';\n const wrapperTemplate = document.getElementById(playerSetupWrapperTemplateId);\n let player, wrapper, wrapperHeading, userDdl, deckDdl, nameInput;\n for (let i = 0; i < playerCount; i++) {\n if (i < players.length) {\n player = players[i];\n }\n else {\n player = PageMtgGame.makeDefaultGamePlayer();\n players.push(player);\n }\n wrapper = wrapperTemplate.cloneNode(true);\n wrapper.removeAttribute(\"id\");\n wrapper.setAttribute(flagDisplayOrder, i + 1);\n wrapper.classList.remove(flagIsCollapsed);\n wrapperHeading = wrapper.querySelector('label');\n wrapperHeading.innerText = 'Player ' + (i + 1);\n userDdl = wrapper.querySelector('.playerUser select');\n DOM.setElementValuesCurrentAndPrevious(userDdl, player[attrUserId]);\n deckDdl = wrapper.querySelector('.playerDeck select');\n DOM.setElementValuesCurrentAndPrevious(deckDdl, player[attrDeckId]);\n nameInput = wrapper.querySelector('.playerName input');\n DOM.setElementValuesCurrentAndPrevious(nameInput, player[flagName]);\n console.log('player: ', player);\n grid.appendChild(wrapper);\n }\n }\n static makeDefaultGamePlayer() {\n return {\n [attrPlayerId]: -players.length\n , [attrGameId]: gameId\n , [attrUserId]: user[attrUserId]\n , [attrDeckId]: 0\n , [flagName]: \"\"\n , [flagNotes]: null\n , [flagDisplayOrder]: players.length\n , [flagActive]: true\n };\n }\n\n async startGame() {\n const playerCountInput = document.getElementById('playerCount');\n if (!playerCountInput) return;\n\n const playerCount = parseInt(playerCountInput.value);\n const playersToSave = [];\n\n let playerSetupWrapper, playerId, player, userDdl, userId, deckDdl, deckId, nameInput, name;\n for (let i = 0; i < playerCount; i++) {\n playerSetupWrapper = document.querySelector('.player-name-input-wrapper[' + flagDisplayOrder + '=\"' + (i + 1) + '\"]');\n userDdl = playerSetupWrapper.querySelector('.playerUser select');\n deckDdl = playerSetupWrapper.querySelector('.playerDeck select');\n nameInput = playerSetupWrapper.querySelector('.playerName input');\n \n userId = DOM.getElementValueCurrent(userDdl);\n deckId = DOM.getElementValueCurrent(deckDdl);\n name = nameInput ? nameInput.value.trim() || null : null; // `Player ${i + 1}` : `Player ${i + 1}`;\n\n playerId = playerSetupWrapper.getAttribute(attrPlayerId);\n player = players.filter(p => p[attrPlayerId] == playerId)[0];\n playersToSave.push({\n ...player\n , [attrGameId]: gameId\n , [attrUserId]: userId\n , [attrDeckId]: deckId\n , [flagName]: name\n , [flagDisplayOrder]: i + 1\n , [flagActive]: true\n });\n }\n\n // Save players to server\n const comment = 'Save players';\n const self = this;\n API.saveGamePlayers(playersToSave, null, comment)\n .then(data => {\n if (data[flagStatus] == flagSuccess) {\n self.leave();\n window.location.reload();\n }\n else {\n console.error('Failed to save players:', data[flagMessage]);\n PageMtgGame.showError('An error occurred while creating the game');\n }\n })\n .catch(error => {\n console.error('Error creating game:', error);\n PageMtgGame.showError('An error occurred while creating the game');\n })\n .finally(() => {\n });\n }\n\n static resetGame() {\n if (confirm('Are you sure you want to start a new game? Current game will be lost.')) {\n localStorage.removeItem(`mtgGame_${gameId}`);\n window.location.href = hashPageGames;\n }\n }\n\n async saveGame() {\n /*\n const gameState = {\n [flagPlayer]: players\n , [flagRound]: rounds\n , [flagDamage]: damageRecords\n };\n if (gameState[flagPlayer].length > 0) {\n localStorage.setItem(`mtgGame_${gameId}`, JSON.stringify(gameState));\n PageMtgGame.showSaveIndicator();\n }\n */\n const comment = 'Save player damage';\n const self = this;\n API.saveGameRoundPlayerDamages(rounds, damageRecords, null, comment)\n .then(data => {\n if (data[flagStatus] == flagSuccess) {\n self.leave();\n window.location.reload();\n }\n else {\n console.error('Failed to save player damages:', data[flagMessage]);\n PageMtgGame.showError('An error occurred while saving player damages');\n }\n })\n .catch(error => {\n console.error('Error saving player damages:', error);\n PageMtgGame.showError('An error occurred while saving player damages');\n })\n .finally(() => {\n });\n }\n /*\n static debouncedSave() {\n clearTimeout(PageMtgGame._saveTimeout);\n PageMtgGame._saveTimeout = setTimeout(() => PageMtgGame.saveGame(), 500);\n }\n\n static showSaveIndicator() {\n const indicator = document.getElementById('saveIndicator');\n if (indicator) {\n indicator.classList.add('show');\n setTimeout(() => {\n indicator.classList.remove('show');\n }, 2000);\n }\n }\n */\n saveRecordsTableDirty() {\n this.saveGame();\n }\n static showError(message) {\n // Check if there's an overlay error element\n const errorOverlay = document.getElementById('overlayError');\n if (errorOverlay) {\n const errorLabel = errorOverlay.querySelector('.error-message, #labelError');\n if (errorLabel) {\n errorLabel.textContent = message;\n }\n errorOverlay.classList.remove('hidden');\n errorOverlay.style.display = 'flex';\n } else {\n // Fallback to alert\n alert(message);\n }\n }\n\n leave() {\n super.leave();\n }\n}\n\n// Static timeout reference for debouncing\nPageMtgGame._saveTimeout = null;\n","\nimport API from \"../../api.js\";\nimport TableBasePage from \"../base_table.js\";\nimport Utils from \"../../lib/utils.js\";\n\nexport default class PageMtgGames extends TableBasePage {\n static hash = hashPageMtgGames;\n static attrIdRowObject = attrGameId;\n callSaveTableContent = API.saveGame;\n\n constructor(router) {\n super(router);\n }\n\n initialize() {\n this.sharedInitialize();\n }\n hookupFilters() {\n /*\n this.sharedHookupFilters();\n this.hookupFilterActive();\n */\n }\n\n loadRowTable(rowJson) {\n if (rowJson == null) return;\n if (_verbose) { Utils.consoleLogIfNotProductionEnvironment(\"applying data row: \", rowJson); }\n }\n getJsonRow(row) {\n return;\n }\n initialiseRowNew(tbody, row) {\n }\n postInitialiseRowNewCallback(tbody) {\n }\n\n hookupTableMain() {\n super.hookupTableMain();\n // this.hookupTableMainRows();\n this.hookupTcgGames();\n // PageMtgGames.hideNewGameForm();\n }\n hookupTcgGames() {\n console.log(\"hookupTableMain PageMtgGames\");\n // Initialize form submission\n const newGameForm = document.getElementById('newGameForm');\n if (newGameForm) {\n newGameForm.addEventListener('submit', this.handleNewGameSubmit.bind(this)); // () => { this.handleNewGameSubmit.bind(this); });\n }\n\n // Initialize filter form\n const filterForm = document.getElementById('formFilters');\n if (filterForm) {\n filterForm.addEventListener('submit', PageMtgGames.handleFilterSubmit);\n }\n\n // Close modal on escape key\n document.addEventListener('keydown', function(e) {\n if (e.key === 'Escape') {\n PageMtgGames.hideNewGameForm();\n }\n });\n\n // Close modal on backdrop click\n const modal = document.getElementById('newGameModal');\n if (modal) {\n modal.addEventListener('click', function(e) {\n if (e.target === modal) {\n PageMtgGames.hideNewGameForm();\n }\n });\n }\n\n // Button onclicks\n const newGameButton = document.getElementById('btnNewGame');\n if (newGameButton) {\n newGameButton.addEventListener('click', PageMtgGames.showNewGameForm);\n }\n const cancelNewGameButtons = document.querySelectorAll(\n '#newGameForm .form-actions .btn-tcg.btn-tcg-secondary'\n + ','\n + '#newGameModal .modal-content .modal-header .modal-close'\n );\n if (cancelNewGameButtons.length > 0) {\n cancelNewGameButtons.forEach((button) => {\n button.addEventListener('click', PageMtgGames.hideNewGameForm);\n });\n }\n\n }\n static showNewGameForm() {\n const modal = document.getElementById('newGameModal');\n if (modal) {\n modal.classList.remove(flagIsCollapsed);\n document.body.style.overflow = 'hidden';\n\n // Focus on first input\n const firstInput = modal.querySelector('input, select');\n if (firstInput) {\n firstInput.focus();\n }\n }\n }\n static hideNewGameForm() {\n const modal = document.getElementById('newGameModal');\n if (modal) {\n modal.classList.add(flagIsCollapsed);\n document.body.style.overflow = '';\n\n // Reset form\n const form = document.getElementById('newGameForm');\n if (form) {\n form.reset();\n }\n }\n }\n async handleNewGameSubmit(e) {\n e.preventDefault();\n\n const form = e.target;\n const formData = new FormData(form);\n\n const gameType = formData.get('game_type');\n const gameData = {\n [attrGameId]: -1\n , [flagIsCommander]: gameType === 'commander'\n , [flagIsDraft]: gameType === 'draft'\n , [flagIsSealed]: gameType === 'sealed'\n , [flagLocationName]: formData.get(flagLocationName) || null\n , [flagNotes]: formData.get(flagNotes) || null\n , [flagStartOn]: new Date().toISOString()\n , [flagStartingLife]: formData.get(flagStartingLife) || 40\n , [flagActive]: true\n };\n\n const submitBtn = form.querySelector('button[type=\"submit\"]');\n const originalText = submitBtn.textContent;\n submitBtn.textContent = 'Creating...';\n submitBtn.disabled = true;\n\n const games = [gameData];\n const comment = 'Create new game';\n API.saveGame(games, form, comment)\n .then(data => {\n if (data[flagStatus] == flagSuccess) {\n if (_verbose) { \n Utils.consoleLogIfNotProductionEnvironment('Records saved!');\n Utils.consoleLogIfNotProductionEnvironment('Data received:', data);\n }\n const gamePageHash = `${hashPageGame}/${data[attrGameId]}`;\n let filtersJson = {};\n this.leave();\n API.goToHash(gamePageHash, filtersJson);\n }\n else {\n Utils.consoleLogIfNotProductionEnvironment(\"error: \" + data[flagMessage]);\n // OverlayError.show(data[flagMessage]);\n window.location.reload();\n }\n })\n .catch(error => {\n console.error('Error creating game:', error);\n PageMtgGames.showError('An error occurred while creating the game');\n })\n .finally(() => {\n submitBtn.textContent = originalText;\n submitBtn.disabled = false;\n });\n \n }\n static handleFilterSubmit(e) {\n // Let the form submit normally - it will reload with query params\n // You can add client-side filtering here if needed\n }\n static getCSRFToken() {\n // Try meta tag first\n const metaTag = document.querySelector('meta[name=\"csrf-token\"]');\n if (metaTag) {\n return metaTag.getAttribute('content');\n }\n\n // Try hidden input\n const hiddenInput = document.querySelector('input[name=\"csrf_token\"]');\n if (hiddenInput) {\n return hiddenInput.value;\n }\n\n // Try cookie\n const cookies = document.cookie.split(';');\n for (let cookie of cookies) {\n const [name, value] = cookie.trim().split('=');\n if (name === 'csrf_token') {\n return value;\n }\n }\n\n return '';\n }\n static showError(message) {\n // Check if there's an overlay error element\n const errorOverlay = document.getElementById('overlayError');\n if (errorOverlay) {\n const errorLabel = errorOverlay.querySelector('.error-message, #labelError');\n if (errorLabel) {\n errorLabel.textContent = message;\n }\n errorOverlay.classList.remove(flagIsCollapsed);\n errorOverlay.style.display = 'flex';\n } else {\n // Fallback to alert\n alert(message);\n }\n }\n static showSuccess(message) {\n // Could implement a toast notification here\n console.log('Success:', message);\n }\n static joinGame(gameId) {\n window.location.href = `${hashPageGame}/${gameId}`;\n }\n static async deleteGame(gameId) {\n if (!confirm('Are you sure you want to delete this game? This action cannot be undone.')) {\n return;\n }\n\n try {\n const gameData = {\n 'game_id': gameId,\n 'active': false\n };\n\n const response = await fetch(hashSaveGame, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-CSRFToken': PageMtgGames.getCSRFToken()\n },\n body: JSON.stringify({\n [flagGame]: [gameData],\n 'form-filters': {},\n 'comment': 'Game deleted'\n })\n });\n\n const result = await response.json();\n\n if (result.status === 'success') {\n // Remove the row from the table\n const row = document.querySelector(`tr[data-game-id=\"${gameId}\"]`);\n if (row) {\n row.style.animation = 'tcg-fadeOut 0.3s ease-out forwards';\n setTimeout(() => row.remove(), 300);\n }\n } else {\n PageMtgGames.showError(result.message || 'Failed to delete game');\n }\n } catch (error) {\n console.error('Error deleting game:', error);\n PageMtgGames.showError('An error occurred while deleting the game');\n }\n }\n\n toggleShowButtonsSaveCancel() {}\n leave() {\n super.leave();\n }\n}\n","\n\nimport API from \"../../api.js\";\nimport BasePage from \"../base.js\";\nimport DOM from \"../../dom.js\";\nimport Events from \"../../lib/events.js\";\n\nexport default class PageMtgHome extends BasePage {\n static hash = hashPageMtgHome;\n\n constructor(router) {\n super(router);\n }\n\n initialize() {\n this.sharedInitialize();\n this.hookupTcgHome();\n }\n\n hookupTcgHome() {\n }\n\n leave() {\n super.leave();\n }\n}\n","import BasePage from \"../base.js\";\n\nexport default class PageAccessibilityReport extends BasePage {\n static hash = hashPageAccessibilityReport;\n\n constructor(router) {\n super(router);\n }\n\n initialize() {\n this.sharedInitialize();\n }\n\n leave() {\n super.leave();\n }\n}\n","import BasePage from \"../base.js\";\n\nexport default class PageAccessibilityStatement extends BasePage {\n static hash = hashPageAccessibilityStatement;\n\n constructor(router) {\n super(router);\n }\n\n initialize() {\n this.sharedInitialize();\n }\n\n leave() {\n super.leave();\n }\n}\n","\nimport BasePage from \"../base.js\";\n\nexport default class PageLicense extends BasePage {\n static hash = hashPageLicense;\n\n constructor(router) {\n super(router);\n }\n\n initialize() {\n this.sharedInitialize();\n }\n\n leave() {\n super.leave();\n }\n}","\nimport BasePage from \"../base.js\";\n\nexport default class PagePrivacyPolicy extends BasePage {\n static hash = hashPagePrivacyPolicy;\n\n constructor(router) {\n super(router);\n }\n\n initialize() {\n this.sharedInitialize();\n }\n\n leave() {\n super.leave();\n }\n}","import BasePage from \"../base.js\";\n\nexport default class PageRetentionSchedule extends BasePage {\n static hash = hashPageDataRetentionSchedule;\n\n constructor(router) {\n super(router);\n }\n\n initialize() {\n this.sharedInitialize();\n }\n\n leave() {\n super.leave();\n }\n}\n","\n\nexport default class MixinPage {\n constructor(pageCurrent) {\n this.page = pageCurrent;\n }\n\n initialize() {\n Utils.consoleLogIfNotProductionEnvironment('hookup start for ', this.page.hash);\n this.hookupFilters();\n this.hookupLocalStorage();\n }\n hookupFilters() {\n }\n hookupLocalStorage() {\n \n }\n \n leave() {}\n}\n","\nimport MixinPage from \"./mixin.js\";\n\nexport default class TableMixinPage extends MixinPage {\n constructor(pageCurrent) {\n super(pageCurrent);\n }\n initialize() {\n super.initialize();\n this.hookupFilters();\n this.hookupTable();\n }\n hookupFilters() {\n // Implement filter-specific functionality here\n }\n hookupTable() {\n // Implement table-specific functionality here\n }\n}","\nimport API from \"../../api.js\";\nimport TableMixinPage from \"../mixin_table.js\";\nimport DOM from \"../../dom.js\";\nimport TableBasePage from \"../base_table.js\";\n\nexport default class PageUser extends TableBasePage {\n static hash = hashPageUserAccount;\n static attrIdRowObject = attrUserId;\n callSaveTableContent = API.saveUsers;\n\n constructor(router) {\n super(router);\n this.mixin = new TableMixinPage(this);\n }\n\n initialize() {\n this.sharedInitialize();\n this.hookupTableMain();\n }\n\n\n hookupFilters() {\n }\n\n loadRowTable(rowJson) {\n if (rowJson == null) return;\n if (_verbose) { Utils.consoleLogIfNotProductionEnvironment(\"applying data row: \", rowJson); }\n }\n getTableRecords(dirtyOnly = false) {\n dirtyOnly = true;\n let container = document.querySelector('.' + flagCard + '.' + flagUser);\n return [this.getJsonRow(container)];\n }\n getJsonRow(container) {\n console.log(\"getJsonRow: \", container);\n if (container == null) return;\n let inputFirstname = container.querySelector(' #' + flagFirstname);\n let inputSurname = container.querySelector(' #' + flagSurname);\n let inputEmail = container.querySelector(' #' + flagEmail);\n\n let idUser = container.getAttribute(attrUserId);\n \n let jsonRow = {\n [attrUserAuth0Id]: null\n , [flagEmail]: null\n , [flagIsEmailVerified]: null\n , [flagIsSuperUser]: null\n , [flagCanAdminUser]: null\n };\n\n jsonRow[attrUserId] = idUser;\n jsonRow[flagFirstname] = DOM.getElementAttributeValueCurrent(inputFirstname);\n jsonRow[flagSurname] = DOM.getElementAttributeValueCurrent(inputSurname);\n jsonRow[flagEmail] = DOM.getElementAttributeValueCurrent(inputEmail);\n return jsonRow;\n }\n \n initialiseRowNew(tbody, row) {\n }\n postInitialiseRowNewCallback(tbody) {\n }\n\n hookupTableMain() {\n super.hookupTableMain();\n this.hookupFieldsFirstname();\n this.hookupFieldsSurname();\n this.hookupFieldsEmail();\n }\n hookupFieldsFirstname() {\n this.hookupChangeHandlerTableCells('.' + flagCard + '.' + flagUser + ' #' + flagFirstname);\n }\n hookupFieldsSurname() {\n this.hookupChangeHandlerTableCells('.' + flagCard + '.' + flagUser + ' #' + flagSurname);\n }\n hookupFieldsEmail() {\n this.hookupChangeHandlerTableCells('.' + flagCard + '.' + flagUser + ' #' + flagEmail);\n }\n\n leave() {\n super.leave();\n }\n}\n","\nimport API from \"../../api\";\nimport TableMixinPage from \"../mixin_table\";\nimport DOM from \"../../dom\";\nimport TableBasePage from \"../base_table\";\nimport Utils from \"../../lib/utils\";\n\nexport default class PageUsers extends TableBasePage {\n static hash = hashPageUserAccounts;\n static attrIdRowObject = attrUserId;\n callSaveTableContent = API.saveUsers;\n\n constructor(router) {\n super(router);\n this.mixin = new TableMixinPage(this);\n }\n\n initialize() {\n this.sharedInitialize();\n }\n\n hookupFilters() {\n this.sharedHookupFilters();\n this.hookupFilterActive();\n }\n\n loadRowTable(rowJson) {\n if (rowJson == null) return;\n if (_verbose) { Utils.consoleLogIfNotProductionEnvironment(\"applying data row: \", rowJson); }\n }\n getJsonRow(row) {\n if (row == null) return;\n let inputFirstname = row.querySelector('td.' + flagFirstname + ' .' + flagFirstname);\n let inputSurname = row.querySelector('td.' + flagSurname + ' .' + flagSurname);\n let inputNotes = row.querySelector('td.' + flagNotes + ' .' + flagNotes);\n let buttonActive = row.querySelector('td.' + flagActive + ' .' + flagActive);\n\n let jsonRow = {\n [attrUserAuth0Id]: null\n , [flagEmail]: null\n , [flagIsEmailVerified]: null\n , [flagIsSuperUser]: null\n , [flagCanAdminUser]: null\n };\n jsonRow[attrUserId] = row.getAttribute(attrUserId);\n jsonRow[flagFirstname] = DOM.getElementAttributeValueCurrent(inputFirstname);\n jsonRow[flagSurname] = DOM.getElementAttributeValueCurrent(inputSurname);\n jsonRow[flagNotes] = DOM.getElementAttributeValueCurrent(inputNotes);\n jsonRow[flagActive] = buttonActive.classList.contains(flagDelete);\n\n console.log(\"jsonRow\");\n console.log(jsonRow);\n\n return jsonRow;\n }\n \n initialiseRowNew(tbody, row) {\n \n }\n postInitialiseRowNewCallback(tbody) {\n let newRows = tbody.querySelectorAll('tr.' + flagRowNew);\n let newestRow = newRows[0];\n let clickableElementsSelector = [].join('');\n newestRow.querySelectorAll(clickableElementsSelector).forEach((clickableElement) => {\n clickableElement.click();\n });\n }\n\n hookupTableMain() {\n super.hookupTableMain();\n this.hookupFieldsFirstname();\n this.hookupFieldsSurname();\n this.hookupFieldsNotesTable();\n this.hookupFieldsActive();\n }\n hookupFieldsFirstname() {\n this.hookupChangeHandlerTableCells(flagFirstname);\n }\n hookupFieldsSurname() {\n this.hookupChangeHandlerTableCells(flagSurname);\n }\n\n leave() {\n super.leave();\n }\n}\n","\n// Pages\n// Core\n// TCG\nimport PageMtgDecks from './pages/tcg/mtg_decks.js';\nimport PageMtgGame from './pages/tcg/mtg_game.js';\nimport PageMtgGames from './pages/tcg/mtg_games.js';\nimport PageMtgHome from './pages/tcg/mtg_home.js';\n// Legal\nimport PageAccessibilityReport from './pages/legal/accessibility_report.js';\nimport PageAccessibilityStatement from './pages/legal/accessibility_statement.js';\nimport PageLicense from './pages/legal/license.js';\nimport PagePrivacyPolicy from './pages/legal/privacy_policy.js';\nimport PageRetentionSchedule from './pages/legal/retention_schedule.js';\n// User\n// import PageUserLogin from './pages/user/login.js';\n// import PageUserLogout from './pages/user/logout.js';\nimport PageUser from './pages/user/user.js';\nimport PageUsers from './pages/user/users.js';\n\nimport API from './api.js';\nimport DOM from './dom.js';\nimport Utils from './lib/utils.js';\n\n\nexport default class Router {\n constructor() {\n // Pages\n this.pages = {};\n // Core\n // TCG\n this.pages[hashPageMtgDecks] = { name: 'PageMtgDecks', module: PageMtgDecks };\n this.pages[hashPageMtgGame] = { name: 'PageMtgGame', module: PageMtgGame };\n this.pages[hashPageMtgGames] = { name: 'PageMtgGames', module: PageMtgGames };\n this.pages[hashPageMtgHome] = { name: 'PageMtgGame', module: PageMtgHome };\n // Legal\n this.pages[hashPageAccessibilityStatement] = { name: 'PageAccessibilityStatement', module: PageAccessibilityStatement };\n this.pages[hashPageDataRetentionSchedule] = { name: 'PageDataRetentionSchedule', module: PageRetentionSchedule };\n this.pages[hashPageLicense] = { name: 'PageLicense', module: PageLicense };\n this.pages[hashPagePrivacyPolicy] = { name: 'PagePrivacyPolicy', module: PagePrivacyPolicy };\n // User\n // this.pages[hashPageUserLogin] = { name: 'PageUserLogin', module: PageUserLogin }; // pathModule: './pages/user/login.js' };\n // this.pages[hashPageUserLogout] = { name: 'PageUserLogout', module: PageUserLogout }; // pathModule: './pages/user/logout.js' };\n this.pages[hashPageUserAccount] = { name: 'PageUser', module: PageUser };\n this.pages[hashPageUserAccounts] = { name: 'PageUsers', module: PageUsers };\n // Routes\n this.routes = {};\n // Core\n // TCG\n this.routes[hashPageMtgDecks] = (isPopState = false) => this.navigateToHash(hashPageMtgDecks, isPopState);\n this.routes[hashPageMtgGame] = (isPopState = false) => this.navigateToHash(hashPageMtgGame, isPopState);\n this.routes[hashPageMtgGames] = (isPopState = false) => this.navigateToHash(hashPageMtgGames, isPopState);\n this.routes[hashPageMtgHome] = (isPopState = false) => this.navigateToHash(hashPageMtgHome, isPopState);\n // Legal\n this.routes[hashPageAccessibilityStatement] = (isPopState = false) => this.navigateToHash(hashPageAccessibilityStatement, isPopState);\n this.routes[hashPageDataRetentionSchedule] = (isPopState = false) => this.navigateToHash(hashPageDataRetentionSchedule, isPopState);\n this.routes[hashPageLicense] = (isPopState = false) => this.navigateToHash(hashPageLicense, isPopState);\n this.routes[hashPagePrivacyPolicy] = (isPopState = false) => this.navigateToHash(hashPagePrivacyPolicy, isPopState);\n // User\n // this.routes[hashPageUserLogin] = (isPopState = false) => this.navigateToHash(hashPageUserLogin, isPopState);\n // this.routes[hashPageUserLogout] = (isPopState = false) => this.navigateToHash(hashPageUserLogout, isPopState);\n this.routes[hashPageUserAccount] = (isPopState = false) => this.navigateToHash(hashPageUserAccount, isPopState);\n this.routes[hashPageUserAccounts] = (isPopState = false) => this.navigateToHash(hashPageUserAccounts, isPopState);\n this.initialize();\n }\n loadPage(hashPage, isPopState = false) {\n const PageClass = this.getClassPageFromHash(hashPage);\n this.currentPage = new PageClass(this);\n this.currentPage.initialize(isPopState);\n window.addEventListener('beforeunload', () => this.currentPage.leave());\n }\n getClassPageFromHash(hashPage) {\n \n let pageJson = this.pages[hashPage];\n try {\n const module = pageJson.module;\n return module; \n }\n catch (error) {\n Utils.consoleLogIfNotProductionEnvironment(\"this.pages: \", this.pages);\n console.error('Page not found:', hashPage);\n throw error;\n }\n }\n initialize() {\n window.addEventListener('popstate', this.handlePopState.bind(this));\n }\n handlePopState(event) {\n this.loadPageCurrent();\n }\n loadPageCurrent() {\n const hashPageCurrent = DOM.getHashPageCurrent();\n this.loadPage(hashPageCurrent);\n }\n navigateToHash(hash, data = null, params = null, isPopState = false) {\n let url = API.getUrlFromHash(hash, params);\n history.pushState({data: data, params: params}, '', hash);\n API.goToUrl(url, data);\n }\n \n navigateToUrl(url, data = null, appendHistory = true) {\n // this.beforeLeave();\n if (appendHistory) history.pushState(data, '', url);\n url = API.parameteriseUrl(url, data);\n API.goToUrl(url);\n }\n\n static loadPageBodyFromResponse(response) {\n DOM.loadPageBody(response.data);\n }\n}\n\nexport const router = new Router();\n","\n'use strict';\n\nimport DOM from './dom.js';\nimport Router from './router.js';\n\n\nclass App {\n constructor() {\n this.dom = new DOM();\n this.router = new Router();\n }\n\n initialize() {\n this.setupEventListeners();\n this.start();\n }\n\n setupEventListeners() {\n // document.addEventListener('click', this.handleGlobalClick.bind(this));\n }\n\n handleGlobalClick(event) {\n }\n\n start() {\n this.initPageCurrent();\n }\n\n initPageCurrent() {\n this.router.loadPageCurrent();\n }\n \n}\n\nconst app = new App();\n\nfunction domReady(fn) {\n if (document.readyState !== 'loading') {\n fn();\n } else {\n document.addEventListener('DOMContentLoaded', fn);\n }\n}\n\ndomReady(() => {\n app.initialize();\n});\n\nwindow.app = app;\n\nexport default app;","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};"],"names":["Validation","isEmpty","object","undefined","length","isString","trim","i","isValidNumber","value","positiveOnly","isNaN","parseFloat","getDataContentType","params","data","contentType","JSON","stringify","Data","ContentType","arrayContainsItem","array","itemValue","hasItem","isJQueryElementArray","jQuery","document","querySelectorAll","is","isDate","Date","getTime","dictHasKey","d","k","areEqualDicts","dict1","dict2","keys1","Object","keys","keys2","key","imageExists","url","callback","img","Image","onload","onerror","src","toFixedOrDefault","decimalPlaces","defaultValue","toFixed","Utils","DOM","setElementAttributesValuesCurrentAndPrevious","element","setElementAttributeValueCurrent","setElementAttributeValuePrevious","setAttribute","attrValueCurrent","attrValuePrevious","setElementValuesCurrentAndPrevious","setElementValueCurrent","tagName","toUpperCase","type","checked","textContent","setElementValueCurrentIfEmpty","getElementValueCurrent","getCellFromElement","closest","getRowFromElement","flagRow","selector","getClosestParent","parentSelector","parent","parentElement","matches","convertForm2JSON","elementForm","dataForm","containersFilter","flagContainerInput","flagFilter","containerFilter","labelFilter","keyFilter","filter","indexFilter","querySelector","getAttribute","loadPageBody","contentNew","pageBody","idPageBody","innerHTML","getHashPageCurrent","hashPageCurrent","body","dataset","page","updateAndCheckIsElementDirty","isElementDirty","isDirty","handleDirtyElement","toggleElementHasClassnameFlag","flagDirty","elementHasFlag","flag","elementAlreadyHasFlag","classList","contains","add","remove","hasDirtyChildrenContainer","container","hasDirtyChildrenNotDeletedContainer","flagDelete","returnVal","flagButton","flagActive","getElementAttributeValueCurrent","flagCheckbox","flagIsChecked","getElementAttributeValuePrevious","scrollToElement","scrollTop","offset","top","isElementInContainer","containerBounds","getBoundingClientRect","elementBounds","left","height","width","alertError","errorType","errorText","alert","createOptionUnselectedProductVariation","flagProductVariationType","flagNameAttrOptionText","flagName","flagNameAttrOptionValue","attrIdProductVariationType","flagProductVariation","attrIdProductVariation","createOption","optionJson","text","option","createElement","selected","escapeHtml","div","unescapeHtml","html","innerText","API","getCsrfToken","idCSRFToken","request","hashEndpoint","method","getUrlFromHash","csrfToken","options","headers","flagCsrfToken","response","fetch","ok","Error","status","json","error","console","hash","hashPageHome","parameteriseUrl","_pathHost","URLSearchParams","toString","goToUrl","window","location","href","goToHash","loginUser","flagCallback","hashPageUserLogin","saveUsers","users","formFilters","comment","dataRequest","flagFormFilters","flagUser","flagComment","hashSaveUserUser","saveGame","game","flagGame","hashSaveGame","getGamePlayers","gameId","saveGamePlayers","players","flagPlayer","hashSaveGamePlayer","getGameRounds","getGameDamageRecords","saveGameRoundPlayerDamages","rounds","damages","flagDamage","flagRound","hashSaveGameRoundPlayerDamage","BusinessObjects","getOptionJsonFromObjectJsonAndKeys","objectJson","keyText","keyValue","valueSelected","getOptionJsonFromObjectJson","getObjectText","getListObjectsFromIdDictAndCsv","idDict","idCsv","listObjects","ids","split","id","push","Events","initialiseEventHandler","selectorElement","classInitialised","eventHandler","forEach","hookupEventHandler","eventType","flagInitialised","addEventListener","event","stopPropagation","LocalStorage","getLocalStorage","parse","localStorage","getItem","setLocalStorage","newLS","setItem","getListFromDict","dict","list","consoleLogIfNotProductionEnvironment","message","environment","is_production","log","OverlayConfirm","hookup","callbackSuccess","idOverlayConfirm","flagCancel","buttonCancel","overlay","style","visibility","flagSubmit","buttonConfirm","textarea","show","flagIsCollapsed","OverlayError","BasePage","constructor","router","title","titlePageCurrent","name","initialize","sharedInitialize","logInitialisation","hookupCommonElements","hookupLogos","hookupNavigation","hookupOverlays","flagImageLogo","flagLogo","navigateToHash","idButtonHamburger","overlayHamburger","idOverlayHamburger","flagExpanded","hookupButtonsNavUserAccount","hookupButtonsNavUserLogout","hookupButtonsNavUserLogin","hookupButtonsNav","buttonSelector","button","pageHash","flagNavUserLogin","navigator","preventDefault","leave","then","Success","Message","hookupOverlayFromId","idOverlayError","idOverlay","display","hookupButtonSave","flagContainer","flagSave","target","setLocalStoragePage","dataPage","getLocalStoragePage","toggleShowButtonsSaveCancel","buttonContainerSelector","buttonSave","idButtonSave","idButtonCancel","isDirtyFilter","idTableMain","msgError","labelError","idLabelError","TableBasePage","cursorYInitial","rowInitial","placeholder","dragSrcEl","dragSrcRow","hookupTableCellDdls","bind","isPopState","isSinglePageApp","hookupFilters","hookupButtonsSaveCancel","hookupTableMain","saveRecordsTableDirtySinglePageApp","saveRecordsTableDirty","filters","getFormFilters","filtersDefault","callFilterTableContent","sharedHookupFilters","hookupButtonApplyFilters","hookupSearchTextFilter","hookupFilterActive","filterSelector","idFormFilters","flagActiveOnly","filterActiveOld","removeAttribute","parentDiv","isChecked","filterActiveNew","filterActive","svgElement","wasChecked","handleChangeFilter","filterValuePrevious","hookupFilter","filterFlag","handler","areDirtyFilters","tbody","rows","row","dirtyInputs","dirtyInput","isDirtyLabel","initialisedElements","initialisedElement","updateAndToggleShowButtonsSaveCancel","hookupFilterIsNotEmpty","flagIsNotEmpty","idButtonApplyFilters","flagSearch","hookupFilterCommandCategory","attrIdCommandCategory","filterCommandCategory","idCommandCategory","filterCommands","commandsInCategory","command","sortedCommands","sort","a","b","localeCompare","filterCommand","flagCommand","idCommandPrevious","appendChild","dispatchEvent","Event","hookupFilterCommand","attrIdCommand","hookupFilterLocation","attrIdLocation","filtersJson","callbackLoadTableContent","table","getTableMain","bodyTable","rowsJson","flagRows","every","hasOwnProperty","display_order","loadRowTable","rowJson","getAndLoadFilteredTableContentSinglePageApp","catch","hookupButtonCancel","records","getTableRecords","formElement","idTextareaConfirm","callSaveTableContent","flagStatus","flagSuccess","_verbose","flagMessage","dirtyOnly","record","getJsonRow","handleClickAddRowTable","_rowBlank","attrIdRowObject","cloneNode","countRows","initialiseRowNew","prepend","postInitialiseRowNewCallback","cacheRowBlank","selectorRowNew","flagRowNew","rowBlankTemp","initialiseSliderDisplayOrderRowNew","slidersDisplayOrder","flagDisplayOrder","flagSlider","maxDisplayOrder","slider","Math","max","sliderDisplayOrder","hookupSlidersDisplayOrderTable","selectorDisplayOrder","hookupChangeHandlerTableCells","inputSelector","handleChangeNestedElementCellTable","input","wasDirtyParentRows","getAllIsDirtyRowsInParentTree","wasDirtyElement","isDirtyElement","cascadeChangedIsDirtyNestedElementCellTable","tr","isDirtyRow","wasDirtyRow","shift","hookupChangeHandlerTableCellsWhenNotCollapsed","hookupFieldsCodeTable","flagCode","hookupFieldsNameTable","hookupFieldsDescriptionTable","flagDescription","hookupFieldsNotesTable","flagNotes","hookupFieldsActive","flagTable","handleClickRowNew","selectorButton","selectorButtonDelete","selectorButtonUndelete","hookupButtonsRowDelete","hookupButtonsRowUndelete","changeHandler","handleClickButtonRowDelete","changeEvent","changeElement","valuePrevious","wasDirty","parentNode","removeChild","buttonAddTemplate","idContainerTemplateElements","flagAdd","buttonAdd","replaceWith","handleClickButtonRowUndelete","buttonDeleteTemplate","buttonDelete","hookupTdsAccessLevel","hookupTableCellDdlPreviews","flagAccessLevel","accessLevels","fieldFlag","optionList","cellSelector","ddlHookup","ddlSelector","handleClickTableCellDdlPreview","optionObjectList","idSelected","td","ddl","optionObjectJson","toggleColumnCollapsed","flagColumn","isCollapsed","toggleColumnHasClassnameFlag","toggleColumnHeaderCollapsed","hookupFieldsCommandCategory","idTable","flagCommandCategory","filterCommandCategories","hookupCommandCategoryDdls","handleChangeCommandCategoryDdl","ddlCategory","idCommandCategoryRowOld","getIdCommandCategoryRow","idCommandCategoryRowNew","idCommandCategoryFilter","getIdCommandCategoryFilter","tdCommand","ddlCommand","hookupFieldsCommand","parentTr","tdCommandCategory","idCommandCategoryRow","filterCommandList","handleChangeCommandDdl","idCommandNew","getIdCommandRow","commandNew","divCommandCategory","ddlCommandCategory","elementCommandCategory","commandCategoryFilter","commandFilter","valueCurrentCommandCategoryFilter","valueCurrentCommandFilter","Number","getHasCommandCategoryFilter","elementCommand","getIdCommandFilter","idCommand","getHasCommandFilter","idCommandFilter","columnFlag","isRequiredFlag","classnameFlag","columnTh","columnThHasFlag","toggleColumnHeaderHasClassnameFlag","areVisibleSaveCancelButtons","PageMtgDecks","hashPageMtgDecks","attrDeckId","saveDeck","newRows","newestRow","clickableElementsSelector","attrCommanderBracketId","join","clickableElement","click","hookupTableMainRows","hookupTableMainIsCommanderCheckboxes","hookupTableMainCommanderBracketPreviews","rowSelector","flagTableMain","isRowExpanded","showSection","toggleShowDeckStatisticsSection","deckId","statisticsSectionTableBody","flagStatistics","deck","decks","newStatisticRowsHtml","statistic","attrStatisticId","flagValue","flagIsCommander","commanderBrackets","PageMtgGame","hashPageMtgGame","attrGameId","hookupTcgGame","initGamePage","pageHeading","updatePlayerSetup","loadGameFromServer","hookupResetButton","hookupPlayerCountInput","hookupStartGameButton","resetGameButton","resetGame","playerCountInput","getElementById","startGameButton","startGame","playersResponse","roundsResponse","damageResponse","Promise","all","setupSection","gameSection","savedPlayers","savedRounds","savedDamageRecords","damageRecords","latestRoundId","getLatestRoundId","latestRound","round","attrRoundId","roundDisplayOrderLabel","getRoundDisplayOrderLabel","renderPlayers","grid","currentRoundDisplayOrder","activeRound","makeDefaultGameRound","previousRoundIds","map","player","index","playerId","attrPlayerId","displayName","makePlayerDisplayName","damagePlayerPairs","maxCommanderDamageReceived","damagePlayerPair","sourceId","filteredPlayerDamages","damage","attrReceivedFromCommanderPlayerId","makeDefaultGameRoundPlayerDamage","includes","flagLifeLoss","reduce","totalDamage","flagLifeGain","life","startingLife","isEliminatedByForce","flagIsEliminated","some","Boolean","isEliminated","totalCommanderDeaths","flagCommanderDeaths","card","className","animationDelay","userName","user_name","deckName","deck_name","renderCommanderDamageRows","reorderPlayerCards","renderCommanderDamageLog","hookupGameRoundEvents","hookupPlayerCardEvents","getActiveRoundDisplayOrder","damageTableBody","flagDamageLog","newTableBodyHtml","r","p","receivedFromPlayer","attrDamageId","receivedFromCommanderPlayerId","roundId","getActiveRoundId","highestRoundDisplayOrder","acc","cur","filteredRounds","user","attrUserId","activeRoundDisplayOrder","otherPlayer","otherPlayerDisplayName","curr","isLethal","incrementRoundButtonSelector","flagRoundDisplayOrderButton","amount","flagRoundDisplayOrderPlus","roundDisplayOrderButtonContainer","newDisplayOrder","displayOrder","lifeGainButtonSelector","parseInt","activeRoundId","damageIndex","findIndex","changeLife","lifeLossButtonSelector","commanderDeathButtonSelector","isMinusButton","changeCommanderDeaths","commmanderDamageButtonSelector","changeCommanderDamage","eliminatePlayerButtonSelector","toggleEliminate","isLifeGainNotLoss","updateDamage","lifeInput","lifeDisplay","currentLife","newLife","damageInput","damageDisplay","currentDamage","newDamage","damageRecord","deathDisplay","currentDeaths","newDeaths","eliminateBtn","wasEliminated","playerGrid","currentPlayerCards","newPlayerCards","playerCardMetas","playerCard","newPlayerGridInnerHTML","playerIdA","playerIdB","isEliminatedAsIntA","isEliminatedAsIntB","playerA","playerB","indexPlayerCard","isPlayerEliminated","playerCardMeta","outerHTML","roundDisplayOrder","filteredRoundIds","hasDamageWithIsEliminated","damageFromOtherPlayers","otherPlayerId","maxDamageFromOtherCommander","totalDamageTaken","playerCount","wrapperTemplate","playerSetupWrapperTemplateId","wrapper","wrapperHeading","userDdl","deckDdl","nameInput","makeDefaultGamePlayer","playersToSave","playerSetupWrapper","userId","self","reload","showError","finally","confirm","removeItem","hashPageGames","errorOverlay","errorLabel","_saveTimeout","PageMtgGames","hashPageMtgGames","hookupTcgGames","newGameForm","handleNewGameSubmit","filterForm","handleFilterSubmit","e","hideNewGameForm","modal","newGameButton","showNewGameForm","cancelNewGameButtons","overflow","firstInput","focus","form","reset","formData","FormData","gameType","get","gameData","flagIsDraft","flagIsSealed","flagLocationName","flagStartOn","toISOString","flagStartingLife","submitBtn","originalText","disabled","games","gamePageHash","hashPageGame","getCSRFToken","metaTag","hiddenInput","cookies","cookie","showSuccess","joinGame","deleteGame","result","animation","setTimeout","PageMtgHome","hashPageMtgHome","hookupTcgHome","PageAccessibilityReport","hashPageAccessibilityReport","PageAccessibilityStatement","hashPageAccessibilityStatement","PageLicense","hashPageLicense","PagePrivacyPolicy","hashPagePrivacyPolicy","PageRetentionSchedule","hashPageDataRetentionSchedule","MixinPage","pageCurrent","hookupLocalStorage","TableMixinPage","hookupTable","PageUser","hashPageUserAccount","mixin","flagCard","inputFirstname","flagFirstname","inputSurname","flagSurname","inputEmail","flagEmail","idUser","jsonRow","attrUserAuth0Id","flagIsEmailVerified","flagIsSuperUser","flagCanAdminUser","hookupFieldsFirstname","hookupFieldsSurname","hookupFieldsEmail","PageUsers","hashPageUserAccounts","inputNotes","buttonActive","Router","pages","module","routes","loadPage","hashPage","PageClass","getClassPageFromHash","currentPage","pageJson","handlePopState","loadPageCurrent","history","pushState","navigateToUrl","appendHistory","loadPageBodyFromResponse","App","dom","setupEventListeners","start","handleGlobalClick","initPageCurrent","app","domReady","fn","readyState"],"sourceRoot":""} \ No newline at end of file diff --git a/static/dist/js/tcg_decks.bundle.js b/static/dist/js/tcg_decks.bundle.js new file mode 100644 index 0000000..b57527b --- /dev/null +++ b/static/dist/js/tcg_decks.bundle.js @@ -0,0 +1,17 @@ +/******/ (() => { // webpackBootstrap +/******/ "use strict"; +// This entry needs to be wrapped in an IIFE because it needs to be isolated against other entry modules. +(() => { +// extracted by mini-css-extract-plugin + +})(); + +// This entry needs to be wrapped in an IIFE because it needs to be isolated against other entry modules. +(() => { +// extracted by mini-css-extract-plugin + +})(); + +/******/ })() +; +//# sourceMappingURL=tcg_decks.bundle.js.map \ No newline at end of file diff --git a/static/dist/js/tcg_decks.bundle.js.map b/static/dist/js/tcg_decks.bundle.js.map new file mode 100644 index 0000000..d895ec3 --- /dev/null +++ b/static/dist/js/tcg_decks.bundle.js.map @@ -0,0 +1 @@ +{"version":3,"file":"js/tcg_decks.bundle.js","mappings":";;;;AAAA;;;;;;ACAA","sources":["webpack://app/./static/css/sections/tcg.css?b213","webpack://app/./static/css/pages/tcg/decks.css?c1be"],"sourcesContent":["// extracted by mini-css-extract-plugin\nexport {};","// extracted by mini-css-extract-plugin\nexport {};"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/static/js/pages/base.js b/static/js/pages/base.js index c8c9efa..84648f8 100644 --- a/static/js/pages/base.js +++ b/static/js/pages/base.js @@ -150,6 +150,7 @@ export default class BasePage { toggleShowButtonsSaveCancel(show, buttonContainerSelector = null) { // , buttonSave = null, buttonCancel = null if (Validation.isEmpty(buttonContainerSelector)) buttonContainerSelector = '.' + flagContainer + '.' + flagSave + '.' + flagCancel; let buttonSave = document.querySelector(buttonContainerSelector + ' ' + idButtonSave); + if (buttonSave == null) return; let buttonCancel = document.querySelector(buttonContainerSelector + ' ' + idButtonCancel); Utils.consoleLogIfNotProductionEnvironment({ show, buttonContainerSelector, buttonCancel, buttonSave }); if (show) { diff --git a/static/js/pages/base_table.js b/static/js/pages/base_table.js index c29f499..7230e34 100644 --- a/static/js/pages/base_table.js +++ b/static/js/pages/base_table.js @@ -335,6 +335,7 @@ export default class TableBasePage extends BasePage { cacheRowBlank() { let selectorRowNew = idTableMain + ' tbody tr.' + flagRowNew; let rowBlankTemp = document.querySelector(selectorRowNew); + if (rowBlankTemp == null) return; Utils.consoleLogIfNotProductionEnvironment("row blank temp: ", rowBlankTemp); let countRows = document.querySelectorAll(idTableMain + ' > tbody > tr').length; _rowBlank = rowBlankTemp.cloneNode(true); @@ -734,11 +735,15 @@ export default class TableBasePage extends BasePage { } updateAndToggleShowButtonsSaveCancel() { - let pageBody = document.querySelector(idPageBody); + // let pageBody = document.querySelector(idPageBody); let isDirty = DOM.hasDirtyChildrenContainer(pageBody); - console.log({ pageBody, isDirty }); + let buttonContainerSelector = '.' + flagContainer + '.' + flagSave + '.' + flagCancel; + let buttonSave = document.querySelector(buttonContainerSelector + ' ' + idButtonSave); + let areVisibleSaveCancelButtons = !buttonSave.classList.contains(flagIsCollapsed); + + console.log({ pageBody, isDirty, areVisibleSaveCancelButtons }); - this.toggleShowButtonsSaveCancel(isDirty); + this.toggleShowButtonsSaveCancel(isDirty || areVisibleSaveCancelButtons); } } diff --git a/static/js/pages/tcg/mtg_decks.js b/static/js/pages/tcg/mtg_decks.js new file mode 100644 index 0000000..c7cd72e --- /dev/null +++ b/static/js/pages/tcg/mtg_decks.js @@ -0,0 +1,110 @@ + +import API from "../../api.js"; +import Events from "../../lib/events.js"; +import TableBasePage from "../base_table.js"; +import Utils from "../../lib/utils.js"; + +export default class PageMtgDecks extends TableBasePage { + static hash = hashPageMtgDecks; + static attrIdRowObject = attrDeckId; + callSaveTableContent = API.saveDeck; + + constructor(router) { + super(router); + } + + initialize() { + this.sharedInitialize(); + } + hookupFilters() { + /* + this.sharedHookupFilters(); + this.hookupFilterActive(); + */ + } + + loadRowTable(rowJson) { + if (rowJson == null) return; + if (_verbose) { Utils.consoleLogIfNotProductionEnvironment("applying data row: ", rowJson); } + } + getJsonRow(row) { + return; + } + initialiseRowNew(tbody, row) { + } + postInitialiseRowNewCallback(tbody) { + let newRows = tbody.querySelectorAll('tr.' + flagRowNew); + let newestRow = newRows[0]; + let clickableElementsSelector = [ + 'td.' + attrCommanderBracketId + ' div.' + attrCommanderBracketId + ].join(''); + newestRow.querySelectorAll(clickableElementsSelector).forEach((clickableElement) => { + clickableElement.click(); + }); + } + + hookupTableMain() { + super.hookupTableMain(); + this.hookupTableMainRows(); + this.hookupFieldsNameTable(); + this.hookupTableMainIsCommanderCheckboxes(); + this.hookupTableMainCommanderBracketPreviews(); + this.hookupFieldsActive(); + } + hookupTableMainRows() { + return; + let rowSelector = 'table.' + flagTableMain + ' tbody tr'; + Events.hookupEventHandler("click", rowSelector, (event, row) => { + let isRowExpanded = row.classList.contains(flagActive); + let showSection; + if (isRowExpanded) { + showSection = false; + PageMtgDecks.toggleShowDeckStatisticsSection(showSection); + } + else { + showSection = true; + let deckId = row.getAttribute(attrDeckId); + let statisticsSectionTableBody = document.querySelector('table.' + flagStatistics + ' tbody'); + statisticsSectionTableBody.innerHTML = ''; + let deck = decks.filter(d => d[attrDeckId] == deckId)[0]; + if (deck[flagStatistics].length > 0) { + let newStatisticRowsHtml = ''; + deck[flagStatistics] + .sort((a, b) => a[flagDisplayOrder] - b[flagDisplayOrder]) + .forEach((statistic) => { + newStatisticRowsHtml += ` + + ${statistic[flagName]} + ${statistic[flagValue]} + + `; + }); + statisticsSectionTableBody.innerHTML = newStatisticRowsHtml; + } + PageMtgDecks.toggleShowDeckStatisticsSection(showSection); + } + }); + } + static toggleShowDeckStatisticsSection(showSection) { + let statisticsSectionTableBody = document.querySelector('table.' + flagStatistics + ' tbody'); + if (showSection) { + statisticsSectionTableBody.classList.remove(flagIsCollapsed); + } + else { + statisticsSectionTableBody.classList.add(flagIsCollapsed); + } + } + hookupTableMainIsCommanderCheckboxes() { + this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagIsCommander + ' .' + flagIsCommander); + } + hookupTableMainCommanderBracketPreviews() { + this.hookupTableCellDdlPreviews( + attrCommanderBracketId + , Utils.getListFromDict(commanderBrackets) + ); + } + + leave() { + super.leave(); + } +} diff --git a/static/js/pages/tcg/mtg_game.js b/static/js/pages/tcg/mtg_game.js index 8179073..2b364b6 100644 --- a/static/js/pages/tcg/mtg_game.js +++ b/static/js/pages/tcg/mtg_game.js @@ -195,30 +195,19 @@ export default class PageMtgGame extends TableBasePage { renderPlayers() { const grid = document.getElementById('playersGrid'); grid.innerHTML = ''; - - // Build a damage lookup: { playerId: { fromPlayerId: damageAmount } } - /* - const damageLookup = {}; - damageRecords.forEach(damage => { - if (!damageLookup[damage.player_id]) { - damageLookup[damage.player_id] = {}; - } - if (damage.received_from_commander_player_id) { - damageLookup[damage.player_id][damage.received_from_commander_player_id] = damage.health_change || 0; - } - }); - */ - let activeRoundId = PageMtgGame.getActiveRoundId(); + // let activeRoundId = PageMtgGame.getActiveRoundId(); const roundDisplayOrderLabel = PageMtgGame.getRoundDisplayOrderLabel(); - if (activeRoundId < 0) { - const currentRoundDisplayOrder = Number(DOM.getElementValueCurrent(roundDisplayOrderLabel)); - rounds.push(PageMtgGame.makeDefaultGameRound(currentRoundDisplayOrder)); - activeRoundId = PageMtgGame.getActiveRoundId(); + const currentRoundDisplayOrder = Number(DOM.getElementValueCurrent(roundDisplayOrderLabel)); + let activeRound = rounds.filter(round => round[flagDisplayOrder] == currentRoundDisplayOrder)[0]; + if (activeRound == null) { + activeRound = PageMtgGame.makeDefaultGameRound(currentRoundDisplayOrder); + rounds.push(activeRound); } - const latestRound = rounds.filter(round => round[attrRoundId] == activeRoundId)[0]; - DOM.setElementValueCurrent(roundDisplayOrderLabel, latestRound[flagDisplayOrder]); + DOM.setElementValueCurrent(roundDisplayOrderLabel, activeRound[flagDisplayOrder]); + const previousRoundIds = rounds.filter(round => round[flagDisplayOrder] <= currentRoundDisplayOrder) + .map(round => round[attrRoundId]); players.forEach((player, index) => { // Build display name: prefer user_name + deck_name, fallback to player name const playerId = player[attrPlayerId]; @@ -228,7 +217,8 @@ export default class PageMtgGame extends TableBasePage { damagePlayerPairs.forEach(damagePlayerPair => { const sourceId = damagePlayerPair[attrPlayerId]; const filteredPlayerDamages = damageRecords.filter(damage => ( - damage[attrRoundId] == activeRoundId + damage[attrRoundId] == activeRound[attrRoundId] + // previousRoundIds.includes(damage[attrRoundId]) && damage[attrPlayerId] == playerId && damage[attrReceivedFromCommanderPlayerId] == sourceId )); //[playerId] || {}; @@ -240,20 +230,30 @@ export default class PageMtgGame extends TableBasePage { , damageRecords.filter(damage => ( damage[attrPlayerId] == playerId && damage[attrReceivedFromCommanderPlayerId] == sourceId + && damage[attrReceivedFromCommanderPlayerId] != null + && previousRoundIds.includes(damage[attrRoundId]) )) - .map(damage => damage[flagHealthChange]) - .reduce((acc, curr) => acc + curr, 0) + .map(damage => damage[flagLifeLoss]) + .reduce((a, b) => a + b, 0) ); }); - const totalDamage = damageRecords.filter(damage => ( damage[attrPlayerId] == playerId )) - .map(damage => damage[flagHealthChange]) - .reduce((acc, curr) => acc + curr, 0); - let life = startingLife + totalDamage; + const totalDamage = damageRecords.filter(damage => ( + damage[attrPlayerId] == playerId + && previousRoundIds.includes(damage[attrRoundId]) + )) + .map(damage => damage[flagLifeLoss] - damage[flagLifeGain]) + .reduce((a, b) => a + b, 0); + let life = startingLife - totalDamage; - let isEliminatedByForce = damageRecords.filter(damage => ( damage[attrPlayerId] == playerId )) + let isEliminatedByForce = damageRecords.filter(damage => ( + damage[attrPlayerId] == playerId + && previousRoundIds.includes(damage[attrRoundId]) + )) .map(damage => damage[flagIsEliminated]) .some(Boolean); + console.log("renderPlayers"); + console.log({isEliminatedByForce, player, life, maxCommanderDamageReceived}); const isEliminated = ( isEliminatedByForce || !player[flagActive] @@ -261,11 +261,13 @@ export default class PageMtgGame extends TableBasePage { || maxCommanderDamageReceived >= 21 ); - const playerOwnDamage = damageRecords.filter(damage => ( + const totalCommanderDeaths = damageRecords.filter(damage => ( damage[attrPlayerId] == playerId && damage[attrReceivedFromCommanderPlayerId] == null - && damage[attrRoundId] == activeRoundId - ))[0]; + && damage[attrRoundId] == activeRound[attrRoundId] + )) + .map(damage => damage[flagCommanderDeaths]) + .reduce((a, b) => a + b, 0); const card = document.createElement('div'); card.className = `player-card ${isEliminated ? 'eliminated' : ''}`; card.style.animationDelay = `${index * 0.1}s`; @@ -281,7 +283,7 @@ export default class PageMtgGame extends TableBasePage { Commander Deaths:
- ${playerOwnDamage[flagCommanderDeaths]} + ${totalCommanderDeaths}
@@ -294,11 +296,19 @@ export default class PageMtgGame extends TableBasePage {
${life}
-
- - - - + +
+ + + + +
+ +
+ + + +
@@ -325,22 +335,25 @@ export default class PageMtgGame extends TableBasePage { this.hookupPlayerCardEvents(); } static renderCommanderDamageLog() { - const roundDisplayOrderLabel = PageMtgGame.getRoundDisplayOrderLabel(); - const currentRoundDisplayOrder = Number(DOM.getElementValueCurrent(roundDisplayOrderLabel)); + const currentRoundDisplayOrder = PageMtgGame.getActiveRoundDisplayOrder(); const damageTableBody = document.querySelector('.' + flagDamageLog + '.' + flagContainer + ' table tbody'); damageTableBody.innerHTML = ''; + const previousRoundIds = rounds.filter(round => round[flagDisplayOrder] <= currentRoundDisplayOrder) + .map(round => round[attrRoundId]); let newTableBodyHtml = ''; damageRecords.forEach((damage) => { if ( damage[flagActive] && ( damage[flagCommanderDeaths] > 0 - || damage[flagHealthChange] != 0 + || damage[flagLifeGain] != 0 + || damage[flagLifeLoss] != 0 || damage[flagIsEliminated] ) - && rounds.filter(r => r[attrRoundId] == damage[attrRoundId])[0][flagDisplayOrder] <= currentRoundDisplayOrder + // && rounds.filter(r => r[attrRoundId] == damage[attrRoundId])[0][flagDisplayOrder] <= currentRoundDisplayOrder + && previousRoundIds.includes(damage[attrRoundId]) ) { let round = rounds.filter(r => r[attrRoundId] == damage[attrRoundId])[0]; let player = players.filter(p => p[attrPlayerId] == damage[attrPlayerId])[0]; @@ -350,7 +363,8 @@ export default class PageMtgGame extends TableBasePage { ${round[flagDisplayOrder]} ${player[flagName]} ${receivedFromPlayer[flagName]} - ${damage[flagHealthChange]} + ${damage[flagLifeGain]} + ${damage[flagLifeLoss]} ${damage[flagCommanderDeaths]} ${damage[flagIsEliminated]} @@ -366,8 +380,10 @@ export default class PageMtgGame extends TableBasePage { , [attrRoundId]: roundId , [attrPlayerId]: playerId , [attrReceivedFromCommanderPlayerId]: receivedFromCommanderPlayerId - , [flagHealthChange]: 0 + , [flagLifeGain]: 0 + , [flagLifeLoss]: 0 , [flagCommanderDeaths]: 0 + , [flagIsEliminated]: false , [flagActive]: true }; } @@ -384,10 +400,13 @@ export default class PageMtgGame extends TableBasePage { } return roundId; } - static getActiveRoundId() { + static getActiveRoundDisplayOrder() { const roundDisplayOrderLabel = PageMtgGame.getRoundDisplayOrderLabel(); - const currentRoundDisplayOrder = Number(DOM.getElementValueCurrent(roundDisplayOrderLabel)); - let roundId = -1; + return Number(DOM.getElementValueCurrent(roundDisplayOrderLabel)); + } + static getActiveRoundId() { + const currentRoundDisplayOrder = PageMtgGame.getActiveRoundDisplayOrder(); + let roundId = 0; if (rounds.length > 0) { let filteredRounds = rounds.filter(round => round[flagDisplayOrder] == currentRoundDisplayOrder); if (filteredRounds.length > 0) roundId = filteredRounds[0][attrRoundId]; @@ -406,7 +425,9 @@ export default class PageMtgGame extends TableBasePage { return player[flagName] || `${(user == null) ? 'Error' : user[flagName]} - ${(deck == null) ? 'Error' : deck[flagName]}`; } static renderCommanderDamageRows(playerId) { - // const roundId = PageMtgGame.getLatestRoundId(); + const activeRoundDisplayOrder = PageMtgGame.getActiveRoundDisplayOrder(); + const previousRoundIds = rounds.filter(round => round[flagDisplayOrder] <= activeRoundDisplayOrder) + .map(round => round[attrRoundId]); return players .filter(otherPlayer => otherPlayer[attrPlayerId] !== playerId) .map(otherPlayer => { @@ -415,10 +436,12 @@ export default class PageMtgGame extends TableBasePage { const totalDamage = damageRecords.filter(damage => ( damage[attrPlayerId] == playerId && damage[attrReceivedFromCommanderPlayerId] == sourceId + // && damage[attrRoundId] == roundId + && previousRoundIds.includes(damage[attrRoundId]) )) - .map(damage => -damage[flagHealthChange]) - .reduce((acc, curr) => acc + curr, 0); - const isLethal = totalDamage >= 21; + .map(damage => damage[flagLifeLoss]) + .reduce((acc, curr) => acc + curr, 0); + const isLethal = (totalDamage >= 21); return `
@@ -460,9 +483,9 @@ export default class PageMtgGame extends TableBasePage { }; } hookupPlayerCardEvents() { - // Life buttons - let lifeButtonSelector = '.life-btn'; - Events.hookupEventHandler("click", lifeButtonSelector, (event, button) => { + // Life gain buttons + let lifeGainButtonSelector = '.life-gain-btn'; + Events.hookupEventHandler("click", lifeGainButtonSelector, (event, button) => { const playerId = button.dataset.playerId; const amount = parseInt(button.dataset.amount); const activeRoundId = PageMtgGame.getActiveRoundId(); @@ -474,6 +497,27 @@ export default class PageMtgGame extends TableBasePage { this.changeLife( playerId // playerId , amount // amount + , true // isLifeGainNotLoss + , true // updateDamage + , damageIndex // damageIndex + ); + }); + + // Life loss buttons + let lifeLossButtonSelector = '.life-loss-btn'; + Events.hookupEventHandler("click", lifeLossButtonSelector, (event, button) => { + const playerId = button.dataset.playerId; + const amount = parseInt(button.dataset.amount); + const activeRoundId = PageMtgGame.getActiveRoundId(); + const damageIndex = damageRecords.findIndex(damage => ( + damage[attrRoundId] == activeRoundId + && damage[attrPlayerId] == playerId + && damage[attrReceivedFromCommanderPlayerId] == null + )); + this.changeLife( + playerId // playerId + , amount // amount + , false // isLifeGainNotLoss , true // updateDamage , damageIndex // damageIndex ); @@ -506,22 +550,24 @@ export default class PageMtgGame extends TableBasePage { }); } - changeLife(playerId, amount, updateDamage = false, damageIndex = null) { + changeLife(playerId, amount, isLifeGainNotLoss = false, updateDamage = false, damageIndex = null) { const card = document.querySelector(`.player-card[data-player-id="${playerId}"]`); - if (!card || card.classList.contains('eliminated')) return; + // if (!card || card.classList.contains('eliminated')) return; const lifeInput = card.querySelector(`.life-value[data-player-id="${playerId}"]`); const lifeDisplay = card.querySelector(`.life-display[data-player-id="${playerId}"]`); const currentLife = parseInt(lifeInput.value) || 0; - const newLife = Math.max(0, currentLife + amount); + const newLife = currentLife + amount * ((isLifeGainNotLoss) ? 1 : -1); + DOM.setElementAttributeValueCurrent(lifeDisplay, newLife); DOM.isElementDirty(lifeDisplay); lifeInput.value = newLife; lifeDisplay.textContent = newLife; if (updateDamage) { - damageRecords[damageIndex][flagHealthChange] += amount; + let fieldFlag = (isLifeGainNotLoss) ? flagLifeGain : flagLifeLoss; + damageRecords[damageIndex][fieldFlag] += amount; } PageMtgGame.renderCommanderDamageLog(); @@ -532,7 +578,7 @@ export default class PageMtgGame extends TableBasePage { changeCommanderDamage(playerId, sourceId, amount) { const card = document.querySelector(`.player-card[data-player-id="${playerId}"]`); - if (!card || card.classList.contains('eliminated')) return; + // if (!card || card.classList.contains('eliminated')) return; const damageInput = card.querySelector(`.damage-value[data-player-id="${playerId}"][data-source-id="${sourceId}"]`); const damageDisplay = card.querySelector(`.damage-display[data-player-id="${playerId}"][data-source-id="${sourceId}"]`); @@ -558,11 +604,13 @@ export default class PageMtgGame extends TableBasePage { && damageRecord[attrPlayerId] == playerId && damageRecord[attrReceivedFromCommanderPlayerId] == sourceId )); - damageRecords[damageIndex][flagHealthChange] -= amount; + damageRecords[damageIndex][flagLifeLoss] += amount; + let isLifeGainNotLoss = false; this.changeLife( playerId // playerId , -amount // amount + , isLifeGainNotLoss // isLifeGainNotLoss , false // updateDamage , damageIndex // damageIndex ); @@ -571,7 +619,7 @@ export default class PageMtgGame extends TableBasePage { changeCommanderDeaths(playerId, amount) { const card = document.querySelector(`.player-card[data-player-id="${playerId}"]`); - if (!card || card.classList.contains('eliminated')) return; + // if (!card || card.classList.contains('eliminated')) return; const deathDisplay = card.querySelector(`.death-display[data-player-id="${playerId}"]`); const currentDeaths = parseInt(deathDisplay.textContent) || 0; @@ -641,14 +689,14 @@ export default class PageMtgGame extends TableBasePage { , [flagDisplayOrder]: index }); }); - let activeRoundId = PageMtgGame.getActiveRoundId(); + let activeRoundDisplayOrder = PageMtgGame.getActiveRoundDisplayOrder(); let newPlayerGridInnerHTML = ''; let playerIdA, playerIdB, isEliminatedAsIntA, isEliminatedAsIntB, playerA, playerB, indexPlayerCard; playerCardMetas.sort((a, b) => { playerIdA = a[attrPlayerId]; playerIdB = b[attrPlayerId]; - isEliminatedAsIntA = PageMtgGame.isPlayerEliminated(playerIdA, activeRoundId) ? 1 : 0; - isEliminatedAsIntB = PageMtgGame.isPlayerEliminated(playerIdB, activeRoundId) ? 1 : 0; + isEliminatedAsIntA = PageMtgGame.isPlayerEliminated(playerIdA, activeRoundDisplayOrder) ? 1 : 0; + isEliminatedAsIntB = PageMtgGame.isPlayerEliminated(playerIdB, activeRoundDisplayOrder) ? 1 : 0; playerA = players.filter(p => p[attrPlayerId] == playerIdA)[0]; playerB = players.filter(p => p[attrPlayerId] == playerIdB)[0]; return ( @@ -671,35 +719,41 @@ export default class PageMtgGame extends TableBasePage { this.hookupPlayerCardEvents(); } - static isPlayerEliminated(playerId, roundId = null) { - if (roundId == null) roundId = PageMtgGame.getActiveRoundId(); + static isPlayerEliminated(playerId, roundDisplayOrder = null) { + if (roundDisplayOrder == null) roundDisplayOrder = PageMtgGame.getActiveRoundDisplayOrder(); + const filteredRoundIds = rounds.filter(round => round[flagDisplayOrder] <= roundDisplayOrder) + .map(round => round[attrRoundId]); let hasDamageWithIsEliminated = damageRecords.filter(damage => ( - damage[attrRoundId] <= roundId + // damage[attrRoundId] <= roundDisplayOrder + filteredRoundIds.includes(damage[attrRoundId]) && damage[attrPlayerId] == playerId && damage[flagIsEliminated] )).length > 0; let damageFromOtherPlayers = {}; let otherPlayerId; damageRecords.filter(damage => ( - damage[attrRoundId] <= roundId + // damage[attrRoundId] <= roundId + filteredRoundIds.includes(damage[attrRoundId]) && damage[attrPlayerId] == playerId && damage[attrReceivedFromCommanderPlayerId] != null )) .forEach((damage) => { otherPlayerId = damage[attrReceivedFromCommanderPlayerId]; damageFromOtherPlayers[otherPlayerId] = - damage[flagHealthChange] + damage[flagLifeLoss] + ((damageFromOtherPlayers[otherPlayerId] == null) ? 0 : damageFromOtherPlayers[otherPlayerId]); }); - let maxDamageFromOtherCommander = Math.max(Object.keys(damageFromOtherPlayers) - .map((playerId) => damageFromOtherPlayers[playerId])); - // .reduce((acc, cur) => acc + cur, 0); + let maxDamageFromOtherCommander = Object.keys(damageFromOtherPlayers) + .map((playerId) => damageFromOtherPlayers[playerId]) + .reduce((acc, cur) => Math.max(acc, cur), 0); let totalDamageTaken = damageRecords.filter(damage => ( - damage[attrRoundId] <= roundId + // damage[attrRoundId] <= roundId + filteredRoundIds.includes(damage[attrRoundId]) && damage[attrPlayerId] == playerId )) - .map((damage) => damage[flagHealthChange]) - .reduce((acc, cur) => acc + cur, 0); + .map((damage) => damage[flagLifeLoss] - damage[flagLifeGain]) + .reduce((a, b) => a + b, 0); + console.log({ roundDisplayOrder, filteredRoundIds, hasDamageWithIsEliminated, maxDamageFromOtherCommander, totalDamageTaken }); return ( hasDamageWithIsEliminated || maxDamageFromOtherCommander >= 21 @@ -771,7 +825,7 @@ export default class PageMtgGame extends TableBasePage { userId = DOM.getElementValueCurrent(userDdl); deckId = DOM.getElementValueCurrent(deckDdl); - name = nameInput ? nameInput.value.trim() || `Player ${i + 1}` : `Player ${i + 1}`; + name = nameInput ? nameInput.value.trim() || null : null; // `Player ${i + 1}` : `Player ${i + 1}`; playerId = playerSetupWrapper.getAttribute(attrPlayerId); player = players.filter(p => p[attrPlayerId] == playerId)[0]; diff --git a/static/js/pages/tcg/mtg_games.js b/static/js/pages/tcg/mtg_games.js index b09ee25..3ad3adc 100644 --- a/static/js/pages/tcg/mtg_games.js +++ b/static/js/pages/tcg/mtg_games.js @@ -14,12 +14,34 @@ export default class PageMtgGames extends TableBasePage { initialize() { this.sharedInitialize(); + } + hookupFilters() { + /* + this.sharedHookupFilters(); + this.hookupFilterActive(); + */ + } + + loadRowTable(rowJson) { + if (rowJson == null) return; + if (_verbose) { Utils.consoleLogIfNotProductionEnvironment("applying data row: ", rowJson); } + } + getJsonRow(row) { + return; + } + initialiseRowNew(tbody, row) { + } + postInitialiseRowNewCallback(tbody) { + } + + hookupTableMain() { + super.hookupTableMain(); + // this.hookupTableMainRows(); this.hookupTcgGames(); + // PageMtgGames.hideNewGameForm(); } hookupTcgGames() { - this.initGamesPage(); - } - initGamesPage() { + console.log("hookupTableMain PageMtgGames"); // Initialize form submission const newGameForm = document.getElementById('newGameForm'); if (newGameForm) { @@ -55,7 +77,7 @@ export default class PageMtgGames extends TableBasePage { newGameButton.addEventListener('click', PageMtgGames.showNewGameForm); } const cancelNewGameButtons = document.querySelectorAll( - '#newGameForm .form-actions .btn-tcg.btn-tcg-secondary' + '#newGameForm .form-actions .btn-tcg.btn-tcg-secondary' + ',' + '#newGameModal .modal-content .modal-header .modal-close' ); @@ -69,7 +91,7 @@ export default class PageMtgGames extends TableBasePage { static showNewGameForm() { const modal = document.getElementById('newGameModal'); if (modal) { - modal.classList.remove('hidden'); + modal.classList.remove(flagIsCollapsed); document.body.style.overflow = 'hidden'; // Focus on first input @@ -82,7 +104,7 @@ export default class PageMtgGames extends TableBasePage { static hideNewGameForm() { const modal = document.getElementById('newGameModal'); if (modal) { - modal.classList.add('hidden'); + modal.classList.add(flagIsCollapsed); document.body.style.overflow = ''; // Reset form @@ -182,7 +204,7 @@ export default class PageMtgGames extends TableBasePage { if (errorLabel) { errorLabel.textContent = message; } - errorOverlay.classList.remove('hidden'); + errorOverlay.classList.remove(flagIsCollapsed); errorOverlay.style.display = 'flex'; } else { // Fallback to alert diff --git a/static/js/router.js b/static/js/router.js index bbd83fc..6d59399 100644 --- a/static/js/router.js +++ b/static/js/router.js @@ -2,6 +2,7 @@ // Pages // Core // TCG +import PageMtgDecks from './pages/tcg/mtg_decks.js'; import PageMtgGame from './pages/tcg/mtg_game.js'; import PageMtgGames from './pages/tcg/mtg_games.js'; import PageMtgHome from './pages/tcg/mtg_home.js'; @@ -28,6 +29,7 @@ export default class Router { this.pages = {}; // Core // TCG + this.pages[hashPageMtgDecks] = { name: 'PageMtgDecks', module: PageMtgDecks }; this.pages[hashPageMtgGame] = { name: 'PageMtgGame', module: PageMtgGame }; this.pages[hashPageMtgGames] = { name: 'PageMtgGames', module: PageMtgGames }; this.pages[hashPageMtgHome] = { name: 'PageMtgGame', module: PageMtgHome }; @@ -45,6 +47,7 @@ export default class Router { this.routes = {}; // Core // TCG + this.routes[hashPageMtgDecks] = (isPopState = false) => this.navigateToHash(hashPageMtgDecks, isPopState); this.routes[hashPageMtgGame] = (isPopState = false) => this.navigateToHash(hashPageMtgGame, isPopState); this.routes[hashPageMtgGames] = (isPopState = false) => this.navigateToHash(hashPageMtgGames, isPopState); this.routes[hashPageMtgHome] = (isPopState = false) => this.navigateToHash(hashPageMtgHome, isPopState); diff --git a/templates/components/tcg/_preview_ddl_commander_bracket.html b/templates/components/tcg/_preview_ddl_commander_bracket.html new file mode 100644 index 0000000..4280630 --- /dev/null +++ b/templates/components/tcg/_preview_ddl_commander_bracket.html @@ -0,0 +1,5 @@ + +{% set value_previous = '0' if is_blank_row else commander_bracket_preview.commander_bracket_id %} +{% set text_previous = '' if is_blank_row else commander_bracket_preview.name %} + +
{{ text_previous }}
diff --git a/templates/components/tcg/_row_deck.html b/templates/components/tcg/_row_deck.html new file mode 100644 index 0000000..cca3028 --- /dev/null +++ b/templates/components/tcg/_row_deck.html @@ -0,0 +1,44 @@ + +{% if is_blank_row %} + + + + + + + + + {% include 'components/tcg/_preview_ddl_commander_bracket.html' %} + + {% set active = True %} + {% include 'components/common/inputs/_td_active.html' %} + +{% else %} + + + + + + + + {% set commander_bracket_preview = deck.commander_bracket %} + + {% include 'components/tcg/_preview_ddl_commander_bracket.html' %} + + {% set active = deck.active %} + {% include 'components/common/inputs/_td_active.html' %} + +{% endif %} diff --git a/templates/layouts/_shared_mtg_scripts.html b/templates/layouts/_shared_mtg_scripts.html index 6c9f539..1a644a4 100644 --- a/templates/layouts/_shared_mtg_scripts.html +++ b/templates/layouts/_shared_mtg_scripts.html @@ -1,23 +1,36 @@ +{% endblock %} diff --git a/templates/pages/tcg/mtg/_game.html b/templates/pages/tcg/mtg/_game.html index 36ff0cc..d7dc7ad 100644 --- a/templates/pages/tcg/mtg/_game.html +++ b/templates/pages/tcg/mtg/_game.html @@ -135,7 +135,8 @@ Round Player Received From Commander - Health Change + Life Gain + Life Loss Commander Deaths Is Eliminated @@ -181,9 +182,6 @@ var damageRecords = {{ model.convert_list_objects_to_json(model.damage_records) | tojson | safe }}; var decks = {{ model.convert_list_objects_to_json(model.decks) | tojson | safe }}; var flagDamageLog = "{{ model.FLAG_DAMAGE_LOG }}"; - var flagDisplayOrder = "{{ model.FLAG_DISPLAY_ORDER }}"; - var flagHealthChange = "{{ model.FLAG_HEALTH_CHANGE }}"; - var flagIsEliminated = "{{ model.FLAG_IS_ELIMINATED }}"; var flagRoundDisplayOrderButton = "{{ model.FLAG_ROUND_DISPLAY_ORDER_BUTTON }}"; var flagRoundDisplayOrderMinus = "{{ model.FLAG_ROUND_DISPLAY_ORDER_MINUS }}"; var flagRoundDisplayOrderPlus = "{{ model.FLAG_ROUND_DISPLAY_ORDER_PLUS }}"; diff --git a/templates/pages/tcg/mtg/_games.html b/templates/pages/tcg/mtg/_games.html index 8021d92..485600a 100644 --- a/templates/pages/tcg/mtg/_games.html +++ b/templates/pages/tcg/mtg/_games.html @@ -40,67 +40,65 @@ -
- - - - - - - - - - - - - {% if model.games and model.games|length > 0 %} - {% for game in model.games %} - - - - - - - - - {% endfor %} - {% else %} - - + + + {% endif %} + +
Game IDTypeLocationStartedStatusActions
#{{ game.game_id }} - {% if game.is_commander %} - Commander - {% elif game.is_draft %} - Draft - {% elif game.is_sealed %} - Sealed - {% else %} - Standard - {% endif %} - {{ game.location_name or 'Unknown' }}{{ model.format_datetime_text(game.start_on) if game.start_on else 'Not started' }} - {% if game.end_on %} - Ended - {% elif game.active %} - Active - {% else %} - Inactive - {% endif %} - - Join Game -
-
- -

No games found. Start a new battle!

-
+ + + + + + + + + + + + + {% if model.games and model.games|length > 0 %} + {% for game in model.games %} + + + + + + + - {% endif %} - -
Game IDTypeLocationStartedStatusActions
#{{ game.game_id }} + {% if game.is_commander %} + Commander + {% elif game.is_draft %} + Draft + {% elif game.is_sealed %} + Sealed + {% else %} + Standard + {% endif %} + {{ game.location_name or 'Unknown' }}{{ model.format_datetime_text(game.start_on) if game.start_on else 'Not started' }} + {% if game.end_on %} + Ended + {% elif game.active %} + Active + {% else %} + Inactive + {% endif %} + + Join Game
- + {% endfor %} + {% else %} +
+
+ +

No games found. Start a new battle!

+
+
-