Reworked the camera to move more independently from the player, also adding basic navmesh collision.

# game

This module contains your game logic.  Its methods are called by the "index"
module to update the game state.

    gamepad = require "./input/gamepad.litcoffee"
    keyboard = require "./input/keyboard.litcoffee"

    context = require "./rendering/context.litcoffee"
    cloud = require "./rendering/cloud.litcoffee"
    matrix = require "./matrix.litcoffee"
    plane = require "./plane.litcoffee"
    misc = require "./misc.litcoffee"
    navmesh = require "./navmesh.litcoffee"
    vector = require "./vector.litcoffee"
    pose = require "./pose.litcoffee"
    ik = require "./ik.litcoffee"

    triangle = undefined

    character = testMap = testNavmesh = undefined
    characterData = require "./characters/test/cloud.coffee"

# load
Called before the first "tick"/"draw" to load any resources needed by the game.
Execute the argument when you have finished successfully.

    load = (callback) ->
        keyboard()
        context.load()
        cloud.load characterData, (character_) ->
            character = character_
            cloud.load (require "./tracks/test/geometry.msc"), (testMap_) ->
                testMap = testMap_
                navmesh.load (require "./tracks/test/navmesh.msn"), (testNavmesh_) ->
                    testNavmesh = testNavmesh_
                    triangle = testNavmesh[0]
                    callback()
                    return
                return
            return
        return

# tick
Called at 20Hz to update game state.  Guaranteed to be called once between
"load" and "draw".  May be called more or than once per call to "draw" or not at
all.

    firstTick = true
    firstDraw = true

    entityTransform = []
    entityTransformToDraw = []
    entityTransformPreviousTick = []
    entityTransformPreviousDraw = []
    matrix.identity entityTransform

    playerPoseOld = pose.create characterData
    playerPoseNew = pose.create characterData

    torsoTransform = []
    torsoTransformToDraw = []
    torsoTransformPreviousTick = []
    torsoTransformPreviousDraw = []

    surfaceCorrectedEntityTransform = []
    matrix.identity surfaceCorrectedEntityTransform

    cameraTransform = []
    cameraTransformPreviousDraw = []
    cameraLocation = []
    cameraLocationPreviousDraw = []
    cameraTarget = []
    cameraTargetPreviousDraw = []
    cameraSide = []
    cameraSidePreviousDraw = [0, 0, 1]
    matrix.identity cameraTransform

    torsoAltitude = 0

    velocity = [0, 0, 0]
    xAxis = []
    yAxis = []
    zAxis = []
    torsoXAxis = []
    torsoZAxis = []
    translation = []
    targetForwardVelocity = []
    targetSidewardVelocity = []
    targetVelocity = []
    torsoTranslation = []

    start = []
    leftFoot = []
    rightFoot = []
    leftHand = []
    leftHandPreviousTick = []
    leftHandToDraw = []
    rightHand = []
    rightHandPreviousTick = []
    rightHandToDraw = []
    walked = 0
    shuffleTicks = 0
    foot = "left"
    ticksSinceLeft = 0
    ticksSinceRight = 0
    offset = []

    yaw = 0
    pitch = 0
    headYawPreviousTick = headYaw = 0

    stick = [0, 0, 0]
    stickAngle = 0

    edgeCallback = (edge) -> vector.flatten velocity, edge.plane.normal, velocity

    tick = ->
        if not firstTick
            matrix.copy entityTransform, entityTransformPreviousTick
            matrix.copy torsoTransform, torsoTransformPreviousTick
            vector.copy leftHand, leftHandPreviousTick
            vector.copy rightHand, rightHandPreviousTick

        matrix.translate velocity, entityTransform
        speed = vector.magnitude velocity
        walked += speed
        moving = speed > 2

        stick[0] = gamepad.right - gamepad.left
        stick[1] = gamepad.forward - gamepad.backward
        stickLength = vector.magnitude stick

        inDeadzone = stickLength < 0.1

        if inDeadzone
            stick[0] = stick[1] = 0
        else
            stickAngle = Math.atan2 -stick[0], stick[1]
            if stickLength > 1
                vector.divide.byScalar stick, stickLength, stick
                stickLength = 1

        # Left/right rotation.
        matrix.rotateY (stick[0] * -0.1), entityTransform, true

        # Apply navmesh triangle collision.
        matrix.getTranslation entityTransform, translation
        triangle = navmesh.constrain translation, triangle, edgeCallback

        # Gravity.
        velocity[1] -= 0.2

        # Forwards/backwards movement.
        matrix.getZ entityTransform, zAxis

        # Determine if we're underground.
        altitude = plane.distance triangle.plane, translation

        if altitude < 0
            velocity = velocity
            plane.project triangle.plane, translation, translation

            # A "bump" when you land.
            matrix.getY entityTransform, yAxis
            impact = Math.abs (vector.dot triangle.plane.normal, velocity) * (vector.dot triangle.plane.normal, yAxis)
            impact -= 1
            if impact < 0 then impact = 0
            impact *= 2
            torsoAltitude -= impact

            # Reflecting the velocity against the hit surface but then
            # flattening it has the effect that hitting a ramp bounces you up it
            # but you don't bounce when falling onto the floor.
            vector.reflect velocity, triangle.plane.normal, velocity
            vector.flatten velocity, triangle.plane.normal, velocity

            if not inDeadzone
                matrix.getX entityTransform, xAxis
                vector.multiply.byScalar zAxis, (stick[1] * 10), targetForwardVelocity
                vector.multiply.byScalar xAxis, (stick[0] * 10), targetSidewardVelocity
                vector.add.vector targetForwardVelocity, targetSidewardVelocity, targetVelocity
            else
                targetVelocity[0] = targetVelocity[1] = targetVelocity[2] = 0
            vector.interpolate velocity, targetVelocity, 0.05, velocity

        # Apply air resistance.
        vector.multiply.byScalar velocity, 0.98, velocity

        # This section attempts to align the entity with the triangle surface.

        # We take the triangle's normal as the Y/up axis.

        # First, flatten the Z/forward axis onto the surface.
        vector.flatten zAxis, triangle.plane.normal, zAxis
        vector.normalize zAxis, zAxis

        # Then, find the X/right axis which is perpendicular to the Z/forward
        # and Y/up axes.
        vector.cross triangle.plane.normal, zAxis, xAxis
        matrix.setX xAxis, surfaceCorrectedEntityTransform
        matrix.setY triangle.plane.normal, surfaceCorrectedEntityTransform
        matrix.setZ zAxis, surfaceCorrectedEntityTransform

        # Blend between our current transform and the aligned one.
        matrix.interpolate entityTransform, surfaceCorrectedEntityTransform, 0.1, entityTransform

        matrix.setTranslation translation, entityTransform

        matrix.copy entityTransform, torsoTransform

        torsoAltitude = misc.interpolate torsoAltitude, (12 - Math.min 2, (speed + if inDeadzone then 0 else 1.5)), 0.4

        matrix.getY entityTransform, yAxis
        vector.multiply.byScalar yAxis, torsoAltitude, torsoTranslation
        vector.add.vector torsoTranslation, translation, torsoTranslation

        yaw = misc.interpolateAngle yaw, stickAngle, 0.1, yaw
        matrix.rotateY yaw, torsoTransform, true

        # Calculating the head angle relative to the torso is complicated by the
        # stick angle being wrapped to 0...2PI, so we have to shift it out of
        # that range to clamp it.
        headYawPreviousTick = headYaw
        headYaw = Math.max Math.PI - 1, Math.min Math.PI + 1, misc.wrapAngle Math.PI + stickAngle - yaw
        headYaw -= Math.PI
        headYaw = misc.interpolateAngle headYawPreviousTick, headYaw, 0.4, headYaw

        matrix.getZ torsoTransform, torsoZAxis # TODO: If the entity transform is ever non-identity at startup we'll need to initialize torsoTransform for this to be right in the first ticks.
        matrix.getX torsoTransform, torsoXAxis # TODO: If the entity transform is ever non-identity at startup we'll need to initialize torsoTransform for this to be right in the first ticks.
        pitch = misc.interpolate pitch, (0.5 * stickLength - 0.1 * vector.dot torsoZAxis, velocity), 0.4
        matrix.rotateX pitch, torsoTransform, true
        matrix.rotateZ (0.1 * vector.dot torsoXAxis, velocity), torsoTransform, true

        matrix.setTranslation torsoTranslation, torsoTransform

        shuffleTicks--
        ticksSinceLeft++
        ticksSinceRight++
        while walked > 5 or shuffleTicks < 0
            shuffleTicks = 5
            walked -= 5
            if (not inDeadzone) or moving
                vector.normalize velocity, offset
                vector.multiply.byScalar offset, 5, offset
            else
                offset[0] = offset[1] = offset[2] = 0
            foot = switch foot
                when "left"
                    matrix.applyToVector playerPoseNew.torso, [-2, -10, 0], leftFoot
                    vector.add.vector offset, leftFoot, leftFoot
                    plane.project triangle.plane, leftFoot, leftFoot
                    ticksSinceLeft = 0
                    "right"
                when "right"
                    matrix.applyToVector playerPoseNew.torso, [2, -10, 0], rightFoot
                    vector.add.vector offset, rightFoot, rightFoot
                    plane.project triangle.plane, rightFoot, rightFoot
                    ticksSinceRight = 0
                    "left"

        if inDeadzone
            leftHand[0] = -6
            rightHand[0] = 6
            leftHand[1] = rightHand[1] = -4
            leftHand[2] = rightHand[2] = 0
        else
            yScale = 7 / (1 + speed)
            rightHand[0] = 2 + (Math.min 4, speed)
            leftHand[0] = -rightHand[0]

            leftHand[1] = rightHand[1] = 3
            motion = Math.pow (Math.cos ticksSinceLeft * 0.25) * 0.5 + 0.5, 4
            leftHand[1] += yScale * motion
            leftHand[2] = 1.5 + 6 * stickLength * motion
            motion = Math.pow (Math.cos ticksSinceRight * 0.25) * 0.5 + 0.5, 4
            rightHand[1] += yScale * motion
            rightHand[2] = 1.5 + 6 * stickLength * motion

        matrix.applyToVector torsoTransform, leftHand, leftHand
        matrix.applyToVector torsoTransform, rightHand, rightHand

        leftHand[1] -= 2
        rightHand[1] -= 2

        if firstTick
            matrix.copy entityTransform, entityTransformPreviousTick
            matrix.copy torsoTransform, torsoTransformPreviousTick
            vector.copy leftHand, leftHandPreviousTick
            vector.copy rightHand, rightHandPreviousTick
            firstTick = false

        lag = 0.15 + 0.4 / (1 + speed / 3)
        if inDeadzone then lag = 0.2
        vector.interpolate leftHandPreviousTick, leftHand, lag, leftHand
        vector.interpolate rightHandPreviousTick, rightHand, lag, rightHand

        return

