code: def solveCubic(a, b, c, d):
      """Solve a cubic equation.
  
      Solves *a*x*x*x + b*x*x + c*x + d = 0* where a, b, c and d are real.
  
      Args:
          a: coefficient of *x³*
          b: coefficient of *x²*
          c: coefficient of *x*
          d: constant term
  
      Returns:
          A list of roots. Note that the returned list is neither guaranteed to
          be sorted nor to contain unique values!
  
      Examples::
  
          >>> solveCubic(1, 1, -6, 0)
          [-3.0, -0.0, 2.0]
          >>> solveCubic(-10.0, -9.0, 48.0, -29.0)
          [-2.9, 1.0, 1.0]
          >>> solveCubic(-9.875, -9.0, 47.625, -28.75)
          [-2.911392, 1.0, 1.0]
          >>> solveCubic(1.0, -4.5, 6.75, -3.375)
          [1.5, 1.5, 1.5]
          >>> solveCubic(-12.0, 18.0, -9.0, 1.50023651123)
          [0.5, 0.5, 0.5]
          >>> solveCubic(
          ...     9.0, 0.0, 0.0, -7.62939453125e-05
          ... ) == [-0.0, -0.0, -0.0]
          True
      """
      #
      # adapted from:
      #   CUBIC.C - Solve a cubic polynomial
      #   public domain by Ross Cottrell
      # found at: http://www.strangecreations.com/library/snippets/Cubic.C
      #
      if abs(a) < epsilon:
          # don't just test for zero; for very small values of 'a' solveCubic()
          # returns unreliable results, so we fall back to quad.
          return solveQuadratic(b, c, d)
      a = float(a)
      a1 = b / a
      a2 = c / a
      a3 = d / a
  
      Q = (a1 * a1 - 3.0 * a2) / 9.0
      R = (2.0 * a1 * a1 * a1 - 9.0 * a1 * a2 + 27.0 * a3) / 54.0
  
      R2 = R * R
      Q3 = Q * Q * Q
      R2 = 0 if R2 < epsilon else R2
      Q3 = 0 if abs(Q3) < epsilon else Q3
  
      R2_Q3 = R2 - Q3
  
      if R2 == 0.0 and Q3 == 0.0:
          x = round(-a1 / 3.0, epsilonDigits)
          return [x, x, x]
      elif R2_Q3 <= epsilon * 0.5:
          # The epsilon * .5 above ensures that Q3 is not zero.
          theta = acos(max(min(R / sqrt(Q3), 1.0), -1.0))
          rQ2 = -2.0 * sqrt(Q)
          a1_3 = a1 / 3.0
          x0 = rQ2 * cos(theta / 3.0) - a1_3
          x1 = rQ2 * cos((theta + 2.0 * pi) / 3.0) - a1_3
          x2 = rQ2 * cos((theta + 4.0 * pi) / 3.0) - a1_3
          x0, x1, x2 = sorted([x0, x1, x2])
          # Merge roots that are close-enough
          if x1 - x0 < epsilon and x2 - x1 < epsilon:
              x0 = x1 = x2 = round((x0 + x1 + x2) / 3.0, epsilonDigits)
          elif x1 - x0 < epsilon:
              x0 = x1 = round((x0 + x1) / 2.0, epsilonDigits)
              x2 = round(x2, epsilonDigits)
          elif x2 - x1 < epsilon:
              x0 = round(x0, epsilonDigits)
              x1 = x2 = round((x1 + x2) / 2.0, epsilonDigits)
          else:
              x0 = round(x0, epsilonDigits)
              x1 = round(x1, epsilonDigits)
              x2 = round(x2, epsilonDigits)
          return [x0, x1, x2]
      else:
          x = pow(sqrt(R2_Q3) + abs(R), 1 / 3.0)
          x = x + Q / x
          if R >= 0.0:
              x = -x
          x = round(x - a1 / 3.0, epsilonDigits)
          return [x]
  
imports: from fontTools.misc.arrayTools import calcBounds, sectRect, rectArea
  from fontTools.misc.transform import Identity
  import math
  from collections import namedtuple
  from math import sqrt, acos, cos, pi
label_desc: Use image node_id 26 for calling a global function with example usage: solveCubic(a, b, c, d) and returns: solveQuadratic, list, list, list