<commit_before>import { RowNode } from "./entities/rowNode";
import {
    ChartRef, GetChartToolbarItems,
    GetContextMenuItems,
    GetMainMenuItems,
    GetRowNodeIdFunc,
    GridOptions,
    IsRowMaster,
    IsRowSelectable,
    NavigateToNextCellParams,
    NodeChildDetails,
    PaginationNumberFormatterParams,
    PostProcessPopupParams,
    ProcessChartOptionsParams,
    ProcessDataFromClipboardParams,
    TabToNextCellParams
} from "./entities/gridOptions";
import { _ } from "./utils";
import { EventService } from "./eventService";
import { Constants } from "./constants";
import { ComponentUtil } from "./components/componentUtil";
import { GridApi } from "./gridApi";
import { ColDef, ColGroupDef, IAggFunc, SuppressKeyboardEventParams } from "./entities/colDef";
import { Autowired, Bean, Context, PostConstruct, PreDestroy, Qualifier } from "./context/context";
import { ColumnApi } from "./columnController/columnApi";
import { ColumnController } from "./columnController/columnController";
import { IViewportDatasource } from "./interfaces/iViewportDatasource";
import { IDatasource } from "./rowModels/iDatasource";
import { CellPosition } from "./entities/cellPosition";
import { IServerSideDatasource } from "./interfaces/iServerSideDatasource";
import { BaseExportParams, ProcessCellForExportParams, ProcessHeaderForExportParams } from "./exporter/exportParams";
import { AgEvent } from "./events";
import { Environment, SASS_PROPERTIES } from "./environment";
import { PropertyKeys } from "./propertyKeys";
import { ColDefUtil } from "./components/colDefUtil";
import { Events } from "./eventKeys";
import { AutoHeightCalculator } from "./rendering/autoHeightCalculator";
import { SideBarDef, SideBarDefParser, ToolPanelDef } from "./entities/sideBar";
import { ModuleNames } from "./modules/moduleNames";
import { ChartOptions } from "./interfaces/iChartOptions";

const DEFAULT_ROW_HEIGHT = 25;
const DEFAULT_DETAIL_ROW_HEIGHT = 300;
const DEFAULT_VIEWPORT_ROW_MODEL_PAGE_SIZE = 5;
const DEFAULT_VIEWPORT_ROW_MODEL_BUFFER_SIZE = 5;
const DEFAULT_KEEP_DETAIL_ROW_COUNT = 10;

function isTrue(value: any): boolean {
    return value === true || value === 'true';
}

function zeroOrGreater(value: any, defaultValue: number): number {
    if (value >= 0) {
        return value;
    }
    // zero gets returned if number is missing or the wrong type
    return defaultValue;
}

function oneOrGreater(value: any, defaultValue: number): number {
    if (value > 0) {
        return value;
    }
    // zero gets returned if number is missing or the wrong type
    return defaultValue;
}

export interface PropertyChangedEvent extends AgEvent {
    currentValue: any;
    previousValue: any;
}

@Bean('gridOptionsWrapper')
export class GridOptionsWrapper {

    private static MIN_COL_WIDTH = 10;

    public static PROP_HEADER_HEIGHT = 'headerHeight';
    public static PROP_GROUP_REMOVE_SINGLE_CHILDREN = 'groupRemoveSingleChildren';
    public static PROP_GROUP_REMOVE_LOWEST_SINGLE_CHILDREN = 'groupRemoveLowestSingleChildren';
    public static PROP_PIVOT_HEADER_HEIGHT = 'pivotHeaderHeight';
    public static PROP_SUPPRESS_CLIPBOARD_PASTE = 'suppressClipboardPaste';

    public static PROP_GROUP_HEADER_HEIGHT = 'groupHeaderHeight';
    public static PROP_PIVOT_GROUP_HEADER_HEIGHT = 'pivotGroupHeaderHeight';

    public static PROP_FLOATING_FILTERS_HEIGHT = 'floatingFiltersHeight';

    public static PROP_SUPPRESS_ROW_DRAG = 'suppressRowDrag';
    public static PROP_POPUP_PARENT = 'popupParent';

    public static PROP_DOM_LAYOUT = 'domLayout';

    @Autowired('gridOptions') private gridOptions: GridOptions;
    @Autowired('columnController') private columnController: ColumnController;
    @Autowired('eventService') private eventService: EventService;
    @Autowired('enterprise') private enterprise: boolean;
    @Autowired('gridApi') private gridApi: GridApi;
    @Autowired('columnApi') private columnApi: ColumnApi;
    @Autowired('environment') private environment: Environment;
    @Autowired('autoHeightCalculator') private autoHeightCalculator: AutoHeightCalculator;
    @Autowired('context') private context: Context;

    private propertyEventService: EventService = new EventService();

    private domDataKey = '__AG_' + Math.random().toString();

    private layoutElements: HTMLElement[] = [];

    // we store this locally, so we are not calling _.getScrollWidth() multiple times as it's an expensive operation
    private scrollWidth: number;

    private agWire(@Qualifier('gridApi') gridApi: GridApi, @Qualifier('columnApi') columnApi: ColumnApi): void {
        this.gridOptions.api = gridApi;
        this.gridOptions.columnApi = columnApi;
        this.checkForDeprecated();
        this.checkForViolations();
    }

