if self.selected: # emit light if the node is selected

from OpenGL.GL import *
from primitive import G_OBJ_CUBE
import numpy
import math
from transformation import scaling, translation

EPSILON = 0.000001

class AABB(object):

    def __init__(self, center, size):
        """ Axis aligned bounding box.
            This is a box that is aligned with the XYZ axes of the model coordinate space.
            It's used for collision detection with rays for selection.
            It could also be used for rudimentary collision detection between nodes. """
        self.center = numpy.array(center)
        self.size = numpy.array(size)

    def intersects_aabb(self, other):
        """ returns True <=> this AABB intersects with the other AABB
            Consumes: other -> another AABB """
        diff = [a - b for a, b in zip(self.center, other.center)]

        if abs(diff[0]) > (size[0] + other.size[0]): return False
        if abs(diff[1]) > (size[1] + other.size[1]): return False
        if abs(diff[2]) > (size[2] + other.size[2]): return False

        return True

    def ray_hit(self, origin, direction, modelmatrix):
        """ Returns True <=> the ray hits the AABB
            Consumes: origin, direction -> describes the ray
                      modelmatrix       -> the matrix to convert from ray coordinate space to AABB coordinate space """
        aabb_min = self.center - self.size
        aabb_max = self.center + self.size
        tmin = 0.0
        tmax = 100000.0

        obb_pos_worldspace = numpy.array([modelmatrix[3, 0], modelmatrix[3, 1], modelmatrix[3, 2]])
        delta = (obb_pos_worldspace - origin)

        # test intersection with 2 planes perpendicular to OBB's x-axis
        xaxis = numpy.array((modelmatrix[0, 0], modelmatrix[1, 0], modelmatrix[2, 0]))

        e = numpy.dot(xaxis, delta)
        f = numpy.dot(direction, xaxis)
        if math.fabs(f) > 0.0 + EPSILON:
            t1 = (e + aabb_min[0])/f
            t2 = (e + aabb_max[0])/f
            if t1 > t2:
                t1, t2 = t2, t1
            if t2 < tmax:
                tmax = t2
            if t1 > tmin:
                tmin = t1
            if tmax < tmin:
                return (False, 0)
        else:
            if (-e + aabb_min[0] > 0.0 + EPSILON) or (-e+aabb_max[0] < 0.0 - EPSILON):
                return False, 0

        yaxis = numpy.array((modelmatrix[0, 1], modelmatrix[1, 1], modelmatrix[2, 1]))
        e = numpy.dot(yaxis, delta)
        f = numpy.dot(direction, yaxis)
        # intersection in y
        if math.fabs(f)> 0.0 + EPSILON:
            t1 = (e + aabb_min[1])/f
            t2 = (e + aabb_max[1])/f
            if t1 > t2:
                t1, t2 = t2, t1
            if t2 < tmax:
                tmax = t2
            if t1 > tmin:
                tmin = t1
            if tmax < tmin:
                return (False, 0)
        else:
            if (-e + aabb_min[1] > 0.0 + EPSILON) or (-e+aabb_max[1] < 0.0 - EPSILON):
                return False, 0

        # intersection in z
        zaxis = numpy.array((modelmatrix[0, 2], modelmatrix[1, 2], modelmatrix[2, 2]))
        e = numpy.dot(zaxis, delta)
        f = numpy.dot(direction, zaxis)
        if math.fabs(f)> 0.0 + EPSILON:
            t1 = (e + aabb_min[2])/f
            t2 = (e + aabb_max[2])/f
            if t1 > t2:
                t1, t2 = t2, t1
            if t2 < tmax:
                tmax = t2
            if t1 > tmin:
                tmin = t1
            if tmax < tmin:
                return (False, 0)
        else:
            if (-e + aabb_min[2] > 0.0 + EPSILON) or (-e+aabb_max[2] < 0.0 - EPSILON):
                return False, 0

        return True, tmin

    def render(self):
        """ render the AABB. This can be useful for debugging purposes """
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        glTranslated(self.center[0], self.center[1], self.center[2]);
        glScaled(2*self.size[0], 2*self.size[1], 2*self.size[2]);
        glCallList(G_OBJ_CUBE);
        glPopMatrix();
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);


-module(torrent_client_sup).

-behaviour(supervisor).

-export([start_link/0, init/1]).

%% Helper macro for declaring children of supervisor
-define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 5000, Type, [I]}).

%% ===================================================================
%% API functions
%% ===================================================================

start_link() ->
    supervisor:start_link({local, ?MODULE}, ?MODULE, []).

%% ===================================================================
%% Supervisor callback
%% ===================================================================

init([]) ->
    ok = application:ensure_started(inets),
    ok = application:ensure_started(crypto),
    ok = application:ensure_started(gproc),

    Rand = crypto:rand_bytes(12),
    ClientID = <<"-ET0000-", Rand/binary>>,
    ok = application:set_env(torrent_client, peer_id, ClientID),

    {ok, { {simple_one_for_one, 5, 10}, [?CHILD(torrent_client, worker)]} }.


{application, torrent_client,
 [
  {description, ""},
  {vsn, "1"},
  {registered, []},
  {applications, [
                  kernel,
                  stdlib
                 ]},
  {mod, { torrent_client, []}},
  {env, []}
 ]}.


markdown        : redcarpet
pygments        : true
contact         : "aosa@aosabook.org"


def picking(self, start, direction, mat):

""" Return whether or not the ray hits the object

Consume:  start, direction    the ray to check

mat                 the modelview matrix to transform the ray by """

s = self.scale_mult * 1.1 if up else 0.9

self.scalemat = numpy.dot(self.scalemat, scaling([s, s, s]))

import sys
import numpy
from node import Sphere, Cube
class Scene(object):
    """ Base class for scene nodes.
        Scene nodes currently only include primitives """

    # the default depth from the camera to place an object at
    PLACE_DEPTH = 15.0

    def __init__(self):
        """ Initialize the Scene """
        # The scene keeps a list of nodes that are displayed
        self.node_list = list()
        # Keep track of the currently selected node.
        # Actions may depend on whether or not something is selected
        self.selected_node = None

    def render(self):
        """ Render the scene. This function simply calls the render function for each node. """
        for node in self.node_list:
            node.render()

    def add_node(self, node):
        """ Add a new node to the scene """
        self.node_list.append(node)

    def picking(self, start, direction, inv_modelview):
        """ Execute selection.
            Consume: start, direction describing a Ray
                     mat              is the inverse of the current modelview matrix for the scene """
        if self.selected_node is not None:
            self.selected_node.select(False)
            self.selected_node = None

        # Keep track of the closest hit.
        mindist, closest_node  = sys.maxint, None
        for node in self.node_list:
            hit, distance = node.picking(start, direction, inv_modelview)
            if hit and distance < mindist:
                mindist, closest_node = distance, node

        # If we hit something, keep track of it.
        if closest_node is not None:
            closest_node.select()
            closest_node.depth = mindist
            closest_node.selected_loc = start + direction * mindist
            self.selected_node = closest_node

    def move(self, start, direction, inv_modelview):
        """ Move the selected node, if there is one.
            Consume:  start, direction  describes the Ray to move to
                      mat               is the modelview matrix for the scene """
        if self.selected_node is None: return

        # Find the current depth and location of the selected node
        node = self.selected_node
        depth = node.depth
        oldloc = node.selected_loc

        # The new location of the node is the same depth along the new ray
        newloc = (start + direction * depth)

        # transform the translation with the modelview matrix
        translation = newloc - oldloc
        pre_tran = numpy.array([translation[0], translation[1], translation[2], 0])
        translation = inv_modelview.dot(pre_tran)

        # translate the node and track its location
        node.translate(translation[0], translation[1], translation[2])
        node.selected_loc = newloc

    def place(self, shape, start, direction, inv_modelview):
        """ Place a new node.
            Consume:  shape             the shape to add
                      start, direction  describes the Ray to move to
                      mat               is the modelview matrix for the scene """
        new_node = None
        if shape == 'sphere': new_node = Sphere()
        elif shape == 'cube': new_node = Cube()

        self.add_node(new_node)

        # place the node at the cursor in camera-space
        translation = (start + direction * self.PLACE_DEPTH)

        # convert the translation to world-space
        pre_tran = numpy.array([translation[0], translation[1], translation[2], 1])
        translation = inv_modelview.dot(pre_tran)

        new_node.translate(translation[0], translation[1], translation[2])

    def rotate_color(self, forwards):
        """ Rotate the color of the currently selected node """
        if self.selected_node is None: return
        self.selected_node.rotate_color(forwards)


import sys, os, BaseHTTPServer

class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):

    # Root of files being served.
    Root_Directory = None

    # Is debugging output on?
    Debug = False

    # HTTP error codes.
    ERR_NO_PERM   = 403
    ERR_NOT_FOUND = 404
    ERR_INTERNAL  = 500

    # How to display a single item in a directory listing.
    Listing_Item = "
%s
"

    # How to display a whole page of listings.
    Listing_Page = """\

Listing for %(path)s

        %(filler)s

        """

    # Classify and handle request.
    def do_GET(self):

        self.log("path is '%s'" % self.path)

        # Handle any errors that arise.
        try:

            # Class not yet initialized.
            if self.Root_Directory is None:
                self.err_internal("Root directory not set")
                return

            # Figure out what exactly is being requested.
            abs_path = self.create_abs_path()
            self.log("abs_path is '%s'" % abs_path)

            # It isn't below the root path.
            if not self.is_parent_dir(self.Root_Directory, abs_path):
                self.log("abs_path not below root directory")
                msg = "Path '%s' not below root directory '%s'" % \
                      (abs_path, self.Root_Directory)
                self.err_no_perm(msg)

            # It doesn't exist.
            elif not os.path.exists(abs_path):
                self.log("abs_path doesn't exist")
                self.err_not_found(abs_path)

            # It's a file.
            elif os.path.isfile(abs_path):
                self.log("abs_path is a file")
                self.handle_file(abs_path)

            # It's a directory.
            elif os.path.isdir(abs_path):
                self.log("abs_path is a directory")
                self.handle_dir(abs_path)

            # ...we can't tell.
            else:
                self.log("can't tell what abs_path is")
                self.err_not_found(abs_path)

        # Handle general errors.
        except Exception, msg:
            self.err_internal("Unexpected exception: %s" % msg)

    def create_abs_path(self):
        head = os.path.abspath(self.Root_Directory)
        result = os.path.normpath(head + self.path)
        return result

    def is_parent_dir(self, left, right):
        return os.path.commonprefix([left, right]) == left

    def handle_file(self, abs_path):
        try:
            input = file(abs_path, "r")
            content = input.read()
            input.close()
            self.send_content(content)
        except IOError, msg:
            msg = "'%s' cannot be read: %s" % (self.path, msg)
            self.err_no_perm(msg)

    def handle_dir(self, abs_path):
        try:
            listing = os.listdir(abs_path)
            filler = '\n'.join([(self.Listing_Item % item) for item in listing])
            content = self.Listing_Page % {'path'   : self.path,
                                           'filler' : filler}
            self.send_content(content)
        except IOError, msg:
            msg = "'%s' cannot be listed: %s" % (self.path, msg)
            self.send_error(ERR_NO_PERM, msg)

    # Send actual content.
    def send_content(self, content):
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.send_header("Content-Length", str(len(content)))
        self.end_headers()
        self.wfile.write(content)

    # Report internal errors.
    def err_internal(self, msg):
        self.send_error(self.ERR_INTERNAL, msg)

    # Handle missing object errors.
    def err_not_found(self, abs_path):
        self.send_error(self.ERR_NOT_FOUND, "'%s' not found" % self.path)

    # Handle no permission errors.
    def err_no_perm(self, msg):
        self.send_error(self.ERR_NO_PERM, msg)

    # Write a log message if in debugging mode
    def log(self, msg):
        if self.Debug:
            print msg

