text:
static CGFloat const StatsTableGraphHeight = 185.0f;
static CGFloat const StatsTableNoResultsHeight = 100.0f;
static CGFloat const StatsTableGroupHeaderHeight = 30.0f;
static NSInteger const StatsTableRowDataOffsetStandard = 2;
static NSInteger const StatsTableRowDataOffsetWithoutGroupHeader = 1;
static NSInteger const StatsTableRowDataOffsetWithGroupSelector = 3;
static NSInteger const StatsTableRowDataOffsetWithGroupSelectorAndTotal = 4;
static NSString *const StatsTableGroupHeaderCellIdentifier = @"GroupHeader";
static NSString *const StatsTableGroupSelectorCellIdentifier = @"GroupSelector";
static NSString *const StatsTableGroupTotalsCellIdentifier = @"GroupTotalsRow";
static NSString *const StatsTableTwoColumnHeaderCellIdentifier = @"TwoColumnHeader";
static NSString *const StatsTableTwoColumnCellIdentifier = @"TwoColumnRow";
static NSString *const StatsTableGraphSelectableCellIdentifier = @"SelectableRow";
static NSString *const StatsTableViewAllCellIdentifier = @"MoreRow";
static NSString *const StatsTableGraphCellIdentifier = @"GraphRow";
static NSString *const StatsTableNoResultsCellIdentifier = @"NoResultsRow";
static NSString *const StatsTablePeriodHeaderCellIdentifier = @"PeriodHeader";
static NSString *const StatsTableSectionHeaderSimpleBorder = @"StatsTableSectionHeaderSimpleBorder";

@interface StatsTableViewController () <WPStatsGraphViewControllerDelegate>

@property (nonatomic, strong) NSArray *sections;
@property (nonatomic, strong) NSMutableDictionary *sectionData;
@property (nonatomic, strong) WPStatsGraphViewController *graphViewController;
@property (nonatomic, assign) StatsPeriodUnit selectedPeriodUnit;
@property (nonatomic, assign) StatsSummaryType selectedSummaryType;
@property (nonatomic, strong) NSDate *selectedDate;

@end

@implementation StatsTableViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    NSBundle *bundle = [NSBundle statsBundle];

    [self.tableView registerClass:[StatsTableSectionHeaderView class] forHeaderFooterViewReuseIdentifier:StatsTableSectionHeaderSimpleBorder];
    [self.tableView registerNib:[UINib nibWithNibName:@"StatsNoResultsRowTableViewCell" bundle:bundle] forCellReuseIdentifier:StatsTableNoResultsCellIdentifier];

    self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 20.0f)];
    self.tableView.backgroundColor = [WPStyleGuide itsEverywhereGrey];
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

    [self setupRefreshControl];

    // Posts, Referrers, Clicks, Authors, Countries, Search Terms, Published, Videos, Comments, Tags, Followers, Publicize
    self.sections =     @[ @(StatsSectionGraph),
                           @(StatsSectionPeriodHeader),
                           @(StatsSectionPosts),
                           @(StatsSectionReferrers),
                           @(StatsSectionClicks),
                           @(StatsSectionAuthors),
                           @(StatsSectionCountry),
                           @(StatsSectionSearchTerms),
                           @(StatsSectionEvents),
                           @(StatsSectionVideos)];

    [self wipeDataAndSeedGroups];

    self.graphViewController = [WPStatsGraphViewController new];

    [self resetDateToTodayForSite];
    self.selectedPeriodUnit = StatsPeriodUnitDay;
    self.selectedSummaryType = StatsSummaryTypeViews;
    self.graphViewController.allowDeselection = NO;
    self.graphViewController.graphDelegate = self;
    [self addChildViewController:self.graphViewController];
    [self.graphViewController didMoveToParentViewController:self];

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
    [nc addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    [self.tableView reloadData];

    [self trackViewControllerAnalytics];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)applicationDidBecomeActive:(NSNotification *)notification
{
    [self resetDateToTodayForSite];
    [self retrieveStatsSkipGraph:NO];
}

#pragma mark - UITableViewDataSource methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return (NSInteger)self.sections.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    StatsSection statsSection = [self statsSectionForTableViewSection:section];
    id data = [self statsDataForStatsSection:statsSection];

    switch (statsSection) {
        case StatsSectionGraph:
            return 5;
        case StatsSectionPeriodHeader:
            return 1;

        // TODO :: Pull offset from StatsGroup
        default:
        {
            StatsGroup *group = (StatsGroup *)data;
            NSInteger count = (NSInteger)group.numberOfRows;

            if (statsSection == StatsSectionComments) {
                count += StatsTableRowDataOffsetWithGroupSelector;
            } else if (statsSection == StatsSectionFollowers) {
                count += StatsTableRowDataOffsetWithGroupSelectorAndTotal;

                if (group.errorWhileRetrieving) {
                    count--;
                }
            } else if (statsSection == StatsSectionEvents) {
                if (count == 0) {
                    count = StatsTableRowDataOffsetStandard;
                } else {
                    count += StatsTableRowDataOffsetWithoutGroupHeader;
                }
            } else {
                count += StatsTableRowDataOffsetStandard;
            }

            if (group.moreItemsExist) {
                count++;
            }

            return count;
        }
    }

    return 0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellIdentifier = [self cellIdentifierForIndexPath:indexPath];
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

    [self configureCell:cell forIndexPath:indexPath];

    return cell;
}

#pragma mark - UITableViewDelegate methods

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    if ([self statsSectionForTableViewSection:section] != StatsSectionPeriodHeader) {
        StatsTableSectionHeaderView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:StatsTableSectionHeaderSimpleBorder];

        return headerView;
    }

    return nil;
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
    if ([self statsSectionForTableViewSection:section] != StatsSectionPeriodHeader) {
        StatsTableSectionHeaderView *footerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:StatsTableSectionHeaderSimpleBorder];
        footerView.footer = YES;

        return footerView;
    }

    return nil;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 1.0f;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    return 10.0f;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellIdentifier = [self cellIdentifierForIndexPath:indexPath];

    if ([cellIdentifier isEqualToString:StatsTableGraphCellIdentifier]) {
        return StatsTableGraphHeight;
    } else if ([cellIdentifier isEqualToString:StatsTableGroupHeaderCellIdentifier]) {
        return StatsTableGroupHeaderHeight;
    } else if ([cellIdentifier isEqualToString:StatsTableNoResultsCellIdentifier]) {
        return StatsTableNoResultsHeight;
    }

    return 44.0f;
}

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    StatsSection statsSection = [self statsSectionForTableViewSection:indexPath.section];

    if (statsSection == StatsSectionGraph && indexPath.row > 0) {
        for (NSIndexPath *selectedIndexPath in [tableView indexPathsForSelectedRows]) {
            [tableView deselectRowAtIndexPath:selectedIndexPath animated:YES];
        }

        return indexPath;
    } else if ([[self cellIdentifierForIndexPath:indexPath] isEqualToString:StatsTableViewAllCellIdentifier]) {
        return indexPath;
    } else if ([[self cellIdentifierForIndexPath:indexPath] isEqualToString:StatsTableTwoColumnCellIdentifier]) {
        // Disable taps on rows without children
        StatsGroup *group = [self statsDataForStatsSection:statsSection];
        StatsItem *item = [group statsItemForTableViewRow:indexPath.row];

        BOOL hasChildItems = item.children.count > 0;
        // TODO :: Look for default action boolean
        BOOL hasDefaultAction = item.actions.count > 0;
        NSIndexPath *newIndexPath = (hasChildItems || hasDefaultAction) ? indexPath : nil;

        return newIndexPath;
    }

    return nil;
}