    @PreDestroy
    private destroy(): void {
        // need to remove these, as we don't own the lifecycle of the gridOptions, we need to
        // remove the references in case the user keeps the grid options, we want the rest
        // of the grid to be picked up by the garbage collector
        this.gridOptions.api = null;
        this.gridOptions.columnApi = null;
    }

    @PostConstruct
    public init(): void {

        if (!(this.gridOptions.suppressPropertyNamesCheck === true)) {
            this.checkGridOptionsProperties();
            this.checkColumnDefProperties();
        }

        const async = this.useAsyncEvents();
        this.eventService.addGlobalListener(this.globalEventHandler.bind(this), async);

        if (this.isGroupSelectsChildren() && this.isSuppressParentsInRowNodes()) {
            console.warn('ag-Grid: groupSelectsChildren does not work wth suppressParentsInRowNodes, this selection method needs the part in rowNode to work');
        }

        if (this.isGroupSelectsChildren()) {
            if (!this.isRowSelectionMulti()) {
                console.warn(`ag-Grid: rowSelection must be 'multiple' for groupSelectsChildren to make sense`);
            }
            if (this.isRowModelServerSide()) {
                console.warn('ag-Grid: group selects children is NOT support for Server Side Row Model. ' +
                    'This is because the rows are lazy loaded, so selecting a group is not possible as' +
                    'the grid has no way of knowing what the children are.');
            }
        }

        if (this.isGroupRemoveSingleChildren() && this.isGroupHideOpenParents()) {
            console.warn('ag-Grid: groupRemoveSingleChildren and groupHideOpenParents do not work with each other, you need to pick one. And don\'t ask us how to us these together on our support forum either you will get the same answer!');
        }

        this.addEventListener(GridOptionsWrapper.PROP_DOM_LAYOUT, this.updateLayoutClasses.bind(this));
    }

    private checkColumnDefProperties() {
        if (this.gridOptions.columnDefs == null) { return; }

        this.gridOptions.columnDefs.forEach(colDef => {
            const userProperties: string [] = Object.getOwnPropertyNames(colDef);
            const validProperties: string [] = ColDefUtil.ALL_PROPERTIES.concat(ColDefUtil.FRAMEWORK_PROPERTIES);

            this.checkProperties(
                userProperties,
                validProperties,
                validProperties,
                'colDef',
                'https://www.ag-grid.com/javascript-grid-column-properties/'
            );
        });
    }

    private checkGridOptionsProperties() {
        const userProperties: string [] = Object.getOwnPropertyNames(this.gridOptions);
        const validProperties: string [] = PropertyKeys.ALL_PROPERTIES.concat(PropertyKeys.FRAMEWORK_PROPERTIES);
        Object.keys(Events).forEach(it => validProperties.push(ComponentUtil.getCallbackForEvent((Events as any)[it])));
        const validPropertiesAndExceptions: string [] = validProperties.concat('api', 'columnApi');

        this.checkProperties(
            userProperties,
            validPropertiesAndExceptions,
            validProperties,
            'gridOptions',
            'https://www.ag-grid.com/javascript-grid-properties/'
        );
    }

    private checkProperties(userProperties: string[],
                            validPropertiesAndExceptions: string[],
                            validProperties: string[],
                            containerName: string,
                            docsUrl: string) {
        const invalidProperties: { [p: string]: string[] } = _.fuzzyCheckStrings(
            userProperties,
            validPropertiesAndExceptions,
            validProperties
        );

        const invalidPropertyKeys = Object.keys(invalidProperties);
        invalidPropertyKeys.forEach(invalidPropertyKey => {
            const fuzzySuggestions: string[] = invalidProperties [invalidPropertyKey];
            console.warn(`ag-grid: invalid ${containerName} property '${invalidPropertyKey}' did you mean any of these: ${fuzzySuggestions.slice(0, 8).join(",")}`);
        });

        if (invalidPropertyKeys.length > 0) {
            console.warn(`ag-grid: to see all the valid ${containerName} properties please check: ${docsUrl}`);
        }
    }

// returns the dom data, or undefined if not found
    public getDomData(element: Node, key: string): any {
        const domData = (element as any)[this.domDataKey];
        if (domData) {
            return domData[key];
        }

        return;
    }

    public setDomData(element: Element, key: string, value: any): any {
        let domData = (element as any)[this.domDataKey];
        if (_.missing(domData)) {
            domData = {};
            (element as any)[this.domDataKey] = domData;
        }
        domData[key] = value;
    }

    public isEnterprise() {
        return this.enterprise;
    }

    public isRowSelection() {
        return this.gridOptions.rowSelection === "single" || this.gridOptions.rowSelection === "multiple";
    }

    public isRowDeselection() {
        return isTrue(this.gridOptions.rowDeselection);
    }

    public isRowSelectionMulti() {
        return this.gridOptions.rowSelection === 'multiple';
    }

    public isRowMultiSelectWithClick() {
        return isTrue(this.gridOptions.rowMultiSelectWithClick);
    }

    public getContext() {
        return this.gridOptions.context;
    }

    public isPivotMode() {
        return isTrue(this.gridOptions.pivotMode);
    }

    public isPivotTotals() {
        return isTrue(this.gridOptions.pivotTotals);
    }

    public getPivotColumnGroupTotals() {
        return this.gridOptions.pivotColumnGroupTotals;
    }

    public getPivotRowTotals() {
        return this.gridOptions.pivotRowTotals;
    }

