Merge branch 'master' into production

This commit is contained in:
Nick Winter 2014-07-16 16:15:46 -07:00
commit 727638b090
70 changed files with 616 additions and 96 deletions

View file

@ -96,7 +96,9 @@ Aether.addGlobal('_', _);
var serializedClasses = { var serializedClasses = {
"Thang": self.require('lib/world/thang'), "Thang": self.require('lib/world/thang'),
"Vector": self.require('lib/world/vector'), "Vector": self.require('lib/world/vector'),
"Rectangle": self.require('lib/world/rectangle') "Rectangle": self.require('lib/world/rectangle'),
"Ellipse": self.require('lib/world/ellipse'),
"LineSegment": self.require('lib/world/line_segment')
}; };
self.currentUserCodeMapCopy = ""; self.currentUserCodeMapCopy = "";
self.currentDebugWorldFrame = 0; self.currentDebugWorldFrame = 0;

View file

@ -181,12 +181,11 @@ module.exports = class Mark extends CocoClass
buildDebug: -> buildDebug: ->
@mark = new createjs.Shape() @mark = new createjs.Shape()
PX = 3 PX = 3
[w, h] = [Math.max(PX, @sprite.thang.width * Camera.PPM), Math.max(PX, @sprite.thang.height * Camera.PPM) * @camera.y2x] [w, h] = [Math.max(PX, @sprite.thang.width * Camera.PPM), Math.max(PX, @sprite.thang.height * Camera.PPM) * @camera.y2x] # TODO: doesn't work with rotation
@mark.alpha = 0.5 @mark.alpha = 0.5
@mark.graphics.beginFill '#abcdef' @mark.graphics.beginFill '#abcdef'
if @sprite.thang.shape in ['ellipsoid', 'disc'] if @sprite.thang.shape in ['ellipsoid', 'disc']
[w, h] = [Math.max(PX, w, h), Math.max(PX, w, h)] @mark.graphics.drawEllipse -w / 2, -h / 2, w, h
@mark.graphics.drawCircle 0, 0, w / 2
else else
@mark.graphics.drawRect -w / 2, -h / 2, w, h @mark.graphics.drawRect -w / 2, -h / 2, w, h
@mark.graphics.endFill() @mark.graphics.endFill()
@ -259,7 +258,7 @@ module.exports = class Mark extends CocoClass
updateRotation: -> updateRotation: ->
if @name is 'debug' or (@name is 'shadow' and @sprite.thang?.shape in ['rectangle', 'box']) if @name is 'debug' or (@name is 'shadow' and @sprite.thang?.shape in ['rectangle', 'box'])
@mark.rotation = @sprite.thang.rotation * 180 / Math.PI @mark.rotation = -@sprite.thang.rotation * 180 / Math.PI
updateScale: -> updateScale: ->
if @name is 'bounds' and ((@sprite.thang.width isnt @lastWidth or @sprite.thang.height isnt @lastHeight) or (@sprite.thang.drawsBoundsIndex isnt @drawsBoundsIndex)) if @name is 'bounds' and ((@sprite.thang.width isnt @lastWidth or @sprite.thang.height isnt @lastHeight) or (@sprite.thang.drawsBoundsIndex isnt @drawsBoundsIndex))

View file

@ -0,0 +1,174 @@
Vector = require './vector'
LineSegment = require './line_segment'
Rectangle = require './rectangle'
class Ellipse
@className: "Ellipse"
# TODO: add class methods for add, multiply, subtract, divide, rotate
isEllipse: true
apiProperties: ['x', 'y', 'width', 'height', 'rotation', 'distanceToPoint', 'distanceSquaredToPoint', 'distanceToRectangle', 'distanceSquaredToRectangle', 'distanceToEllipse', 'distanceSquaredToEllipse', 'distanceToShape', 'distanceSquaredToShape', 'containsPoint', 'intersectsLineSegment', 'intersectsRectangle', 'intersectsEllipse', 'getPos', 'containsPoint', 'copy']
constructor: (@x=0, @y=0, @width=0, @height=0, @rotation=0) ->
copy: ->
new Ellipse(@x, @y, @width, @height, @rotation)
getPos: ->
new Vector(@x, @y)
rectangle: ->
new Rectangle(@x, @y, @width, @height, @rotation)
axisAlignedBoundingBox: (rounded=true) ->
@rectangle().axisAlignedBoundingBox()
distanceToPoint: (p) ->
@rectangle().distanceToPoint p # TODO: actually implement ellipse ellipse-point distance
distanceSquaredToPoint: (p) ->
# Doesn't handle rotation; just supposed to be faster than distanceToPoint.
@rectangle().distanceSquaredToPoint p # TODO: actually implement ellipse-point distance
distanceToRectangle: (other) ->
Math.sqrt @distanceSquaredToRectangle other
distanceSquaredToRectangle: (other) ->
@rectangle().distanceSquaredToRectangle other # TODO: actually implement ellipse-rectangle distance
distanceToEllipse: (ellipse) ->
Math.sqrt @distanceSquaredToEllipse ellipse
distanceSquaredToEllipse: (ellipse) ->
@rectangle().distanceSquaredToEllipse ellipse # TODO: actually implement ellipse-ellipse distance
distanceToShape: (shape) ->
Math.sqrt @distanceSquaredToShape shape
distanceSquaredToShape: (shape) ->
if shape.isEllipse then @distanceSquaredToEllipse shape else @distanceSquaredToRectangle shape
containsPoint: (p, withRotation=true) ->
[a, b] = [@width / 2, @height / 2]
[h, k] = [@x, @y]
[x, y] = [p.x, p.y]
x2 = Math.pow(x, 2)
a2 = Math.pow(a, 2)
a4 = Math.pow(a, 4)
b2 = Math.pow(b, 2)
b4 = Math.pow(b, 4)
h2 = Math.pow(h, 2)
k2 = Math.pow(k, 2)
if withRotation and @rotation
sint = Math.sin(@rotation)
sin2t = Math.sin(2 * @rotation)
cost = Math.cos(@rotation)
cos2t = Math.cos(2 * @rotation)
numeratorLeft = (-a2 * h * sin2t) + (a2 * k * cos2t) + (a2 * k) + (a2 * x * sin2t)
numeratorMiddle = Math.SQRT2 * Math.sqrt((a4 * b2 * cos2t) + (a4 * b2) - (a2 * b4 * cos2t) + (a2 * b4) - (2 * a2 * b2 * h2) + (4 * a2 * b2 * h * x) - (2 * a2 * b2 * x2))
numeratorRight = (b2 * h * sin2t) - (b2 * k * cos2t) + (b2 * k) - (b2 * x * sin2t)
denominator = (a2 * cos2t) + a2 - (b2 * cos2t) + b2
solution1 = (numeratorLeft - numeratorMiddle + numeratorRight) / denominator
solution2 = (numeratorLeft + numeratorMiddle + numeratorRight) / denominator
if (not isNaN solution1) and (not isNaN solution2)
[bigSolution, littleSolution] = if solution1 > solution2 then [solution1, solution2] else [solution2, solution1]
if y > littleSolution and y < bigSolution
return true
else
return false
else
return false
else
numeratorLeft = a2 * k
numeratorRight = Math.sqrt((a4 * b2) - (a2 * b2 * h2) + (2 * a2 * b2 * h * x) - (a2 * b2 * x2))
denominator = a2
solution1 = (numeratorLeft + numeratorRight) / denominator
solution2 = (numeratorLeft - numeratorRight) / denominator
if (not isNaN solution1) and (not isNaN solution2)
[bigSolution, littleSolution] = if solution1 > solution2 then [solution1, solution2] else [solution2, solution1]
if y > littleSolution and y < bigSolution
return true
else
return false
else
return false
false
intersectsLineSegment: (p1, p2) ->
[px1, py1, px2, py2] = [p1.x, p1.y, p2.x, p2.y]
m = (py1 - py2) / (px1 - px2)
m2 = Math.pow(m, 2)
c = py1 - (m * px1)
c2 = Math.pow(c, 2)
[a, b] = [@width / 2, @height / 2]
[h, k] = [@x, @y]
a2 = Math.pow(a, 2)
a4 = Math.pow(a, 2)
b2 = Math.pow(b, 2)
b4 = Math.pow(b, 4)
h2 = Math.pow(h, 2)
k2 = Math.pow(k, 2)
sint = Math.sin(@rotation)
sin2t = Math.sin(2 * @rotation)
cost = Math.cos(@rotation)
cos2t = Math.cos(2 * @rotation)
if (not isNaN m) and m != Infinity and m != -Infinity
numeratorLeft = (-a2 * c * m * cos2t) - (a2 * c * m) + (a2 * c * sin2t) - (a2 * h * m * sin2t) - (a2 * h * cos2t) + (a2 * h) + (a2 * k * m * cos2t) + (a2 * k * m) - (a2 * k * sin2t)
numeratorMiddle = Math.SQRT2 * Math.sqrt((a4 * b2 * m2 * cos2t) + (a4 * b2 * m2) - (2 * a4 * b2 * m * sin2t) - (a4 * b2 * cos2t) + (a4 * b2) - (a2 * b4 * m2 * cos2t) + (a2 * b4 * m2) + (2 * a2 * b4 * m * sin2t) + (a2 * b4 * cos2t) + (a2 * b4) - (2 * a2 * b2 * c2) - (4 * a2 * b2 * c * h * m) + (4 * a2 * b2 * c * k) - (2 * a2 * b2 * h2 * m2) + (4 * a2 * b2 * h * k * m) - (2 * a2 * b2 * k2))
numeratorRight = (b2 * c * m * cos2t) - (b2 * c * m) - (b2 * c * sin2t) + (b2 * h * m * sin2t) + (b2 * h * cos2t) + (b2 * h) - (b2 * k * m * cos2t) + (b2 * k * m) + (b2 * k * sin2t)
denominator = (a2 * m2 * cos2t) + (a2 * m2) - (2 * a2 * m * sin2t) - (a2 * cos2t) + a2 - (b2 * m2 * cos2t) + (b2 * m2) + (2 * b2 * m * sin2t) + (b2 * cos2t) + b2
solution1 = (-numeratorLeft - numeratorMiddle + numeratorRight) / denominator
solution2 = (-numeratorLeft + numeratorMiddle + numeratorRight) / denominator
if (not isNaN solution1) and (not isNaN solution2)
[littleX, bigX] = if px1 < px2 then [px1, px2] else [px2, px1]
if (littleX <= solution1 and bigX >= solution1) or (littleX <= solution2 and bigX >= solution2)
return true
if (not isNaN solution1) or (not isNaN solution2)
solution = if not isNaN solution1 then solution1 else solution2
[littleX, bigX] = if px1 < px2 then [px1, px2] else [px2, px1]
if littleX <= solution and bigX >= solution
return true
else
return false
else
x = px1
x2 = Math.pow(x, 2)
numeratorLeft = (-a2 * h * sin2t) + (a2 * k * cos2t) + (a2 * k) + (a2 * x * sin2t)
numeratorMiddle = Math.SQRT2 * Math.sqrt((a4 * b2 * cos2t) + (a4 * b2) - (a2 * b4 * cos2t) + (a2 * b4) - (2 * a2 * b2 * h2) + (4 * a2 * b2 * h * x) - (2 * a2 * b2 * x2))
numeratorRight = (b2 * h * sin2t) - (b2 * k * cos2t) + (b2 * k) - (b2 * x * sin2t)
denominator = (a2 * cos2t) + a2 - (b2 * cos2t) + b2
solution1 = (numeratorLeft - numeratorMiddle + numeratorRight) / denominator
solution2 = (numeratorLeft + numeratorMiddle + numeratorRight) / denominator
if (not isNaN solution1) or (not isNaN solution2)
solution = if not isNaN solution1 then solution1 else solution2
[littleY, bigY] = if py1 < py2 then [py1, py2] else [py2, py1]
if littleY <= solution and bigY >= solution
return true
else
return false
false
intersectsRectangle: (rectangle) ->
rectangle.intersectsEllipse @
intersectsEllipse: (ellipse) ->
@rectangle().intersectsEllipse @ # TODO: actually implement ellipse-ellipse intersection
#return true if @containsPoint ellipse.getPos()
intersectsShape: (shape) ->
if shape.isEllipse then @intersectsEllipse shape else @intersectsRectangle shape
toString: ->
return "{x: #{@x.toFixed(0)}, y: #{@y.toFixed(0)}, w: #{@width.toFixed(0)}, h: #{@height.toFixed(0)}, rot: #{@rotation.toFixed(3)}}"
serialize: ->
{CN: @constructor.className, x: @x, y: @y, w: @width, h: @height, r: @rotation}
@deserialize: (o, world, classMap) ->
new Ellipse o.x, o.y, o.w, o.h, o.r
serializeForAether: -> @serialize()
@deserializeFromAether: (o) -> @deserialize o
module.exports = Ellipse

