<commit_before>window.LC = window.LC ? {}


class LC.LiterallyCanvas

  constructor: (@canvas, @opts) ->
    @$canvas = $(@canvas)

    LC.bindEvents(this, @canvas, @opts.keyboardShortcuts)

    @colors =
      primary: @opts.primaryColor or '#000'
      secondary: @opts.secondaryColor or '#fff'
      background: @opts.backgroundColor or 'rgb(230, 230, 230)'
    $(@canvas).css('background-color', @colors.background)

    @watermarkImage = @opts.watermarkImage
    unless @watermarkImage.complete
      @watermarkImage.onload = => @repaint(true, false)

    @buffer = $('<canvas>').get(0)
    @ctx = @canvas.getContext('2d')
    @bufferCtx = @buffer.getContext('2d')

    @shapes = []
    @undoStack = []
    @redoStack = []

    @isDragging = false
    @position = {x: 0, y: 0}
    @scale = 1.0
    @tool = undefined

    @repaint()

  updateSize: =>
    @$canvas.attr('width', @$canvas.width())
    @$canvas.attr('height', @$canvas.height())
    @repaint()

  trigger: (name, data) ->
    @canvas.dispatchEvent(new CustomEvent(name, detail: data))

  on: (name, fn) ->
    @canvas.addEventListener name, (e) ->
      fn e.detail

  clientCoordsToDrawingCoords: (x, y) ->
    x: (x - @position.x) / @scale,
    y: (y - @position.y) / @scale,

  drawingCoordsToClientCoords: (x, y) ->
    x: x * @scale + @position.x,
    y: y * @scale + @position.y

  setTool: (tool) ->
    @tool = tool
    @trigger('toolChange', {tool})

  begin: (x, y) ->
    newPos = @clientCoordsToDrawingCoords(x, y)
    @tool.begin newPos.x, newPos.y, this
    @isDragging = true
    @trigger("drawingStart", {tool: @tool})

  continue: (x, y) ->
    newPos = @clientCoordsToDrawingCoords(x, y)
    if @isDragging
      @tool.continue newPos.x, newPos.y, this
      @trigger("drawingContinue", {tool: @tool})

  end: (x, y) ->
    newPos = @clientCoordsToDrawingCoords(x, y)
    if @isDragging
      @tool.end newPos.x, newPos.y, this
      @isDragging = false
      @trigger("drawingEnd", {tool: @tool})

  setColor: (name, color) ->
    @colors[name] = color
    $(@canvas).css('background-color', @colors.background)
    @trigger "#{name}ColorChange", @colors[name]
    @repaint()

  getColor: (name) -> @colors[name]

  saveShape: (shape) ->
    @execute(new LC.AddShapeAction(this, shape))
    @trigger('saveShape', {shape: shape})

  pan: (x, y) ->
    # Subtract because we are moving the viewport
    @position.x = @position.x - x
    @position.y = @position.y - y
    @trigger('pan', {x: @position.x, y: @position.y})

  zoom: (factor) ->
    oldScale = @scale
    @scale = @scale + factor
    @scale = Math.max(@scale, 0.2)
    @scale = Math.min(@scale, 4.0)
    @scale = Math.round(@scale * 100) / 100

    @position.x = LC.scalePositionScalar(
      @position.x, @canvas.width, oldScale, @scale)
    @position.y = LC.scalePositionScalar(
      @position.y, @canvas.height, oldScale, @scale)

    @repaint()
    @trigger('zoom', {oldScale: oldScale, newScale: @scale})

  # Repaints the canvas.
  # If dirty is true then all saved shapes are completely redrawn,
  # otherwise the back buffer is simply copied to the screen as is.
  # If drawBackground is true, the background is rendered as a solid
  # color, otherwise it is left transparent.
  repaint: (dirty = true, drawBackground = false) ->
    if dirty
      @buffer.width = @canvas.width
      @buffer.height = @canvas.height
      @bufferCtx.clearRect(0, 0, @buffer.width, @buffer.height)
      if drawBackground
        @bufferCtx.fillStyle = @colors.background<commit_msg>limit zoom out to 0.6 because <=0.5 is busted for why?<commit_after>window.LC = window.LC ? {}