# draw
Called with the progress through the current frame (a number between 0 and 1) to
redraw the scene.

    draw = (progress) ->

        if not firstDraw
            matrix.copy entityTransformToDraw, entityTransformPreviousDraw
            matrix.copy cameraTransform, cameraTransformPreviousDraw
            matrix.copy torsoTransformToDraw, torsoTransformPreviousDraw
            pose.copy playerPoseNew, playerPoseOld
            vector.copy cameraTarget, cameraTargetPreviousDraw
            vector.copy cameraLocation, cameraLocationPreviousDraw

        matrix.interpolate entityTransformPreviousTick, entityTransform, progress, entityTransformToDraw
        matrix.interpolate torsoTransformPreviousTick, torsoTransform, progress, playerPoseNew.torso

        matrix.getY entityTransformToDraw, yAxis
        matrix.getZ entityTransformToDraw, zAxis
        matrix.getTranslation entityTransformToDraw, cameraTarget
        vector.multiply.byScalar yAxis, 18, offset
        vector.add.vector cameraTarget, offset, cameraTarget
        vector.multiply.byScalar zAxis, -20, offset
        vector.add.vector cameraTarget, offset, cameraLocation

        vector.interpolate cameraTargetPreviousDraw, cameraTarget, 0.1, cameraTarget
        vector.interpolate cameraLocationPreviousDraw, cameraLocation, 0.1, cameraLocation

        matrix.getX entityTransformToDraw, cameraSide
        vector.interpolate cameraSidePreviousDraw, cameraSide, 0.1, cameraSide
        vector.copy cameraSide, cameraSidePreviousDraw

        cameraTriangle = triangle
        cameraTriangle = navmesh.constrain cameraLocation, cameraTriangle
        cameraAltitude = (plane.distance cameraTriangle.plane, cameraLocation) - 4
        if cameraAltitude < 0
            vector.multiply.byScalar cameraTriangle.plane.normal, -cameraAltitude, offset
            vector.add.vector offset, cameraLocation, cameraLocation

        ik.lookAt cameraLocation, cameraTarget, cameraSide, cameraTransform
        matrix.invert cameraTransform, cameraTransform

        matrix.applyToVector playerPoseNew.torso, [-1.5, -2.5, 0], start
        matrix.getX playerPoseNew.torso, xAxis
        ik.computeLimb start, leftFoot, 10, xAxis, playerPoseNew.legLeftUpper, playerPoseNew.legLeftLower

        matrix.applyToVector playerPoseNew.torso, [1.5, -2.5, 0], start
        ik.computeLimb start, rightFoot, 10, xAxis, playerPoseNew.legRightUpper, playerPoseNew.legRightLower

        matrix.getY playerPoseNew.torso, yAxis
        vector.negate xAxis, xAxis
        vector.interpolate xAxis, yAxis, 0.05, offset

        matrix.applyToVector playerPoseNew.torso, [-1.5, 4, 0], start
        vector.interpolate leftHandPreviousTick, leftHand, progress, leftHandToDraw
        ik.computeLimb start, leftHandToDraw, 10, offset, playerPoseNew.armLeftUpper, playerPoseNew.armLeftLower

        vector.negate yAxis, yAxis
        vector.interpolate xAxis, yAxis, 0.05, offset

        matrix.applyToVector playerPoseNew.torso, [1.5, 4, 0], start
        vector.interpolate rightHandPreviousTick, rightHand, progress, rightHandToDraw
        ik.computeLimb start, rightHandToDraw, 10, offset, playerPoseNew.armRightUpper, playerPoseNew.armRightLower

        matrix.copy playerPoseNew.torso, playerPoseNew.head
        matrix.translate [0, 6, 0], playerPoseNew.head, true
        matrix.rotateY (misc.interpolate headYawPreviousTick, headYaw, progress), playerPoseNew.head, true

        if firstDraw
            matrix.copy entityTransformToDraw, entityTransformPreviousDraw
            matrix.copy cameraTransform, cameraTransformPreviousDraw
            pose.copy playerPoseNew, playerPoseOld
            vector.copy cameraTarget, cameraTargetPreviousDraw
            vector.copy cameraLocation, cameraLocationPreviousDraw
            firstDraw = false

        context.begin 0, 0, context.width, context.height, 1, cameraTransformPreviousDraw, cameraTransform, 0.1, 0.5, 0.9
        cloud.draw testMap
        cloud.draw character, playerPoseOld, playerPoseNew

        return

    module.exports = { load, tick, draw }

# game

This module contains your game logic.  Its methods are called by the "index"
module to update the game state.

    gamepad = require "./input/gamepad.litcoffee"
    keyboard = require "./input/keyboard.litcoffee"

    context = require "./rendering/context.litcoffee"
    cloud = require "./rendering/cloud.litcoffee"
    matrix = require "./matrix.litcoffee"
    plane = require "./plane.litcoffee"
    misc = require "./misc.litcoffee"
    navmesh = require "./navmesh.litcoffee"
    vector = require "./vector.litcoffee"
    pose = require "./pose.litcoffee"
    ik = require "./ik.litcoffee"

    triangle = undefined

    character = testMap = testNavmesh = undefined
    characterData = require "./characters/test/cloud.coffee"

# load
Called before the first "tick"/"draw" to load any resources needed by the game.
Execute the argument when you have finished successfully.

    load = (callback) ->
        keyboard()
        context.load()
        cloud.load characterData, (character_) ->
            character = character_
            cloud.load (require "./tracks/test/geometry.msc"), (testMap_) ->
                testMap = testMap_
                navmesh.load (require "./tracks/test/navmesh.msn"), (testNavmesh_) ->
                    testNavmesh = testNavmesh_
                    triangle = testNavmesh[0]
                    callback()
                    return
                return
            return
        return