#----------------------------------------------------------------------

if __name__ == '__main__':

    # Main libraries
    import getopt

    # How to use
    Usage = "server.py [-v] root_directory"

    # Handle command-line arguments
    options, rest = getopt.getopt(sys.argv[1:], "v")

    for (flag, arg) in options:
        if flag == "-v":
            RequestHandler.Debug = True
        else:
            print >> sys.stderr, Usage
            sys.exit(1)

    if not rest:
        print >> sys.stderr, Usage
        sys.exit(1)
    root = os.path.abspath(rest[0])
    if not os.path.isdir(root):
        print >> sys.stderr, "No such directory '%s'" % root
        sys.exit(1)
    RequestHandler.Root_Directory = root

    # Create and run server.
    server_address = ('', 8080)
    server = BaseHTTPServer.HTTPServer(server_address, RequestHandler)
    server.serve_forever()


import logging
from network import Node
from statemachine import sequence_generator

# Remove from final copy:
#  - logging

class Member(Node):

    def __init__(self):
        Node.__init__(self)

    def start(self, execute_fn, initial_value=None):
        self.execute_fn = execute_fn
        self.state = initial_value
        self.run()

    def invoke(self, input):
        self.state, output = self.execute_fn(self.state, input)
        return output

    def do_INVOKE(self, input, cid, caller):
        self.send([caller], 'INVOKED', output=self.invoke(input))

if __name__ == "__main__":
    logging.basicConfig(
        format="%(asctime)s %(name)s %(message)s", level=logging.DEBUG)
    member = Member()
    print member.address
    member.start(sequence_generator, initial_value=0)

# tests

import unittest
import threading

class FakeClient(Node):

    def do_INVOKED(self, output):
        self.output = output
        self.stop()

class MemberTests(unittest.TestCase):

    def test_invoke(self):
        member = Member()
        client = FakeClient()
        client.member = member
        memberthd = threading.Thread(target=member.start, args=(sequence_generator, 0,))
        memberthd.daemon = 1
        memberthd.start()
        client.send([member.address], 'INVOKE', input=5, caller=client.address)
        client.run()
        self.assertEqual(client.output, [0, 1, 2, 3, 4])


import sys
import math
from collections import defaultdict

from OpenGLContext import quaternion
from OpenGLContext.move import trackball
from OpenGLContext.arrays import *

from OpenGL.GLUT import *
from OpenGL.GL import *
from OpenGL.GLU import *

class Interaction(object):

    def __init__(self):
        """ Handles user interaction """
        # currently pressed mouse button
        self.pressed = None
        # current rotation, stored as quaternion
        self.rotation = quaternion.fromEuler()
        self.camera_loc = array( [0, 0, 0, 0], 'd')
        # the trackball to calculate rotation
        self.trackball = None
        # the current mouse location
        self.mouse_loc = None
        # Unsophisticated callback mechanism
        self.callbacks = defaultdict(list)

    def registerCallback(self, name, func):
        """ registers a callback for a certain event """
        self.callbacks[name].append(func)

    def trigger(self, name, *args, **kwargs):
        """ calls a callback, forwards the args """
        for func in self.callbacks[name]:
            func(*args, **kwargs)

    def translate(self, x, y, z):
        """ translate the camera """
        self.camera_loc[0] += x
        self.camera_loc[1] += y
        self.camera_loc[2] += z

    def MouseButton(self, button, mode, x, y):
        """ Called when the mouse button is pressed or released """
        xSize, ySize = glutGet( GLUT_WINDOW_WIDTH ), glutGet( GLUT_WINDOW_HEIGHT )
        y = ySize - y # invert the y coordinate because OpenGL is inverted
        self.mouse_loc = (x, y)

        if mode == GLUT_DOWN:
            self.pressed = button
            if button == GLUT_RIGHT_BUTTON:
                self.trackball = trackball.Trackball(self.camera_loc, self.rotation, (0,0,0), x, y, xSize, ySize)
            elif button == GLUT_LEFT_BUTTON: # picking
                self.trigger('picking', x, y)
            elif button == 3: # scroll up
                self.translate(0, 0, -1.0)
            elif button == 4: # scroll up
                self.translate(0, 0, 1.0)
        else: # mouse button release
            self.trackball = None
            self.pressed = None
        glutPostRedisplay()

    def MouseMove(self, x, screen_y):
       """ Called when the mouse is moved """
       xSize, ySize = glutGet( GLUT_WINDOW_WIDTH ), glutGet( GLUT_WINDOW_HEIGHT )
       y = ySize - screen_y # invert the y coordinate because OpenGL is inverted
       if self.pressed is not None:
           if self.pressed == GLUT_RIGHT_BUTTON and self.trackball is not None:
               # ignore the updated camera loc because we want to always rotate around the origin
               _, self.rotation = self.trackball.update(x, y)
           elif self.pressed == GLUT_LEFT_BUTTON:
               self.trigger('move', x, y)
           elif self.pressed == GLUT_MIDDLE_BUTTON:
               dx = self.mouse_loc[0] - x
               dy = self.mouse_loc[1] - y
               self.translate(dx/60.0, dy/60.0, 0)
           else:
               pass
           glutPostRedisplay()
       self.mouse_loc = (x, y)

    def Keyboard(self, key, x, screen_y):
        """ Called on keyboard input from the user """
        xSize, ySize = glutGet( GLUT_WINDOW_WIDTH ), glutGet( GLUT_WINDOW_HEIGHT )
        y = ySize - screen_y
        if key == 's':
            self.trigger('place', 'sphere', x, y)
        elif key == 'c':
            self.trigger('place', 'cube', x, y)
        elif key == GLUT_KEY_UP:
            self.trigger('color', True)
        elif key == GLUT_KEY_DOWN:
            self.trigger('color', False)
        glutPostRedisplay()

    def register(self):
        """ register callbacks with glut """
        glutMouseFunc(self.MouseButton)
        glutMotionFunc(self.MouseMove)
        glutKeyboardFunc(self.Keyboard)
        glutSpecialFunc(self.Keyboard)
        glutPassiveMotionFunc(None)


# transform the modelview matrix by the current scale and translation

newmat = numpy.dot(self.translation, numpy.dot(mat, self.scalemat))

results = self.aabb.ray_hit(start, direction, newmat)

keep keep keep keep replace replace replace replace replace replace replace replace keep keep keep keep

# transform the modelview matrix by the current translation

newmat = numpy.dot(mat, self.translation)


'''Simple client that sends data, and waits for an echo.'''

import sys, socket

# How much data to receive at one time?
size = 1024

# Who to talk to, and what to say?
host, port, message = sys.argv[1], int(sys.argv[2]), sys.argv[3]

# Create a socket, and connect to a server.
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))

# Send message.
s.send(sys.argv[3])

# Wait for it to be echoed back.
data = s.recv(size)
print 'client received', `data`

# Put our toys away.
s.close()


require 'catechism'

describe 'using catechism matchers' do
  class Harness; end

  it 'lets you test equality' do
    expect(1).to_equal(1)
    expect(2).not.to_equal(1)
  end

  it 'lets you test nilness' do
    expect(nil).to_be_nil
    expect(1).not.to_be_nil
  end

  it 'lets you test exception raising' do
    expect { raise 'hands' }.to_raise_error
    expect { 3 + 1 }.not.to_raise_error
  end

  it 'lets you test that an instance receives a message' do
    tacos = Harness.new
    expect { tacos.sauce }.to_send(:sauce).to(tacos)
    expect { tacos.to_s }.not.to_send(:sauce).to(tacos)
  end

  it 'lets you test that a class receives a message' do
    expect { Harness.to_s }.to_send(:to_s).to(Harness)
    expect { Harness.inspect }.not.to_send(:to_s).to(Harness)
  end

  it 'lets you test that an instance receives a message with arguments' do
    pants = Object.new
    expect {
      pants.tuck_into('socks')
    }.to_send(:tuck_into).with('socks').to(pants)

    expect {
      pants.tuck_into('ears')
    }.not.to_send(:tuck_into).with('socks').to(pants)
  end
end


def picking(self, start, direction, inv_modelview):

Consume: start, direction describing a Ray