- (NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([self statsSectionForTableViewSection:indexPath.section] == StatsSectionGraph && indexPath.row > 0) {
        return nil;
    }

    return indexPath;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    StatsSection statsSection = [self statsSectionForTableViewSection:indexPath.section];
    if (statsSection == StatsSectionGraph && indexPath.row > 0) {
        self.selectedSummaryType = (StatsSummaryType)(indexPath.row - 1);

        NSIndexPath *graphIndexPath = [NSIndexPath indexPathForItem:0 inSection:indexPath.section];
        [tableView beginUpdates];
        [tableView reloadRowsAtIndexPaths:@[graphIndexPath] withRowAnimation:UITableViewRowAnimationNone];
        [tableView endUpdates];
    } else if ([[self cellIdentifierForIndexPath:indexPath] isEqualToString:StatsTableTwoColumnCellIdentifier]) {
        [tableView deselectRowAtIndexPath:indexPath animated:YES];

        StatsGroup *statsGroup = [self statsDataForStatsSection:statsSection];
        StatsItem *statsItem = [statsGroup statsItemForTableViewRow:indexPath.row];

        // Do nothing for posts - handled by segue to show post details
        if (statsSection == StatsSectionPosts || (statsSection == StatsSectionAuthors && statsItem.parent != nil)) {
            return;
        }

        if (statsItem.children.count > 0) {
            BOOL insert = !statsItem.isExpanded;
            NSInteger numberOfRowsBefore = (NSInteger)statsItem.numberOfRows - 1;
            statsItem.expanded = !statsItem.isExpanded;
            NSInteger numberOfRowsAfter = (NSInteger)statsItem.numberOfRows - 1;

            StatsTwoColumnTableViewCell *cell = (StatsTwoColumnTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
            cell.expanded = statsItem.isExpanded;
            [cell doneSettingProperties];

            NSMutableArray *indexPaths = [NSMutableArray new];

            NSInteger numberOfRows = insert ? numberOfRowsAfter : numberOfRowsBefore;
            for (NSInteger row = 1; row <= numberOfRows; ++row) {
                [indexPaths addObject:[NSIndexPath indexPathForRow:(row + indexPath.row) inSection:indexPath.section]];
            }

            // Reload row one above to get rid of the double border
            NSIndexPath *previousRowIndexPath = [NSIndexPath indexPathForRow:indexPath.row - 1 inSection:indexPath.section];

            [self.tableView beginUpdates];
            [self.tableView reloadRowsAtIndexPaths:@[previousRowIndexPath] withRowAnimation:UITableViewRowAnimationNone];
            [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];

            if (insert) {
                [self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationMiddle];
            } else {
                [self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
            }

            [self.tableView endUpdates];
        } else if (statsItem.actions.count > 0) {
            for (StatsItemAction *action in statsItem.actions) {
                if (action.defaultAction) {
                    if ([self.statsDelegate respondsToSelector:@selector(statsViewController:openURL:)]) {
                        WPStatsViewController *statsViewController = (WPStatsViewController *)self.navigationController;
                        [self.statsDelegate statsViewController:statsViewController openURL:action.url];
                    } else {
                        [AppExtensionUtils openURL:action.url fromController:self];
                    }
                    break;
                }
            }
        }
    }
}

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSInteger numberOfSections = [self.tableView numberOfSections];
    NSInteger numberOfRows = [self.tableView numberOfRowsInSection:(numberOfSections - 1)];

    if (indexPath.section == (numberOfSections - 1) && indexPath.row == (numberOfRows - 1)) {
        [WPAnalytics track:WPAnalyticsStatStatsScrolledToBottom withProperties:@{ @"blog_id" : self.statsService.siteId}];
    }
}

#pragma mark - Segue methods

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(UITableViewCell *)sender
{
    if ([identifier isEqualToString:@"PostDetails"]) {
        NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
        StatsSection statsSection = [self statsSectionForTableViewSection:indexPath.section];
        StatsGroup *statsGroup = [self statsDataForStatsSection:statsSection];
        StatsItem *statsItem = [statsGroup statsItemForTableViewRow:indexPath.row];

        // Only fire the segue for the posts section or authors if a nested row
        return statsSection == StatsSectionPosts || (statsSection == StatsSectionAuthors && statsItem.parent != nil);
    }

    return YES;
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(UITableViewCell *)sender
{
    [super prepareForSegue:segue sender:sender];

    NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
    StatsSection statsSection = [self statsSectionForTableViewSection:indexPath.section];

    if ([segue.destinationViewController isKindOfClass:[StatsViewAllTableViewController class]]) {
        StatsViewAllTableViewController *viewAllVC = (StatsViewAllTableViewController *)segue.destinationViewController;
        viewAllVC.selectedDate = self.selectedDate;
        viewAllVC.periodUnit = self.selectedPeriodUnit;
        viewAllVC.statsSection = statsSection;
        viewAllVC.statsSubSection = StatsSubSectionNone;
        viewAllVC.statsService = self.statsService;
        viewAllVC.statsDelegate = self.statsDelegate;
    } else if ([segue.destinationViewController isKindOfClass:[StatsPostDetailsTableViewController class]]) {
        StatsGroup *statsGroup = [self statsDataForStatsSection:statsSection];
        StatsItem *statsItem = [statsGroup statsItemForTableViewRow:indexPath.row];

        StatsPostDetailsTableViewController *postVC = (StatsPostDetailsTableViewController *)segue.destinationViewController;
        postVC.postID = statsItem.itemID;
        postVC.postTitle = statsItem.label;
        postVC.statsService = self.statsService;
        postVC.statsDelegate = self.statsDelegate;
    }

    [self.tableView deselectRowAtIndexPath:indexPath animated:NO];
}

#pragma mark - WPStatsGraphViewControllerDelegate methods

- (void)statsGraphViewController:(WPStatsGraphViewController *)controller didSelectDate:(NSDate *)date
{
    [WPAnalytics track:WPAnalyticsStatStatsTappedBarChart withProperties:@{ @"blog_id" : self.statsService.siteId}];

    self.selectedDate = date;

    NSInteger section = (NSInteger)[self.sections indexOfObject:@(StatsSectionPeriodHeader)];
    if (section != NSNotFound) {
        NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:(NSUInteger)section];
        [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationFade];
    }

    // Reset the data (except the graph) and refresh
    id graphData = self.sectionData[@(StatsSectionGraph)];
    [self wipeDataAndSeedGroups];
    self.sectionData[@(StatsSectionGraph)] = graphData;

    [self.tableView reloadData];

    section = (NSInteger)[self.sections indexOfObject:@(StatsSectionGraph)];
    if (section != NSNotFound) {
        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:(self.selectedSummaryType + 1) inSection:section];
        [self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
    }

    [self retrieveStatsSkipGraph:YES];
}

#pragma mark - Stats retrieval methods

- (IBAction)refreshCurrentStats:(UIRefreshControl *)sender
{
    [self resetDateToTodayForSite];
    [self.statsService expireAllItemsInCacheForPeriodStats];
    [self retrieveStatsSkipGraph:NO];
}

- (void)changeGraphPeriod:(StatsPeriodUnit)toPeriod
{
    self.selectedPeriodUnit = toPeriod;
    [self resetDateToTodayForSite];
    NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:[self.sections indexOfObject:@(StatsSectionPeriodHeader)]];
    [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationFade];

    [self wipeDataAndSeedGroups];
    [self.tableView reloadData];

    [self retrieveStatsSkipGraph:NO];

    [self trackViewControllerAnalytics];
}

- (void)switchToSummaryType:(StatsSummaryType)summaryType
{
    self.selectedSummaryType = summaryType;
    [self changeGraphPeriod:StatsPeriodUnitDay];
}

- (void)retrieveStatsSkipGraph:(BOOL)skipGraph
{
    [AppExtensionUtils setNetworkActivityIndicatorVisible:YES fromController:self];

    if ([self.statsProgressViewDelegate respondsToSelector:@selector(statsViewControllerDidBeginLoadingStats:)]
        && self.refreshControl.isRefreshing == NO) {
        self.refreshControl = nil;
    }

    __weak __typeof(self) weakSelf = self;

    [self.statsService retrieveAllStatsForDate:self.selectedDate
                                          unit:self.selectedPeriodUnit
                    withVisitsCompletionHandler:^(StatsVisits *visits, NSError *error)
     {
         if (skipGraph) {
             return;
         }

         weakSelf.sectionData[@(StatsSectionGraph)] = visits;

         if (visits.errorWhileRetrieving == NO) {
             weakSelf.selectedDate = ((StatsSummary *)visits.statsData.lastObject).date;
         }

         [weakSelf.tableView reloadData];

         NSInteger sectionNumber = (NSInteger)[weakSelf.sections indexOfObject:@(StatsSectionGraph)];
         NSIndexPath *indexPath = [NSIndexPath indexPathForItem:(weakSelf.selectedSummaryType + 1) inSection:sectionNumber];
         [weakSelf.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
     }
                       eventsCompletionHandler:^(StatsGroup *group, NSError *error)
     {
         group.offsetRows = StatsTableRowDataOffsetWithoutGroupHeader;
         weakSelf.sectionData[@(StatsSectionEvents)] = group;

         [weakSelf.tableView beginUpdates];

         NSUInteger sectionNumber = [weakSelf.sections indexOfObject:@(StatsSectionEvents)];
         NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:sectionNumber];
         [weakSelf.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];

         [weakSelf.tableView endUpdates];
     }
                         postsCompletionHandler:^(StatsGroup *group, NSError *error)
     {
         group.offsetRows = StatsTableRowDataOffsetStandard;
         weakSelf.sectionData[@(StatsSectionPosts)] = group;

         [weakSelf.tableView beginUpdates];

         NSUInteger sectionNumber = [weakSelf.sections indexOfObject:@(StatsSectionPosts)];
         NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:sectionNumber];
         [weakSelf.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];

         [weakSelf.tableView endUpdates];
     }
                     referrersCompletionHandler:^(StatsGroup *group, NSError *error)
     {
         group.offsetRows = StatsTableRowDataOffsetStandard;
         weakSelf.sectionData[@(StatsSectionReferrers)] = group;

         [weakSelf.tableView beginUpdates];

         NSUInteger sectionNumber = [weakSelf.sections indexOfObject:@(StatsSectionReferrers)];
         NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:sectionNumber];
         [weakSelf.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];

         [weakSelf.tableView endUpdates];
     }
                        clicksCompletionHandler:^(StatsGroup *group, NSError *error)
     {
         group.offsetRows = StatsTableRowDataOffsetStandard;
         weakSelf.sectionData[@(StatsSectionClicks)] = group;

         [weakSelf.tableView beginUpdates];

         NSUInteger sectionNumber = [weakSelf.sections indexOfObject:@(StatsSectionClicks)];
         NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:sectionNumber];
         [weakSelf.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];

         [weakSelf.tableView endUpdates];
     }
                       countryCompletionHandler:^(StatsGroup *group, NSError *error)
     {
         group.offsetRows = StatsTableRowDataOffsetStandard;
         weakSelf.sectionData[@(StatsSectionCountry)] = group;

         [weakSelf.tableView beginUpdates];

         NSUInteger sectionNumber = [weakSelf.sections indexOfObject:@(StatsSectionCountry)];
         NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:sectionNumber];
         [weakSelf.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];

         [weakSelf.tableView endUpdates];
     }
                        videosCompletionHandler:^(StatsGroup *group, NSError *error)
     {
         group.offsetRows = StatsTableRowDataOffsetStandard;
         weakSelf.sectionData[@(StatsSectionVideos)] = group;

         [weakSelf.tableView beginUpdates];

         NSUInteger sectionNumber = [weakSelf.sections indexOfObject:@(StatsSectionVideos)];
         NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:sectionNumber];
         [weakSelf.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];

         [weakSelf.tableView endUpdates];
     }
                      authorsCompletionHandler:^(StatsGroup *group, NSError *error)
     {
         group.offsetRows = StatsTableRowDataOffsetStandard;
         weakSelf.sectionData[@(StatsSectionAuthors)] = group;

         [weakSelf.tableView beginUpdates];

         NSUInteger sectionNumber = [weakSelf.sections indexOfObject:@(StatsSectionAuthors)];
         NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:sectionNumber];
         [weakSelf.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];

         [weakSelf.tableView endUpdates];
     }
                  searchTermsCompletionHandler:^(StatsGroup *group, NSError *error)
     {
         group.offsetRows = StatsTableRowDataOffsetStandard;
         weakSelf.sectionData[@(StatsSectionSearchTerms)] = group;

         [weakSelf.tableView beginUpdates];

         NSUInteger sectionNumber = [weakSelf.sections indexOfObject:@(StatsSectionSearchTerms)];
         NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:sectionNumber];
         [weakSelf.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic];

         [weakSelf.tableView endUpdates];
     }
                                 progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations)
    {
        if (numberOfFinishedOperations == 0 && [weakSelf.statsProgressViewDelegate respondsToSelector:@selector(statsViewControllerDidBeginLoadingStats:)]) {
            [weakSelf.statsProgressViewDelegate statsViewControllerDidBeginLoadingStats:weakSelf];
        }

        if (numberOfFinishedOperations > 0 && [weakSelf.statsProgressViewDelegate respondsToSelector:@selector(statsViewController:loadingProgressPercentage:)]) {
            CGFloat percentage = (CGFloat)numberOfFinishedOperations / (CGFloat)totalNumberOfOperations;
            [weakSelf.statsProgressViewDelegate statsViewController:weakSelf loadingProgressPercentage:percentage];
        }
     }
                   andOverallCompletionHandler:^
     {
         [AppExtensionUtils setNetworkActivityIndicatorVisible:NO fromController:self];
         [weakSelf setupRefreshControl];
         [weakSelf.refreshControl endRefreshing];

         if ([weakSelf.statsProgressViewDelegate respondsToSelector:@selector(statsViewControllerDidEndLoadingStats:)]) {
             [weakSelf.statsProgressViewDelegate statsViewControllerDidEndLoadingStats:weakSelf];
         }
     }];
}