# tick
Called at 20Hz to update game state.  Guaranteed to be called once between
"load" and "draw".  May be called more or than once per call to "draw" or not at
all.

    firstTick = true
    firstDraw = true

    entityTransform = []
    entityTransformToDraw = []
    entityTransformPreviousTick = []
    entityTransformPreviousDraw = []
    matrix.identity entityTransform

    playerPoseOld = pose.create characterData
    playerPoseNew = pose.create characterData

    torsoTransform = []
    torsoTransformToDraw = []
    torsoTransformPreviousTick = []
    torsoTransformPreviousDraw = []

    surfaceCorrectedEntityTransform = []
    matrix.identity surfaceCorrectedEntityTransform

    cameraTransform = []
    cameraTransformPreviousDraw = []
    matrix.identity cameraTransform

    torsoAltitude = 0

    velocity = [0, 0, 0]
    xAxis = []
    yAxis = []
    zAxis = []
    torsoXAxis = []
    torsoZAxis = []
    translation = []
    targetForwardVelocity = []
    targetSidewardVelocity = []
    targetVelocity = []
    torsoTranslation = []

    start = []
    leftFoot = []
    rightFoot = []
    leftHand = []
    leftHandPreviousTick = []
    leftHandToDraw = []
    rightHand = []
    rightHandPreviousTick = []
    rightHandToDraw = []
    walked = 0
    shuffleTicks = 0
    foot = "left"
    ticksSinceLeft = 0
    ticksSinceRight = 0
    offset = []

    yaw = 0
    pitch = 0
    headYawPreviousTick = headYaw = 0

    stick = [0, 0, 0]
    stickAngle = 0

    edgeCallback = (edge) -> vector.flatten velocity, edge.plane.normal, velocity

    tick = ->
        if not firstTick
            matrix.copy entityTransform, entityTransformPreviousTick
            matrix.copy torsoTransform, torsoTransformPreviousTick
            vector.copy leftHand, leftHandPreviousTick
            vector.copy rightHand, rightHandPreviousTick

        matrix.translate velocity, entityTransform
        speed = vector.magnitude velocity
        walked += speed
        moving = speed > 2

        stick[0] = gamepad.right - gamepad.left
        stick[1] = gamepad.forward - gamepad.backward
        stickLength = vector.magnitude stick

        inDeadzone = stickLength < 0.1

        if inDeadzone
            stick[0] = stick[1] = 0
        else
            stickAngle = Math.atan2 -stick[0], stick[1]
            if stickLength > 1
                vector.divide.byScalar stick, stickLength, stick
                stickLength = 1

        # Left/right rotation.
        matrix.rotateY (stick[0] * -0.1), entityTransform, true

        # Apply navmesh triangle collision.
        matrix.getTranslation entityTransform, translation
        triangle = navmesh.constrain translation, triangle, edgeCallback

        # Gravity.
        velocity[1] -= 0.2

        # Forwards/backwards movement.
        matrix.getZ entityTransform, zAxis

        # Determine if we're underground.
        altitude = plane.distance triangle.plane, translation

        if altitude < 0
            velocity = velocity
            plane.project triangle.plane, translation, translation

            # A "bump" when you land.
            matrix.getY entityTransform, yAxis
            impact = Math.abs (vector.dot triangle.plane.normal, velocity) * (vector.dot triangle.plane.normal, yAxis)
            impact -= 1
            if impact < 0 then impact = 0
            impact *= 2
            torsoAltitude -= impact

            # Reflecting the velocity against the hit surface but then
            # flattening it has the effect that hitting a ramp bounces you up it
            # but you don't bounce when falling onto the floor.
            vector.reflect velocity, triangle.plane.normal, velocity
            vector.flatten velocity, triangle.plane.normal, velocity

            if not inDeadzone
                matrix.getX entityTransform, xAxis
                vector.multiply.byScalar zAxis, (stick[1] * 10), targetForwardVelocity
                vector.multiply.byScalar xAxis, (stick[0] * 10), targetSidewardVelocity
                vector.add.vector targetForwardVelocity, targetSidewardVelocity, targetVelocity
            else
                targetVelocity[0] = targetVelocity[1] = targetVelocity[2] = 0
            vector.interpolate velocity, targetVelocity, 0.05, velocity

        # Apply air resistance.
        vector.multiply.byScalar velocity, 0.98, velocity

        # This section attempts to align the entity with the triangle surface.

        # We take the triangle's normal as the Y/up axis.

        # First, flatten the Z/forward axis onto the surface.
        vector.flatten zAxis, triangle.plane.normal, zAxis
        vector.normalize zAxis, zAxis

        # Then, find the X/right axis which is perpendicular to the Z/forward
        # and Y/up axes.
        vector.cross triangle.plane.normal, zAxis, xAxis
        matrix.setX xAxis, surfaceCorrectedEntityTransform
        matrix.setY triangle.plane.normal, surfaceCorrectedEntityTransform
        matrix.setZ zAxis, surfaceCorrectedEntityTransform

        # Blend between our current transform and the aligned one.
        matrix.interpolate entityTransform, surfaceCorrectedEntityTransform, 0.1, entityTransform

        matrix.setTranslation translation, entityTransform

        matrix.copy entityTransform, torsoTransform

        torsoAltitude = misc.interpolate torsoAltitude, (12 - Math.min 2, (speed + if inDeadzone then 0 else 1.5)), 0.4

        matrix.getY entityTransform, yAxis
        vector.multiply.byScalar yAxis, torsoAltitude, torsoTranslation
        vector.add.vector torsoTranslation, translation, torsoTranslation

        yaw = misc.interpolateAngle yaw, stickAngle, 0.1, yaw
        matrix.rotateY yaw, torsoTransform, true

        # Calculating the head angle relative to the torso is complicated by the
        # stick angle being wrapped to 0...2PI, so we have to shift it out of
        # that range to clamp it.
        headYawPreviousTick = headYaw
        headYaw = Math.max Math.PI - 1, Math.min Math.PI + 1, misc.wrapAngle Math.PI + stickAngle - yaw
        headYaw -= Math.PI
        headYaw = misc.interpolateAngle headYawPreviousTick, headYaw, 0.4, headYaw

        matrix.getZ torsoTransform, torsoZAxis # TODO: If the entity transform is ever non-identity at startup we'll need to initialize torsoTransform for this to be right in the first ticks.
        matrix.getX torsoTransform, torsoXAxis # TODO: If the entity transform is ever non-identity at startup we'll need to initialize torsoTransform for this to be right in the first ticks.
        pitch = misc.interpolate pitch, (0.5 * stickLength - 0.1 * vector.dot torsoZAxis, velocity), 0.4
        matrix.rotateX pitch, torsoTransform, true
        matrix.rotateZ (0.1 * vector.dot torsoXAxis, velocity), torsoTransform, true

        matrix.setTranslation torsoTranslation, torsoTransform

        shuffleTicks--
        ticksSinceLeft++
        ticksSinceRight++
        while walked > 5 or shuffleTicks < 0
            shuffleTicks = 5
            walked -= 5
            if (not inDeadzone) or moving
                vector.normalize velocity, offset
                vector.multiply.byScalar offset, 5, offset
            else
                offset[0] = offset[1] = offset[2] = 0
            foot = switch foot
                when "left"
                    matrix.applyToVector playerPoseNew.torso, [-2, -10, 0], leftFoot
                    vector.add.vector offset, leftFoot, leftFoot
                    plane.project triangle.plane, leftFoot, leftFoot
                    ticksSinceLeft = 0
                    "right"
                when "right"
                    matrix.applyToVector playerPoseNew.torso, [2, -10, 0], rightFoot
                    vector.add.vector offset, rightFoot, rightFoot
                    plane.project triangle.plane, rightFoot, rightFoot
                    ticksSinceRight = 0
                    "left"

        if inDeadzone
            leftHand[0] = -6
            rightHand[0] = 6
            leftHand[1] = rightHand[1] = -4
            leftHand[2] = rightHand[2] = 0
        else
            yScale = 7 / (1 + speed)
            rightHand[0] = 2 + (Math.min 4, speed)
            leftHand[0] = -rightHand[0]

            leftHand[1] = rightHand[1] = 3
            motion = Math.pow (Math.cos ticksSinceLeft * 0.25) * 0.5 + 0.5, 4
            leftHand[1] += yScale * motion
            leftHand[2] = 1.5 + 6 * stickLength * motion
            motion = Math.pow (Math.cos ticksSinceRight * 0.25) * 0.5 + 0.5, 4
            rightHand[1] += yScale * motion
            rightHand[2] = 1.5 + 6 * stickLength * motion

        matrix.applyToVector torsoTransform, leftHand, leftHand
        matrix.applyToVector torsoTransform, rightHand, rightHand

        leftHand[1] -= 2
        rightHand[1] -= 2

        if firstTick
            matrix.copy entityTransform, entityTransformPreviousTick
            matrix.copy torsoTransform, torsoTransformPreviousTick
            vector.copy leftHand, leftHandPreviousTick
            vector.copy rightHand, rightHandPreviousTick
            firstTick = false

        lag = 0.15 + 0.4 / (1 + speed / 3)
        if inDeadzone then lag = 0.2
        vector.interpolate leftHandPreviousTick, leftHand, lag, leftHand
        vector.interpolate rightHandPreviousTick, rightHand, lag, rightHand

        return