mat              is the inverse of the current modelview matrix for the scene """

keep keep keep replace keep keep keep keep

def picking(self, start, direction, mat):

#! /usr/bin/env python
from OpenGLContext import testingcontext, quaternion, contextdefinition
BaseContext = testingcontext.getInteractive()

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from OpenGLContext.arrays import *
from numpy.linalg import norm
import numpy

from interaction import Interaction
from primitive import InitPrimitives, G_OBJ_PLANE
from node import Sphere, Cube
from scene import Scene
from transformation import make_perspective

class TestContext(BaseContext):
    def OnInit(self):
        """ Initialize the context. """
        InitPrimitives()
        self.interaction = Interaction()
        self.interaction.register()
        self.scene = Scene()

        self.interaction.registerCallback('picking', self.picking)
        self.interaction.registerCallback('move', self.move)
        self.interaction.registerCallback('place', self.place)
        self.interaction.registerCallback('color', self.color)

        self.InitialScene()
        self.inverseModelView = numpy.identity(4)

    def Render(self, mode = None):
        """ The render pass for the scene """
        BaseContext.Render(self, mode)

        self.initView()

        # Enable lighting and color
        glEnable(GL_LIGHTING)
        glEnable(GL_LIGHT0)
        glLightfv(GL_LIGHT0, GL_POSITION, GLfloat_4(0, 0, 1, 0))
        glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, GLfloat_3(0, 0, -1))

        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)
        glEnable( GL_COLOR_MATERIAL)

        glClearColor(0.4, 0.4, 0.4, 0.0);
        glClear(GL_COLOR_BUFFER_BIT)

        # Load the modelview matrix from the current state of the trackball
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix()
        glLoadIdentity()
        loc = self.interaction.camera_loc
        glTranslated(-loc[0], -loc[1], -loc[2])
        glMultMatrixf(self.interaction.rotation.matrix(inverse=False))

        # store the inverse of the current modelview.
        mat = numpy.array(glGetFloatv( GL_MODELVIEW_MATRIX ))
        self.inverseModelView = numpy.linalg.inv(numpy.transpose(mat))

        # Render the scene. This will call the render function for each object in the scene
        self.scene.render()

        # draw the grid
        glDisable(GL_LIGHTING)
        glCallList(G_OBJ_PLANE)
        glPopMatrix()

    def initView(self):
        xSize, ySize = glutGet( GLUT_WINDOW_WIDTH ), glutGet( GLUT_WINDOW_HEIGHT )
        aspect_rat = float(xSize) / float(ySize)

        # load the projection matrix. Always the same
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();

        glViewport(0, 0, xSize, ySize);
        gluPerspective(70, aspect_rat , 0.1, 1000.0)
        glTranslated(0, 0, -15);

    def InitialScene(self):
        cube_node = Cube()
        cube_node.translate(2, 0, 2)
        cube_node.color_index = 2
        self.scene.add_node(cube_node)

        cube_node = Sphere()
        cube_node.translate(-2, 0, 2)
        cube_node.color_index = 3
        self.scene.add_node(cube_node)

        cube_node = Sphere()
        cube_node.translate(-2, 0, -2)
        cube_node.color_index = 1
        self.scene.add_node(cube_node)

    def getRay(self, x, y):
        """ Generate a ray beginning at the near plane, in the direction that the x, y coordinates are facing
            Consumes: x, y coordinates of mouse on screen
            Return: start, direction of the ray """
        self.initView()

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity()

        # get two points on the line.
        start = array(gluUnProject(x, y, 0.001))
        end = array(gluUnProject(x, y, 0.999))

        # convert those points into a ray
        direction = end - start
        direction = direction / norm(direction)

        return (start, direction)

    def picking(self, x, y):
        """ Execute picking of an object. Selects an object in the scene.
            Consumes: x, y coordinates of the mouse on the screen """
        start, direction = self.getRay(x, y)
        self.scene.picking(start, direction, self.inverseModelView)

    def move(self, x, y):
        """ Execute a move command on the scene.
            Consumes: x, y coordinates of the mouse on the screen """
        start, direction = self.getRay(x, y)
        self.scene.move(start, direction, self.inverseModelView)

    def place(self, shape, x, y):
        """ Execute a placement of a new primitive into the scene.
            Consumes: x, y coordinates of the mouse on the screen """
        start, direction = self.getRay(x, y)
        self.scene.place(shape, start, direction, self.inverseModelView)

    def color(self, forwards):
        self.scene.rotate_color(forwards)

if __name__=="__main__":
    TestContext.ContextMainLoop( definition = contextdefinition.ContextDefinition(size = (500,500),))


#!/usr/bin/env ruby
lib = File.expand_path('../../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require "catechism"
Catechism::Cli.start


mindist, closest_node  = sys.maxint, None

hit, distance = node.picking(start, direction, inv_modelview)

keep keep keep keep keep replace keep keep keep

hit, distance = node.picking(start, direction, mat)

import numpy

def translation(displacement):
  t = numpy.identity(4)
  t[3, 0] = displacement[0]
  t[3, 1] = displacement[1]
  t[3, 2] = displacement[2]
  return t

def scaling(scale):
  s = numpy.identity(4)
  s[0, 0] = scale[0]
  s[1, 1] = scale[1]
  s[2, 2] = scale[2]
  return s

def make_perspective(fov, aspect, near, far):
    fov = fov * math.pi / 180;
    f = 1/tan(fov/2);
    persp_mat = numpy.zeros((4, 4))
    persp_mat[0][0] = f/aspect;
    persp_mat[0][1] = 0;
    persp_mat[0][2] = 0;
    persp_mat[0][3] = 0;

    persp_mat[1][0] = 0;
    persp_mat[1][1] = f;
    persp_mat[1][2] = 0;
    persp_mat[1][3] = 0;

    persp_mat[2][0] = 0;
    persp_mat[2][1] = 0;
    persp_mat[2][2] = (far+near)/(near-far);
    persp_mat[2][3] = (2*far*near)/(near-far);

    persp_mat[3][0] = 0;
    persp_mat[3][1] = 0;
    persp_mat[3][2] = -1;
    persp_mat[3][3] = 0;

    return numpy.transpose(persp_mat)


*.gem
*.rbc
.bundle
.config
.yardoc
Gemfile.lock
InstalledFiles
_yardoc
coverage
doc/
lib/bundler/man
pkg
rdoc
spec/reports
test/tmp
test/version_tmp
tmp


---
---
<!DOCTYPE html>

    {% include header.html %}

{{page.title}}

          {{content}}

      {% include footer.html %}


import logging

class Member(object):  # TODO: rename

    def __init__(self, node):
        self.node = node
        self.address = self.node.address
        self.components = []

    def register(self, component):
        self.components.append(component)
        self.node.register(component)

    def unregister(self, component):
        self.components.remove(component)
        self.node.unregister(component)

    def event(self, message, **kwargs):
        method = 'on_' + message + '_event'
        for comp in self.components:
            if hasattr(comp, method):
                getattr(comp, method)(**kwargs)

class Component(object):  # TODO: rename

    def __init__(self, member):
        self.member = member
        self.member.register(self)
        self.address = member.address
        self.logger = logging.getLogger("%s.%s" % (self.address, self.__class__.__name__))

    def event(self, message, **kwargs):
        self.member.event(message, **kwargs)

    def send(self, destinations, action, **kwargs):
        self.member.node.send(destinations, action, **kwargs)

    def set_timer(self, seconds, callable):
        # TODO: refactor to attach timer to this component, not address
        return self.member.node.set_timer(seconds, callable)

    def cancel_timer(self, timer):
        self.member.node.cancel_timer(timer)

    def stop(self):
        self.member.unregister(self)


import numpy
def translation(displacement):
t = numpy.identity(4)
t[3, 0] = displacement[0]
t[3, 1] = displacement[1]
t[3, 2] = displacement[2]
return t
def scaling(scale):

keep keep keep keep replace replace replace keep keep keep

t[0, 3] = displacement[0]
t[1, 3] = displacement[1]
t[2, 3] = displacement[2]


from collections import defaultdict
from protocol import ScoutId
from member import Component

class Scout(Component):

    PREPARE_RETRANSMIT = 1

    def __init__(self, member, leader, ballot_num, peers):
        super(Scout, self).__init__(member)
        self.leader = leader
        self.scout_id = ScoutId(self.address, ballot_num)
        self.ballot_num = ballot_num
        self.pvals = defaultdict()
        self.accepted = set([])
        self.peers = peers
        self.quorum = len(peers) / 2 + 1
        self.retransmit_timer = None

    def start(self):
        self.logger.info("scout starting")
        self.send_prepare()

    def send_prepare(self):
        self.send(self.peers, 'PREPARE',  # p1a
                       scout_id=self.scout_id,
                       ballot_num=self.ballot_num)
        self.retransmit_timer = self.set_timer(
            self.PREPARE_RETRANSMIT, self.send_prepare)

    def finished(self, adopted, ballot_num):
        self.cancel_timer(self.retransmit_timer)
        self.logger.info(
            "finished - adopted" if adopted else "finished - preempted")
        self.leader.scout_finished(adopted, ballot_num, self.pvals)
        self.stop()

    def do_PROMISE(self, scout_id, acceptor, ballot_num, accepted):  # p1b
        if scout_id != self.scout_id:
            return
        if ballot_num == self.ballot_num:
            self.logger.info("got matching promise; need %d" %
                                  self.quorum)
            self.pvals.update(accepted)
            self.accepted.add(acceptor)
            if len(self.accepted) >= self.quorum:
                # We're adopted; note that this does *not* mean that no other leader is active.
                # Any such conflicts will be handled by the commanders.
                self.finished(True, ballot_num)
        else:
            # ballot_num > self.ballot_num; responses to other scouts don't
            # result in a call to this method
            self.finished(False, ballot_num)


from util import defaultlist, view_primary
from protocol import Ballot
from member import Component
from scout import Scout
from commander import Commander

class Leader(Component):

    HEARTBEAT_INTERVAL = 1

    def __init__(self, member, unique_id, commander_cls=Commander, scout_cls=Scout):
        super(Leader, self).__init__(member)
        self.ballot_num = Ballot(0, unique_id)
        self.active = False
        self.proposals = defaultlist()
        self.commander_cls = commander_cls
        self.commanders = {}
        self.scout_cls = scout_cls
        self.scout = None
        self.peers = None

    def on_view_change_event(self, viewchange):
        self.peers = viewchange.peers
        is_primary = view_primary(viewchange.viewid, viewchange.peers) == self.address
        self.is_primary = is_primary
        if is_primary:
            if not self.scout and not self.active:
                self.spawn_scout()
        else:
            if self.scout:
                self.scout.finished(False, None)
                # .. which eventually calls self.preempted
            elif self.active:
                self.preempted(None)

    def spawn_scout(self):
        assert not self.scout
        sct = self.scout = self.scout_cls(self.member, self, self.ballot_num, self.peers)
        sct.start()

    def scout_finished(self, adopted, ballot_num, pvals):
        self.scout = None
        if adopted:
            # pvals is a defaultlist of (slot, proposal) by ballot num; we need the
            # highest ballot number for each slot.  TODO: this is super
            # inefficient!
            last_by_slot = defaultlist()
            for b, s in reversed(sorted(pvals.keys())):
                p = pvals[b, s]
                if last_by_slot[s] is None:
                    last_by_slot[s] = p
            for s, p in enumerate(last_by_slot):
                if p is not None:
                    self.proposals[s] = p
            for s, p in enumerate(self.proposals):
                if p is not None:
                    self.spawn_commander(ballot_num, s, p)
            self.logger.info("leader becoming active")
            self.active = True
        else:
            self.preempted(ballot_num)

    def preempted(self, ballot_num):
        # ballot_num is None when we are preempted by a view change
        if ballot_num:
            self.logger.info("leader preempted by %s" % (ballot_num.leader,))
        else:
            self.logger.info("leader preempted by view change")
        self.active = False
        self.ballot_num = Ballot(
            (ballot_num if ballot_num else self.ballot_num).n + 1, self.ballot_num.leader)
        # if we're the primary for this view, re-scout immediately
        if not self.scout and self.is_primary:
            self.logger.info("re-scouting as the primary for this view")
            self.spawn_scout()

    def spawn_commander(self, ballot_num, slot, proposal):
        cmd = self.commander_cls(self.member, self, ballot_num, slot, proposal, self.peers)
        if cmd.commander_id in self.commanders:
            return
        print "set", cmd.commander_id
        self.commanders[cmd.commander_id] = cmd
        cmd.start()

    def commander_finished(self, commander_id, ballot_num, preempted):
        print "del", commander_id
        del self.commanders[commander_id]
        if preempted:
            self.preempted(ballot_num)

    def do_PROPOSE(self, slot, proposal):
        if self.proposals[slot] is None:
            if self.active:
                self.proposals[slot] = proposal
                self.spawn_commander(self.ballot_num, slot, proposal)
            else:
                if not self.scout:
                    self.logger.warning(
                        "got PROPOSE when not active - scouting")
                    self.spawn_scout()


<link href="{{page.root}}/css/bootstrap/bootstrap.css" rel="stylesheet" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="{{page.root}}/css/bootstrap/bootstrap-responsive.css" rel="stylesheet" />
<meta http-equiv="last-modified" content="{{site.timestamp}}" />
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
  <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->


def make_perspective(fov, aspect, near, far):


'''Simple client that sends data read from standard input.'''

import sys
import socket

# Who to talk to, and what to say?
host, port = '', int(sys.argv[1])

# Create a socket, and connect to a server.
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))

# Send message.
data = sys.stdin.read()
s.send(data)

# Put our toys away.
s.close()


# A Torrent Client

## How The Torrent Protocol Works

To share a file using the torrent system, first someone has to construct a `.torrent` file that describes the content of the file being shared.  It uses a kind of binary JSON format called bencode.  The contents of the `.torrent` file describes the file name, size, block size, and a list of SHA1-hash values for each block of data in the file.  The block size is decided by whoever creates the torrent file, but it should be bigger than 32k, and also so large that there are no more than ~4000 block all in all.  Since each SHA1-hash is 20 bytes, this leaves the resulting torrent file comfortably below 100k, which is the recommended maximum.  The SHA1-hash of the torrent file itself (the hash of hashes) is called the *Info Hash*, and is used to identify the file being shared as a whole.

A set of running torrent clients which all have a copy of the same torrent file is called a *swarm*.  Each agent in the swarm is called a *peer*.  Some peers will have all the blocks (called *seeders*), and some will just have a subset (called *leechers*).  The shared goal of the swarm is to help all the peers to get a complete copy of the original file.

> Now, you might say "why not just download the file from the original seeder?"

> The issue is that if a million people want to download a 400GB disk image, then your DSL line might get swamped quite quickly.  So, the idea is to share it with just a few peers, assuming they will also also share it with a few other peers, and quickly this leaves everyone better off.  Not only does this leave the original seeder off a huge bill from her ISV, it also means that the downloaders may be able to ultimately download most of the file from a closer peer, yielding better download speed.

> For instance, if you are making Linux distributions, all your downloaders can cooperate to download quicker, all the while saving on the bill you need to pay your ISV.

To share the file with anyone however, you need to know who is part of the swarm, and for this you need a *tracker*.  A tracker a web server that all the peers will contact to register, and ask who else is part of the swarm for a given torrent file as identified by the info hash.  The tracker doesn't even need to know the contents of the `.torrent` file, but just keeps a list of *peer-id* (a 20-byte random number) and *host:port* for all the peers interested in a given info hash.  The URL of the tracker is also included in the `.torrent` file.

>There are other ways to form swarms than using a HTTP-based tracker, one of which is known as DHT (for Distributed Hash Table).  Except for this paragraph, we'll only cover HTTP based trackers.
>DHT work by forming a global network of all torrent peers in the world, and using them much like we use DNS.  In the DHT network, all nodes participate as routers for the peers it knows, and as trackers for info hashes that "close to" the node's own peer id (for some definition of "close to").

Ideally, all the peers in a swarm can accept connections on the public internet, so that other peers can contact them.  The peers that can accept connections are at an advantage because they can get more peers, but the system will work fine if just some peers are accessible on the internet.   Once connected, the peer to peer relationship is completely symmetrical, as is the protocol they speak to each other.

To reduce complexity and code size, this torrent client does not accept connections from the internet.  Also, since you're likely to be running the examples from behind a firewall, it may not always work.

## A Few Notes on Reading Erlang

I'll assume that you don't know Erlang, and so here are a few hints to how to read the code that will come ahead.  If you're new to Erlang, please take some time to understand these rules, and you'll be much happier going forward:

- Expressions that are evaluated in sequence are separated by commas.  Semi-colons are used in between the individual cases of a `case` statement, of which erlang has several kinds.  Function definitions (and other top-level declarations) are terminated with a period.  This is consistenly employed, but somewhat unorthodox.  Take your time to locate the semi-colon and the period in this code defining a speed function:

````erlang
speed(Time, Distance) ->
  case Time of
    0 -> io:format("very fast!\n"),
         infinity;
    _ -> Distance / Time
  end.
````
- Unsurprisingly, code is organized in modules, and in order to call a function in another module you write `module:function(...)`.  When calling local function, you don't need to prefix the function call with the module name.  The "return value" of a function is simply the value of the last expression of its evaluation; there is no `return Foo` statement.
- A constant string is called an *atom* in Erlang, and usually looks like an all-lowercase identifier `like_this`.  Atoms are used as you would normally use enums in other languages: they are globally unique, and so they're fast to compare for equality.  Regardless of it's resemblance with identifiers in most languages it is not an identifier, it's just a constant string!  You can enclose it in single quotes if you want `'like_this'`, but that is only useful for atoms containing non-lowercase letters.  In the above code, `infinity` is an atom. In fact, in Erlang the boolean values `true` and `false` are also just atoms.
- Variables are identifiers that start with a capital letter, `LikeThis`.  That's quite unlike languages like Java and Ruby, where uppercase identifiers signal constant-ness.
- All assignments are final; so a variable cannot change.  As such, they are not really variables, but that's a discussion I won't take here.  Becaus of this single-assignment rule, you will often see the same variable name with 1, 2, or 3 attached, such as `State1` or `State2` to signify different "versions" of the same value.
- Tuples `{1,2,3}` are widely used for simple structures.  It's a common idiom to return a 2-tuple with an `ok` atom in the first position, such as `{ok, Value}` for success, and `{error, Reason}` for failure.
- All assignments use desctructuring (pattern matching), so the assignment below succeeds iff the `foo` function returns a 2-tuple, in which the first element is the atom `ok`.  The variable `Value` is assigned whatever was in the second position of the returned tuple.

````erlang
{ok, Value} = foo(1,2,3)
````

- The special identifier `_` (underbar) always matches, and discards the value.
- If you assign a value to a "variable" that has already been assigned, then it will only suceed if the new value is equal to the old one.

Enough, let's dive in!

## The Main Logic of the Code

The code is organized in a number of modules, of which two has special interest to understand how it operates: `torrent_client` and `torrent_peer`.  Both of these modules have a `main_loop` function that runs an infinite loop. We will have

- one process (thread) for each `.torrent` file being shared executing the `torrent_client:main_loop` function, and
- one process executing the `torrent_peer:main_loop` function for each remote peer we're connected to with a tcp socket.

In Erlang, a function can execute in an infinite loop by calling itself without causing the stack to run full, if the self-recursive call appears as the *last* expression of the function, in so-called *tail position*.  This is because a self-call at that place can discard all the local variables (the activation record) since those would not be available anyway, and just do the call using a `goto` operation on the underlying virtual machine.

### Client Process

The "client" knows which parts we have, and which parts we want (two disjoint sets of block numbers, of which the union is the full set of block numbers).  Every time a peer completes a part download it sends a `{downloaded, PartNo}` message to the client process, which updates the have/want sets and broadcasts `{finished, PartNo}` to all the peer processes.   Erlang's `receive` construct is a blocking operation that waits for a message matching one of the enclosed clauses. Thus, the gist of the client's main loop is this:

````erlang
main_loop(State=#state{ peers=Peers, have=Have, missing = Missing }) ->
    receive
        {downloaded, PieceNo} ->
            State2=State#state{
                   missing = ordsets:del_element(PieceNo, Missing),
                   have    = ordsets:add_element(PieceNo, Have) },
            case State2#state.missing == [] of
                true  ->
                    [ erlang:exit(PeerPID, shutdown) || PeerPID <- Peers ],
                    io:format("download done!~n"),
                    ok;
                false ->
                    [ PeerPID ! {finished, PieceNo} || PeerPID <- Peers ],
                    main_loop(State2)
            end;
    ...
````

### Peer Process

For each connected peer, there is a process that sits in an infinite loop waiting for incoming messages.  The peer waits for

- Data from the socket.  Incoming data arrives as a `{tcp, Socket, Packet}` where `Packet` is the actual data received.
- The 10-second interval timer triggering,
- Notifications from the manager that some other peer has successfully finished downloading some piece

The main loop is depicted here:

````erlang
main_loop(State=#state{ sock=Sock, upload_allowance=Allowance, want=Want, have=Have }) ->
  receive
    {tcp, Sock, Packet} ->
       Message = torrent_protocol:decode_packet(Packet, Info),
       inet:setopts(Sock, [{active,once}]),
       handle_incoming(Message, State);

    {timeout, _, ten_sec_timer} ->
      Timer = erlang:start_timer(10000, self(), ten_sec_timer),
      {ok, State2} = send(keep_alive, State),
      do_work(State2#state{
            upload_allowance=?UPLOAD_BYTES_PER_10SECOND),
            timer=Timer });

    {finished, PieceNo} ->
      case ordsets:is_element(PieceNo, Want) of
        true  ->
            % cancel any outstanding requests
            {ok, State2} = cancel(PieceNo, State);
        false ->
            % inform peer that we can now provide PieceNo
            {ok, State2} = send({have, PieceNo}, State)
      end,
      do_work(State2#state{
                have=ordsets:add_element(PieceNo, Have),
                want=ordsets:del_element(PieceNo, Want) });
      ...
````


module Catechism
  module Matchers
    class Equal < Struct.new(:subject, :expectation, :negated)
      def equal?
        subject == expectation
      end

      def valid?
        equal? ^ negated
      end

      def failure_message
        if negated
          "#{subject} equals #{expected}"
        else
          "#{subject} does not equal #{expected}"
        end
      end
    end
  end
end


from OpenGL.GL import *
from primitive import G_OBJ_CUBE
import numpy
import math
from transformation import scaling, translation

EPSILON = 0.000001

class AABB(object):

    def __init__(self, center, size):
        """ Axis aligned bounding box.
            This is a box that is aligned with the XYZ axes of the model coordinate space.
            It's used for collision detection with rays for selection.
            It could also be used for rudimentary collision detection between nodes. """
        self.center = numpy.array(center)
        self.size = numpy.array(size)

    def intersects_aabb(self, other):
        """ returns True <=> this AABB intersects with the other AABB
            Consumes: other -> another AABB """
        diff = [a - b for a, b in zip(self.center, other.center)]

        if abs(diff[0]) > (size[0] + other.size[0]): return False
        if abs(diff[1]) > (size[1] + other.size[1]): return False
        if abs(diff[2]) > (size[2] + other.size[2]): return False

        return True

    def ray_hit(self, origin, direction, modelmatrix):
        """ Returns True <=> the ray hits the AABB
            Consumes: origin, direction -> describes the ray
                      modelmatrix       -> the matrix to convert from ray coordinate space to AABB coordinate space """
        aabb_min = self.center - self.size
        aabb_max = self.center + self.size
        tmin = 0.0
        tmax = 100000.0

        obb_pos_worldspace = numpy.array([modelmatrix[3, 0], modelmatrix[3, 1], modelmatrix[3, 2]])
        delta = (obb_pos_worldspace - origin)

        # test intersection with 2 planes perpendicular to OBB's x-axis
        xaxis = numpy.array((modelmatrix[0, 0], modelmatrix[1, 0], modelmatrix[2, 0]))

        e = numpy.dot(xaxis, delta)
        f = numpy.dot(direction, xaxis)
        if math.fabs(f) > 0.0 + EPSILON:
            t1 = (e + aabb_min[0])/f
            t2 = (e + aabb_max[0])/f
            if t1 > t2:
                t1, t2 = t2, t1
            if t2 < tmax:
                tmax = t2
            if t1 > tmin:
                tmin = t1
            if tmax < tmin:
                return (False, 0)
        else:
            if (-e + aabb_min[0] > 0.0 + EPSILON) or (-e+aabb_max[0] < 0.0 - EPSILON):
                return False, 0

        yaxis = numpy.array((modelmatrix[0, 1], modelmatrix[1, 1], modelmatrix[2, 1]))
        e = numpy.dot(yaxis, delta)
        f = numpy.dot(direction, yaxis)
        # intersection in y
        if math.fabs(f)> 0.0 + EPSILON:
            t1 = (e + aabb_min[1])/f
            t2 = (e + aabb_max[1])/f
            if t1 > t2:
                t1, t2 = t2, t1
            if t2 < tmax:
                tmax = t2
            if t1 > tmin:
                tmin = t1
            if tmax < tmin:
                return (False, 0)
        else:
            if (-e + aabb_min[1] > 0.0 + EPSILON) or (-e+aabb_max[1] < 0.0 - EPSILON):
                return False, 0

        # intersection in z
        zaxis = numpy.array((modelmatrix[0, 2], modelmatrix[1, 2], modelmatrix[2, 2]))
        e = numpy.dot(zaxis, delta)
        f = numpy.dot(direction, zaxis)
        if math.fabs(f)> 0.0 + EPSILON:
            t1 = (e + aabb_min[2])/f
            t2 = (e + aabb_max[2])/f
            if t1 > t2:
                t1, t2 = t2, t1
            if t2 < tmax:
                tmax = t2
            if t1 > tmin:
                tmin = t1
            if tmax < tmin:
                return (False, 0)
        else:
            if (-e + aabb_min[2] > 0.0 + EPSILON) or (-e+aabb_max[2] < 0.0 - EPSILON):
                return False, 0

        return True, tmin

    def render(self):
        """ render the AABB. This can be useful for debugging purposes """
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        glTranslated(self.center[0], self.center[1], self.center[2]);
        glScaled(2*self.size[0], 2*self.size[1], 2*self.size[2]);
        glCallList(G_OBJ_CUBE);
        glPopMatrix();
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);


from protocol import CommanderId
from member import Component

class Commander(Component):

    def __init__(self, member, leader, ballot_num, slot, proposal, peers):
        super(Commander, self).__init__(member)
        self.leader = leader
        self.ballot_num = ballot_num
        self.slot = slot
        self.proposal = proposal
        self.commander_id = CommanderId(self.address, slot, proposal)
        self.accepted = set([])
        self.peers = peers
        self.quorum = len(peers) / 2 + 1

    def start(self):
        self.send(self.peers, 'ACCEPT',  # p2a
                         commander_id=self.commander_id,
                         ballot_num=self.ballot_num,
                         slot=self.slot,
                         proposal=self.proposal)

    def finished(self, ballot_num, preempted):
        self.leader.commander_finished(self.commander_id, ballot_num, preempted)
        self.stop()

    def do_ACCEPTED(self, commander_id, acceptor, ballot_num):  # p2b
        if commander_id != self.commander_id:
            return
        if ballot_num == self.ballot_num:
            self.accepted.add(acceptor)
            if len(self.accepted) < self.quorum:
                return
            self.send(self.peers, 'DECISION',
                                slot=self.slot,
                                proposal=self.proposal)
            self.finished(ballot_num, False)
        else:
            self.finished(ballot_num, True)


import cPickle as pickle
import uuid
import logging
import time
import heapq
import socket

NAMESPACE = uuid.UUID('7e0d7720-fa98-4270-94ff-650a2c25f3f0')

def addr_to_tuple(addr):
    parts = addr.split('-')
    return parts[0], int(parts[1])

def tuple_to_addr(addr):
    if addr[0] == '0.0.0.0':
        addr = socket.gethostbyname(socket.gethostname()), addr[1]
    return '%s-%s' % addr

class Node(object):

    port = 0  # XXX temporary

    def __init__(self):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.bind(('', self.port))  # XXX temporary
        self.address = tuple_to_addr(self.sock.getsockname())
        self.timers = []
        self.logger = logging.getLogger('node.%s' % (self.address,))
        self.unique_id = uuid.uuid3(NAMESPACE, self.address).int
        # XXX temporary
        self.unique_id = self.sock.getsockname()[1]

    def start(self):
        # subclasses can override this
        pass

    def run(self):
        self.start()
        self.running = True
        while self.running:
            if self.timers:
                next_timer = self.timers[0][0]
                if next_timer < time.time():
                    when, do, callable = heapq.heappop(self.timers)
                    if do:
                        callable()
                    continue
            else:
                next_timer = 0
            timeout = max(0.1, next_timer - time.time())
            self.sock.settimeout(timeout)
            try:
                msg, address = self.sock.recvfrom(102400)
            except socket.timeout:
                continue
            action, kwargs = pickle.loads(msg)
            self.logger.debug("received %r with args %r" % (action, kwargs))
            getattr(self, 'do_%s' % action)(**kwargs)

    def stop(self):
        self.running = False

    def set_timer(self, seconds, callable):
        timer = [time.time() + seconds, True, callable]
        heapq.heappush(self.timers, timer)
        return timer

    def cancel_timer(self, timer):
        timer[1] = False

    def send(self, destinations, action, **kwargs):
        self.logger.debug("sending %s with args %s to %s" %
                          (action, kwargs, destinations))
        pkl = pickle.dumps((action, kwargs))
        for dest in destinations:
            self.sock.sendto(pkl, addr_to_tuple(dest))

# tests

import unittest
import threading

class TestNode(Node):
    foo_called = False
    bar_called = False

    def do_FOO(self, x, y):
        self.foo_called = True
        self.stop()

class NodeTests(unittest.TestCase):

    def test_comm(self):
        sender = Node()
        receiver = TestNode()
        rxthread = threading.Thread(target=receiver.run)
        rxthread.start()
        sender.send([receiver.address], 'FOO', x=10, y=20)
        rxthread.join()
        self.failUnless(receiver.foo_called)

    def test_timeout(self):
        node = TestNode()
        def cb():
            node.bar_called = True
            node.stop()
        node.set_timer(0.01, cb)
        node.run()
        self.failUnless(node.bar_called)

    def test_cancel_timeout(self):
        node = TestNode()
        def fail():
            raise RuntimeError("nooo")
        nonex = node.set_timer(0.01, fail)
        def cb():
            node.bar_called = True
            node.stop()
        node.set_timer(0.02, cb)
        node.cancel_timer(nonex)
        node.run()
        # this just needs to not crash


import protocol
from util import defaultlist
from member import Component

class Seed(Component):

    """A component which simply provides an initial state and view.  It waits
    until it has heard JOIN requests from enough nodes to form a cluster, then
    WELCOMEs them all to the same view with the given initial state."""

    def __init__(self, member, initial_state):
        super(Seed, self).__init__(member)
        self.initial_state = initial_state
        self.peers = set([])
        self.exit_timer = None

    def do_JOIN(self, requester):
        # three is the minimum membership for a working cluster, so don't
        # respond until then, but don't expand the peers list beyond 3
        if len(self.peers) < 3:
            self.peers.add(requester)
            if len(self.peers) < 3:
                return

        # otherwise, we have a cluster, but don't welcome any nodes not
        # part of that cluster (the cluster can do that itself)
        if requester not in self.peers:
            return

        self.send(self.peers, 'WELCOME',
                  state=self.initial_state,
                  slot_num=1,
                  decisions=defaultlist(),
                  viewid=0,
                  peers=list(self.peers))

        # stick around for long enough that we don't hear any new JOINs from
        # the newly formed cluster
        if self.exit_timer:
            self.cancel_timer(self.exit_timer)
        self.exit_timer = self.set_timer(
            protocol.JOIN_RETRANSMIT * 2, self.stop)


# store the inverse of the current modelview.

mat = numpy.array(glGetFloatv( GL_MODELVIEW_MATRIX ))

# Render the scene. This will call the render function for each object in the scene


import protocol
from protocol import ViewChange
from member import Component

class Bootstrap(Component):

    def __init__(self, member, peers, bootstrapped_cb):
        super(Bootstrap, self).__init__(member)
        self.peers = peers
        self.bootstrapped_cb = bootstrapped_cb

    def start(self):
        self.join()

    def join(self):
        "Try to join the cluster"
        self.peers = self.peers[1:] + self.peers[:1] # rotate through peers
        self.send([self.peers[0]], 'JOIN', requester=self.address)
        self.set_timer(protocol.JOIN_RETRANSMIT, self.join)

    def do_WELCOME(self, state, slot_num, decisions, viewid, peers):
        self.bootstrapped_cb(state, slot_num, decisions, viewid, peers)
        self.event('view_change', viewchange=ViewChange(viewid, peers))  # TODO: pass viewid, peers separately
        self.stop()


import fake_network
import member
import unittest

class ComponentTestCase(unittest.TestCase):

    def setUp(self):
        self.node = fake_network.FakeNode()
        self.member = member.Member(self.node)

    def tearDown(self):
        if self.node.sent:
            self.fail("extra messages from node: %r" % (self.node.sent,))

    def assertMessage(self, destinations, action, **kwargs):
        destinations.sort()
        got = self.node.sent.pop(0)
        self.assertEqual((sorted(got[0]), got[1], got[2]),
                         (destinations, action, kwargs))


'''Simple server that echoes data back.'''

import sys, socket

size = 1024

# Empty string for host means 'this machine'.
host, port = '', int(sys.argv[1])

# Create and bind a socket.
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))

# Wait for a connection request.
s.listen(True)
conn, addr = s.accept()
print 'Connected by', addr

# Receive and display a message.
data = conn.recv(size)
print 'server saw', `data`

# Echo it back to the sender.
conn.send(data)

# Put our toys away.
conn.close()


""" Execute picking of an object. Selects an object in the scene.