View file

@ -0,0 +1,80 @@
class LineSegment
@className: "LineSegment"
constructor: (@a, @b) ->
@slope = (@a.y - @b.y) / (@a.x - @b.x)
@y0 = @a.y - (@slope * @a.x)
@left = if @a.x < @b.x then @a else @b
@right = if @a.x > @b.x then @a else @b
@bottom = if @a.y < @b.y then @a else @b
@top = if @a.y > @b.y then @a else @b
y: (x) ->
(@slope * x) + @y0
x: (y) ->
(y - @y0) / @slope
intersectsLineSegment: (lineSegment) ->
if lineSegment.slope is @slope
if lineSegment.y0 is @y0
if lineSegment.left.x is @left.x or lineSegment.left.x is @right.x or lineSegment.right.x is @right.x or lineSegment.right.x is @left.x
# segments are of the same line with shared start and/or end points
return true
else
[left, right] = if lineSegment.left.x < @left.x then [lineSegment, @] else [@, lineSegment]
if left.right.x > right.left.x
# segments are of the same line and one is contained within the other
return true
else if Math.abs(@slope) isnt Infinity and Math.abs(lineSegment.slope) isnt Infinity
x = (lineSegment.y0 - @y0) / (@slope - lineSegment.slope)
if x >= @left.x and x <= @right.x and x >= lineSegment.left.x and x <= lineSegment.right.x
return true
else if Math.abs(@slope) isnt Infinity or Math.abs(lineSegment.slope) isnt Infinity
[vertical, nonvertical] = if Math.abs(@slope) isnt Infinity then [lineSegment, @] else [@, lineSegment]
x = vertical.a.x
bottom = vertical.bottom.y
top = vertical.top.y
y = nonvertical.y(x)
left = nonvertical.left.x
right = nonvertical.right.x
if y >= bottom and y <= top and x >= left and x <= right
return true
false
pointOnLine: (point, segment=true) ->
if point.y is @y(point.x)
if segment
[littleY, bigY] = if @a.y < @b.y then [@a.y, @b.y] else [@b.y, @a.y]
if littleY <= point.y and bigY >= point.y
return true
else
return true
false
distanceSquaredToPoint: (point) ->
# http://stackoverflow.com/a/1501725/540620
return @a.distanceSquared point if @a.equals @b
res = Math.min point.distanceSquared(@a), point.distanceSquared(@b)
lineMagnitudeSquared = @a.distanceSquared @b
t = ((point.x - @a.x) * (@b.x - @a.x) + (point.y - @a.y) * (@b.y - @a.y)) / lineMagnitudeSquared
return @a.distanceSquared point if t < 0
return @b.distanceSquared point if t > 1
point.distanceSquared x: @a.x + t * (@b.x - @a.x), y: @a.y + t * (@b.y - @a.y)
distanceToPoint: (point) ->
Math.sqrt @distanceSquaredToPoint point
toString: ->
"lineSegment(a=#{@a}, b=#{@b}, slope=#{@slope}, y0=#{@y0}, left=#{@left}, right=#{@right}, bottom=#{@bottom}, top=#{@top})"
serialize: ->
{CN: @constructor.className, a: @a, b: @b}
@deserialize: (o, world, classMap) ->
new LineSegment o.a, o.b
serializeForAether: -> @serialize()
@deserializeFromAether: (o) -> @deserialize o
module.exports = LineSegment

View file