# draw
Called with the progress through the current frame (a number between 0 and 1) to
redraw the scene.

    draw = (progress) ->

        if not firstDraw
            matrix.copy entityTransformToDraw, entityTransformPreviousDraw
            matrix.copy cameraTransform, cameraTransformPreviousDraw
            matrix.copy torsoTransformToDraw, torsoTransformPreviousDraw
            pose.copy playerPoseNew, playerPoseOld

        matrix.interpolate entityTransformPreviousTick, entityTransform, progress, entityTransformToDraw
        matrix.interpolate torsoTransformPreviousTick, torsoTransform, progress, playerPoseNew.torso

        matrix.invert entityTransformToDraw, cameraTransform
        matrix.translate [0,-10, 10], cameraTransform

        matrix.applyToVector playerPoseNew.torso, [-1.5, -2.5, 0], start
        matrix.getX playerPoseNew.torso, xAxis
        ik.computeLimb start, leftFoot, 10, xAxis, playerPoseNew.legLeftUpper, playerPoseNew.legLeftLower

        matrix.applyToVector playerPoseNew.torso, [1.5, -2.5, 0], start
        ik.computeLimb start, rightFoot, 10, xAxis, playerPoseNew.legRightUpper, playerPoseNew.legRightLower

        matrix.getY playerPoseNew.torso, yAxis
        vector.negate xAxis, xAxis
        vector.interpolate xAxis, yAxis, 0.05, offset

        matrix.applyToVector playerPoseNew.torso, [-1.5, 4, 0], start
        vector.interpolate leftHandPreviousTick, leftHand, progress, leftHandToDraw
        ik.computeLimb start, leftHandToDraw, 10, offset, playerPoseNew.armLeftUpper, playerPoseNew.armLeftLower

        vector.negate yAxis, yAxis
        vector.interpolate xAxis, yAxis, 0.05, offset

        matrix.applyToVector playerPoseNew.torso, [1.5, 4, 0], start
        vector.interpolate rightHandPreviousTick, rightHand, progress, rightHandToDraw
        ik.computeLimb start, rightHandToDraw, 10, offset, playerPoseNew.armRightUpper, playerPoseNew.armRightLower

        matrix.copy playerPoseNew.torso, playerPoseNew.head
        matrix.translate [0, 6, 0], playerPoseNew.head, true
        matrix.rotateY (misc.interpolate headYawPreviousTick, headYaw, progress), playerPoseNew.head, true

        if firstDraw
            matrix.copy entityTransformToDraw, entityTransformPreviousDraw
            matrix.copy cameraTransform, cameraTransformPreviousDraw
            pose.copy playerPoseNew, playerPoseOld
            firstDraw = false

        context.begin 0, 0, context.width, context.height, 1, cameraTransformPreviousDraw, cameraTransform, 0.1, 0.5, 0.9
        cloud.draw testMap
        cloud.draw character, playerPoseOld, playerPoseNew

        return

    module.exports = { load, tick, draw }


cross origin

cross origin

    _self = this

    if console?.log?
     LOG = console.log.bind console
    else
     LOG = -> null

    if console?.error?
     ERROR_LOG = console.error.bind console
    else
     ERROR_LOG = -> null

    POLL_TYPE =
     progress: true

##Response class

    class Response
     constructor: (data, port, options) ->
      @id = data.id
      @port = port
      @options = options
      @queue = []
      @fresh = true

     progress: (progress, data, callback) ->
      @queue.push
       method: 'progress'
       data: data
       options: {progress: progress}
       callback: callback
      @_handleQueue()

     success: (data) ->
      @queue.push method: 'success', data: data, options: {}
      @_handleQueue()

     fail: (data) ->
      @queue.push method: 'fail', data: data, options: {}
      @_handleQueue()

     setOptions: (options) ->
      @options = options
      @fresh = true
      @_handleQueue()

     _handleQueue: ->
      return unless @queue.length > 0

      d = @queue[0]

      if @port.isStreaming
       @port.respond this, d.method, d.data, d.options, @options, d.callback
       @queue.shift()
      else if @fresh
       @port.respond this, d.method, d.data, d.options, @options, d.callback
       @queue.shift()
       @fresh = false

##Call class

    class Call
     constructor: (@id, @method, @data, @callbacks, @options) -> null

     handle: (data, options) ->
      if not @callbacks[options.status]?
       return if options.status is 'progress'
       #Handled by caller
       throw new Error "No callback registered #{@method} #{options.status}"
      self = this
      setTimeout (-> self.callbacks[options.status] data, options), 0

      if POLL_TYPE[options.status]?
       return false
      else
       return true

##Port base class

    class Port
     constructor: ->
      @handlers = {}
      @callsCache = {}
      @callsCounter = 0
      @id = parseInt Math.random() * 1000
      @responses = {}
      @wrappers =
       send: []
       respond: []
       handleCall: []
       handleResponse: []

     isStreaming: true

     onCallError: (msg, options) ->
      for id, call of @callsCache
       if not call.callbacks.fail?
        ERROR_LOG 'fail callback not registered', call.method, call.data
       else
        call.callbacks.fail error: 'connectionError', msg: msg, options: options, {}

      @callsCache = {}

      @errorCallback msg, options

     onHandleError: (msg, data, options) ->
      @errorCallback msg, data
      response = new Response data, this, options
      response.fail msg

     errorCallback: (msg, options) ->
      ERROR_LOG msg, options

     wrap: (wrapper) ->
      for key, f of wrapper
       if @wrappers[key]?
        @wrappers[key].push f
       else
        this[key] = f

###Send RPC call

     send: (method, data, callbacks, options = {}) ->
      if (typeof callbacks) is 'function'
       callbacks =
        success: callbacks

      for f in @wrappers.send
       return unless f.apply this, [method, data, callbacks, options]

      params = @_createCall method, data, callbacks, options
      @_send params, callbacks

###Respond to a RPC call

     respond: (response, status, data, options = {}, portOptions = {}, callback = null) ->
      for f in @wrappers.respond
       return unless f.apply this, [response, status, data, options, portOptions]

      @_respond (@_createResponse response, status, data, options), portOptions, callback
      if not POLL_TYPE[status]?
       delete @responses[response.id]

###Create Call object
This is a private function

     _createCall: (method, data, callbacks, options) ->
      call = new Call "#{@id}-#{@callsCounter}", method, data, callbacks, options
      @callsCounter++
      @callsCache[call.id] = call

      params =
       type: 'call'
       id: call.id
       method: call.method
       data: call.data

      params[k] = v for k, v of options
      return params

###Create Response object

     _createResponse: (response, status, data, options) ->
      params =
       type: 'response'
       id: response.id
       status: status
       data: data

      params[k] = v for k, v of options

      return params

###Add handler

     on: (method, callback) ->
      @handlers[method] = callback

###Handle incoming message

     _handleMessage: (data, options) ->
      switch data.type
       when 'response'
        @_handleResponse data, options
       when 'call'
        @_handleCall data, options
       when 'poll'
        @_handlePoll data, options

     _handleCall: (data, options) ->
      for f in @wrappers.handleCall
       return unless f.apply this, arguments
      if not @handlers[data.method]?
       @onHandleError "Unknown method: #{data.method}", data, options
       return
      @responses[data.id] = new Response data, this, options
      @handlers[data.method] data.data, data, @responses[data.id]

     _handleResponse: (data, options) ->
      for f in @wrappers.handleResponse
       return unless f.apply this, arguments
      if not @callsCache[data.id]?
       #Cannot reply
       @errorCallback "Response without call: #{data.id}", data
       return
      try
       if @callsCache[data.id].handle data.data, data
        delete @callsCache[data.id]
      catch e
       @errorCallback e.message, data
       delete @callsCache[data.id]

     _handlePoll: (data, options) ->
      @onHandleError "Poll not implemented", data, options

