code: def node(self, rows, ind, dep, depth=0, parent=None, parent_decisions=None):
          
          depth += 1
  
          if self.max_depth < depth:
              terminal_node = Node(choices=parent_decisions, node_id=self.node_count,
                                   parent=parent, indices=rows, dep_v=dep)
              self._tree_store.append(terminal_node)
              self.node_count += 1
              terminal_node.split.invalid_reason = InvalidSplitReason.MAX_DEPTH
              return self._tree_store
  
          split = self._stats.best_split(ind, dep)
  
          node = Node(choices=parent_decisions, node_id=self.node_count, indices=rows, dep_v=dep,
                      parent=parent, split=split)
  
          self._tree_store.append(node)
          parent = self.node_count
          self.node_count += 1
  
          if not split.valid():
              return self._tree_store
  
          for index, choices in enumerate(split.splits):
              correct_rows = np.in1d(ind[split.column_id].arr, choices)
              dep_slice = dep[correct_rows]
              ind_slice = [vect[correct_rows] for vect in ind]
              row_slice = rows[correct_rows]
              if self.min_parent_node_size < len(dep_slice.arr):
                  self.node(row_slice, ind_slice, dep_slice, depth=depth, parent=parent,
                            parent_decisions=split.split_map[index])
              else:
                  terminal_node = Node(choices=split.split_map[index], node_id=self.node_count,
                                       parent=parent, indices=row_slice, dep_v=dep_slice)
                  terminal_node.split.invalid_reason = InvalidSplitReason.MIN_PARENT_NODE_SIZE
                  self._tree_store.append(terminal_node)
                  self.node_count += 1
          return self._tree_store
docs: internal method to create a node in the tree