    public isRowModelInfinite() {
        return this.gridOptions.rowModelType === Constants.ROW_MODEL_TYPE_INFINITE;
    }

    public isRowModelViewport() {
        return this.gridOptions.rowModelType === Constants.ROW_MODEL_TYPE_VIEWPORT;
    }

    public isRowModelServerSide() {
        return this.gridOptions.rowModelType === Constants.ROW_MODEL_TYPE_SERVER_SIDE;
    }

    public isRowModelDefault() {
        return _.missing(this.gridOptions.rowModelType) ||
            this.gridOptions.rowModelType === Constants.ROW_MODEL_TYPE_CLIENT_SIDE ||
            this.gridOptions.rowModelType === Constants.DEPRECATED_ROW_MODEL_TYPE_NORMAL;
    }

    public isFullRowEdit() {
        return this.gridOptions.editType === 'fullRow';
    }

    public isSuppressFocusAfterRefresh() {
        return isTrue(this.gridOptions.suppressFocusAfterRefresh);
    }

    public isSuppressBrowserResizeObserver() {
        return isTrue(this.gridOptions.suppressBrowserResizeObserver);
    }

    public isSuppressMaintainUnsortedOrder() {
        return isTrue(this.gridOptions.suppressMaintainUnsortedOrder);
    }

    public isShowToolPanel() {
        return isTrue(this.gridOptions.sideBar && Array.isArray(this.getSideBar().toolPanels));
    }

    public getSideBar(): SideBarDef {
        return (this.gridOptions.sideBar as SideBarDef);
    }

    public isSuppressTouch() {
        return isTrue(this.gridOptions.suppressTouch);
    }

    public isSuppressRowTransform() {
        return isTrue(this.gridOptions.suppressRowTransform);
    }

    public isSuppressSetColumnStateEvents() {
        return isTrue(this.gridOptions.suppressSetColumnStateEvents);
    }

    public useAsyncEvents() {
        return !isTrue(this.gridOptions.suppressAsyncEvents);
    }

    public isEnableCellChangeFlash() {
        return isTrue(this.gridOptions.enableCellChangeFlash);
    }

    public isGroupSelectsChildren() {
        const result = isTrue(this.gridOptions.groupSelectsChildren);
        if (result && this.isTreeData()) {
            console.warn('ag-Grid: groupSelectsChildren does not work with tree data');
            return false;
        }

        return result;
    }

    public isSuppressRowHoverHighlight() {
        return isTrue(this.gridOptions.suppressRowHoverHighlight);
    }

    public isGroupSelectsFiltered() {
        return isTrue(this.gridOptions.groupSelectsFiltered);
    }

    public isGroupHideOpenParents() {
        return isTrue(this.gridOptions.groupHideOpenParents);
    }

    // if we are doing hideOpenParents, then we always have groupMultiAutoColumn, otherwise hideOpenParents would not work
    public isGroupMultiAutoColumn() {
        return isTrue(this.gridOptions.groupMultiAutoColumn) || isTrue(this.gridOptions.groupHideOpenParents);
    }

    public isGroupRemoveSingleChildren() {
        return isTrue(this.gridOptions.groupRemoveSingleChildren);
    }

    public isGroupRemoveLowestSingleChildren() {
        return isTrue(this.gridOptions.groupRemoveLowestSingleChildren);
    }

    public isGroupIncludeFooter() {
        return isTrue(this.gridOptions.groupIncludeFooter);
    }

    public isGroupIncludeTotalFooter() {
        return isTrue(this.gridOptions.groupIncludeTotalFooter);
    }

    public isGroupSuppressBlankHeader() {
        return isTrue(this.gridOptions.groupSuppressBlankHeader);
    }

    public isSuppressRowClickSelection() {
        return isTrue(this.gridOptions.suppressRowClickSelection);
    }

    public isSuppressCellSelection() {
        return isTrue(this.gridOptions.suppressCellSelection);
    }

    public isSuppressMultiSort() {
        return isTrue(this.gridOptions.suppressMultiSort);
    }

    public isMultiSortKeyCtrl() {
        return this.gridOptions.multiSortKey === 'ctrl';
    }

    public isGroupSuppressAutoColumn() {
        return isTrue(this.gridOptions.groupSuppressAutoColumn);
    }

    public isSuppressDragLeaveHidesColumns() {
        return isTrue(this.gridOptions.suppressDragLeaveHidesColumns);
    }

    public isSuppressScrollOnNewData() {
        return isTrue(this.gridOptions.suppressScrollOnNewData);
    }

    public isRowDragManaged() {
        return isTrue(this.gridOptions.rowDragManaged);
    }

    public isSuppressRowDrag() {
        return isTrue(this.gridOptions.suppressRowDrag);
    }

    // returns either 'print', 'autoHeight' or 'normal' (normal is the default)
    public getDomLayout(): string {

        const domLayout = this.gridOptions.domLayout;

        if (domLayout === Constants.DOM_LAYOUT_PRINT
            || domLayout === Constants.DOM_LAYOUT_AUTO_HEIGHT
            || domLayout === Constants.DOM_LAYOUT_NORMAL) {
            return domLayout;
        } else if (domLayout === null || domLayout === undefined) {
            return Constants.DOM_LAYOUT_NORMAL;
        } else {
            _.doOnce(() => console.warn(`ag-Grid: ${this.gridOptions.domLayout} is not valid for DOM Layout, valid values are ${Constants.DOM_LAYOUT_NORMAL}, ${Constants.DOM_LAYOUT_AUTO_HEIGHT} and ${Constants.DOM_LAYOUT_PRINT}`),
                'warn about dom layout values');
            return Constants.DOM_LAYOUT_NORMAL;
        }
    }