Consumes: x, y coordinates of the mouse on the screen """

""" Execute a move command on the scene.

import sys
import numpy
from node import Sphere, Cube
class Scene(object):
    """ Base class for scene nodes.
        Scene nodes currently only include primitives """

    # the default depth from the camera to place an object at
    PLACE_DEPTH = 15.0

    def __init__(self):
        """ Initialize the Scene """
        # The scene keeps a list of nodes that are displayed
        self.node_list = list()
        # Keep track of the currently selected node.
        # Actions may depend on whether or not something is selected
        self.selected_node = None

    def render(self):
        """ Render the scene. This function simply calls the render function for each node. """
        for node in self.node_list:
            node.render()

    def add_node(self, node):
        """ Add a new node to the scene """
        self.node_list.append(node)

    def picking(self, start, direction, inv_modelview):
        """ Execute selection.
            Consume: start, direction describing a Ray
                     mat              is the inverse of the current modelview matrix for the scene """
        if self.selected_node is not None:
            self.selected_node.select(False)
            self.selected_node = None

        # Keep track of the closest hit.
        mindist, closest_node  = sys.maxint, None
        for node in self.node_list:
            hit, distance = node.picking(start, direction, inv_modelview)
            if hit and distance < mindist:
                mindist, closest_node = distance, node

        # If we hit something, keep track of it.
        if closest_node is not None:
            closest_node.select()
            closest_node.depth = mindist
            closest_node.selected_loc = start + direction * mindist
            self.selected_node = closest_node

    def move(self, start, direction, inv_modelview):
        """ Move the selected node, if there is one.
            Consume:  start, direction  describes the Ray to move to
                      mat               is the modelview matrix for the scene """
        if self.selected_node is None: return

        # Find the current depth and location of the selected node
        node = self.selected_node
        depth = node.depth
        oldloc = node.selected_loc

        # The new location of the node is the same depth along the new ray
        newloc = (start + direction * depth)

        # transform the translation with the modelview matrix
        translation = newloc - oldloc
        pre_tran = numpy.array([translation[0], translation[1], translation[2], 0])
        translation = inv_modelview.dot(pre_tran)

        # translate the node and track its location
        node.translate(translation[0], translation[1], translation[2])
        node.selected_loc = newloc

    def place(self, shape, start, direction, inv_modelview):
        """ Place a new node.
            Consume:  shape             the shape to add
                      start, direction  describes the Ray to move to
                      mat               is the modelview matrix for the scene """
        new_node = None
        if shape == 'sphere': new_node = Sphere()
        elif shape == 'cube': new_node = Cube()

        self.add_node(new_node)

        # place the node at the cursor in camera-space
        translation = (start + direction * self.PLACE_DEPTH)

        # convert the translation to world-space
        pre_tran = numpy.array([translation[0], translation[1], translation[2], 1])
        translation = inv_modelview.dot(pre_tran)

        new_node.translate(translation[0], translation[1], translation[2])

    def rotate_color(self, forwards):
        """ Rotate the color of the currently selected node """
        if self.selected_node is None: return
        self.selected_node.rotate_color(forwards)


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<title>Cluster Status</title>