#pragma mark - Cell configuration private methods

- (NSString *)cellIdentifierForIndexPath:(NSIndexPath *)indexPath
{
    NSString *identifier = @"";

    StatsSection statsSection = [self statsSectionForTableViewSection:indexPath.section];

    switch (statsSection) {
        case StatsSectionGraph:
            switch (indexPath.row) {
                case 0:
                    identifier = StatsTableGraphCellIdentifier;
                    break;

                default:
                    identifier = StatsTableGraphSelectableCellIdentifier;
                    break;
            }
            break;
        case StatsSectionPeriodHeader:
            return StatsTablePeriodHeaderCellIdentifier;
        case StatsSectionEvents:
        {
            StatsGroup *group = (StatsGroup *)[self statsDataForStatsSection:statsSection];
            if (indexPath.row == 0) {
                identifier = StatsTableGroupHeaderCellIdentifier;
            } else if (indexPath.row == 1 && group.numberOfRows == 0) {
                identifier = StatsTableNoResultsCellIdentifier;
            } else if (group.moreItemsExist && indexPath.row == (NSInteger)(group.numberOfRows + StatsTableRowDataOffsetWithoutGroupHeader)) {
                identifier = StatsTableViewAllCellIdentifier;
            } else {
                identifier = StatsTableTwoColumnCellIdentifier;
            }
            break;
        }

        case StatsSectionPosts:
        case StatsSectionReferrers:
        case StatsSectionClicks:
        case StatsSectionCountry:
        case StatsSectionVideos:
        case StatsSectionAuthors:
        case StatsSectionSearchTerms:
        case StatsSectionTagsCategories:
        case StatsSectionPublicize:
        {
            StatsGroup *group = (StatsGroup *)[self statsDataForStatsSection:statsSection];
            if (indexPath.row == 0) {
                identifier = StatsTableGroupHeaderCellIdentifier;
            } else if (indexPath.row == 1 && group.numberOfRows > 0) {
                identifier = StatsTableTwoColumnHeaderCellIdentifier;
            } else if (indexPath.row == 1) {
                identifier = StatsTableNoResultsCellIdentifier;
            } else if (group.moreItemsExist && indexPath.row == (NSInteger)(group.numberOfRows + StatsTableRowDataOffsetStandard)) {
                identifier = StatsTableViewAllCellIdentifier;
            } else {
                identifier = StatsTableTwoColumnCellIdentifier;
            }
            break;
        }

        case StatsSectionFollowers:
        {
            StatsGroup *group = [self statsDataForStatsSection:statsSection];

            if (indexPath.row == 0) {
                identifier = StatsTableGroupHeaderCellIdentifier;
            } else if (indexPath.row == 1) {
                identifier = StatsTableGroupSelectorCellIdentifier;
            } else if (indexPath.row == 2) {
                if (group.numberOfRows > 0) {
                    identifier = StatsTableGroupTotalsCellIdentifier;
                } else {
                    identifier = StatsTableNoResultsCellIdentifier;
                }
            } else if (indexPath.row == 3) {
                identifier = StatsTableTwoColumnHeaderCellIdentifier;
            } else {
                if (group.moreItemsExist && indexPath.row == (NSInteger)(group.numberOfRows + StatsTableRowDataOffsetWithGroupSelectorAndTotal)) {
                    identifier = StatsTableViewAllCellIdentifier;
                } else {
                    identifier = StatsTableTwoColumnCellIdentifier;
                }
            }

            break;
        }

        case StatsSectionComments:
        {
            StatsGroup *group = [self statsDataForStatsSection:statsSection];

            if (indexPath.row == 0) {
                identifier = StatsTableGroupHeaderCellIdentifier;
            } else if (indexPath.row == 1) {
                identifier = StatsTableGroupSelectorCellIdentifier;
            } else if (indexPath.row == 2) {
                if (group.numberOfRows > 0) {
                    identifier = StatsTableTwoColumnHeaderCellIdentifier;
                } else {
                    identifier = StatsTableNoResultsCellIdentifier;
                }
            } else {
                if (group.moreItemsExist && indexPath.row == (NSInteger)(group.numberOfRows + StatsTableRowDataOffsetWithGroupSelector)) {
                    identifier = StatsTableViewAllCellIdentifier;
                } else {
                    identifier = StatsTableTwoColumnCellIdentifier;
                }
            }

            break;
        }
        case StatsSectionPostDetailsAveragePerDay:
        case StatsSectionPostDetailsGraph:
        case StatsSectionInsightsAllTime:
        case StatsSectionInsightsMostPopular:
        case StatsSectionInsightsPostActivity:
        case StatsSectionInsightsTodaysStats:
        case StatsSectionInsightsLatestPostSummary:
        case StatsSectionPostDetailsLoadingIndicator:
        case StatsSectionPostDetailsMonthsYears:
        case StatsSectionPostDetailsRecentWeeks:
        case StatsSectionWebVersion:
            break;
    }

    return identifier;
}