##WorkerPort class
Used for browser and worker

    class WorkerPort extends Port
     constructor: (worker) ->
      super()
      @worker = worker
      @worker.onmessage = @_onMessage.bind this
      #@worker.onerror = @onCallError.bind this

     _send: (data) ->  @worker.postMessage data
     _respond: (data, options, callback) ->
      @worker.postMessage data
      callback?()

     _onMessage: (e) ->
      data = e.data
      @_handleMessage data

##SocketPort class

    class SocketPort extends Port
     constructor: (socket) ->
      super()
      @socket = socket
      @socket.on 'message', @_onMessage.bind this

     _send: (data) ->  @socket.emit 'message', data
     _respond: (data, options, callback) ->
      @worker.emit 'message', data
      callback?()

     _onMessage: (e) ->
      data = e.data
      @_handleMessage data

##ServerSocketPort class

    class ServerSocketPort extends Port
     constructor: (server) ->
      super()
      @server = server
      @server.on 'connection', @_onConnection.bind this

     _onConnection: (socket) ->
      new SocketPort handlers: @handlers, socket

##AJAX class

    class AjaxHttpPort extends Port
     constructor: (options) ->
      super()
      @protocol = options.protocol
      @host = options.host
      @port = options.port
      @path = options.path ? '/'
      @url = @path
      if @protocol?
       if @host? and not @port?
        @url = "#{@protocol}://#{@host}#{@path}"
       else if @host? and @port?
        @url = "#{@protocol}://#{@host}:#{@port}#{@path}"
      else
       if @host? and not @port?
        @url = "//#{@host}#{@path}"
       else if @host? and @port?
        @url = "//#{@host}:#{@port}#{@path}"

     isStreaming: false

     _onRequest: (xhr) ->
      return unless xhr.readyState is 4
      status = xhr.status
      if ((not status and xhr.responseText? and xhr.responseText != '') or
          (status >= 200 and status < 300) or
          (status is 304))
       try
        jsonData = JSON.parse xhr.responseText
       catch e
        @onCallError 'ParseError', e
        return

       @_handleMessage jsonData, xhr: xhr
      else
       @onCallError 'Cannot connect to server'

     _respond: (data, options, callback) ->
      @errorCallback 'AJAX cannot respond', data
      callback?()

     _send: (data) ->
      data = JSON.stringify data
      xhr = new XMLHttpRequest
      xhr.open 'POST', @url
      xhr.onreadystatechange = =>
       @_onRequest xhr
      xhr.setRequestHeader 'Accept', 'application/json'
      #xhr.setRequestHeader 'Content-Type', 'application/json'
      xhr.send data

     _handleResponse: (data, options) ->
      for f in @wrappers.handleResponse
       return unless f.apply this, arguments
      if not @callsCache[data.id]?
       @errorCallback "Response without call: #{data.id}", data
       return
      call = @callsCache[data.id]
      try
       if call.handle data.data, data
        delete @callsCache[data.id]
       else
        params =
         type: 'poll'
         id: call.id
        params[k] = v for k, v of call.options
        @_send params
      catch e
       @errorCallback e.message, data
       delete @callsCache[data.id]

##NodeHttpPort class

    class NodeHttpPort extends Port
     constructor: (options, http) ->
      super()
      @host = options.host ? 'localhost'
      @port = options.port ? 80
      @path = options.path ? '/'
      @http = http
      @_createHttpOptions()

     isStreaming: false

     _createHttpOptions: ->
      @httpOptions =
       hostname: @host
       port: @port
       path: @path
       method: 'POST'
       agent: false
       headers:
        accept: 'application/json'
       'content-type': 'application/json'

     _onRequest: (res) ->
      data = ''
      #LOG 'STATUS: ' + res.statusCode
      #LOG 'HEADERS: ' + JSON.stringify res.headers
      res.setEncoding 'utf8'
      res.on 'data', (chunk) ->
       data += chunk
      #LOG 'result', res
      res.on 'end', =>
       try
        jsonData = JSON.parse data
       catch e
        @onCallError 'ParseError', e
        return

       @_handleMessage jsonData, response: res

     _respond: (data, options, callback) ->
      data = JSON.stringify data
      res = options.response
      res.setHeader 'content-length', Buffer.byteLength data, 'utf8'
      if callback?
       res.once 'finish', ->
        callback()
       res.once 'close', ->
        callback()

      res.write data
      res.end()

     _send: (data, callbacks) ->
      data = JSON.stringify data
      options = @httpOptions
      options.headers['content-length'] = Buffer.byteLength data, 'utf8'

      req = @http.request options, @_onRequest.bind this
      delete options.headers['content-length']
      req.on 'error', (e) ->
       callbacks.fail? e

      req.write data
      req.end()

     _handleResponse: (data, options) ->
      for f in @wrappers.handleResponse
       return unless f.apply this, arguments
      if not @callsCache[data.id]?
       @errorCallback "Response without call: #{data.id}", data
       return
      call = @callsCache[data.id]
      if not call.handle data.data, data
       params =
        type: 'poll'
        id: call.id
       params[k] = v for k, v of call.options
       @_send params, call.callbacks

##NodeHttpServerPort class

    class NodeHttpServerPort extends Port
     constructor: (options, http, zlib = null) ->
      super()
      @port = options.port
      @http = http
      @zlib = zlib
      @allowOrigin = options.allowOrigin

     isStreaming: false

     _onRequest: (req, res) ->
      data = ''
      res.setHeader 'content-type', 'application/json'

      req.on 'data', (chunk) ->
       data += chunk
      req.on 'end', =>
       try
        jsonData = JSON.parse data
       catch e
        @errorCallback 'ParseError', e
        return

       @_handleMessage jsonData, response: res, request: req

     _respond: (data, options, callback) ->
      if @allowOrigin?
       options.response.setHeader 'Access-Control-Allow-Origin', @allowOrigin

      accept = options.request.headers['accept-encoding']
      accept ?= ''
      if not @zlib?
       accept = ''

      data = JSON.stringify data
      buffer = new Buffer data, 'utf8'
      if accept.match /\bdeflate\b/
       options.response.setHeader 'content-encoding', 'deflate'
       @zlib.deflate buffer, (err, result) =>
        if err?
         return @errorCallback 'DeflateError', e
        @_sendBuffer result, options.response, callback
      else if accept.match /\bgzip\b/
       options.response.setHeader 'content-encoding', 'gzip'
       @zlib.gzip buffer, (err, result) =>
        if err?
         return @errorCallback 'GZipeError', e
        @_sendBuffer result, options.response, callback
      else
       @_sendBuffer buffer, options.response, callback

     _sendBuffer: (buf, res, callback) ->
       res.setHeader 'content-length', buf.length
       if callback?
        res.once 'finish', ->
         callback()
        res.once 'close', ->
         callback()

       res.write buf
       res.end()

     listen: ->
      @server = @http.createServer @_onRequest.bind this
      @server.listen @port

     _handlePoll: (data, options) ->
      for f in @wrappers.handleCall
       return unless f.apply this, arguments
      if not @responses[data.id]?
       @onHandleError "Poll without response: #{data.id}", data, options
       return
      @responses[data.id].setOptions options

##NodeHttpsServerPort class

    class NodeHttpsServerPort extends NodeHttpServerPort
     constructor: (options, http) ->
      super options, http
      @_key = options.key
      @_cert = options.cert

     listen: ->
      options =
       key: @_key
       cert: @_cert

      @server = @http.createServer options, @_onRequest.bind this
      @server.listen @port