class LC.LiterallyCanvas

  constructor: (@canvas, @opts) ->
    @$canvas = $(@canvas)

    LC.bindEvents(this, @canvas, @opts.keyboardShortcuts)

    @colors =
      primary: @opts.primaryColor or '#000'
      secondary: @opts.secondaryColor or '#fff'
      background: @opts.backgroundColor or 'rgb(230, 230, 230)'
    $(@canvas).css('background-color', @colors.background)

    @watermarkImage = @opts.watermarkImage
    unless @watermarkImage.complete
      @watermarkImage.onload = => @repaint(true, false)

    @buffer = $('<canvas>').get(0)
    @ctx = @canvas.getContext('2d')
    @bufferCtx = @buffer.getContext('2d')

    @shapes = []
    @undoStack = []
    @redoStack = []

    @isDragging = false
    @position = {x: 0, y: 0}
    @scale = 1.0
    @tool = undefined

    @repaint()

  updateSize: =>
    @$canvas.attr('width', @$canvas.width())
    @$canvas.attr('height', @$canvas.height())
    @repaint()

  trigger: (name, data) ->
    @canvas.dispatchEvent(new CustomEvent(name, detail: data))

  on: (name, fn) ->
    @canvas.addEventListener name, (e) ->
      fn e.detail

  clientCoordsToDrawingCoords: (x, y) ->
    x: (x - @position.x) / @scale,
    y: (y - @position.y) / @scale,

  drawingCoordsToClientCoords: (x, y) ->
    x: x * @scale + @position.x,
    y: y * @scale + @position.y

  setTool: (tool) ->
    @tool = tool
    @trigger('toolChange', {tool})

  begin: (x, y) ->
    newPos = @clientCoordsToDrawingCoords(x, y)
    @tool.begin newPos.x, newPos.y, this
    @isDragging = true
    @trigger("drawingStart", {tool: @tool})

  continue: (x, y) ->
    newPos = @clientCoordsToDrawingCoords(x, y)
    if @isDragging
      @tool.continue newPos.x, newPos.y, this
      @trigger("drawingContinue", {tool: @tool})

  end: (x, y) ->
    newPos = @clientCoordsToDrawingCoords(x, y)
    if @isDragging
      @tool.end newPos.x, newPos.y, this
      @isDragging = false
      @trigger("drawingEnd", {tool: @tool})

  setColor: (name, color) ->
    @colors[name] = color
    $(@canvas).css('background-color', @colors.background)
    @trigger "#{name}ColorChange", @colors[name]
    @repaint()

  getColor: (name) -> @colors[name]

  saveShape: (shape) ->
    @execute(new LC.AddShapeAction(this, shape))
    @trigger('saveShape', {shape: shape})

  pan: (x, y) ->
    # Subtract because we are moving the viewport
    @position.x = @position.x - x
    @position.y = @position.y - y
    @trigger('pan', {x: @position.x, y: @position.y})

  zoom: (factor) ->
    oldScale = @scale
    @scale = @scale + factor
    @scale = Math.max(@scale, 0.6)
    @scale = Math.min(@scale, 4.0)
    @scale = Math.round(@scale * 100) / 100

    @position.x = LC.scalePositionScalar(
      @position.x, @canvas.width, oldScale, @scale)
    @position.y = LC.scalePositionScalar(
      @position.y, @canvas.height, oldScale, @scale)

    @repaint()
    @trigger('zoom', {oldScale: oldScale, newScale: @scale})

  # Repaints the canvas.
  # If dirty is true then all saved shapes are completely redrawn,
  # otherwise the back buffer is simply copied to the screen as is.
  # If drawBackground is true, the background is rendered as a solid
  # color, otherwise it is left transparent.
  repaint: (dirty = true, drawBackground = false) ->
    if dirty
      @buffer.width = @canvas.width
      @buffer.height = @canvas.height
      @bufferCtx.clearRect(0, 0, @buffer.width, @buffer.height)
      if drawBackground
        @bufferCtx.fillStyle = @colors.background
{'fraction_non_alphanumeric': 0.1609990122759983, 'fraction_numerical': 0.009312826301679131, 'mean_word_length': 3.0759056929269697, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3589577', 'n_tokens_mistral': 2519, 'n_tokens_neox': 2429, 'n_words': 595}