- (void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath
{
    StatsSection statsSection = [self statsSectionForTableViewSection:indexPath.section];
    NSString *cellIdentifier = [self cellIdentifierForIndexPath:indexPath];

    if (       [cellIdentifier isEqualToString:StatsTableGraphCellIdentifier]) {
        [self configureSectionGraphCell:(StatsStandardBorderedTableViewCell *)cell];

    } else if ([cellIdentifier isEqualToString:StatsTablePeriodHeaderCellIdentifier]) {
        [self configurePeriodHeaderCell:cell];

    } else if ([cellIdentifier isEqualToString:StatsTableGraphSelectableCellIdentifier]) {
        [self configureSectionGraphSelectableCell:(StatsSelectableTableViewCell *)cell forRow:indexPath.row];

    } else if ([cellIdentifier isEqualToString:StatsTableGroupHeaderCellIdentifier]) {
        [self configureSectionGroupHeaderCell:(StatsStandardBorderedTableViewCell *)cell
                             withStatsSection:statsSection];

    } else if ([cellIdentifier isEqualToString:StatsTableTwoColumnHeaderCellIdentifier]) {
        [self configureSectionTwoColumnHeaderCell:(StatsStandardBorderedTableViewCell *)cell
                                 withStatsSection:statsSection];

    } else if ([cellIdentifier isEqualToString:StatsTableNoResultsCellIdentifier]) {
        [self configureNoResultsCell:cell withStatsSection:statsSection];

    } else if ([cellIdentifier isEqualToString:StatsTableViewAllCellIdentifier]) {
        UILabel *label = (UILabel *)[cell.contentView viewWithTag:100];
        label.text = NSLocalizedString(@"View All", @"View All button in stats for larger list");
        label.textColor = [WPStyleGuide wordPressBlue];

    } else if ([cellIdentifier isEqualToString:StatsTableTwoColumnCellIdentifier]) {
        StatsGroup *group = [self statsDataForStatsSection:statsSection];
        StatsItem *item = [group statsItemForTableViewRow:indexPath.row];
        StatsItem *nextItem = [group statsItemForTableViewRow:indexPath.row + 1];

        [self configureTwoColumnRowCell:cell
                        forStatsSection:statsSection
                          withStatsItem:item
                       andNextStatsItem:nextItem];
    }
}

- (void)configureSectionGraphCell:(StatsStandardBorderedTableViewCell *)cell
{
    if (![[cell.contentView subviews] containsObject:self.graphViewController.view]) {
        UIView *graphView = self.graphViewController.view;
        [graphView removeFromSuperview];
        graphView.frame = CGRectMake(8.0f, 0.0f, CGRectGetWidth(cell.contentView.bounds) - 16.0f, StatsTableGraphHeight - 1.0);
        graphView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        [cell.contentView addSubview:graphView];
    }

    cell.bottomBorderEnabled = NO;

    StatsVisits *visits = [self statsDataForStatsSection:StatsSectionGraph];
    [self.graphViewController setVisits:visits forSummaryType:self.selectedSummaryType withSelectedDate:self.selectedDate];
}

- (void)configurePeriodHeaderCell:(UITableViewCell *)cell
{
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    NSString *labelText = @"";

    switch (self.selectedPeriodUnit) {
        case StatsPeriodUnitDay:
            [dateFormatter setLocalizedDateFormatFromTemplate:@"MMMM d"];
            labelText = [NSString stringWithFormat:NSLocalizedString(@"Stats for %@", @"Stats header for single date"), [dateFormatter stringFromDate:self.selectedDate]];
            break;
        case StatsPeriodUnitWeek:
        {
            [dateFormatter setLocalizedDateFormatFromTemplate:@"MMMM d"];
            StatsDateUtilities *dateUtils = [StatsDateUtilities new];
            NSDate *endDate = [dateUtils calculateEndDateForPeriodUnit:self.selectedPeriodUnit withDateWithinPeriod:self.selectedDate];
            labelText = [NSString stringWithFormat:NSLocalizedString(@"Stats for %@ - %@", @"Stats header label for date range"), [dateFormatter stringFromDate:self.selectedDate], [dateFormatter stringFromDate:endDate]];
            break;
        }
        case StatsPeriodUnitMonth:
            [dateFormatter setLocalizedDateFormatFromTemplate:@"MMMM"];
            labelText = [NSString stringWithFormat:NSLocalizedString(@"Stats for %@", @"Stats header for single date"), [dateFormatter stringFromDate:self.selectedDate]];
            break;
        case StatsPeriodUnitYear:
            [dateFormatter setLocalizedDateFormatFromTemplate:@"yyyy"];
            labelText = [NSString stringWithFormat:NSLocalizedString(@"Stats for %@", @"Stats header for single date"), [dateFormatter stringFromDate:self.selectedDate]];
            break;
    }

    UILabel *label = (UILabel *)[cell.contentView viewWithTag:100];
    label.text = labelText;

    cell.backgroundColor = self.tableView.backgroundColor;
}

- (void)configureSectionGraphSelectableCell:(StatsSelectableTableViewCell *)cell forRow:(NSInteger)row
{
    StatsVisits *visits = [self statsDataForStatsSection:StatsSectionGraph];
    StatsSummary *summary = visits.statsDataByDate[self.selectedDate];

    switch (row) {
        case 1: // Views
        {
            cell.cellType = StatsSelectableTableViewCellTypeViews;
            cell.valueLabel.text = summary.views ?: @"-";
            break;
        }

        case 2: // Visitors
        {
            cell.cellType = StatsSelectableTableViewCellTypeVisitors;
            cell.valueLabel.text = summary.visitors ?: @"-";
            break;
        }

        case 3: // Likes
        {
            cell.cellType = StatsSelectableTableViewCellTypeLikes;
            cell.valueLabel.text = summary.likes ?: @"-";
            break;
        }

        case 4: // Comments
        {
            cell.cellType = StatsSelectableTableViewCellTypeComments;
            cell.valueLabel.text = summary.comments ?: @"-";
            break;
        }

        default:
            break;
    }
}

- (void)configureSectionGroupHeaderCell:(StatsStandardBorderedTableViewCell *)cell withStatsSection:(StatsSection)statsSection
{
    StatsGroup *statsGroup = [self statsDataForStatsSection:statsSection];
    NSString *headerText = statsGroup.groupTitle;

    UILabel *label = (UILabel *)[cell.contentView viewWithTag:100];
    label.text = headerText;
    label.textColor = [WPStyleGuide darkGrey];

    cell.bottomBorderEnabled = NO;
}

- (void)configureSectionTwoColumnHeaderCell:(StatsStandardBorderedTableViewCell *)cell withStatsSection:(StatsSection)statsSection
{
    StatsGroup *statsGroup = [self statsDataForStatsSection:statsSection];
    StatsItem *statsItem = [statsGroup statsItemForTableViewRow:2];

    NSString *leftText = statsGroup.titlePrimary;
    NSString *rightText = statsGroup.titleSecondary;

    // Hide the bottom border if the first row is expanded
    cell.bottomBorderEnabled = !statsItem.isExpanded;

    UILabel *label1 = (UILabel *)[cell.contentView viewWithTag:100];
    label1.text = leftText;
    label1.textColor = [WPStyleGuide grey];

    UILabel *label2 = (UILabel *)[cell.contentView viewWithTag:200];
    label2.text = rightText;
    label2.textColor = [WPStyleGuide grey];
}

- (void)configureNoResultsCell:(UITableViewCell *)cell withStatsSection:(StatsSection)statsSection
{
    NSString *text;
    id data = [self statsDataForStatsSection:statsSection];

    if (!data) {
        text = NSLocalizedString(@"Waiting for data...", @"Message displayed in stats while waiting for remote operations to finish.");
    } else if ([data errorWhileRetrieving] == YES) {
        text = NSLocalizedString(@"An error occurred while retrieving data. Retry in a bit!", @"Error message in section when data failed.");
    } else {
        switch (statsSection) {
            case StatsSectionClicks:
                text = NSLocalizedString(@"No clicks recorded", @"");
                break;
            case StatsSectionCountry:
                text = NSLocalizedString(@"No countries recorded", @"");
                break;
            case StatsSectionEvents:
                text = NSLocalizedString(@"No items published during this timeframe", @"");
                break;
            case StatsSectionAuthors:
            case StatsSectionPosts:
                text = NSLocalizedString(@"No posts or pages viewed", @"");
                break;
            case StatsSectionReferrers:
                text = NSLocalizedString(@"No referrers recorded", @"");
                break;
            case StatsSectionSearchTerms:
                text = NSLocalizedString(@"No search terms recorded", @"");
                break;
            case StatsSectionVideos:
                text = NSLocalizedString(@"No videos played", @"");
                break;
            case StatsSectionComments:
            case StatsSectionFollowers:
            case StatsSectionGraph:
            case StatsSectionInsightsAllTime:
            case StatsSectionInsightsMostPopular:
            case StatsSectionInsightsPostActivity:
            case StatsSectionInsightsTodaysStats:
            case StatsSectionInsightsLatestPostSummary:
            case StatsSectionPeriodHeader:
            case StatsSectionPublicize:
            case StatsSectionTagsCategories:
            case StatsSectionWebVersion:
            case StatsSectionPostDetailsAveragePerDay:
            case StatsSectionPostDetailsGraph:
            case StatsSectionPostDetailsLoadingIndicator:
            case StatsSectionPostDetailsMonthsYears:
            case StatsSectionPostDetailsRecentWeeks:
                break;
        }
    }

    UILabel *label = (UILabel *)[cell.contentView viewWithTag:100];
    label.text = text;
}

- (void)configureTwoColumnRowCell:(UITableViewCell *)cell
                  forStatsSection:(StatsSection)statsSection
                    withStatsItem:(StatsItem *)statsItem
                 andNextStatsItem:(StatsItem *)nextStatsItem
{
    BOOL showCircularIcon = (statsSection == StatsSectionComments || statsSection == StatsSectionFollowers || statsSection == StatsSectionAuthors);

    StatsTwoColumnTableViewCellSelectType selectType = StatsTwoColumnTableViewCellSelectTypeDetail;
    if (statsItem.actions.count > 0 && (statsSection == StatsSectionReferrers || statsSection == StatsSectionClicks)) {
        selectType = StatsTwoColumnTableViewCellSelectTypeURL;
    } else if (statsSection == StatsSectionTagsCategories) {
        if ([statsItem.alternateIconValue isEqualToString:@"category"]) {
            selectType = StatsTwoColumnTableViewCellSelectTypeCategory;
        } else if ([statsItem.alternateIconValue isEqualToString:@"tag"]) {
            selectType = StatsTwoColumnTableViewCellSelectTypeTag;
        }
    }

    StatsTwoColumnTableViewCell *statsCell = (StatsTwoColumnTableViewCell *)cell;
    statsCell.leftText = statsItem.label;
    statsCell.rightText = statsItem.value;
    statsCell.imageURL = statsItem.iconURL;
    statsCell.showCircularIcon = showCircularIcon;
    statsCell.indentLevel = statsItem.depth;
    statsCell.indentable = NO;
    statsCell.expandable = statsItem.children.count > 0;
    statsCell.expanded = statsItem.expanded;
    statsCell.selectable = statsItem.actions.count > 0 || statsItem.children.count > 0;
    statsCell.selectType = selectType;
    statsCell.bottomBorderEnabled = !(nextStatsItem.isExpanded);

    [statsCell doneSettingProperties];
}

#pragma mark - Row and section calculation methods

- (StatsSection)statsSectionForTableViewSection:(NSInteger)section
{
    return (StatsSection)[self.sections[(NSUInteger)section] integerValue];
}

- (id)statsDataForStatsSection:(StatsSection)statsSection
{
    id data = self.sectionData[@(statsSection)];

    return data;
}

- (void)wipeDataAndSeedGroups
{
    if (self.sectionData) {
        [self.sectionData removeAllObjects];
    } else {
        self.sectionData = [NSMutableDictionary new];
    }

    self.sectionData[@(StatsSectionComments)] = [NSMutableDictionary new];
    self.sectionData[@(StatsSectionFollowers)] = [NSMutableDictionary new];

    for (NSNumber *statsSectionNumber in self.sections) {
        StatsSection statsSection = (StatsSection)statsSectionNumber.integerValue;
        if (statsSection != StatsSectionGraph) {
            StatsGroup *group = [[StatsGroup alloc] initWithStatsSection:statsSection andStatsSubSection:StatsSubSectionNone];
            self.sectionData[statsSectionNumber] = group;
        }
    }
}

- (void)setupRefreshControl
{
    if (self.refreshControl) {
        return;
    }

    UIRefreshControl *refreshControl = [UIRefreshControl new];
    [refreshControl addTarget:self action:@selector(refreshCurrentStats:) forControlEvents:UIControlEventValueChanged];
    self.refreshControl = refreshControl;
}

// Resets self.selected date to an NSDate with device local timezone but representing what today is
// for the site, not the device
- (void)resetDateToTodayForSite
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    calendar.timeZone = self.statsService.siteTimeZone;

    NSDateComponents *components = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:[NSDate date]];

    calendar.timeZone = [NSTimeZone localTimeZone];
    NSDate *date = [calendar dateFromComponents:components];
    self.selectedDate = date;
}

- (void)trackViewControllerAnalytics
{
    WPAnalyticsStat stat;

    switch (self.selectedPeriodUnit) {
        case StatsPeriodUnitDay:
            stat = WPAnalyticsStatStatsPeriodDaysAccessed;
            break;
        case StatsPeriodUnitWeek:
            stat = WPAnalyticsStatStatsPeriodWeeksAccessed;
            break;
        case StatsPeriodUnitMonth:
            stat = WPAnalyticsStatStatsPeriodMonthsAccessed;
            break;
        case StatsPeriodUnitYear:
            stat = WPAnalyticsStatStatsPeriodYearsAccessed;
            break;
    }

    [WPAnalytics track:stat withProperties:@{ @"blog_id" : self.statsService.siteId}];
}

@end


text:
#pragma once
#include <aws/backup/Backup_EXPORTS.h>
#include <aws/backup/BackupRequest.h>
#include <aws/core/utils/memory/stl/AWSString.h>
#include <aws/core/utils/memory/stl/AWSMap.h>
#include <utility>

namespace Aws
{
namespace Backup
{
namespace Model
{

  /**
   */
  class AWS_BACKUP_API CreateBackupVaultRequest : public BackupRequest
  {
  public:
    CreateBackupVaultRequest();

    // Service request name is the Operation name which will send this request out,
    // each operation should has unique request name, so that we can get operation's name from this request.
    // Note: this is not true for response, multiple operations may have the same response name,
    // so we can not get operation's name from response.
    inline virtual const char* GetServiceRequestName() const override { return "CreateBackupVault"; }

    Aws::String SerializePayload() const override;

    /**
     *
The name of a logical container where backups are stored. Backup vaults are
     * identified by names that are unique to the account used to create them and the
     * Amazon Web Services Region where they are created. They consist of letters,
     * numbers, and hyphens.

     */
    inline const Aws::String& GetBackupVaultName() const{ return m_backupVaultName; }

    /**
     *
The name of a logical container where backups are stored. Backup vaults are
     * identified by names that are unique to the account used to create them and the
     * Amazon Web Services Region where they are created. They consist of letters,
     * numbers, and hyphens.

     */
    inline bool BackupVaultNameHasBeenSet() const { return m_backupVaultNameHasBeenSet; }

    /**
     *
The name of a logical container where backups are stored. Backup vaults are
     * identified by names that are unique to the account used to create them and the
     * Amazon Web Services Region where they are created. They consist of letters,
     * numbers, and hyphens.

     */
    inline void SetBackupVaultName(const Aws::String& value) { m_backupVaultNameHasBeenSet = true; m_backupVaultName = value; }