@ -1,14 +1,16 @@
Vector = require './vector' Vector = require './vector'
LineSegment = require './line_segment'
class Rectangle class Rectangle
@className: 'Rectangle' @className: 'Rectangle'
# Class methods for nondestructively operating # Class methods for nondestructively operating - TODO: add rotate
for name in ['add', 'subtract', 'multiply', 'divide'] for name in ['add', 'subtract', 'multiply', 'divide']
do (name) -> do (name) ->
Rectangle[name] = (a, b) -> Rectangle[name] = (a, b) ->
a.copy()[name](b) a.copy()[name](b)
apiProperties: ['x', 'y', 'width', 'height', 'rotation', 'getPos', 'vertices', 'touchesRect', 'touchesPoint', 'distanceToPoint', 'containsPoint', 'copy'] isRectangle: true
apiProperties: ['x', 'y', 'width', 'height', 'rotation', 'getPos', 'vertices', 'touchesRect', 'touchesPoint', 'distanceToPoint', 'distanceSquaredToPoint', 'distanceToRectangle', 'distanceSquaredToRectangle', 'distanceToEllipse', 'distanceSquaredToEllipse', 'distanceToShape', 'distanceSquaredToShape', 'containsPoint', 'copy', 'intersectsLineSegment', 'intersectsEllipse', 'intersectsRectangle', 'intersectsShape']
constructor: (@x=0, @y=0, @width=0, @height=0, @rotation=0) -> constructor: (@x=0, @y=0, @width=0, @height=0, @rotation=0) ->
@ -28,6 +30,14 @@ class Rectangle
new Vector @x + (w2 * cos + h2 * sin), @y + (w2 * sin - h2 * cos) new Vector @x + (w2 * cos + h2 * sin), @y + (w2 * sin - h2 * cos)
] ]
lineSegments: ->
vertices = @vertices()
lineSegment0 = new LineSegment vertices[0], vertices[1]
lineSegment1 = new LineSegment vertices[1], vertices[2]
lineSegment2 = new LineSegment vertices[2], vertices[3]
lineSegment3 = new LineSegment vertices[3], vertices[0]
[lineSegment0, lineSegment1, lineSegment2, lineSegment3]
touchesRect: (other) -> touchesRect: (other) ->
# Whether this rect shares part of any edge with other rect, for non-rotated, non-overlapping rectangles. # Whether this rect shares part of any edge with other rect, for non-rotated, non-overlapping rectangles.
# I think it says kitty-corner rects touch, but I don't think I want that. # I think it says kitty-corner rects touch, but I don't think I want that.
@ -62,25 +72,90 @@ class Rectangle
box box
distanceToPoint: (p) -> distanceToPoint: (p) ->
# Get p in rect's coordinate space, then operate in one quadrant # Get p in rect's coordinate space, then operate in one quadrant.
p = Vector.subtract(p, @getPos()).rotate(-@rotation) p = Vector.subtract(p, @getPos()).rotate(-@rotation)
dx = Math.max(Math.abs(p.x) - @width / 2, 0) dx = Math.max(Math.abs(p.x) - @width / 2, 0)
dy = Math.max(Math.abs(p.y) - @height / 2, 0) dy = Math.max(Math.abs(p.y) - @height / 2, 0)
Math.sqrt dx * dx + dy * dy Math.sqrt dx * dx + dy * dy
distanceSquaredToPoint: (p) -> distanceSquaredToPoint: (p) ->
# Doesn't handle rotation; just supposed to be faster than distanceToPoint # Doesn't handle rotation; just supposed to be faster than distanceToPoint.
p = Vector.subtract(p, @getPos()) p = Vector.subtract(p, @getPos())
dx = Math.max(Math.abs(p.x) - @width / 2, 0) dx = Math.max(Math.abs(p.x) - @width / 2, 0)
dy = Math.max(Math.abs(p.y) - @height / 2, 0) dy = Math.max(Math.abs(p.y) - @height / 2, 0)
dx * dx + dy * dy dx * dx + dy * dy
distanceToRectangle: (other) ->
Math.sqrt @distanceSquaredToRectangle other
distanceSquaredToRectangle: (other) ->
return 0 if @intersectsRectangle other
[firstVertices, secondVertices] = [@vertices(), other.vertices()]
[firstEdges, secondEdges] = [@lineSegments(), other.lineSegments()]
ans = Infinity
for i in [0 ... 4]
for j in [0 ... firstEdges.length]
ans = Math.min ans, firstEdges[j].distanceSquaredToPoint(secondVertices[i])
for j in [0 ... secondEdges.length]
ans = Math.min ans, secondEdges[j].distanceSquaredToPoint(firstVertices[i])
ans
distanceToEllipse: (ellipse) ->
Math.sqrt @distanceSquaredToEllipse ellipse
distanceSquaredToEllipse: (ellipse) ->
@distanceSquaredToRectangle ellipse.rectangle() # TODO: actually implement rectangle-ellipse distance
distanceToShape: (shape) ->
Math.sqrt @distanceSquaredToShape shape
distanceSquaredToShape: (shape) ->
if shape.isEllipse then @distanceSquaredToEllipse shape else @distanceSquaredToRectangle shape
containsPoint: (p, withRotation=true) -> containsPoint: (p, withRotation=true) ->
if withRotation and @rotation if withRotation and @rotation
not @distanceToPoint(p) not @distanceToPoint(p)
else else
@x - @width / 2 < p.x < @x + @width / 2 and @y - @height / 2 < p.y < @y + @height / 2 @x - @width / 2 < p.x < @x + @width / 2 and @y - @height / 2 < p.y < @y + @height / 2
intersectsLineSegment: (p1, p2) ->
[px1, py1, px2, py2] = [p1.x, p1.y, p2.x, p2.y]
m1 = (py1 - py2) / (px1 - px2)
b1 = py1 - (m1 * px1)
vertices = @vertices()
lineSegments = [[vertices[0], vertices[1]], [vertices[1], vertices[2]], [vertices[2], vertices[3]], [vertices[3], vertices[0]]]
for lineSegment in lineSegments
[px1, py1, px2, py2] = [p1.x, p1.y, p2.x, p2.y]
m2 = (py1 - py2) / (px1 - px2)
b2 = py1 - (m * px1)
if m1 isnt m2
m = m1 - m2
b = b2 - b1
x = b / m
[littleX, bigX] = if px1 < px2 then [px1, px2] else [px2, px1]
if x >= littleX and x <= bigX
y = (m1 * x) + b1
[littleY, bigY] = if py1 < py2 then [py1, py2] else [py2, py1]
if littleY <= solution and bigY >= solution
return true
false
intersectsRectangle: (rectangle) ->
return true if @containsPoint rectangle.getPos()
for thisLineSegment in @lineSegments()
for thatLineSegment in rectangle.lineSegments()
if thisLineSegment.intersectsLineSegment(thatLineSegment)
return true
false
intersectsEllipse: (ellipse) ->
return true if @containsPoint ellipse.getPos()
return true for lineSegment in @lineSegments() when ellipse.intersectsLineSegment lineSegment.a, lineSegment.b
false
intersectsShape: (shape) ->
if shape.isEllipse then @intersectsEllipse shape else @intersectsRectangle shape
subtract: (point) -> subtract: (point) ->
@x -= point.x @x -= point.x
@y -= point.y @y -= point.y
@ -102,10 +177,10 @@ class Rectangle
@ @
isEmpty: () -> isEmpty: () ->
@width == 0 and @height == 0 @width is 0 and @height is 0
invalid: () -> invalid: () ->
return (@x == Infinity) || isNaN(@x) || @y == Infinity || isNaN(@y) || @width == Infinity || isNaN(@width) || @height == Infinity || isNaN(@height) || @rotation == Infinity || isNaN(@rotation) return (@x is Infinity) || isNaN(@x) || @y is Infinity || isNaN(@y) || @width is Infinity || isNaN(@width) || @height is Infinity || isNaN(@height) || @rotation is Infinity || isNaN(@rotation)
toString: -> toString: ->
return "{x: #{@x.toFixed(0)}, y: #{@y.toFixed(0)}, w: #{@width.toFixed(0)}, h: #{@height.toFixed(0)}, rot: #{@rotation.toFixed(3)}}" return "{x: #{@x.toFixed(0)}, y: #{@y.toFixed(0)}, w: #{@width.toFixed(0)}, h: #{@height.toFixed(0)}, rot: #{@rotation.toFixed(3)}}"

View file

@ -1,5 +1,7 @@
Vector = require './vector' Vector = require './vector'
Rectangle = require './rectangle' Rectangle = require './rectangle'
Ellipse = require './ellipse'
LineSegment = require './line_segment'
WorldFrame = require './world_frame' WorldFrame = require './world_frame'
Thang = require './thang' Thang = require './thang'
ThangState = require './thang_state' ThangState = require './thang_state'
@ -21,7 +23,7 @@ module.exports = class World
apiProperties: ['age', 'dt'] apiProperties: ['age', 'dt']
constructor: (@userCodeMap, classMap) -> constructor: (@userCodeMap, classMap) ->
# classMap is needed for deserializing Worlds, Thangs, and other classes # classMap is needed for deserializing Worlds, Thangs, and other classes
@classMap = classMap ? {Vector: Vector, Rectangle: Rectangle, Thang: Thang} @classMap = classMap ? {Vector: Vector, Rectangle: Rectangle, Thang: Thang, Ellipse: Ellipse, LineSegment: LineSegment}
Thang.resetThangIDs() Thang.resetThangIDs()
@userCodeMap ?= {} @userCodeMap ?= {}

View file