*.gem
*.rbc
.bundle
.config
.yardoc
Gemfile.lock
InstalledFiles
_yardoc
coverage
doc/
lib/bundler/man
pkg
rdoc
spec/reports
test/tmp
test/version_tmp
tmp


keep keep keep keep add keep keep keep keep keep

import { act } from 'preact/test-utils';
import { createElement, render, Fragment, Component } from 'preact';
import {
	setupScratch,
	teardown,
	serializeHtml
} from '../../../test/_util/helpers';
import { useEffectAssertions } from './useEffectAssertions.test';
import { useLayoutEffect, useRef, useState } from 'preact/hooks';

/** @jsx createElement */

describe('useLayoutEffect', () => {
	/** @type {HTMLDivElement} */
	let scratch;

	beforeEach(() => {
		scratch = setupScratch();
	});

	afterEach(() => {
		teardown(scratch);
	});

	// Layout effects fire synchronously
	const scheduleEffectAssert = assertFn =>
		new Promise(resolve => {
			assertFn();
			resolve();
		});

	useEffectAssertions(useLayoutEffect, scheduleEffectAssert);

	it('calls the effect immediately after render', () => {
		const cleanupFunction = sinon.spy();
		const callback = sinon.spy(() => cleanupFunction);

		function Comp() {
			useLayoutEffect(callback);
			return null;
		}

		render(<Comp />, scratch);
		render(<Comp />, scratch);

		expect(cleanupFunction).to.be.calledOnce;
		expect(callback).to.be.calledTwice;

		render(<Comp />, scratch);

		expect(cleanupFunction).to.be.calledTwice;
		expect(callback).to.be.calledThrice;
	});

	it('works on a nested component', () => {
		const callback = sinon.spy();

		function Parent() {
			return (

					<Child />

			);
		}

		function Child() {
			useLayoutEffect(callback);
			return null;
		}

		render(<Parent />, scratch);

		expect(callback).to.be.calledOnce;
	});

	it('should execute multiple layout effects in same component in the right order', () => {
		let executionOrder = [];
		const App = ({ i }) => {
			executionOrder = [];
			useLayoutEffect(() => {
				executionOrder.push('action1');
				return () => executionOrder.push('cleanup1');
			}, [i]);
			useLayoutEffect(() => {
				executionOrder.push('action2');
				return () => executionOrder.push('cleanup2');
			}, [i]);
			return
Test
;
		};
		render(<App i={0} />, scratch);
		render(<App i={2} />, scratch);
		expect(executionOrder).to.deep.equal([
			'cleanup1',
			'cleanup2',
			'action1',
			'action2'
		]);
	});

	it('should correctly display DOM', () => {
		function AutoResizeTextareaLayoutEffect(props) {
			const ref = useRef(null);
			useLayoutEffect(() => {
				// IE & Edge put textarea's value as child of textarea when reading innerHTML so use
				// cross browser serialize helper
				const actualHtml = serializeHtml(scratch);
				const expectedHTML = `<div class="${props.value}"><p>${props.value}</p><textarea></textarea></div>`;
				expect(actualHtml).to.equal(expectedHTML);
				expect(document.body.contains(ref.current)).to.equal(true);
			});
			return (
				<Fragment>

{props.value}

					<textarea ref={ref} value={props.value} onChange={props.onChange} />
				</Fragment>
			);
		}

		function App(props) {
			return (

					<AutoResizeTextareaLayoutEffect {...props} />

			);
		}

		render(<App value="hi" />, scratch);
		render(<App value="hii" />, scratch);
	});

	it('should invoke layout effects after subtree is fully connected', () => {
		let ref;
		let layoutEffect = sinon.spy(() => {
			const isConnected = document.body.contains(ref.current);
			expect(isConnected).to.equal(true, 'isConnected');
		});

		function Inner() {
			ref = useRef(null);
			useLayoutEffect(layoutEffect);
			return (
				<Fragment>
					<textarea ref={ref} />
					hello;
				</Fragment>
			);
		}

		function Outer() {
			return (

					<Inner />

			);
		}

		render(<Outer />, scratch);
		expect(layoutEffect).to.have.been.calledOnce;
	});

	// TODO: Make this test pass to resolve issue #1886
	it.skip('should call effects correctly when unmounting', () => {
		let onClick, calledFoo, calledBar, calledFooCleanup, calledBarCleanup;

		const Foo = () => {
			useLayoutEffect(() => {
				if (!calledFoo) calledFoo = scratch.innerHTML;
				return () => {
					if (!calledFooCleanup) calledFooCleanup = scratch.innerHTML;
				};
			}, []);

			return (

Foo

			);
		};

		const Bar = () => {
			useLayoutEffect(() => {
				if (!calledBar) calledBar = scratch.innerHTML;
				return () => {
					if (!calledBarCleanup) calledBarCleanup = scratch.innerHTML;
				};
			}, []);

			return (

Bar

			);
		};

		function App() {
			const [current, setCurrent] = useState('/foo');

			onClick = () => setCurrent(current === '/foo' ? '/bar' : '/foo');

			return (
				<Fragment>
					<button onClick={onClick}>next</button>

					{current === '/foo' && <Foo />}
					{current === '/bar' && <Bar />}
				</Fragment>
			);
		}

		render(<App />, scratch);
		expect(calledFoo).to.equal(
			'<button>next</button>

Foo

',
			'calledFoo'
		);

		act(() => onClick());
		expect(calledFooCleanup).to.equal(
			'<button>next</button>

Bar

',
			'calledFooCleanup'
		);
		expect(calledBar).to.equal(
			'<button>next</button>

Bar

',
			'calledBar'
		);

		act(() => onClick());
		expect(calledBarCleanup).to.equal(
			'<button>next</button>

Foo

',
			'calledBarCleanup'
		);
	});

	it('should throw an error upwards', () => {
		const spy = sinon.spy();
		let errored = false;

		const Page1 = () => {
			const [state, setState] = useState('loading');
			useLayoutEffect(() => {
				setState('loaded');
			}, []);
			return
{state}
;
		};

		const Page2 = () => {
			useLayoutEffect(() => {
				throw new Error('err');
			}, []);
			return
invisible
;
		};

		class App extends Component {
			componentDidCatch(err) {
				spy();
				errored = err;
			}

			render(props, state) {
				if (errored) {
					return
Error
;
				}

				return <Fragment>{props.page === 1 ? <Page1 /> : <Page2 />}</Fragment>;
			}
		}

		act(() => render(<App page={1} />, scratch));
		expect(spy).to.not.be.called;
		expect(scratch.innerHTML).to.equal('
loaded
');

		act(() => render(<App page={2} />, scratch));
		expect(spy).to.be.calledOnce;
		expect(scratch.innerHTML).to.equal('
Error
');
		errored = false;

		act(() => render(<App page={1} />, scratch));
		expect(spy).to.be.calledOnce;
		expect(scratch.innerHTML).to.equal('
loaded
');
	});

	it('should throw an error upwards from return', () => {
		const spy = sinon.spy();
		let errored = false;

		const Page1 = () => {
			const [state, setState] = useState('loading');
			useLayoutEffect(() => {
				setState('loaded');
			}, []);
			return
{state}
;
		};

		const Page2 = () => {
			useLayoutEffect(() => {
				return () => {
					throw new Error('err');
				};
			}, []);
			return
Load
;
		};

		class App extends Component {
			componentDidCatch(err) {
				spy();
				errored = err;
			}

			render(props, state) {
				if (errored) {
					return
Error
;
				}

				return <Fragment>{props.page === 1 ? <Page1 /> : <Page2 />}</Fragment>;
			}
		}

		act(() => render(<App page={2} />, scratch));
		expect(scratch.innerHTML).to.equal('
Load
');

		act(() => render(<App page={1} />, scratch));
		expect(spy).to.be.calledOnce;
		expect(scratch.innerHTML).to.equal('
Error
');
	});
});


/**
 * Assign properties from `props` to `obj`
 * @template O, P The obj and props types
 * @param {O} obj The object to copy properties to
 * @param {P} props The object to copy properties from
 * @returns {O & P}
 */
export function assign(obj, props) {
	for (let i in props) obj[i] = props[i];
	return /** @type {O & P} */ (obj);
}

/**
 * Check if two objects have a different shape
 * @param {object} a
 * @param {object} b
 * @returns {boolean}
 */
export function shallowDiffers(a, b) {
	for (let i in a) if (i !== '__source' && !(i in b)) return true;
	for (let i in b) if (i !== '__source' && a[i] !== b[i]) return true;
	return false;
}


The MIT License (MIT)

Copyright (c) 2015-present Jason Miller

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


import { toChildArray } from 'preact';

const mapFn = (children, fn) => {
	if (children == null) return null;
	return toChildArray(toChildArray(children).map(fn));
};

// This API is completely unnecessary for Preact, so it's basically passthrough.
export const Children = {
	map: mapFn,
	forEach: mapFn,
	count(children) {
		return children ? toChildArray(children).length : 0;
	},
	only(children) {
		const normalized = toChildArray(children);
		if (normalized.length !== 1) throw 'Children.only';
		return normalized[0];
	},
	toArray: toChildArray
};


import { act } from 'preact/test-utils';
import { createElement, render, Fragment, Component } from 'preact';
import { setupScratch, teardown } from '../../../test/_util/helpers';
import { useEffect, useState } from 'preact/hooks';
import { useEffectAssertions } from './useEffectAssertions.test';
import { scheduleEffectAssert } from '../_util/useEffectUtil';

/** @jsx createElement */

describe('useEffect', () => {
	/** @type {HTMLDivElement} */
	let scratch;

	beforeEach(() => {
		scratch = setupScratch();
	});

	afterEach(() => {
		teardown(scratch);
	});

	useEffectAssertions(useEffect, scheduleEffectAssert);

	it('calls the effect immediately if another render is about to start', () => {
		const cleanupFunction = sinon.spy();
		const callback = sinon.spy(() => cleanupFunction);

		function Comp() {
			useEffect(callback);
			return null;
		}

		render(<Comp />, scratch);
		render(<Comp />, scratch);

		expect(cleanupFunction).to.be.not.called;
		expect(callback).to.be.calledOnce;

		render(<Comp />, scratch);

		expect(cleanupFunction).to.be.calledOnce;
		expect(callback).to.be.calledTwice;
	});

	it('cancels the effect when the component get unmounted before it had the chance to run it', () => {
		const cleanupFunction = sinon.spy();
		const callback = sinon.spy(() => cleanupFunction);

		function Comp() {
			useEffect(callback);
			return null;
		}

		render(<Comp />, scratch);
		render(null, scratch);

		return scheduleEffectAssert(() => {
			expect(cleanupFunction).to.not.be.called;
			expect(callback).to.not.be.called;
		});
	});

	it('should execute multiple effects in same component in the right order', () => {
		let executionOrder = [];
		const App = ({ i }) => {
			executionOrder = [];
			useEffect(() => {
				executionOrder.push('action1');
				return () => executionOrder.push('cleanup1');
			}, [i]);
			useEffect(() => {
				executionOrder.push('action2');
				return () => executionOrder.push('cleanup2');
			}, [i]);
			return
Test
;
		};
		act(() => render(<App i={0} />, scratch));
		act(() => render(<App i={2} />, scratch));
		expect(executionOrder).to.deep.equal([
			'cleanup1',
			'cleanup2',
			'action1',
			'action2'
		]);
	});

	it('should throw an error upwards', () => {
		const spy = sinon.spy();
		let errored = false;

		const Page1 = () => {
			const [state, setState] = useState('loading');
			useEffect(() => {
				setState('loaded');
			}, []);
			return
{state}
;
		};

		const Page2 = () => {
			useEffect(() => {
				throw new Error('err');
			}, []);
			return
invisible
;
		};

		class App extends Component {
			componentDidCatch(err) {
				spy();
				errored = err;
			}

			render(props, state) {
				if (errored) {
					return
Error
;
				}

				return <Fragment>{props.page === 1 ? <Page1 /> : <Page2 />}</Fragment>;
			}
		}

		act(() => render(<App page={1} />, scratch));
		expect(spy).to.not.be.called;
		expect(scratch.innerHTML).to.equal('
loaded
');

		act(() => render(<App page={2} />, scratch));
		expect(spy).to.be.calledOnce;
		expect(scratch.innerHTML).to.equal('
Error
');
		errored = false;

		act(() => render(<App page={1} />, scratch));
		expect(spy).to.be.calledOnce;
		expect(scratch.innerHTML).to.equal('
loaded
');
	});

	it('should throw an error upwards from return', () => {
		const spy = sinon.spy();
		let errored = false;

		const Page1 = () => {
			const [state, setState] = useState('loading');
			useEffect(() => {
				setState('loaded');
			}, []);
			return
{state}
;
		};

		const Page2 = () => {
			useEffect(() => {
				return () => {
					throw new Error('err');
				};
			}, []);
			return
Load
;
		};

		class App extends Component {
			componentDidCatch(err) {
				spy();
				errored = err;
			}

			render(props, state) {
				if (errored) {
					return
Error
;
				}

				return <Fragment>{props.page === 1 ? <Page1 /> : <Page2 />}</Fragment>;
			}
		}

		act(() => render(<App page={2} />, scratch));
		expect(scratch.innerHTML).to.equal('
Load
');

		act(() => render(<App page={1} />, scratch));
		expect(spy).to.be.calledOnce;
		expect(scratch.innerHTML).to.equal('
Error
');
	});

	it('catches errors when error is invoked during render', () => {
		const spy = sinon.spy();
		let errored;

		function Comp() {
			useEffect(() => {
				throw new Error('hi');
			});
			return null;
		}

		class App extends Component {
			componentDidCatch(err) {
				spy();
				errored = err;
			}

			render(props, state) {
				if (errored) {
					return
Error
;
				}

				return <Comp />;
			}
		}

		render(<App />, scratch);
		act(() => {
			render(<App />, scratch);
		});
		expect(spy).to.be.calledOnce;
		expect(scratch.innerHTML).to.equal('
Error
');
	});

	it('should allow creating a new root', () => {
		const root = document.createElement('div');
		const global = document.createElement('div');
		scratch.appendChild(root);
		scratch.appendChild(global);

		const Modal = props => {
			let [, setCanProceed] = useState(true);
			let ChildProp = props.content;

			return (

					<ChildProp setCanProceed={setCanProceed} />

			);
		};

		const Inner = () => {
			useEffect(() => {
				render(
global
, global);
			}, []);

			return
Inner
;
		};

		act(() => {
			render(
				<Modal
					content={props => {
						props.setCanProceed(false);
						return <Inner />;
					}}
				/>,
				root
			);
		});

		expect(scratch.innerHTML).to.equal(
			'

Inner

global

'
		);
	});

	it('should not crash when effect returns truthy non-function value', () => {
		const callback = sinon.spy(() => 'truthy');
		function Comp() {
			useEffect(callback);
			return null;
		}

		render(<Comp />, scratch);
		render(<Comp />, scratch);

		expect(callback).to.have.been.calledOnce;

		render(
Replacement
, scratch);
	});
});


import { expect } from 'chai';
import {
	createElement,
	ComponentFactory,
	ComponentConstructor,
	Component
} from '../../';
import { SimpleComponent, SimpleComponentProps } from './Component-test';

export interface highlightedProps {
	isHighlighted: boolean;
}

export function highlighted<T>(
	Wrappable: ComponentFactory<T>
): ComponentConstructor<T & highlightedProps> {
	return class extends Component<T & highlightedProps> {
		constructor(props: T & highlightedProps) {
			super(props);
		}

		render() {
			let className = this.props.isHighlighted ? 'highlighted' : '';
			return (
				<div className={className}>
					<Wrappable {...this.props} />
				</div>
			);
		}

		toString() {
			return `Highlighted ${Wrappable.name}`;
		}
	};
}

const HighlightedSimpleComponent = highlighted<SimpleComponentProps>(
	SimpleComponent
);

describe('hoc', () => {
	it('wraps the given component', () => {
		const highlight = new HighlightedSimpleComponent({
			initialName: 'initial name',
			isHighlighted: true
		});

		expect(highlight.toString()).to.eq('Highlighted SimpleComponent');
	});
});


It controls protected/private property mangling so that minified builds have consistent property names.

Most properties are only used on one type of objects, so they can have the same name since they will never collide. Doing this reduces size.


/**
 * Serialize an object
 * @param {Object} obj
 * @return {string}
 */
function serialize(obj) {
	if (obj instanceof Text) return '#text';
	if (obj instanceof Element) return `<${obj.localName}>${obj.textContent}`;
	if (obj === document) return 'document';
	if (typeof obj == 'string') return obj;
	return Object.prototype.toString.call(obj).replace(/(^\[object |\]$)/g, '');
}

/** @type {string[]} */
let log = [];

/**
 * Modify obj's original method to log calls and arguments on logger object
 * @template T
 * @param {T} obj
 * @param {keyof T} method
 */
export function logCall(obj, method) {
	let old = obj[method];
	obj[method] = function(...args) {
		let c = '';
		for (let i = 0; i < args.length; i++) {
			if (c) c += ', ';
			c += serialize(args[i]);
		}

		// Normalize removeChild -> remove to keep output clean and readable
		const operation =
			method != 'removeChild'
				? `${serialize(this)}.${method}(${c})`
				: `${serialize(c)}.remove()`;
		log.push(operation);
		return old.apply(this, args);
	};
}

/**
 * Return log object
 * @return {string[]} log
 */
export function getLog() {
	return log;
}

/** Clear log object */
export function clearLog() {
	log = [];
}

export function getLogSummary() {
	/** @type {{ [key: string]: number }} */
	const summary = {};

	for (let entry of log) {
		summary[entry] = (summary[entry] || 0) + 1;
	}

	return summary;
}


keep keep keep add keep keep keep keep keep


#people-app {
	.avatar {
		display: inline-block;
		overflow: hidden;
		width: var(--avatar-size, 32px);
		height: var(--avatar-size, 32px);
		background-color: var(--avatar-color, var(--app-primary));
		border-radius: 50%;
		font-size: calc(var(--avatar-size, 32px) * 0.5);
		line-height: var(--avatar-size, 32px);
		object-fit: cover;
		text-align: center;
		text-transform: uppercase;
		white-space: nowrap;
	}
}


declare module Chai {
	export interface Assertion {
		equalNode(node: Node | null, message?: string): void;
	}
}


import { Component } from 'preact';
import { shallowDiffers } from './util';

/**
 * Component class with a predefined `shouldComponentUpdate` implementation
 */
export function PureComponent(p) {
	this.props = p;
}
PureComponent.prototype = new Component();
// Some third-party libraries check if this property is present
PureComponent.prototype.isPureReactComponent = true;
PureComponent.prototype.shouldComponentUpdate = function(props, state) {
	return shallowDiffers(this.props, props) || shallowDiffers(this.state, state);
};


it('should allow creating a new root', () => {

expect(errored)
.to.be.an('Error')
.with.property('message', 'hi');


preact

Fast 3kb React-compatible Virtual DOM library.

microbundle build --raw -f iife src/cjs.js -o dist/preact.min.js

microbundle build --raw --cwd test-utils

microbundle build --raw --cwd compat --globals 'preact/hooks=preactHooks'

microbundle watch --raw --format cjs --cwd hooks

microbundle watch --raw --format cjs --cwd compat --globals 'preact/hooks=preactHooks'

run-p test:mocha test:karma:minify test:ts

tsc -p test/ts/ && mocha --require "@babel/register" test/ts/**/*-test.js

mocha --recursive --require "@babel/register" test/shared test/node

cross-env COVERAGE=true karma start karma.conf.js --single-run

cross-env COVERAGE=true MINIFY=true karma start karma.conf.js --single-run

karma start karma.conf.js --no-single-run

cross-env COVERAGE=false karma start karma.conf.js --grep=hooks/test/browser/**.js --no-single-run

cross-env PERFORMANCE=false COVERAGE=false karma start karma.conf.js --grep=test-utils/test/shared/**.js --no-single-run

cross-env PERFORMANCE=true COVERAGE=false karma start karma.conf.js --grep=test/benchmarks/**.js --single-run

npm run test:karma:bench -- no-single-run

eslint src test debug compat hooks test-utils

src dist compat/dist compat/src compat/server.js compat/package.json debug/dist debug/src debug/package.json devtools/dist devtools/src devtools/package.json hooks/dist hooks/src hooks/package.json test-utils/src test-utils/package.json test-utils/dist

preact
react
ui
user interface
virtual dom
vdom
components
dom diff

The Preact Authors (https://github.com/preactjs/preact/contributors)


import { options, createElement, render } from 'preact';
import { useEffect, useReducer, useState } from 'preact/hooks';
import { act } from 'preact/test-utils';
import { setupScratch, teardown } from '../../../test/_util/helpers';

/** @jsx createElement */

// IE11 doesn't support `new Event()`
function createEvent(name) {
	if (typeof Event == 'function') return new Event(name);

	const event = document.createEvent('Event');
	event.initEvent(name, true, true);
	return event;
}

describe('act', () => {
	/** @type {HTMLDivElement} */
	let scratch;

	beforeEach(() => {
		scratch = setupScratch();
	});

	afterEach(() => {
		teardown(scratch);
		options.debounceRendering = undefined;
	});

	it('should reset options after act finishes', () => {
		expect(options.requestAnimationFrame).to.equal(undefined);
		act(() => null);
		expect(options.requestAnimationFrame).to.equal(undefined);
	});

	it('should flush pending effects', () => {
		let spy = sinon.spy();
		function StateContainer() {
			useEffect(spy);
			return
;
		}
		act(() => render(<StateContainer />, scratch));
		expect(spy).to.be.calledOnce;
	});

	it('should flush pending and initial effects', () => {
		const spy = sinon.spy();
		function StateContainer() {
			const [count, setCount] = useState(0);
			useEffect(() => spy(), [count]);
			return (

Count: {count}

					<button onClick={() => setCount(c => c + 11)} />

			);
		}

		act(() => render(<StateContainer />, scratch));
		expect(spy).to.be.calledOnce;
		expect(scratch.textContent).to.include('Count: 0');
		act(() => {
			const button = scratch.querySelector('button');
			button.click();
			expect(spy).to.be.calledOnce;
			expect(scratch.textContent).to.include('Count: 0');
		});
		expect(spy).to.be.calledTwice;
		expect(scratch.textContent).to.include('Count: 1');
	});

	it('should flush series of hooks', () => {
		const spy = sinon.spy();
		const spy2 = sinon.spy();
		function StateContainer() {
			const [count, setCount] = useState(0);
			useEffect(() => {
				spy();
				if (count === 1) {
					setCount(() => 2);
				}
			}, [count]);
			useEffect(() => {
				if (count === 2) {
					spy2();
					setCount(() => 4);
					return () => setCount(() => 3);
				}
			}, [count]);
			return (

Count: {count}

					<button onClick={() => setCount(c => c + 1)} />

			);
		}
		act(() => render(<StateContainer />, scratch));
		expect(spy).to.be.calledOnce;
		expect(scratch.textContent).to.include('Count: 0');
		act(() => {
			const button = scratch.querySelector('button');
			button.click();
		});
		expect(spy.callCount).to.equal(5);
		expect(spy2).to.be.calledOnce;
		expect(scratch.textContent).to.include('Count: 3');
	});

	it('should drain the queue of hooks', () => {
		const spy = sinon.spy();
		function StateContainer() {
			const [count, setCount] = useState(0);
			useEffect(() => spy());
			return (

Count: {count}

					<button onClick={() => setCount(c => c + 11)} />

			);
		}

		render(<StateContainer />, scratch);
		expect(scratch.textContent).to.include('Count: 0');
		act(() => {
			const button = scratch.querySelector('button');
			button.click();
			expect(scratch.textContent).to.include('Count: 0');
		});
		expect(scratch.textContent).to.include('Count: 1');
	});

	it('should restore options.requestAnimationFrame', () => {
		const spy = sinon.spy();

		options.requestAnimationFrame = spy;
		act(() => null);

		expect(options.requestAnimationFrame).to.equal(spy);
		expect(spy).to.not.be.called;
	});

	it('should restore options.debounceRendering', () => {
		const spy = sinon.spy();

		options.debounceRendering = spy;
		act(() => null);

		expect(options.debounceRendering).to.equal(spy);
		expect(spy).to.not.be.called;
	});

	it('should restore options.debounceRendering when it was undefined before', () => {
		act(() => null);
		expect(options.debounceRendering).to.equal(undefined);
	});

	it('should flush state updates if there are pending state updates before `act` call', () => {
		function CounterButton() {
			const [count, setCount] = useState(0);
			const increment = () => setCount(count => count + 1);
			return <button onClick={increment}>{count}</button>;
		}

		render(<CounterButton />, scratch);
		const button = scratch.querySelector('button');

		// Click button. This will schedule an update which is deferred, as is
		// normal for Preact, since it happens outside an `act` call.
		button.dispatchEvent(createEvent('click'));

		expect(button.textContent).to.equal('0');

		act(() => {
			// Click button a second time. This will schedule a second update.
			button.dispatchEvent(createEvent('click'));
		});
		// All state updates should be applied synchronously after the `act`
		// callback has run but before `act` returns.
		expect(button.textContent).to.equal('2');
	});

	it('should flush effects if there are pending effects before `act` call', () => {
		function Counter() {
			const [count, setCount] = useState(0);
			useEffect(() => {
				setCount(count => count + 1);
			}, []);
			return
{count}
;
		}

		// Render a component which schedules an effect outside of an `act`
		// call. This will be scheduled to execute after the next paint as usual.
		render(<Counter />, scratch);
		expect(scratch.firstChild.textContent).to.equal('0');

		// Render a component inside an `act` call, this effect should be
		// executed synchronously before `act` returns.
		act(() => {
			render(
, scratch);
			render(<Counter />, scratch);
		});
		expect(scratch.firstChild.textContent).to.equal('1');
	});

	it('returns a Promise if invoked with a sync callback', () => {
		const result = act(() => {});
		expect(result.then).to.be.a('function');
		return result;
	});

	it('returns a Promise if invoked with an async callback', () => {
		const result = act(async () => {});
		expect(result.then).to.be.a('function');
		return result;
	});

	it('should await "thenable" result of callback before flushing', async () => {
		const events = [];

		function TestComponent() {
			useEffect(() => {
				events.push('flushed effect');
			}, []);
			events.push('scheduled effect');
			return
Test
;
		}

		const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

		events.push('began test');
		const acted = act(async () => {
			events.push('began act callback');
			await delay(1);
			render(<TestComponent />, scratch);
			events.push('end act callback');
		});
		events.push('act returned');
		await acted;
		events.push('act result resolved');

		expect(events).to.deep.equal([
			'began test',
			'began act callback',
			'act returned',
			'scheduled effect',
			'end act callback',
			'flushed effect',
			'act result resolved'
		]);
	});

	context('when `act` calls are nested', () => {
		it('should invoke nested sync callback and return a Promise', () => {
			let innerResult;
			const spy = sinon.stub();

			act(() => {
				innerResult = act(spy);
			});

			expect(spy).to.be.calledOnce;
			expect(innerResult.then).to.be.a('function');
		});

		it('should invoke nested async callback and return a Promise', async () => {
			const events = [];

			await act(async () => {
				events.push('began outer act callback');
				await act(async () => {
					events.push('began inner act callback');
					await Promise.resolve();
					events.push('end inner act callback');
				});
				events.push('end outer act callback');
			});
			events.push('act finished');

			expect(events).to.deep.equal([
				'began outer act callback',
				'began inner act callback',
				'end inner act callback',
				'end outer act callback',
				'act finished'
			]);
		});

		it('should only flush effects when outer `act` call returns', () => {
			let counter = 0;

			function Widget() {
				useEffect(() => {
					++counter;
				});
				const [, forceUpdate] = useReducer(x => x + 1, 0);
				return <button onClick={forceUpdate}>test</button>;
			}

			act(() => {
				render(<Widget />, scratch);
				const button = scratch.querySelector('button');
				expect(counter).to.equal(0);

				act(() => {
					button.dispatchEvent(createEvent('click'));
				});

				// Effect triggered by inner `act` call should not have been
				// flushed yet.
				expect(counter).to.equal(0);
			});

			// Effects triggered by inner `act` call should now have been
			// flushed.
			expect(counter).to.equal(2);
		});

		it('should only flush updates when outer `act` call returns', () => {
			function Button() {
				const [count, setCount] = useState(0);
				const increment = () => setCount(count => count + 1);
				return <button onClick={increment}>{count}</button>;
			}

			render(<Button />, scratch);
			const button = scratch.querySelector('button');
			expect(button.textContent).to.equal('0');

			act(() => {
				act(() => {
					button.dispatchEvent(createEvent('click'));
				});

				// Update triggered by inner `act` call should not have been
				// flushed yet.
				expect(button.textContent).to.equal('0');
			});

			// Updates from outer and inner `act` calls should now have been
			// flushed.
			expect(button.textContent).to.equal('1');
		});
	});

	describe('when `act` callback throws an exception', () => {
		function BrokenWidget() {
			throw new Error('BrokenWidget is broken');
		}

		let effectCount;

		function WorkingWidget() {
			const [count, setCount] = useState(0);

			useEffect(() => {
				++effectCount;
			}, []);

			if (count === 0) {
				setCount(1);
			}

			return
{count}
;
		}

		beforeEach(() => {
			effectCount = 0;
		});

		const renderBroken = () => {
			act(() => {
				render(<BrokenWidget />, scratch);
			});
		};

		const renderWorking = () => {
			act(() => {
				render(<WorkingWidget />, scratch);
			});
		};

		const tryRenderBroken = () => {
			try {
				renderBroken();
			} catch (e) {}
		};

		describe('synchronously', () => {
			it('should rethrow the exception', () => {
				expect(renderBroken).to.throw('BrokenWidget is broken');
			});

			it('should not affect state updates in future renders', () => {
				tryRenderBroken();
				renderWorking();
				expect(scratch.textContent).to.equal('1');
			});

			it('should not affect effects in future renders', () => {
				tryRenderBroken();
				renderWorking();
				expect(effectCount).to.equal(1);
			});
		});

		describe('asynchronously', () => {
			const renderBrokenAsync = async () => {
				await act(async () => {
					render(<BrokenWidget />, scratch);
				});
			};

			it('should rethrow the exception', async () => {
				let err;
				try {
					await renderBrokenAsync();
				} catch (e) {
					err = e;
				}
				expect(err.message).to.equal('BrokenWidget is broken');
			});

			it('should not affect state updates in future renders', async () => {
				try {
					await renderBrokenAsync();
				} catch (e) {}

				renderWorking();
				expect(scratch.textContent).to.equal('1');
			});

			it('should not affect effects in future renders', async () => {
				try {
					await renderBrokenAsync();
				} catch (e) {}

				renderWorking();
				expect(effectCount).to.equal(1);
			});
		});

		describe('in an effect', () => {
			function BrokenEffect() {
				useEffect(() => {
					throw new Error('BrokenEffect effect');
				}, []);
				return null;
			}

			const renderBrokenEffect = () => {
				act(() => {
					render(<BrokenEffect />, scratch);
				});
			};

			it('should rethrow the exception', () => {
				expect(renderBrokenEffect).to.throw('BrokenEffect effect');
			});

			it('should not affect state updates in future renders', () => {
				try {
					renderBrokenEffect();
				} catch (e) {}

				renderWorking();
				expect(scratch.textContent).to.equal('1');
			});

			it('should not affect effects in future renders', () => {
				try {
					renderBrokenEffect();
				} catch (e) {}

				renderWorking();
				expect(effectCount).to.equal(1);
			});
		});
	});
});


export function scheduleEffectAssert(assertFn) {
	return new Promise(resolve => {
		requestAnimationFrame(() =>
			setTimeout(() => {
				assertFn();
				resolve();
			}, 0)
		);
	});
}