    public isSuppressHorizontalScroll() {
        return isTrue(this.gridOptions.suppressHorizontalScroll);
    }

    public isSuppressMaxRenderedRowRestriction() {
        return isTrue(this.gridOptions.suppressMaxRenderedRowRestriction);
    }

    public isExcludeChildrenWhenTreeDataFiltering() {
        return isTrue(this.gridOptions.excludeChildrenWhenTreeDataFiltering);
    }

    public isAlwaysShowVerticalScroll() {
        return isTrue(this.gridOptions.alwaysShowVerticalScroll);
    }

    public isSuppressLoadingOverlay() {
        return isTrue(this.gridOptions.suppressLoadingOverlay);
    }

    public isSuppressNoRowsOverlay() {
        return isTrue(this.gridOptions.suppressNoRowsOverlay);
    }

    public isSuppressFieldDotNotation() {
        return isTrue(this.gridOptions.suppressFieldDotNotation);
    }

    public getPinnedTopRowData(): any[] | undefined {
        return this.gridOptions.pinnedTopRowData;
    }

    public getPinnedBottomRowData(): any[] | undefined {
        return this.gridOptions.pinnedBottomRowData;
    }

    public isFunctionsPassive() {
        return isTrue(this.gridOptions.functionsPassive);
    }

    public isSuppressTabbing() {
        return isTrue(this.gridOptions.suppressTabbing);
    }

    public isSuppressChangeDetection() {
        return isTrue(this.gridOptions.suppressChangeDetection);
    }

    public isSuppressAnimationFrame() {
        return isTrue(this.gridOptions.suppressAnimationFrame);
    }

    public getQuickFilterText(): string | undefined {
        return this.gridOptions.quickFilterText;
    }

    public isCacheQuickFilter() {
        return isTrue(this.gridOptions.cacheQuickFilter);
    }

    public isUnSortIcon() {
        return isTrue(this.gridOptions.unSortIcon);
    }

    public isSuppressMenuHide() {
        return isTrue(this.gridOptions.suppressMenuHide);
    }

    public isEnterMovesDownAfterEdit() {
        return isTrue(this.gridOptions.enterMovesDownAfterEdit);
    }

    public isEnterMovesDown() {
        return isTrue(this.gridOptions.enterMovesDown);
    }

    public getRowStyle() {
        return this.gridOptions.rowStyle;
    }

    public getRowClass() {
        return this.gridOptions.rowClass;
    }

    public getRowStyleFunc() {
        return this.gridOptions.getRowStyle;
    }

    public getRowClassFunc() {
        return this.gridOptions.getRowClass;
    }

    public rowClassRules() {
        return this.gridOptions.rowClassRules;
    }

    public getCreateChartContainerFunc(): (params: ChartRef) => void | undefined {
        return this.gridOptions.createChartContainer;
    }

    public getPopupParent() {
        return this.gridOptions.popupParent;
    }

    public getBlockLoadDebounceMillis() {
        return this.gridOptions.blockLoadDebounceMillis;
    }

    public getPostProcessPopupFunc(): ((params: PostProcessPopupParams) => void) | undefined {
        return this.gridOptions.postProcessPopup;
    }

    public getDoesDataFlowerFunc(): ((data: any) => boolean) | undefined {
        return this.gridOptions.doesDataFlower;
    }

    public getPaginationNumberFormatterFunc(): ((params: PaginationNumberFormatterParams) => string) | undefined {
        return this.gridOptions.paginationNumberFormatter;
    }

    public getChildCountFunc() {
        return this.gridOptions.getChildCount;
    }

    public getDefaultGroupSortComparator() {
        return this.gridOptions.defaultGroupSortComparator;
    }

    public getIsFullWidthCellFunc(): ((rowNode: RowNode) => boolean) | undefined {
        return this.gridOptions.isFullWidthCell;
    }

    public getFullWidthCellRendererParams() {
        return this.gridOptions.fullWidthCellRendererParams;
    }

    public isEmbedFullWidthRows() {
        return isTrue(this.gridOptions.embedFullWidthRows);
    }

    public getSuppressKeyboardEventFunc(): (params: SuppressKeyboardEventParams) => boolean {
        return this.gridOptions.suppressKeyboardEvent;
    }

    public getBusinessKeyForNodeFunc() {
        return this.gridOptions.getBusinessKeyForNode;
    }

    public getApi(): GridApi | undefined | null {
        return this.gridOptions.api;
    }

    public getColumnApi(): ColumnApi | undefined | null {
        return this.gridOptions.columnApi;
    }

    public isDeltaRowDataMode() {
        return isTrue(this.gridOptions.deltaRowDataMode);
    }

    public isDeltaColumnMode() {
        return isTrue(this.gridOptions.deltaColumnMode);
    }