    /**
     *
The name of a logical container where backups are stored. Backup vaults are
     * identified by names that are unique to the account used to create them and the
     * Amazon Web Services Region where they are created. They consist of letters,
     * numbers, and hyphens.

     */
    inline void SetBackupVaultName(Aws::String&& value) { m_backupVaultNameHasBeenSet = true; m_backupVaultName = std::move(value); }

    /**
     *
The name of a logical container where backups are stored. Backup vaults are
     * identified by names that are unique to the account used to create them and the
     * Amazon Web Services Region where they are created. They consist of letters,
     * numbers, and hyphens.

     */
    inline void SetBackupVaultName(const char* value) { m_backupVaultNameHasBeenSet = true; m_backupVaultName.assign(value); }

    /**
     *
The name of a logical container where backups are stored. Backup vaults are
     * identified by names that are unique to the account used to create them and the
     * Amazon Web Services Region where they are created. They consist of letters,
     * numbers, and hyphens.

     */
    inline CreateBackupVaultRequest& WithBackupVaultName(const Aws::String& value) { SetBackupVaultName(value); return *this;}

    /**
     *
The name of a logical container where backups are stored. Backup vaults are
     * identified by names that are unique to the account used to create them and the
     * Amazon Web Services Region where they are created. They consist of letters,
     * numbers, and hyphens.

     */
    inline CreateBackupVaultRequest& WithBackupVaultName(Aws::String&& value) { SetBackupVaultName(std::move(value)); return *this;}

    /**
     *
The name of a logical container where backups are stored. Backup vaults are
     * identified by names that are unique to the account used to create them and the
     * Amazon Web Services Region where they are created. They consist of letters,
     * numbers, and hyphens.

     */
    inline CreateBackupVaultRequest& WithBackupVaultName(const char* value) { SetBackupVaultName(value); return *this;}

    /**
     *
Metadata that you can assign to help organize the resources that you create.
     * Each tag is a key-value pair.

     */
    inline const Aws::Map<Aws::String, Aws::String>& GetBackupVaultTags() const{ return m_backupVaultTags; }

    /**
     *
Metadata that you can assign to help organize the resources that you create.
     * Each tag is a key-value pair.

     */
    inline bool BackupVaultTagsHasBeenSet() const { return m_backupVaultTagsHasBeenSet; }

    /**
     *
Metadata that you can assign to help organize the resources that you create.
     * Each tag is a key-value pair.

     */
    inline void SetBackupVaultTags(const Aws::Map<Aws::String, Aws::String>& value) { m_backupVaultTagsHasBeenSet = true; m_backupVaultTags = value; }

    /**
     *
Metadata that you can assign to help organize the resources that you create.
     * Each tag is a key-value pair.

     */
    inline void SetBackupVaultTags(Aws::Map<Aws::String, Aws::String>&& value) { m_backupVaultTagsHasBeenSet = true; m_backupVaultTags = std::move(value); }

    /**
     *
Metadata that you can assign to help organize the resources that you create.
     * Each tag is a key-value pair.

     */
    inline CreateBackupVaultRequest& WithBackupVaultTags(const Aws::Map<Aws::String, Aws::String>& value) { SetBackupVaultTags(value); return *this;}

    /**
     *
Metadata that you can assign to help organize the resources that you create.
     * Each tag is a key-value pair.

     */
    inline CreateBackupVaultRequest& WithBackupVaultTags(Aws::Map<Aws::String, Aws::String>&& value) { SetBackupVaultTags(std::move(value)); return *this;}

    /**
     *
Metadata that you can assign to help organize the resources that you create.
     * Each tag is a key-value pair.

     */
    inline CreateBackupVaultRequest& AddBackupVaultTags(const Aws::String& key, const Aws::String& value) { m_backupVaultTagsHasBeenSet = true; m_backupVaultTags.emplace(key, value); return *this; }

    /**
     *
Metadata that you can assign to help organize the resources that you create.
     * Each tag is a key-value pair.

     */
    inline CreateBackupVaultRequest& AddBackupVaultTags(Aws::String&& key, const Aws::String& value) { m_backupVaultTagsHasBeenSet = true; m_backupVaultTags.emplace(std::move(key), value); return *this; }

    /**
     *
Metadata that you can assign to help organize the resources that you create.
     * Each tag is a key-value pair.

     */
    inline CreateBackupVaultRequest& AddBackupVaultTags(const Aws::String& key, Aws::String&& value) { m_backupVaultTagsHasBeenSet = true; m_backupVaultTags.emplace(key, std::move(value)); return *this; }

    /**
     *
Metadata that you can assign to help organize the resources that you create.
     * Each tag is a key-value pair.

     */
    inline CreateBackupVaultRequest& AddBackupVaultTags(Aws::String&& key, Aws::String&& value) { m_backupVaultTagsHasBeenSet = true; m_backupVaultTags.emplace(std::move(key), std::move(value)); return *this; }

    /**
     *
Metadata that you can assign to help organize the resources that you create.
     * Each tag is a key-value pair.

     */
    inline CreateBackupVaultRequest& AddBackupVaultTags(const char* key, Aws::String&& value) { m_backupVaultTagsHasBeenSet = true; m_backupVaultTags.emplace(key, std::move(value)); return *this; }

    /**
     *
Metadata that you can assign to help organize the resources that you create.
     * Each tag is a key-value pair.

     */
    inline CreateBackupVaultRequest& AddBackupVaultTags(Aws::String&& key, const char* value) { m_backupVaultTagsHasBeenSet = true; m_backupVaultTags.emplace(std::move(key), value); return *this; }

    /**
     *
Metadata that you can assign to help organize the resources that you create.
     * Each tag is a key-value pair.

     */
    inline CreateBackupVaultRequest& AddBackupVaultTags(const char* key, const char* value) { m_backupVaultTagsHasBeenSet = true; m_backupVaultTags.emplace(key, value); return *this; }

    /**
     *
The server-side encryption key that is used to protect your backups; for
     * example,
     * arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab.

     */
    inline const Aws::String& GetEncryptionKeyArn() const{ return m_encryptionKeyArn; }

    /**
     *
The server-side encryption key that is used to protect your backups; for
     * example,
     * arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab.

     */
    inline bool EncryptionKeyArnHasBeenSet() const { return m_encryptionKeyArnHasBeenSet; }

    /**
     *
The server-side encryption key that is used to protect your backups; for
     * example,
     * arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab.

     */
    inline void SetEncryptionKeyArn(const Aws::String& value) { m_encryptionKeyArnHasBeenSet = true; m_encryptionKeyArn = value; }

    /**
     *
The server-side encryption key that is used to protect your backups; for
     * example,
     * arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab.

     */
    inline void SetEncryptionKeyArn(Aws::String&& value) { m_encryptionKeyArnHasBeenSet = true; m_encryptionKeyArn = std::move(value); }

    /**
     *
The server-side encryption key that is used to protect your backups; for
     * example,
     * arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab.

     */
    inline void SetEncryptionKeyArn(const char* value) { m_encryptionKeyArnHasBeenSet = true; m_encryptionKeyArn.assign(value); }

    /**
     *
The server-side encryption key that is used to protect your backups; for
     * example,
     * arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab.

     */
    inline CreateBackupVaultRequest& WithEncryptionKeyArn(const Aws::String& value) { SetEncryptionKeyArn(value); return *this;}

    /**
     *
The server-side encryption key that is used to protect your backups; for
     * example,
     * arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab.

     */
    inline CreateBackupVaultRequest& WithEncryptionKeyArn(Aws::String&& value) { SetEncryptionKeyArn(std::move(value)); return *this;}

    /**
     *
The server-side encryption key that is used to protect your backups; for
     * example,
     * arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab.

     */
    inline CreateBackupVaultRequest& WithEncryptionKeyArn(const char* value) { SetEncryptionKeyArn(value); return *this;}

    /**
     *
A unique string that identifies the request and allows failed requests to be
     * retried without the risk of running the operation twice.

     */
    inline const Aws::String& GetCreatorRequestId() const{ return m_creatorRequestId; }

    /**
     *
A unique string that identifies the request and allows failed requests to be
     * retried without the risk of running the operation twice.

     */
    inline bool CreatorRequestIdHasBeenSet() const { return m_creatorRequestIdHasBeenSet; }

    /**
     *
A unique string that identifies the request and allows failed requests to be
     * retried without the risk of running the operation twice.

     */
    inline void SetCreatorRequestId(const Aws::String& value) { m_creatorRequestIdHasBeenSet = true; m_creatorRequestId = value; }

    /**
     *
A unique string that identifies the request and allows failed requests to be
     * retried without the risk of running the operation twice.

     */
    inline void SetCreatorRequestId(Aws::String&& value) { m_creatorRequestIdHasBeenSet = true; m_creatorRequestId = std::move(value); }

    /**
     *
A unique string that identifies the request and allows failed requests to be
     * retried without the risk of running the operation twice.

     */
    inline void SetCreatorRequestId(const char* value) { m_creatorRequestIdHasBeenSet = true; m_creatorRequestId.assign(value); }

    /**
     *
A unique string that identifies the request and allows failed requests to be
     * retried without the risk of running the operation twice.

     */
    inline CreateBackupVaultRequest& WithCreatorRequestId(const Aws::String& value) { SetCreatorRequestId(value); return *this;}

    /**
     *
A unique string that identifies the request and allows failed requests to be
     * retried without the risk of running the operation twice.

     */
    inline CreateBackupVaultRequest& WithCreatorRequestId(Aws::String&& value) { SetCreatorRequestId(std::move(value)); return *this;}

    /**
     *
A unique string that identifies the request and allows failed requests to be
     * retried without the risk of running the operation twice.

     */
    inline CreateBackupVaultRequest& WithCreatorRequestId(const char* value) { SetCreatorRequestId(value); return *this;}

  private:

    Aws::String m_backupVaultName;
    bool m_backupVaultNameHasBeenSet;

    Aws::Map<Aws::String, Aws::String> m_backupVaultTags;
    bool m_backupVaultTagsHasBeenSet;

    Aws::String m_encryptionKeyArn;
    bool m_encryptionKeyArnHasBeenSet;

    Aws::String m_creatorRequestId;
    bool m_creatorRequestIdHasBeenSet;
  };

} // namespace Model
} // namespace Backup
} // namespace Aws

redpajama_set_name: RedPajamaGithub


text:
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
// See http://java.sun.com/xml/jaxb
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2015.10.08 at 09:29:27 PM CEST
//

package edu.anb.core;

import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlEnumValue;
import javax.xml.bind.annotation.XmlType;

