text:
<?php

namespace Tienvx\Bundle\MbtBundle\Tests\Model\Generator;

use PHPUnit\Framework\TestCase;
use Tienvx\Bundle\MbtBundle\Exception\OutOfRangeException;
use Tienvx\Bundle\MbtBundle\Model\Generator\State;
use Tienvx\Bundle\MbtBundle\Model\Generator\StateInterface;

/**
 * @covers \Tienvx\Bundle\MbtBundle\Model\Generator\State
 */
class StateTest extends TestCase
{
    protected StateInterface $state;

    protected function setUp(): void
    {
        $this->state = new State([], [], 5, 10);
    }

    /**
     * @dataProvider totalPlacesAndTransitionsProvider
     */
    public function testMissingPlaceOrTransition(int $places, int $transitions): void
    {
        $this->expectExceptionObject(new OutOfRangeException('State need at least 1 place and 1 transition'));
        new State([], [], $places, $transitions);
    }

    public function testPlaceCoverage(): void
    {
        $this->assertSame(0.0, $this->state->getPlaceCoverage());
        $this->state->addVisitedPlace(1);
        $this->assertSame(20.0, $this->state->getPlaceCoverage());
    }

    public function testTransitionCoverage(): void
    {
        $this->assertSame(0.0, $this->state->getTransitionCoverage());
        $this->state->addVisitedTransition(1);
        $this->assertSame(10.0, $this->state->getTransitionCoverage());
    }

    public function totalPlacesAndTransitionsProvider(): array
    {
        return [
            [0, 11],
            [12, 0],
            [0, 0],
        ];
    }
}


text:
Angular directive for Summernote

Basic

Super Simple WYSIWYG Editor on Bootstrap

  	<summernote height="300" ng-model="text"></summernote>

Air-mode

Air-mode gives clearer interface with hiddened toolbar. To reveal toolbar, select a text where you want to shape up. Simply turn on airMode and just focus on text.

    <summernote airMode ng-model="text">
    </summernote>

Custom toolbar

Summernote allows you to make own custom toolbar.

    <summernote config="options"></summernote>

redpajama_set_name: RedPajamaGithub


text:
PtUtil = {}
PtUtil.charWidths = {6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 4, 8, 12, 10, 12, 12, 4, 6, 6, 8, 8, 6, 8, 4, 12, 10, 6, 10, 10, 10, 10, 10, 10, 10, 10, 4, 4, 8, 8, 8, 10, 12, 10, 10, 8, 10, 8, 8, 10, 10, 8, 10, 10, 8, 12, 10, 10, 10, 10, 10, 10, 8, 10, 10, 12, 10, 10, 8, 6, 12, 6, 8, 10, 6, 10, 10, 9, 10, 10, 8, 10, 10, 4, 6, 9, 4, 12, 10, 10, 10, 10, 8, 10, 8, 10, 10, 12, 8, 10, 10, 8, 4, 8, 10, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 10, 10, 15, 10, 5, 13, 7, 14, 15, 15, 10, 6, 14, 12, 16, 14, 7, 7, 6, 11, 12, 8, 7, 6, 16, 16, 15, 15, 15, 10, 10, 10, 10, 10, 10, 10, 14, 10, 8, 8, 8, 8, 8, 8, 8, 8, 13, 10, 10, 10, 10, 10, 10, 10, 13, 10, 10, 10, 10, 10, 14, 11, 10, 10, 10, 10, 10, 10, 15, 9, 10, 10, 10, 10, 8, 8, 8, 8, 12, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 15, 10}

function PtUtil.library()
  return {
    "/penguingui/Util.lua",
    "/penguingui/Binding.lua",
    "/penguingui/BindingFunctions.lua",
    "/penguingui/GUI.lua",
    "/penguingui/Component.lua",
    "/penguingui/Line.lua",
    "/penguingui/Rectangle.lua",
    "/penguingui/Align.lua",
    "/penguingui/HorizontalLayout.lua",
    "/penguingui/VerticalLayout.lua",
    "/penguingui/Panel.lua",
    "/penguingui/Frame.lua",
    "/penguingui/Button.lua",
    "/penguingui/Label.lua",
    "/penguingui/TextButton.lua",
    "/penguingui/TextField.lua",
    "/penguingui/Image.lua",
    "/penguingui/CheckBox.lua",
    "/penguingui/RadioButton.lua",
    "/penguingui/TextRadioButton.lua",
    "/penguingui/Slider.lua",
    "/penguingui/List.lua",
    "/lib/profilerapi.lua",
    "/lib/inspect.lua"
  }
end

function PtUtil.drawText(text, options, fontSize, color)
  fontSize = fontSize or 16
  if text:byte() == 32 then -- If it starts with a space, offset the string
    local xOffset = PtUtil.getStringWidth(" ", fontSize)
    local oldX = options.position[1]
    options.position[1] = oldX + xOffset
    console.canvasDrawText(text, options, fontSize, color)
    options.position[1] = oldX
  else
    console.canvasDrawText(text, options, fontSize, color)
  end
end

function PtUtil.getStringWidth(text, fontSize)
  local widths = PtUtil.charWidths
  local scale = PtUtil.getFontScale(fontSize)
  local out = 0
  local len = #text
  for i=1,len,1 do
    out = out + widths[string.byte(text, i)]
  end
  return out * scale
end

function PtUtil.getFontScale(size)
  return size / 16
end

PtUtil.specialKeyMap = {
  [8] = "backspace",
  [13] = "enter",
  [127] = "delete",
  [275] = "right",
  [276] = "left",
  [278] = "home",
  [279] = "end",
  [301] = "capslock",
  [303] = "shift",
  [304] = "shift"
}

PtUtil.shiftKeyMap = {
  [39] = "\"",
  [44] = "<",
  [45] = "_",
  [46] = ">",
  [47] = "?",
  [48] = ")",
  [49] = "!",
  [50] = "@",
  [51] = "#",
  [52] = "$",
  [53] = "%",
  [54] = "^",
  [55] = "&",
  [56] = "*",
  [57] = "(",
  [59] = ":",
  [61] = "+",
  [91] = "{",
  [92] = "|",
  [93] = "}",
  [96] = "~"
}

function PtUtil.getKey(key, shift, capslock)
  if (capslock and not shift) or (shift and not capslock) then
    if key >= 97 and key <= 122 then
      return string.upper(string.char(key))
    end
  end
  if shift and PtUtil.shiftKeyMap[key] then
    return PtUtil.shiftKeyMap[key]
  else
    if key >= 32 and key <= 122 then
      return string.char(key)
    elseif PtUtil.specialKeyMap[key] then
      return PtUtil.specialKeyMap[key]
    else
      return "unknown"
    end
  end
end

function PtUtil.fillRect(rect, color)
  console.canvasDrawRect(rect, color)
end

function PtUtil.fillPoly(poly, color)
  console.logInfo("fillPoly is not functional yet")
end

function PtUtil.drawLine(p1, p2, color, width)
  console.canvasDrawLine(p1, p2, color, width * 2)
end

function PtUtil.drawRect(rect, color, width)
  local minX = rect[1] + width / 2
  local minY = math.floor((rect[2] + width / 2) * 2) / 2
  local maxX = rect[3] - width / 2
  local maxY = math.floor((rect[4] - width / 2) * 2) / 2
  PtUtil.drawLine(
    {minX - width / 2, minY},
    {maxX + width / 2, minY},
    color, width
  )
  PtUtil.drawLine(
    {maxX, minY},
    {maxX, maxY},
    color, width
  )
  PtUtil.drawLine(
    {minX - width / 2, maxY},
    {maxX + width / 2, maxY},
    color, width
  )
  PtUtil.drawLine(
    {minX, minY},
    {minX, maxY},
    color, width
  )
end