    public isEnsureDomOrder() {
        return isTrue(this.gridOptions.ensureDomOrder);
    }
<commit_msg>AG-3157 - embedFullWidthRows and deprecatedEmbedFullWidthRows should work<commit_after>import { RowNode } from "./entities/rowNode";
import {
    ChartRef, GetChartToolbarItems,
    GetContextMenuItems,
    GetMainMenuItems,
    GetRowNodeIdFunc,
    GridOptions,
    IsRowMaster,
    IsRowSelectable,
    NavigateToNextCellParams,
    NodeChildDetails,
    PaginationNumberFormatterParams,
    PostProcessPopupParams,
    ProcessChartOptionsParams,
    ProcessDataFromClipboardParams,
    TabToNextCellParams
} from "./entities/gridOptions";
import { _ } from "./utils";
import { EventService } from "./eventService";
import { Constants } from "./constants";
import { ComponentUtil } from "./components/componentUtil";
import { GridApi } from "./gridApi";
import { ColDef, ColGroupDef, IAggFunc, SuppressKeyboardEventParams } from "./entities/colDef";
import { Autowired, Bean, Context, PostConstruct, PreDestroy, Qualifier } from "./context/context";
import { ColumnApi } from "./columnController/columnApi";
import { ColumnController } from "./columnController/columnController";
import { IViewportDatasource } from "./interfaces/iViewportDatasource";
import { IDatasource } from "./rowModels/iDatasource";
import { CellPosition } from "./entities/cellPosition";
import { IServerSideDatasource } from "./interfaces/iServerSideDatasource";
import { BaseExportParams, ProcessCellForExportParams, ProcessHeaderForExportParams } from "./exporter/exportParams";
import { AgEvent } from "./events";
import { Environment, SASS_PROPERTIES } from "./environment";
import { PropertyKeys } from "./propertyKeys";
import { ColDefUtil } from "./components/colDefUtil";
import { Events } from "./eventKeys";
import { AutoHeightCalculator } from "./rendering/autoHeightCalculator";
import { SideBarDef, SideBarDefParser, ToolPanelDef } from "./entities/sideBar";
import { ModuleNames } from "./modules/moduleNames";
import { ChartOptions } from "./interfaces/iChartOptions";

const DEFAULT_ROW_HEIGHT = 25;
const DEFAULT_DETAIL_ROW_HEIGHT = 300;
const DEFAULT_VIEWPORT_ROW_MODEL_PAGE_SIZE = 5;
const DEFAULT_VIEWPORT_ROW_MODEL_BUFFER_SIZE = 5;
const DEFAULT_KEEP_DETAIL_ROW_COUNT = 10;

function isTrue(value: any): boolean {
    return value === true || value === 'true';
}

function zeroOrGreater(value: any, defaultValue: number): number {
    if (value >= 0) {
        return value;
    }
    // zero gets returned if number is missing or the wrong type
    return defaultValue;
}

function oneOrGreater(value: any, defaultValue: number): number {
    if (value > 0) {
        return value;
    }
    // zero gets returned if number is missing or the wrong type
    return defaultValue;
}

export interface PropertyChangedEvent extends AgEvent {
    currentValue: any;
    previousValue: any;
}

@Bean('gridOptionsWrapper')
export class GridOptionsWrapper {

    private static MIN_COL_WIDTH = 10;

    public static PROP_HEADER_HEIGHT = 'headerHeight';
    public static PROP_GROUP_REMOVE_SINGLE_CHILDREN = 'groupRemoveSingleChildren';
    public static PROP_GROUP_REMOVE_LOWEST_SINGLE_CHILDREN = 'groupRemoveLowestSingleChildren';
    public static PROP_PIVOT_HEADER_HEIGHT = 'pivotHeaderHeight';
    public static PROP_SUPPRESS_CLIPBOARD_PASTE = 'suppressClipboardPaste';

    public static PROP_GROUP_HEADER_HEIGHT = 'groupHeaderHeight';
    public static PROP_PIVOT_GROUP_HEADER_HEIGHT = 'pivotGroupHeaderHeight';

    public static PROP_FLOATING_FILTERS_HEIGHT = 'floatingFiltersHeight';

    public static PROP_SUPPRESS_ROW_DRAG = 'suppressRowDrag';
    public static PROP_POPUP_PARENT = 'popupParent';

    public static PROP_DOM_LAYOUT = 'domLayout';

    @Autowired('gridOptions') private gridOptions: GridOptions;
    @Autowired('columnController') private columnController: ColumnController;
    @Autowired('eventService') private eventService: EventService;
    @Autowired('enterprise') private enterprise: boolean;
    @Autowired('gridApi') private gridApi: GridApi;
    @Autowired('columnApi') private columnApi: ColumnApi;
    @Autowired('environment') private environment: Environment;
    @Autowired('autoHeightCalculator') private autoHeightCalculator: AutoHeightCalculator;
    @Autowired('context') private context: Context;

    private propertyEventService: EventService = new EventService();

    private domDataKey = '__AG_' + Math.random().toString();

    private layoutElements: HTMLElement[] = [];

    // we store this locally, so we are not calling _.getScrollWidth() multiple times as it's an expensive operation
    private scrollWidth: number;

    private agWire(@Qualifier('gridApi') gridApi: GridApi, @Qualifier('columnApi') columnApi: ColumnApi): void {
        this.gridOptions.api = gridApi;
        this.gridOptions.columnApi = columnApi;
        this.checkForDeprecated();
        this.checkForViolations();
    }

    @PreDestroy
    private destroy(): void {
        // need to remove these, as we don't own the lifecycle of the gridOptions, we need to
        // remove the references in case the user keeps the grid options, we want the rest
        // of the grid to be picked up by the garbage collector
        this.gridOptions.api = null;
        this.gridOptions.columnApi = null;
    }

