here are interfaces of some classes:
```

class RectFactory {
  constructor(container, basePluginParams = {})
  scheduleRenderCSS() 
  registerPlugin(pluginClass, options = {}, pluginName = null)
  _newPluginContext(pluginId, globalDefaults)
  unregisterPlugin(pluginKey) 
  updatePluginOptions(pluginKey, options)
  renderCSS() 
  defineProfile(profileName, pluginKeys = [])
  createRect(baseParams, profileName = "base", pluginKeyParamPairs = [])
  _onRectRemove(rect, rectElement)
  _getProfile(profileName)
  _getPluginByKey(pluginKey)
  getPluginContext(pluginKey)
  getAll()
}

class DrawArea extends EventEmitter {
  constructor(
    container,
    {
      drawStartWidth = 5,
      drawStartHeight = 5,
      minWidth = 50,
      minHeight = 50,
    } = {}
  )
  getContainer()
  start(container)
  stop()
  #getElementPageCoordinates(element)
  handleMouseDown(e)
  handleMouseMove(e)
  handleMouseUp(e), currentRect);
  }
}

class OverlayManager {
  constructor(targetElement, options = {}) 
  debounce(func, wait)
  init()
  start()
  stop()
  #setContent(newContent)
  setContent(newContent)
  destroy()
  trapFocus()
  handleKeyDown(event)
}

```

this is the main file:
```
import OverlayManager from "./overlay-manager.mjs";
import DrawArea from "./draw-area.mjs";
import {
  VertexPlugin,
  MousePlugin,
  RectFactory,
  RectCursorAction,
} from "./rect-factory.mjs";

class DrawHandler {
  constructor(drawarea, factory) {
    this.drawarea = drawarea;
    this.factory = factory;
    this.rect = null;
    this.isInitialized = false; // Keep track if setup has been done
  }

  // This method sets up the event listeners and starts the drawing process
  initializeDrawing() {
    if (this.isInitialized) {
      console.warn("Drawing is already initialized.");
      return;
    }

    this.drawarea.on("draw:upsert", this.handleUpsert.bind(this));
    this.drawarea.on("draw:end", this.handleEnd.bind(this));

    this.isInitialized = true; // Mark as initialized
    console.log("Drawing initialized.");
  }

  handleUpsert({ x, y, width, height }) {
    console.log(x, y);
    if (this.rect) {
      this.rect.update({ x, y, width, height });
    } else {
      this.rect = this.factory.createRect({ x, y, width, height });
    }
  }

  handleEnd({ shouldCreate }) {
    if (shouldCreate) {
      this.rect?.useProfile("normal");
    } else {
      this.rect?.remove();
    }
    this.rect = null;
  }
}

const container = document.createElement("div");
Object.assign(container.style, {
  width: "100%",
  height: "100%",
});
const overlay = new OverlayManager(document.body, {
  content: container,
});
overlay.init();
const minSize = {
  minWidth: 50,
  minHeight: 50,
};
const factory = new RectFactory(container, {
  borderColor: "#3498db",
  borderSize: "2px",
  fill: "rgba(52, 152, 219, 0.2)",
});
factory.registerPlugin(VertexPlugin, {
  size: "10px",
  color: "red",
  autohide: true,
});
factory.registerPlugin(MousePlugin, { ...minSize });
factory.defineProfile("normal", [VertexPlugin, MousePlugin]);
RectCursorAction.setNullActionCursor("crosshair");
const drawarea = new DrawArea(container, { ...minSize });
const drawHandler = new DrawHandler(drawarea, factory);
overlay.start();
drawarea.start();
drawHandler.initializeDrawing();
```

1. suggest better names than `DrawHandler`
2. structure the main code into a class with methods: `start` (which also inits), `stop`, `destroy`(deinit), `getAllRects`