docs: function apportion(subtreeV, subtreeW, ancestor, separation) {
  
      if (subtreeW) {
          var nodeOutRight = subtreeV;
          var nodeInRight = subtreeV;
          var nodeOutLeft = nodeInRight.parentNode.children[0];
          var nodeInLeft = subtreeW;
  
          var sumOutRight = nodeOutRight.hierNode.modifier;
          var sumInRight = nodeInRight.hierNode.modifier;
          var sumOutLeft = nodeOutLeft.hierNode.modifier;
          var sumInLeft = nodeInLeft.hierNode.modifier;
  
          while (nodeInLeft = nextRight(nodeInLeft), nodeInRight = nextLeft(nodeInRight), nodeInLeft && nodeInRight) {
              nodeOutRight = nextRight(nodeOutRight);
              nodeOutLeft = nextLeft(nodeOutLeft);
              nodeOutRight.hierNode.ancestor = subtreeV;
              var shift = nodeInLeft.hierNode.prelim + sumInLeft - nodeInRight.hierNode.prelim
                      - sumInRight + separation(nodeInLeft, nodeInRight);
              if (shift > 0) {
                  moveSubtree(nextAncestor(nodeInLeft, subtreeV, ancestor), subtreeV, shift);
                  sumInRight += shift;
                  sumOutRight += shift;
              }
              sumInLeft += nodeInLeft.hierNode.modifier;
              sumInRight += nodeInRight.hierNode.modifier;
              sumOutRight += nodeOutRight.hierNode.modifier;
              sumOutLeft += nodeOutLeft.hierNode.modifier;
          }
          if (nodeInLeft && !nextRight(nodeOutRight)) {
              nodeOutRight.hierNode.thread = nodeInLeft;
              nodeOutRight.hierNode.modifier += sumInLeft - sumOutRight;
  
          }
          if (nodeInRight && !nextLeft(nodeOutLeft)) {
              nodeOutLeft.hierNode.thread = nodeInRight;
              nodeOutLeft.hierNode.modifier += sumInRight - sumOutLeft;
              ancestor = subtreeV;
          }
      }
      return ancestor;
  }