    @PostConstruct
    public init(): void {

        if (!(this.gridOptions.suppressPropertyNamesCheck === true)) {
            this.checkGridOptionsProperties();
            this.checkColumnDefProperties();
        }

        const async = this.useAsyncEvents();
        this.eventService.addGlobalListener(this.globalEventHandler.bind(this), async);

        if (this.isGroupSelectsChildren() && this.isSuppressParentsInRowNodes()) {
            console.warn('ag-Grid: groupSelectsChildren does not work wth suppressParentsInRowNodes, this selection method needs the part in rowNode to work');
        }

        if (this.isGroupSelectsChildren()) {
            if (!this.isRowSelectionMulti()) {
                console.warn(`ag-Grid: rowSelection must be 'multiple' for groupSelectsChildren to make sense`);
            }
            if (this.isRowModelServerSide()) {
                console.warn('ag-Grid: group selects children is NOT support for Server Side Row Model. ' +
                    'This is because the rows are lazy loaded, so selecting a group is not possible as' +
                    'the grid has no way of knowing what the children are.');
            }
        }

        if (this.isGroupRemoveSingleChildren() && this.isGroupHideOpenParents()) {
            console.warn('ag-Grid: groupRemoveSingleChildren and groupHideOpenParents do not work with each other, you need to pick one. And don\'t ask us how to us these together on our support forum either you will get the same answer!');
        }

        this.addEventListener(GridOptionsWrapper.PROP_DOM_LAYOUT, this.updateLayoutClasses.bind(this));
    }

    private checkColumnDefProperties() {
        if (this.gridOptions.columnDefs == null) { return; }

        this.gridOptions.columnDefs.forEach(colDef => {
            const userProperties: string [] = Object.getOwnPropertyNames(colDef);
            const validProperties: string [] = ColDefUtil.ALL_PROPERTIES.concat(ColDefUtil.FRAMEWORK_PROPERTIES);

            this.checkProperties(
                userProperties,
                validProperties,
                validProperties,
                'colDef',
                'https://www.ag-grid.com/javascript-grid-column-properties/'
            );
        });
    }

    private checkGridOptionsProperties() {
        const userProperties: string [] = Object.getOwnPropertyNames(this.gridOptions);
        const validProperties: string [] = PropertyKeys.ALL_PROPERTIES.concat(PropertyKeys.FRAMEWORK_PROPERTIES);
        Object.keys(Events).forEach(it => validProperties.push(ComponentUtil.getCallbackForEvent((Events as any)[it])));
        const validPropertiesAndExceptions: string [] = validProperties.concat('api', 'columnApi');

        this.checkProperties(
            userProperties,
            validPropertiesAndExceptions,
            validProperties,
            'gridOptions',
            'https://www.ag-grid.com/javascript-grid-properties/'
        );
    }

    private checkProperties(userProperties: string[],
                            validPropertiesAndExceptions: string[],
                            validProperties: string[],
                            containerName: string,
                            docsUrl: string) {
        const invalidProperties: { [p: string]: string[] } = _.fuzzyCheckStrings(
            userProperties,
            validPropertiesAndExceptions,
            validProperties
        );

        const invalidPropertyKeys = Object.keys(invalidProperties);
        invalidPropertyKeys.forEach(invalidPropertyKey => {
            const fuzzySuggestions: string[] = invalidProperties [invalidPropertyKey];
            console.warn(`ag-grid: invalid ${containerName} property '${invalidPropertyKey}' did you mean any of these: ${fuzzySuggestions.slice(0, 8).join(",")}`);
        });

        if (invalidPropertyKeys.length > 0) {
            console.warn(`ag-grid: to see all the valid ${containerName} properties please check: ${docsUrl}`);
        }
    }

// returns the dom data, or undefined if not found
    public getDomData(element: Node, key: string): any {
        const domData = (element as any)[this.domDataKey];
        if (domData) {
            return domData[key];
        }

        return;
    }

    public setDomData(element: Element, key: string, value: any): any {
        let domData = (element as any)[this.domDataKey];
        if (_.missing(domData)) {
            domData = {};
            (element as any)[this.domDataKey] = domData;
        }
        domData[key] = value;
    }

    public isEnterprise() {
        return this.enterprise;
    }

    public isRowSelection() {
        return this.gridOptions.rowSelection === "single" || this.gridOptions.rowSelection === "multiple";
    }

    public isRowDeselection() {
        return isTrue(this.gridOptions.rowDeselection);
    }

    public isRowSelectionMulti() {
        return this.gridOptions.rowSelection === 'multiple';
    }

    public isRowMultiSelectWithClick() {
        return isTrue(this.gridOptions.rowMultiSelectWithClick);
    }

    public getContext() {
        return this.gridOptions.context;
    }

    public isPivotMode() {
        return isTrue(this.gridOptions.pivotMode);
    }

    public isPivotTotals() {
        return isTrue(this.gridOptions.pivotTotals);
    }

    public getPivotColumnGroupTotals() {
        return this.gridOptions.pivotColumnGroupTotals;
    }

    public getPivotRowTotals() {
        return this.gridOptions.pivotRowTotals;
    }

    public isRowModelInfinite() {
        return this.gridOptions.rowModelType === Constants.ROW_MODEL_TYPE_INFINITE;
    }

