public function OnPrePageLoad()
 {
     # Different page title for add and edit
     if ($this->player->GetId() and !$this->add_player_already_exists) {
         $this->SetPageTitle("Rename " . $this->player->GetName());
     } else {
         $this->SetPageTitle("Add player for " . $this->player->Team()->GetName());
     }
     $this->SetContentConstraint(StoolballPage::ConstrainText());
     $this->LoadClientScript("playeredit.js", true);
 }
 public function __construct(Player $player)
 {
     $this->searchable = new SearchItem("player", "player" . $player->GetId(), $player->GetPlayerUrl());
     $this->searchable->Description($player->GetPlayerDescription());
     $this->searchable->WeightOfType(20);
     if ($player->GetPlayerRole() == Player::PLAYER) {
         $this->searchable->Title($player->GetName() . ", " . $player->Team()->GetName());
         $this->searchable->WeightWithinType($player->GetTotalMatches());
     } else {
         $this->searchable->Title($player->GetName() . " conceded by " . $player->Team()->GetName());
     }
     $this->searchable->Keywords($this->searchable->Title());
 }
 /**
  * Merges the records for two players, retaining the id of the destination player
  * @param int $source_player_id
  * @param int $destination_player_id
  * @return void
  */
 public function MergePlayers(Player $source_player, Player $destination_player)
 {
     if (!$source_player->GetId()) {
         throw new Exception("source_player must have an Id");
     }
     if (!$destination_player->GetId()) {
         throw new Exception("destination_player must have an Id");
     }
     if ($source_player->GetPlayerRole() != PLAYER::PLAYER) {
         throw new Exception("Cannot merge source player because it's an extras player");
     }
     if ($destination_player->GetPlayerRole() != PLAYER::PLAYER) {
         throw new Exception("Cannot merge destination player because it's an extras player");
     }
     $players = $this->GetSettings()->GetTable("Player");
     $batting = $this->GetSettings()->GetTable("Batting");
     $bowling = $this->GetSettings()->GetTable("Bowling");
     $matches = $this->GetSettings()->GetTable("Match");
     $statistics = $this->GetSettings()->GetTable("PlayerMatch");
     # Make a note of matches where source player was involved
     $sql = "SELECT DISTINCT match_team_id FROM {$batting} WHERE player_id = " . $source_player->GetId();
     $result = $this->GetDataConnection()->query($sql);
     $source_batted = array();
     while ($row = $result->fetch()) {
         $source_batted[] = $row->match_team_id;
     }
     $sql = "SELECT match_team_id FROM {$statistics}\n\t\t\t\tWHERE player_id = " . $source_player->GetId() . " AND (run_outs > 0 OR catches > 0)";
     $result = $this->GetDataConnection()->query($sql);
     $source_fielded = array();
     while ($row = $result->fetch()) {
         $source_fielded[] = $row->match_team_id;
     }
     $sql = "SELECT match_team_id FROM {$statistics}\n\t\t\t\tWHERE player_id = " . $source_player->GetId() . " AND wickets IS NOT NULL";
     $result = $this->GetDataConnection()->query($sql);
     $source_bowled = array();
     while ($row = $result->fetch()) {
         $source_bowled[] = $row->match_team_id;
     }
     $sql = "SELECT match_id FROM {$statistics}\n\t\t\t\tWHERE player_id = " . $source_player->GetId() . " AND player_of_match = 1";
     $result = $this->GetDataConnection()->query($sql);
     $source_player_of_match = array();
     while ($row = $result->fetch()) {
         $source_player_of_match[] = $row->match_id;
     }
     # Transfer batting and bowling
     $this->LoggedQuery("UPDATE {$batting} SET player_id = " . Sql::ProtectNumeric($destination_player->GetId()) . "\n\t\tWHERE player_id = " . Sql::ProtectNumeric($source_player->GetId()));
     $this->LoggedQuery("UPDATE {$batting} SET dismissed_by_id = " . Sql::ProtectNumeric($destination_player->GetId()) . "\n\t\tWHERE dismissed_by_id = " . Sql::ProtectNumeric($source_player->GetId()));
     $this->LoggedQuery("UPDATE {$batting} SET bowler_id = " . Sql::ProtectNumeric($destination_player->GetId()) . "\n\t\tWHERE bowler_id = " . Sql::ProtectNumeric($source_player->GetId()));
     $this->LoggedQuery("UPDATE {$bowling} SET player_id = " . Sql::ProtectNumeric($destination_player->GetId()) . "\n\t\tWHERE player_id = " . Sql::ProtectNumeric($source_player->GetId()));
     # Update dismissals in stats table too, because then fielding statistics will update correctly below.
     # Normally dismissals are updated with the batting, but here it's quite possible we are only updating the fielding.
     $this->LoggedQuery("UPDATE {$statistics} SET caught_by = " . Sql::ProtectNumeric($destination_player->GetId()) . "\n\t\tWHERE caught_by = " . Sql::ProtectNumeric($source_player->GetId()));
     $this->LoggedQuery("UPDATE {$statistics} SET run_out_by = " . Sql::ProtectNumeric($destination_player->GetId()) . "\n\t\tWHERE run_out_by = " . Sql::ProtectNumeric($source_player->GetId()));
     if (!$this->is_internal_delete) {
         # Doing an internal delete the destination player will be Unknown. Transfer batting and bowling
         # because that preserves the position for other bowlers and batters as well as related statistics
         # such as number of runs. But set player of the match to null because there's not much value in
         # setting it unknown.
         # Transfer player of the match award
         $this->LoggedQuery("UPDATE {$matches} SET player_of_match_id = " . Sql::ProtectNumeric($destination_player->GetId()) . ",\n\t\t\tdate_changed = " . gmdate('U') . "\n\t\t\tWHERE player_of_match_id = " . Sql::ProtectNumeric($source_player->GetId()));
         $this->LoggedQuery("UPDATE {$matches} SET player_of_match_home_id = " . Sql::ProtectNumeric($destination_player->GetId()) . ",\n\t\t\tdate_changed = " . gmdate('U') . "\n\t\t\tWHERE player_of_match_home_id = " . Sql::ProtectNumeric($source_player->GetId()));
         $this->LoggedQuery("UPDATE {$matches} SET player_of_match_away_id = " . Sql::ProtectNumeric($destination_player->GetId()) . ",\n\t\t\tdate_changed = " . gmdate('U') . "\n\t\t\tWHERE player_of_match_away_id = " . Sql::ProtectNumeric($source_player->GetId()));
         # If a user has claimed either player, remember that. If two different claimants, prefer the destination one.
         if ($source_player->GetUser() instanceof User and $source_player->GetUser()->GetId()) {
             $this->LoggedQuery("UPDATE {$players}\n\t\t\t\tSET user_id = " . Sql::ProtectNumeric($source_player->GetUser()->GetId()) . ",\n\t\t\t\tdate_changed = " . gmdate('U') . "\n\t\t\t\tWHERE player_id = " . Sql::ProtectNumeric($destination_player->GetId()) . " AND user_id = NULL");
         }
         # Now that the source player's data has been moved, delete the source player
         $this->Delete(array($source_player->GetId()));
     }
     # Recalculate all the derived data
     # Note: this method is tightly integrated with the Delete() method. They call each other. When the source player
     # is deleted, above, it will call back into this method before all the derived statistics for the source player
     # have gone. Therefore the queries at the top of this method will find the source player still exists. That in turn
     # leads to these methods being called for a player which has only derived statistics, and no actual data. It is
     # important therefore to call DeleteObsoleteStatistics() to clear out the redundant records as soon as they created.
     require_once 'stoolball/statistics/statistics-manager.class.php';
     $statistics_manager = new StatisticsManager($this->GetSettings(), $this->GetDataConnection());
     if (count($source_batted)) {
         $statistics_manager->UpdateBattingStatistics(array($destination_player->GetId()), $source_batted);
     }
     if (count($source_fielded)) {
         $statistics_manager->UpdateFieldingStatistics(array($destination_player->GetId()), $source_fielded);
     }
     if (count($source_bowled)) {
         $statistics_manager->UpdateBowlingStatistics(array($destination_player->GetId()), $source_bowled);
     }
     foreach ($source_player_of_match as $match_id) {
         $statistics_manager->UpdatePlayerOfTheMatchStatistics($match_id);
         $statistics_manager->DeleteObsoleteStatistics($match_id);
     }
     $statistics_manager->UpdatePlayerStatistics(array($destination_player->GetId()));
     unset($statistics_manager);
 }
 public function OnPageLoad()
 {
     if ($this->not_found) {
         require_once $_SERVER['DOCUMENT_ROOT'] . "/wp-content/themes/stoolball/section-404.php";
         return;
     }
     if ($this->regenerating) {
         echo $this->regenerating_control;
         return;
     }
     # Container element for structured data
     echo '<div typeof="schema:Person" about="' . htmlentities($this->player->GetLinkedDataUri(), ENT_QUOTES, "UTF-8", false) . '">';
     $querystring = '?player=' . $this->player->GetId();
     if ($_SERVER["QUERY_STRING"]) {
         $querystring = htmlspecialchars('?' . $_SERVER["QUERY_STRING"]);
     }
     require_once "stoolball/statistics/player-summary-control.class.php";
     echo new \Stoolball\Statistics\PlayerSummaryControl($this->player, $this->filter, $this->filter_matched_nothing, $querystring);
     if ($this->player->GetPlayerRole() == Player::PLAYER) {
         require_once 'xhtml/navigation/tabs.class.php';
         $tabs = array('Batting' => '', 'Bowling and fielding' => $this->player->GetPlayerUrl() . '/bowling');
         echo new Tabs($tabs);
         ?>
         <div class="box tab-box">
             <div class="dataFilter"></div>
             <div class="box-content">
         <?php 
     }
     # Filter control
     echo $this->filter_control;
     # Batting stats
     if ($this->player->TotalBattingInnings()) {
         //echo "<h2>Batting</h2>";
         # Overview table
         $batting_table = new XhtmlTable();
         $batting_table->SetCssClass("numeric");
         $batting_table->SetCaption("Batting");
         $batting_heading_row = new XhtmlRow(array('<abbr title="Innings" class="small">Inn</abbr><span class="large">Innings</span>', "Not out", "Runs", "50s", "100s", "Best", '<abbr title="Average" class="small">Avg</abbr><span class="large">Average</span>', '<abbr title="Strike rate" class="small">S/R</abbr><span class="large">Strike rate</span>'));
         $batting_heading_row->SetIsHeader(true);
         $batting_table->AddRow($batting_heading_row);
         $batting_table->AddRow(new XhtmlRow(array($this->player->TotalBattingInnings(), $this->player->NotOuts(), $this->player->TotalRuns(), $this->player->Fifties(), $this->player->Centuries(), $this->player->BestBatting(), is_null($this->player->BattingAverage()) ? "&#8211;" : $this->player->BattingAverage(), is_null($this->player->BattingStrikeRate()) ? "&#8211;" : $this->player->BattingStrikeRate())));
         echo $batting_table;
         if ($this->player->TotalBattingInnings()) {
             echo '<p class="statsViewAll"><a href="/play/statistics/individual-scores' . $querystring . '">Individual scores &#8211; view all and filter</a></p>';
         }
         ?>
         <span class="chart-js-template" id="score-spread-chart"></span>
         <span class="chart-js-template" id="batting-form-chart"></span>
         <span class="chart-js-template" id="dismissals-chart"></span>
         <?php 
     }
     $this->ShowSocial();
     if ($this->player->GetPlayerRole() == Player::PLAYER) {
         ?>
         </div>
         </div>
         <?php 
     }
     # End container for structured data
     echo "</div>";
     if ($this->player->GetPlayerRole() == Player::PLAYER) {
         $has_permission = AuthenticationManager::GetUser()->Permissions()->HasPermission(PermissionType::MANAGE_TEAMS, $this->player->Team()->GetLinkedDataUri());
         $has_admin_permission = AuthenticationManager::GetUser()->Permissions()->HasPermission(PermissionType::MANAGE_PLAYERS);
         if ($has_permission) {
             $this->AddSeparator();
             $panel = new UserEditPanel($this->GetSettings());
             $panel->AddLink("rename this player", $this->player->GetEditUrl());
             if ($has_admin_permission) {
                 $panel->AddLink("delete this player", $this->player->GetDeleteUrl());
             }
             echo $panel;
         }
     }
 }
    public function OnLoadPageData()
    {
        # Now get statistics for the player
        $filter_by_player = array($this->player->GetId());
        $statistics_manager = new StatisticsManager($this->GetSettings(), $this->GetDataConnection());
        $statistics_manager->FilterByPlayer($filter_by_player);
        # Apply filters common to all statistics
        StatisticsFilter::SupportMatchTypeFilter($statistics_manager);
        StatisticsFilter::SupportOppositionFilter($statistics_manager);
        StatisticsFilter::SupportCompetitionFilter($statistics_manager);
        StatisticsFilter::ApplySeasonFilter($this->GetSettings(), $this->GetDataConnection(), $statistics_manager);
        StatisticsFilter::SupportGroundFilter($statistics_manager);
        StatisticsFilter::SupportDateFilter($statistics_manager);
        StatisticsFilter::SupportBattingPositionFilter($statistics_manager);
        StatisticsFilter::SupportInningsFilter($statistics_manager);
        StatisticsFilter::SupportMatchResultFilter($statistics_manager);
        # Now get the statistics for the player
        $this->player = new Player($this->GetSettings());
        $data = $statistics_manager->ReadBestBowlingPerformance(true);
        foreach ($data as $performance) {
            # Not useful for either average or economy
            if (is_null($performance["runs_conceded"])) {
                continue;
            }
            $bowling = new Bowling($this->player);
            $bowling->SetWickets($performance["wickets"]);
            $bowling->SetRunsConceded($performance["runs_conceded"]);
            $bowling->SetOvers($performance["overs"]);
            $match = new Match($this->GetSettings());
            $match->SetStartTime($performance["match_time"]);
            $bowling->SetMatch($match);
            $this->player->Bowling()->Add($bowling);
        }
        $statistics_manager->FilterByPlayer(null);
        $statistics_manager->FilterByBowler($filter_by_player);
        $statistics_manager->FilterByHowOut(array(Batting::BODY_BEFORE_WICKET, Batting::BOWLED, Batting::CAUGHT, Batting::CAUGHT_AND_BOWLED, Batting::HIT_BALL_TWICE));
        $this->player->SetHowWicketsTaken($statistics_manager->ReadHowWicketsFall());
        unset($statistics_manager);
        # How dismissed
        ?>
{
    <?php 
        if ($this->player->Bowling()->GetCount()) {
            ?>
        "economy": {
            "labels": [<?php 
            echo $this->BuildBowlingTimeline($this->player->Bowling()->GetItems());
            ?>
],
            "datasets": [
                {
                    "label": "Economy in each match",
                    "data": [<?php 
            echo $this->BuildMatchEconomyData($this->player->Bowling()->GetItems());
            ?>
]
                },
                {
                    "label": "Economy overall",
                    "data": [<?php 
            echo $this->BuildEconomyData($this->player->Bowling()->GetItems());
            ?>
]
                }
            ]
        },                    
        "bowlingAverage": {
            "labels": [<?php 
            echo $this->BuildBowlingTimeline($this->player->Bowling()->GetItems());
            ?>
],
            "datasets": [
                {
                    "label": "Average in each match",
                    "data": [<?php 
            echo $this->BuildMatchBowlingAverageData($this->player->Bowling()->GetItems());
            ?>
]
                },
                {
                    "label": "Average overall",
                    "data": [<?php 
            echo $this->BuildBowlingAverageData($this->player->Bowling()->GetItems());
            ?>
]
                }
            ]
        },                    
        <?php 
        }
        ?>
    "wickets": [
        <?php 
        $how_out = $this->player->GetHowWicketsTaken();
        $len = count($how_out);
        $count = 0;
        foreach ($how_out as $key => $value) {
            $label = ucfirst(html_entity_decode(Batting::Text($key)));
            echo '{ "label":"' . $label . '","value":' . $value . "}";
            $count++;
            if ($count < $len) {
                echo ',';
            }
        }
        ?>
        
    ]    
}
        <?php 
        exit;
    }
    public function OnLoadPageData()
    {
        # Now get statistics for the player
        $filter_by_player = array($this->player->GetId());
        $statistics_manager = new StatisticsManager($this->GetSettings(), $this->GetDataConnection());
        $statistics_manager->FilterByPlayer($filter_by_player);
        # Apply filters common to all statistics
        StatisticsFilter::SupportMatchTypeFilter($statistics_manager);
        StatisticsFilter::SupportOppositionFilter($statistics_manager);
        StatisticsFilter::SupportCompetitionFilter($statistics_manager);
        StatisticsFilter::ApplySeasonFilter($this->GetSettings(), $this->GetDataConnection(), $statistics_manager);
        StatisticsFilter::SupportGroundFilter($statistics_manager);
        StatisticsFilter::SupportDateFilter($statistics_manager);
        StatisticsFilter::SupportBattingPositionFilter($statistics_manager);
        StatisticsFilter::SupportInningsFilter($statistics_manager);
        StatisticsFilter::SupportMatchResultFilter($statistics_manager);
        # Now get the statistics for the player
        $this->player = new Player($this->GetSettings());
        $data = $statistics_manager->ReadBestBattingPerformance(false, true);
        foreach ($data as $performance) {
            $batting = new Batting($this->player, $performance["how_out"], null, null, $performance["runs_scored"]);
            $match = new Match($this->GetSettings());
            $match->SetStartTime($performance["match_time"]);
            $batting->SetMatch($match);
            $this->player->Batting()->Add($batting);
        }
        unset($statistics_manager);
        # How dismissed
        ?>
{
    <?php 
        $score_spread = $this->player->ScoreSpread();
        if (is_array($score_spread)) {
            ?>
    "scoreSpread": {
        "labels":  [
        <?php 
            $len = count($score_spread);
            $count = 0;
            foreach ($score_spread as $key => $value) {
                echo '"' . $key . '"';
                $count++;
                if ($count < $len) {
                    echo ',';
                }
            }
            ?>
         
        ],
        "datasets": [
             {
                 "label": "Not out", 
                "data":  [
                <?php 
            $len = count($score_spread);
            $count = 0;
            foreach ($score_spread as $key => $value) {
                echo $value["not-out"];
                $count++;
                if ($count < $len) {
                    echo ',';
                }
            }
            ?>
                ]
            }, 
             {
                 "label": "Out", 
                "data":  [
                <?php 
            $len = count($score_spread);
            $count = 0;
            foreach ($score_spread as $key => $value) {
                echo $value["out"];
                $count++;
                if ($count < $len) {
                    echo ',';
                }
            }
            ?>
                ]
            }
        ]
    },
    <?php 
        }
        if ($this->player->Batting()->GetCount()) {
            ?>
        "battingForm": {
            "labels": [<?php 
            echo $this->BuildBattingTimeline($this->player->Batting()->GetItems());
            ?>
],
            "datasets": [
                {
                    "label": "Scores",
                    "data": [<?php 
            echo $this->BuildScoresData($this->player->Batting()->GetItems());
            ?>
]
                },
                {
                    "label": "Average",
                    "data": [<?php 
            echo $this->BuildBattingAverageData($this->player->Batting()->GetItems());
            ?>
]
                }
            ]
        },                    
        <?php 
        }
        ?>
    "dismissals": [
        <?php 
        $how_out = $this->player->HowOut();
        $len = count($how_out);
        $count = 0;
        foreach ($how_out as $key => $value) {
            if ($key == Batting::DID_NOT_BAT) {
                continue;
            }
            $label = ucfirst(html_entity_decode(Batting::Text($key)));
            echo '{ "label":"' . $label . '","value":' . $value . "}";
            $count++;
            if ($count < $len) {
                echo ',';
            }
        }
        ?>
        
    ]
}
        <?php 
        exit;
    }
 public function OnPageLoad()
 {
     if ($this->not_found) {
         require_once $_SERVER['DOCUMENT_ROOT'] . "/wp-content/themes/stoolball/section-404.php";
         return;
     }
     if ($this->regenerating) {
         echo $this->regenerating_control;
         return;
     }
     # Container element for structured data
     echo '<div typeof="schema:Person" about="' . htmlentities($this->player->GetLinkedDataUri(), ENT_QUOTES, "UTF-8", false) . '">';
     $querystring = '?player=' . $this->player->GetId();
     if ($_SERVER["QUERY_STRING"]) {
         $querystring = htmlspecialchars('?' . $_SERVER["QUERY_STRING"]);
     }
     require_once "stoolball/statistics/player-summary-control.class.php";
     echo new \Stoolball\Statistics\PlayerSummaryControl($this->player, $this->filter, $this->filter_matched_nothing, $querystring);
     if ($this->player->GetPlayerRole() == Player::PLAYER) {
         require_once 'xhtml/navigation/tabs.class.php';
         $tabs = array('Batting' => $this->player->GetPlayerUrl(), 'Bowling and fielding' => '');
         echo new Tabs($tabs);
         ?>
         <div class="box tab-box">
             <div class="dataFilter"></div>
             <div class="box-content">
         <?php 
     }
     # Filter control
     echo $this->filter_control;
     if ($this->player->Bowling()->GetCount()) {
         //			echo "<h2>Bowling</h2>";
         # Overview table
         $bowling_table = new XhtmlTable();
         $bowling_table->SetCssClass("numeric");
         $bowling_table->SetCaption("Bowling");
         $bowling_heading_row = new XhtmlRow(array('<abbr title="Innings" class="small">Inn</abbr><span class="large">Innings</span>', '<abbr title="Overs" class="small">Ov</abbr><span class="large">Overs</span>', '<abbr title="Maiden overs" class="small">Md</abbr><abbr title="Maiden overs" class="large">Mdns</abbr>', "Runs", '<abbr title="Wickets" class="small">Wk</abbr><abbr title="Wickets" class="large">Wkts</abbr>', "Best", '<abbr title="Economy" class="small">Econ</abbr><span class="large">Economy</span>', '<abbr title="Average" class="small">Avg</abbr><span class="large">Average</span>', '<abbr title="Strike rate" class="small">S/R</abbr><span class="large">Strike rate</span>', '<abbr title="5 wickets" class="small">5 wk</abbr><abbr title="5 wickets" class="large">5 wkts</abbr>'));
         $bowling_heading_row->SetIsHeader(true);
         $bowling_table->AddRow($bowling_heading_row);
         $bowling_table->AddRow(new XhtmlRow(array($this->player->BowlingInnings(), $this->player->Overs(), $this->player->MaidenOvers(), $this->player->RunsAgainst(), $this->player->WicketsTaken(), is_null($this->player->BestBowling()) ? "&#8211;" : $this->player->BestBowling(), is_null($this->player->BowlingEconomy()) ? "&#8211;" : $this->player->BowlingEconomy(), is_null($this->player->BowlingAverage()) ? "&#8211;" : $this->player->BowlingAverage(), is_null($this->player->BowlingStrikeRate()) ? "&#8211;" : $this->player->BowlingStrikeRate(), $this->player->FiveWicketHauls())));
         echo $bowling_table;
         echo '<p class="statsViewAll"><a href="/play/statistics/bowling-performances' . $querystring . '">Bowling performances &#8211; view all and filter</a></p>';
     }
     ?>
     <span class="chart-js-template" id="economy-chart"></span>
     <span class="chart-js-template" id="bowling-average-chart"></span>
     <span class="chart-js-template" id="wickets-chart"></span>
     <?php 
     # Fielding
     $catches = $this->player->GetCatches();
     $run_outs = $this->player->GetRunOuts();
     if ($catches or $run_outs) {
         $fielding_table = new XhtmlTable();
         $fielding_table->SetCssClass("numeric");
         $fielding_table->SetCaption("Fielding");
         $fielding_heading_row = new XhtmlRow(array('Catches', "Run-outs"));
         $fielding_heading_row->SetIsHeader(true);
         $fielding_table->AddRow($fielding_heading_row);
         $fielding_table->AddRow(new XhtmlRow(array($catches, $run_outs)));
         echo $fielding_table;
     }
     $this->ShowSocial();
     if ($this->player->GetPlayerRole() == Player::PLAYER) {
         ?>
         </div>
         </div>
         <?php 
     }
     # End container for structured data
     echo "</div>";
     if ($this->player->GetPlayerRole() == Player::PLAYER) {
         $has_permission = AuthenticationManager::GetUser()->Permissions()->HasPermission(PermissionType::MANAGE_TEAMS, $this->player->Team()->GetLinkedDataUri());
         $has_admin_permission = AuthenticationManager::GetUser()->Permissions()->HasPermission(PermissionType::MANAGE_PLAYERS);
         if ($has_permission) {
             $this->AddSeparator();
             $panel = new UserEditPanel($this->GetSettings());
             $panel->AddLink("rename this player", $this->player->GetEditUrl());
             if ($has_admin_permission) {
                 $panel->AddLink("delete this player", $this->player->GetDeleteUrl());
             }
             echo $panel;
         }
     }
 }