/**
 *
Java class for PrintOrientationEnum.
 *
 *
The following schema fragment specifies the expected content contained within this class.
 *

 *

 * <simpleType name="PrintOrientationEnum">
 *   <restriction base="{http://www.w3.org/2001/XMLSchema}string">
 *     <enumeration value="OrientLandscape"/>
 *     <enumeration value="OrientPortrait"/>
 *   </restriction>
 * </simpleType>
 *

 *
 */
@XmlType(name = "PrintOrientationEnum")
@XmlEnum
public enum PrintOrientationEnum {

    /**
     * Landscape orientation for printed charts.
     *
     */
    @XmlEnumValue("OrientLandscape")
    ORIENT_LANDSCAPE("OrientLandscape"),

    /**
     * Portrait orientation for printed charts.
     *
     */
    @XmlEnumValue("OrientPortrait")
    ORIENT_PORTRAIT("OrientPortrait");
    private final java.lang.String value;

    PrintOrientationEnum(java.lang.String v) {
        value = v;
    }

    public java.lang.String value() {
        return value;
    }

    public static PrintOrientationEnum fromValue(java.lang.String v) {
        for (PrintOrientationEnum c: PrintOrientationEnum.values()) {
            if (c.value.equals(v)) {
                return c;
            }
        }
        throw new IllegalArgumentException(v);
    }

}


text:
package summary

import (
    info "github.com/google/cadvisor/info/v2"
)

// Manages a buffer of usage samples.
// This is similar to stats buffer in cache/memory.
// The main difference is that we do not pre-allocate the buffer as most containers
// won't live that long.
type SamplesBuffer struct {
    // list of collected samples.
    samples []info.Usage
    // maximum size this buffer can grow to.
    maxSize int
    // index for the latest sample.
    index   int
}

// Initializes an empty buffer.
func NewSamplesBuffer(size int) *SamplesBuffer {
    return &SamplesBuffer{
        index:   -1,
        maxSize: size,
    }
}

// Returns the current number of samples in the buffer.
func (s *SamplesBuffer) Size() int {
    return len(s.samples)
}

// Add an element to the buffer. Oldest one is overwritten if required.
func (s *SamplesBuffer) Add(stat info.Usage) {
    if len(s.samples) < s.maxSize {
        s.samples = append(s.samples, stat)
        s.index++
        return
    }
    s.index = (s.index + 1) % s.maxSize
    s.samples[s.index] = stat
}

// Returns pointers to the last 'n' stats.
func (s *SamplesBuffer) RecentStats(n int) []*info.Usage {
    if n > len(s.samples) {
        n = len(s.samples)
    }
    start := s.index - (n - 1)
    if start < 0 {
        start += len(s.samples)
    }

    out := make([]*info.Usage, n)
    for i := 0; i < n; i++ {
        index := (start + i) % len(s.samples)
        out[i] = &s.samples[index]
    }
    return out
}


text:
@interface CCBlendModeCache : CCCache
{
}

- (id)createPublicObjectForSharedData:(id)arg1;
- (id)createSharedDataForKey:(id)arg1;
- (void)disposeOfSharedData:(id)arg1;
- (void)flush;
- (id)objectForKey:(id)arg1;

@end


text:
<?php

namespace vod\Request\V20170321;

class DeleteStreamRequest extends \RpcAcsRequest
{
	function  __construct()
	{
		parent::__construct("vod", "2017-03-21", "DeleteStream", "vod", "openAPI");
		$this->setMethod("POST");
	}

	private  $resourceOwnerId;

	private  $resourceOwnerAccount;

	private  $jobIds;

	private  $videoId;

	private  $ownerId;

	public function getResourceOwnerId() {
		return $this->resourceOwnerId;
	}

	public function setResourceOwnerId($resourceOwnerId) {
		$this->resourceOwnerId = $resourceOwnerId;
		$this->queryParameters["ResourceOwnerId"]=$resourceOwnerId;
	}

	public function getResourceOwnerAccount() {
		return $this->resourceOwnerAccount;
	}

	public function setResourceOwnerAccount($resourceOwnerAccount) {
		$this->resourceOwnerAccount = $resourceOwnerAccount;
		$this->queryParameters["ResourceOwnerAccount"]=$resourceOwnerAccount;
	}

	public function getJobIds() {
		return $this->jobIds;
	}

	public function setJobIds($jobIds) {
		$this->jobIds = $jobIds;
		$this->queryParameters["JobIds"]=$jobIds;
	}

	public function getVideoId() {
		return $this->videoId;
	}

	public function setVideoId($videoId) {
		$this->videoId = $videoId;
		$this->queryParameters["VideoId"]=$videoId;
	}

	public function getOwnerId() {
		return $this->ownerId;
	}

	public function setOwnerId($ownerId) {
		$this->ownerId = $ownerId;
		$this->queryParameters["OwnerId"]=$ownerId;
	}

}


text:
package com.hosseini.persian.dt.PersianDate;

/**
 * AgoTime Class
 *

 * This class provide and generate persian date in Ago format
 * like {@code //1 year ago}
 *

 *
 * @author abbashosseini <mrabbashosseini@gmail.com>
 * @version 0.1
 * @see Config
 * @since 3/1/2016
 */

import com.hosseini.persian.dt.PersianDate.enumCollections.AgoFomat;

public final class AgoTime extends Config {

    private final static ThreadLocal<CallbackHolder> holder = new ThreadLocal<>();

    public AgoTime(String date, String sentence){
        super(date, sentence);
    }

    /**
     * its pass date in Ago Format and String, its more readable and userfrndly
     * and  Does not support the century's
     *
     * @return A Formated date in Ago Format
     **/
    public String format() {

        long current = System.currentTimeMillis(),
                        timestamp = getDateContaindateObject().getTime(),
                        diff = (current - timestamp) / 1000;
        int amount;
        String what;

        for (AgoFomat format : AgoFomat.values())
        /** check and make sure divide (/) don't be zero and don't allow
         * java.lang.ArithmeticException execption going to happen*/
            if (diff > AgoFomat.minute.getFormatNumber())
                // Check and know how to format thw date in ago
                if (diff > format.getFormatNumber()) {
                    // get digit for Ago format
                    amount = (int) (diff / format.getFormatNumber());
                    //get name (year/month/day) for Ago format
                    what = format.getFormatname();

                    if (amount == 1) {

                        if (what.equals(AgoFomat.day.getFormatname())) {
                            return "دیروز";
                        }

                    }

                    return String.format("%s %s %s", amount, what, FormatNames.Extenion());
                }

        amount = (int) (diff);
        return String.format("%d %s", amount, AgoFomat.now.getFormatname());
    }

    /**
     * its pass date in Ago Format and String, its more readable and userfrndly
     * and  Does not support the century's
     *
     * @see AgoTime#format()
     * @deprecated this method has awful design .
     * @return String in Ago format
     */
    @Deprecated
    public String dateTime() {

        long current = System.currentTimeMillis(),
                timestamp = getDateContaindateObject().getTime(),
                diff = (current - timestamp) / 1000;

        int amount = 0;
        String what = null;

        if (diff > 31536000) {
            amount = (int) (diff / 31536000);
            what = FormatNames.YearAgo();
        } else if (diff > 2592000) {
            amount = (int) (diff / 2592000);
            what = FormatNames.MonthAgo();

        } else if (diff > 604800) {
            amount = (int) (diff / 604800);
            what = FormatNames.WeekAgo();

        } else if (diff > 86400) {
            amount = (int) (diff / 86400);
            what = FormatNames.DayAgo();
        } else if (diff > 3600) {
            amount = (int) (diff / 3600);
            what = FormatNames.HourAgo();
        } else if (diff > 60) {
            amount = (int) (diff / 60);
            what = FormatNames.MinAgo();
        } else {
            amount = (int) (diff);
            return String.format("%d %s %s", amount, FormatNames.SecAgo(), FormatNames.Extenion());
        }

        if (amount == 1) {
            if (what.equals(FormatNames.DayAgo())) {
                return FormatNames.YESTERDAY();
            } else if (what.equals(FormatNames.WeekAgo()) || what.equals(FormatNames.MonthAgo()) || what.equals(FormatNames.YearAgo())) {
                return String.format("%s %s", what, FormatNames.Extenion());
            }
        }

        return String.format("%s %s %s ", amount, what, FormatNames.Extenion());
    }

    /**
     * CallBack Pattern
     *

     * we use callback to get value from any where possible in PersianDT
     * and this is Asynchronous way to get date and pass it to dev/user
     * can get resonse and deal with it
     * and of course we add Builder Pattern how ? easy we return  current
     * object so we can access it after we implement or what ever correct
     * way you are gonna use.
     *

     *
     * @param callBack we have too declare callback it
     *                 how ? easy you can implement the
     *                 class or use lambda or method refrence
     *                 of course in java 8 or use Anonymous implement
     *                 for more you can see examples in Example folder
     * @return a AgoTime object
     * @see AgoTime Example
     * @see Current date Example
     * @see Current date Example
     * @see generate date Example
     * @see Genrate Date Example
     */

    public AgoTime CallBack(CallBack callBack) {
        holder.set(new CallbackHolder(callBack));
        return this;
    }

    /**
     * get date in Ago format
     **/

    public void parse() {
        String date = super.Location(format());
        holder.get().getCallBack().onReceive(date);
    }

}


text:
Responsive CSS Gallery without javascripts.
>v.1.0 Initial

###Features:
* Responsive
* Html5
* CSS3
* No javascripts
* The number of images is not dependent on the CSS