function PtUtil.drawPoly(poly, color, width)
  for i=1,#poly - 1,1 do
    PtUtil.drawLine(poly[i], poly[i + 1], color, width)
  end
  PtUtil.drawLine(poly[#poly], poly[1], color, width)
end

function PtUtil.drawImage(image, position, scale)
  console.canvasDrawImage(image, position, scale)
end

function ripairs(t)
  local function ripairs_it(t,i)
    i=i-1
    local v=t[i]
    if v==nil then return v end
    return i,v
  end
  return ripairs_it, t, #t+1
end

function PtUtil.removeObject(t, o)
  for i,obj in ipairs(t) do
    if obj == o then
      table.remove(t, i)
      return i
    end
  end
  return -1
end

function class(...)
  local cls, bases = {}, {...}

  for i, base in ipairs(bases) do
    for k, v in pairs(base) do
      cls[k] = v
    end
  end

  cls.__index, cls.is_a = cls, {[cls] = true}
  for i, base in ipairs(bases) do
    for c in pairs(base.is_a) do
      cls.is_a[c] = true
    end
    cls.is_a[base] = true
  end
  setmetatable(
    cls,
    {
      __call = function (c, ...)
        local instance = setmetatable({}, c)
        instance = Binding.proxy(instance)

        local init = instance._init
        if init then init(instance, ...) end
        return instance
      end
    }
  )
  return cls
end

function dump(value, indent, seen)
  if type(value) ~= "table" then
    if type(value) == "string" then
      return string.format('%q', value)
    else
      return tostring(value)
    end
  else
    if type(seen) ~= "table" then
      seen = {}
    elseif seen[value] then
      return "{...}"
    end
    seen[value] = true
    indent = indent or ""
    if next(value) == nil then
      return "{}"
    end
    local str = "{"
    local first = true
    for k,v in pairs(value) do
      if first then
        first = false
      else
        str = str..","
      end
      str = str.."\n"..indent.."  ".."["..dump(k, "", seen)
        .."] = "..dump(v, indent.."  ", seen)
    end
    str = str.."\n"..indent.."}"
    return str
  end
end

--------------------------------------------------------------------------------
-- Binding.lua
--------------------------------------------------------------------------------

Binding = setmetatable(
  {},
  {
    __call = function(t, ...)
      return t.value(...)
    end
  }
)

Binding.proxyTable = {
  __index = function(t, k)
    local out = t._instance[k]
    if out ~= nil then
      return out
    else
      return Binding.proxyTable[k]
    end
  end,
  __newindex = function(t, k, v)
    local instance = t._instance
    local old = instance[k]
    local new = v
    instance[k] = new
    if old ~= v then
      local listeners = instance.listeners
      if listeners and listeners[k] then
        local keyListeners = listeners[k]
        for _,keyListener in ipairs(keyListeners) do
          new = keyListener(t, k, old, new) or new
        end
      end
      local bindings = instance.bindings
      if bindings and bindings[k] then
        local keyBindings = bindings[k]
        for _,keyBinding in ipairs(keyBindings) do
          keyBinding:valueChanged(old, new)
        end
      end
    end
  end,
  __pairs = function(t)
    return pairs(t._instance)
  end,
  __ipairs = function(t)
    return ipairs(t._instance)
  end,
  __add = function(a, b)
    return a._instance + (type(b) == "table" and b._instance or b)
  end,
  __sub = function(a, b)
    return a._instance - (type(b) == "table" and b._instance or b)
  end,
  __mul = function(a, b)
    return a._instance * (type(b) == "table" and b._instance or b)
  end,
  __div = function(a, b)
    return a._instance / (type(b) == "table" and b._instance or b)
  end,
  __mod = function(a, b)
    return a._instance % (type(b) == "table" and b._instance or b)
  end,
  __pow = function(a, b)
    return a._instance ^ (type(b) == "table" and b._instance or b)
  end,
  __unm = function(a)
    return -a._instance
  end,
  __concat = function(a, b)
    return a._instance .. (type(b) == "table" and b._instance or b)
  end,
  __len = function(a)
    return #a._instance
  end,
  __eq = function(a, b)
    return a._instance == b._instance
  end,
  __lt = function(a, b)
    return a._instance < b._instance
  end,
  __le = function(a, b)
    return a._instance <= b._instance
  end,
  __call = function(t, ...)
    return t._instance(...)
  end
}

function Binding.isValue(object)
  return type(object) == "table"
    and getmetatable(object._instance) == Binding.valueTable
end

Binding.weakMetaTable = {
  __mode = "v"
}

Binding.valueTable = {}

Binding.valueTable.__index = Binding.valueTable

function Binding.valueTable:addValueListener(listener)
  return self:addListener("value", listener)
end

function Binding.valueTable:removeValueListener(listener)
  return self:removeListener("value", listener)
end

function Binding.valueTable:addValueBinding(binding)
  return self:addBinding("value", binding)
end

function Binding.valueTable:removeValueBinding(binding)
  return self:removeBinding("value", binding)
end

function Binding.valueTable:unbind()
  local bindings = self.bindings
  if bindings and bindings.value then
    local valueBindings = bindings.value
    for _,binding in ipairs(valueBindings) do
      binding:unbind()
    end
  end
  local boundto = self.boundto
  for _,bound in ipairs(boundto) do
    for _,boundTable in pairs(bound.bindings) do
      PtUtil.removeObject(boundTable, self)
    end
  end
  self.boundto = nil
  local bindTargets = self.bindTargets
  if bindTargets then
    for bindTarget,_ in pairs(bindTargets) do
      local bindTargetBoundto = bindTarget.boundto
      for key,binding in pairs(bindTargetBoundto) do
        if binding == self then
          bindTargetBoundto[key] = nil
        end
      end
    end
  end
end

function Binding.unbindChain(binding)
  Binding.valueTable.unbind(binding)
  local bindingTable = binding.bindingTable
  for i=1, #bindingTable - 1, 1 do
    bindingTable[i]:unbind()
    bindingTable[i] = nil
  end
end

function Binding.value(t, k)
  local out = Binding.proxy(setmetatable({}, Binding.valueTable))
  if type(k) == "string" then -- Single key
    out.value = t[k]
    out.valueChanged = function(binding, old, new)
      binding.value = new
    end
    t:addBinding(k, out)
    out.boundto = {t}
    return out
  else -- Table of keys
    local numKeys = #k
    local currTable = t
    local bindingTable = {}
    for i=1, numKeys - 1, 1 do
      local currBinding = Binding.proxy(setmetatable({}, Binding.valueTable))
      local currKey = k[i]
      local index = i

      currBinding.valueChanged = function(binding, old, new)
        if old == new then return end
        local oldTable = old
        local newTable = new
        local subKey
        local transplant
        for j=index + 1, numKeys, 1 do
          subKey = k[j]
          transplant = bindingTable[j]
          transplant.boundto[1] = newTable
          oldTable:removeBinding(subKey, transplant)
          newTable:addBinding(subKey, transplant)

          if j < numKeys then
            oldTable = oldTable[subKey]
            newTable = newTable[subKey]
          end
        end
      end
      currBinding.boundto = {currTable}
      currTable:addBinding(currKey, currBinding)
      bindingTable[index] = currBinding

      currTable = t[currKey]
    end
    out.valueChanged = function(binding, old, new)
      binding.value = new
    end
    out.bindingTable = bindingTable
    out.boundto = {currTable}
    out.unbind = Binding.unbindChain
    currTable:addBinding(k[numKeys], out)
    bindingTable[numKeys] = out
    return out
  end
end

function Binding.proxyTable:addListener(key, listener)
  local listeners = self.listeners
  if not listeners then
    listeners = {}
    self.listeners = listeners
  end
  local keyListeners = listeners[key]
  if not keyListeners then
    keyListeners = {}
    listeners[key] = keyListeners
  end
  table.insert(keyListeners, listener)
  return listener
end

function Binding.proxyTable:removeListener(key, listener)
  local keyListeners = self.listeners[key]
  return PtUtil.removeObject(keyListeners, listener) ~= -1
end

function Binding.proxyTable:addBinding(key, binding)
  local bindings = self.bindings
  if not bindings then
    bindings = {}
    self.bindings = bindings
  end
  local keyBindings = bindings[key]
  if not keyBindings then
    keyBindings = setmetatable({}, Binding.weakMetaTable)
    bindings[key] = keyBindings
  end
  table.insert(keyBindings, binding)
  binding:valueChanged(self[key], self[key])
  return binding
end

function Binding.proxyTable:removeBinding(key, binding)
  local keyBindings = self.bindings[key]
  return PtUtil.removeObject(keyBindings, binding) ~= -1
end

function Binding.bind(target, key, value)
  local listener = function(t, k, old, new)
    target[key] = new
  end
  value:addValueListener(listener)

  local boundto = target.boundto
  if not boundto then
    boundto = {}
    target.boundto = boundto
  end
  local boundtoKey = boundto[key]
  assert(not boundtoKey, key .. " is already bound to another value")
  boundto[key] = value

  local bindTargets = value.bindTargets

  if not bindTargets then
    bindTargets = {}
    value.bindTargets = bindTargets
  end
  local bindKeyTargets = bindTargets[target]
  if not bindKeyTargets then
    bindKeyTargets = {}
    bindTargets[target] = bindKeyTargets
  end
  bindKeyTargets[key] = listener

  target[key] = value.value
end

Binding.proxyTable.bind = Binding.bind

function Binding.bindBidirectional(t1, k1, t2, k2)
  t1:bind(k1, Binding(t2, k2))
  t2:bind(k2, Binding(t1, k1))
end

Binding.proxyTable.bindBidirectional = Binding.bindBidirectional

function Binding.unbind(target, key)
  local binding = target.boundto[key]
  if binding then
    binding:removeValueListener(binding.bindTargets[target][key])
    binding.bindTargets[target][key] = nil
    target.boundto[key] = nil
  end
end

Binding.proxyTable.unbind = Binding.unbind

function Binding.proxy(instance)
  return setmetatable(
    {_instance = instance},
    Binding.proxyTable
  )
end

--------------------------------------------------------------------------------
-- BindingFunctions.lua
--------------------------------------------------------------------------------

local createFunction = function(f)
  return function(...)
    local out = Binding.proxy(setmetatable({}, Binding.valueTable))
    local getters = {}
    local boundto = {self}
    local args = table.pack(...)
    local numArgs = args.n
    for i = 1, numArgs, 1 do
      local value = args[i]
      local getter
      if Binding.isValue(value) then
        getter = function()
          return value.value
        end
      else
        getter = function()
          return value
        end
      end
      getters[i] = getter
    end
    out.valueChanged = function(binding, old, new)
      out.value = f(table.unpack(getters))
    end
    for i = 1, numArgs, 1 do
      local value = args[i]
      if Binding.isValue(value) then
        value:addValueBinding(out)
      end
      table.insert(boundto, value)
    end
    out.boundto = boundto
    return out
  end
end

Binding.valueTable.tostring = createFunction(
  function(value)
    return tostring(value())
  end
)
Binding.tostring = Binding.valueTable.tostring

Binding.valueTable.tonumber = createFunction(
  function(value)
    return tonumber(value())
  end
)
Binding.tonumber = Binding.valueTable.tonumber

Binding.valueTable.add = createFunction(
  function(first, ...)
    local out = first()
    local args = table.pack(...)
    for _,value in ipairs(args) do
      out = out + value()
    end
    return out
  end
)
Binding.add = Binding.valueTable.add

Binding.valueTable.sub = createFunction(
  function(first, ...)
    local out = first()
    local args = table.pack(...)
    for _,value in ipairs(args) do
      out = out - value()
    end
    return out
  end
)
Binding.sub = Binding.valueTable.sub

Binding.valueTable.mul = createFunction(
  function(first, ...)
    local out = first()
    local args = table.pack(...)
    for _,value in ipairs(args) do
      out = out * value()
    end
    return out
  end
)
Binding.mul = Binding.valueTable.mul

Binding.valueTable.div = createFunction(
  function(first, ...)
    local out = first()
    local args = table.pack(...)
    for _,value in ipairs(args) do
      out = out / value()
    end
    return out
  end
)
Binding.div = Binding.valueTable.div

Binding.valueTable.mod = createFunction(
  function(first, ...)
    local out = first()
    local args = table.pack(...)
    for _,value in ipairs(args) do
      out = out % value()
    end
    return out
  end
)
Binding.mod = Binding.valueTable.mod

Binding.valueTable.pow = createFunction(
  function(first, ...)
    local out = first()
    local args = table.pack(...)
    for _,value in ipairs(args) do
      out = out ^ value()
    end
    return out
  end
)
Binding.pow = Binding.valueTable.pow

Binding.valueTable.negate = createFunction(
  function(value)
    return -value()
  end
)
Binding.negate = Binding.valueTable.negate

Binding.valueTable.concat = createFunction(
  function(first, ...)
    local out = first()
    local args = table.pack(...)
    for _,value in ipairs(args) do
      out = out .. value()
    end
    return out
  end
)
Binding.concat = Binding.valueTable.concat

Binding.valueTable.len = createFunction(
  function(value)
    return #value()
  end
)
Binding.len = Binding.valueTable.len

Binding.valueTable.eq = createFunction(
  function(a, b)
    return a() == b()
  end
)
Binding.eq = Binding.valueTable.eq

Binding.valueTable.ne = createFunction(
  function(a, b)
    return a() ~= b()
  end
)
Binding.ne = Binding.valueTable.ne

Binding.valueTable.lt = createFunction(
  function(a, b)
    return a() < b()
  end
)
Binding.lt = Binding.valueTable.lt

Binding.valueTable.gt = createFunction(
  function(a, b)
    return a() > b()
  end
)
Binding.gt = Binding.valueTable.gt

Binding.valueTable.le = createFunction(
  function(a, b)
    return a() <= b()
  end
)
Binding.le = Binding.valueTable.le

Binding.valueTable.ge = createFunction(
  function(a, b)
    return a() >= b()
  end
)
Binding.ge = Binding.valueTable.ge

Binding.valueTable.AND = createFunction(
  function(first, ...)
    local out = first()
    local args = table.pack(...)
    for _,value in ipairs(args) do
      out = out and value()
    end
    return out
  end
)
Binding.AND = Binding.valueTable.AND

Binding.valueTable.OR = createFunction(
  function(first, ...)
    local out = first()
    local args = table.pack(...)
    for _,value in ipairs(args) do
      out = out or value()
    end
    return out
  end
)
Binding.OR = Binding.valueTable.OR

Binding.valueTable.NOT = createFunction(
  function(value)
    return not value()
  end
)
Binding.NOT = Binding.valueTable.NOT

Binding.valueTable.THEN = function(self, ifTrue, ifFalse)
  local out = Binding.proxy(setmetatable({}, Binding.valueTable))
  local trueFunction
  local falseFunction
  local boundto = {self}
  if Binding.isValue(ifTrue) then
    trueFunction = function()
      return ifTrue.value
    end
  else
    trueFunction = function()
      return ifTrue
    end
  end
  if Binding.isValue(ifFalse) then
    falseFunction = function()
      return ifFalse.value
    end
  else
    falseFunction = function()
      return ifFalse
    end
  end
  out.valueChanged = function(binding, old, new)
    if self.value then
      out.value = trueFunction()
    else
      out.value = falseFunction()
    end
  end
  self:addValueBinding(out)
  if Binding.isValue(ifTrue) then
    ifTrue:addValueBinding(out)
    table.insert(boundto, ifTrue)
  end
  if Binding.isValue(ifFalse) then
    ifFalse:addValueBinding(out)
    table.insert(boundto, ifFalse)
  end
  out.boundto = boundto
  return out
end
Binding.THEN = Binding.valueTable.THEN

--------------------------------------------------------------------------------
-- GUI.lua
--------------------------------------------------------------------------------

GUI = {
  components = {},
  mouseState = {},
  keyState = {},
  mousePosition = {0, 0}
}

function GUI.add(component)
  GUI.components[#GUI.components + 1] = component
  component:setParent(nil)
end

function GUI.remove(component)
  for index,comp in ripairs(GUI.components) do
    if (comp == component) then
      component:removeSelf()
      return true
    end
  end
  return false
end

function GUI.setFocusedComponent(component)
  local focusedComponent = GUI.focusedComponent
  if focusedComponent then
    focusedComponent.hasFocus = false
  end
  GUI.focusedComponent = component
  component.hasFocus = true
end

function GUI.clickEvent(position, button, pressed)
  GUI.mouseState[button] = pressed
  local components = GUI.components
  local topFound = false
  for index,component in ripairs(components) do
    if component.visible ~= false then
      if not topFound then
        if component:contains(position) then
          table.remove(components, index)
          components[#components + 1] = component
          topFound = true
        end
      end
      if GUI.clickEventHelper(component, position, button, pressed) then
        break
      end
    end
  end
end

function GUI.clickEventHelper(component, position, button, pressed)
  local children = component.children
  for _,child in ripairs(children) do
    if child.visible ~= false then
      if GUI.clickEventHelper(child, position, button, pressed) then
        return true
      end
    end
  end
  if component.clickEvent then
    if component:contains(position) then
      if component:clickEvent(position, button, pressed) then
        GUI.setFocusedComponent(component)
        return true
      end
    end
  end
end

function GUI.keyEvent(key, pressed)
  GUI.keyState[key] = pressed
  local component = GUI.focusedComponent
  while component do
    if component.visible ~= false then
      local keyEvent = component.keyEvent
      if keyEvent then
        if keyEvent(component, key, pressed) then
          return
        end
      end
    end
    component = component.parent
  end
end

function GUI.step(dt)
  GUI.mousePosition = console.canvasMousePosition()
  local hoverComponent
  for _,component in ipairs(GUI.components) do
    if component.visible ~= false then
      hoverComponent = component:step(dt) or hoverComponent
    end
  end
  if hoverComponent then
    hoverComponent.mouseOver = true
  end
end

--------------------------------------------------------------------------------
-- Component.lua
--------------------------------------------------------------------------------

Component = class()
Component.x = 0
Component.y = 0
Component.width = 0
Component.height = 0

Component.mouseOver = nil

Component.hasFocus = nil

function Component:_init()
  self.children = {}
  self.offset = Binding.proxy({0, 0})
end

function Component:add(child)
  local children = self.children
  children[#children + 1] = child
  child:setParent(self)
end

function Component:remove(child)
  local children = self.children
  for index,comp in ripairs(children) do
    if (comp == child) then
      child:removeSelf()
      return true
    end
  end
  return false
end

function Component:removeSelf()
  local siblings
  if self.parent then
    siblings = self.parent.children
  else
    siblings = GUI.components
  end
  for index,sibling in ripairs(siblings) do
    if sibling == self then
      table.remove(siblings, index)
      return
    end
  end
end

function Component:pack(padding)
  local width = 0
  local height = 0
  for _,child in ipairs(self.children) do
    width = math.max(width, child.x + child.width)
    height = math.max(height, child.y + child.height)
  end
  if padding == nil then
    if self.width < width then
      self.width = width
    end
    if self.height < height then
      self.height = height
    end
  else
    self.width = width + padding
    self.height = height + padding
  end
end

function Component:step(dt)
  local hoverComponent
  if self.mouseOver ~= nil then
    if self:contains(GUI.mousePosition) then
      hoverComponent = self
    else
      self.mouseOver = false
    end
  end

  self:update(dt)

  local layout = self.layout
  if layout then
    self:calculateOffset()
    self.layout = false
  end
  self:draw(dt)

  for _,child in ipairs(self.children) do
    if layout then
      child.layout = true
    end
    if child.visible ~= false then
      hoverComponent = child:step(dt) or hoverComponent
    end
  end
  return hoverComponent
end

function Component:update(dt)
end

function Component:draw(dt)
end

function Component:setParent(parent)
  self.parent = parent
  if parent then
    parent.layout = true
  end
end

function Component:calculateOffset()
  local offset = self.offset

  local parent = self.parent
  if parent then
    offset[1] = parent.offset[1] + parent.x
    offset[2] = parent.offset[2] + parent.y
  else
    offset[1] = 0
    offset[2] = 0
  end

  return offset
end

function Component:contains(position)
  local pos = {position[1] - self.offset[1], position[2] - self.offset[2]}

  if pos[1] >= self.x and pos[1] <= self.x + self.width
    and pos[2] >= self.y and pos[2] <= self.y + self.height
  then
    return true
  end
  return false
end

--------------------------------------------------------------------------------
-- Line.lua
--------------------------------------------------------------------------------

Line = class(Component)
Line.color = {0, 0, 0}
Line.size = 1

function Line:_init(x, y, endX, endY, color, lineSize)
  Component._init(self)
  self.x = x
  self.y = y
  self.endX = x
  self.endY = y
  self.width = endX - x
  self.height = endY - y
  self.color = color
  self.size = size
end

function Line:draw(dt)
  local offset = self.offset
  local startX = self.x + offset[1]
  local startY = self.y + offset[2]
  local endX = self.endX + offset[1]
  local endY = self.endY + offset[2]

  local size = self.size
  local color = self.color
  PtUtil.drawLine({startX, startY}, {endX, endY}, color, width)
end

--------------------------------------------------------------------------------
-- Rectangle.lua
--------------------------------------------------------------------------------

Rectangle = class(Component)
Rectangle.color = {0, 0, 0}
Rectangle.lineSize = nil

function Rectangle:_init(x, y, width, height, color, lineSize)
  Component._init(self)
  self.x = x
  self.y = y
  self.width = width
  self.height = height
  self.color = color
  self.lineSize = lineSize
end

function Rectangle:draw(dt)
  local startX = self.x + self.offset[1]
  local startY = self.y + self.offset[2]
  local w = self.width
  local h = self.height

  local rect = {startX, startY, startX + w, startY + h}
  local lineSize = self.lineSize
  local color = self.color
  if lineSize then
    PtUtil.drawRect(rect, color, lineSize)
  else
    PtUtil.fillRect(rect, color)
  end
end

--------------------------------------------------------------------------------
-- Align.lua
--------------------------------------------------------------------------------

Align = {}

Align.LEFT = 0
Align.CENTER = 1
Align.RIGHT = 2
Align.TOP = 3
Align.BOTTOM = 4

--------------------------------------------------------------------------------
-- HorizontalLayout.lua
--------------------------------------------------------------------------------

HorizontalLayout = class()

HorizontalLayout.padding = nil
HorizontalLayout.vAlignment = Align.CENTER
HorizontalLayout.hAlignment = Align.LEFT

function HorizontalLayout:_init(padding, hAlign, vAlign)
  self.padding = padding or 0
  if hAlign then
    self.hAlignment = hAlign
  end
  if vAlign then
    self.vAlignment = vAlign
  end
end

function HorizontalLayout:layout()
  local vAlign = self.vAlignment
  local hAlign = self.hAlignment
  local padding = self.padding

  local container = self.container
  local components = container.children
  local totalWidth = 0
  for _,component in ipairs(components) do
    totalWidth = totalWidth + component.width
  end
  totalWidth = totalWidth + (#components - 1) * padding

  local startX
  if hAlign == Align.LEFT then
    startX = 0
  elseif hAlign == Align.CENTER then
    startX = (container.width - totalWidth) / 2
  else -- ALIGN_RIGHT
    startX = container.width - totalWidth
  end

  for _,component in ipairs(components) do
    component.x = startX
    if vAlign == Align.TOP then
      component.y = container.height - component.height
    elseif vAlign == Align.CENTER then
      component.y = (container.height - component.height) / 2
    else -- ALIGN_BOTTOM
      component.y = 0
    end
    startX = startX + component.width + padding
  end
end

--------------------------------------------------------------------------------
-- VerticalLayout.lua
--------------------------------------------------------------------------------

VerticalLayout = class()

VerticalLayout.padding = nil
VerticalLayout.vAlignment = Align.TOP
VerticalLayout.hAlignment = Align.CENTER

function VerticalLayout:_init(padding, vAlign, hAlign)
  self.padding = padding or 0
  if hAlign then
    self.hAlignment = hAlign
  end
  if vAlign then
    self.vAlignment = vAlign
  end
end

function VerticalLayout:layout()
  local vAlign = self.vAlignment
  local hAlign = self.hAlignment
  local padding = self.padding

  local container = self.container
  local components = container.children
  local totalHeight = 0
  for _,component in ipairs(components) do
    totalHeight = totalHeight + component.height
  end
  totalHeight = totalHeight + (#components - 1) * padding

  local startY
  if vAlign == Align.TOP then
    startY = container.height
  elseif vAlign == Align.CENTER then
    startY = container.height - (container.height - totalHeight) / 2
  else -- ALIGN_BOTTOM
    startY = totalHeight
  end

  for _,component in ipairs(components) do
    component.y = startY - component.height
    if hAlign == Align.LEFT then
      component.x = 0
    elseif hAlign == Align.CENTER then
      component.x = (container.width - component.width) / 2
    else -- ALIGN_RIGHT
      component.x = container.width - component.width
    end
    startY = startY - (component.height + padding)
  end
end

--------------------------------------------------------------------------------
-- Panel.lua
--------------------------------------------------------------------------------

Panel = class(Component)

function Panel:_init(x, y, width, height)
  Component._init(self)
  self.x = x
  self.y = y
  if width then
    self.width = width
  end
  if height then
    self.height = height
  end
end

function Panel:add(child)
  Component.add(self, child)
  self:updateLayoutManager()
  if not self.layoutManager then
    self:pack()
  end
end

function Panel:setLayoutManager(layout)
  self.layoutManager = layout
  layout.container = self
  self:updateLayoutManager()
end

function Panel:updateLayoutManager()
  local layout = self.layoutManager
  if layout then
    layout:layout()
  end
end

--------------------------------------------------------------------------------
-- Frame.lua
--------------------------------------------------------------------------------

Frame = class(Panel)
Frame.borderColor = {0, 0, 0}
Frame.borderThickness = 1
Frame.backgroundColor = {35, 35, 35}

function Frame:_init(x, y)
  Panel._init(self, x, y)
end

function Frame:update(dt)
  if self.dragging then
    if self.hasFocus then
      local mousePos = GUI.mousePosition
      self.x = self.x + (mousePos[1] - self.dragOrigin[1])
      self.y = self.y + (mousePos[2] - self.dragOrigin[2])
      self.layout = true
      self.dragOrigin = mousePos
    else
      self.dragging = false
    end
  end
end

function Frame:draw(dt)
  local startX = self.x - self.offset[1]
  local startY = self.y - self.offset[2]
  local w = self.width
  local h = self.height
  local border = self.borderThickness

  local borderRect = {
    startX, startY,
    startX + w, startY + h
  }
  local backgroundRect = {
    startX + border, startY + border,
    startX + w - border, startY + h - border
  }

  PtUtil.drawRect(borderRect, self.borderColor, border)
  PtUtil.fillRect(backgroundRect, self.backgroundColor)
end

function Frame:clickEvent(position, button, pressed)
  if pressed then
    self.dragging = true
    self.dragOrigin = position
  else
    self.dragging = false
  end
  return true
end

--------------------------------------------------------------------------------
-- Button.lua
--------------------------------------------------------------------------------

Button = class(Component)
Button.outerBorderColor = {0, 0, 0} --black
Button.innerBorderColor = {84, 84, 84} --#545454
Button.innerBorderHoverColor = {147, 147, 147} --#939393
Button.color = {38, 38, 38} --#262626
Button.hoverColor = {84, 84, 84} --#545454

function Button:_init(x, y, width, height)
  world.logInfo("Button init with "..x..","..y..","..width..","..height..".")

  Component._init(self)
  self.mouseOver = false

  self.x = x
  self.y = y
  self.width = width
  self.height = height
end

function Button:update(dt)
  if self.pressed and not self.mouseOver then
    self:setPressed(false)
  end
end

function Button:draw(dt)
  local startX = self.x + self.offset[1]
  local startY = self.y + self.offset[2]
  local w = self.width
  local h = self.height

  local borderPoly = {
    {startX + 1, startY + 0.5},
    {startX + w - 1, startY + 0.5},
    {startX + w - 0.5, startY + 1},
    {startX + w - 0.5, startY + h - 1},
    {startX + w - 1, startY + h - 0.5},
    {startX + 1, startY + h - 0.5},
    {startX + 0.5, startY + h - 1},
    {startX + 0.5, startY + 1},
  }
  local innerBorderRect = {
    startX + 1, startY + 1, startX + w - 1, startY + h - 1
  }
  local rectOffset = 1.5
  local rect = {
    startX + rectOffset, startY + rectOffset, startX + w - rectOffset, startY + h - rectOffset
  }

  world.logInfo("drawing now...")

  PtUtil.drawPoly(borderPoly, self.outerBorderColor, 1)
  if self.mouseOver then
    PtUtil.drawRect(innerBorderRect, self.innerBorderHoverColor, 0.5)
    PtUtil.fillRect(rect, self.hoverColor)
  else
    PtUtil.drawRect(innerBorderRect, self.innerBorderColor, 0.5)
    PtUtil.fillRect(rect, self.color)
  end
end

function Button:setPressed(pressed)
  if pressed and not self.pressed then
    self.x = self.x + 1
    self.y = self.y - 1
    self.layout = true
  end
  if not pressed and self.pressed then
    self.x = self.x - 1
    self.y = self.y + 1
    self.layout = true
  end
  self.pressed = pressed
end

function Button:clickEvent(position, button, pressed)
  if button <= 3 then
    if self.onClick and not pressed and self.pressed then
      self:onClick(button)
    end
    self:setPressed(pressed)
    return true
  end
end

--------------------------------------------------------------------------------
-- Label.lua
--------------------------------------------------------------------------------

Label = class(Component)
Label.text = nil

function Label:_init(x, y, text, fontSize, fontColor)
  Component._init(self)
  fontSize = fontSize or 10
  self.fontSize = fontSize
  self.fontColor = fontColor or {255, 255, 255}
  self.text = text
  self.x = x
  self.y = y
  self:addListener("text", self.recalculateBounds)
  self:recalculateBounds()
end

function Label:recalculateBounds()
  self.width = PtUtil.getStringWidth(self.text, self.fontSize)
  self.height = self.fontSize
end

function Label:draw(dt)
  local startX = self.x + self.offset[1]
  local startY = self.y + self.offset[2]

  PtUtil.drawText(self.text, {
                    position = {startX, startY},
                    verticalAnchor = "bottom"
                             }, self.fontSize, self.fontColor)
end

--------------------------------------------------------------------------------
-- TextButton.lua
--------------------------------------------------------------------------------

TextButton = class(Button)
TextButton.text = nil
TextButton.textPadding = 2

function TextButton:_init(x, y, width, height, text, fontColor)
  Button._init(self, x, y, width, height)
  local padding = self.textPadding
  local fontSize = height - padding * 2
  local label = Label(0, padding, text, fontSize, fontColor)
  self.text = text

  self.label = label
  self:add(label)

  self:addListener(
    "text",
    function(t, k, old, new)
      t.label.text = new
      t:repositionLabel()
    end
  )

  self:repositionLabel()
end

function TextButton:repositionLabel()
  local label = self.label
  local text = label.text
  local padding = self.textPadding
  local maxHeight = self.height - padding * 2
  local maxWidth = self.width - padding * 2
  if label.height < maxHeight then
    label.fontSize = maxHeight
    label:recalculateBounds()
  end
  while label.width > maxWidth do
    label.fontSize = label.fontSize - 1
    label:recalculateBounds()
  end
  label.x = (self.width - label.width) / 2
  label.y = (self.height - label.height) / 2
end

--------------------------------------------------------------------------------
-- TextField.lua
--------------------------------------------------------------------------------

TextField = class(Component)
TextField.vPadding = 3
TextField.hPadding = 4
TextField.borderColor = {84, 84, 84}
TextField.backgroundColor = {0, 0, 0}
TextField.textColor = {255, 255, 255}
TextField.textHoverColor = {153, 153, 153}
TextField.defaultTextColor = {51, 51, 51}
TextField.defaultTextHoverColor = {119, 119, 119}
TextField.cursorColor = {255, 255, 255}
TextField.cursorRate = 1
TextField.filter = nil

TextField.repeatDelay = 0.5
TextField.repeatInterval = 0.05

function TextField:_init(x, y, width, height, defaultText)
  Component._init(self)
  self.x = x
  self.y = y
  self.width = width
  self.height = height
  self.fontSize = height - self.vPadding * 2
  self.cursorPosition = 0
  self.cursorX = 0
  self.cursorTimer = self.cursorRate
  self.text = ""
  self.defaultText = defaultText
  self.textOffset = 0
  self.textClip = nil
  self.mouseOver = false
  self.keyTimes = {}
end

function TextField:update(dt)
  if self.hasFocus then
    local keyTimes = self.keyTimes
    for key,dur in pairs(keyTimes) do
      local time = dur + dt
      keyTimes[key] = time
      if time > self.repeatDelay + self.repeatInterval then
        self:keyEvent(key, true)
        keyTimes[key] = self.repeatDelay
      end
    end

    local timer = self.cursorTimer
    local rate = self.cursorRate
    timer = timer - dt
    if timer < 0 then
      timer = rate
    end
    self.cursorTimer = timer
  end
end

function TextField:draw(dt)
  local startX = self.x + self.offset[1]
  local startY = self.y + self.offset[2]
  local w = self.width
  local h = self.height

  local borderRect = {
    startX, startY, startX + w, startY + h
  }
  local backgroundRect = {
    startX + 1, startY + 1, startX + w - 1, startY + h - 1
  }
  PtUtil.fillRect(borderRect, self.borderColor)
  PtUtil.fillRect(backgroundRect, self.backgroundColor)

  local text = self.text
  local default = (text == "") and (self.defaultText ~= nil)

  local textColor
  if self.mouseOver then
    textColor = default and self.defaultTextHoverColor or self.textHoverColor
  else
    textColor = default and self.defaultTextColor or self.textColor
  end

  local cursorPosition = self.cursorPosition
  text = default and self.defaultText
    or text:sub(self.textOffset + 1, self.textOffset
                  + (self.textClip or #text))

  PtUtil.drawText(text, {
                    position = {
                      startX + self.hPadding,
                      startY + self.vPadding
                    },
                    verticalAnchor = "bottom"
                        }, self.fontSize, textColor)

  if self.hasFocus then
    local timer = self.cursorTimer
    local rate = self.cursorRate

    if timer > rate / 2 then -- Draw cursor
      local cursorX = startX + self.cursorX + self.hPadding
      local cursorY = startY + self.vPadding
      PtUtil.drawLine({cursorX, cursorY},
        {cursorX, cursorY + h - self.vPadding * 2},
        self.cursorColor,
        1)
    end
  end
end

function TextField:setCursorPosition(pos)
  if pos > #self.text then
    pos = #self.text
  end
  self.cursorPosition = pos

  if pos < self.textOffset then
    self.textOffset = pos
  end
  self:calculateTextClip()
  local textClip = self.textClip
  while (textClip) and (pos > self.textOffset + textClip) do
    self.textOffset = self.textOffset + 1
    self:calculateTextClip()
    textClip = self.textClip
  end
  while self.textOffset > 0 and not textClip do
    self.textOffset = self.textOffset - 1
    self:calculateTextClip()
    textClip = self.textClip
    if textClip then
      self.textOffset = self.textOffset + 1
      self:calculateTextClip()
    end
  end

  local text = self.text
  local cursorX = 0
  for i=self.textOffset + 1,pos,1 do
    local charWidth = PtUtil.getStringWidth(text:sub(i, i), self.fontSize)
    cursorX = cursorX + charWidth
  end
  self.cursorX = cursorX
  self.cursorTimer = self.cursorRate
end

function TextField:calculateTextClip()
  local maxX = self.width - self.hPadding * 2
  local text = self.text
  local totalWidth = 0
  local startI = self.textOffset + 1
  for i=startI,#text,1 do
    totalWidth = totalWidth
      + PtUtil.getStringWidth(text:sub(i, i), self.fontSize)
    if totalWidth > maxX then
      self.textClip = i - startI
      return
    end
  end
  self.textClip = nil
end

function TextField:clickEvent(position, button, pressed)
  if button <= 3 then
    local xPos = position[1] - self.x - self.offset[1] - self.hPadding

    local text = self.text
    local totalWidth = 0
    for i=self.textOffset + 1,#text,1 do
      local charWidth = PtUtil.getStringWidth(text:sub(i, i), self.fontSize)
      if xPos < (totalWidth + charWidth * 0.6) then
        self:setCursorPosition(i - 1)
        return true
      end
      totalWidth = totalWidth + charWidth
    end
    self:setCursorPosition(#text)

    return true
  end
end

function TextField:keyEvent(keyCode, pressed)
  if pressed then
    self.keyTimes[keyCode] = self.keyTimes[keyCode] or 0
  else
    self.keyTimes[keyCode] = nil
  end

  local keyState = GUI.keyState
  if not pressed
    or keyState[305] or keyState[306]
    or keyState[307] or keyState[308]
  then
    return
  end

  local shift = keyState[303] or keyState[304]
  local caps = keyState[301]
  local key = PtUtil.getKey(keyCode, shift, caps)

  local text = self.text
  local cursorPos = self.cursorPosition

  local filter = self.filter
  if #key == 1 then -- Type a character
    text = text:sub(1, cursorPos) .. key .. text:sub(cursorPos + 1)
    if filter then
      if not text:match(filter) then
        return true
      end
    end
    self.text = text
    self:setCursorPosition(cursorPos + 1)
  else -- Special character
    if key == "backspace" then
      if cursorPos > 0 then
        text = text:sub(1, cursorPos - 1) .. text:sub(cursorPos + 1)
        if filter then
          if not text:match(filter) then
            return true
          end
        end
        self.text = text
        self:setCursorPosition(cursorPos - 1)
      end
    elseif key == "enter" then
      if self.onEnter then
        self:onEnter()
      end
    elseif key == "delete" then
      if cursorPos < #text then
        text = text:sub(1, cursorPos) .. text:sub(cursorPos + 2)
        if filter then
          if not text:match(filter) then
            return true
          end
        end
        self.text = text
      end
    elseif key == "right" then
      self:setCursorPosition(math.min(cursorPos + 1, #text))
    elseif key == "left" then
      self:setCursorPosition(math.max(0, cursorPos - 1))
    elseif key == "home" then
      self:setCursorPosition(0)
    elseif key == "end" then
      self:setCursorPosition(#text)
    end
  end
  return true
end

--------------------------------------------------------------------------------
-- Image.lua
--------------------------------------------------------------------------------

Image = class(Component)

function Image:_init(x, y, image, scale)
  Component._init(self)
  scale = scale or 1

  self.x = x
  self.y = y
  local imageSize = root.imageSize(image)
  self.width = imageSize[1] * scale
  self.height = imageSize[2] * scale
  self.image = image
  self.scale = scale
end

function Image:draw(dt)
  local startX = self.x + self.offset[1]
  local startY = self.y + self.offset[2]
  local image = self.image
  local scale = self.scale

  PtUtil.drawImage(image, {startX, startY}, scale)
end

--------------------------------------------------------------------------------
-- CheckBox.lua
--------------------------------------------------------------------------------

CheckBox = class(Component)
CheckBox.borderColor = {84, 84, 84}
CheckBox.backgroundColor = {0, 0, 0}
CheckBox.hoverColor = {28, 28, 28}
CheckBox.checkColor = {197, 26, 11}
CheckBox.pressedColor = {52, 52, 52}

function CheckBox:_init(x, y, size)
  Component._init(self)
  self.mouseOver = false

  self.x = x
  self.y = y
  self.width = size
  self.height = size

  self.selected = false
end

function CheckBox:update(dt)
  if self.pressed and not self.mouseOver then
    self.pressed = false
  end
end

function CheckBox:draw(dt)
  local startX = self.x + self.offset[1]
  local startY = self.y + self.offset[2]
  local w = self.width
  local h = self.height

  local borderRect = {startX, startY, startX + w, startY + h}
  local rect = {startX + 1, startY + 1, startX + w - 1, startY + h - 1}
  PtUtil.drawRect(borderRect, self.borderColor, 1)

  if self.pressed then
    PtUtil.fillRect(rect, self.pressedColor)
  elseif self.mouseOver then
    PtUtil.fillRect(rect, self.hoverColor)
  else
    PtUtil.fillRect(rect, self.backgroundColor)
  end

  if self.selected then
    self:drawCheck(dt)
  end
end

function CheckBox:drawCheck(dt)
  local startX = self.x + self.offset[1]
  local startY = self.y + self.offset[2]
  local w = self.width
  local h = self.height
  PtUtil.drawLine(
    {startX + w / 4, startY + w / 2},
    {startX + w / 3, startY + h / 4},
    self.checkColor, 1)
  PtUtil.drawLine(
    {startX + w / 3, startY + h / 4},
    {startX + 3 * w / 4, startY + 3 * h / 4},
    self.checkColor, 1)
end

function CheckBox:clickEvent(position, button, pressed)
  if button <= 3 then
    if not pressed and self.pressed then
      self.selected = not self.selected
    end
    self.pressed = pressed
    return true
  end
end

--------------------------------------------------------------------------------
-- RadioButton.lua
--------------------------------------------------------------------------------

RadioButton = class(CheckBox)

function RadioButton:drawCheck(dt)
  local startX = self.x + self.offset[1]
  local startY = self.y + self.offset[2]
  local w = self.width
  local h = self.height
  local checkRect = {startX + w / 4, startY + h / 4,
                     startX + 3 * w / 4, startY + 3 * h / 4}
  PtUtil.fillRect(checkRect, self.checkColor)
end

function RadioButton:select()
  local siblings
  if self.parent == nil then
    siblings = GUI.components
  else
    siblings = self.parent.children
  end

  local selectedButton
  for _,sibling in ipairs(siblings) do
    if sibling ~= self and sibling.is_a[RadioButton]
      and sibling.selected
    then
      selectedButton = sibling
    end
  end
  if selectedButton then
    selectedButton.selected = false
  end

  if not self.selected then
    self.selected = true
  end
end

function RadioButton:setParent(parent)
  Component.setParent(self, parent)
  local siblings
  if self.parent == nil then
    siblings = GUI.components
  else
    siblings = self.parent.children
  end

  for _,sibling in ipairs(siblings) do
    if sibling ~= self and sibling.is_a[RadioButton] and sibling.selected then
      return
    end
  end
  self.selected = true
end

function RadioButton:removeSelf()
  CheckBox.removeSelf(self)
  if self.selected then
    local siblings
    if self.parent == nil then
      siblings = GUI.components
    else
      siblings = self.parent.children
    end

    for _,sibling in ipairs(siblings) do
      if sibling.is_a[RadioButton] then
        sibling:select()
        return
      end
    end
  end
end

function RadioButton:clickEvent(position, button, pressed)
  if button <= 3 then
    if not pressed and self.pressed then
      self:select()
    end
    self.pressed = pressed
    return true
  end
end

--------------------------------------------------------------------------------
-- TextRadioButton.lua
--------------------------------------------------------------------------------

TextRadioButton = class(RadioButton)
TextRadioButton.hoverColor = {31, 31, 31}
TextRadioButton.pressedColor = {69, 69, 69}
TextRadioButton.checkColor = {52, 52, 52}
TextRadioButton.text = nil
TextRadioButton.textPadding = 2

function TextRadioButton:_init(x, y, width, height, text)
  RadioButton._init(self, x, y, 0)
  self.width = width
  self.height = height

  local padding = self.textPadding
  local fontSize = height - padding * 2
  local label = Label(0, padding, text, fontSize, fontColor)

  self.label = label
  self:add(label)

  self.text = text
  self:addListener(
    "text",
    function(t, k, old, new)
      t.label.text = new
      t:repositionLabel()
    end
  )
  self:repositionLabel()
end

function TextRadioButton:drawCheck(dt)
  local startX = self.x + self.offset[1]
  local startY = self.y + self.offset[2]
  local w = self.width
  local h = self.height
  local checkRect = {startX + 1, startY + 1,
                     startX + w - 1, startY + h - 1}
  PtUtil.fillRect(checkRect, self.checkColor)
end

TextRadioButton.repositionLabel = TextButton.repositionLabel

--------------------------------------------------------------------------------
-- Slider.lua
--------------------------------------------------------------------------------

Slider = class(Component)
Slider.lineColor = {0, 0, 0}
Slider.lineSize = 2
Slider.handleBorderColor = {177, 177, 177}
Slider.handleBorderSize = 1
Slider.handleColor = Slider.lineColor
Slider.handleHoverColor = {50, 50, 50}
Slider.handlePressedColor = {84, 84, 84}
Slider.handleSize = 5
Slider.value = nil
Slider.maxValue = nil
Slider.minValue = nil

function Slider:_init(x, y, width, height, min, max, step, vertical)
  Component._init(self)
  self.x = x
  self.y = y
  self.width = width
  self.height = height
  self.mouseOver = false
  self.minValue = min or 0
  self.maxValue = max or 1
  self.valueStep = step
  self.vertical = vertical
  self.value = self.minValue
  self:addListener(
    "maxValue",
    function(t, k, old, new)
      if t.value > new then
        t.value = new
      end
    end
  )
end

function Slider:update(dt)
  if self.dragging then
    if not GUI.mouseState[1] then
      self.dragging = false
    else
      local mousePos = GUI.mousePosition
      local lineSize = self.lineSize
      local min = self.minValue
      local max = self.maxValue
      local len = max - min
      local step = self.valueStep
      local sliderValue
      if self.vertical then
        sliderValue = (mousePos[2] - self.dragOffset
                         - (self.y + self.offset[2] + lineSize)
                      ) / (self.height - lineSize * 2 - self.handleSize) * len
      else
        sliderValue = (mousePos[1] - self.dragOffset
                         - (self.x + self.offset[1] + lineSize)
                      ) / (self.width - lineSize * 2 - self.handleSize) * len
      end
      if sliderValue ~= sliderValue then -- sliderValue is NaN
        sliderValue = 0
      end
      sliderValue = math.max(sliderValue, 0)
      sliderValue = math.min(sliderValue, len)
      if step then
        local stepFreq = 1 / step
        sliderValue = math.floor(sliderValue * stepFreq + 0.5) / stepFreq
      end
      sliderValue = sliderValue + min
      self.value = sliderValue
    end
  end
  if self.moving ~= nil then
    if not GUI.mouseState[1] then
      self.moving = nil
    else
      local step = self.valueStep
      local direction = self.moving
      local max = self.maxValue
      local min = self.minValue
      local len = max - min
      if not step then
        step = len / 100
      end
      local value = self.value
      if direction then
        self.value = math.min(value + step, max)
      else
        self.value = math.max(value - step, min)
      end
    end
  end
end

function Slider:draw(dt)
  local startX = self.x + self.offset[1]
  local startY = self.y + self.offset[2]
  local w = self.width
  local h = self.height

  local lineSize = self.lineSize
  local lineColor = self.lineColor
  local percentage = self:getPercentage()
  local handleBorderSize = self.handleBorderSize
  local handleSize = self.handleSize
  local slidableLength
  local handleBorderRect
  local handleRect
  if self.vertical then
    PtUtil.drawLine({startX + w / 2, startY},
      {startX + w / 2, startY + h}, lineColor, lineSize)
    PtUtil.drawLine({startX, startY + lineSize / 2}
      , {startX + w, startY + lineSize / 2}, lineColor, lineSize)
    PtUtil.drawLine({startX, startY + h - lineSize / 2}
      , {startX + w, startY + h - lineSize / 2}, lineColor, lineSize)

    slidableLength = h - lineSize * 2 - handleSize
    local sliderY = startY + lineSize + percentage * slidableLength
    handleBorderRect = {startX, sliderY, startX + w, sliderY + handleSize}
    handleRect = {startX + handleBorderSize, sliderY + handleBorderSize
                  , startX + w - handleBorderSize
                  , sliderY + handleSize - handleBorderSize}
  else
    PtUtil.drawLine({startX, startY + h / 2},
      {startX + w, startY + h / 2}, self.lineColor, self.lineSize)
    PtUtil.drawLine({startX + lineSize / 2, startY},
      {startX + lineSize / 2, startY + h}, lineColor, lineSize)
    PtUtil.drawLine({startX + w - lineSize / 2, startY},
      {startX + w - lineSize / 2, startY + h}, lineColor, lineSize)

    slidableLength = w - lineSize * 2 - handleSize
    local sliderX = startX + lineSize + percentage * slidableLength
    handleBorderRect = {sliderX, startY, sliderX + handleSize, startY + h}
    handleRect = {sliderX + handleBorderSize, startY + handleBorderSize
                  , sliderX + handleSize - handleBorderSize
                  , startY + h - handleBorderSize}
  end
  PtUtil.drawRect(handleBorderRect, self.handleBorderColor, handleBorderSize)
  local handleColor
  if self.dragging then
    handleColor = self.handlePressedColor
  elseif self.mouseOver then
    handleColor = self.handleHoverColor
  else
    handleColor = self.handleColor
  end
  PtUtil.fillRect(handleRect, handleColor)
end

function Slider:getPercentage()
  local min = self.minValue
  local max = self.maxValue
  local len = max - min
  if len == 0 then
    return 0
  else
    return (self.value - min) / len
  end
end

function Slider:clickEvent(position, button, pressed)
  if button == 1 then -- Only react to LMB
    if pressed then
      local startX = self.x + self.offset[1]
      local startY = self.y + self.offset[2]
      local w = self.width
      local h = self.height

      local lineSize = self.lineSize
      local handleSize = self.handleSize
      local percentage = self:getPercentage()
      local handleX
      local handleY
      local handleWidth
      local handleHeight
      if self.vertical then
        local slidableLength = h - lineSize * 2 - handleSize
        handleX = startX
        handleY = startY + lineSize + percentage * slidableLength
        handleWidth = w
        handleHeight = handleSize
      else
        local slidableLength = w - lineSize * 2 - handleSize
        handleX = startX + lineSize + percentage * slidableLength
        handleY = startY
        handleWidth = handleSize
        handleHeight = h
      end
      if position[1] >= handleX and position[1] <= handleX + handleWidth
        and position[2] >= handleY and position[2] <= handleY + handleHeight
      then
        local dragOffset
        if self.vertical then
          dragOffset = position[2] - handleY
        else
          dragOffset = position[1] - handleX
        end
        self.dragOffset = dragOffset
        self.dragging = true
      else
        if self.vertical then
          if position[2] < handleY then
            self.moving = false
          else
            self.moving = true
          end
        else
          if position[1] < handleX then
            self.moving = false
          else
            self.moving = true
          end
        end
      end
    end
    return true
  end
end

--------------------------------------------------------------------------------
-- List.lua
--------------------------------------------------------------------------------

List = class(Component)
List.borderColor = {84, 84, 84}
List.borderSize = 1
List.backgroundColor = {0, 0, 0}
List.itemPadding = 2
List.scrollBarSize = 3

function List:_init(x, y, width, height, itemSize, itemFactory, horizontal)
  Component._init(self)
  self.x = x
  self.y = y
  self.width = width
  self.height = height
  self.itemSize = itemSize
  self.itemFactory = itemFactory or TextRadioButton
  self.items = {}
  self.topIndex = 1
  self.bottomIndex = 1
  self.itemCount = 0
  self.horizontal = horizontal
  self.mouseOver = false

  local borderSize = self.borderSize
  local barSize = self.scrollBarSize
  local slider
  if horizontal then
    slider = Slider(borderSize + 0.5, borderSize + 0.5
                    , width - borderSize * 2 - 1, barSize, 0, 0, 1, false)
  else
    slider = Slider(width - borderSize - barSize - 0.5
                    , borderSize + 0.5, barSize
                    , height - borderSize * 2 - 1, 0, 0, 1, true)
  end
  slider.lineSize = 0
  slider.handleBorderSize = 0
  slider.handleColor = {84, 84, 84}
  slider.handleHoverColor = {120, 120, 120}
  slider.handlePressedColor = {160, 160, 160}
  slider:addListener(
    "value",
    function(t, k, old, new)
      local list = t.parent
      if list.horizontal then
        list.topIndex = new + 1
      else
        list.topIndex = t.maxValue - t.value + 1
      end
      list:positionItems()
    end
  )
  self.slider = slider
  self:add(slider)

  self:positionItems()
end

function List:draw(dt)
  local startX = self.x + self.offset[1]
  local startY = self.y + self.offset[2]
  local w = self.width
  local h = self.height

  local borderSize = self.borderSize
  local borderColor = self.borderColor
  local borderRect = {startX, startY, startX + w, startY + h}
  local rect = {startX + 1, startY + 1, startX + w - 1, startY + h - 1}
  PtUtil.drawRect(borderRect, borderColor, borderSize)
  PtUtil.fillRect(rect, self.backgroundColor)

  local scrollBarSize = self.scrollBarSize
  if self.horizontal then
    local lineY = startY + borderSize + scrollBarSize + 1.5
    PtUtil.drawLine({startX, lineY}, {startX + w, lineY}, borderColor, 1)
  else
    local lineX = startX + w - borderSize - scrollBarSize - 1.5
    PtUtil.drawLine({lineX, startY}, {lineX, startY + h}, borderColor, 1)
  end
end

function List:emplaceItem(...)
  local width
  local height
  if self.horizontal then
    width = self.itemSize
    height = self.height - (self.borderSize * 2
                              + self.itemPadding * 2
                              + self.scrollBarSize + 2)
  else
    width = self.width - (self.borderSize * 2
                            + self.itemPadding * 2
                            + self.scrollBarSize + 2)
    height = self.itemSize
  end
  item = self.itemFactory(0, 0, width, height, ...)
  return self:addItem(item)
end

function List:addItem(item)
  self:add(item)
  local items = self.items
  local index = #items + 1
  items[index] = item
  self.itemCount = self.itemCount + 1
  self:positionItems()
  return item, index
end

function List:removeItem(target)
  local item
  local index
  if type(target) == "number" then -- Remove by index
    index = target
    item = table.remove(self.items, index)
    if not item then
      return nil, -1
    end
  else -- Remove by item
    if target == nil then
      return nil
    end
    item = target
    index = PtUtil.removeObject(self.items, item)
    if index == -1 then
      return nil, -1
    end
  end
  self:remove(item)
  if not item.filtered then
    self.itemCount = self.itemCount - 1
  end
  if self.bottomIndex > self.itemCount + 1 then
    self:scroll(true)
  else
    self:positionItems()
  end
  return item, index
end

function List:clearItems()
  for index,item in ripairs(self.items) do
    self:removeItem(index)
  end
end

function List:getItem(index)
  return self.items[index]
end

function List:indexOfItem(item)
  for index,obj in ipairs(self.items) do
    if item == obj then
      return index
    end
  end
  return -1
end

function List:filter(filter)
  local itemCount = 0
  if filter then
    for _,item in ipairs(self.items) do
      if not filter(item) then
        item.filtered = true
      else
        itemCount = itemCount + 1
        item.filtered = nil
      end
    end
  else
    for _,item in ipairs(self.items) do
      itemCount = itemCount + 1
      item.filtered = nil
    end
  end
  self.itemCount = itemCount
  self.topIndex = 1
  self:positionItems()
end

function List:positionItems()
  local items = self.items
  local padding = self.itemPadding
  local border = self.borderSize
  local topIndex = self.topIndex
  local itemSize = self.itemSize
  local current
  local min
  if self.horizontal then
    current = border
    min = border + padding
  else
    current = self.height - border
    min = border + padding
  end
  local past = false
  local itemCount = 0
  local possibleItemCount = 1
  for i,item in ipairs(items) do
    if possibleItemCount < topIndex and not item.filtered then
      item.visible = false
      possibleItemCount = possibleItemCount + 1
    elseif past or item.filtered then
      item.visible = false
    else
      itemCount = itemCount + 1
      item.visible = nil
      if self.horizontal then
        item.y = min
        current = current + (padding + itemSize)
        item.x = current
        if current + itemSize > self.width - borderSize then
          item.visible = false
          self.bottomIndex = itemCount + topIndex - 1
          past = true
        end
      else
        item.x = min
        current = current - (padding + itemSize)
        item.y = current
        if current < border then
          item.visible = false
          self.bottomIndex = itemCount + topIndex - 1
          past = true
        end
      end
    end
    item.layout = true
  end
  if not past then
    self.bottomIndex = topIndex + itemCount
  end
  self:updateScrollBar()
end

function List:updateScrollBar()
  local maxLength
  local slider = self.slider
  local offset
  if self.horizontal then
    maxLength = slider.width
  else
    maxLength = slider.height
  end
  local items = self.items
  local topIndex = self.topIndex
  local bottomIndex = self.bottomIndex
  local itemCount = self.itemCount
  if bottomIndex > itemCount and topIndex == 1 then
    slider.handleSize = maxLength
    slider.maxValue = 0
  else
    local numItems = bottomIndex - topIndex -- Number of displayed items
    local barLength = math.max(
      numItems * maxLength / itemCount,
      self.scrollBarSize)
    slider.handleSize = barLength
    slider.maxValue = itemCount - numItems
    if self.horizontal then
      slider.value = topIndex - 1
    else
      slider.value = slider.maxValue - (topIndex - 1)
    end
  end
end

function List:scroll(up)
  if up then
    self.topIndex = math.max(self.topIndex - 1, 1)
  else
    if self.bottomIndex <= self.itemCount then
      self.topIndex = self.topIndex + 1
    end
  end
  self:positionItems()
end

function List:clickEvent(position, button, pressed)
  if button >= 4 then -- scroll
    if pressed then
      if button == 4 then -- Scroll up
        self:scroll(true)
      else -- Scroll down
        self:scroll(false)
      end
    end
    return true
  end
end


text:
class DVAPI TRasterFxRenderData : public TSmartObject
{
public:
	virtual ~TRasterFxRenderData() {}

	virtual bool operator==(const TRasterFxRenderData &data) const = 0;
	virtual std::string toString() const = 0;

	//! Returns a value respresenting the type of a renderData instance. The type
	//! is used to sort renderData entries for both retrieval and processing.
	//! The floating return type specification is used to allow insertions between
	//! two close-up values, if needed.
	virtual float typeIndex() const = 0;

	//! Currently used by TColumnFx to find out whether a renderData instance
	//! will enlarge the rendering of the specified bounding box.
	virtual TRectD getBBoxEnlargement(const TRectD &bbox) { return bbox; }
};

//===================================================================

#ifdef WIN32
template class DVAPI TSmartPointerT<TRasterFxRenderData>;
#endif
typedef TSmartPointerT<TRasterFxRenderData> TRasterFxRenderDataP;

#endif // TRASTERFXRENDERDATA_H


text:
<?xml version="1.0"?>

<!--
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
    this work for additional information regarding copyright ownership.
    The ASF licenses this file to You under the Apache License, Version 2.0
    the "License"); you may not use this file except in compliance with
    the License.  You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
 -->

<project name="solr-dataimporthandler-extras" default="default">

  <description>
    Data Import Handler Extras
  </description>

  <import file="../contrib-build.xml"/>

  <solr-contrib-uptodate name="dataimporthandler"
                         property="solr-dataimporthandler.uptodate"
                         classpath.property="solr-dataimporthandler.jar"/>

  <target name="compile-solr-dataimporthandler" unless="solr-dataimporthandler.uptodate">
  	<ant dir="${common-solr.dir}/contrib/dataimporthandler" target="compile-core" inheritAll="false">
      <propertyset refid="uptodate.and.compiled.properties"/>
    </ant>
  </target>

  <!--
       really sucks we do this always, without an up-to-date thing for tests
       we should probably fix this, the same issue exists in modules
   -->
  <target name="compile-solr-dataimporthandler-tests">
  	<ant dir="${common-solr.dir}/contrib/dataimporthandler" target="compile-test" inheritAll="false">
      <propertyset refid="uptodate.and.compiled.properties"/>
    </ant>
  </target>

  <!-- we don't actually need to compile this thing, we just want its libs -->
  <target name="resolve-extraction-libs">
    <ant dir="${common-solr.dir}/contrib/extraction" target="resolve" inheritAll="false">
      <propertyset refid="uptodate.and.compiled.properties"/>
    </ant>
  </target>

  <path id="classpath">
    <pathelement location="${common-solr.dir}/build/contrib/solr-dataimporthandler/classes/java"/>
    <fileset dir="${common-solr.dir}/contrib/dataimporthandler-extras/lib" excludes="${common.classpath.excludes}"/>
    <fileset dir="${common-solr.dir}/contrib/extraction/lib" excludes="${common.classpath.excludes}"/>
    <path refid="solr.base.classpath"/>
  </path>

  <path id="test.classpath">
    <path refid="solr.test.base.classpath"/>
    <pathelement location="${common-solr.dir}/build/contrib/solr-dataimporthandler/classes/test"/>
    <path refid="classpath"/>
    <fileset dir="${test.lib.dir}" includes="*.jar"/>
  </path>

  <!-- TODO: make this nicer like lucene? -->
  <target name="javadocs" depends="compile-core,define-lucene-javadoc-url,lucene-javadocs,javadocs-solr-core,javadocs-dataimporthandler,check-javadocs-uptodate" unless="javadocs-uptodate-${name}">
        <sequential>
      <mkdir dir="${javadoc.dir}/${name}"/>
      <solr-invoke-javadoc>
        <solrsources>
          <packageset dir="${src.dir}"/>
        </solrsources>
        <links>
          <link href="../solr-solrj"/>
          <link href="../solr-core"/>
          <link href="../solr-dataimporthandler"/>
        </links>
      </solr-invoke-javadoc>
      <solr-jarify basedir="${javadoc.dir}/${name}" destfile="${build.dir}/${final.name}-javadoc.jar"/>
     </sequential>
  </target>

  <target name="javadocs-dataimporthandler">
    <ant dir="${common-solr.dir}/contrib/dataimporthandler" target="javadocs" inheritAll="false">
      <propertyset refid="uptodate.and.compiled.properties"/>
    </ant>
  </target>

  <target name="-ecj-javadoc-lint-tests" depends="compile-solr-dataimporthandler-tests,common.-ecj-javadoc-lint-tests"/>

  <target name="compile-core" depends="compile-solr-dataimporthandler,resolve-extraction-libs,solr-contrib-build.compile-core"/>
  <target name="compile-test" depends="compile-solr-dataimporthandler-tests, common-solr.compile-test"/>
</project>


text:
import utils.xmls as xml_utils
import utils.unicode as unicode_utils

from venues.models import Venue

from django.core.management.base import BaseCommand

def is_venue(xml_obj):
    """Return true if the XML object has a Team tag"""
    return xml_obj.tag == "Venue"

class Command(BaseCommand):
    """
    Sample usage:
    python manage.py build_venue_table \
        --dry_run \
        --data_filename=data/f9/srml-98-2016-f842641-matchresults.xml
    """
    help = "Populate venue table"

    def add_arguments(self, parser):
        """Add custom CLI arguments"""
        parser.add_argument(
            "--dry_run",
            action="store_true",
            dest="dry_run",
            default=False,
            help="Don't save and just print venues",
            )

        parser.add_argument(
            "--data_filename",
            dest="data_filename",
            type=str,
            required=True,
            help="Filename with data",
            )

    def handle(self, *args, **options):
        data_filename = options["data_filename"]
        is_dry_run = options["dry_run"]

        new_venues = []
        print "Importing venues from %s" % data_filename
        if is_dry_run:
            print "This is a dry run and will not save any data"

        xml_data_root = xml_utils.get_root_from_file(data_filename)

        for child in xml_utils.get_children(xml_data_root):
            # Iterate over each item
            for item in xml_utils.get_children(child):
                if is_venue(item) == False:
                    continue
                name = xml_utils.get_tag(item, "Name").text
                name = unicode_utils.remove_accents(name)
                uuid = xml_utils.get_attrib(item, "uID")
                country = xml_utils.get_tag(item, "Country").text
                venue = Venue(name=name, uuid=uuid, country=country)
                new_venues.append(venue)

        # get all existing uuids
        existing_venue_uuids = Venue.objects.all().values_list("uuid")

        # log out for audit and save if not dry run and it is a new venue
        for venue in new_venues:
            print venue.__dict__
            if is_dry_run == False and venue.uuid not in existing_venue_uuids:
                venue.save()


text:
set -e

SCRIPTS=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
ROOT=$(dirname $SCRIPTS)
TEMP=$(mktemp -d /tmp/react-native-XXXXXXXX)

# When tests run on CI server, we won't be able to see logs
# from packager because it runs in a separate window. This is
# a simple workaround, see packager/packager.sh
export REACT_PACKAGER_LOG="$TEMP/server.log"

# To make sure we actually installed the local version
# of react-native, we will create a temp file inside SampleApp
# and check that it exists after `react-native init`
MARKER=$(mktemp $ROOT/Examples/SampleApp/XXXXXXXX)

function cleanup {
  EXIT_CODE=$?
  set +e

  if [ $EXIT_CODE -ne 0 ];
  then
    WATCHMAN_LOGS=/usr/local/Cellar/watchman/3.1/var/run/watchman/$USER.log
    [ -f $WATCHMAN_LOGS ] && cat $WATCHMAN_LOGS

    [ -f $REACT_PACKAGER_LOG ] && cat $REACT_PACKAGER_LOG
  fi

  rm $MARKER
  [ $SINOPIA_PID ] && kill -9 $SINOPIA_PID
  [ $SERVER_PID ] && kill -9 $SERVER_PID
  [ -f ~/.npmrc.bak ] && mv ~/.npmrc.bak ~/.npmrc
}
trap cleanup EXIT

cd $TEMP

# sinopia is npm registry proxy, it is used to make npm
# think react-native and react-native-cli are actually
# published on npm
which sinopia || npm install -g sinopia

# but in order to make npm use sinopia we temporarily
# replace its config file
[ -f ~/.npmrc ] && cp ~/.npmrc ~/.npmrc.bak
cp $SCRIPTS/e2e-npmrc ~/.npmrc

sinopia --config $SCRIPTS/e2e-sinopia.config.yml &
SINOPIA_PID=$!

# Make sure to remove old version of react-native in
# case it was cached
npm unpublish react-native --force
npm unpublish react-native-cli --force
npm publish $ROOT
npm publish $ROOT/react-native-cli

npm install -g react-native-cli
react-native init EndToEndTest
cd EndToEndTest

# Make sure we installed local version of react-native
ls `basename $MARKER` > /dev/null

flow --retries 10

node ./node_modules/react-native/packager/packager.js --nonPersistent &
SERVER_PID=$!
cd iOS
xctool -scheme EndToEndTest -sdk iphonesimulator test


text:
package org.hope6537.note.design.flyweight.multi;

/**
 * 使用外部状态类来表示
 */
public class ExtrinsicState {

    private String subject;

    private String location;

    public ExtrinsicState(String subject, String location) {
        this.subject = subject;
        this.location = location;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        ExtrinsicState that = (ExtrinsicState) o;

        if (location != null ? !location.equals(that.location) : that.location != null) return false;
        if (subject != null ? !subject.equals(that.subject) : that.subject != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = subject != null ? subject.hashCode() : 0;
        result = 31 * result + (location != null ? location.hashCode() : 0);
        return result;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }
}


text:
import json
import logging
import re
import threading
import time
from urllib.parse import unquote_plus, urlparse

import websocket

from streamlink import logger
from streamlink.plugin import Plugin, PluginArgument, PluginArguments, pluginmatcher
from streamlink.plugin.api import useragents
from streamlink.stream import HLSStream
from streamlink.utils.times import hours_minutes_seconds
from streamlink.utils.url import update_qsd

_log = logging.getLogger(__name__)

_login_url = "https://account.nicovideo.jp/login/redirector"

_login_url_params = {
    "show_button_twitter": 1,
    "show_button_facebook": 1,
    "next_url": "/"}

@pluginmatcher(re.compile(
    r"https?://(?P<domain>live\d*\.nicovideo\.jp)/watch/lv\d*"
))
class NicoLive(Plugin):
    arguments = PluginArguments(
        PluginArgument(
            "email",
            argument_name="niconico-email",
            sensitive=True,
            metavar="EMAIL",
            help="The email or phone number associated with your "
                 "Niconico account"),
        PluginArgument(
            "password",
            argument_name="niconico-password",
            sensitive=True,
            metavar="PASSWORD",
            help="The password of your Niconico account"),
        PluginArgument(
            "user-session",
            argument_name="niconico-user-session",
            sensitive=True,
            metavar="VALUE",
            help="Value of the user-session token \n(can be used in "
                 "case you do not want to put your password here)"),
        PluginArgument(
            "purge-credentials",
            argument_name="niconico-purge-credentials",
            action="store_true",
            help="""
        Purge cached Niconico credentials to initiate a new session
        and reauthenticate.
        """),
        PluginArgument(
            "timeshift-offset",
            type=hours_minutes_seconds,
            argument_name="niconico-timeshift-offset",
            metavar="[HH:]MM:SS",
            default=None,
            help="Amount of time to skip from the beginning of a stream. "
                 "Default is 00:00:00."))

    is_stream_ready = False
    is_stream_ended = False
    watching_interval = 30
    watching_interval_worker_thread = None
    stream_reader = None
    _ws = None

    frontend_id = None

    def _get_streams(self):
        if self.options.get("purge_credentials"):
            self.clear_cookies()
            _log.info("All credentials were successfully removed")

        self.url = self.url.split("?")[0]
        self.session.http.headers.update({
            "User-Agent": useragents.CHROME,
        })

        self.niconico_web_login()
        if not self.get_wss_api_url():
            _log.error(
                "Failed to get wss_api_url. "
                "Please check if the URL is correct, "
                "and make sure your account has access to the video.")
            return None

        self.api_connect(self.wss_api_url)

        i = 0
        while not self.is_stream_ready:
            if i % 10 == 0:
                _log.debug("Waiting for permit...")
            if i == 600:
                _log.error("Waiting for permit timed out.")
                return None
            if self.is_stream_ended:
                return None
            time.sleep(0.1)
            i += 1

        streams = HLSStream.parse_variant_playlist(
            self.session, self.hls_stream_url)

        nico_streams = {}
        for s in streams:
            nico_stream = NicoHLSStream(streams[s], self)
            nico_streams[s] = nico_stream

        return nico_streams

    def get_wss_api_url(self):
        _log.debug("Getting video page: {0}".format(self.url))
        resp = self.session.http.get(self.url)

        try:
            self.wss_api_url = extract_text(
                resp.text, ""webSocketUrl":"", """)
            if not self.wss_api_url:
                return False
        except Exception as e:
            _log.debug(e)
            _log.debug("Failed to extract wss api url")
            return False

        try:
            self.frontend_id = extract_text(
                resp.text, ""frontendId":", ","")
        except Exception as e:
            _log.debug(e)
            _log.warning("Failed to extract frontend id")

        self.wss_api_url = "{0}&frontend_id={1}".format(self.wss_api_url, self.frontend_id)

        _log.debug("Video page response code: {0}".format(resp.status_code))
        _log.trace("Video page response body: {0}".format(resp.text))
        _log.debug("Got wss_api_url: {0}".format(self.wss_api_url))
        _log.debug("Got frontend_id: {0}".format(self.frontend_id))

        return self.wss_api_url.startswith("wss://")

    def api_on_open(self):
        self.send_playerversion()
        require_new_stream = not self.is_stream_ready
        self.send_getpermit(require_new_stream=require_new_stream)

    def api_on_error(self, ws, error=None):
        if error:
            _log.warning(error)
        _log.warning("wss api disconnected.")
        _log.warning("Attempting to reconnect in 5 secs...")
        time.sleep(5)
        self.api_connect(self.wss_api_url)

    def api_connect(self, url):
        # Proxy support adapted from the UStreamTV plugin (ustreamtv.py)
        proxy_url = self.session.get_option("https-proxy")
        if proxy_url is None:
            proxy_url = self.session.get_option("http-proxy")
        proxy_options = parse_proxy_url(proxy_url)
        if proxy_options.get('http_proxy_host'):
            _log.debug("Using proxy ({0}://{1}:{2})".format(
                proxy_options.get('proxy_type') or "http",
                proxy_options.get('http_proxy_host'),
                proxy_options.get('http_proxy_port') or 80))

        _log.debug("Connecting: {0}".format(url))
        if logger.root.level <= logger.TRACE:
            websocket.enableTrace(True, _log)

        def on_error(wssapp, error):
            return self.api_on_error(wssapp, error)

        def on_message(wssapp, message):
            return self.handle_api_message(message)

        def on_open(wssapp):
            return self.api_on_open()

        self._ws = websocket.WebSocketApp(
            url,
            header=["User-Agent: {0}".format(useragents.CHROME)],
            on_open=on_open,
            on_message=on_message,
            on_error=on_error)
        self.ws_worker_thread = threading.Thread(
            target=self._ws.run_forever,
            kwargs=proxy_options)
        self.ws_worker_thread.daemon = True
        self.ws_worker_thread.start()

    def send_message(self, type_, body):
        msg = {"type": type_, "body": body}
        msg_json = json.dumps(msg)
        _log.debug(f"Sending: {msg_json}")
        if self._ws and self._ws.sock.connected:
            self._ws.send(msg_json)
        else:
            _log.warning("wss api is not connected.")

    def send_no_body_message(self, type_):
        msg = {"type": type_}
        msg_json = json.dumps(msg)
        _log.debug(f"Sending: {msg_json}")
        if self._ws and self._ws.sock.connected:
            self._ws.send(msg_json)
        else:
            _log.warning("wss api is not connected.")

    def send_custom_message(self, msg):
        msg_json = json.dumps(msg)
        _log.debug(f"Sending: {msg_json}")
        if self._ws and self._ws.sock.connected:
            self._ws.send(msg_json)
        else:
            _log.warning("wss api is not connected.")

    def send_playerversion(self):
        body = {
            "type": "startWatching",
            "data": {
                "stream": {
                    "quality": "abr",
                    "protocol": "hls",
                    "latency": "high",
                    "chasePlay": False
                },
                "room": {
                    "protocol": "webSocket",
                    "commentable": True
                },
                "reconnect": False
            }
        }
        self.send_custom_message(body)

    def send_getpermit(self, require_new_stream=True):
        body = {
            "type": "getAkashic",
            "data": {
                "chasePlay": False
            }
        }
        self.send_custom_message(body)

    def send_watching(self):
        body = {
            "command": "watching",
            "params": [self.broadcast_id, "-1", "0"]
        }
        self.send_message("watch", body)

    def send_pong(self):
        self.send_no_body_message("pong")
        self.send_no_body_message("keepSeat")

    def handle_api_message(self, message):
        _log.debug(f"Received: {message}")
        message_parsed = json.loads(message)

        if message_parsed["type"] == "stream":
            data = message_parsed["data"]
            self.hls_stream_url = data["uri"]
            # load in the offset for timeshift live videos
            offset = self.get_option("timeshift-offset")
            if offset and 'timeshift' in self.wss_api_url:
                self.hls_stream_url = update_qsd(self.hls_stream_url, {"start": offset})
            self.is_stream_ready = True

        if message_parsed["type"] == "watch":
            body = message_parsed["body"]
            command = body["command"]

            if command == "currentstream":
                current_stream = body["currentStream"]
                self.hls_stream_url = current_stream["uri"]
                self.is_stream_ready = True

            elif command == "watchinginterval":
                self.watching_interval = int(body["params"][0])
                _log.debug("Got watching_interval: {0}".format(
                    self.watching_interval))

                if self.watching_interval_worker_thread is None:
                    _log.debug("send_watching_scheduler starting.")
                    self.watching_interval_worker_thread = threading.Thread(
                        target=self.send_watching_scheduler)
                    self.watching_interval_worker_thread.daemon = True
                    self.watching_interval_worker_thread.start()

                else:
                    _log.debug("send_watching_scheduler already running.")

            elif command == "disconnect":
                _log.info("Websocket API closed.")
                _log.info("Stream ended.")
                self.is_stream_ended = True

                if self.stream_reader is not None:
                    self.stream_reader.close()
                    _log.info("Stream reader closed.")

        elif message_parsed["type"] == "ping":
            self.send_pong()

    def send_watching_scheduler(self):
        """
        Periodically send "watching" command to the API.
        This is necessary to keep the session alive.
        """
        while not self.is_stream_ended:
            self.send_watching()
            time.sleep(self.watching_interval)

    def niconico_web_login(self):
        user_session = self.get_option("user-session")
        email = self.get_option("email")
        password = self.get_option("password")

        if user_session is not None:
            _log.info("User session cookie is provided. Using it.")
            self.session.http.cookies.set(
                "user_session",
                user_session,
                path="/",
                domain="nicovideo.jp")
            self.save_cookies()
            return True
        elif self.session.http.cookies.get("user_session"):
            _log.info("cached session cookie is provided. Using it.")
            return True
        elif email is not None and password is not None:
            _log.info("Email and password are provided. Attemping login.")

            payload = {"mail_tel": email, "password": password}
            resp = self.session.http.post(_login_url, data=payload,
                                          params=_login_url_params)

            _log.debug("Login response code: {0}".format(resp.status_code))
            _log.trace("Login response body: {0}".format(resp.text))
            _log.debug("Cookies: {0}".format(
                self.session.http.cookies.get_dict()))

            if self.session.http.cookies.get("user_session") is None:
                try:
                    msg = extract_text(
                        resp.text, '
', "
")
                except Exception as e:
                    _log.debug(e)
                    msg = "unknown reason"
                _log.warning("Login failed. {0}".format(msg))
                return False
            else:
                _log.info("Logged in.")
                self.save_cookies()
                return True
        else:
            return False

class NicoHLSStream(HLSStream):

    def __init__(self, hls_stream, nicolive_plugin):
        super().__init__(
            hls_stream.session,
            force_restart=hls_stream.force_restart,
            start_offset=hls_stream.start_offset,
            duration=hls_stream.duration,
            **hls_stream.args)
        # url is already in hls_stream.args

        self.nicolive_plugin = nicolive_plugin

    def open(self):
        reader = super().open()
        self.nicolive_plugin.stream_reader = reader
        return reader

def extract_text(text, left, right):
    """Extract text from HTML"""
    result = re.findall("{0}(.*?){1}".format(left, right), text)
    if len(result) != 1:
        raise Exception("Failed to extract string. "
                        "Expected 1, found {0}".format(len(result)))
    return result[0]

def parse_proxy_url(purl):
    """Adapted from UStreamTV plugin (ustreamtv.py)"""

    proxy_options = {}
    if purl:
        p = urlparse(purl)
        proxy_options['proxy_type'] = p.scheme
        proxy_options['http_proxy_host'] = p.hostname
        if p.port:
            proxy_options['http_proxy_port'] = p.port
        if p.username:
            proxy_options['http_proxy_auth'] = \
                (unquote_plus(p.username), unquote_plus(p.password or ""))
    return proxy_options

__plugin__ = NicoLive


text:
package rui.coder.foundation.io;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.io.*;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

/**
 * <p>
 * 类描述
 * </p>
 * 创建于 2017/2/13
 *
 * @author 赵睿
 */
class StreamTest {

    @Test
    @DisplayName("先关闭然后读取,期待异常")
    void closeThenRead() throws IOException {
        FileInputStream fileInputStream=new FileInputStream(new File("D:/Pictures/龙王.jpg"));
        fileInputStream.close();
        @SuppressWarnings("ResultOfMethodCallIgnored")
        Throwable throwable=assertThrows(IOException.class, fileInputStream::read);
        assertEquals("Stream Closed",throwable.getMessage());
    }
}


text:
package org.powermock.api.mockito.internal.mockcreation;

import org.mockito.MockSettings;
import org.mockito.Mockito;
import org.mockito.internal.InternalMockHandler;
import org.mockito.internal.creation.MockSettingsImpl;
import org.mockito.internal.creation.instance.DefaultInstantiatorProvider;
import org.mockito.internal.handler.MockHandlerFactory;
import org.mockito.internal.util.MockNameImpl;
import org.mockito.internal.util.reflection.LenientCopyTool;
import org.powermock.api.mockito.internal.invocation.MockitoMethodInvocationControl;
import org.powermock.api.mockito.repackaged.ClassImposterizer;
import org.powermock.api.mockito.repackaged.MethodInterceptorFilter;
import org.powermock.core.ClassReplicaCreator;
import org.powermock.core.DefaultFieldValueGenerator;
import org.powermock.core.MockRepository;
import org.powermock.core.classloader.MockClassLoader;
import org.powermock.reflect.Whitebox;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class MockCreator extends AbstractMockCreator {

    private static final MockCreator MOCK_CREATOR = new MockCreator();

    @SuppressWarnings("unchecked")
    public static <T> T mock(Class<T> type, boolean isStatic, boolean isSpy, Object delegator,
                             MockSettings mockSettings, Method... methods) {
        return MOCK_CREATOR.createMock(type, isStatic, isSpy, delegator, mockSettings, methods);
    }

    @SuppressWarnings("unchecked")
    protected <T> T createMock(Class<T> type, boolean isStatic, boolean isSpy, Object delegator,
                               MockSettings mockSettings, Method... methods) {
        if (type == null) {
            throw new IllegalArgumentException("The class to mock cannot be null");
        }

        validateType(type, isStatic, isSpy);

        final String mockName = toInstanceName(type, mockSettings);

        MockRepository.addAfterMethodRunner(new MockitoStateCleanerRunnable());

        final Class<T> typeToMock;
        if (isFinalJavaSystemClass(type)) {
            typeToMock = (Class<T>) new ClassReplicaCreator().createClassReplica(type);
        } else {
            typeToMock = type;
        }

        final MockData<T> mockData = createMethodInvocationControl(mockName, typeToMock, methods, isSpy, delegator,
                mockSettings);

        T mock = mockData.getMock();
        if (isFinalJavaSystemClass(type) && !isStatic) {
            mock = Whitebox.newInstance(type);
            DefaultFieldValueGenerator.fillWithDefaultValues(mock);
        }

        if (isStatic) {
            MockRepository.putStaticMethodInvocationControl(type, mockData.getMethodInvocationControl());
        } else {
            MockRepository.putInstanceMethodInvocationControl(mock, mockData.getMethodInvocationControl());
        }

        if (isSpy) {
            new LenientCopyTool().copyToMock(delegator, mock);
        }

        return mock;
    }

    private static <T> boolean isFinalJavaSystemClass(Class<T> type) {
        return type.getName().startsWith("java.") && Modifier.isFinal(type.getModifiers());
    }

    @SuppressWarnings("unchecked")
    private static <T> MockData<T> createMethodInvocationControl(final String mockName, Class<T> type,
                                                                 Method[] methods, boolean isSpy, Object delegator, MockSettings mockSettings) {
        final MockSettingsImpl settings;
        if (mockSettings == null) {
            // We change the context classloader to the current CL in order for the Mockito
            // framework to load it's plugins (such as MockMaker) correctly.
            final ClassLoader originalCL = Thread.currentThread().getContextClassLoader();
            Thread.currentThread().setContextClassLoader(MockCreator.class.getClassLoader());
            try {
                settings = (MockSettingsImpl) Mockito.withSettings();
            } finally {
                Thread.currentThread().setContextClassLoader(originalCL);
            }
        } else {
            settings = (MockSettingsImpl) mockSettings;
        }

        if (isSpy) {
            settings.defaultAnswer(Mockito.CALLS_REAL_METHODS);
        }

        settings.setMockName(new MockNameImpl(mockName));
        settings.setTypeToMock(type);

        InternalMockHandler mockHandler = new MockHandlerFactory().create(settings);
        MethodInterceptorFilter filter = new PowerMockMethodInterceptorFilter(mockHandler, settings);
        final T mock = new ClassImposterizer(new DefaultInstantiatorProvider().getInstantiator(settings)).imposterise(filter, type);
        ClassLoader classLoader = mock.getClass().getClassLoader();
        if (classLoader instanceof MockClassLoader) {
            MockClassLoader mcl = (MockClassLoader) classLoader;
            mcl.cache(mock.getClass());
        }
        final MockitoMethodInvocationControl invocationControl = new MockitoMethodInvocationControl(
                filter,
                isSpy && delegator == null ? new Object() : delegator,
                mock,
                methods);

        return new MockData<T>(invocationControl, mock);
    }

    private  String toInstanceName(Class<?> clazz, final MockSettings mockSettings) {
        // if the settings define a mock name, use it
        if (mockSettings instanceof MockSettingsImpl<?>) {
            String settingName = ((MockSettingsImpl<?>) mockSettings).getName();
            if (settingName != null) {
                return settingName;
            }
        }

        // else, use the class name as mock name
        String className = clazz.getSimpleName();
        if (className.length() == 0) {
            return clazz.getName();
        }
        // lower case first letter
        return className.substring(0, 1).toLowerCase() + className.substring(1);
    }

    /**
     * Class that encapsulate a mock and its corresponding invocation control.
     */
    private static class MockData<T> {
        private final MockitoMethodInvocationControl methodInvocationControl;

        private final T mock;

        MockData(MockitoMethodInvocationControl methodInvocationControl, T mock) {
            this.methodInvocationControl = methodInvocationControl;
            this.mock = mock;
        }

        public MockitoMethodInvocationControl getMethodInvocationControl() {
            return methodInvocationControl;
        }

        public T getMock() {
            return mock;
        }
    }

    /**
     * Clear state in Mockito that retains memory between tests
     */
    private static class MockitoStateCleanerRunnable implements Runnable {
        public void run() {
            MockitoStateCleaner cleaner = new MockitoStateCleaner();
            cleaner.clearConfiguration();
            cleaner.clearMockProgress();
        }

    }
}