add(a1, a2, a3) {
    const isAnim = isObj(a2);
    const isTimer = isObj(a1);
    const isFunc = isFnc(a1);
    if (isAnim || isTimer || isFunc) {
      this._hasChildren = true;
      if (isAnim) {
        const childParams = /** @type {AnimationParams} */(a2);
        // Check for function for children stagger positions
        if (isFnc(a3)) {
          const staggeredPosition = /** @type {Function} */(a3);
          const parsedTargetsArray = parseTargets(/** @type {TargetsParam} */(a1));
          // Store initial duration before adding new children that will change the duration
          const tlDuration = this.duration;
          // Store initial _iterationDuration before adding new children that will change the duration
          const tlIterationDuration = this._iterationDuration;
          // Store the original id in order to add specific indexes to the new animations ids
          const id = childParams.id;
          let i = 0;
          const parsedLength = parsedTargetsArray.length;
          parsedTargetsArray.forEach((/** @type {Target} */target) => {
            // Create a new parameter object for each staggered children
            const staggeredChildParams = { ...childParams };
            // Reset the duration of the timeline iteration before each stagger to prevent wrong start value calculation
            this.duration = tlDuration;
            this._iterationDuration = tlIterationDuration;
            if (!isUnd(id)) staggeredChildParams.id = id + '-' + i;
            addTlChild(
              staggeredChildParams,
              this,
              staggeredPosition(target, i, parsedLength, this),
              target,
              i,
              parsedLength
            );
            i++;
          });
        } else {
          addTlChild(
            childParams,
            this,
            parseTimelinePosition(this, a3),
            /** @type {TargetsParam} */(a1),
          );
        }
      } else {
        // It's a Timer or a Function
        addTlChild(
          /** @type TimerParams */(isTimer ? a1 : { onComplete: a1, duration: minValue }),
          this,
          parseTimelinePosition(this,/** @type TimePosition */(a2)),
        );
      }
      this.init(1); // 1 = internalRender
      return this._autoplay === true ? this.play() : this;
    } else if (isStr(a1)) {
      this.labels[a1] = parseTimelinePosition(this,/** @type TimePosition */(a2));
      return this;
    }
  }
@overload
@param {TargetsParam} a1
@param {AnimationParams} a2
@param {TimePosition} [a3]
@return {this}

@overload
@param {TimerParams} a1
@param {TimePosition} [a2]
@return {this}

@overload
@param {String} a1
@param {TimePosition} [a2]
@return {this}

@overload
@param {TimerCallback} a1
@param {TimePosition} [a2]
@return {this}

@param {TargetsParam|TimerParams|String|TimerCallback} a1
@param {AnimationParams|TimePosition} a2
@param {TimePosition} [a3]