### 1.Getting Started
```html
<!-- html head -->
<meta name="viewport" content="width=device-width, initial-scale=1, minimal-ui, user-scalable=no">
<link href="./stylesheets/ma5-cssgallery.css" media="screen, projection" rel="stylesheet" type="text/css">
<!--[if lte IE 9]>
<link href="./stylesheets/ma5-cssgallery-ie9.css" media="screen, projection" rel="stylesheet" type="text/css">
<![endif]-->

<!-- html body -->
<div class="ma5-css-gallery">
    <input type="radio" name="gallery-1" id="gallery-1" checked="checked">
    <div class="ma5-gallery-content">
        <!-- thumbnails -->
        <figure>
            <label for="gallery-1-slide-1">Slide 1</label>
            <img src="./path/to/thumbnail.jpg" alt="">
        </figure>
        <figure>
            <label for="gallery-1-slide-2">Slide 2</label>
            <img src="./path/to/thumbnail.jpg" alt="">
        </figure>
        <figure>
            <label for="gallery-1-slide-3">slide3</label>
            <img src="./path/to/thumbnail.jpg" alt="">
        </figure>
        <!-- slider -->
        <div class="ma5-container">
            <div class="ma5-cssslider">
                <label class="ma5-close" for="gallery-1">close</label>
                <div class="ma5-slides">
                    <!-- slide 1 -->
                    <div class="ma5-slide">
                        <input type="radio" name="gallery-1" id="gallery-1-slide-1">
                        <figure class="ma5-has-figcaption">
                            <img src="./path/to/full.jpg" alt="">
                            <figcaption>Title of slide 1</figcaption>
                        </figure>
                        <label for="gallery-1-slide-1"><img src="./path/to/navigator-icon.jpg" alt=""></label>
                    </div>
                    <!-- slide 2 -->
                    <div class="ma5-slide">
                        <input type="radio" name="gallery-1" id="gallery-1-slide-2">
                        <figure class="ma5-has-figcaption">
                            <img src="./path/to/full.jpg" alt="">
                            <figcaption>Title of slide 2</figcaption>
                        </figure>
                        <label for="gallery-1-slide-2"><img src="./path/to/navigator-icon.jpg" alt=""></label>
                    </div>
                    <!-- slide 3 -->
                    <div class="ma5-slide">
                        <input type="radio" name="gallery-1" id="gallery-1-slide-3">
                        <figure class="ma5-has-figcaption">
                            <img src="./path/to/full.jpg" alt="">
                            <figcaption>Title of slide 3</figcaption>
                        </figure>
                        <label for="gallery-1-slide-3"><img src="./path/to/navigator-icon.jpg" alt=""></label>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
```
When the picture hasn't figcaption:

```html
<!-- slide without figcaption -->
<div class="ma5-slide">
    <input type="radio" name="gallery-1" id="gallery-1-slide-1">
    <figure>
        <img src="./path/to/full.jpg" alt="">
    </figure>
    <label for="gallery-1-slide-1"><img src="./path/to/navigator-icon.jpg" alt=""></label>
</div>
```

License
------------
The MIT License (MIT)


text:
/**
 *
 * @module HUD
 * @submodule HUDComponents
 *
*/

module Kiwi.HUD.HUDComponents {

	/**
	* A Component to manage and display a Time in a particular format.
	* The Time Component creates a new clock on the Time Manager and it uses that clock to keep track of the time.
	* When you create a new Time Component you can specify a format that you want the time to display in, which is a string based on keywords.
	* Current supported keywords for the format are:
	*  's' = 'seconds'
	*  'm' = 'minutes'
	*  'ms' = milliseconds'
	*  'ss' = 'seconds with leading zero'
	*  'mm' = 'minutes with leading zero'
	*
	* @class Time
	* @extends Kiwi.Component
	* @namespace Kiwi.HUD.HUDComponents
	* @constructor
	* @param owner {any} The object that this component belongs to.
	* @param [format=''] {string} The format that the time is to be displayed in. Leave blank for the default time.
	* @return {Kiwi.HUD.HUDComponents.Counter}
	*/
	export class Time extends Kiwi.Component {

		constructor(owner:any, format:string='') {
			super(owner, "time");

			this.clock = this.game.time.addClock(name + '-clock', 1000);
			this.format = format;

		}

		/**
		* The type of object that this is.
		* @method objType
		* @return {String} 'TimeComponent'
		* @public
		*/
		public objType(): string {
			return 'TimeComponent';
		}

		/**
		* The clock that this component creates and uses to manage the current time.
		* @property clock
		* @type Kiwi.Time.Clock
		* @private
		*/
		public clock: Kiwi.Time.Clock;

		/**
		* Indicates whether or not the clock is currently running or not, and thus whether or not the time is playing or not.
		* @property isRunning
		* @type boolean
		* @public
		*/
		public get isRunning():boolean {
			return this.clock.isRunning();
		}

		/**
		* Pauses the clock where is stands. Calls the pause method on the clock.
		* @method pause
		* @public
		*/
		public pause() {
			this.clock.pause();
		}

		/**
		* Stops the clock and thus the time. Calls the stop method of the clock.
		* @method stop
		* @public
		*/
		public stop() {
			this.clock.stop();
		}

		/**
		* Starts the clock and thus the time.
		* @method start
		* @public
		*/
		public start() {
			this.clock.start();
			this._timeBefore = this.clock.elapsed();
		}

		/**
		* Resumes the clock and thus the time.
		* @method resume
		* @public
		*/
		public resume() {
			this.clock.resume();
		}

		/**
		* The format that they want the time to be displayed.
		* @property _format
		* @type string
		* @private
		*/
		private _format: string;

		/**
		* The format that you want the time to be displayed in.
		* @property format
		* @type string
		* @public
		*/
		public set format(val: string) {
			this._format = val;
		}
		public get format(): string {
			return this._format;
		}

		/**
		* If the clock should 'count down' instead of up.
		* @property countDown
		* @type boolean
		* @default false
		* @public
		*/
		public countDown: boolean = false;

		/**
		* Used during the formatting stage of displaying the time.
		* @property _displayString
		* @type string
		* @private
		*/
		private _displayString: string = '';

		/**
		* The current time in seconds.
		* @property _currentTime
		* @type number
		* @private
		*/
		private _currentTime: number = 0;

		/**
		* The current time in seconds. This is READ ONLY.
		* @property currentTime
		* @type number
		* @public
		*/
		public get currentTime(): number {
			return this._currentTime;
		}

		/**
		* The last time that the timer update. Used to calculate the time delta.
		* @property _timeBefore
		* @type number
		* @private
		*/
		private _timeBefore: number = 0;

		/**
		* Sets the current time of the timer.
		* @method setTime
		* @param milli {number} The number of milliseconds.
		* @param [sec=0] {number} The number of seconds to add.
		* @param [minutes=0] {number} The number of minutes to add.
		* @public
		*/
		public setTime(milli: number, sec: number= 0, minutes: number= 0) {
			this._currentTime = milli;
			if(sec != 0) this._currentTime += (sec * 1000);
			if(minutes != 0) this._currentTime += (minutes * 60 * 1000);
		}

		/**
		* Increases the current time by the amount passed.
		* @method addTime
		* @param milli {number} The number of milliseconds.
		* @param [sec=0] {number} The number of seconds to add.
		* @param [minutes=0] {number} The number of minutes to add.
		* @public
		*/
		public addTime(milli:number, sec:number= 0,minutes:number= 0) {
			this._currentTime += milli;
			if(sec != 0) this._currentTime += (sec * 1000);
			if (minutes != 0) this._currentTime += (minutes * 60 * 1000);
		}

		/**
		* Decreases the current time by the amount passed.
		* @method removeTime
		* @param milli {number} The number of milliseconds.
		* @param [sec=0] {number} The number of seconds to add.
		* @param [minutes=0] {number} The number of minutes to add.
		* @public
		*/
		public removeTime(milli: number, sec: number= 0, minutes: number= 0) {
			this._currentTime -= milli;
			if (sec != 0) this._currentTime -= (sec * 1000);
			if (minutes != 0) this._currentTime -= (minutes * 60 * 1000);
		}

		/**
		* The speed at which the time will increase/decrease by.
		* Modify this property to make the time count down slower/faster.
		* @property _speed
		* @type number
		* @default 1
		* @private
		*/
		public speed: number = 1;

		/**
		* Returns a string with the current time that this component is upto in the format that was passed.
		*
		* @method updateTime
		* @return string
		* @public
		*/
		public getTime():string {
			if (this.countDown) {
				this._currentTime -= (this.clock.elapsed() - this._timeBefore) * this.speed;
			} else {
				this._currentTime += (this.clock.elapsed() - this._timeBefore) * this.speed;
			}
			this._timeBefore = this.clock.elapsed();

			//format time
			if (this._format !== '') {
				this._displayString = this._format;

				//milliseconds
				if (this._displayString.indexOf('ms') !== -1) {
					var t = String(Math.floor(this._currentTime * 1000) % 1000);
					this._displayString = this._displayString.replace('ms', t);
				}
				//seconds - leading
				if (this._displayString.indexOf('ss') != -1) {
					var t = String(Math.floor(this._currentTime) % 60);
					if (t.length < 2) t = '0' + t;
					this._displayString = this._displayString.replace('ss', t);
				}
				//minutes - leading
				if (this._displayString.indexOf('mm') !== -1) {
					var t = String(Math.floor(this._currentTime / 60) % 60);
					if (t.length < 2) t = '0' + t;
					this._displayString = this._displayString.replace('mm', t);
				}
				//minutes - no leading
				if (this._displayString.indexOf('s') != -1) {
					var t = String(Math.floor(this._currentTime) % 60);
					this._displayString = this._displayString.replace('s', t);
				}
				//seconds - no leading
				if (this._displayString.indexOf('m') !== -1) {
					var t = String(Math.floor(this._currentTime / 60) % 60);
					this._displayString = this._displayString.replace('m', t);
				}

				return this._displayString;
			} else {
				return String(this._currentTime.toFixed(2));
			}
		}

	}

}


text:
namespace KFS
{
	class MetaRequest;

	class ChildProcessTrackingTimer : public ITimeout {
	public:
		ChildProcessTrackingTimer(int timeoutMilliSec = 500) {
			SetTimeoutInterval(timeoutMilliSec);
		};
		// On a timeout check the child processes for exit status
		virtual void Timeout();
		// track the process with pid and return the exit status to MetaRequest
		void Track(pid_t pid, MetaRequest *r);
	private:
		typedef std::multimap<pid_t, MetaRequest *> Pending;
		Pending mPending;
	};

	extern ChildProcessTrackingTimer gChildProcessTracker;
}

#endif // META_CHILDPROCESSTRACKER_H