    public isRowModelViewport() {
        return this.gridOptions.rowModelType === Constants.ROW_MODEL_TYPE_VIEWPORT;
    }

    public isRowModelServerSide() {
        return this.gridOptions.rowModelType === Constants.ROW_MODEL_TYPE_SERVER_SIDE;
    }

    public isRowModelDefault() {
        return _.missing(this.gridOptions.rowModelType) ||
            this.gridOptions.rowModelType === Constants.ROW_MODEL_TYPE_CLIENT_SIDE ||
            this.gridOptions.rowModelType === Constants.DEPRECATED_ROW_MODEL_TYPE_NORMAL;
    }

    public isFullRowEdit() {
        return this.gridOptions.editType === 'fullRow';
    }

    public isSuppressFocusAfterRefresh() {
        return isTrue(this.gridOptions.suppressFocusAfterRefresh);
    }

    public isSuppressBrowserResizeObserver() {
        return isTrue(this.gridOptions.suppressBrowserResizeObserver);
    }

    public isSuppressMaintainUnsortedOrder() {
        return isTrue(this.gridOptions.suppressMaintainUnsortedOrder);
    }

    public isShowToolPanel() {
        return isTrue(this.gridOptions.sideBar && Array.isArray(this.getSideBar().toolPanels));
    }

    public getSideBar(): SideBarDef {
        return (this.gridOptions.sideBar as SideBarDef);
    }

    public isSuppressTouch() {
        return isTrue(this.gridOptions.suppressTouch);
    }

    public isSuppressRowTransform() {
        return isTrue(this.gridOptions.suppressRowTransform);
    }

    public isSuppressSetColumnStateEvents() {
        return isTrue(this.gridOptions.suppressSetColumnStateEvents);
    }

    public useAsyncEvents() {
        return !isTrue(this.gridOptions.suppressAsyncEvents);
    }

    public isEnableCellChangeFlash() {
        return isTrue(this.gridOptions.enableCellChangeFlash);
    }

    public isGroupSelectsChildren() {
        const result = isTrue(this.gridOptions.groupSelectsChildren);
        if (result && this.isTreeData()) {
            console.warn('ag-Grid: groupSelectsChildren does not work with tree data');
            return false;
        }

        return result;
    }

    public isSuppressRowHoverHighlight() {
        return isTrue(this.gridOptions.suppressRowHoverHighlight);
    }

    public isGroupSelectsFiltered() {
        return isTrue(this.gridOptions.groupSelectsFiltered);
    }

    public isGroupHideOpenParents() {
        return isTrue(this.gridOptions.groupHideOpenParents);
    }

    // if we are doing hideOpenParents, then we always have groupMultiAutoColumn, otherwise hideOpenParents would not work
    public isGroupMultiAutoColumn() {
        return isTrue(this.gridOptions.groupMultiAutoColumn) || isTrue(this.gridOptions.groupHideOpenParents);
    }

    public isGroupRemoveSingleChildren() {
        return isTrue(this.gridOptions.groupRemoveSingleChildren);
    }

    public isGroupRemoveLowestSingleChildren() {
        return isTrue(this.gridOptions.groupRemoveLowestSingleChildren);
    }

    public isGroupIncludeFooter() {
        return isTrue(this.gridOptions.groupIncludeFooter);
    }

    public isGroupIncludeTotalFooter() {
        return isTrue(this.gridOptions.groupIncludeTotalFooter);
    }

    public isGroupSuppressBlankHeader() {
        return isTrue(this.gridOptions.groupSuppressBlankHeader);
    }

    public isSuppressRowClickSelection() {
        return isTrue(this.gridOptions.suppressRowClickSelection);
    }

    public isSuppressCellSelection() {
        return isTrue(this.gridOptions.suppressCellSelection);
    }

    public isSuppressMultiSort() {
        return isTrue(this.gridOptions.suppressMultiSort);
    }

    public isMultiSortKeyCtrl() {
        return this.gridOptions.multiSortKey === 'ctrl';
    }

    public isGroupSuppressAutoColumn() {
        return isTrue(this.gridOptions.groupSuppressAutoColumn);
    }

    public isSuppressDragLeaveHidesColumns() {
        return isTrue(this.gridOptions.suppressDragLeaveHidesColumns);
    }

    public isSuppressScrollOnNewData() {
        return isTrue(this.gridOptions.suppressScrollOnNewData);
    }

    public isRowDragManaged() {
        return isTrue(this.gridOptions.rowDragManaged);
    }

    public isSuppressRowDrag() {
        return isTrue(this.gridOptions.suppressRowDrag);
    }

    // returns either 'print', 'autoHeight' or 'normal' (normal is the default)
    public getDomLayout(): string {

        const domLayout = this.gridOptions.domLayout;

        if (domLayout === Constants.DOM_LAYOUT_PRINT
            || domLayout === Constants.DOM_LAYOUT_AUTO_HEIGHT
            || domLayout === Constants.DOM_LAYOUT_NORMAL) {
            return domLayout;
        } else if (domLayout === null || domLayout === undefined) {
            return Constants.DOM_LAYOUT_NORMAL;
        } else {
            _.doOnce(() => console.warn(`ag-Grid: ${this.gridOptions.domLayout} is not valid for DOM Layout, valid values are ${Constants.DOM_LAYOUT_NORMAL}, ${Constants.DOM_LAYOUT_AUTO_HEIGHT} and ${Constants.DOM_LAYOUT_PRINT}`),
                'warn about dom layout values');
            return Constants.DOM_LAYOUT_NORMAL;
        }
    }

