_tryGrabWholeColumn(hand, duplicate, alt) {
        if (hand.isBusy() || hand.pos === undefined) {
            return undefined;
        }

        let col = Math.round(this.toColumnSpaceCoordinate(hand.pos.x));
        if (col < 0 || col >= this.circuitDefinition.columns.length || this.circuitDefinition.columns[col].isEmpty()) {
            return undefined;
        }

        let newCols = [...this.circuitDefinition.columns];
        if (!duplicate) {
            newCols.splice(col, 1, GateColumn.empty(this.circuitDefinition.numWires));
        }

        let holdOffset = new Point(0, this.wireIndexAt(hand.pos.y) * Config.WIRE_SPACING + Config.WIRE_SPACING/2);
        let grabbedGates = this.circuitDefinition.columns[col];
        if (alt) {
            grabbedGates = new GateColumn(grabbedGates.gates.map(e => e === undefined ? e : e.alternate));
        }
        return {
            newCircuit: this.withCircuit(this.circuitDefinition.withColumns(newCols)),
            newHand: hand.withHeldGateColumn(grabbedGates, holdOffset)
        };
    }
@param {!Hand} hand
@param {!boolean} duplicate
@param {!boolean} alt Whether or not to replace grabbed gates with their alternates.
@returns {undefined|!{newCircuit: !DisplayedCircuit, newHand: !Hand}}
@private