anchor.diff:      }
     }
   
  -  double _thumbExtent() {
  -    // Thumb extent reflects fraction of content visible, as long as this
  -    // isn't less than the absolute minimum size.
  -    // _totalContentExtent >= viewportDimension, so (_totalContentExtent - _mainAxisPadding) > 0
  -    final double fractionVisible = clampDouble(
  -        (_lastMetrics!.extentInside - _mainAxisPadding) /
  -            (_totalContentExtent - _mainAxisPadding),
  -        0.0,
  -        1.0);
  -
  -    final double thumbExtent = math.max(
  -      math.min(_traversableTrackExtent, minOverscrollLength),
  -      _traversableTrackExtent * fractionVisible,
  -    );
  -
  -    final double fractionOverscrolled = 1.0 - _lastMetrics!.extentInside / _lastMetrics!.viewportDimension;
  -    final double safeMinLength = math.min(minLength, _traversableTrackExtent);
  -    final double newMinLength = (_beforeExtent > 0 && _afterExtent > 0)
  -      // Thumb extent is no smaller than minLength if scrolling normally.
  -      ? safeMinLength
  -      // User is overscrolling. Thumb extent can be less than minLength
  -      // but no smaller than minOverscrollLength. We can't use the
  -      // fractionVisible to produce intermediate values between minLength and
  -      // minOverscrollLength when the user is transitioning from regular
  -      // scrolling to overscrolling, so we instead use the percentage of the
  -      // content that is still in the viewport to determine the size of the
  -      // thumb. iOS behavior appears to have the thumb reach its minimum size
  -      // with ~20% of overscroll. We map the percentage of minLength from
  -      // [0.8, 1.0] to [0.0, 1.0], so 0% to 20% of overscroll will produce
  -      // values for the thumb that range between minLength and the smallest
  -      // possible value, minOverscrollLength.
  -      : safeMinLength * (1.0 - clampDouble(fractionOverscrolled, 0.0, 0.2) / 0.2);
  -
  -    // The `thumbExtent` should be no greater than `trackSize`, otherwise
  -    // the scrollbar may scroll towards the wrong direction.
  -    final double extent = clampDouble(thumbExtent, newMinLength, _traversableTrackExtent);
  -    return extent;
  -  }
  -
  -  @override
  -  void dispose() {
  -    fadeoutOpacityAnimation.removeListener(notifyListeners);
  -    super.dispose();
  -  }
  -
  -  bool get _isVertical => _lastAxisDirection == AxisDirection.down || _lastAxisDirection == AxisDirection.up;
  -  bool get _isReversed => _lastAxisDirection == AxisDirection.up || _lastAxisDirection == AxisDirection.left;
  -  // The amount of scroll distance before and after the current position.
  -  double get _beforeExtent => _isReversed ? _lastMetrics!.extentAfter : _lastMetrics!.extentBefore;
  -  double get _afterExtent => _isReversed ? _lastMetrics!.extentBefore : _lastMetrics!.extentAfter;
  -  // Padding of the thumb track.
  -  double get _mainAxisPadding => _isVertical ? padding.vertical : padding.horizontal;
  -  // The length of the painted track.
  -  double get _trackExtent => _lastMetrics!.viewportDimension - _mainAxisPadding;
  -  // The length of the track that is traversable by the thumb.
  -  double get _traversableTrackExtent => _trackExtent - (2 * mainAxisMargin);
  -
  -  // The total size of the scrollable content.
  -  double get _totalContentExtent {
  -    return _lastMetrics!.maxScrollExtent
  -      - _lastMetrics!.minScrollExtent
  -      + _lastMetrics!.viewportDimension;
  -  }
  -
  -  /// Convert between a thumb track position and the corresponding scroll
  -  /// position.
  -  ///
  -  /// thumbOffsetLocal is a position in the thumb track. Cannot be null.
  -  double getTrackToScroll(double thumbOffsetLocal) {
  -    assert(thumbOffsetLocal != null);
  -    final double scrollableExtent = _lastMetrics!.maxScrollExtent - _lastMetrics!.minScrollExtent;
  -    final double thumbMovableExtent = _traversableTrackExtent - _thumbExtent();
  -
  -    return scrollableExtent * thumbOffsetLocal / thumbMovableExtent;
  -  }
  -
  -  // Converts between a scroll position and the corresponding position in the
  -  // thumb track.
  -  double _getScrollToTrack(ScrollMetrics metrics, double thumbExtent) {
  -    final double scrollableExtent = metrics.maxScrollExtent - metrics.minScrollExtent;
  -
  -    final double fractionPast = (scrollableExtent > 0)
  -      ? clampDouble((metrics.pixels - metrics.minScrollExtent) / scrollableExtent, 0.0, 1.0)
  -      : 0;
  -
  -    return (_isReversed ? 1 - fractionPast : fractionPast) * (_traversableTrackExtent - thumbExtent);
  -  }
  -
     @override
     void paint(Canvas canvas, Size size) {
       if (_lastAxisDirection == null
  
positive.code:       ..color = trackColor.withOpacity(trackColor.opacity * fadeoutOpacityAnimation.value);
    }
  
    void _paintScrollbar(Canvas canvas, Size size, double thumbExtent, AxisDirection direction) {
      assert(
        textDirection != null,
        'A TextDirection must be provided before a Scrollbar can be painted.',
      );
  
      final ScrollbarOrientation resolvedOrientation;
  
      if (scrollbarOrientation == null) {
        if (_isVertical) {
          resolvedOrientation = textDirection == TextDirection.ltr
            ? ScrollbarOrientation.right
            : ScrollbarOrientation.left;
        } else {
          resolvedOrientation = ScrollbarOrientation.bottom;
        }
      }
      else {
        resolvedOrientation = scrollbarOrientation!;
      }
  
      final double x, y;
      final Size thumbSize, trackSize;
      final Offset trackOffset, borderStart, borderEnd;
  
      _debugAssertIsValidOrientation(resolvedOrientation);
  
      switch(resolvedOrientation) {
        case ScrollbarOrientation.left:
          thumbSize = Size(thickness, thumbExtent);
          trackSize = Size(thickness + 2 * crossAxisMargin, _trackExtent);
          x = crossAxisMargin + padding.left;
          y = _thumbOffset;
          trackOffset = Offset(x - crossAxisMargin, padding.top);
          borderStart = trackOffset + Offset(trackSize.width, 0.0);
          borderEnd = Offset(trackOffset.dx + trackSize.width, trackOffset.dy + _trackExtent);
          break;
        case ScrollbarOrientation.right:
          thumbSize = Size(thickness, thumbExtent);
          trackSize = Size(thickness + 2 * crossAxisMargin, _trackExtent);
          x = size.width - thickness - crossAxisMargin - padding.right;
          y = _thumbOffset;
          trackOffset = Offset(x - crossAxisMargin, padding.top);
          borderStart = trackOffset;
          borderEnd = Offset(trackOffset.dx, trackOffset.dy + _trackExtent);
          break;
        case ScrollbarOrientation.top:
          thumbSize = Size(thumbExtent, thickness);
          trackSize = Size(_trackExtent, thickness + 2 * crossAxisMargin);
          x = _thumbOffset;
          y = crossAxisMargin + padding.top;
          trackOffset = Offset(padding.left, y - crossAxisMargin);
          borderStart = trackOffset + Offset(0.0, trackSize.height);
          borderEnd = Offset(trackOffset.dx + _trackExtent, trackOffset.dy + trackSize.height);
          break;
        case ScrollbarOrientation.bottom:
          thumbSize = Size(thumbExtent, thickness);
          trackSize = Size(_trackExtent, thickness + 2 * crossAxisMargin);
          x = _thumbOffset;
          y = size.height - thickness - crossAxisMargin - padding.bottom;
          trackOffset = Offset(padding.left, y - crossAxisMargin);
          borderStart = trackOffset;
          borderEnd = Offset(trackOffset.dx + _trackExtent, trackOffset.dy);
          break;
  
negative.code:     thickness = nextThickness;
      radius = nextRadius;
    }
  
    // - Painting
  
    Paint get _paintThumb {
      return Paint()
  