#IO Module

    IO =
     addPort: (name, port) ->
      IO[name] = port

     ports:
      WorkerPort: WorkerPort
      SocketPort: SocketPort
      AjaxHttpPort: AjaxHttpPort
      NodeHttpPort: NodeHttpPort
      NodeHttpServerPort: NodeHttpServerPort
      NodeHttpsServerPort: NodeHttpsServerPort
      ServerSocketPort: ServerSocketPort

     Helpers:
      progress: (from, to, func) ->
       (progress, data) ->
        func? progress * (to - from) + from, data

     setup_____: (options) ->
      options.workers ?= []
      switch options.platform
       when 'ui'
        for worker in options.workers
         IO.addPort worker.name, new WorkerPort worker.js
        for socket in options.sockets
         IO.addPort socket.name, new SocketPort socket.url
       when 'node'
        for socket in options.listenSockets
         IO.addPort socket.name, new SocketListenPort socket.port
        for socket in options.sockets
         IO.addPort socket.name, new SocketPort socket.url
       when 'worker'
        IO.addPort 'UI', new WorkerListenPort _self

    if exports?
     module.exports = IO
    else
     _self.IO = IO

    _self = this

    if console?.log?
     LOG = console.log.bind console
    else
     LOG = -> null

    if console?.error?
     ERROR_LOG = console.error.bind console
    else
     ERROR_LOG = -> null

    POLL_TYPE =
     progress: true

##Response class

    class Response
     constructor: (data, port, options) ->
      @id = data.id
      @port = port
      @options = options
      @queue = []
      @fresh = true

     progress: (progress, data, callback) ->
      @queue.push
       method: 'progress'
       data: data
       options: {progress: progress}
       callback: callback
      @_handleQueue()

     success: (data) ->
      @queue.push method: 'success', data: data, options: {}
      @_handleQueue()

     fail: (data) ->
      @queue.push method: 'fail', data: data, options: {}
      @_handleQueue()

     setOptions: (options) ->
      @options = options
      @fresh = true
      @_handleQueue()

     _handleQueue: ->
      return unless @queue.length > 0

      d = @queue[0]

      if @port.isStreaming
       @port.respond this, d.method, d.data, d.options, @options, d.callback
       @queue.shift()
      else if @fresh
       @port.respond this, d.method, d.data, d.options, @options, d.callback
       @queue.shift()
       @fresh = false

##Call class

    class Call
     constructor: (@id, @method, @data, @callbacks, @options) -> null

     handle: (data, options) ->
      if not @callbacks[options.status]?
       return if options.status is 'progress'
       #Handled by caller
       throw new Error "No callback registered #{@method} #{options.status}"
      self = this
      setTimeout (-> self.callbacks[options.status] data, options), 0

      if POLL_TYPE[options.status]?
       return false
      else
       return true

##Port base class

    class Port
     constructor: ->
      @handlers = {}
      @callsCache = {}
      @callsCounter = 0
      @id = parseInt Math.random() * 1000
      @responses = {}
      @wrappers =
       send: []
       respond: []
       handleCall: []
       handleResponse: []

     isStreaming: true

     onCallError: (msg, options) ->
      for id, call of @callsCache
       if not call.callbacks.fail?
        ERROR_LOG 'fail callback not registered', call.method, call.data
       else
        call.callbacks.fail error: 'connectionError', msg: msg, options: options, {}

      @callsCache = {}

      @errorCallback msg, options

     onHandleError: (msg, data, options) ->
      @errorCallback msg, data
      response = new Response data, this, options
      response.fail msg

     errorCallback: (msg, options) ->
      ERROR_LOG msg, options

     wrap: (wrapper) ->
      for key, f of wrapper
       if @wrappers[key]?
        @wrappers[key].push f
       else
        this[key] = f

###Send RPC call

     send: (method, data, callbacks, options = {}) ->
      if (typeof callbacks) is 'function'
       callbacks =
        success: callbacks

      for f in @wrappers.send
       return unless f.apply this, [method, data, callbacks, options]

      params = @_createCall method, data, callbacks, options
      @_send params, callbacks

###Respond to a RPC call

     respond: (response, status, data, options = {}, portOptions = {}, callback = null) ->
      for f in @wrappers.respond
       return unless f.apply this, [response, status, data, options, portOptions]

      @_respond (@_createResponse response, status, data, options), portOptions, callback
      if not POLL_TYPE[status]?
       delete @responses[response.id]

###Create Call object
This is a private function

     _createCall: (method, data, callbacks, options) ->
      call = new Call "#{@id}-#{@callsCounter}", method, data, callbacks, options
      @callsCounter++
      @callsCache[call.id] = call

      params =
       type: 'call'
       id: call.id
       method: call.method
       data: call.data

      params[k] = v for k, v of options
      return params

###Create Response object

     _createResponse: (response, status, data, options) ->
      params =
       type: 'response'
       id: response.id
       status: status
       data: data

      params[k] = v for k, v of options

      return params

###Add handler

     on: (method, callback) ->
      @handlers[method] = callback

###Handle incoming message

     _handleMessage: (data, options) ->
      switch data.type
       when 'response'
        @_handleResponse data, options
       when 'call'
        @_handleCall data, options
       when 'poll'
        @_handlePoll data, options

     _handleCall: (data, options) ->
      for f in @wrappers.handleCall
       return unless f.apply this, arguments
      if not @handlers[data.method]?
       @onHandleError "Unknown method: #{data.method}", data, options
       return
      @responses[data.id] = new Response data, this, options
      @handlers[data.method] data.data, data, @responses[data.id]

     _handleResponse: (data, options) ->
      for f in @wrappers.handleResponse
       return unless f.apply this, arguments
      if not @callsCache[data.id]?
       #Cannot reply
       @errorCallback "Response without call: #{data.id}", data
       return
      try
       if @callsCache[data.id].handle data.data, data
        delete @callsCache[data.id]
      catch e
       @errorCallback e.message, data
       delete @callsCache[data.id]

     _handlePoll: (data, options) ->
      @onHandleError "Poll not implemented", data, options

##WorkerPort class
Used for browser and worker

    class WorkerPort extends Port
     constructor: (worker) ->
      super()
      @worker = worker
      @worker.onmessage = @_onMessage.bind this
      #@worker.onerror = @onCallError.bind this

     _send: (data) ->  @worker.postMessage data
     _respond: (data, options, callback) ->
      @worker.postMessage data
      callback?()

     _onMessage: (e) ->
      data = e.data
      @_handleMessage data

##SocketPort class

    class SocketPort extends Port
     constructor: (socket) ->
      super()
      @socket = socket
      @socket.on 'message', @_onMessage.bind this

     _send: (data) ->  @socket.emit 'message', data
     _respond: (data, options, callback) ->
      @worker.emit 'message', data
      callback?()

     _onMessage: (e) ->
      data = e.data
      @_handleMessage data

##ServerSocketPort class

    class ServerSocketPort extends Port
     constructor: (server) ->
      super()
      @server = server
      @server.on 'connection', @_onConnection.bind this

     _onConnection: (socket) ->
      new SocketPort handlers: @handlers, socket

##AJAX class

    class AjaxHttpPort extends Port
     constructor: (options) ->
      super()
      @protocol = options.protocol
      @host = options.host
      @port = options.port
      @path = options.path ? '/'
      @url = @path
      if @protocol?
       if @host? and not @port?
        @url = "#{@protocol}://#{@host}#{@path}"
       else if @host? and @port?
        @url = "#{@protocol}://#{@host}:#{@port}#{@path}"
      else
       if @host? and not @port?
        @url = "//#{@host}#{@path}"
       else if @host? and @port?
        @url = "//#{@host}:#{@port}#{@path}"

     isStreaming: false

     _onRequest: (xhr) ->
      return unless xhr.readyState is 4
      status = xhr.status
      if ((not status and xhr.responseText? and xhr.responseText != '') or
          (status >= 200 and status < 300) or
          (status is 304))
       try
        jsonData = JSON.parse xhr.responseText
       catch e
        @onCallError 'ParseError', e
        return

       @_handleMessage jsonData, xhr: xhr
      else
       @onCallError 'Cannot connect to server'

     _respond: (data, options, callback) ->
      @errorCallback 'AJAX cannot respond', data
      callback?()

     _send: (data) ->
      data = JSON.stringify data
      xhr = new XMLHttpRequest
      xhr.open 'POST', @url
      xhr.onreadystatechange = =>
       @_onRequest xhr
      xhr.setRequestHeader 'Accept', 'application/json'
      #xhr.setRequestHeader 'Content-Type', 'application/json'
      xhr.send data

     _handleResponse: (data, options) ->
      for f in @wrappers.handleResponse
       return unless f.apply this, arguments
      if not @callsCache[data.id]?
       @errorCallback "Response without call: #{data.id}", data
       return
      call = @callsCache[data.id]
      try
       if call.handle data.data, data
        delete @callsCache[data.id]
       else
        params =
         type: 'poll'
         id: call.id
        params[k] = v for k, v of call.options
        @_send params
      catch e
       @errorCallback e.message, data
       delete @callsCache[data.id]