@ -1,5 +1,7 @@
Vector = require './vector' Vector = require './vector'
Rectangle = require './rectangle' Rectangle = require './rectangle'
Ellipse = require './ellipse'
LineSegment = require './line_segment'
Grid = require './Grid' Grid = require './Grid'
module.exports.typedArraySupport = typedArraySupport = Float32Array? # Not in IE until IE 10; we'll fall back to normal arrays module.exports.typedArraySupport = typedArraySupport = Float32Array? # Not in IE until IE 10; we'll fall back to normal arrays
@ -36,7 +38,7 @@ module.exports.clone = clone = (obj, skipThangs=false) ->
flags += 'y' if obj.sticky? flags += 'y' if obj.sticky?
return new RegExp(obj.source, flags) return new RegExp(obj.source, flags)
if (obj instanceof Vector) or (obj instanceof Rectangle) if (obj instanceof Vector) or (obj instanceof Rectangle) or (obj instanceof Ellipse) or (obj instanceof LineSegment)
return obj.copy() return obj.copy()
if skipThangs and obj.isThang if skipThangs and obj.isThang

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi
# error_saving: "Error Saving" # error_saving: "Error Saving"
# saved: "Changes Saved" # saved: "Changes Saved"
# password_mismatch: "Password does not match." # password_mismatch: "Password does not match."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "български език", englishDescri
# error_saving: "Error Saving" # error_saving: "Error Saving"
# saved: "Changes Saved" # saved: "Changes Saved"
# password_mismatch: "Password does not match." # password_mismatch: "Password does not match."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "Català", englishDescription: "Catalan", tr
# error_saving: "Error Saving" # error_saving: "Error Saving"
# saved: "Changes Saved" # saved: "Changes Saved"
# password_mismatch: "Password does not match." # password_mismatch: "Password does not match."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
error_saving: "Chyba při ukládání" error_saving: "Chyba při ukládání"
saved: "Změny uloženy" saved: "Změny uloženy"
password_mismatch: "Hesla nesouhlasí." password_mismatch: "Hesla nesouhlasí."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
error_saving: "Fejl under Gemning" error_saving: "Fejl under Gemning"
saved: "Ændringer Gemt" saved: "Ændringer Gemt"
password_mismatch: "Password matcher ikke." password_mismatch: "Password matcher ikke."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "Deutsch (Österreich)", englishDescription:
# error_saving: "Error Saving" # error_saving: "Error Saving"
# saved: "Changes Saved" # saved: "Changes Saved"
# password_mismatch: "Password does not match." # password_mismatch: "Password does not match."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "Deutsch (Schweiz)", englishDescription: "Ge
# error_saving: "Error Saving" # error_saving: "Error Saving"
# saved: "Changes Saved" # saved: "Changes Saved"
# password_mismatch: "Password does not match." # password_mismatch: "Password does not match."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
error_saving: "Fehler beim Speichern" error_saving: "Fehler beim Speichern"
saved: "Änderungen gespeichert" saved: "Änderungen gespeichert"
password_mismatch: "Passwörter stimmen nicht überein." password_mismatch: "Passwörter stimmen nicht überein."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
job_profile: "Jobprofil" job_profile: "Jobprofil"
job_profile_approved: "Dein Jobprofil wurde von CodeCombat freigegeben. Arbeitgeber können dieses solange einsehen, bis du es als inaktiv markiert oder wenn innerhalb von vier Wochen keine Änderung daran vorgenommen wurde." job_profile_approved: "Dein Jobprofil wurde von CodeCombat freigegeben. Arbeitgeber können dieses solange einsehen, bis du es als inaktiv markiert oder wenn innerhalb von vier Wochen keine Änderung daran vorgenommen wurde."
job_profile_explanation: "Hi! Fülle dies aus und wir melden uns bei dir bezüglich des Auffindens eines Jobs als Programmierer" job_profile_explanation: "Hi! Fülle dies aus und wir melden uns bei dir bezüglich des Auffindens eines Jobs als Programmierer"

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
error_saving: "Fehler beim Speichern" error_saving: "Fehler beim Speichern"
saved: "Änderungen gespeichert" saved: "Änderungen gespeichert"
password_mismatch: "Passwörter stimmen nicht überein." password_mismatch: "Passwörter stimmen nicht überein."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
job_profile: "Jobprofil" job_profile: "Jobprofil"
job_profile_approved: "Dein Jobprofil wurde von CodeCombat freigegeben. Arbeitgeber können dieses solange einsehen, bis du es als inaktiv markiert oder wenn innerhalb von vier Wochen keine Änderung daran vorgenommen wurde." job_profile_approved: "Dein Jobprofil wurde von CodeCombat freigegeben. Arbeitgeber können dieses solange einsehen, bis du es als inaktiv markiert oder wenn innerhalb von vier Wochen keine Änderung daran vorgenommen wurde."
job_profile_explanation: "Hi! Fülle dies aus und wir melden uns bei dir bezüglich des Auffindens eines Jobs als Programmierer" job_profile_explanation: "Hi! Fülle dies aus und wir melden uns bei dir bezüglich des Auffindens eines Jobs als Programmierer"

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
error_saving: "Σφάλμα αποθήκευσης" error_saving: "Σφάλμα αποθήκευσης"
saved: "Οι αλλαγές αποθηκεύτηκαν" saved: "Οι αλλαγές αποθηκεύτηκαν"
password_mismatch: "Οι κωδικοί δεν ταιριάζουν" password_mismatch: "Οι κωδικοί δεν ταιριάζουν"
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English
# error_saving: "Error Saving" # error_saving: "Error Saving"
# saved: "Changes Saved" # saved: "Changes Saved"
# password_mismatch: "Password does not match." # password_mismatch: "Password does not match."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English
# error_saving: "Error Saving" # error_saving: "Error Saving"
# saved: "Changes Saved" # saved: "Changes Saved"
# password_mismatch: "Password does not match." # password_mismatch: "Password does not match."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English
# error_saving: "Error Saving" # error_saving: "Error Saving"
# saved: "Changes Saved" # saved: "Changes Saved"
# password_mismatch: "Password does not match." # password_mismatch: "Password does not match."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@
error_saving: "Error Saving" error_saving: "Error Saving"
saved: "Changes Saved" saved: "Changes Saved"
password_mismatch: "Password does not match." password_mismatch: "Password does not match."
password_repeat: "Please repeat your massword." password_repeat: "Please repeat your password."
job_profile: "Job Profile" job_profile: "Job Profile"
job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip
error_saving: "Error al Guardar" error_saving: "Error al Guardar"
saved: "Cambios Guardados" saved: "Cambios Guardados"
password_mismatch: "La contraseña no coincide." password_mismatch: "La contraseña no coincide."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
job_profile: "Perfil de Trabajo" job_profile: "Perfil de Trabajo"
job_profile_approved: "Tu perfil de trabajo ha sido aprobado por CodeCombat. Los empleadores podrán verlo hasta que lo marques como inactivo o permanezca sin cambios por cuatro semanas." job_profile_approved: "Tu perfil de trabajo ha sido aprobado por CodeCombat. Los empleadores podrán verlo hasta que lo marques como inactivo o permanezca sin cambios por cuatro semanas."
job_profile_explanation: "¡Hola! Llena esto, y te contactaremos acerca de encontrar un trabajo como desarrollador de software." job_profile_explanation: "¡Hola! Llena esto, y te contactaremos acerca de encontrar un trabajo como desarrollador de software."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
error_saving: "Error al guardar" error_saving: "Error al guardar"
saved: "Cambios guardados" saved: "Cambios guardados"
password_mismatch: "La contraseña no coincide" password_mismatch: "La contraseña no coincide"
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
job_profile: "Perfil de trabajo" job_profile: "Perfil de trabajo"
job_profile_approved: "Tu perfil de trabajo ha sido aprobado por CodeCombat. Los empleadores podrán verlo hasta que lo marques como inactivo o no haya sido cambiado durante cuatro semanas." job_profile_approved: "Tu perfil de trabajo ha sido aprobado por CodeCombat. Los empleadores podrán verlo hasta que lo marques como inactivo o no haya sido cambiado durante cuatro semanas."
job_profile_explanation: "¡Hola! Rellena esto y estaremos en contacto para hablar sobre encontrarte un trabajo como desarrollador de software." job_profile_explanation: "¡Hola! Rellena esto y estaremos en contacto para hablar sobre encontrarte un trabajo como desarrollador de software."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
error_saving: "Error al guardar" error_saving: "Error al guardar"
saved: "Cambios guardados" saved: "Cambios guardados"
password_mismatch: "La contraseña no coincide" password_mismatch: "La contraseña no coincide"
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
# error_saving: "Error Saving" # error_saving: "Error Saving"
# saved: "Changes Saved" # saved: "Changes Saved"
# password_mismatch: "Password does not match." # password_mismatch: "Password does not match."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "suomi", englishDescription: "Finnish", tran
# error_saving: "Error Saving" # error_saving: "Error Saving"
# saved: "Changes Saved" # saved: "Changes Saved"
# password_mismatch: "Password does not match." # password_mismatch: "Password does not match."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
error_saving: "Problème d'enregistrement" error_saving: "Problème d'enregistrement"
saved: "Changements sauvegardés" saved: "Changements sauvegardés"
password_mismatch: "Le mot de passe ne correspond pas." password_mismatch: "Le mot de passe ne correspond pas."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
job_profile: "Profil d'emploi" job_profile: "Profil d'emploi"
job_profile_approved: "Votre profil d'emploi a été approuvé par CodeCombat. Les employeurs seront en mesure de voir votre profil jusqu'à ce que vous le marquez inactif ou qu'il n'a pas été changé pendant quatre semaines." job_profile_approved: "Votre profil d'emploi a été approuvé par CodeCombat. Les employeurs seront en mesure de voir votre profil jusqu'à ce que vous le marquez inactif ou qu'il n'a pas été changé pendant quatre semaines."
job_profile_explanation: "Salut! Remplissez-le et nous prendrons contact pour vous trouver un emploi de développeur de logiciels." job_profile_explanation: "Salut! Remplissez-le et nous prendrons contact pour vous trouver un emploi de développeur de logiciels."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "עברית", englishDescription: "Hebrew",
error_saving: "בעיה בשמירה" error_saving: "בעיה בשמירה"
saved: "השינויים נשמרו" saved: "השינויים נשמרו"
password_mismatch: "סיסמאות לא זהות" password_mismatch: "סיסמאות לא זהות"
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "मानक हिन्दी", englishDe
# error_saving: "Error Saving" # error_saving: "Error Saving"
# saved: "Changes Saved" # saved: "Changes Saved"
# password_mismatch: "Password does not match." # password_mismatch: "Password does not match."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "magyar", englishDescription: "Hungarian", t
error_saving: "Hiba a mentés során" error_saving: "Hiba a mentés során"
saved: "Változtatások elmentve" saved: "Változtatások elmentve"
password_mismatch: "A jelszavak nem egyeznek." password_mismatch: "A jelszavak nem egyeznek."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
job_profile: "Munkaköri leírás" job_profile: "Munkaköri leírás"
job_profile_approved: "Munkaköri leírásodat a Codecombat jóváhagyta. Munkaadók mindaddig láthatják, amíg meg nem jelölöd inaktívként, vagy négy hétig, ha addig nem kerül megváltoztatásra." job_profile_approved: "Munkaköri leírásodat a Codecombat jóváhagyta. Munkaadók mindaddig láthatják, amíg meg nem jelölöd inaktívként, vagy négy hétig, ha addig nem kerül megváltoztatásra."
job_profile_explanation: "Szió! Töltsd ki ezt és majd kapcsolatba lépünk veled és keresünk neked egy szoftware fejlesztői állást." job_profile_explanation: "Szió! Töltsd ki ezt és majd kapcsolatba lépünk veled és keresünk neked egy szoftware fejlesztői állást."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "Bahasa Indonesia", englishDescription: "Ind
# error_saving: "Error Saving" # error_saving: "Error Saving"
# saved: "Changes Saved" # saved: "Changes Saved"
# password_mismatch: "Password does not match." # password_mismatch: "Password does not match."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "Italiano", englishDescription: "Italian", t
error_saving: "Errore durante il salvataggio" error_saving: "Errore durante il salvataggio"
saved: "Modifiche salvate" saved: "Modifiche salvate"
password_mismatch: "La password non corrisponde." password_mismatch: "La password non corrisponde."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "日本語", englishDescription: "Japanese",
error_saving: "セーブ中にエラーが発生しました" error_saving: "セーブ中にエラーが発生しました"
saved: "変更しました" saved: "変更しました"
password_mismatch: "パスワードが違います" password_mismatch: "パスワードが違います"
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
job_profile: "求職情報" job_profile: "求職情報"
job_profile_approved: "CodeCombatは、あなたの求職情報を承りました。無効にする、もしくは4週間の間変更をしなければ雇用者はあなたの求職情報を見ることができなくなります。" job_profile_approved: "CodeCombatは、あなたの求職情報を承りました。無効にする、もしくは4週間の間変更をしなければ雇用者はあなたの求職情報を見ることができなくなります。"
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t
error_saving: "오류 저장" error_saving: "오류 저장"
saved: "변경사항 저장 완료" saved: "변경사항 저장 완료"
password_mismatch: "비밀번호가 일치하지 않습니다." password_mismatch: "비밀번호가 일치하지 않습니다."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith
# error_saving: "Error Saving" # error_saving: "Error Saving"
# saved: "Changes Saved" # saved: "Changes Saved"
# password_mismatch: "Password does not match." # password_mismatch: "Password does not match."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "Bahasa Melayu", englishDescription: "Bahasa
error_saving: "Masalah menyimpan" error_saving: "Masalah menyimpan"
saved: "Pengubahsuian disimpan" saved: "Pengubahsuian disimpan"
password_mismatch: "Kata-laluan tidak sama." password_mismatch: "Kata-laluan tidak sama."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "Norsk Bokmål", englishDescription: "Norweg
error_saving: "Lagring Feilet" error_saving: "Lagring Feilet"
saved: "Endringer Lagret" saved: "Endringer Lagret"
password_mismatch: "Passordene er ikke like." password_mismatch: "Passordene er ikke like."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "Nederlands (België)", englishDescription:
error_saving: "Fout Tijdens Het Opslaan" error_saving: "Fout Tijdens Het Opslaan"
saved: "Aanpassingen Opgeslagen" saved: "Aanpassingen Opgeslagen"
password_mismatch: "Het wachtwoord komt niet overeen." password_mismatch: "Het wachtwoord komt niet overeen."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
job_profile: "Job Profiel" job_profile: "Job Profiel"
job_profile_approved: "Jouw job profiel werd goedgekeurd door CodeCombat. Werkgevers zullen het kunnen bekijken totdat je het inactief zet of als er geen verandering in komt voor vier weken." job_profile_approved: "Jouw job profiel werd goedgekeurd door CodeCombat. Werkgevers zullen het kunnen bekijken totdat je het inactief zet of als er geen verandering in komt voor vier weken."
job_profile_explanation: "Hey! Vul dit in en we zullen je contacteren om je een job als softwareontwikkelaar te helpen vinden." job_profile_explanation: "Hey! Vul dit in en we zullen je contacteren om je een job als softwareontwikkelaar te helpen vinden."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription
error_saving: "Fout Tijdens Het Opslaan" error_saving: "Fout Tijdens Het Opslaan"
saved: "Aanpassingen Opgeslagen" saved: "Aanpassingen Opgeslagen"
password_mismatch: "Het wachtwoord komt niet overeen." password_mismatch: "Het wachtwoord komt niet overeen."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
job_profile: "Job Profiel" job_profile: "Job Profiel"
job_profile_approved: "Jouw job profiel werd goedgekeurd door CodeCombat. Werkgevers zullen het kunnen bekijken totdat je het inactief zet of als er geen verandering in komt voor vier weken." job_profile_approved: "Jouw job profiel werd goedgekeurd door CodeCombat. Werkgevers zullen het kunnen bekijken totdat je het inactief zet of als er geen verandering in komt voor vier weken."
job_profile_explanation: "Hey! Vul dit in en we zullen je contacteren om je een job als softwareontwikkelaar te helpen vinden." job_profile_explanation: "Hey! Vul dit in en we zullen je contacteren om je een job als softwareontwikkelaar te helpen vinden."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "Nederlands", englishDescription: "Dutch", t
error_saving: "Fout Tijdens Het Opslaan" error_saving: "Fout Tijdens Het Opslaan"
saved: "Aanpassingen Opgeslagen" saved: "Aanpassingen Opgeslagen"
password_mismatch: "Het wachtwoord komt niet overeen." password_mismatch: "Het wachtwoord komt niet overeen."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
job_profile: "Job Profiel" job_profile: "Job Profiel"
job_profile_approved: "Jouw job profiel werd goedgekeurd door CodeCombat. Werkgevers zullen het kunnen bekijken totdat je het inactief zet of als er geen verandering in komt voor vier weken." job_profile_approved: "Jouw job profiel werd goedgekeurd door CodeCombat. Werkgevers zullen het kunnen bekijken totdat je het inactief zet of als er geen verandering in komt voor vier weken."
job_profile_explanation: "Hey! Vul dit in en we zullen je contacteren om je een job als softwareontwikkelaar te helpen vinden." job_profile_explanation: "Hey! Vul dit in en we zullen je contacteren om je een job als softwareontwikkelaar te helpen vinden."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "Norwegian Nynorsk", englishDescription: "No
# error_saving: "Error Saving" # error_saving: "Error Saving"
# saved: "Changes Saved" # saved: "Changes Saved"
# password_mismatch: "Password does not match." # password_mismatch: "Password does not match."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "Norsk", englishDescription: "Norwegian", tr
error_saving: "Lagring Feilet" error_saving: "Lagring Feilet"
saved: "Endringer Lagret" saved: "Endringer Lagret"
password_mismatch: "Passordene er ikke like." password_mismatch: "Passordene er ikke like."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "język polski", englishDescription: "Polish
error_saving: "Błąd zapisywania" error_saving: "Błąd zapisywania"
saved: "Zmiany zapisane" saved: "Zmiany zapisane"
password_mismatch: "Hasła róznią się od siebie" password_mismatch: "Hasła róznią się od siebie"
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "português do Brasil", englishDescription:
error_saving: "Erro no salvamento" error_saving: "Erro no salvamento"
saved: "Alterações Salvas" saved: "Alterações Salvas"
password_mismatch: "As senhas não estão iguais" password_mismatch: "As senhas não estão iguais"
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
job_profile: "Perfil de trabalho" job_profile: "Perfil de trabalho"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
error_saving: "Erro ao Guardar" error_saving: "Erro ao Guardar"
saved: "Alterações Guardadas" saved: "Alterações Guardadas"
password_mismatch: "As palavras-passe não coincidem." password_mismatch: "As palavras-passe não coincidem."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
job_profile: "Perfil de Emprego" job_profile: "Perfil de Emprego"
job_profile_approved: "O seu perfil de emprego foi aprovado pelo CodeCombat. Os empregadores poderão vê-lo até que o defina como inativo ou não o tenha alterado à 4 semanas." job_profile_approved: "O seu perfil de emprego foi aprovado pelo CodeCombat. Os empregadores poderão vê-lo até que o defina como inativo ou não o tenha alterado à 4 semanas."
job_profile_explanation: "Olá! Preencha isto e entraremos em contacto consigo sobre encontrar um emprego de desenvolvedor de software para si." job_profile_explanation: "Olá! Preencha isto e entraremos em contacto consigo sobre encontrar um emprego de desenvolvedor de software para si."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "português", englishDescription: "Portugues
error_saving: "Erro no salvamento" error_saving: "Erro no salvamento"
saved: "Alterações Salvas" saved: "Alterações Salvas"
password_mismatch: "As senhas não estão iguais" password_mismatch: "As senhas não estão iguais"
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "limba română", englishDescription: "Roman
error_saving: "Salvare erori" error_saving: "Salvare erori"
saved: "Modificări salvate" saved: "Modificări salvate"
password_mismatch: "Parola nu se potrivește." password_mismatch: "Parola nu se potrivește."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
error_saving: "Ошибка сохранения" error_saving: "Ошибка сохранения"
saved: "Изменения сохранены" saved: "Изменения сохранены"
password_mismatch: "Пароли не совпадают." password_mismatch: "Пароли не совпадают."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
job_profile: "Профиль соискателя" job_profile: "Профиль соискателя"
job_profile_approved: "Ваш профиль соискателя был одобрен CodeCombat. Работодатели смогут видеть его, пока вы не отметите его неактивным или он не будет изменен в течение четырёх недель." job_profile_approved: "Ваш профиль соискателя был одобрен CodeCombat. Работодатели смогут видеть его, пока вы не отметите его неактивным или он не будет изменен в течение четырёх недель."
job_profile_explanation: "Привет! Заполните это, и мы свяжемся с вами при нахождении работы разработчика программного обеспечения для вас." job_profile_explanation: "Привет! Заполните это, и мы свяжемся с вами при нахождении работы разработчика программного обеспечения для вас."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "slovenčina", englishDescription: "Slovak",
error_saving: "Chyba pri ukladaní" error_saving: "Chyba pri ukladaní"
saved: "Zmeny uložené" saved: "Zmeny uložené"
password_mismatch: "Heslá nesedia." password_mismatch: "Heslá nesedia."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "slovenščina", englishDescription: "Sloven
# error_saving: "Error Saving" # error_saving: "Error Saving"
# saved: "Changes Saved" # saved: "Changes Saved"
# password_mismatch: "Password does not match." # password_mismatch: "Password does not match."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian
error_saving: "Чување грешке..." error_saving: "Чување грешке..."
saved: "Измене су сачуване" saved: "Измене су сачуване"
password_mismatch: "Шифре се не слажу." password_mismatch: "Шифре се не слажу."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "Svenska", englishDescription: "Swedish", tr
error_saving: "Ett fel uppstod när ändringarna skulle sparas" error_saving: "Ett fel uppstod när ändringarna skulle sparas"
saved: "Ändringar sparade" saved: "Ändringar sparade"
password_mismatch: "De angivna lösenorden stämmer inte överens." password_mismatch: "De angivna lösenorden stämmer inte överens."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "ไทย", englishDescription: "Thai", tra
error_saving: "บันทึกผิดพลาด" error_saving: "บันทึกผิดพลาด"
saved: "เปลี่ยนรหัสผ่าน" saved: "เปลี่ยนรหัสผ่าน"
password_mismatch: "รหัสผ่านไม่ถูกต้อง" password_mismatch: "รหัสผ่านไม่ถูกต้อง"
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t
error_saving: "Kayıt Esnasında Hata" error_saving: "Kayıt Esnasında Hata"
saved: "Değişiklikler Kaydedildi" saved: "Değişiklikler Kaydedildi"
password_mismatch: "Şifreler Uyuşmuyor" password_mismatch: "Şifreler Uyuşmuyor"
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "українська мова", englishDesc
error_saving: "Помилка при збереженні" error_saving: "Помилка при збереженні"
saved: "Зміни збережено" saved: "Зміни збережено"
password_mismatch: "Паролі не збігаються." password_mismatch: "Паролі не збігаються."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
job_profile: "Профіль роботи" job_profile: "Профіль роботи"
job_profile_approved: "Ваш робочий пофіль буде затверджений CodeCombat. Роботодавці зможуть бачити його якщо він буде відмічений як активний, або він не зазнає змін протягом 4 тижнів." job_profile_approved: "Ваш робочий пофіль буде затверджений CodeCombat. Роботодавці зможуть бачити його якщо він буде відмічений як активний, або він не зазнає змін протягом 4 тижнів."
job_profile_explanation: "Привіт! Заповніть це і ми з Вами зв‘яжемось знайшовши для Вас роботу розробника ПЗ." job_profile_explanation: "Привіт! Заповніть це і ми з Вами зв‘яжемось знайшовши для Вас роботу розробника ПЗ."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "اُردُو", englishDescription: "Urdu",
# error_saving: "Error Saving" # error_saving: "Error Saving"
# saved: "Changes Saved" # saved: "Changes Saved"
# password_mismatch: "Password does not match." # password_mismatch: "Password does not match."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn
error_saving: "Lỗi lưu" error_saving: "Lỗi lưu"
saved: "Thay đổi được lưu" saved: "Thay đổi được lưu"
password_mismatch: "Mật khẩu không khớp." password_mismatch: "Mật khẩu không khớp."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
error_saving: "保存时出错" error_saving: "保存时出错"
saved: "更改已保存" saved: "更改已保存"
password_mismatch: "密码不匹配。" password_mismatch: "密码不匹配。"
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
job_profile: "工作经历" job_profile: "工作经历"
job_profile_approved: "你填写的工作经历将由CodeCombat认证. 雇主将看到这些信息,除非你将它设置为不启用状态或者连续四周没有更新." job_profile_approved: "你填写的工作经历将由CodeCombat认证. 雇主将看到这些信息,除非你将它设置为不启用状态或者连续四周没有更新."
job_profile_explanation: "你好! 填写这些信息, 我们将使用它帮你寻找一份软件开发的工作." job_profile_explanation: "你好! 填写这些信息, 我们将使用它帮你寻找一份软件开发的工作."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "繁体中文", englishDescription: "Chinese
error_saving: "保存時發生錯誤" error_saving: "保存時發生錯誤"
saved: "修改已儲存" saved: "修改已儲存"
password_mismatch: "密碼不正確。" password_mismatch: "密碼不正確。"
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "吴语", englishDescription: "Wuu (Simplifi
# error_saving: "Error Saving" # error_saving: "Error Saving"
# saved: "Changes Saved" # saved: "Changes Saved"
# password_mismatch: "Password does not match." # password_mismatch: "Password does not match."
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "吳語", englishDescription: "Wuu (Traditio
error_saving: "保存時出錯" error_saving: "保存時出錯"
saved: "保存起來哉" saved: "保存起來哉"
password_mismatch: "密碼弗合。" password_mismatch: "密碼弗合。"
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
job_profile: "工作經歷" job_profile: "工作經歷"
job_profile_approved: "爾填個工作經歷會讓CodeCombat來確認. 僱主會望着箇許訊息,除非爾畀渠調成望弗着狀態要勿粘牢四個星期朆改動。" job_profile_approved: "爾填個工作經歷會讓CodeCombat來確認. 僱主會望着箇許訊息,除非爾畀渠調成望弗着狀態要勿粘牢四個星期朆改動。"
job_profile_explanation: "爾好!填箇許訊息,我裏會用渠幫爾尋一份軟件開發個工作。" job_profile_explanation: "爾好!填箇許訊息,我裏會用渠幫爾尋一份軟件開發個工作。"