    public isSuppressHorizontalScroll() {
        return isTrue(this.gridOptions.suppressHorizontalScroll);
    }

    public isSuppressMaxRenderedRowRestriction() {
        return isTrue(this.gridOptions.suppressMaxRenderedRowRestriction);
    }

    public isExcludeChildrenWhenTreeDataFiltering() {
        return isTrue(this.gridOptions.excludeChildrenWhenTreeDataFiltering);
    }

    public isAlwaysShowVerticalScroll() {
        return isTrue(this.gridOptions.alwaysShowVerticalScroll);
    }

    public isSuppressLoadingOverlay() {
        return isTrue(this.gridOptions.suppressLoadingOverlay);
    }

    public isSuppressNoRowsOverlay() {
        return isTrue(this.gridOptions.suppressNoRowsOverlay);
    }

    public isSuppressFieldDotNotation() {
        return isTrue(this.gridOptions.suppressFieldDotNotation);
    }

    public getPinnedTopRowData(): any[] | undefined {
        return this.gridOptions.pinnedTopRowData;
    }

    public getPinnedBottomRowData(): any[] | undefined {
        return this.gridOptions.pinnedBottomRowData;
    }

    public isFunctionsPassive() {
        return isTrue(this.gridOptions.functionsPassive);
    }

    public isSuppressTabbing() {
        return isTrue(this.gridOptions.suppressTabbing);
    }

    public isSuppressChangeDetection() {
        return isTrue(this.gridOptions.suppressChangeDetection);
    }

    public isSuppressAnimationFrame() {
        return isTrue(this.gridOptions.suppressAnimationFrame);
    }

    public getQuickFilterText(): string | undefined {
        return this.gridOptions.quickFilterText;
    }

    public isCacheQuickFilter() {
        return isTrue(this.gridOptions.cacheQuickFilter);
    }

    public isUnSortIcon() {
        return isTrue(this.gridOptions.unSortIcon);
    }

    public isSuppressMenuHide() {
        return isTrue(this.gridOptions.suppressMenuHide);
    }

    public isEnterMovesDownAfterEdit() {
        return isTrue(this.gridOptions.enterMovesDownAfterEdit);
    }

    public isEnterMovesDown() {
        return isTrue(this.gridOptions.enterMovesDown);
    }

    public getRowStyle() {
        return this.gridOptions.rowStyle;
    }

    public getRowClass() {
        return this.gridOptions.rowClass;
    }

    public getRowStyleFunc() {
        return this.gridOptions.getRowStyle;
    }

    public getRowClassFunc() {
        return this.gridOptions.getRowClass;
    }

    public rowClassRules() {
        return this.gridOptions.rowClassRules;
    }

    public getCreateChartContainerFunc(): (params: ChartRef) => void | undefined {
        return this.gridOptions.createChartContainer;
    }

    public getPopupParent() {
        return this.gridOptions.popupParent;
    }

    public getBlockLoadDebounceMillis() {
        return this.gridOptions.blockLoadDebounceMillis;
    }

    public getPostProcessPopupFunc(): ((params: PostProcessPopupParams) => void) | undefined {
        return this.gridOptions.postProcessPopup;
    }

    public getDoesDataFlowerFunc(): ((data: any) => boolean) | undefined {
        return this.gridOptions.doesDataFlower;
    }

    public getPaginationNumberFormatterFunc(): ((params: PaginationNumberFormatterParams) => string) | undefined {
        return this.gridOptions.paginationNumberFormatter;
    }

    public getChildCountFunc() {
        return this.gridOptions.getChildCount;
    }

    public getDefaultGroupSortComparator() {
        return this.gridOptions.defaultGroupSortComparator;
    }

    public getIsFullWidthCellFunc(): ((rowNode: RowNode) => boolean) | undefined {
        return this.gridOptions.isFullWidthCell;
    }

    public getFullWidthCellRendererParams() {
        return this.gridOptions.fullWidthCellRendererParams;
    }

    public isEmbedFullWidthRows() {
        return isTrue(this.gridOptions.embedFullWidthRows) || isTrue(this.gridOptions.deprecatedEmbedFullWidthRows);
    }

    public getSuppressKeyboardEventFunc(): (params: SuppressKeyboardEventParams) => boolean {
        return this.gridOptions.suppressKeyboardEvent;
    }

    public getBusinessKeyForNodeFunc() {
        return this.gridOptions.getBusinessKeyForNode;
    }

    public getApi(): GridApi | undefined | null {
        return this.gridOptions.api;
    }

    public getColumnApi(): ColumnApi | undefined | null {
        return this.gridOptions.columnApi;
    }

    public isDeltaRowDataMode() {
        return isTrue(this.gridOptions.deltaRowDataMode);
    }

    public isDeltaColumnMode() {
        return isTrue(this.gridOptions.deltaColumnMode);
    }

    public isEnsureDomOrder() {
        return isTrue(this.gridOptions.ensureDomOrder);
    }

{'fraction_non_alphanumeric': 0.09370510166808718, 'fraction_numerical': 0.000876658955314745, 'mean_word_length': 3.1934034514449094, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 29, 'https://': 4, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2492173', 'n_tokens_mistral': 11327, 'n_tokens_neox': 11116, 'n_words': 2314}