##NodeHttpPort class

    class NodeHttpPort extends Port
     constructor: (options, http) ->
      super()
      @host = options.host ? 'localhost'
      @port = options.port ? 80
      @path = options.path ? '/'
      @http = http
      @_createHttpOptions()

     isStreaming: false

     _createHttpOptions: ->
      @httpOptions =
       hostname: @host
       port: @port
       path: @path
       method: 'POST'
       agent: false
       headers:
        accept: 'application/json'
       'content-type': 'application/json'

     _onRequest: (res) ->
      data = ''
      #LOG 'STATUS: ' + res.statusCode
      #LOG 'HEADERS: ' + JSON.stringify res.headers
      res.setEncoding 'utf8'
      res.on 'data', (chunk) ->
       data += chunk
      #LOG 'result', res
      res.on 'end', =>
       try
        jsonData = JSON.parse data
       catch e
        @onCallError 'ParseError', e
        return

       @_handleMessage jsonData, response: res

     _respond: (data, options, callback) ->
      data = JSON.stringify data
      res = options.response
      res.setHeader 'content-length', Buffer.byteLength data, 'utf8'
      if callback?
       res.once 'finish', ->
        callback()
       res.once 'close', ->
        callback()

      res.write data
      res.end()

     _send: (data, callbacks) ->
      data = JSON.stringify data
      options = @httpOptions
      options.headers['content-length'] = Buffer.byteLength data, 'utf8'

      req = @http.request options, @_onRequest.bind this
      delete options.headers['content-length']
      req.on 'error', (e) ->
       callbacks.fail? e

      req.write data
      req.end()

     _handleResponse: (data, options) ->
      for f in @wrappers.handleResponse
       return unless f.apply this, arguments
      if not @callsCache[data.id]?
       @errorCallback "Response without call: #{data.id}", data
       return
      call = @callsCache[data.id]
      if not call.handle data.data, data
       params =
        type: 'poll'
        id: call.id
       params[k] = v for k, v of call.options
       @_send params, call.callbacks

##NodeHttpServerPort class

    class NodeHttpServerPort extends Port
     constructor: (options, http, zlib = null) ->
      super()
      @port = options.port
      @http = http
      @zlib = zlib

     isStreaming: false

     _onRequest: (req, res) ->
      data = ''
      res.setHeader 'content-type', 'application/json'

      req.on 'data', (chunk) ->
       data += chunk
      req.on 'end', =>
       try
        jsonData = JSON.parse data
       catch e
        @errorCallback 'ParseError', e
        return

       @_handleMessage jsonData, response: res, request: req

     _respond: (data, options, callback) ->
      accept = options.request.headers['accept-encoding']
      accept ?= ''
      if not @zlib?
       accept = ''

      data = JSON.stringify data
      buffer = new Buffer data, 'utf8'
      if accept.match /\bdeflate\b/
       options.response.setHeader 'content-encoding', 'deflate'
       @zlib.deflate buffer, (err, result) =>
        if err?
         return @errorCallback 'DeflateError', e
        @_sendBuffer result, options.response, callback
      else if accept.match /\bgzip\b/
       options.response.setHeader 'content-encoding', 'gzip'
       @zlib.gzip buffer, (err, result) =>
        if err?
         return @errorCallback 'GZipeError', e
        @_sendBuffer result, options.response, callback
      else
       @_sendBuffer buffer, options.response, callback

     _sendBuffer: (buf, res, callback) ->
       res.setHeader 'content-length', buf.length
       if callback?
        res.once 'finish', ->
         callback()
        res.once 'close', ->
         callback()

       res.write buf
       res.end()

     listen: ->
      @server = @http.createServer @_onRequest.bind this
      @server.listen @port

     _handlePoll: (data, options) ->
      for f in @wrappers.handleCall
       return unless f.apply this, arguments
      if not @responses[data.id]?
       @onHandleError "Poll without response: #{data.id}", data, options
       return
      @responses[data.id].setOptions options

##NodeHttpsServerPort class

    class NodeHttpsServerPort extends NodeHttpServerPort
     constructor: (options, http) ->
      super options, http
      @_key = options.key
      @_cert = options.cert

     listen: ->
      options =
       key: @_key
       cert: @_cert

      @server = @http.createServer options, @_onRequest.bind this
      @server.listen @port

#IO Module

    IO =
     addPort: (name, port) ->
      IO[name] = port

     ports:
      WorkerPort: WorkerPort
      SocketPort: SocketPort
      AjaxHttpPort: AjaxHttpPort
      NodeHttpPort: NodeHttpPort
      NodeHttpServerPort: NodeHttpServerPort
      NodeHttpsServerPort: NodeHttpsServerPort
      ServerSocketPort: ServerSocketPort

     Helpers:
      progress: (from, to, func) ->
       (progress, data) ->
        func? progress * (to - from) + from, data

     setup_____: (options) ->
      options.workers ?= []
      switch options.platform
       when 'ui'
        for worker in options.workers
         IO.addPort worker.name, new WorkerPort worker.js
        for socket in options.sockets
         IO.addPort socket.name, new SocketPort socket.url
       when 'node'
        for socket in options.listenSockets
         IO.addPort socket.name, new SocketListenPort socket.port
        for socket in options.sockets
         IO.addPort socket.name, new SocketPort socket.url
       when 'worker'
        IO.addPort 'UI', new WorkerListenPort _self

    if exports?
     module.exports = IO
    else
     _self.IO = IO


slimming SourceMap slightly further

slimming SourceMap slightly further

Source maps allow JavaScript runtimes to match running JavaScript back to
the original CoffeeScript source code that corresponds to it. In order to
produce maps, we must keep track of positions (line number, column number)
for every construct in the syntax tree, and be able to generate a map file
-- which is a compact, VLQ-encoded representation of the JSON serialization
of this information -- to write out alongside the generated JavaScript.

    {merge} = require './helpers'

LineMap
-------

Keeps track of information about column positions within a single line of
output JavaScript code. **SourceMap**s are implemented in terms of **LineMap**s.

    class LineMap
      constructor: (@line) ->
        @columns = []

      add: (column, [sourceLine, sourceColumn], options={}) ->
        return if @columns[column] and options.noReplace
        @columns[column] = {line: @line, column, sourceLine, sourceColumn}

      sourceLocation: (column) ->
        column-- until (mapping = @columns[column]) or (column <= 0)
        mapping and [mapping.sourceLine, mapping.sourceColumn]

SourceMap
---------

Maps locations in for a single generated JavaScript file back to locations in
the original CoffeeScript source file.

This is intentionally agnostic towards how a source map might be represented on
disk. Once the compiler is ready to produce a "v3"-style source map, we can walk
through the arrays of line and column buffer to produce it.

    class SourceMap
      constructor: ->
        @lines = []

Adds a mapping to this SourceMap. `sourceLocation` and `generatedLocation`
are both `[line, column]` arrays. If `options.noReplace` is true, then if there
is already a mapping for the specified `line` and `column`, this will have no
effect.

      add: (sourceLocation, generatedLocation, options = {}) ->
        [line, column] = generatedLocation
        lineMap = (@lines[line] or= new LineMap(line))
        lineMap.add column, sourceLocation, options

Look up the original position of a given `line` and `column` in the generated
code.

      sourceLocation: ([line, column]) ->
        line-- until (lineMap = @lines[line]) or (line <= 0)
        lineMap and lineMap.sourceLocation column

V3 SourceMap Generation
-----------------------

Builds up a V3 source map, returning the generated JSON as a string.
`options.sourceRoot` may be used to specify the sourceRoot written to the source
map.  Also, `options.sourceFiles` and `options.generatedFile` may be passed to
set "sources" and "file", respectively.

      generate: (options = {}, code = null) ->
        writingline       = 0
        lastColumn        = 0
        lastSourceLine    = 0
        lastSourceColumn  = 0
        needComma         = no
        buffer            = ""

        for lineMap, lineNumber in @lines when lineMap
          for mapping in lineMap.columns when mapping
            while writingline < mapping.line
              lastColumn = 0
              needComma = no
              buffer += ";"
              writingline++

Write a comma if we've already written a segment on this line.

            if needComma
              buffer += ","
              needComma = no

