text:
/**
 * ag-grid-community - Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components
 * @version v19.1.2
 * @link http://www.ag-grid.com/
 * @license MIT
 */
"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    }
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
var utils_1 = require("../utils");
var cellComp_1 = require("./cellComp");
var rowNode_1 = require("../entities/rowNode");
var gridOptionsWrapper_1 = require("../gridOptionsWrapper");
var column_1 = require("../entities/column");
var events_1 = require("../events");
var context_1 = require("../context/context");
var component_1 = require("../widgets/component");
var componentAnnotations_1 = require("../widgets/componentAnnotations");
var LoadingCellRenderer = /** @class */ (function (_super) {
    __extends(LoadingCellRenderer, _super);
    function LoadingCellRenderer() {
        return _super.call(this, LoadingCellRenderer.TEMPLATE) || this;
    }
    LoadingCellRenderer.prototype.init = function (params) {
        var eLoadingIcon = utils_1._.createIconNoSpan('groupLoading', this.gridOptionsWrapper, null);
        this.eLoadingIcon.appendChild(eLoadingIcon);
        var localeTextFunc = this.gridOptionsWrapper.getLocaleTextFunc();
        this.eLoadingText.innerText = localeTextFunc('loadingOoo', 'Loading');
    };
    LoadingCellRenderer.prototype.refresh = function (params) {
        return false;
    };
    LoadingCellRenderer.TEMPLATE = "
\n            \n            \n
";
    __decorate([
        context_1.Autowired('gridOptionsWrapper'),
        __metadata("design:type", gridOptionsWrapper_1.GridOptionsWrapper)
    ], LoadingCellRenderer.prototype, "gridOptionsWrapper", void 0);
    __decorate([
        componentAnnotations_1.RefSelector('eLoadingIcon'),
        __metadata("design:type", HTMLElement)
    ], LoadingCellRenderer.prototype, "eLoadingIcon", void 0);
    __decorate([
        componentAnnotations_1.RefSelector('eLoadingText'),
        __metadata("design:type", HTMLElement)
    ], LoadingCellRenderer.prototype, "eLoadingText", void 0);
    return LoadingCellRenderer;
}(component_1.Component));
exports.LoadingCellRenderer = LoadingCellRenderer;
var RowComp = /** @class */ (function (_super) {
    __extends(RowComp, _super);
    function RowComp(parentScope, bodyContainerComp, pinnedLeftContainerComp, pinnedRightContainerComp, fullWidthContainerComp, rowNode, beans, animateIn, useAnimationFrameForCreate, printLayout, embedFullWidth) {
        var _this = _super.call(this) || this;
        _this.eAllRowContainers = [];
        _this.active = true;
        _this.columnRefreshPending = false;
        _this.cellComps = {};
        // for animations, there are bits we want done in the next VM turn, to all DOM to update first.
        // instead of each row doing a setTimeout(func,0), we put the functions here and the rowRenderer
        // executes them all in one timeout
        _this.createSecondPassFuncs = [];
        // these get called before the row is destroyed - they set up the DOM for the remove animation (ie they
        // set the DOM up for the animation), then the delayedDestroyFunctions get called when the animation is
        // complete (ie removes from the dom).
        _this.removeFirstPassFuncs = [];
        // for animations, these functions get called 400ms after the row is cleared, called by the rowRenderer
        // so each row isn't setting up it's own timeout
        _this.removeSecondPassFuncs = [];
        _this.initialised = false;
        _this.parentScope = parentScope;
        _this.beans = beans;
        _this.bodyContainerComp = bodyContainerComp;
        _this.pinnedLeftContainerComp = pinnedLeftContainerComp;
        _this.pinnedRightContainerComp = pinnedRightContainerComp;
        _this.fullWidthContainerComp = fullWidthContainerComp;
        _this.rowNode = rowNode;
        _this.rowIsEven = _this.rowNode.rowIndex % 2 === 0;
        _this.paginationPage = _this.beans.paginationProxy.getCurrentPage();
        _this.useAnimationFrameForCreate = useAnimationFrameForCreate;
        _this.printLayout = printLayout;
        _this.embedFullWidth = embedFullWidth;
        _this.setAnimateFlags(animateIn);
        return _this;
    }
    RowComp.prototype.init = function () {
        var _this = this;
        this.rowFocused = this.beans.focusedCellController.isRowFocused(this.rowNode.rowIndex, this.rowNode.rowPinned);
        this.scope = this.createChildScopeOrNull(this.rowNode.data);
        this.setupRowContainers();
        this.addListeners();
        if (this.slideRowIn) {
            this.createSecondPassFuncs.push(function () {
                _this.onTopChanged();
            });
        }
        if (this.fadeRowIn) {
            this.createSecondPassFuncs.push(function () {
                _this.eAllRowContainers.forEach(function (eRow) { return utils_1._.removeCssClass(eRow, 'ag-opacity-zero'); });
            });
        }
    };
    RowComp.prototype.createTemplate = function (contents, extraCssClass) {
        if (extraCssClass === void 0) { extraCssClass = null; }
        var templateParts = [];
        var rowHeight = this.rowNode.rowHeight;
        var rowClasses = this.getInitialRowClasses(extraCssClass).join(' ');
        var rowIdSanitised = utils_1._.escape(this.rowNode.id);
        var userRowStyles = this.preProcessStylesFromGridOptions();
        var businessKey = this.getRowBusinessKey();
        var businessKeySanitised = utils_1._.escape(businessKey);
        var rowTopStyle = this.getInitialRowTopStyle();
        templateParts.push("<div");
        templateParts.push(" role=\"row\"");
        templateParts.push(" row-index=\"" + this.rowNode.getRowIndexString() + "\"");
        templateParts.push(rowIdSanitised ? " row-id=\"" + rowIdSanitised + "\"" : "");
        templateParts.push(businessKey ? " row-business-key=\"" + businessKeySanitised + "\"" : "");
        templateParts.push(" comp-id=\"" + this.getCompId() + "\"");
        templateParts.push(" class=\"" + rowClasses + "\"");
        templateParts.push(" style=\"height: " + rowHeight + "px; " + rowTopStyle + " " + userRowStyles + "\">");
        // add in the template for the cells
        templateParts.push(contents);
        templateParts.push("
");
        return templateParts.join('');
    };
    RowComp.prototype.getCellForCol = function (column) {
        var cellComp = this.cellComps[column.getColId()];
        if (cellComp) {
            return cellComp.getGui();
        }
        else {
            return null;
        }
    };
    RowComp.prototype.afterFlush = function () {
        if (!this.initialised) {
            this.initialised = true;
            this.executeProcessRowPostCreateFunc();
        }
    };
    RowComp.prototype.executeProcessRowPostCreateFunc = function () {
        var func = this.beans.gridOptionsWrapper.getProcessRowPostCreateFunc();
        if (func) {
            var params = {
                eRow: this.eBodyRow,
                ePinnedLeftRow: this.ePinnedLeftRow,
                ePinnedRightRow: this.ePinnedRightRow,
                node: this.rowNode,
                api: this.beans.gridOptionsWrapper.getApi(),
                rowIndex: this.rowNode.rowIndex,
                addRenderedRowListener: this.addEventListener.bind(this),
                columnApi: this.beans.gridOptionsWrapper.getColumnApi(),
                context: this.beans.gridOptionsWrapper.getContext()
            };
            func(params);
        }
    };
    RowComp.prototype.getInitialRowTopStyle = function () {
        // print layout uses normal flow layout for row positioning
        if (this.printLayout) {
            return '';
        }
        // if sliding in, we take the old row top. otherwise we just set the current row top.
        var pixels = this.slideRowIn ? this.roundRowTopToBounds(this.rowNode.oldRowTop) : this.rowNode.rowTop;
        var afterPaginationPixels = this.applyPaginationOffset(pixels);
        var afterScalingPixels = this.beans.heightScaler.getRealPixelPosition(afterPaginationPixels);
        if (this.beans.gridOptionsWrapper.isSuppressRowTransform()) {
            return "top: " + afterScalingPixels + "px; ";
        }
        else {
            return "transform: translateY(" + afterScalingPixels + "px); ";
        }
    };
    RowComp.prototype.getRowBusinessKey = function () {
        if (typeof this.beans.gridOptionsWrapper.getBusinessKeyForNodeFunc() === 'function') {
            var businessKey = this.beans.gridOptionsWrapper.getBusinessKeyForNodeFunc()(this.rowNode);
            return businessKey;
        }
    };
    RowComp.prototype.lazyCreateCells = function (cols, eRow) {
        if (this.active) {
            var cellTemplatesAndComps = this.createCells(cols);
            eRow.innerHTML = cellTemplatesAndComps.template;
            this.callAfterRowAttachedOnCells(cellTemplatesAndComps.cellComps, eRow);
        }
    };
    RowComp.prototype.createRowContainer = function (rowContainerComp, cols, callback) {
        var _this = this;
        var cellTemplatesAndComps;
        if (this.useAnimationFrameForCreate) {
            cellTemplatesAndComps = { cellComps: [], template: '' };
        }
        else {
            cellTemplatesAndComps = this.createCells(cols);
        }
        var rowTemplate = this.createTemplate(cellTemplatesAndComps.template);
        rowContainerComp.appendRowTemplate(rowTemplate, function () {
            var eRow = rowContainerComp.getRowElement(_this.getCompId());
            _this.afterRowAttached(rowContainerComp, eRow);
            callback(eRow);
            if (_this.useAnimationFrameForCreate) {
                _this.beans.taskQueue.addP1Task(_this.lazyCreateCells.bind(_this, cols, eRow));
            }
            else {
                _this.callAfterRowAttachedOnCells(cellTemplatesAndComps.cellComps, eRow);
            }
        });
    };
    RowComp.prototype.createChildScopeOrNull = function (data) {
        if (this.beans.gridOptionsWrapper.isAngularCompileRows()) {
            var newChildScope_1 = this.parentScope.$new();
            newChildScope_1.data = data;
            newChildScope_1.rowNode = this.rowNode;
            newChildScope_1.context = this.beans.gridOptionsWrapper.getContext();
            this.addDestroyFunc(function () {
                newChildScope_1.$destroy();
                newChildScope_1.data = null;
                newChildScope_1.rowNode = null;
                newChildScope_1.context = null;
            });
            return newChildScope_1;
        }
        else {
            return null;
        }
    };
    RowComp.prototype.setupRowContainers = function () {
        var isFullWidthCellFunc = this.beans.gridOptionsWrapper.getIsFullWidthCellFunc();
        var isFullWidthCell = isFullWidthCellFunc ? isFullWidthCellFunc(this.rowNode) : false;
        var isDetailCell = this.beans.doingMasterDetail && this.rowNode.detail;
        var isGroupSpanningRow = this.rowNode.group && this.beans.gridOptionsWrapper.isGroupUseEntireRow();
        if (this.rowNode.stub) {
            this.createFullWidthRows(RowComp.LOADING_CELL_RENDERER, RowComp.LOADING_CELL_RENDERER_COMP_NAME);
        }
        else if (isDetailCell) {
            this.createFullWidthRows(RowComp.DETAIL_CELL_RENDERER, RowComp.DETAIL_CELL_RENDERER_COMP_NAME);
        }
        else if (isFullWidthCell) {
            this.createFullWidthRows(RowComp.FULL_WIDTH_CELL_RENDERER, null);
        }
        else if (isGroupSpanningRow) {
            this.createFullWidthRows(RowComp.GROUP_ROW_RENDERER, RowComp.GROUP_ROW_RENDERER_COMP_NAME);
        }
        else {
            this.setupNormalRowContainers();
        }
    };
    RowComp.prototype.setupNormalRowContainers = function () {
        var _this = this;
        var centerCols;
        var leftCols;
        var rightCols;
        if (this.printLayout) {
            centerCols = this.beans.columnController.getAllDisplayedColumns();
            leftCols = [];
            rightCols = [];
        }
        else {
            centerCols = this.beans.columnController.getAllDisplayedCenterVirtualColumnsForRow(this.rowNode);
            leftCols = this.beans.columnController.getDisplayedLeftColumnsForRow(this.rowNode);
            rightCols = this.beans.columnController.getDisplayedRightColumnsForRow(this.rowNode);
        }
        this.createRowContainer(this.bodyContainerComp, centerCols, function (eRow) { return _this.eBodyRow = eRow; });
        this.createRowContainer(this.pinnedRightContainerComp, rightCols, function (eRow) { return _this.ePinnedRightRow = eRow; });
        this.createRowContainer(this.pinnedLeftContainerComp, leftCols, function (eRow) { return _this.ePinnedLeftRow = eRow; });
    };
    RowComp.prototype.createFullWidthRows = function (type, name) {
        var _this = this;
        this.fullWidthRow = true;
        if (this.embedFullWidth) {
            this.createFullWidthRowContainer(this.bodyContainerComp, null, null, type, name, function (eRow) {
                _this.eFullWidthRowBody = eRow;
            }, function (cellRenderer) {
                _this.fullWidthRowComponentBody = cellRenderer;
            });
            // printLayout doesn't put components into the pinned sections
            if (!this.printLayout) {
                this.createFullWidthRowContainer(this.pinnedLeftContainerComp, column_1.Column.PINNED_LEFT, 'ag-cell-last-left-pinned', type, name, function (eRow) {
                    _this.eFullWidthRowLeft = eRow;
                }, function (cellRenderer) {
                    _this.fullWidthRowComponentLeft = cellRenderer;
                });
                this.createFullWidthRowContainer(this.pinnedRightContainerComp, column_1.Column.PINNED_RIGHT, 'ag-cell-first-right-pinned', type, name, function (eRow) {
                    _this.eFullWidthRowRight = eRow;
                }, function (cellRenderer) {
                    _this.fullWidthRowComponentRight = cellRenderer;
                });
            }
        }
        else {
            // otherwise we add to the fullWidth container as normal
            // let previousFullWidth = ensureDomOrder ? this.lastPlacedElements.eFullWidth : null;
            this.createFullWidthRowContainer(this.fullWidthContainerComp, null, null, type, name, function (eRow) {
                _this.eFullWidthRow = eRow;
            }, function (cellRenderer) {
                _this.fullWidthRowComponent = cellRenderer;
            });
        }
    };
    RowComp.prototype.setAnimateFlags = function (animateIn) {
        if (animateIn) {
            var oldRowTopExists = utils_1._.exists(this.rowNode.oldRowTop);
            // if the row had a previous position, we slide it in (animate row top)
            this.slideRowIn = oldRowTopExists;
            // if the row had no previous position, we fade it in (animate
            this.fadeRowIn = !oldRowTopExists;
        }
        else {
            this.slideRowIn = false;
            this.fadeRowIn = false;
        }
    };
    RowComp.prototype.isEditing = function () {
        return this.editingRow;
    };
    RowComp.prototype.stopRowEditing = function (cancel) {
        this.stopEditing(cancel);
    };
    RowComp.prototype.isFullWidth = function () {
        return this.fullWidthRow;
    };
    RowComp.prototype.addListeners = function () {
        this.addDestroyableEventListener(this.rowNode, rowNode_1.RowNode.EVENT_HEIGHT_CHANGED, this.onRowHeightChanged.bind(this));
        this.addDestroyableEventListener(this.rowNode, rowNode_1.RowNode.EVENT_ROW_SELECTED, this.onRowSelected.bind(this));
        this.addDestroyableEventListener(this.rowNode, rowNode_1.RowNode.EVENT_ROW_INDEX_CHANGED, this.onRowIndexChanged.bind(this));
        this.addDestroyableEventListener(this.rowNode, rowNode_1.RowNode.EVENT_TOP_CHANGED, this.onTopChanged.bind(this));
        this.addDestroyableEventListener(this.rowNode, rowNode_1.RowNode.EVENT_EXPANDED_CHANGED, this.onExpandedChanged.bind(this));
        this.addDestroyableEventListener(this.rowNode, rowNode_1.RowNode.EVENT_DATA_CHANGED, this.onRowNodeDataChanged.bind(this));
        this.addDestroyableEventListener(this.rowNode, rowNode_1.RowNode.EVENT_CELL_CHANGED, this.onRowNodeCellChanged.bind(this));
        this.addDestroyableEventListener(this.rowNode, rowNode_1.RowNode.EVENT_DRAGGING_CHANGED, this.onRowNodeDraggingChanged.bind(this));
        var eventService = this.beans.eventService;
        this.addDestroyableEventListener(eventService, events_1.Events.EVENT_HEIGHT_SCALE_CHANGED, this.onTopChanged.bind(this));
        this.addDestroyableEventListener(eventService, events_1.Events.EVENT_DISPLAYED_COLUMNS_CHANGED, this.onDisplayedColumnsChanged.bind(this));
        this.addDestroyableEventListener(eventService, events_1.Events.EVENT_VIRTUAL_COLUMNS_CHANGED, this.onVirtualColumnsChanged.bind(this));
        this.addDestroyableEventListener(eventService, events_1.Events.EVENT_COLUMN_RESIZED, this.onColumnResized.bind(this));
        this.addDestroyableEventListener(eventService, events_1.Events.EVENT_CELL_FOCUSED, this.onCellFocusChanged.bind(this));
        this.addDestroyableEventListener(eventService, events_1.Events.EVENT_PAGINATION_CHANGED, this.onPaginationChanged.bind(this));
        this.addDestroyableEventListener(eventService, events_1.Events.EVENT_GRID_COLUMNS_CHANGED, this.onGridColumnsChanged.bind(this));
        this.addDestroyableEventListener(eventService, events_1.Events.EVENT_MODEL_UPDATED, this.onModelUpdated.bind(this));
    };
    // when grid columns change, then all cells should be cleaned out,
    // as the new columns could have same id as the previous columns and may conflict
    RowComp.prototype.onGridColumnsChanged = function () {
        var allRenderedCellIds = Object.keys(this.cellComps);
        this.removeRenderedCells(allRenderedCellIds);
    };
    RowComp.prototype.onRowNodeDataChanged = function (event) {
        // if this is an update, we want to refresh, as this will allow the user to put in a transition
        // into the cellRenderer refresh method. otherwise this might be completely new data, in which case
        // we will want to completely replace the cells
        this.forEachCellComp(function (cellComp) {
            return cellComp.refreshCell({
                suppressFlash: !event.update,
                newData: !event.update
            });
        });
        // check for selected also, as this could be after lazy loading of the row data, in which case
        // the id might of just gotten set inside the row and the row selected state may of changed
        // as a result. this is what happens when selected rows are loaded in virtual pagination.
        // - niall note - since moving to the stub component, this may no longer be true, as replacing
        // the stub component now replaces the entire row
        this.onRowSelected();
        // as data has changed, then the style and class needs to be recomputed
        this.postProcessCss();
    };
    RowComp.prototype.onRowNodeCellChanged = function (event) {
        // as data has changed, then the style and class needs to be recomputed
        this.postProcessCss();
    };
    RowComp.prototype.postProcessCss = function () {
        this.postProcessStylesFromGridOptions();
        this.postProcessClassesFromGridOptions();
        this.postProcessRowClassRules();
        this.postProcessRowDragging();
    };
    RowComp.prototype.onRowNodeDraggingChanged = function () {
        this.postProcessRowDragging();
    };
    RowComp.prototype.postProcessRowDragging = function () {
        var dragging = this.rowNode.dragging;
        this.eAllRowContainers.forEach(function (row) { return utils_1._.addOrRemoveCssClass(row, 'ag-row-dragging', dragging); });
    };
    RowComp.prototype.onExpandedChanged = function () {
        if (this.rowNode.group && !this.rowNode.footer) {
            var expanded_1 = this.rowNode.expanded;
            this.eAllRowContainers.forEach(function (row) { return utils_1._.addOrRemoveCssClass(row, 'ag-row-group-expanded', expanded_1); });
            this.eAllRowContainers.forEach(function (row) { return utils_1._.addOrRemoveCssClass(row, 'ag-row-group-contracted', !expanded_1); });
        }
    };
    RowComp.prototype.onDisplayedColumnsChanged = function () {
        if (!this.fullWidthRow) {
            this.refreshCells();
        }
    };
    RowComp.prototype.destroyFullWidthComponents = function () {
        if (this.fullWidthRowComponent) {
            if (this.fullWidthRowComponent.destroy) {
                this.fullWidthRowComponent.destroy();
            }
            this.fullWidthRowComponent = null;
        }
        if (this.fullWidthRowComponentBody) {
            if (this.fullWidthRowComponentBody.destroy) {
                this.fullWidthRowComponentBody.destroy();
            }
            this.fullWidthRowComponent = null;
        }
        if (this.fullWidthRowComponentLeft) {
            if (this.fullWidthRowComponentLeft.destroy) {
                this.fullWidthRowComponentLeft.destroy();
            }
            this.fullWidthRowComponentLeft = null;
        }
        if (this.fullWidthRowComponentRight) {
            if (this.fullWidthRowComponentRight.destroy) {
                this.fullWidthRowComponentRight.destroy();
            }
            this.fullWidthRowComponent = null;
        }
    };
    RowComp.prototype.getContainerForCell = function (pinnedType) {
        switch (pinnedType) {
            case column_1.Column.PINNED_LEFT: return this.ePinnedLeftRow;
            case column_1.Column.PINNED_RIGHT: return this.ePinnedRightRow;
            default: return this.eBodyRow;
        }
    };
    RowComp.prototype.onVirtualColumnsChanged = function () {
        if (!this.fullWidthRow) {
            this.refreshCells();
        }
    };
    RowComp.prototype.onColumnResized = function () {
        if (!this.fullWidthRow) {
            this.refreshCells();
        }
    };
    RowComp.prototype.refreshCells = function () {
        var suppressAnimationFrame = this.beans.gridOptionsWrapper.isSuppressAnimationFrame();
        var skipAnimationFrame = suppressAnimationFrame || this.printLayout;
        if (skipAnimationFrame) {
            this.refreshCellsInAnimationFrame();
        }
        else {
            if (this.columnRefreshPending) {
                return;
            }
            this.beans.taskQueue.addP1Task(this.refreshCellsInAnimationFrame.bind(this));
        }
    };
    RowComp.prototype.refreshCellsInAnimationFrame = function () {
        if (!this.active) {
            return;
        }
        this.columnRefreshPending = false;
        var centerCols;
        var leftCols;
        var rightCols;
        if (this.printLayout) {
            centerCols = this.beans.columnController.getAllDisplayedColumns();
            leftCols = [];
            rightCols = [];
        }
        else {
            centerCols = this.beans.columnController.getAllDisplayedCenterVirtualColumnsForRow(this.rowNode);
            leftCols = this.beans.columnController.getDisplayedLeftColumnsForRow(this.rowNode);
            rightCols = this.beans.columnController.getDisplayedRightColumnsForRow(this.rowNode);
        }
        this.insertCellsIntoContainer(this.eBodyRow, centerCols);
        this.insertCellsIntoContainer(this.ePinnedLeftRow, leftCols);
        this.insertCellsIntoContainer(this.ePinnedRightRow, rightCols);
        var colIdsToRemove = Object.keys(this.cellComps);
        centerCols.forEach(function (col) { return utils_1._.removeFromArray(colIdsToRemove, col.getId()); });
        leftCols.forEach(function (col) { return utils_1._.removeFromArray(colIdsToRemove, col.getId()); });
        rightCols.forEach(function (col) { return utils_1._.removeFromArray(colIdsToRemove, col.getId()); });
        // we never remove editing cells, as this would cause the cells to loose their values while editing
        // as the grid is scrolling horizontally.
        colIdsToRemove = utils_1._.filter(colIdsToRemove, this.isCellEligibleToBeRemoved.bind(this));
        // remove old cells from gui, but we don't destroy them, we might use them again
        this.removeRenderedCells(colIdsToRemove);
    };
    RowComp.prototype.removeRenderedCells = function (colIds) {
        var _this = this;
        colIds.forEach(function (key) {
            var cellComp = _this.cellComps[key];
            // could be old reference, ie removed cell
            if (utils_1._.missing(cellComp)) {
                return;
            }
            cellComp.detach();
            cellComp.destroy();
            _this.cellComps[key] = null;
        });
    };
    RowComp.prototype.isCellEligibleToBeRemoved = function (indexStr) {
        var displayedColumns = this.beans.columnController.getAllDisplayedColumns();
        var REMOVE_CELL = true;
        var KEEP_CELL = false;
        var renderedCell = this.cellComps[indexStr];
        if (!renderedCell) {
            return REMOVE_CELL;
        }
        // always remove the cell if it's in the wrong pinned location
        if (this.isCellInWrongRow(renderedCell)) {
            return REMOVE_CELL;
        }
        // we want to try and keep editing and focused cells
        var editing = renderedCell.isEditing();
        var focused = this.beans.focusedCellController.isCellFocused(renderedCell.getGridCell());
        var mightWantToKeepCell = editing || focused;
        if (mightWantToKeepCell) {
            var column = renderedCell.getColumn();
            var cellStillDisplayed = displayedColumns.indexOf(column) >= 0;
            return cellStillDisplayed ? KEEP_CELL : REMOVE_CELL;
        }
        else {
            return REMOVE_CELL;
        }
    };
    RowComp.prototype.ensureCellInCorrectContainer = function (cellComp) {
        // for print layout, we always put cells into centre, otherwise we put in correct pinned section
        if (this.printLayout) {
            return;
        }
        var element = cellComp.getGui();
        var column = cellComp.getColumn();
        var pinnedType = column.getPinned();
        var eContainer = this.getContainerForCell(pinnedType);
        // if in wrong container, remove it
        var eOldContainer = cellComp.getParentRow();
        var inWrongRow = eOldContainer !== eContainer;
        if (inWrongRow) {
            // take out from old row
            if (eOldContainer) {
                eOldContainer.removeChild(element);
            }
            eContainer.appendChild(element);
            cellComp.setParentRow(eContainer);
        }
    };
    RowComp.prototype.isCellInWrongRow = function (cellComp) {
        var column = cellComp.getColumn();
        var rowWeWant = this.getContainerForCell(column.getPinned());
        // if in wrong container, remove it
        var oldRow = cellComp.getParentRow();
        return oldRow !== rowWeWant;
    };
    RowComp.prototype.insertCellsIntoContainer = function (eRow, cols) {
        var _this = this;
        if (!eRow) {
            return;
        }
        var cellTemplates = [];
        var newCellComps = [];
        cols.forEach(function (col) {
            var colId = col.getId();
            var oldCell = _this.cellComps[colId];
            if (oldCell) {
                _this.ensureCellInCorrectContainer(oldCell);
            }
            else {
                _this.createNewCell(col, eRow, cellTemplates, newCellComps);
            }
        });
        if (cellTemplates.length > 0) {
            utils_1._.appendHtml(eRow, cellTemplates.join(''));
            this.callAfterRowAttachedOnCells(newCellComps, eRow);
        }
    };
    RowComp.prototype.addDomData = function (eRowContainer) {
        var gow = this.beans.gridOptionsWrapper;
        gow.setDomData(eRowContainer, RowComp.DOM_DATA_KEY_RENDERED_ROW, this);
        this.addDestroyFunc(function () {
            gow.setDomData(eRowContainer, RowComp.DOM_DATA_KEY_RENDERED_ROW, null);
        });
    };
    RowComp.prototype.createNewCell = function (col, eContainer, cellTemplates, newCellComps) {
        var newCellComp = new cellComp_1.CellComp(this.scope, this.beans, col, this.rowNode, this, false, this.printLayout);
        var cellTemplate = newCellComp.getCreateTemplate();
        cellTemplates.push(cellTemplate);
        newCellComps.push(newCellComp);
        this.cellComps[col.getId()] = newCellComp;
        newCellComp.setParentRow(eContainer);
    };
    RowComp.prototype.onMouseEvent = function (eventName, mouseEvent) {
        switch (eventName) {
            case 'dblclick':
                this.onRowDblClick(mouseEvent);
                break;
            case 'click':
                this.onRowClick(mouseEvent);
                break;
        }
    };
    RowComp.prototype.createRowEvent = function (type, domEvent) {
        return {
            type: type,
            node: this.rowNode,
            data: this.rowNode.data,
            rowIndex: this.rowNode.rowIndex,
            rowPinned: this.rowNode.rowPinned,
            context: this.beans.gridOptionsWrapper.getContext(),
            api: this.beans.gridOptionsWrapper.getApi(),
            columnApi: this.beans.gridOptionsWrapper.getColumnApi(),
            event: domEvent
        };
    };
    RowComp.prototype.createRowEventWithSource = function (type, domEvent) {
        var event = this.createRowEvent(type, domEvent);
        // when first developing this, we included the rowComp in the event.
        // this seems very weird. so when introducing the event types, i left the 'source'
        // out of the type, and just include the source in the two places where this event
        // was fired (rowClicked and rowDoubleClicked). it doesn't make sense for any
        // users to be using this, as the rowComp isn't an object we expose, so would be
        // very surprising if a user was using it.
        event.source = this;
        return event;
    };
    RowComp.prototype.onRowDblClick = function (mouseEvent) {
        if (utils_1._.isStopPropagationForAgGrid(mouseEvent)) {
            return;
        }
        var agEvent = this.createRowEventWithSource(events_1.Events.EVENT_ROW_DOUBLE_CLICKED, mouseEvent);
        this.beans.eventService.dispatchEvent(agEvent);
    };
    RowComp.prototype.onRowClick = function (mouseEvent) {
        var stop = utils_1._.isStopPropagationForAgGrid(mouseEvent);
        if (stop) {
            return;
        }
        var agEvent = this.createRowEventWithSource(events_1.Events.EVENT_ROW_CLICKED, mouseEvent);
        this.beans.eventService.dispatchEvent(agEvent);
        // ctrlKey for windows, metaKey for Apple
        var multiSelectKeyPressed = mouseEvent.ctrlKey || mouseEvent.metaKey;
        var shiftKeyPressed = mouseEvent.shiftKey;
        // we do not allow selecting groups by clicking (as the click here expands the group), or if it's a detail row,
        // so return if it's a group row
        if (this.rowNode.group) {
            return;
        }
        // this is needed so we don't unselect other rows when we click this row, eg if this row is not selectable,
        // and we click it, the selection should not change (ie any currently selected row should stay selected)
        if (!this.rowNode.selectable) {
            return;
        }
        // we also don't allow selection of pinned rows
        if (this.rowNode.rowPinned) {
            return;
        }
        // if no selection method enabled, do nothing
        if (!this.beans.gridOptionsWrapper.isRowSelection()) {
            return;
        }
        // if click selection suppressed, do nothing
        if (this.beans.gridOptionsWrapper.isSuppressRowClickSelection()) {
            return;
        }
        var multiSelectOnClick = this.beans.gridOptionsWrapper.isRowMultiSelectWithClick();
        var rowDeselectionWithCtrl = this.beans.gridOptionsWrapper.isRowDeselection();
        if (this.rowNode.isSelected()) {
            if (multiSelectOnClick) {
                this.rowNode.setSelectedParams({ newValue: false });
            }
            else if (multiSelectKeyPressed) {
                if (rowDeselectionWithCtrl) {
                    this.rowNode.setSelectedParams({ newValue: false });
                }
            }
            else {
                // selected with no multi key, must make sure anything else is unselected
                this.rowNode.setSelectedParams({ newValue: true, clearSelection: true });
            }
        }
        else {
            var clearSelection = multiSelectOnClick ? false : !multiSelectKeyPressed;
            this.rowNode.setSelectedParams({ newValue: true, clearSelection: clearSelection, rangeSelect: shiftKeyPressed });
        }
    };
    RowComp.prototype.createFullWidthRowContainer = function (rowContainerComp, pinned, extraCssClass, cellRendererType, cellRendererName, eRowCallback, cellRendererCallback) {
        var _this = this;
        var rowTemplate = this.createTemplate('', extraCssClass);
        rowContainerComp.appendRowTemplate(rowTemplate, function () {
            var eRow = rowContainerComp.getRowElement(_this.getCompId());
            var params = _this.createFullWidthParams(eRow, pinned);
            var callback = function (cellRenderer) {
                if (_this.isAlive()) {
                    var gui = cellRenderer.getGui();
                    eRow.appendChild(gui);
                    cellRendererCallback(cellRenderer);
                }
                else {
                    if (cellRenderer.destroy) {
                        cellRenderer.destroy();
                    }
                }
            };
            var res = _this.beans.componentResolver.createAgGridComponent(null, params, cellRendererType, params, cellRendererName);
            if (!res) {
                console.error('ag-Grid: fullWidthCellRenderer not defined');
                return;
            }
            res.then(callback);
            _this.afterRowAttached(rowContainerComp, eRow);
            eRowCallback(eRow);
            _this.angular1Compile(eRow);
        });
    };
    RowComp.prototype.angular1Compile = function (element) {
        if (this.scope) {
            this.beans.$compile(element)(this.scope);
        }
    };
    RowComp.prototype.createFullWidthParams = function (eRow, pinned) {
        var params = {
            fullWidth: true,
            data: this.rowNode.data,
            node: this.rowNode,
            value: this.rowNode.key,
            $scope: this.scope,
            rowIndex: this.rowNode.rowIndex,
            api: this.beans.gridOptionsWrapper.getApi(),
            columnApi: this.beans.gridOptionsWrapper.getColumnApi(),
            context: this.beans.gridOptionsWrapper.getContext(),
            // these need to be taken out, as part of 'afterAttached' now
            eGridCell: eRow,
            eParentOfValue: eRow,
            pinned: pinned,
            addRenderedRowListener: this.addEventListener.bind(this)
        };
        return params;
    };
    RowComp.prototype.getInitialRowClasses = function (extraCssClass) {
        var classes = [];
        if (utils_1._.exists(extraCssClass)) {
            classes.push(extraCssClass);
        }
        classes.push('ag-row');
        classes.push(this.rowFocused ? 'ag-row-focus' : 'ag-row-no-focus');
        if (this.fadeRowIn) {
            classes.push('ag-opacity-zero');
        }
        if (this.rowIsEven) {
            classes.push('ag-row-even');
        }
        else {
            classes.push('ag-row-odd');
        }
        if (this.rowNode.isSelected()) {
            classes.push('ag-row-selected');
        }
        if (this.rowNode.group) {
            classes.push('ag-row-group');
            // if a group, put the level of the group in
            classes.push('ag-row-level-' + this.rowNode.level);
            if (this.rowNode.footer) {
                classes.push('ag-row-footer');
            }
        }
        else {
            // if a leaf, and a parent exists, put a level of the parent, else put level of 0 for top level item
            if (this.rowNode.parent) {
                classes.push('ag-row-level-' + (this.rowNode.parent.level + 1));
            }
            else {
                classes.push('ag-row-level-0');
            }
        }
        if (this.rowNode.stub) {
            classes.push('ag-row-stub');
        }
        if (this.fullWidthRow) {
            classes.push('ag-full-width-row');
        }
        if (this.rowNode.group && !this.rowNode.footer) {
            classes.push(this.rowNode.expanded ? 'ag-row-group-expanded' : 'ag-row-group-contracted');
        }
        if (this.rowNode.dragging) {
            classes.push('ag-row-dragging');
        }
        utils_1._.pushAll(classes, this.processClassesFromGridOptions());
        utils_1._.pushAll(classes, this.preProcessRowClassRules());
        // we use absolute position unless we are doing print layout
        classes.push(this.printLayout ? 'ag-row-position-relative' : 'ag-row-position-absolute');
        this.firstRowOnPage = this.isFirstRowOnPage();
        this.lastRowOnPage = this.isLastRowOnPage();
        if (this.firstRowOnPage) {
            classes.push('ag-row-first');
        }
        if (this.lastRowOnPage) {
            classes.push('ag-row-last');
        }
        return classes;
    };
    RowComp.prototype.isFirstRowOnPage = function () {
        return this.rowNode.rowIndex === this.beans.paginationProxy.getPageFirstRow();
    };
    RowComp.prototype.isLastRowOnPage = function () {
        return this.rowNode.rowIndex === this.beans.paginationProxy.getPageLastRow();
    };
    RowComp.prototype.onModelUpdated = function () {
        var newFirst = this.isFirstRowOnPage();
        var newLast = this.isLastRowOnPage();
        if (this.firstRowOnPage !== newFirst) {
            this.firstRowOnPage = newFirst;
            this.eAllRowContainers.forEach(function (row) { return utils_1._.addOrRemoveCssClass(row, 'ag-row-first', newFirst); });
        }
        if (this.lastRowOnPage !== newLast) {
            this.lastRowOnPage = newLast;
            this.eAllRowContainers.forEach(function (row) { return utils_1._.addOrRemoveCssClass(row, 'ag-row-last', newLast); });
        }
    };
    RowComp.prototype.preProcessRowClassRules = function () {
        var res = [];
        this.processRowClassRules(function (className) {
            res.push(className);
        }, function (className) {
            // not catered for, if creating, no need
            // to remove class as it was never there
        });
        return res;
    };
    RowComp.prototype.processRowClassRules = function (onApplicableClass, onNotApplicableClass) {
        this.beans.stylingService.processClassRules(this.beans.gridOptionsWrapper.rowClassRules(), {
            value: undefined,
            colDef: undefined,
            data: this.rowNode.data,
            node: this.rowNode,
            rowIndex: this.rowNode.rowIndex,
            api: this.beans.gridOptionsWrapper.getApi(),
            $scope: this.scope,
            context: this.beans.gridOptionsWrapper.getContext()
        }, onApplicableClass, onNotApplicableClass);
    };
    RowComp.prototype.stopEditing = function (cancel) {
        if (cancel === void 0) { cancel = false; }
        this.forEachCellComp(function (renderedCell) {
            renderedCell.stopEditing(cancel);
        });
        if (this.editingRow) {
            if (!cancel) {
                var event_1 = this.createRowEvent(events_1.Events.EVENT_ROW_VALUE_CHANGED);
                this.beans.eventService.dispatchEvent(event_1);
            }
            this.setEditingRow(false);
        }
    };
    RowComp.prototype.setEditingRow = function (value) {
        this.editingRow = value;
        this.eAllRowContainers.forEach(function (row) { return utils_1._.addOrRemoveCssClass(row, 'ag-row-editing', value); });
        var event = value ?
            this.createRowEvent(events_1.Events.EVENT_ROW_EDITING_STARTED)
            : this.createRowEvent(events_1.Events.EVENT_ROW_EDITING_STOPPED);
        this.beans.eventService.dispatchEvent(event);
    };
    RowComp.prototype.startRowEditing = function (keyPress, charPress, sourceRenderedCell) {
        if (keyPress === void 0) { keyPress = null; }
        if (charPress === void 0) { charPress = null; }
        if (sourceRenderedCell === void 0) { sourceRenderedCell = null; }
        // don't do it if already editing
        if (this.editingRow) {
            return;
        }
        this.forEachCellComp(function (renderedCell) {
            var cellStartedEdit = renderedCell === sourceRenderedCell;
            if (cellStartedEdit) {
                renderedCell.startEditingIfEnabled(keyPress, charPress, cellStartedEdit);
            }
            else {
                renderedCell.startEditingIfEnabled(null, null, cellStartedEdit);
            }
        });
        this.setEditingRow(true);
    };
    RowComp.prototype.forEachCellComp = function (callback) {
        utils_1._.iterateObject(this.cellComps, function (key, cellComp) {
            if (cellComp) {
                callback(cellComp);
            }
        });
    };
    RowComp.prototype.postProcessClassesFromGridOptions = function () {
        var _this = this;
        var cssClasses = this.processClassesFromGridOptions();
        if (cssClasses) {
            cssClasses.forEach(function (classStr) {
                _this.eAllRowContainers.forEach(function (row) { return utils_1._.addCssClass(row, classStr); });
            });
        }
    };
    RowComp.prototype.postProcessRowClassRules = function () {
        var _this = this;
        this.processRowClassRules(function (className) {
            _this.eAllRowContainers.forEach(function (row) { return utils_1._.addCssClass(row, className); });
        }, function (className) {
            _this.eAllRowContainers.forEach(function (row) { return utils_1._.removeCssClass(row, className); });
        });
    };
    RowComp.prototype.processClassesFromGridOptions = function () {
        var res = [];
        var process = function (rowCls) {
            if (typeof rowCls === 'string') {
                res.push(rowCls);
            }
            else if (Array.isArray(rowCls)) {
                rowCls.forEach(function (e) { return res.push(e); });
            }
        };
        // part 1 - rowClass
        var rowClass = this.beans.gridOptionsWrapper.getRowClass();
        if (rowClass) {
            if (typeof rowClass === 'function') {
                console.warn('ag-Grid: rowClass should not be a function, please use getRowClass instead');
                return;
            }
            process(rowClass);
        }
        // part 2 - rowClassFunc
        var rowClassFunc = this.beans.gridOptionsWrapper.getRowClassFunc();
        if (rowClassFunc) {
            var params = {
                node: this.rowNode,
                data: this.rowNode.data,
                rowIndex: this.rowNode.rowIndex,
                context: this.beans.gridOptionsWrapper.getContext(),
                api: this.beans.gridOptionsWrapper.getApi()
            };
            var rowClassFuncResult = rowClassFunc(params);
            process(rowClassFuncResult);
        }
        return res;
    };
    RowComp.prototype.preProcessStylesFromGridOptions = function () {
        var rowStyles = this.processStylesFromGridOptions();
        return utils_1._.cssStyleObjectToMarkup(rowStyles);
    };
    RowComp.prototype.postProcessStylesFromGridOptions = function () {
        var rowStyles = this.processStylesFromGridOptions();
        this.eAllRowContainers.forEach(function (row) { return utils_1._.addStylesToElement(row, rowStyles); });
    };
    RowComp.prototype.processStylesFromGridOptions = function () {
        // part 1 - rowStyle
        var rowStyle = this.beans.gridOptionsWrapper.getRowStyle();
        if (rowStyle && typeof rowStyle === 'function') {
            console.warn('ag-Grid: rowStyle should be an object of key/value styles, not be a function, use getRowStyle() instead');
            return;
        }
        // part 1 - rowStyleFunc
        var rowStyleFunc = this.beans.gridOptionsWrapper.getRowStyleFunc();
        var rowStyleFuncResult;
        if (rowStyleFunc) {
            var params = {
                data: this.rowNode.data,
                node: this.rowNode,
                api: this.beans.gridOptionsWrapper.getApi(),
                context: this.beans.gridOptionsWrapper.getContext(),
                $scope: this.scope
            };
            rowStyleFuncResult = rowStyleFunc(params);
        }
        return utils_1._.assign({}, rowStyle, rowStyleFuncResult);
    };
    RowComp.prototype.createCells = function (cols) {
        var _this = this;
        var templateParts = [];
        var newCellComps = [];
        cols.forEach(function (col) {
            var newCellComp = new cellComp_1.CellComp(_this.scope, _this.beans, col, _this.rowNode, _this, false, _this.printLayout);
            var cellTemplate = newCellComp.getCreateTemplate();
            templateParts.push(cellTemplate);
            newCellComps.push(newCellComp);
            _this.cellComps[col.getId()] = newCellComp;
        });
        var templateAndComps = {
            template: templateParts.join(''),
            cellComps: newCellComps
        };
        return templateAndComps;
    };
    RowComp.prototype.onRowSelected = function () {
        var selected = this.rowNode.isSelected();
        this.eAllRowContainers.forEach(function (row) { return utils_1._.addOrRemoveCssClass(row, 'ag-row-selected', selected); });
    };
    // called:
    // + after row created for first time
    // + after horizontal scroll, so new cells due to column virtualisation
    RowComp.prototype.callAfterRowAttachedOnCells = function (newCellComps, eRow) {
        var _this = this;
        newCellComps.forEach(function (cellComp) {
            cellComp.setParentRow(eRow);
            cellComp.afterAttached();
            // if we are editing the row, then the cell needs to turn
            // into edit mode
            if (_this.editingRow) {
                cellComp.startEditingIfEnabled();
            }
        });
    };
    RowComp.prototype.afterRowAttached = function (rowContainerComp, eRow) {
        var _this = this;
        this.addDomData(eRow);
        this.removeSecondPassFuncs.push(function () {
            // console.log(eRow);
            rowContainerComp.removeRowElement(eRow);
        });
        this.removeFirstPassFuncs.push(function () {
            if (utils_1._.exists(_this.rowNode.rowTop)) {
                // the row top is updated anyway, however we set it here again
                // to something more reasonable for the animation - ie if the
                // row top is 10000px away, the row will flash out, so this
                // gives it a rounded value, so row animates out more slowly
                var rowTop = _this.roundRowTopToBounds(_this.rowNode.rowTop);
                _this.setRowTop(rowTop);
            }
            else {
                utils_1._.addCssClass(eRow, 'ag-opacity-zero');
            }
        });
        this.eAllRowContainers.push(eRow);
        // adding hover functionality adds listener to this row, so we
        // do it lazily in an animation frame
        if (this.useAnimationFrameForCreate) {
            this.beans.taskQueue.addP1Task(this.addHoverFunctionality.bind(this, eRow));
        }
        else {
            this.addHoverFunctionality(eRow);
        }
    };
    RowComp.prototype.addHoverFunctionality = function (eRow) {
        var _this = this;
        // because we use animation frames to do this, it's possible the row no longer exists
        // by the time we get to add it
        if (!this.active) {
            return;
        }
        // because mouseenter and mouseleave do not propagate, we cannot listen on the gridPanel
        // like we do for all the other mouse events.
        // because of the pinning, we cannot simply add / remove the class based on the eRow. we
        // have to check all eRow's (body & pinned). so the trick is if any of the rows gets a
        // mouse hover, it sets such in the rowNode, and then all three reflect the change as
        // all are listening for event on the row node.
        // step 1 - add listener, to set flag on row node
        this.addDestroyableEventListener(eRow, 'mouseenter', function () { return _this.rowNode.onMouseEnter(); });
        this.addDestroyableEventListener(eRow, 'mouseleave', function () { return _this.rowNode.onMouseLeave(); });
        // step 2 - listen for changes on row node (which any eRow can trigger)
        this.addDestroyableEventListener(this.rowNode, rowNode_1.RowNode.EVENT_MOUSE_ENTER, function () {
            // if hover turned off, we don't add the class. we do this here so that if the application
            // toggles this property mid way, we remove the hover form the last row, but we stop
            // adding hovers from that point onwards.
            if (!_this.beans.gridOptionsWrapper.isSuppressRowHoverHighlight()) {
                utils_1._.addCssClass(eRow, 'ag-row-hover');
            }
        });
        this.addDestroyableEventListener(this.rowNode, rowNode_1.RowNode.EVENT_MOUSE_LEAVE, function () {
            utils_1._.removeCssClass(eRow, 'ag-row-hover');
        });
    };
    // for animation, we don't want to animate entry or exit to a very far away pixel,
    // otherwise the row would move so fast, it would appear to disappear. so this method
    // moves the row closer to the viewport if it is far away, so the row slide in / out
    // at a speed the user can see.
    RowComp.prototype.roundRowTopToBounds = function (rowTop) {
        var range = this.beans.gridPanel.getVScrollPosition();
        var minPixel = this.applyPaginationOffset(range.top, true) - 100;
        var maxPixel = this.applyPaginationOffset(range.bottom, true) + 100;
        if (rowTop < minPixel) {
            return minPixel;
        }
        else if (rowTop > maxPixel) {
            return maxPixel;
        }
        else {
            return rowTop;
        }
    };
    RowComp.prototype.onRowHeightChanged = function () {
        // check for exists first - if the user is resetting the row height, then
        // it will be null (or undefined) momentarily until the next time the flatten
        // stage is called where the row will then update again with a new height
        if (utils_1._.exists(this.rowNode.rowHeight)) {
            var heightPx_1 = this.rowNode.rowHeight + 'px';
            this.eAllRowContainers.forEach(function (row) { return row.style.height = heightPx_1; });
        }
    };
    RowComp.prototype.addEventListener = function (eventType, listener) {
        if (eventType === 'renderedRowRemoved' || eventType === 'rowRemoved') {
            eventType = events_1.Events.EVENT_VIRTUAL_ROW_REMOVED;
            console.warn('ag-Grid: Since version 11, event renderedRowRemoved is now called ' + events_1.Events.EVENT_VIRTUAL_ROW_REMOVED);
        }
        _super.prototype.addEventListener.call(this, eventType, listener);
    };
    RowComp.prototype.removeEventListener = function (eventType, listener) {
        if (eventType === 'renderedRowRemoved' || eventType === 'rowRemoved') {
            eventType = events_1.Events.EVENT_VIRTUAL_ROW_REMOVED;
            console.warn('ag-Grid: Since version 11, event renderedRowRemoved and rowRemoved is now called ' + events_1.Events.EVENT_VIRTUAL_ROW_REMOVED);
        }
        _super.prototype.removeEventListener.call(this, eventType, listener);
    };
    RowComp.prototype.destroy = function (animate) {
        if (animate === void 0) { animate = false; }
        _super.prototype.destroy.call(this);
        this.active = false;
        // why do we have this method? shouldn't everything below be added as a destroy func beside
        // the corresponding create logic?
        this.destroyFullWidthComponents();
        if (animate) {
            this.removeFirstPassFuncs.forEach(function (func) { return func(); });
            this.removeSecondPassFuncs.push(this.destroyContainingCells.bind(this));
        }
        else {
            this.destroyContainingCells();
            // we are not animating, so execute the second stage of removal now.
            // we call getAndClear, so that they are only called once
            var delayedDestroyFunctions = this.getAndClearDelayedDestroyFunctions();
            delayedDestroyFunctions.forEach(function (func) { return func(); });
        }
        var event = this.createRowEvent(events_1.Events.EVENT_VIRTUAL_ROW_REMOVED);
        this.dispatchEvent(event);
        this.beans.eventService.dispatchEvent(event);
    };
    RowComp.prototype.destroyContainingCells = function () {
        this.forEachCellComp(function (renderedCell) { return renderedCell.destroy(); });
        this.destroyFullWidthComponents();
    };
    // we clear so that the functions are never executed twice
    RowComp.prototype.getAndClearDelayedDestroyFunctions = function () {
        var result = this.removeSecondPassFuncs;
        this.removeSecondPassFuncs = [];
        return result;
    };
    RowComp.prototype.onCellFocusChanged = function () {
        var rowFocused = this.beans.focusedCellController.isRowFocused(this.rowNode.rowIndex, this.rowNode.rowPinned);
        if (rowFocused !== this.rowFocused) {
            this.eAllRowContainers.forEach(function (row) { return utils_1._.addOrRemoveCssClass(row, 'ag-row-focus', rowFocused); });
            this.eAllRowContainers.forEach(function (row) { return utils_1._.addOrRemoveCssClass(row, 'ag-row-no-focus', !rowFocused); });
            this.rowFocused = rowFocused;
        }
        // if we are editing, then moving the focus out of a row will stop editing
        if (!rowFocused && this.editingRow) {
            this.stopEditing(false);
        }
    };
    RowComp.prototype.onPaginationChanged = function () {
        var currentPage = this.beans.paginationProxy.getCurrentPage();
        // it is possible this row is in the new page, but the page number has changed, which means
        // it needs to reposition itself relative to the new page
        if (this.paginationPage !== currentPage) {
            this.paginationPage = currentPage;
            this.onTopChanged();
        }
    };
    RowComp.prototype.onTopChanged = function () {
        this.setRowTop(this.rowNode.rowTop);
    };
    // applies pagination offset, eg if on second page, and page height is 500px, then removes
    // 500px from the top position, so a row with rowTop 600px is displayed at location 100px.
    // reverse will take the offset away rather than add.
    RowComp.prototype.applyPaginationOffset = function (topPx, reverse) {
        if (reverse === void 0) { reverse = false; }
        if (this.rowNode.isRowPinned()) {
            return topPx;
        }
        else {
            var pixelOffset = this.beans.paginationProxy.getPixelOffset();
            if (reverse) {
                return topPx + pixelOffset;
            }
            else {
                return topPx - pixelOffset;
            }
        }
    };
    RowComp.prototype.setRowTop = function (pixels) {
        // print layout uses normal flow layout for row positioning
        if (this.printLayout) {
            return;
        }
        // need to make sure rowTop is not null, as this can happen if the node was once
        // visible (ie parent group was expanded) but is now not visible
        if (utils_1._.exists(pixels)) {
            var afterPaginationPixels = this.applyPaginationOffset(pixels);
            var afterScalingPixels = this.beans.heightScaler.getRealPixelPosition(afterPaginationPixels);
            var topPx_1 = afterScalingPixels + "px";
            if (this.beans.gridOptionsWrapper.isSuppressRowTransform()) {
                this.eAllRowContainers.forEach(function (row) { return row.style.top = "" + topPx_1; });
            }
            else {
                this.eAllRowContainers.forEach(function (row) { return row.style.transform = "translateY(" + topPx_1 + ")"; });
            }
        }
    };
    // we clear so that the functions are never executed twice
    RowComp.prototype.getAndClearNextVMTurnFunctions = function () {
        var result = this.createSecondPassFuncs;
        this.createSecondPassFuncs = [];
        return result;
    };
    RowComp.prototype.getRowNode = function () {
        return this.rowNode;
    };
    RowComp.prototype.getRenderedCellForColumn = function (column) {
        return this.cellComps[column.getColId()];
    };
    RowComp.prototype.onRowIndexChanged = function () {
        this.onCellFocusChanged();
        this.updateRowIndexes();
    };
    RowComp.prototype.updateRowIndexes = function () {
        var rowIndexStr = this.rowNode.getRowIndexString();
        var rowIsEven = this.rowNode.rowIndex % 2 === 0;
        var rowIsEvenChanged = this.rowIsEven !== rowIsEven;
        if (rowIsEvenChanged) {
            this.rowIsEven = rowIsEven;
        }
        this.eAllRowContainers.forEach(function (eRow) {
            eRow.setAttribute('row-index', rowIndexStr);
            if (rowIsEvenChanged) {
                utils_1._.addOrRemoveCssClass(eRow, 'ag-row-even', rowIsEven);
                utils_1._.addOrRemoveCssClass(eRow, 'ag-row-odd', !rowIsEven);
            }
        });
    };
    RowComp.prototype.ensureDomOrder = function () {
        var body = this.getBodyRowElement();
        if (body) {
            this.bodyContainerComp.ensureDomOrder(body);
        }
        var left = this.getPinnedLeftRowElement();
        if (left) {
            this.pinnedLeftContainerComp.ensureDomOrder(left);
        }
        var right = this.getPinnedRightRowElement();
        if (right) {
            this.pinnedRightContainerComp.ensureDomOrder(right);
        }
        var fullWidth = this.getFullWidthRowElement();
        if (fullWidth) {
            this.fullWidthContainerComp.ensureDomOrder(fullWidth);
        }
    };
    // returns the pinned left container, either the normal one, or the embedded full with one if exists
    RowComp.prototype.getPinnedLeftRowElement = function () {
        return this.ePinnedLeftRow ? this.ePinnedLeftRow : this.eFullWidthRowLeft;
    };
    // returns the pinned right container, either the normal one, or the embedded full with one if exists
    RowComp.prototype.getPinnedRightRowElement = function () {
        return this.ePinnedRightRow ? this.ePinnedRightRow : this.eFullWidthRowRight;
    };
    // returns the body container, either the normal one, or the embedded full with one if exists
    RowComp.prototype.getBodyRowElement = function () {
        return this.eBodyRow ? this.eBodyRow : this.eFullWidthRowBody;
    };
    // returns the full width container
    RowComp.prototype.getFullWidthRowElement = function () {
        return this.eFullWidthRow;
    };
    RowComp.DOM_DATA_KEY_RENDERED_ROW = 'renderedRow';
    RowComp.FULL_WIDTH_CELL_RENDERER = 'fullWidthCellRenderer';
    RowComp.GROUP_ROW_RENDERER = 'groupRowRenderer';
    RowComp.GROUP_ROW_RENDERER_COMP_NAME = 'agGroupRowRenderer';
    RowComp.LOADING_CELL_RENDERER = 'loadingCellRenderer';
    RowComp.LOADING_CELL_RENDERER_COMP_NAME = 'agLoadingCellRenderer';
    RowComp.DETAIL_CELL_RENDERER = 'detailCellRenderer';
    RowComp.DETAIL_CELL_RENDERER_COMP_NAME = 'agDetailCellRenderer';
    return RowComp;
}(component_1.Component));
exports.RowComp = RowComp;


Brian Renk: The enemy are publishing books on the Lipstadt trial already; are we?
Adrian Jensen asks, Why be rude about Prof. Lipstadt? Was she a liar?
A baffled Australian reader asks: Why are Irving books available here free?
A. Stadlen was in Court when Mr Irving spoke the words "mein Führer"
Mike Hourston says David Irving's summation provided sufficient light on the issues, but will people be willing to use that light?
John Coffey read the transcripts, and writes: "What a feast!"
Why are Irving books suppressed yet Amazon.com sells MEIN KAMPF and Henry Ford's The International Jew?
Sebastian Barnard feels that Historians should now concentrate on the "Why?"
Katrina Mitchell asks: Did Professor Heisenberg want to build the atomic bomb; or did he just conceal his failure?
Luigi Capano asks Is it true that Picasso started his Guernica painting years before the air raid on Guernica?
A computer expert in Berlin asks: Why are no German editions of David Irving books available as free downloads?
TV documentary on Nuremberg Trials claims Mauthausen had a gas chamber. Did it?
John Ball asks why fake photos are being removed after 4 years, and just one month before the Wehrmacht exhibit moves to America?
An Icelander Dr. Gudbrandur Jonasson became a personal friend of Heinrich Himmler (in the 1920s).
Hugh McInnish asks if Churchill mentioned the Holocaust in his WWII volumes?
Sharon Fleischmann asks, Did Hitler visit the Nazi concentration camps?
When a man of your stature speaks people listen, writes an Ottawa law student. Are you absolutely sure that there were no gas chambers?
Michel Mills comments on the 1948 German newsreel of a Polish war-crimes court judgement that "altogether nearly 300,000 died at Auschwitz"
Phoebe asks: "If Anne Frank didn't completely write her diary, then who did?"
A-level scholar Susan Toft of the UK asks, Apr 10, 1999: why do they call Mr Irving a holocaust denier?
Michael Mills quotes an inoccuous example of the use of the word "Sonderaktion"
Stavros Elia, UK A-level student, asks: "Was there a systematic Nazi Plan to exterminate the Jewish race from 1933 and how significant was Hitler in this?"
Jim Dean of Atlanta asks what is a "Holocaust Denier?"
John Kyle, on actor Carlos Thompson's curious attack on David Irving.
Auschwitz-I commandant's daughter, writes that her mother says "those [crematoria] were not there"
Correspondence with the late Professor Klaus J Herrmann, of Montreal university, about Nazi concentration camps and evidence.
Harold T has written a book about Kurt Waldheim entitled The Anatomy of a Witch Hunt.
Pawel Szalamacha writes from Poland, August 31, 1998: did the Polish cavalry charge Nazi tanks in 1939?
Lawrence Starr, United States, feels that the international Right-wing is flailing ineffectually.
Art Kleps suggests turning New York City over to "terrorist leader" Bin Laden.
Lawrence Starr makes allegations, August 23, 1998 about criminal records of National Alliance members in Cleveland.
Jeff Kledis asks questions about the embarrassing Potocki Papers published by the Nazis in 1940.
Review of a Lazar Kaganovich biography, The Wolf of the Kremlin, by Stuart Kahan.
A Scandinavian Friend writes a scathing commentary on the kaleidoscope of killing methods used during the Holocaust.
A reader comments, August 3, 1998, on an inaccuracy in David Irving's press release on being banned from Auschwitz.
Alan Moses, of Tampa, Florida, July 26, 1998, on the Australian and Auschwitz bans on David Irving.
David Kramer, a New York Jew, joins the doubters, July 24, and August 10, 1998.
Samuel Crowell, United States, Sunday, July 8, 1998: Ron Rosenbaum's new book Explaining Hitler.
Nicolas Alvarez, in Chile, asks how he can purchase Spanish language books by David Irving.
Gilbert Gendron writes from Montreal, July 1, 1998: did Hitler in fact ever talk of a "1,000 Year Reich"? Another reader replies.
Ivan Marchevsky writes from Veliko Tarnovo, June 21, 1998 about references to Bulgaria in Hitler's War.
Alexander Mayer, Jewish-born Director of Progen, ("Project Genocide"), of New Brunswick, New Jersey, writes on June 21, 1998, about Romanian documents suggesting that Hitler did know of Final Solution; and June 22, 1998 [updated July 10] about the possibiity that Auschwitz deportees were sent to Transnistria instead.
Maureen Bower of Ontario writes June 19, 1998 about the role of Masons in the British legal system.
Frank Lowe, North Carolina, June 8, 1998: the underground War by Typhus in WW2 Poland; with a commentary by Samuel Crowell.
Eric de Chalain, South Africa: Mr Irving to lecture there?
Samuel Crowell, United States, Sunday, May 17, 1998: Auschwitz, Höss, Warsaw Ghetto.
Frank Paulson of Texas comments on Hitler's War, May 7, 1998.
A former Berkeley student, April 27, 1998, expresses anger that he was denied the right to hear David Irving at UCB in 1994.
"Samuel Crowell," United States, Friday, March 21, 1998: comments on this site's documentation.
Albert Doyle, United States, Friday, March 20, 1998: on the Vatican's role.
Robert E Reis, United States, March 19, 1998: the Himmler Diaries.
Robert Gilmor, United States, March 15, 1998: on book ordering, and David Irving's next speaking functions.
Grant G., Australia, March 13, 1998: Nazi persecution of the Jews. On Auschwitz see our file [full name removed at his request].


Generic programming and medical simulation.
I would like to offer some introductions to specific topics from my portfolio. I hope this helps you better understand the background of services offered by CMM.
I work on and with generic programming since about 1995. As a mathematician, I am fascinated by the idea to transfer the generality and abstractness of mathematical structures into programming and software. I firmly believe that today, the potential of generic programming is still far from being fully exploited. It would be a pleasure for me to help you discover the advantages of this paradigm yourself!
Geometry processing for medical simulation has become one of my major work areas since 2001. Mastering patient-specific geometry is pivotal for personalised bio-mechanical simulation supporting medical decisions. Again, I am convinced that individualised medical simulation has a bright future.


This is the twenty-second installment of The Curious Creative, weekly 10-minute writing exercises for busy individuals interested in exploring their creativity. For the complete rationale, click here.
I recently wrote a choose-your-own-adventure poem, combining a classic genre from my childhood with the sparse, metaphorical language of poetry. It was a blast to write! It felt freeing to constantly be thinking about the multiple directions a story could go. For this week's exercise, we'll take inspiration from this genre, but instead of thinking up a brand new story, which is an overwhelming task for someone with only 10 minutes to spare, we'll revise a moment from the past.
Think of a memorable personal event. Free write about it for five minutes.
Next, make a list of specific markers of the place where it occurred (i.e., names of streets/shops/restaurants, details about the weather, the quality of light, what was hanging in shop windows, etc.).
Circle five salient words from your list.
Now, rewrite the story incorporating these five new markers of place. Allow the new words' connotations to carry the event in new directions.
How did you do? Did you feel a lighthearted surrender as you released control of the memory? Did the exercise feel fun and playful?


text:
Scientists Say the Ozone Layer is Recovering
September 10, 2014Vallarta Daily NewsMore News
Earth's protective ozone layer is beginning to recover, largely because of the phase-out since the 1980s of certain chemicals used in refrigerants and aerosol cans, a U.N. scientific panel reported Wednesday in a rare piece of good news about the health of the planet. Scientists said the development demonstrates that when the world comes together,...
Toyota Looking For A Good Spot in Mexico for a New Manufacturing Plant
September 10, 2014Vallarta Daily NewsBusiness and Economy
Toyota Motor Corp. (7203), the last of the world's major automakers without a full assembly plant in Mexico, is scouting the country for possible factory sites, two people with direct knowledge of the matter said. The search spans several states, said the people, who asked not to be identified because the details aren't public. Company...
Why are businesses having the worst summer if tourism is breaking records?
As Puerto Vallarta is welcoming a record number of tourists this summer travel season, many business owners say they are having the worst summer sales in years. So here is this week's "Vallartenses Voice" question: What can the city and business owners do to help increase local sales and get our record number of tourists...
Youth in Mexico Confront a Bleak Job Market
The National Survey of Occupation and Employment (ENOE) indicated in late August that 85% of youth between the ages of 20 and 29 earn the lowest wages in the country, at 6,000 pesos (US$450) or less a month. The youth unemployment rate nationally stood at 8.3 percent, equivalent to 349,000 young people between the ages...
Tropical Storm Odile Could Bring Its Center Close to Puerto Vallarta This Weekend
September 10, 2014Vallarta Daily NewsPuerto Vallarta News
*** UPDATE SEPTEMBER 10 – 10:30 PM *** Tropical Storm Odile is strengthening off the coast of southern Mexico, and the first tropical storm watch has been posted for the Mexican coast. Wednesday evening, the government of Mexico issued a tropical storm watch for its Pacific coast from Lazaro Cardenas, in the state of Michoacan,...
Practically Every Global Auto Manufacture is Represented in Mexico
The news of Kia moving to Mexico was so important to Mexico's economy that the president made the announcement himself. On the same day that General Motors Co. (NYSE:GM) said it would be calling home Cadillac SRX crossover production from Mexico in a deal worked out with the United Auto Workers union, South Korean automaker...
Puerto Vallarta's Properties are Becoming Recognizable Landamarks
Promotional images of Puerto Vallarta often depict the iconic Senora de Guadelupe Church and the stunning sweep of the Bay of Banderas. What tourism officials also want visitors to experience are the destination's boutique properties tucked away in the hillsides and along the beaches. "Boutique hotels are an important part of Puerto Vallarta's hotel offerings...

redpajama_set_name: RedPajamaCommonCrawl


An entrepreneurial spirit and commitment to service run deep at William & Mary. Tribefunding, our crowdfunding initiative, helps the community dream up big ideas, fund bold projects and make a difference at W&M and far beyond.
Every semester, a new group of campaigns will launch on GiveCampus, our crowdfunding platform.
Visit the site to browse projects, join the community and support great ideas from the Tribe community.
Spring Tribefunding will launch April 10, 2019.
Have a project or idea in need of funding?
We welcome applications from students, faculty and staff for university-related projects that benefit the community and enhance the student experience.
The 'Save Our Bay Scallops' Tribefunding campaign raised more than $20,000 to purchase and then seed thousands of juvenile bay scallops into the seaside bays of Virginia's Eastern Shore with the goal of giving this species, locally extinct since the '30s, its best chance for revival.
Campaigns are launched twice a year, with spring projects starting in early April and fall projects starting in early November.
Currents students, faculty and staff are welcome to submit an application. Projects should benefit the W&M community, align with the mission of the university and adhere to all university policies.
Projects are evaluated based on their goals, suitability for crowdfunding and commitment demonstrated by the team. We will work with teams to adjust projects as needed to ensure a successful outcome.
What support is offered to project teams?
Staff within University Advancement will help all approved projects at every stage of their campaigns. Training will be provided to help teams craft a great strategy, leverage their own networks and promote their projects online. And after projects are launched, we'll continue to support projects and help teams reach their goals.
What should project teams expect?
Although most campaigns run for just 30 days, Tribefunding is a 3-month commitment. We recommend teams have one or two project leaders, with 8-10 additional members who can take an active role promoting the project. All team members are encouraged to attend an orientation training session; this training is required for project leaders. Teams will develop a detailed budget for their project, as well as a description, short video, social media plan and outreach calendar to promote the project.
Fundraising isn't easy, but we're here to help! Tribefunding is powered by the GiveCampus online platform and includes assistance from staff within University Advancement.
Your contribution is a charitable gift to William & Mary, designated for the project that you have chosen to fund.
Does my gift count towards my annual giving to W&M?
Since your payment is a charitable contribution to W&M, it will be considered as part of your annual gift to W&M. Your payment will also be counted toward your membership in our donor recognition societies.
Yes. International payments can be made via credit card in U.S. dollars through GiveCampus.


Indrajith Review: Fantasy films which manage topics like fortune chase, against the background of enamoring scenes, are dependably a treat to watch.In any case, what make such endeavors work is the mix of drawing in screenplay, interesting characters, capturing visuals, shocking portrayal and nail-gnawing activity groupings.
Indrajith has a place with the dream sort, yet is without the previously mentioned components, aside from the way that there are a few shots which seem lovely on screen.Indrajith (Gautham), an undertaking addict, joins Mayil Vahanam (Sachin Khedekar), who is the previous chief of Archeological Survey of India (ASI). The last is looking for a valuable stone which has one of a kind restorative advantages.
One of his progenitors had thought regarding the course delineate encourages one to achieve the thick timberlands in Arunachal Pradesh, where the stone is accessible. With the assistance of Mayil's partners, Indrajith figures out how to discover the course outline.
In the mean time, Kapil Sharma (Sudanshu Pandey), the present chief of ASI, who isn't in great terms with Mayil, endeavors to procure the guide as he, as well, is anxious to get the stone. Kapil assaults Mayil with his cohorts, however the last escapes safe. Mayil, with his helpers and Indrajith, set out to Arunachal, after which they confront a large number of startling obstacles.
Will Indrajith help Mayil to get the stone which could change the destiny of people? Kapil, who has brought forth different plans to ruin Mayi's endeavor, is furnished with arms. Will the fortunes support him?
The Real Jackpot 2 (Indrajith) 2019 Hindi Dubbed Full Movie The film has an aggressive plot, however is destroyed with lazy composition, poor CG and silly characters. The courageous women in the film, Sonarika and Ashrita, have nothing to do, while Sachin and Sudanshu did equity to their jobs in the most ideal way they could do.


text:
Fraud perpetrated on the U.S. government takes money out of the pockets of every U.S. citizen. Major types of fraud on the government generally fall into the following categories:
Government's major role in our health care system, through Medicare and Medicaid, has resulted in health care fraud being the largest type of fraud committed on the government. Those companies and individuals with whom the government transacts to take care of its citizens, regularly cheat the government out of billions of dollars.
Early day defense contractors, dating back to the Civil war, are attributed with having sold the Union Army decrepit horses and mules in poor health, faulty rifles and ammunition, and spoiled rations and provisions. As a result, the False Claims Act was passed by Congress on March 2, 1863. Central to the False Claims Act is that it permits citizens to sue on behalf of the government and be paid a percentage of the recovery. Defense contractors continue to be a significant source of fraud on the government, with the only change appearing to be the sheer magnitude of the fraud.
The IRS Whistleblower Office allows whistleblowers to help bring to justice U.S. tax cheats. Dodd Frank Wall Street Reform and Consumer Protection Act created the SEC Whistleblower Office and CFTC Whistleblower Office, both of which regulate enormous parts of our financial markets. These relatively new whistleblower programs are in direct response to the enormous financial frauds committed in so many areas of our economy.
EOil & Gas royalties derive from the rich natural resources that we all own as U.S. citizens. The companies who have come to control these resources represent one of the single highest sources of income for the U.S. government, our government. An antiquated system of reporting and collection leaves this area of our economy ripe for abuse, by some of the largest corporations on the globe.
Many large companies have whole divisions dedicated to selling directly to the government. The government's enormous appetite for goods and services is fulfilled by a complex system of GSA contracts and GSA schedules. The staggering sums spent by government, and the complexities of transacting with the government, have resulted in procurement fraud of all types being an increasing focus of whistleblower actions.


Deepak Rauniyar is a Berlinale Talent Campus and TIFF Talent Lab alumnus. His feature-length debut, 'Highway' (2012) had its premiere at the Berlin International Film Festival, and was first Nepali film ever to screen at a major international festival. Currently in progress, 'White Sun', his second feature, has been selected for L'Atelier at the Festival de Cannes and Boost! in Rotterdam, and awarded funding from the Hubert Bals Fund, Doha & Tribeca Film Institutes.


text:
Q: How do I change my skin manually? I have access to my iPhone's file system.
As stated in this answer by me, it is a confirmed bug where skins, when in the photo library, are converted straight into .jpeg, instead of the required .png format.

How do I change my skin?
To simply put it: Which app folder directory do I upload the skin file into?
Also: No, replacing the char.png located in the app package IS NOT THE ANSWER, since nobody else can see that skin, except for you, as it's changing the default skin, rather than the player's custom skin, and no, using the in-game skin changer is not an answer as, in the first place, it does not work!

Note: This may have already been answered in a totally unrelated question somewhere. I just can't seem to find it.

A: Update: Now I remember: It was a comment on the bug tracker.
To change your Minecraft Skin manually on iOS, simply open a file system viewer and browse to the following folder:
.../[Minecraft PE]/Documents/game/com.mojang/minecraftpe/

And name it: custom.png.

redpajama_set_name: RedPajamaStackExchange


text:
Disgust and Tenderness in Garth Greenwell's What Belongs to You (Ploughshares)
October 4, 2017 October 4, 2017 Cassandra
My essay "Disgust and Tenderness in Garth Greenwell's What Belongs to You," was published today on the Ploughshares blog! You can read it here.
Garth Greenwell's debut novel What Belongs to You is a beautiful and heartbreaking meditation on how we learn to fill the emotional space between ourselves and others. The unnamed narrator is an American teacher in Bulgaria whose coming-out experiences as a teenage boy in the South indelibly shape his relationships with others later in life.
Yet, it would be falsely reductive to label this book as somehow limited in its interests to gay experience; the loneliness and the struggle to reach out, to touch other human beings, belongs to all of us. Indeed, one of Greenwell's successes in this book is the ability to subvert common tropes of shame and disgust around homosexuality, and expose an original tenderness, a vulnerability underneath, that we all share.
In the opening chapter, after the narrator experiences his first small betrayal by a younger Bulgarian man named Mitko, he reflects, "There's something theatrical in all our embraces, I think, as we weigh our responses against those we perceive or project; always we desire too much or not enough, and compensate accordingly." But romantic attraction is only an entry-point into this question for Greenwell, who guides his narrative gracefully through the narrator's strained memories of his father, meandering walks through the Bulgarian landscape, and encounters with strangers in a hospital and on a train. Continue reading
There is so much I love about this book, and I was only able to write about a sliver of it. I hope you'll pick up a copy and read it next time you wander through the bookstore!
Categories: Publications	Tags: book review, Garth Greenwell, gay literature, Ploughshares blog, What Belongs to You
← Notes on a Modern Cinderella (concīs)
"The First Jews of San Antonio" Among Winners of San Antonio's 30 Poems for the Tricentennial Contest →
4 thoughts on "Disgust and Tenderness in Garth Greenwell's What Belongs to You (Ploughshares)"
suicidemike says:
Great to see your writing Cassandra!
Cassandra says:
Hey, thanks for reading it! 🙂 I loved this book so much!
Debbra Palmer says:
This has moved to the top of my reading list. "His anger is not just a protective shell. It pushes against that silent look of disgust in the car and allows the narrator to occupy space in the world. We sometimes glance too quickly away from anger in the face of gross injustice." Thanks Cassandra!
Debbra, it's so good. The questions the narrator asks about himself as he bounces from his present-day difficult interactions with Mitko to his past interactions with his father and this shitty friend K. are just really powerful, and there are other interactions along the way with hospital staff and strangers that just continue to build out the complexity. It's really well done.


text:
Jean-Paul Gaultier announces retirement after 50 years in the business
Matte no more: Bulgari drops new satin-polished Octo Finissimo models
Josh Kua on how he embodies the BOSS Bottled Man of Today
Please read these Terms and Conditions ("Terms", "Terms and Conditions") carefully before using the website www.lifestyleasia.com (the "Service"), operated by Lifestyle Asia ("us", "we", or "our").
By accessing or using the Service you agree to be bound by these Terms. If you disagree with any part of the terms, then you may not access the Service. Unauthorized use of the Site may give rise to a claim for damages and/or be a criminal offense.
The Terms, together with our Privacy Policy and any other terms and conditions incorporated hereunder, shall constitute the entire agreement between you and us concerning our Service.
The Terms operate to the fullest extent permissible by law. If any provision of the Terms is unlawful, void or unenforceable, that provision is deemed severable from the Terms and does not affect the validity and enforceability of any remaining provisions, which shall remain in full force and effect.
You warrant and attest that you are of the age of majority. By using our Service, you are confirming that you meet the minimum age. You further agree that you fully understand the contents, meaning and impact of these Terms and warrant and represent that you are fully able and competent to enter into and be bound by these Terms.
All content published on Lifestyle Asia is intended for personal, non-commercial use only. These include, but are not limited to, articles, illustrations, images, logos, fonts and video clips; and are protected by international copyright laws. The content is owned by Lifestyle Asia unless indicated otherwise.
You may not replicate, publish, reproduce, or in any way seek commercial benefit by using content from the Service without prior written permission from Lifestyle Asia.
The Service may contain links to third-party websites or services that are not owned or controlled by Lifestyle Asia.
Lifestyle Asia has no control over, and assumes no responsibility for, the content, privacy policies, or practices of any third-party sites or services. You further acknowledge and agree that Lifestyle Asia shall not be responsible or liable, directly or indirectly, for any damage or loss caused or alleged to be caused by or in connection with the use of or reliance on any such content, goods or services available on or through any such websites or services.
These Terms shall be governed and construed in accordance with the laws of Hong Kong, Singapore, Kuala Lumpur, Bangkok or India where applicable, without regard to its conflict of law provisions.
Our failure to enforce any right or provision of these Terms will not be considered a waiver of those rights. If any provision of these Terms is held to be invalid or unenforceable by a court, the remaining provisions of these Terms will remain in effect. These Terms constitute the entire agreement between us regarding our Service and supersede and replace any prior agreements we might have between us regarding the Service.
Except in jurisdictions where such provisions are restricted (and in that event, liability is disclaimed to the fullest extent permitted by law), in no event will Lifestyle Asia be liable to you or any third party for any indirect, consequential, exemplary, incidental, special or punitive damages, including also lost profits arising from your use of the Service.
All users agree to indemnify, and hold harmless Lifestyle Asia, its officers, directors, employees and agents from and against any claims, actions, demands, losses or damages arising from or resulting from their use of the Site or their breach of these Terms.
We reserve the right to modify or replace these Terms at any time. If a revision is material we will try to provide at least 30 days' notice prior to any new terms taking effect. What constitutes a material change will be determined at our sole discretion.
If you have any questions about these Terms, please contact us at
info@lifestyleasia.com.


text:
Home Tech Realme GT 2 Pro: Check Out What's New On Mobile
Realme GT 2 Pro: Check Out What's New On Mobile
Realme made official, this Monday (20), some details about the Realme GT 2 Pro. The company's first top-of-the-line will be the world's first cell phone with biobased materials.
The smartphone will have an ecological footprint and a design that was thought of by artist Naoto Fukasawa. The back was developed with a biopolymer that uses plant materials, unlike traditional plastics made with petroleum. The device's housing also had a reduction in its plastic composition, going from 21.7% to just 0.3%.
In terms of hardware, details about the cameras were revealed. The device will be the first in the world to have a 150° wide-angle lens, which can expand the field of view by up to 278%. With this, the cell phone will be able to capture very deep images of landscapes.
In addition, the device will also have a "fisheye" mode. The feature, which comes for the first time for mobile phones, is based on the lens of the photography industry and serves to produce a great perspective or depth effect with a large field of view. See, below, an example of a photo taken with the mode turned on.
To improve the gaming experience and overall usability, the device's performance was thought of in a particular way. Therefore, the Realme GT 2 Pro was equipped with the "Antenna Array Matrix System", a technology that promises to improve internet connection and connectivity. The system combines 3 features:
Ultra-wide Band HyperSmart Antenna Switching: which supports access to many frequency bands. In all, 48 global bands from over 150 countries and regions are supported. The promise is a sign "anywhere". The device also has 12 antennas spread across its body, which prevents them from being blocked during gambling, for example.
Wi-Fi Enhancer: The phone has a symmetrical Wi-Fi antenna design that allows it to receive Wi-Fi signals from any direction. The smartphone has Wi-Fi 6 connection, supports Wi-Fi and Wi-Fi acceleration overlay.
NFC 360°: the novelty allows NFC communication technology (very used for payments) to be used at any angle on the device. The device's NFC area has been increased by 500% and steering improved by 20%.
TikTok 'Family Safety Mode' Gives Parents App Control
Gigabyte Introduces One of the Fastest SSDs in the World


Welcome to Wachovia (B2B Banks - ATMs) on 2500 NW 72nd Ave in Miami, Florida. This bank is listed on Bank Map under Banks - B2B Banks - ATMs. You can reach us on phone number (305) 597-3600, fax number or email address . Our office is located on 2500 NW 72nd Ave, Miami, FL.
Not sure where Wachovia on 2500 NW 72nd Ave is? The following places (sorted by popularity) are located nearby. We've also included the estimated walking distance.
These are the bank hours for Wachovia. Call (305) 597-3600 to learn more about office hours. Please note that these bank hours are general and other hours of operation may apply on certain holidays.


text:
Amiens explain Olanrewaju Kayode's transfer situation
Taiye Taiwo
Nigeria A'
African All Stars
The Nigeria international is yet to sign for the Stade de la Licorne outfit after failing to complete his move before the transfer deadline
French Ligue 1 side Amiens have released a statement regarding the delay in the transfer of Olanrewaju Kayode on loan from Manchester City.
After struggling for regular playing time in Girona this season, the 24-year-old forward was due to move to the French top-flight outfit on loan for the remainder of the season but necessary formalities were not validated in time.
The Unicorns faulted the delay in Kayode's move on 'administrative reasons', as they now await decision by the 'football authorities'
"Amiens SC is keen to comment on the situation of Nigerian international striker Larry Kayode, who was at the Stade de la Licorne last night, ho.ping to join the club," read a statement on the club website.
"All stakeholders agreed within the time frame set by the international regulations. For administrative reasons, the transfer of Larry Kayode has not been validated.
"The 3 clubs concerned [Manchester City, Girona FC and Amiens SC] are currently working on the follow-up to this case, and on the possible solutions.
"The final decision will be taken by the football authorities, after evaluation of the file.
"Whatever the outcome of this transfer, Amiens SC will be able to count on a competitive workforce and its loyal supporters, to achieve its main goal: the maintenance in Ligue 1 Conforama."
Olunga's rise should worry Olarenwaju Kayode outshines Uzoho as Girona defeat Deportivo


text:
Agro-Terrorism
Posted by presspass on February 27, 2019
Join us July 18/19, as we talk to Dee Grimm about the risks and threats of Agro-Terrorism.
Bio-Terrorism
Our June 29,2019 show will talk about the risks and impacts related to Bio-Terrorism with expert Dee Grimm. Enjoy!
Concerning the State of Vaccines in America By Dr. John and Linda Gonino
In 2013 a CDC whistle blower leaked that the centers study in 2004 of the MMR vaccine and its' link to autism, was purposefully tainted as they omitted evidence and data that produced the causal relationship of the two. What commenced and came out of this persons information is the movie VAXXED: From Cover Up to Catastrophe. Join us as Director Dr. Andrew Wakefield and Producer Polly Tommy tell us about the movie, the bus tour, the scrutiny and eventual blast off of the movie that is a true source of the state of vaccine damage, death and laws in America.
This subject matter is controversial, but at the heart of this film is the real life stories of parents with vaccine injured and sadly, dead children from vaccines. Texans for Vaccine Choice, Director of state policy, Rebecca Hardy is with us as well giving us the pulse of legislation trying to be passed in the state of Texas on vaccines and what you can do to join your local movements and stand up for medical liberties.
Guest Bios:
Dr. Andrew Wakefield MB.BS. is an academic gastroenterologist. He received his medical degree from St. Mary's Hospital Medical School, London in 1981. He qualified as Fellow of the Royal College of Surgeons in 1985 and trained as a gastrointestinal surgeon with a particular interest in inflammatory bowel disease. He was awarded a Wellcome Trust Traveling Fellowship to study small-intestinal transplantation in Toronto. He was made a Fellow of the Royal College of Pathologists in the U.K. in 2001. Wakefield has published over 140 original scientific papers, reviews, and book chapters.
In 1995, as an academic physician working in a London teaching hospital, he was contacted by the parent of an autistic child with stomach issues. He soon learned from several other parents with autistic behaviors, that their children's regressive behavior immediately followed an MMR vaccine. He started investigating a possible role between gastrointestinal issues, the MMR vaccine, and neurological injury in children. In pursuit of this possible link, Dr. Wakefield participated in a study of twelve children with both stomach and developmental issues. The ensuing report, written with twelve other authors would catapult Wakefield into becoming one of the most controversial figures in the history of Medicine. He is the Director of "Vaxxed: From Cover-Up to Catastrophe."
Polly Tommey is the mother of Billy, a 20-year old boy with autism, a book author, founding Editor-in-Chief of the world's preeminent autism magazine The Autism File, and Autism Media Channel's TV host and award-winning documentary film producer ("Who Killed Alex Spourdalakis").
An outspoken autism advocate and founder of the not-for-profit Autism Trust in the UK and US, Polly has appeared in print and television media around the globe, gone head-to-head with top political leaders, and never compromised.
She has received multiple nominations and awards from, among others, The Women of The Year Foundation, Red magazine, and the British Society of Magazine Editors.
She is also a Producer on "Vaxxed: From Cover-Up to Catastrophe."
Rebecca Hardy
As a speech-language pathologist, Rebecca has encountered many children with profound vaccine injuries. These experiences created a passion for protecting others from these kinds of negative health outcomes, which she has turned into activism. Rebecca is one of the founders of the group Texans for Vaccine Choice and currently serves as its Director of State Policy. A native Texan, she grew up in the Austin area, graduated from Southwestern University in Georgetown before earning her Master's in Speech Language Pathology from the University of Texas at Dallas. Whether it's meeting with legislators, drafting legislative strategy, or block-walking for candidates, Rebecca is dedicated to protecting medical liberties and informed consent for all Texans.
More Here!
Zika virus – the NEXT scare, Be NOT afraid! by Nicholas St Jon
Posted by Editor on January 30, 2016
Zika virus is the "new" threat. BTW, they are NEVER gonna stop coming, there will always be something new and threatening, so learn what YOU can do, don't wait for someone else to protect you.
Quit waiting for someone else to find the solution to the next epidemic or pandemic. I'd love for the CDC to do something, but they have already proven with West Nile and Ebola that they are simply not capable of doing hardly anything.
There's NOT going to be a vaccine for Zika, after 14 years, almost 1,000 deaths and thousands maimed from WNV, still no vaccine nor is there likely to be one. All of the "authorities" websites say the exact same thing, there is NO treatment, there is NO cure. That's reassuring!?!
They can simply duplicate those paragraphs when they create the Zika pages because its the same.
Its YOUR health, take charge for there is something you CAN do against ALL viral and bacterial infections like Zika and West Nile.
Occam's razor says that all things being equal, the best solution to a problem is usually the easiest and simplest.
What is that solution? Its simple, do the opposite of what the "authorities" say makes you vulnerable to these infections in the first place, you're vulnerable and reduce your chances of recovery if you have a weak or weakened immune system. The overly obvious answer would then be to "strengthen" your immune system, but they really don't give you much help there.
So fasten your seat belts, here it is, the simplest, easiest, almost unbelievably powerful, most researched nutrient ever but the very foundation of the entire Immune System, fortify your white blood cells with plenty of Sodium Ascorbate. That's it.
Sodium Ascorbate in significant amounts, like over 3,000 mg per day (not all at once), has shown so effective against all viruses its ridiculous that its been ignored for so long.
Its YOUR health, don't wait for someone else to protect you, they're simply not capable fast enough.
Learn more at bit dot ly / out-ahead to find 9 other things that supercharge the Immune System.
Tune in every Tuesday at 3pm PST to The Health Cure Show!