constructor(containers = [document.body], options = {}) {
    /**
     * Draggable containers
     * @property containers
     * @type {HTMLElement[]}
     */
    if (containers instanceof NodeList || containers instanceof Array) {
      this.containers = [...containers];
    } else if (containers instanceof HTMLElement) {
      this.containers = [containers];
    } else {
      throw new Error(
        'Draggable containers are expected to be of type `NodeList`, `HTMLElement[]` or `HTMLElement`',
      );
    }

    this.options = {
      ...defaultOptions,
      ...options,
      classes: {
        ...defaultClasses,
        ...(options.classes || {}),
      },
      announcements: {
        ...defaultAnnouncements,
        ...(options.announcements || {}),
      },
      exclude: {
        plugins: (options.exclude && options.exclude.plugins) || [],
        sensors: (options.exclude && options.exclude.sensors) || [],
      },
    };

    /**
     * Draggables event emitter
     * @property emitter
     * @type {Emitter}
     */
    this.emitter = new Emitter();

    /**
     * Current drag state
     * @property dragging
     * @type {Boolean}
     */
    this.dragging = false;

    /**
     * Active plugins
     * @property plugins
     * @type {Plugin[]}
     */
    this.plugins = [];

    /**
     * Active sensors
     * @property sensors
     * @type {Sensor[]}
     */
    this.sensors = [];

    this[onDragStart] = this[onDragStart].bind(this);
    this[onDragMove] = this[onDragMove].bind(this);
    this[onDragStop] = this[onDragStop].bind(this);
    this[onDragPressure] = this[onDragPressure].bind(this);
    this[dragStop] = this[dragStop].bind(this);

    document.addEventListener('drag:start', this[onDragStart], true);
    document.addEventListener('drag:move', this[onDragMove], true);
    document.addEventListener('drag:stop', this[onDragStop], true);
    document.addEventListener('drag:pressure', this[onDragPressure], true);

    const defaultPlugins = Object.values(Draggable.Plugins).filter(
      (Plugin) => !this.options.exclude.plugins.includes(Plugin),
    );
    const defaultSensors = Object.values(Draggable.Sensors).filter(
      (sensor) => !this.options.exclude.sensors.includes(sensor),
    );

    this.addPlugin(...[...defaultPlugins, ...this.options.plugins]);
    this.addSensor(...[...defaultSensors, ...this.options.sensors]);

    const draggableInitializedEvent = new DraggableInitializedEvent({
      draggable: this,
    });

    this.on('mirror:created', ({mirror}) => (this.mirror = mirror));
    this.on('mirror:destroy', () => (this.mirror = null));

    this.trigger(draggableInitializedEvent);
  }
Draggable constructor.
@constructs Draggable
@param {HTMLElement[]|NodeList|HTMLElement} containers - Draggable containers
@param {Object} options - Options for draggable