Write the next segment. Segments can be 1, 4, or 5 values.  If just one, then it
is a generated column which doesn't match anything in the source code.

The starting column in the generated source, relative to any previous recorded
column for the current line:

            buffer += @encodeVlq mapping.column - lastColumn
            lastColumn = mapping.column

The index into the list of sources:

            buffer += @encodeVlq 0

The starting line in the original source, relative to the previous source line.

            buffer += @encodeVlq mapping.sourceLine - lastSourceLine
            if lastSourceLine isnt mapping.sourceLine
              lastSourceLine = mapping.sourceLine
              lastSourceColumn = 0

The starting column in the original source, relative to the previous column.

            buffer += @encodeVlq mapping.sourceColumn - lastSourceColumn
            lastSourceColumn = mapping.sourceColumn
            needComma = yes

Produce the canonical JSON object format for a "v3" source map.

        v3 =
          version:    3
          file:       options.generatedFile or ''
          sourceRoot: options.sourceRoot or ''
          sources:    options.sourceFiles or ['']
          names:      []
          mappings:   buffer

        v3.sourcesContent = [code] if options.inline

        JSON.stringify v3, null, 2

Base64 VLQ Encoding
-------------------

Note that SourceMap VLQ encoding is "backwards".  MIDI-style VLQ encoding puts
the most-significant-bit (MSB) from the original value into the MSB of the VLQ
encoded value (see [Wikipedia](http://en.wikipedia.org/wiki/File:Uintvar_coding.svg)).
SourceMap VLQ does things the other way around, with the least significat four
bits of the original value encoded into the first byte of the VLQ encoded value.

      VLQ_SHIFT            = 5
      VLQ_CONTINUATION_BIT = 1 << VLQ_SHIFT             # 0010 0000
      VLQ_VALUE_MASK       = VLQ_CONTINUATION_BIT - 1   # 0001 1111

      encodeVlq: (value) ->
        answer = ''

        # Least significant bit represents the sign.
        signBit = if value < 0 then 1 else 0

        # The next bits are the actual value.
        valueToEncode = (Math.abs(value) << 1) + signBit

        # Make sure we encode at least one character, even if valueToEncode is 0.
        while valueToEncode or not answer
          nextChunk = valueToEncode & VLQ_VALUE_MASK
          valueToEncode = valueToEncode >> VLQ_SHIFT
          nextChunk |= VLQ_CONTINUATION_BIT if valueToEncode
          answer += @encodeBase64 nextChunk

        answer

Regular Base64 Encoding
-----------------------

      BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

      encodeBase64: (value) ->
        BASE64_CHARS[value] or throw new Error "Cannot Base64 encode value: #{value}"

Our API for source maps is just the `SourceMap` class.

    module.exports = SourceMap

Source maps allow JavaScript runtimes to match running JavaScript back to
the original CoffeeScript source code that corresponds to it. In order to
produce maps, we must keep track of positions (line number, column number)
for every construct in the syntax tree, and be able to generate a map file
-- which is a compact, VLQ-encoded representation of the JSON serialization
of this information -- to write out alongside the generated JavaScript.

    {merge} = require './helpers'

LineMap
-------

Keeps track of information about column positions within a single line of
output JavaScript code. **SourceMap**s are implemented in terms of **LineMap**s.

    class LineMap
      constructor: (@line) ->
        @columns = []

      add: (column, [sourceLine, sourceColumn], options={}) ->
        return if @columns[column] and options.noReplace
        @columns[column] = {line: @line, column, sourceLine, sourceColumn}

      sourceLocation: (column) ->
        column-- until (mapping = @columns[column]) or (column <= 0)
        mapping and [mapping.sourceLine, mapping.sourceColumn]

SourceMap
---------

Maps locations in for a single generated JavaScript file back to locations in
the original CoffeeScript source file.

This is intentionally agnostic towards how a source map might be represented on
disk. Once the compiler is ready to produce a "v3"-style source map, we can walk
through the arrays of line and column buffer to produce it.

    class SourceMap
      constructor: ->
        @lines = []

Adds a mapping to this SourceMap. `sourceLocation` and `generatedLocation`
are both `[line, column]` arrays. If `options.noReplace` is true, then if there
is already a mapping for the specified `line` and `column`, this will have no
effect.

      add: (sourceLocation, generatedLocation, options = {}) ->
        [line, column] = generatedLocation
        lineMap = (@lines[line] or= new LineMap(line))
        lineMap.add column, sourceLocation, options

Look up the original position of a given `line` and `column` in the generated
code.

      sourceLocation: ([line, column]) ->
        line-- until (lineMap = @lines[line]) or (line <= 0)
        lineMap and lineMap.sourceLocation column

`func` will be called once for every recorded mapping, in the order in
which they occur in the generated source.  `fn` will be passed an object
with four properties: sourceLine, sourceColumn, line, and
column.

      each: (iterator) ->
        for lineMap, lineNumber in @lines when lineMap
          for mapping in lineMap.columns when mapping
            iterator mapping

V3 SourceMap Generation
-----------------------

Builds up a V3 source map, returning the generated JSON as a string.
`options.sourceRoot` may be used to specify the sourceRoot written to the source
map.  Also, `options.sourceFiles` and `options.generatedFile` may be passed to
set "sources" and "file", respectively.

      generate: (options = {}, code = null) ->
        writingline       = 0
        lastColumn        = 0
        lastSourceLine    = 0
        lastSourceColumn  = 0
        needComma         = no
        buffer            = ""

        @each (mapping) =>
          while writingline < mapping.line
            lastColumn = 0
            needComma = no
            buffer += ";"
            writingline++

Write a comma if we've already written a segment on this line.

          if needComma
            buffer += ","
            needComma = no

Write the next segment. Segments can be 1, 4, or 5 values.  If just one, then it
is a generated column which doesn't match anything in the source code.

The starting column in the generated source, relative to any previous recorded
column for the current line:

          buffer += @encodeVlq mapping.column - lastColumn
          lastColumn = mapping.column

The index into the list of sources:

          buffer += @encodeVlq 0

The starting line in the original source, relative to the previous source line.

          buffer += @encodeVlq mapping.sourceLine - lastSourceLine
          if lastSourceLine isnt mapping.sourceLine
            lastSourceLine = mapping.sourceLine
            lastSourceColumn = 0

The starting column in the original source, relative to the previous column.

          buffer += @encodeVlq mapping.sourceColumn - lastSourceColumn
          lastSourceColumn = mapping.sourceColumn
          needComma = yes

Produce the canonical JSON object format for a "v3" source map.

        v3 =
          version:    3
          file:       options.generatedFile or ''
          sourceRoot: options.sourceRoot or ''
          sources:    options.sourceFiles or ['']
          names:      []
          mappings:   buffer

        v3.sourcesContent = [code] if options.inline

        return JSON.stringify v3, null, 2

Base64 VLQ Encoding
-------------------

Note that SourceMap VLQ encoding is "backwards".  MIDI-style VLQ encoding puts
the most-significant-bit (MSB) from the original value into the MSB of the VLQ
encoded value (see [Wikipedia](http://en.wikipedia.org/wiki/File:Uintvar_coding.svg)).
SourceMap VLQ does things the other way around, with the least significat four
bits of the original value encoded into the first byte of the VLQ encoded value.

      VLQ_SHIFT            = 5
      VLQ_CONTINUATION_BIT = 1 << VLQ_SHIFT             # 0010 0000
      VLQ_VALUE_MASK       = VLQ_CONTINUATION_BIT - 1   # 0001 1111

      encodeVlq: (value) ->
        answer = ''

        # Least significant bit represents the sign.
        signBit = if value < 0 then 1 else 0

        # The next bits are the actual value.
        valueToEncode = (Math.abs(value) << 1) + signBit

        # Make sure we encode at least one character, even if valueToEncode is 0.
        while valueToEncode or not answer
          nextChunk = valueToEncode & VLQ_VALUE_MASK
          valueToEncode = valueToEncode >> VLQ_SHIFT
          nextChunk |= VLQ_CONTINUATION_BIT if valueToEncode
          answer += @encodeBase64 nextChunk

        return answer

Regular Base64 Encoding
-----------------------

      BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

      encodeBase64: (value) ->
        BASE64_CHARS[value] or throw new Error "Cannot Base64 encode value: #{value}"

Our API for source maps is just the `SourceMap` class.

    module.exports = SourceMap