(function (global) {
  global.ARQ = global.ARQ || {};
  var canvas = null;
  var currentStroke = null;
  var panning = false;
  var panStart = null;
  var shapeStart = null;
  var transformDrag = null;
  var marqueeDrag = null;
  var lassoDrag = null;
  var cropDrag = null;
  var moverDrag = null;

  function copyCorners(c) {
    return c.map(function (p) { return { x: p.x, y: p.y }; });
  }

  function centroid4(c) {
    var x = 0, y = 0, i;
    for (i = 0; i < 4; i++) { x += c[i].x; y += c[i].y; }
    return { x: x / 4, y: y / 4 };
  }

  function cropConstrain(x0, y0, x1, y1, fixedRatio) {
    if (!fixedRatio) return { x0: x0, y0: y0, x1: x1, y1: y1 };
    var w = x1 - x0;
    var h = y1 - y0;
    var aw = Math.abs(w);
    var ah = Math.abs(h);
    var s = Math.max(aw, ah);
    if (w < 0) x1 = x0 - s; else x1 = x0 + s;
    if (h < 0) y1 = y0 - s; else y1 = y0 + s;
    return { x0: x0, y0: y0, x1: x1, y1: y1 };
  }

  ARQ.pointer = {
    getLiveStroke: function () { return currentStroke; },
    init: function (el) {
      canvas = el;
      el.addEventListener('pointerdown', this._down.bind(this), { passive: false });
      el.addEventListener('pointermove', this._move.bind(this), { passive: false });
      el.addEventListener('pointerup', this._up.bind(this));
      el.addEventListener('pointercancel', this._up.bind(this));
    },
    _prefs: function () {
      return ARQ.storage.get(ARQ.STORAGE_KEYS.UI_PREFS) || {};
    },
    _down: function (e) {
      if (global.ARQ._twoFingerNav) return;
      if (ARQ.viewport && ARQ.viewport.isViewportBlockingDraw && ARQ.viewport.isViewportBlockingDraw()) {
        return;
      }
      var prefs = this._prefs();
      if (prefs.stylusOnly === true && ARQ.tools.isDrawTool() && e.pointerType === 'touch') {
        return;
      }
      var project = ARQ.store.getProject();
      var sheet = ARQ.utils.activeSheet(project);
      if (!sheet) return;
      var tool = ARQ.tools.currentTool();
      var p = ARQ.viewport.screenToSheet(e.clientX, e.clientY);

      if (tool === 'pan') {
        panning = true;
        sheet.pan_actual = sheet.pan_actual || { x: 0, y: 0 };
        panStart = { x: e.clientX, y: e.clientY, px: sheet.pan_actual.x, py: sheet.pan_actual.y };
        try { canvas.setPointerCapture(e.pointerId); } catch (err) {}
        e.preventDefault();
        return;
      }

      if (tool === 'marquee' && ARQ.selection) {
        marqueeDrag = { x0: p.x, y0: p.y };
        try { canvas.setPointerCapture(e.pointerId); } catch (errM) {}
        e.preventDefault();
        return;
      }

      if (tool === 'lasso' && ARQ.selection) {
        lassoDrag = { points: [{ x: p.x, y: p.y }] };
        ARQ.selection.setDraftLasso(sheet, lassoDrag.points);
        try { canvas.setPointerCapture(e.pointerId); } catch (errL) {}
        e.preventDefault();
        return;
      }

      if (tool === 'wand' && ARQ.selection && ARQ.floodFill) {
        if (ARQ.tools.syncFromDom) ARQ.tools.syncFromDom();
        var layerW = ARQ.store.activeLayer();
        if (!layerW || !ARQ.guards.canDrawOnLayer(layerW)) {
          ARQ.bus.emit(ARQ.EVENTS.TOAST, 'Capa bloqueada u oculta');
          return;
        }
        var w = sheet.ancho || 1920;
        var h = sheet.alto || 1080;
        var px = Math.floor(p.x);
        var py = Math.floor(p.y);
        if (px < 0 || py < 0 || px >= w || py >= h) return;
        var combine = ARQ.selection.combineMode(e.shiftKey, e.altKey);
        var tol = ARQ.tools.wandTolerance != null ? ARQ.tools.wandTolerance : 48;
        var contig = ARQ.tools.wandContiguous !== false;
        ARQ.canvasEngine.preloadLayerImages(sheet, [layerW]).then(function () {
          var c = global.document.createElement('canvas');
          c.width = w;
          c.height = h;
          var ctx = c.getContext('2d');
          if (!ctx) return;
          ctx.clearRect(0, 0, w, h);
          ctx.save();
          ctx.globalAlpha = layerW.opacidad != null ? layerW.opacidad : 1;
          ARQ.canvasEngine.renderLayersToContext(ctx, sheet, [layerW], { includeBackground: false });
          ctx.restore();
          var imageData = ctx.getImageData(0, 0, w, h);
          var mask = ARQ.floodFill.buildSelectionMask(imageData, w, h, px, py, tol, contig);
          ARQ.selection.applyBinaryMask(sheet, mask, combine);
          if (ARQ.history.pushDescription) ARQ.history.pushDescription('Varita mágica');
          if (ARQ.actionLog && ARQ.actionLog.append) {
            ARQ.actionLog.append(sheet, 'wand', layerW.id, { x: px, y: py, tolerance: tol, contiguo: contig, combine: combine });
          }
        }).catch(function () {});
        e.preventDefault();
        return;
      }

      if (tool === 'crop' && ARQ.selection) {
        if (ARQ.tools.syncFromDom) ARQ.tools.syncFromDom();
        cropDrag = { x0: p.x, y0: p.y };
        try { canvas.setPointerCapture(e.pointerId); } catch (errC) {}
        e.preventDefault();
        return;
      }

      if (tool === 'mover') {
        if (ARQ.selection && ARQ.selection.hasMask(sheet)) {
          ARQ.history.pushUndo();
          moverDrag = { kind: 'selection', x0: p.x, y0: p.y };
          try { canvas.setPointerCapture(e.pointerId); } catch (errV) {}
          e.preventDefault();
          return;
        }
        if (!ARQ.transform || !ARQ.viewport) return;
        var hitMove = ARQ.transform.findTopImageLayerAt(sheet, p);
        if (hitMove) {
          ARQ.store.setActiveLayerId(hitMove.id);
          if (ARQ.layers && ARQ.layers.renderPanel) ARQ.layers.renderPanel();
          ARQ.transform.ensureQuadCorners(hitMove);
          var mc = ARQ.transform.getCorners(hitMove);
          ARQ.history.pushUndo();
          moverDrag = {
            kind: 'layer',
            layerId: hitMove.id,
            startCorners: copyCorners(mc),
            originP: { x: p.x, y: p.y },
          };
          try { canvas.setPointerCapture(e.pointerId); } catch (errV2) {}
          e.preventDefault();
          return;
        }
        ARQ.bus.emit(ARQ.EVENTS.TOAST, 'Nada que mover en este punto');
        e.preventDefault();
        return;
      }

      if (tool === 'select') {
        if (!ARQ.transform || !ARQ.viewport) return;
        if (ARQ.transform.isActive()) {
          var tl = null;
          (sheet.capas || []).forEach(function (l) {
            if (l.id === ARQ.transform.layerId) tl = l;
          });
          if (tl && tl.contenido && tl.contenido.imageSrc && ARQ.guards.canDrawOnLayer(tl)) {
            ARQ.transform.ensureQuadCorners(tl);
            var tc = ARQ.transform.getCorners(tl);
            var th = ARQ.transform.hitTest(p, tc);
            if (th) {
              ARQ.history.pushUndo();
              if (th.kind === 'corner') {
                transformDrag = { kind: 'corner', layerId: tl.id, index: th.index, startCorners: copyCorners(tc), originP: { x: p.x, y: p.y } };
              } else if (th.kind === 'edge') {
                transformDrag = { kind: 'edge', layerId: tl.id, index: th.index, startCorners: copyCorners(tc), originP: { x: p.x, y: p.y } };
              } else if (th.kind === 'body') {
                transformDrag = {
                  kind: 'body',
                  layerId: tl.id,
                  startCorners: copyCorners(tc),
                  originP: { x: p.x, y: p.y },
                };
              } else if (th.kind === 'rotate') {
                var C = centroid4(tc);
                transformDrag = {
                  kind: 'rotate',
                  layerId: tl.id,
                  startCorners: copyCorners(tc),
                  center: C,
                  angle0: Math.atan2(p.y - C.y, p.x - C.x),
                };
              }
              try { canvas.setPointerCapture(e.pointerId); } catch (err2) {}
              e.preventDefault();
              return;
            }
          }
          ARQ.transform.deactivate();
          ARQ.canvasEngine.redraw();
        }
        var hitLayer = ARQ.transform.findTopImageLayerAt(sheet, p);
        if (hitLayer) {
          ARQ.store.setActiveLayerId(hitLayer.id);
          if (ARQ.layers && ARQ.layers.renderPanel) ARQ.layers.renderPanel();
          ARQ.transform.activate(hitLayer.id);
          ARQ.transform.ensureQuadCorners(hitLayer);
          var oc = ARQ.transform.getCorners(hitLayer);
          var h2 = ARQ.transform.hitTest(p, oc);
          if (h2) {
            ARQ.history.pushUndo();
            if (h2.kind === 'corner') {
              transformDrag = { kind: 'corner', layerId: hitLayer.id, index: h2.index, startCorners: copyCorners(oc), originP: { x: p.x, y: p.y } };
            } else if (h2.kind === 'edge') {
              transformDrag = { kind: 'edge', layerId: hitLayer.id, index: h2.index, startCorners: copyCorners(oc), originP: { x: p.x, y: p.y } };
            } else if (h2.kind === 'body') {
              transformDrag = {
                kind: 'body',
                layerId: hitLayer.id,
                startCorners: copyCorners(oc),
                originP: { x: p.x, y: p.y },
              };
            } else if (h2.kind === 'rotate') {
              var C2 = centroid4(oc);
              transformDrag = {
                kind: 'rotate',
                layerId: hitLayer.id,
                startCorners: copyCorners(oc),
                center: C2,
                angle0: Math.atan2(p.y - C2.y, p.x - C2.x),
              };
            }
            try { canvas.setPointerCapture(e.pointerId); } catch (err3) {}
          }
          ARQ.canvasEngine.redraw();
          e.preventDefault();
          return;
        }
        ARQ.transform.deactivate();
        if (ARQ.selection) ARQ.selection.clear(sheet);
        ARQ.canvasEngine.redraw();
        return;
      }

      if (ARQ.tools.isShapeTool()) {
        shapeStart = { x: p.x, y: p.y, tool: tool };
        try { canvas.setPointerCapture(e.pointerId); } catch (err) {}
        e.preventDefault();
        return;
      }

      if (tool === 'bote_pintura') {
        if (ARQ.tools.syncFromDom) ARQ.tools.syncFromDom();
        var layerB = ARQ.store.activeLayer();
        if (!layerB || !ARQ.guards.canDrawOnLayer(layerB)) {
          ARQ.bus.emit(ARQ.EVENTS.TOAST, 'Capa bloqueada u oculta');
          return;
        }
        ARQ.history.pushUndo();
        if (ARQ.bucketFill && ARQ.bucketFill.applyAtSheetPoint) {
          ARQ.bucketFill.applyAtSheetPoint(layerB, sheet, p).then(function (filled) {
            if (filled > 0) {
              ARQ.history.pushDescription('Bote de pintura');
              ARQ.layers && ARQ.layers.renderPanel && ARQ.layers.renderPanel();
            } else if (ARQ.history && ARQ.history.undo) {
              ARQ.history.undo();
            }
          }).catch(function () {
            if (ARQ.history && ARQ.history.undo) ARQ.history.undo();
            ARQ.bus.emit(ARQ.EVENTS.TOAST, 'No se pudo rellenar');
          });
        }
        e.preventDefault();
        return;
      }

      if (tool === 'texto') {
        ARQ.dialog.prompt('Texto:', '').then(function (txt) {
          if (!txt) return;
          ARQ.history.pushUndo();
          var layer = ARQ.store.activeLayer();
          if (!layer || !ARQ.guards.canDrawOnLayer(layer)) return;
          var cont = layer.contenido || {};
          cont.texts = cont.texts || [];
          cont.texts.push({
            id: ARQ.utils.uuid(),
            x: p.x,
            y: p.y,
            text: txt,
            fontSize: 28,
            color: ARQ.tools.color,
            opacidad: ARQ.tools.opacity,
          });
          layer.contenido = cont;
          ARQ.store.setDirty(true);
          ARQ.canvasEngine.requestRedraw();
          ARQ.history.pushDescription('Texto');
        });
        return;
      }

      if (!ARQ.tools.isDrawTool()) return;
      var layer = ARQ.store.activeLayer();
      if (!layer || !ARQ.guards.canDrawOnLayer(layer)) {
        ARQ.bus.emit(ARQ.EVENTS.TOAST, 'Capa bloqueada u oculta');
        return;
      }
      ARQ.history.pushUndo();
      layer.contenido = layer.contenido || {};
      layer.contenido.strokes = layer.contenido.strokes || [];
      currentStroke = {
        id: ARQ.utils.uuid(),
        herramienta: tool,
        color: ARQ.tools.color,
        color_id_material: ARQ.tools.colorMaterialId,
        grosor: ARQ.tools.size,
        opacidad: ARQ.tools.opacity,
        suavizado: ARQ.tools.smooth,
        puntos: [{ x: p.x, y: p.y }],
        pressure: [],
      };
      try { canvas.setPointerCapture(e.pointerId); } catch (err) {}
      e.preventDefault();
    },
    _move: function (e) {
      if (transformDrag && ARQ.viewport) {
        var p = ARQ.viewport.screenToSheet(e.clientX, e.clientY);
        var project = ARQ.store.getProject();
        var sheet = ARQ.utils.activeSheet(project);
        var lyr = null;
        ((sheet && sheet.capas) || []).forEach(function (l) {
          if (l.id === transformDrag.layerId) lyr = l;
        });
        if (!lyr || !lyr.contenido) {
          transformDrag = null;
          return;
        }
        var tr = lyr.contenido.imageTransform || {};
        var corners = tr.corners && tr.corners.length === 4 ? copyCorners(tr.corners) : ARQ.transform.getCorners(lyr);
        if (transformDrag.kind === 'corner') {
          var sc = transformDrag.startCorners;
          var O = sc[(transformDrag.index + 2) % 4];
          if (e.shiftKey) {
            var C0 = sc[transformDrag.index];
            var l0 = Math.hypot(C0.x - O.x, C0.y - O.y) || 1;
            var lp = Math.hypot(p.x - O.x, p.y - O.y) || 1;
            var s = lp / l0;
            corners[transformDrag.index] = {
              x: O.x + (C0.x - O.x) * s,
              y: O.y + (C0.y - O.y) * s,
            };
          } else {
            corners[transformDrag.index] = { x: p.x, y: p.y };
          }
          ARQ.transform.setCorners(lyr, corners);
        } else if (transformDrag.kind === 'edge') {
          var ii = transformDrag.index;
          var jj = (ii + 1) % 4;
          var dx = p.x - transformDrag.originP.x;
          var dy = p.y - transformDrag.originP.y;
          var scE = transformDrag.startCorners;
          corners = copyCorners(scE);
          corners[ii] = { x: scE[ii].x + dx, y: scE[ii].y + dy };
          corners[jj] = { x: scE[jj].x + dx, y: scE[jj].y + dy };
          ARQ.transform.setCorners(lyr, corners);
        } else if (transformDrag.kind === 'body') {
          var dxb = p.x - transformDrag.originP.x;
          var dyb = p.y - transformDrag.originP.y;
          var moved = transformDrag.startCorners.map(function (c) {
            return { x: c.x + dxb, y: c.y + dyb };
          });
          ARQ.transform.setCorners(lyr, moved);
        } else if (transformDrag.kind === 'rotate') {
          var a1 = Math.atan2(p.y - transformDrag.center.y, p.x - transformDrag.center.x);
          var delta = a1 - transformDrag.angle0;
          var rotated = ARQ.transform.rotateCornersAround(transformDrag.startCorners, transformDrag.center, delta);
          ARQ.transform.setCorners(lyr, rotated);
        }
        ARQ.store.setDirty(true);
        ARQ.canvasEngine.requestRedraw();
        e.preventDefault();
        return;
      }
      if (moverDrag && moverDrag.kind === 'layer' && ARQ.viewport) {
        var pm = ARQ.viewport.screenToSheet(e.clientX, e.clientY);
        var projM = ARQ.store.getProject();
        var sheetM = ARQ.utils.activeSheet(projM);
        var lyrM = null;
        ((sheetM && sheetM.capas) || []).forEach(function (l) {
          if (l.id === moverDrag.layerId) lyrM = l;
        });
        if (lyrM && lyrM.contenido) {
          var dxm = pm.x - moverDrag.originP.x;
          var dym = pm.y - moverDrag.originP.y;
          var movedC = moverDrag.startCorners.map(function (c) {
            return { x: c.x + dxm, y: c.y + dym };
          });
          ARQ.transform.setCorners(lyrM, movedC);
          ARQ.store.setDirty(true);
          ARQ.canvasEngine.requestRedraw();
        }
        e.preventDefault();
        return;
      }
      if (marqueeDrag && ARQ.selection && ARQ.viewport) {
        var pr = ARQ.viewport.screenToSheet(e.clientX, e.clientY);
        var sheetR = ARQ.utils.activeSheet(ARQ.store.getProject());
        if (sheetR) ARQ.selection.setDraftRect(sheetR, marqueeDrag.x0, marqueeDrag.y0, pr.x, pr.y);
        e.preventDefault();
        return;
      }
      if (lassoDrag && ARQ.selection && ARQ.viewport) {
        var pl = ARQ.viewport.screenToSheet(e.clientX, e.clientY);
        lassoDrag.points.push({ x: pl.x, y: pl.y });
        var sheetL = ARQ.utils.activeSheet(ARQ.store.getProject());
        if (sheetL) ARQ.selection.setDraftLasso(sheetL, lassoDrag.points);
        e.preventDefault();
        return;
      }
      if (cropDrag && ARQ.selection && ARQ.viewport) {
        var pc = ARQ.viewport.screenToSheet(e.clientX, e.clientY);
        var sheetC = ARQ.utils.activeSheet(ARQ.store.getProject());
        if (sheetC) {
          var cr = cropConstrain(cropDrag.x0, cropDrag.y0, pc.x, pc.y, ARQ.tools.cropFixedRatio === true);
          ARQ.selection.setCropDraft(sheetC, cr.x0, cr.y0, cr.x1, cr.y1);
        }
        e.preventDefault();
        return;
      }
      if (ARQ.viewport && ARQ.viewport.isViewportBlockingDraw && ARQ.viewport.isViewportBlockingDraw()) {
        if (currentStroke) {
          currentStroke = null;
          try { canvas.releasePointerCapture(e.pointerId); } catch (err) {}
          if (ARQ.history && ARQ.history.undo) ARQ.history.undo();
          ARQ.canvasEngine.redraw();
        }
        if (shapeStart) {
          shapeStart = null;
          try { canvas.releasePointerCapture(e.pointerId); } catch (err) {}
          ARQ.canvasEngine.redraw();
        }
        return;
      }
      if (panning && panStart) {
        var sheetP = ARQ.utils.activeSheet(ARQ.store.getProject());
        if (sheetP) {
          sheetP.pan_actual = sheetP.pan_actual || { x: 0, y: 0 };
          sheetP.pan_actual.x = panStart.px + (e.clientX - panStart.x);
          sheetP.pan_actual.y = panStart.py + (e.clientY - panStart.y);
          ARQ.viewport.applyFromSheet(sheetP);
        }
        e.preventDefault();
        return;
      }
      if (shapeStart) {
        ARQ.canvasEngine.requestRedraw();
        e.preventDefault();
        return;
      }
      if (!currentStroke) return;
      var prs = e.pressure != null && e.pressure > 0 ? e.pressure : 1;
      var ps = ARQ.viewport.screenToSheet(e.clientX, e.clientY);
      currentStroke.puntos.push({ x: ps.x, y: ps.y });
      currentStroke.pressure.push(prs);
      ARQ.canvasEngine.requestRedraw();
      e.preventDefault();
    },
    _up: function (e) {
      var project = ARQ.store.getProject();
      var sheet = ARQ.utils.activeSheet(project);

      if (marqueeDrag && ARQ.selection && sheet && ARQ.viewport) {
        var pEnd = ARQ.viewport.screenToSheet(e.clientX, e.clientY);
        var combine = ARQ.selection.combineMode(e.shiftKey, e.altKey);
        ARQ.selection.applyRect(sheet, marqueeDrag.x0, marqueeDrag.y0, pEnd.x, pEnd.y, combine);
        marqueeDrag = null;
        try { canvas.releasePointerCapture(e.pointerId); } catch (errM2) {}
        if (ARQ.history.pushDescription) ARQ.history.pushDescription('Marco de selección');
        if (ARQ.actionLog && ARQ.actionLog.append) {
          ARQ.actionLog.append(sheet, 'marquee', null, { combine: combine });
        }
        ARQ.canvasEngine.redraw();
        return;
      }

      if (lassoDrag && ARQ.selection && sheet) {
        var combL = ARQ.selection.combineMode(e.shiftKey, e.altKey);
        if (lassoDrag.points.length >= 3) {
          ARQ.selection.applyPolygon(sheet, lassoDrag.points, combL);
          if (ARQ.history.pushDescription) ARQ.history.pushDescription('Lazo');
          if (ARQ.actionLog && ARQ.actionLog.append) {
            ARQ.actionLog.append(sheet, 'lasso', null, { puntos: lassoDrag.points.length, combine: combL });
          }
        } else {
          ARQ.selection.clearDraft(sheet);
        }
        lassoDrag = null;
        try { canvas.releasePointerCapture(e.pointerId); } catch (errL2) {}
        ARQ.canvasEngine.redraw();
        return;
      }

      if (cropDrag && ARQ.selection && sheet && ARQ.viewport) {
        var pCe = ARQ.viewport.screenToSheet(e.clientX, e.clientY);
        var crF = cropConstrain(cropDrag.x0, cropDrag.y0, pCe.x, pCe.y, ARQ.tools.cropFixedRatio === true);
        ARQ.selection.setCropDraft(sheet, crF.x0, crF.y0, crF.x1, crF.y1);
        cropDrag = null;
        try { canvas.releasePointerCapture(e.pointerId); } catch (errC2) {}
        ARQ.canvasEngine.redraw();
        return;
      }

      if (moverDrag && sheet && ARQ.selection) {
        if (moverDrag.kind === 'selection') {
          var pV = ARQ.viewport.screenToSheet(e.clientX, e.clientY);
          var ddx = pV.x - moverDrag.x0;
          var ddy = pV.y - moverDrag.y0;
          var layerV = ARQ.store.activeLayer();
          if (layerV && (Math.abs(ddx) > 0.5 || Math.abs(ddy) > 0.5)) {
            ARQ.selection.moveMaskedPixels(sheet, layerV, ddx, ddy).then(function (ok) {
              if (ok && ARQ.history.pushDescription) ARQ.history.pushDescription('Mover selección');
              if (ok && ARQ.actionLog && ARQ.actionLog.append) {
                ARQ.actionLog.append(sheet, 'move_selection', layerV.id, { dx: ddx, dy: ddy });
              }
              if (!ok && ARQ.history.undo) ARQ.history.undo();
              ARQ.layers && ARQ.layers.renderPanel && ARQ.layers.renderPanel();
            });
          } else if (ARQ.history.undo) ARQ.history.undo();
        } else if (moverDrag.kind === 'layer') {
          var pEndL = ARQ.viewport.screenToSheet(e.clientX, e.clientY);
          var ddxl = pEndL.x - moverDrag.originP.x;
          var ddyl = pEndL.y - moverDrag.originP.y;
          if (Math.abs(ddxl) < 0.5 && Math.abs(ddyl) < 0.5) {
            if (ARQ.history.undo) ARQ.history.undo();
          } else {
            if (ARQ.history.pushDescription) ARQ.history.pushDescription('Mover capa');
            if (ARQ.actionLog && ARQ.actionLog.append) {
              ARQ.actionLog.append(sheet, 'move_layer', moverDrag.layerId, { dx: ddxl, dy: ddyl });
            }
          }
        }
        moverDrag = null;
        try { canvas.releasePointerCapture(e.pointerId); } catch (errV3) {}
        ARQ.canvasEngine.redraw();
        ARQ.bus.emit(ARQ.EVENTS.HISTORY_CHANGED);
        return;
      }

      if (transformDrag) {
        var tLayerId = transformDrag.layerId;
        transformDrag = null;
        if (ARQ.history && ARQ.history.pushDescription) ARQ.history.pushDescription('Transformar imagen');
        try { canvas.releasePointerCapture(e.pointerId); } catch (err4) {}
        var shT = ARQ.utils.activeSheet(ARQ.store.getProject());
        if (shT && ARQ.actionLog && ARQ.actionLog.append && tLayerId) {
          var lyrT = null;
          (shT.capas || []).forEach(function (l) { if (l.id === tLayerId) lyrT = l; });
          if (lyrT && lyrT.contenido && lyrT.contenido.imageTransform && lyrT.contenido.imageTransform.corners) {
            ARQ.actionLog.append(shT, 'transform', tLayerId, { corners: lyrT.contenido.imageTransform.corners });
          }
        }
        ARQ.canvasEngine.redraw();
        ARQ.bus.emit(ARQ.EVENTS.HISTORY_CHANGED);
        return;
      }
      if (panning) {
        panning = false;
        panStart = null;
        if (ARQ.viewport && ARQ.viewport.scheduleViewportSettle) ARQ.viewport.scheduleViewportSettle();
        try { canvas.releasePointerCapture(e.pointerId); } catch (err) {}
        return;
      }
      if (shapeStart) {
        var p = ARQ.viewport.screenToSheet(e.clientX, e.clientY);
        var layer = ARQ.store.activeLayer();
        if (layer && ARQ.guards.canDrawOnLayer(layer)) {
          ARQ.history.pushUndo();
          layer.contenido = layer.contenido || {};
          layer.contenido.shapes = layer.contenido.shapes || [];
          var t = shapeStart.tool;
          var sh = { id: ARQ.utils.uuid(), color: ARQ.tools.color, grosor: ARQ.tools.size, opacidad: ARQ.tools.opacity, fill: 'transparent' };
          if (t === 'rect') {
            sh.tipo = 'rect';
            sh.x = Math.min(shapeStart.x, p.x);
            sh.y = Math.min(shapeStart.y, p.y);
            sh.w = Math.abs(p.x - shapeStart.x);
            sh.h = Math.abs(p.y - shapeStart.y);
          } else if (t === 'circulo') {
            sh.tipo = 'circulo';
            sh.cx = (shapeStart.x + p.x) / 2;
            sh.cy = (shapeStart.y + p.y) / 2;
            sh.r = Math.sqrt(Math.pow(p.x - shapeStart.x, 2) + Math.pow(p.y - shapeStart.y, 2)) / 2;
          } else {
            sh.tipo = 'linea';
            sh.x1 = shapeStart.x;
            sh.y1 = shapeStart.y;
            sh.x2 = p.x;
            sh.y2 = p.y;
          }
          layer.contenido.shapes.push(sh);
          ARQ.store.setDirty(true);
          ARQ.history.pushDescription('Forma');
        }
        shapeStart = null;
        try { canvas.releasePointerCapture(e.pointerId); } catch (err) {}
        ARQ.canvasEngine.redraw();
        return;
      }
      if (!currentStroke) return;
      try { canvas.releasePointerCapture(e.pointerId); } catch (err) {}
      var lyr = ARQ.store.activeLayer();
      if (currentStroke.herramienta === 'borrador' && ARQ.eraser && ARQ.eraser.eraseStrokesByPath) {
        if (currentStroke.puntos.length >= 1) {
          var n = ARQ.eraser.eraseStrokesByPath(lyr, currentStroke);
          if (n > 0) {
            ARQ.history.pushDescription('Borrador');
          }
        }
      } else if (currentStroke.puntos.length >= 2) {
        lyr.contenido.strokes.push(currentStroke);
        ARQ.store.setDirty(true);
        ARQ.history.pushDescription('Trazo');
      }
      currentStroke = null;
      ARQ.canvasEngine.redraw();
      ARQ.bus.emit(ARQ.EVENTS.HISTORY_CHANGED);
    },
  };
})(typeof window !== 'undefined' ? window : this);