View file

@ -186,7 +186,7 @@ module.exports = nativeDescription: "中文", englishDescription: "Chinese", tra
error_saving: "保存失败" error_saving: "保存失败"
saved: "已保存" saved: "已保存"
password_mismatch: "密码不对应" password_mismatch: "密码不对应"
# password_repeat: "Please repeat your massword." # password_repeat: "Please repeat your password."
# job_profile: "Job Profile" # job_profile: "Job Profile"
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks." # job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job." # job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."

View file

@ -1,5 +1,7 @@
#test-view #test-view
background-color: #eee
margin: 0 20px margin: 0 20px
padding: 0
h2 h2
background: #add8e6 background: #add8e6

View file

@ -20,3 +20,5 @@ ol.breadcrumb
span.spl= child.name span.spl= child.name
if child.type == 'folder' if child.type == 'folder'
strong (#{child.size}) strong (#{child.size})
.clearfix

View file

@ -6,6 +6,8 @@ serializedClasses =
Thang: require 'lib/world/thang' Thang: require 'lib/world/thang'
Vector: require 'lib/world/vector' Vector: require 'lib/world/vector'
Rectangle: require 'lib/world/rectangle' Rectangle: require 'lib/world/rectangle'
Ellipse: require 'lib/world/ellipse'
LineSegment: require 'lib/world/line_segment'
module.exports = class DebugView extends View module.exports = class DebugView extends View
className: 'spell-debug-view' className: 'spell-debug-view'

View file

@ -14,7 +14,7 @@ describe 'Camera (Surface point of view)', ->
sup = cam.worldToSurface wop sup = cam.worldToSurface wop
expect(sup.x).toBeCloseTo wop.x * Camera.PPM expect(sup.x).toBeCloseTo wop.x * Camera.PPM
expect(sup.y).toBeCloseTo cam.surfaceHeight - (wop.y + wop.z * cam.z2y) * cam.y2x * Camera.PPM expect(sup.y).toBeCloseTo -(wop.y + wop.z * cam.z2y) * cam.y2x * Camera.PPM
cap = cam.worldToCanvas wop cap = cam.worldToCanvas wop
expect(cap.x).toBeCloseTo (sup.x - cam.surfaceViewport.x) * cam.zoom expect(cap.x).toBeCloseTo (sup.x - cam.surfaceViewport.x) * cam.zoom
@ -83,47 +83,48 @@ describe 'Camera (Surface point of view)', ->
testAngles = [0, Math.PI / 4, null, Math.PI / 2] testAngles = [0, Math.PI / 4, null, Math.PI / 2]
testFOVs = [Math.PI / 6, Math.PI / 3, Math.PI / 2, Math.PI] testFOVs = [Math.PI / 6, Math.PI / 3, Math.PI / 2, Math.PI]
xit 'handles lots of different cases correctly', -> it 'handles lots of different cases correctly', ->
for wop in testWops for wop in testWops
for size in testCanvasSizes for size in testCanvasSizes
for zoom in testZooms for zoom in testZooms
for target in testZoomTargets for target in testZoomTargets
for angle in testAngles for angle in testAngles
for fov in testFOVs for fov in testFOVs
cam = new Camera size.width, size.height, size.width * Camera.MPP, size.height * Camera.MPP, testLayer, zoom, null, angle, fov cam = new Camera {attr: (attr) -> if 'attr' is 'width' then size.width else size.height}, angle, fov
checkCameraPos cam, wop checkCameraPos cam, wop
cam.zoomTo target, zoom, 0 cam.zoomTo target, zoom, 0
checkConversionsFromWorldPos wop, cam checkConversionsFromWorldPos wop, cam
checkCameraPos cam, wop checkCameraPos cam, wop
it 'works at 90 degrees', -> it 'works at 90 degrees', ->
cam = new Camera {attr: (x) -> 100}, 100 * Camera.MPP, 100 * Camera.MPP cam = new Camera {attr: (attr) -> 100}, Math.PI / 2
expect(cam.x2y).toBeCloseTo 1 expect(cam.x2y).toBeCloseTo 1
expect(cam.x2z).toBeGreaterThan 9001 expect(cam.x2z).toBeGreaterThan 9001
expect(cam.z2y).toBeCloseTo 0 expect(cam.z2y).toBeCloseTo 0
it 'works at 0 degrees', -> it 'works at 0 degrees', ->
cam = new Camera {attr: (x) -> 100}, 100 * Camera.MPP, 100 * Camera.MPP cam = new Camera {attr: (attr) -> 100}, 0
expect(cam.x2z).toBeGreaterThan 9001 expect(cam.x2y).toBeGreaterThan 9001
expect(cam.x2y).toBeCloseTo 1 expect(cam.x2z).toBeCloseTo 1
expect(cam.z2y).toBeCloseTo 0 expect(cam.z2y).toBeGreaterThan 9001
it 'works at 45 degrees', -> it 'works at 45 degrees', ->
cam = new Camera {attr: (x) -> 100}, 100 * Camera.MPP, 100 * Camera.MPP cam = new Camera {attr: (attr) -> 100}, Math.PI / 4
expect(cam.x2y).toBeCloseTo 1 expect(cam.x2y).toBeCloseTo Math.sqrt(2)
expect(cam.x2z).toBeGreaterThan 9001 expect(cam.x2z).toBeCloseTo Math.sqrt(2)
expect(cam.z2y).toBeCloseTo 0 expect(cam.z2y).toBeCloseTo 1
xit 'works at default angle of asin(0.75) ~= 48.9 degrees', -> it 'works at default angle of asin(0.75) ~= 48.9 degrees', ->
cam = new Camera {attr: (x) -> 100}, 100 * Camera.MPP, 100 * Camera.MPP cam = new Camera {attr: (attr) -> 100}, null
angle = 1 / Math.cos angle angle = Math.asin(3 / 4)
expect(cam.angle).toBeCloseTo angle expect(cam.angle).toBeCloseTo angle
expect(cam.x2y).toBeCloseTo 1 expect(cam.x2y).toBeCloseTo 4 / 3
expect(cam.x2z).toBeGreaterThan 9001 expect(cam.x2z).toBeCloseTo 1 / Math.cos angle
expect(cam.z2y).toBeCloseTo 0 expect(cam.z2y).toBeCloseTo (4 / 3) * Math.cos angle
xit 'works at 2x zoom, 90 degrees', -> xit 'works at 2x zoom, 90 degrees', ->
cam = new Camera {attr: (x) -> 100}, 100 * Camera.MPP, 100 * Camera.MPP cam = new Camera {attr: (attr) -> 100}, Math.PI / 2
cam.zoomTo null, 2, 0
checkCameraPos cam checkCameraPos cam
wop = x: 5, y: 2.5, z: 7 wop = x: 5, y: 2.5, z: 7
cap = cam.worldToCanvas wop cap = cam.worldToCanvas wop
@ -143,7 +144,8 @@ describe 'Camera (Surface point of view)', ->
expectPositionsEqual cap, {x: 0, y: 50} expectPositionsEqual cap, {x: 0, y: 50}
xit 'works at 2x zoom, 30 degrees', -> xit 'works at 2x zoom, 30 degrees', ->
cam = new Camera {attr: (x) -> 100}, 100 * Camera.MPP, 2 * 100 * Camera.MPP cam = new Camera {attr: (attr) -> 100}, Math.PI / 6
cam.zoomTo null, 2, 0
expect(cam.x2y).toBeCloseTo 1 expect(cam.x2y).toBeCloseTo 1
expect(cam.x2z).toBeGreaterThan 9001 expect(cam.x2z).toBeGreaterThan 9001
checkCameraPos cam checkCameraPos cam
@ -164,15 +166,18 @@ describe 'Camera (Surface point of view)', ->
expectPositionsEqual cap, {x: 50, y: -100} expectPositionsEqual cap, {x: 50, y: -100}
it 'works at 2x zoom, 60 degree hFOV', -> it 'works at 2x zoom, 60 degree hFOV', ->
cam = new Camera {attr: (x) -> 100}, 100 * Camera.MPP, 100 * Camera.MPP cam = new Camera {attr: (attr) -> 100}, null, Math.PI / 3
cam.zoomTo null, 2, 0
checkCameraPos cam checkCameraPos cam
xit 'works at 2x zoom, 60 degree hFOV, 40 degree hFOV', -> it 'works at 2x zoom, 60 degree hFOV, 40 degree vFOV', ->
cam = new Camera {attr: (x) -> x is 'height' ? 63.041494 : 100}, 100 * Camera.MPP, 63.041494 * Camera.MPP cam = new Camera {attr: (attr) -> if attr is 'height' then 63.041494 else 100}, null, Math.PI / 3
cam.zoomTo null, 2, 0
checkCameraPos cam checkCameraPos cam
xit 'works on a surface wider than it is tall, 30 degrees, default viewing upper left corner', -> xit 'works at 2x zoom on a surface wider than it is tall, 30 degrees, default viewing upper left corner', ->
cam = new Camera {attr: (x) -> 100}, 200 * Camera.MPP, 2 * 50 * Camera.MPP cam = new Camera {attr: (attr) -> 100}, Math.PI / 6 # 200 * Camera.MPP, 2 * 50 * Camera.MPP
cam.zoomTo null, 2, 0
checkCameraPos cam checkCameraPos cam
expect(cam.zoom).toBeCloseTo 2 expect(cam.zoom).toBeCloseTo 2
wop = x: 5, y: 4, z: 6 * cam.y2z # like x: 5, y: 10 out of world width: 20, height: 10 wop = x: 5, y: 4, z: 6 * cam.y2z # like x: 5, y: 10 out of world width: 20, height: 10

View file

@ -0,0 +1,99 @@
describe 'Ellipse', ->
Ellipse = require 'lib/world/ellipse'
Rectangle = require 'lib/world/rectangle'
Vector = require 'lib/world/vector'
#it 'contains its own center', ->
# ellipse = new Ellipse 0, 0, 10, 10
# expect(ellipse.containsPoint(new Vector 0, 0)).toBe true
#
#it 'contains a point when rotated', ->
# ellipse = new Ellipse 0, -20, 40, 40, 3 * Math.PI / 4
# p = new Vector 0, 2
# expect(ellipse.containsPoint(p, true)).toBe true
#
#it 'contains more points properly', ->
# # ellipse with y major axis, off-origin center, and 45 degree rotation
# ellipse = new Ellipse 1, 2, 4, 6, Math.PI / 4
# expect(ellipse.contains new Vector(1, 2)).toBe true
# expect(ellipse.contains new Vector(-1, 3)).toBe true
# expect(ellipse.contains new Vector(0, 4)).toBe true
# expect(ellipse.contains new Vector(1, 4)).toBe true
# expect(ellipse.contains new Vector(3, 0)).toBe true
# expect(ellipse.contains new Vector(1, 0)).toBe true
# expect(ellipse.contains new Vector(0, 1)).toBe true
# expect(ellipse.contains new Vector(-1, 2)).toBe true
# expect(ellipse.contains new Vector(2, 2)).toBe true
# expect(ellipse.contains new Vector(0, 0)).toBe false
# expect(ellipse.contains new Vector(0, 5)).toBe false
# expect(ellipse.contains new Vector(3, 4)).toBe false
# expect(ellipse.contains new Vector(4, 0)).toBe false
# expect(ellipse.contains new Vector(2, -1)).toBe false
# expect(ellipse.contains new Vector(0, -3)).toBe false
# expect(ellipse.contains new Vector(-2, -2)).toBe false
# expect(ellipse.contains new Vector(-2, 0)).toBe false
# expect(ellipse.contains new Vector(-2, 4)).toBe false
#
#it 'correctly calculates distance to a faraway point', ->
# ellipse = new Ellipse 100, 50, 20, 40
# p = new Vector 200, 300
# d = 10 * Math.sqrt(610)
# expect(ellipse.distanceToPoint(p)).toBeCloseTo d
# ellipse.rotation = Math.PI / 2
# d = 80 * Math.sqrt(10)
# expect(ellipse.distanceToPoint(p)).toBeCloseTo d
#
#it 'does not modify itself or target Vector when calculating distance', ->
# ellipse = new Ellipse -100, -200, 1, 100
# ellipse2 = ellipse.copy()
# p = new Vector -100.25, -101
# p2 = p.copy()
# ellipse.distanceToPoint(p)
# expect(p.x).toEqual p2.x
# expect(p.y).toEqual p2.y
# expect(ellipse.x).toEqual ellipse2.x
# expect(ellipse.y).toEqual ellipse2.y
# expect(ellipse.width).toEqual ellipse2.width
# expect(ellipse.height).toEqual ellipse2.height
# expect(ellipse.rotation).toEqual ellipse2.rotation
#
#it 'correctly calculates distance to contained point', ->
# ellipse = new Ellipse -100, -200, 1, 100
# ellipse2 = ellipse.copy()
# p = new Vector -100.25, -160
# p2 = p.copy()
# expect(ellipse.distanceToPoint(p)).toBe 0
# ellipse.rotation = 0.00000001 * Math.PI
# expect(ellipse.distanceToPoint(p)).toBe 0
#
#it 'AABB works when not rotated', ->
# ellipse = new Ellipse 10, 20, 30, 40
# rect = new Rectangle 10, 20, 30, 40
# aabb1 = ellipse.axisAlignedBoundingBox()
# aabb2 = ellipse.axisAlignedBoundingBox()
# for prop in ['x', 'y', 'width', 'height']
# expect(aabb1[prop]).toBe aabb2[prop]
#
#it 'AABB works when rotated', ->
# ellipse = new Ellipse 10, 20, 30, 40, Math.PI / 3
# rect = new Rectangle 10, 20, 30, 40, Math.PI / 3
# aabb1 = ellipse.axisAlignedBoundingBox()
# aabb2 = ellipse.axisAlignedBoundingBox()
# for prop in ['x', 'y', 'width', 'height']
# expect(aabb1[prop]).toBe aabb2[prop]
#
#it 'calculates ellipse intersections properly', ->
# # ellipse with y major axis, off-origin center, and 45 degree rotation
# ellipse = new Ellipse 1, 2, 4, 6, Math.PI / 4
# expect(ellipse.intersectsShape new Rectangle(0, 0, 2, 2, 0)).toBe true
# expect(ellipse.intersectsShape new Rectangle(0, -1, 2, 3, 0)).toBe true
# expect(ellipse.intersectsShape new Rectangle(-1, -0.5, 2 * Math.SQRT2, 2 * Math.SQRT2, Math.PI / 4)).toBe true
# expect(ellipse.intersectsShape new Rectangle(-1, -0.5, 2 * Math.SQRT2, 2 * Math.SQRT2, 0)).toBe true
# expect(ellipse.intersectsShape new Rectangle(-1, -1, 2 * Math.SQRT2, 2 * Math.SQRT2, 0)).toBe true
# expect(ellipse.intersectsShape new Rectangle(-1, -1, 2 * Math.SQRT2, 2 * Math.SQRT2, Math.PI / 4)).toBe false
# expect(ellipse.intersectsShape new Rectangle(-2, -2, 2, 2, 0)).toBe false
# expect(ellipse.intersectsShape new Rectangle(-Math.SQRT2 / 2, -Math.SQRT2 / 2, Math.SQRT2, Math.SQRT2, 0)).toBe false
# expect(ellipse.intersectsShape new Rectangle(-Math.SQRT2 / 2, -Math.SQRT2 / 2, Math.SQRT2, Math.SQRT2, Math.PI / 4)).toBe false
# expect(ellipse.intersectsShape new Rectangle(-2, 0, 2, 2, 0)).toBe false
# expect(ellipse.intersectsShape new Rectangle(0, -2, 2, 2, 0)).toBe false
# expect(ellipse.intersectsShape new Rectangle(1, 2, 1, 1, 0)).toBe true

View file

@ -0,0 +1,51 @@
describe 'LineSegment', ->
LineSegment = require 'lib/world/line_segment'
Vector = require 'lib/world/vector'
v00 = new Vector(0, 0)
v11 = new Vector(1, 1)
v22 = new Vector(2, 2)
v34 = new Vector(3, 4)
v04 = new Vector(0, 4)
v30 = new Vector(3, 0)
vneg = new Vector(-1, -1)
it 'intersects itself', ->
lineSegment = new LineSegment v00, v34
expect(lineSegment.intersectsLineSegment lineSegment).toBe true
it 'intersects other segments properly', ->
l1 = new LineSegment v00, v34
l2 = new LineSegment v04, v30
l3 = new LineSegment v00, v11
expect(l1.intersectsLineSegment l2).toBe true
expect(l2.intersectsLineSegment l1).toBe true
expect(l1.intersectsLineSegment l3).toBe true
expect(l3.intersectsLineSegment l1).toBe true
expect(l2.intersectsLineSegment l3).toBe false
expect(l3.intersectsLineSegment l2).toBe false
it 'can tell when a point is on a line or segment', ->
lineSegment = new LineSegment v00, v11
expect(lineSegment.pointOnLine v22, false).toBe true
#expect(lineSegment.pointOnLine v22, true).toBe false
#expect(lineSegment.pointOnLine v00, false).toBe true
#expect(lineSegment.pointOnLine v00, true).toBe true
#expect(lineSegment.pointOnLine v11, true).toBe true
#expect(lineSegment.pointOnLine v11, false).toBe true
#expect(lineSegment.pointOnLine v34, false).toBe false
#expect(lineSegment.pointOnLine v34, true).toBe false
it 'correctly calculates distance to points', ->
lineSegment = new LineSegment v00, v11
expect(lineSegment.distanceToPoint v00).toBe 0
expect(lineSegment.distanceToPoint v11).toBe 0
expect(lineSegment.distanceToPoint v22).toBeCloseTo Math.SQRT2
expect(lineSegment.distanceToPoint v34).toBeCloseTo Math.sqrt(2 * 2 + 3 * 3)
expect(lineSegment.distanceToPoint v04).toBeCloseTo Math.sqrt(1 * 1 + 3 * 3)
expect(lineSegment.distanceToPoint v30).toBeCloseTo Math.sqrt(2 * 2 + 1 * 1)
expect(lineSegment.distanceToPoint vneg).toBeCloseTo Math.SQRT2
nullSegment = new LineSegment v11, v11
expect(lineSegment.distanceToPoint v11).toBe 0
expect(lineSegment.distanceToPoint v22).toBeCloseTo Math.SQRT2

View file

@ -1,6 +1,7 @@
describe 'Rectangle', -> describe 'Rectangle', ->
Rectangle = require 'lib/world/rectangle' Rectangle = require 'lib/world/rectangle'
Vector = require 'lib/world/vector' Vector = require 'lib/world/vector'
Ellipse = require 'lib/world/ellipse'
it 'contains its own center', -> it 'contains its own center', ->
rect = new Rectangle 0, 0, 10, 10 rect = new Rectangle 0, 0, 10, 10
@ -43,6 +44,13 @@ describe 'Rectangle', ->
rect.rotation = 0.00000001 * Math.PI rect.rotation = 0.00000001 * Math.PI
expect(rect.distanceToPoint(p)).toBe 0 expect(rect.distanceToPoint(p)).toBe 0
it 'correctly calculates distance to other rectangles', ->
expect(new Rectangle(0, 0, 4, 4, Math.PI / 4).distanceToRectangle(new Rectangle(4, -4, 2, 2, 0))).toBeCloseTo 2.2426
expect(new Rectangle(0, 0, 3, 3, 0).distanceToRectangle(new Rectangle(0, 0, 2, 2, 0))).toBe 0
expect(new Rectangle(0, 0, 3, 3, 0).distanceToRectangle(new Rectangle(0, 0, 2.5, 2.5, Math.PI / 4))).toBe 0
expect(new Rectangle(0, 0, 4, 4, 0).distanceToRectangle(new Rectangle(4, 2, 2, 2, 0))).toBe 1
expect(new Rectangle(0, 0, 4, 4, 0).distanceToRectangle(new Rectangle(4, 2, 2, 2, Math.PI / 4))).toBeCloseTo 2 - Math.SQRT2
it 'has predictable vertices', -> it 'has predictable vertices', ->
rect = new Rectangle 50, 50, 100, 100 rect = new Rectangle 50, 50, 100, 100
v = rect.vertices() v = rect.vertices()
@ -79,3 +87,22 @@ describe 'Rectangle', ->
aabb = rect.axisAlignedBoundingBox() aabb = rect.axisAlignedBoundingBox()
for prop in ['x', 'y', 'width', 'height'] for prop in ['x', 'y', 'width', 'height']
expect(rect[prop]).toBe aabb[prop] expect(rect[prop]).toBe aabb[prop]
it 'calculates rectangle intersections properly', ->
rect = new Rectangle 1, 1, 2, 2, 0
expect(rect.intersectsShape new Rectangle(3, 1, 2, 2, 0)).toBe true
expect(rect.intersectsShape new Rectangle(3, 3, 2, 2, 0)).toBe true
expect(rect.intersectsShape new Rectangle(1, 1, 2, 2, 0)).toBe true
expect(rect.intersectsShape new Rectangle(1, 1, Math.SQRT1_2, Math.SQRT1_2, Math.PI / 4)).toBe true
expect(rect.intersectsShape new Rectangle(4, 1, 2, 2, 0)).toBe false
expect(rect.intersectsShape new Rectangle(3, 4, 2, 2, 0)).toBe false
expect(rect.intersectsShape new Rectangle(1, 4, 2 * Math.SQRT1_2, 2 * Math.SQRT1_2, Math.PI / 4)).toBe false
expect(rect.intersectsShape new Rectangle(3, 1, 2, 2, Math.PI / 4)).toBe true
expect(rect.intersectsShape new Rectangle(1, 2, 2 * Math.SQRT2, 2 * Math.SQRT2, Math.PI / 4)).toBe true
it 'calculates ellipse intersections properly', ->
rect = new Rectangle 1, 1, 2, 2, 0
expect(rect.intersectsShape new Ellipse(1, 1, Math.SQRT1_2, Math.SQRT1_2, Math.PI / 4)).toBe true
expect(rect.intersectsShape new Ellipse(4, 1, 2, 2, 0)).toBe false
expect(rect.intersectsShape new Ellipse(3, 4, 2, 2, 0)).toBe false
expect(rect.intersectsShape new Ellipse(1, 4, 2 * Math.SQRT1_2, 2 * Math.SQRT1_2, Math.PI / 4)).toBe false

View file

@ -1,5 +1,3 @@
body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
.html-reporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; } .html-reporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
.html-reporter a { text-decoration: none; } .html-reporter a { text-decoration: none; }
.html-reporter a:hover { text-decoration: underline; } .html-reporter a:hover { text-decoration: underline; }