text:
html, body {padding:0; border:0px; margin:0; font-family:arial}
header {width:100%; height:90px; overflow:hidden; position:relative; border-bottom:1px solid #ccc; text-align:center;}
header strong {font-weight:200; font-size:2em; display:block; padding:10px; text-align:center; padding:0; margin:10px;}
header img {position:absolute; left:15px;  top:0; height:100%;}
nav {width:170px; padding:20px 0 0 10px; position:absolute; background:#eee; top:91px; bottom:0; overflow:auto;}
main {position:absolute; top:91px; bottom:0; left:180px; right:0; overflow:auto; padding:20px;}

h1 {font-size:2.2em; font-weight:200; padding:0; margin:0;}
h2 {font-size:1.2em; font-weight:200; border-bottom:1px solid #ccc; padding:0 0 20px 0;}

strong {font-size:2em;}
dl {padding:0 .2em;}
dl dt {font-weight:700;}
dl dd {padding:0; margin:0 0 2em 0;}

#map {position:absolute; top:80px; bottom:0px; left:0px; right:0px;}

.clearfix:after {content:"."; display:block; height:0; clear:both; visibility:hidden;}


text:
//=============================================================================
// ShortestDistanceCalculator.js
// ----------------------------------------------------------------------------
// Copyright (c) 2017-2020 Tsumio
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.0.1 2020/11/09 誤字の訂正。
// 1.0.0 2020/11/08 公開。
// ----------------------------------------------------------------------------
// [GitHub] : https://github.com/Tsumio/rmmv-plugins
// [Twitter]: https://twitter.com/TsumioNtGame
//=============================================================================

/*:
 * @plugindesc Calculate the shortest distance
 * @author Tsumio
 *
 * @param ----Basic Settings----
 * @desc
 * @default
 *
 *
 * @help Calculate the shortest distance
 *
 * ----feature----
 * -> Calculate the shortest distance between events and players
 *
 * ----how to use----
 * After installing the plugin, use plugin command.
 *
 * ----script command----
 * -> CharacterA.calcShortestDistance (CharacterB, number of reoccurrence)
 * Returns the shortest distance for characterA to reach characterB
 *
 * Specify the target event or player for characters A and B.
  * The number of reoccurrence is 130 by default.
  * This number is the number of times the route is searched.
  * If you know the distance is more than 130, please specify more than 130 times.
 *
 * ----example----
 * //Assign the shortest distance from event11 to event12 to dis
 * const dis = $gameMap.event(11).calcShortestDistance($gameMap.event(12));
 * console.log(dis);
 *
 * //Assign the shortest distance from player to event12 to dis2
 * const dis2 = $gamePlayer.calcShortestDistance($gameMap.event(12));
 * console.log(dis2);
 *
 * ----note----
 * The process of calculating the shortest distance (calcShortestDistance) is very heavy.
 * Running in parallel processing events may cause the game to be heavy.
 *
 * ----change log---
 * 1.0.1 2020/11/09 Fix typos.
 * 1.0.0 2020/01/08 Release.
 *
 * ----remarks----
 * I shall not be responsible for any loss, damages and troubles from using this plugin.
 *
 * --Terms of Use--
 * This plugin is free for both commercial and non-commercial use.
 * You may edit the source code to suit your needs,
 * so long as you don't claim the source code belongs to you.
 *
 */
/*:ja
 * @plugindesc 最短距離を計算するプラグイン
 * @author ツミオ
 *
 * @param ----基本的な設定----
 * @desc
 * @default
 *
 *
 * @help 最短距離を計算するプラグイン
 *
 * 【特徴】
 * ・イベント同士やプレイヤーとの最短距離を計算できます
 *
 * 【使用方法】
 * プラグインの導入後、スクリプトコマンドを使用します。
 *
 * 【スクリプトコマンド】
 * ■キャラクターA.calcShortestDistance(キャラクターB, 再帰回数)
 * キャラクターAがキャラクターBへ到達するための最短距離を返します
 *
 * キャラクターA,Bには対象のイベントやプレイヤーなどを指定します。
 * 再帰回数はデフォルトで130回が指定されています。
 * この回数は経路を探索する回数のことです。
 * 距離が130以上あることがわかっている場合、130回以上を指定してください。
 *
 * 例:
 * //イベント11からイベント12への最短距離をdisへ代入
 * const dis = $gameMap.event(11).calcShortestDistance($gameMap.event(12));
 * console.log(dis);
 *
 * //プレイヤーからイベント12への最短距離をdis2に代入
 * const dis2 = $gamePlayer.calcShortestDistance($gameMap.event(12));
 * console.log(dis2);
 *
 * ■再帰回数を超えた場合
 * JavaScript において正確に扱える最大整数値が返ってきます。
 *
 * 【注意】
 * 最短距離を計算する処理(calcShortestDistance)は非常にコストが高くなっています。
 * 並列処理イベントで実行するとゲームが重くなる原因となるかもしれません。
 *
 * 【更新履歴】
 * 1.0.1 2020/11/09 誤字の訂正。
 * 1.0.0 2020/01/08 公開。
 *
 * 【備考】
 * 当プラグインを利用したことによるいかなる損害に対しても、制作者は一切の責任を負わないこととします。
 *
 * 【利用規約】
 * ソースコードの著作権者が自分であると主張しない限り、
 * 作者に無断で改変、再配布が可能です。
 * 利用形態(商用、18禁利用等)についても制限はありません。
 * 自由に使用してください。
 *
 */

(function() {
    'use strict';
    var pluginName = 'ShortestDistanceCalculator';

////=============================================================================
//// Local function
////  These functions checks & formats pluguin's command parameters.
////  I borrowed these functions from Triacontane.Thanks!
////=============================================================================
    var getParamString = function(paramNames) {
        if (!Array.isArray(paramNames)) paramNames = [paramNames];
        for (var i = 0; i < paramNames.length; i++) {
            var name = PluginManager.parameters(pluginName)[paramNames[i]];
            if (name) return name;
        }
        return '';
    };

    var getParamNumber = function(paramNames, min, max) {
        var value = getParamString(paramNames);
        if (arguments.length < 2) min = -Infinity;
        if (arguments.length < 3) max = Infinity;
        return (parseInt(value) || 0).clamp(min, max);
    };

////=============================================================================
//// Get and set pluguin parameters.
////=============================================================================
    var param                          = {};

//////=============================================================================
///// Game_Character
/////  距離の計算をおこなうメソッドを追加する
//////=============================================================================

    /**
     * targetへの最短距離を返す。
     * Note:非常にコストの高い処理なので、ループ等では呼ばないこと。
     * Note:100%最短経路を返すとは限らない。
     * Note:再帰回数のデフォルト値の130は適当な値で意味は特にない。
     */
    Game_Character.prototype.calcShortestDistance = function(target, recursiveTimes = 130) {
        //現在のインスタンスを元に、画面上には存在しないダミーキャラクターを作成する
        const dummyCharacter = JsonEx.parse(JsonEx.stringify(this));

        //最短距離を計算する
        const calcShortestDistanceRecursive = function(count, x, y) {
            //再帰の回数を制限する
            const canRecursive = count < recursiveTimes;
            if(!canRecursive) {
                return Number.MAX_SAFE_INTEGER;
            }
            //実際の計算をおこなう
            dummyCharacter.moveTowardCharacter2(target.x, target.y);
            const isMoved = dummyCharacter.x !== x || dummyCharacter.y !== y;
            const isArrived = dummyCharacter.existAround4(target);
            return isMoved && !isArrived ? calcShortestDistanceRecursive(count + 1) : count+1;
        };

        //最短距離を返す
        return calcShortestDistanceRecursive(0, dummyCharacter.x, dummyCharacter.y);
    };

    /**
     * moveTowardCharacterみたいなやつ。
     * Note:TouchInputによっておこる移動の処理を流用。
     * Note:次に移動すべき場所を計算するとき、moveTowardCharacterでは動きが止まる可能性が高過ぎる。
     */
    Game_Character.prototype.moveTowardCharacter2 = function(x, y) {
        const direction = this.findDirectionTo(x, y);
        if (direction > 0) {
            this.moveStraight(direction);
        }
    };

    /**
     * 周囲4方向に対象がいるかどうかを返す
     */
    Game_Character.prototype.existAround4 = function(target) {
        const diffX = Math.abs(this.x - target.x);
        const diffY = Math.abs(this.y - target.y);
        return (diffX + diffY) <= 1;
    };

    /**
     * 周り(4方向ではなく8方向をチェック)に対象キャラクターがいたらtrueを返す。
     * 8方向プラグインに対応させるならこちら。
     */
    Game_Character.prototype.existAround8 = function(target) {
        const fromX = Math.abs(this.deltaXFrom(target.x));
        const fromY = Math.abs(this.deltaYFrom(target.y));
        return fromX <= 1 && fromY <= 1;
    };

})();


text:
namespace ConfigurationFromXml
{
    using System;
    using Trigger.NET;
    using Trigger.NET.Configuration;

    class Program
    {
        static void Main(string[] args)
        {
            var scheduler = new Scheduler();

            scheduler.ConfigureFromXml(".\\scheduler.config");

            Console.WriteLine("Press any key to exit...");

            Console.ReadKey();
        }
    }

    public class WriteDot : IJob
    {
        public void Execute(JobContext context)
        {
            Console.WriteLine(".");
        }
    }
}


text:
/*
 * This software is distributed under BSD 3-clause license (see LICENSE file).
 *
 * Authors: Soeren Sonnenburg, Yuyu Zhang, Evan Shelhamer, Bjoern Esser,
 *          Sergey Lisitsyn, Roman Votyakov
 */

#ifndef MEANSQUAREDERROR_H_
#define MEANSQUAREDERROR_H_

#include <shogun/lib/config.h>

#include <shogun/evaluation/Evaluation.h>
#include <shogun/labels/Labels.h>

namespace shogun
{

class CLabels;

/** @brief Class MeanSquaredError
 * used to compute an error of regression model.
 *
 * Formally, for real labels \f$ L,R, |L|=|R|\f$ mean squared
 * error (MSE) is estimated as
 *
 * \f[
 *		\frac{1}{|L|} \sum_{i=1}^{|L|} (L_i - R_i)^2
 * \f]
 *
 */
class CMeanSquaredError: public CEvaluation
{
public:
	/** constructor */
	CMeanSquaredError() : CEvaluation() {};

	/** destructor */
	virtual ~CMeanSquaredError() {};

	/** evaluate mean squared error
	 * @param predicted labels for evaluating
	 * @param ground_truth labels assumed to be correct
	 * @return mean squared error
	 */
	virtual float64_t evaluate(CLabels* predicted, CLabels* ground_truth);

	inline EEvaluationDirection get_evaluation_direction() const
	{
		return ED_MINIMIZE;
	}

	/** get name */
	virtual const char* get_name() const { return "MeanSquaredError"; }
};

}

#endif /* MEANSQUAREDERROR_H_ */


text:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:background="@android:color/white"
              android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:text="@string/map"
        android:textSize="14sp"/>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="16dp"
        android:layout_weight="1">

        <TextView
            android:id="@+id/tv_logs"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="Click Button To Get IP From Urls:\n"
            android:textSize="12sp"/>
    </ScrollView>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/btn_operator"
            android:layout_width="0dp"
            android:layout_height="50dp"
            android:layout_weight="1"
            android:background="@android:color/darker_gray"
            android:gravity="center"
            android:text="Operator FlatMap Normal"
            android:textAllCaps="false"/>

        <TextView
            android:id="@+id/btn_operator_map_ips"
            android:layout_width="0dp"
            android:layout_height="50dp"
            android:layout_marginLeft="1dp"
            android:layout_weight="1"
            android:background="@android:color/darker_gray"
            android:gravity="center"
            android:text="Operator FlatMap IPs"
            android:textAllCaps="false"/>
    </LinearLayout>

</LinearLayout>