src/vs/workbench/contrib/notebook/browser/view/cellParts/cellDnd.ts/CellDragAndDropController/explicitDrag
class CellDragAndDropController:	public explicitDrag(cell: ICellViewModel, dragOffsetY: number) {
		if (!this.notebookEditor.notebookOptions.getLayoutConfiguration().dragAndDropEnabled || !!this.notebookEditor.isReadOnly) {
			return;
		}

		const target = this.list.elementAt(dragOffsetY);
		if (target && target !== cell) {
			const cellTop = this.list.getAbsoluteTopOfElement(target);
			const cellHeight = this.list.elementHeight(target);

			const dropDirection = this.getExplicitDragDropDirection(dragOffsetY, cellTop, cellHeight);
			const insertionIndicatorAbsolutePos = dropDirection === 'above' ? cellTop : cellTop + cellHeight;
			this.updateInsertIndicator(dropDirection, insertionIndicatorAbsolutePos);
		}

		// Try scrolling list if needed
		if (this.currentDraggedCell !== cell) {
			return;
		}

		const notebookViewRect = this.notebookEditor.getDomNode().getBoundingClientRect();
		const eventPositionInView = dragOffsetY - this.list.scrollTop;

		// Percentage from the top/bottom of the screen where we start scrolling while dragging
		const notebookViewScrollMargins = 0.2;

		const maxScrollDeltaPerFrame = 20;

		const eventPositionRatio = eventPositionInView / notebookViewRect.height;
		if (eventPositionRatio < notebookViewScrollMargins) {
			this.list.scrollTop -= maxScrollDeltaPerFrame * (1 - eventPositionRatio / notebookViewScrollMargins);
		} else if (eventPositionRatio > 1 - notebookViewScrollMargins) {
			this.list.scrollTop += maxScrollDeltaPerFrame * (1 - ((1 - eventPositionRatio) / notebookViewScrollMargins));
		}
	}