Kaynağa Gözat

Added scaling support, unit checking and changing API, fixed re-plotting problems, added documentation.

Juan Pablo Caram 12 yıl önce
ebeveyn
işleme
1ce8f672af
95 değiştirilmiş dosya ile 8975 ekleme ve 107 silme
  1. 336 79
      camlib.py
  2. 98 25
      cirkuix.py
  3. 325 3
      cirkuix.ui
  4. 177 0
      doc/Makefile
  5. 4 0
      doc/build/.buildinfo
  6. BIN
      doc/build/.doctrees/camlib.doctree
  7. BIN
      doc/build/.doctrees/environment.pickle
  8. BIN
      doc/build/.doctrees/index.doctree
  9. 4 0
      doc/build/_sources/camlib.txt
  10. 55 0
      doc/build/_sources/index.txt
  11. BIN
      doc/build/_static/ajax-loader.gif
  12. 536 0
      doc/build/_static/basic.css
  13. BIN
      doc/build/_static/comment-bright.png
  14. BIN
      doc/build/_static/comment-close.png
  15. BIN
      doc/build/_static/comment.png
  16. BIN
      doc/build/_static/contents.png
  17. 0 0
      doc/build/_static/css/badge_only.css
  18. 0 0
      doc/build/_static/css/theme.css
  19. 256 0
      doc/build/_static/default.css
  20. BIN
      doc/build/_static/dialog-note.png
  21. BIN
      doc/build/_static/dialog-seealso.png
  22. BIN
      doc/build/_static/dialog-todo.png
  23. BIN
      doc/build/_static/dialog-topic.png
  24. BIN
      doc/build/_static/dialog-warning.png
  25. 235 0
      doc/build/_static/doctools.js
  26. BIN
      doc/build/_static/down-pressed.png
  27. BIN
      doc/build/_static/down.png
  28. 310 0
      doc/build/_static/epub.css
  29. BIN
      doc/build/_static/file.png
  30. BIN
      doc/build/_static/font/fontawesome_webfont.eot
  31. 195 0
      doc/build/_static/font/fontawesome_webfont.svg
  32. BIN
      doc/build/_static/font/fontawesome_webfont.ttf
  33. BIN
      doc/build/_static/font/fontawesome_webfont.woff
  34. BIN
      doc/build/_static/footerbg.png
  35. BIN
      doc/build/_static/headerbg.png
  36. 7 0
      doc/build/_static/ie6.css
  37. 1 0
      doc/build/_static/jquery.js
  38. 47 0
      doc/build/_static/js/theme.js
  39. BIN
      doc/build/_static/middlebg.png
  40. BIN
      doc/build/_static/minus.png
  41. BIN
      doc/build/_static/navigation.png
  42. BIN
      doc/build/_static/plus.png
  43. 62 0
      doc/build/_static/pygments.css
  44. 342 0
      doc/build/_static/pyramid.css
  45. 622 0
      doc/build/_static/searchtools.js
  46. 159 0
      doc/build/_static/sidebar.js
  47. 339 0
      doc/build/_static/sphinxdoc.css
  48. BIN
      doc/build/_static/transparent.gif
  49. 31 0
      doc/build/_static/underscore.js
  50. BIN
      doc/build/_static/up-pressed.png
  51. BIN
      doc/build/_static/up.png
  52. 808 0
      doc/build/_static/websupport.js
  53. 147 0
      doc/build/camlib.html
  54. 554 0
      doc/build/genindex.html
  55. 905 0
      doc/build/index.html
  56. BIN
      doc/build/objects.inv
  57. 163 0
      doc/build/py-modindex.html
  58. 159 0
      doc/build/search.html
  59. 0 0
      doc/build/searchindex.js
  60. 242 0
      doc/make.bat
  61. 17 0
      doc/source/_theme/__init__.py
  62. 19 0
      doc/source/_theme/breadcrumbs.html
  63. 32 0
      doc/source/_theme/footer.html
  64. 149 0
      doc/source/_theme/layout.html
  65. 205 0
      doc/source/_theme/layout_old.html
  66. 50 0
      doc/source/_theme/search.html
  67. 7 0
      doc/source/_theme/searchbox.html
  68. 17 0
      doc/source/_theme/sphinx_rtd_theme/__init__.py
  69. 19 0
      doc/source/_theme/sphinx_rtd_theme/breadcrumbs.html
  70. 32 0
      doc/source/_theme/sphinx_rtd_theme/footer.html
  71. 149 0
      doc/source/_theme/sphinx_rtd_theme/layout.html
  72. 205 0
      doc/source/_theme/sphinx_rtd_theme/layout_old.html
  73. 50 0
      doc/source/_theme/sphinx_rtd_theme/search.html
  74. 7 0
      doc/source/_theme/sphinx_rtd_theme/searchbox.html
  75. 0 0
      doc/source/_theme/sphinx_rtd_theme/static/css/badge_only.css
  76. 0 0
      doc/source/_theme/sphinx_rtd_theme/static/css/theme.css
  77. BIN
      doc/source/_theme/sphinx_rtd_theme/static/font/fontawesome_webfont.eot
  78. 195 0
      doc/source/_theme/sphinx_rtd_theme/static/font/fontawesome_webfont.svg
  79. BIN
      doc/source/_theme/sphinx_rtd_theme/static/font/fontawesome_webfont.ttf
  80. BIN
      doc/source/_theme/sphinx_rtd_theme/static/font/fontawesome_webfont.woff
  81. 47 0
      doc/source/_theme/sphinx_rtd_theme/static/js/theme.js
  82. 8 0
      doc/source/_theme/sphinx_rtd_theme/theme.conf
  83. 37 0
      doc/source/_theme/sphinx_rtd_theme/versions.html
  84. 0 0
      doc/source/_theme/static/css/badge_only.css
  85. 0 0
      doc/source/_theme/static/css/theme.css
  86. BIN
      doc/source/_theme/static/font/fontawesome_webfont.eot
  87. 195 0
      doc/source/_theme/static/font/fontawesome_webfont.svg
  88. BIN
      doc/source/_theme/static/font/fontawesome_webfont.ttf
  89. BIN
      doc/source/_theme/static/font/fontawesome_webfont.woff
  90. 47 0
      doc/source/_theme/static/js/theme.js
  91. 8 0
      doc/source/_theme/theme.conf
  92. 37 0
      doc/source/_theme/versions.html
  93. 4 0
      doc/source/camlib.rst
  94. 265 0
      doc/source/conf.py
  95. 55 0
      doc/source/index.rst

+ 336 - 79
camlib.py

@@ -1,11 +1,13 @@
 from numpy import arctan2, Inf, array, sqrt, pi, ceil, sin, cos
 from matplotlib.figure import Figure
+import re
 
 # See: http://toblerity.org/shapely/manual.html
 from shapely.geometry import Polygon, LineString, Point, LinearRing
 from shapely.geometry import MultiPoint, MultiPolygon
 from shapely.geometry import box as shply_box
 from shapely.ops import cascaded_union
+import shapely.affinity as affinity
 
 # Used for solid polygons in Matplotlib
 from descartes.patch import PolygonPatch
@@ -74,16 +76,113 @@ class Geometry:
             else:
                 break
         return poly_cuts
+
+    def scale(self, factor):
+        """
+        Scales all of the object's geometry by a given factor. Override
+        this method.
+        :param factor: Number by which to scale.
+        :type factor: float
+        :return: None
+        :rtype: None
+        """
+        return
+
+    def convert_units(self, units):
+        """
+        Converts the units of the object to ``units`` by scaling all
+        the geometry appropriately.
+
+        :param units: "IN" or "MM"
+        :type units: str
+        :return: Scaling factor resulting from unit change.
+        :rtype: float
+        """
+
+        if units.upper() == self.units.upper():
+            return 1.0
+
+        if units.upper() == "MM":
+            factor = 25.4
+        elif units.upper() == "IN":
+            factor = 1/25.4
+        else:
+            print "Unsupported units:", units
+            return 1.0
+
+        self.units = units
+        self.scale(factor)
+        return factor
         
 
 class Gerber (Geometry):
+    """
+    **ATTRIBUTES**
+
+    * ``apertures`` (dict): The keys are names/identifiers of each aperture.
+      The values are dictionaries key/value pairs which describe the aperture. The
+      type key is always present and the rest depend on the key:
+
+    +-----------+-----------------------------------+
+    | Key       | Value                             |
+    +===========+===================================+
+    | type      | (str) "C", "R", or "O"            |
+    +-----------+-----------------------------------+
+    | others    | Depend on ``type``                |
+    +-----------+-----------------------------------+
+
+    * ``paths`` (list): A path is described by a line an aperture that follows that
+      line. Each paths[i] is a dictionary:
+
+    +------------+------------------------------------------------+
+    | Key        | Value                                          |
+    +============+================================================+
+    | linestring | (Shapely.LineString) The actual path.          |
+    +------------+------------------------------------------------+
+    | aperture   | (str) The key for an aperture in apertures.    |
+    +------------+------------------------------------------------+
+
+    * ``flashes`` (list): Flashes are single-point strokes of an aperture. Each
+      is a dictionary:
+
+    +------------+------------------------------------------------+
+    | Key        | Value                                          |
+    +============+================================================+
+    | loc        | (list) [x (float), y (float)] coordinates.     |
+    +------------+------------------------------------------------+
+    | aperture   | (str) The key for an aperture in apertures.    |
+    +------------+------------------------------------------------+
+
+    * ``regions`` (list): Are surfaces defined by a polygon (Shapely.Polygon),
+      which have an exterior and zero or more interiors. An aperture is also
+      associated with a region. Each is a dictionary:
+
+    +------------+-----------------------------------------------------+
+    | Key        | Value                                               |
+    +============+=====================================================+
+    | polygon    | (Shapely.Polygon) The polygon defining the region.  |
+    +------------+-----------------------------------------------------+
+    | aperture   | (str) The key for an aperture in apertures.         |
+    +------------+-----------------------------------------------------+
+
+    * ``flash_geometry`` (list): List of (Shapely) geometric object resulting
+      from ``flashes``. These are generated from ``flashes`` in ``do_flashes()``.
+
+    * ``buffered_paths`` (list): List of (Shapely) polygons resulting from
+      *buffering* (or thickening) the ``paths`` with the aperture. These are
+      generated from ``paths`` in ``buffer_paths()``.
+    """
+
     def __init__(self):
         # Initialize parent
         Geometry.__init__(self)        
         
         # Number format
         self.digits = 3
+        """Number of integer digits in Gerber numbers. Used during parsing."""
+
         self.fraction = 4
+        """Number of fraction digits in Gerber numbers. Used during parsing."""
         
         ## Gerber elements ##
         # Apertures {'id':{'type':chr, 
@@ -91,7 +190,7 @@ class Gerber (Geometry):
         #             ['height':float]}, ...}
         self.apertures = {}
         
-        # Paths [{'linestring':LineString, 'aperture':dict}]
+        # Paths [{'linestring':LineString, 'aperture':str}]
         self.paths = []
         
         # Buffered Paths [Polygon]
@@ -99,15 +198,61 @@ class Gerber (Geometry):
         # offsetting the aperture size/2
         self.buffered_paths = []
         
-        # Polygon regions [{'polygon':Polygon, 'aperture':dict}]
+        # Polygon regions [{'polygon':Polygon, 'aperture':str}]
         self.regions = []
         
-        # Flashes [{'loc':[float,float], 'aperture':dict}]
+        # Flashes [{'loc':[float,float], 'aperture':str}]
         self.flashes = []
         
         # Geometry from flashes
         self.flash_geometry = []
-        
+
+    def scale(self, factor):
+        """
+        Scales the objects' geometry on the XY plane by a given factor.
+        These are:
+
+        * ``apertures``
+        * ``paths``
+        * ``regions``
+        * ``flashes``
+
+        Then ``buffered_paths``, ``flash_geometry`` and ``solid_geometry``
+        are re-created with ``self.create_geometry()``.
+        :param factor: Number by which to scale.
+        :type factor: float
+        :rtype : None
+        """
+        # Apertures
+        print "Scaling apertures..."
+        for apid in self.apertures:
+            for param in self.apertures[apid]:
+                if param != "type":  # All others are dimensions.
+                    print "Tool:", apid, "Parameter:", param
+                    self.apertures[apid][param] *= factor
+
+        # Paths
+        print "Scaling paths..."
+        for path in self.paths:
+            path['linestring'] = affinity.scale(path['linestring'],
+                                                factor, factor, origin=(0, 0))
+
+        # Flashes
+        print "Scaling flashes..."
+        for fl in self.flashes:
+            # TODO: Shouldn't 'loc' be a numpy.array()?
+            fl['loc'][0] *= factor
+            fl['loc'][1] *= factor
+
+        # Regions
+        print "Scaling regions..."
+        for reg in self.regions:
+            reg['polygon'] = affinity.scale(reg['polygon'], factor, factor,
+                                            origin=(0, 0))
+
+        # Now buffered_paths, flash_geometry and solid_geometry
+        self.create_geometry()
+
     def fix_regions(self):
         """
         Overwrites the region polygons with fixed
@@ -125,8 +270,13 @@ class Gerber (Geometry):
     
     def aperture_parse(self, gline):
         """
-        Parse gerber aperture definition
-        into dictionary of apertures.
+        Parse gerber aperture definition into dictionary of apertures.
+        The following kinds and their attributes are supported:
+
+        * *Circular (C)*: size (float)
+        * *Rectangle (R)*: width (float), height (float)
+        * *Obround (O)*: width (float), height (float). NOTE: This can
+          be parsed, but it is not supported further yet.
         """
         indexstar = gline.find("*")
         indexc = gline.find("C,")
@@ -168,6 +318,10 @@ class Gerber (Geometry):
         """
         Main Gerber parser.
         """
+
+        # Mode (IN/MM)
+        mode_re = re.compile(r'^%MO(IN|MM)\*%$')
+
         path = []  # Coordinates of the current path
         last_path_aperture = None
         current_aperture = None
@@ -220,10 +374,17 @@ class Gerber (Geometry):
                 self.digits = int(gline[indexx + 1])
                 self.fraction = int(gline[indexx + 2])
                 continue
+
+            # Mode (IN/MM)
+            match = mode_re.search(gline)
+            if match:
+                self.units = match.group(1)
+                continue
+
             print "WARNING: Line ignored:", gline
         
         if len(path) > 1:
-            # EOF, create shapely LineString if something in path
+            # EOF, create shapely LineString if something still in path
             self.paths.append({"linestring": LineString(path),
                                "aperture": last_path_aperture})
     
@@ -250,11 +411,20 @@ class Gerber (Geometry):
                 self.flash_geometry.append(rectangle)
                 continue
             #TODO: Add support for type='O'
-            print "WARNING: Aperture type %s not implemented"%(aperture['type'])
+            print "WARNING: Aperture type %s not implemented" % (aperture['type'])
     
     def create_geometry(self):
-        if len(self.buffered_paths) == 0:
-            self.buffer_paths()
+        """
+        Geometry from a Gerber file is made up entirely of polygons.
+        Every stroke (linear or circular) has an aperture which gives
+        it thickness. Additionally, aperture strokes have non-zero area,
+        and regions naturally do as well.
+        :rtype : None
+        @return: None
+        """
+        # if len(self.buffered_paths) == 0:
+        #     self.buffer_paths()
+        self.buffer_paths()
         self.fix_regions()
         self.do_flashes()
         self.solid_geometry = cascaded_union(
@@ -264,12 +434,30 @@ class Gerber (Geometry):
 
 
 class Excellon(Geometry):
+    """
+    *ATTRIBUTES*
+
+    * ``tools`` (dict): The key is the tool name and the value is
+      the size (diameter).
+
+    * ``drills`` (list): Each is a dictionary:
+
+    ================  ====================================
+    Key               Value
+    ================  ====================================
+    point             (Shapely.Point) Where to drill
+    tool              (str) A key in ``tools``
+    ================  ====================================
+    """
     def __init__(self):
         Geometry.__init__(self)
         
         self.tools = {}
         
         self.drills = []
+
+        # Trailing "T" or leading "L"
+        self.zeros = ""
         
     def parse_file(self, filename):
         efile = open(filename, 'r')
@@ -281,6 +469,8 @@ class Excellon(Geometry):
         """
         Main Excellon parser.
         """
+        units_re = re.compile(r'^(INCH|METRIC)(?:,([TL])Z)?$')
+
         current_tool = ""
         
         for eline in elines:
@@ -291,10 +481,10 @@ class Excellon(Geometry):
             indexC = eline.find("C")
             indexF = eline.find("F")
             # Type 1
-            if indexT != -1 and indexC > indexT and indexF > indexF:
+            if indexT != -1 and indexC > indexT and indexF > indexC:
                 tool = eline[1:indexC]
                 spec = eline[indexC+1:indexF]
-                self.tools[tool] = spec
+                self.tools[tool] = float(spec)
                 continue
             # Type 2
             # TODO: Is this inches?
@@ -309,7 +499,7 @@ class Excellon(Geometry):
             if indexT != -1 and indexC > indexT:
                 tool = eline[1:indexC]
                 spec = eline[indexC+1:-1]
-                self.tools[tool] = spec
+                self.tools[tool] = float(spec)
                 continue
             
             ## Tool change
@@ -325,7 +515,13 @@ class Excellon(Geometry):
                 y = float(int(eline[indexy+1:-1])/10000.0)
                 self.drills.append({'point': Point((x, y)), 'tool': current_tool})
                 continue
-            
+
+            # Units and number format
+            match = units_re.match(eline)
+            if match:
+                self.zeros = match.group(2)  # "T" or "L"
+                self.units = {"INCH": "IN", "METRIC": "MM"}[match.group(1)]
+
             print "WARNING: Line ignored:", eline
         
     def create_geometry(self):
@@ -338,19 +534,49 @@ class Excellon(Geometry):
             self.solid_geometry.append(poly)
         self.solid_geometry = cascaded_union(self.solid_geometry)
 
+    def scale(self, factor):
+        """
+        Scales geometry on the XY plane in the object by a given factor.
+        Tool sizes, feedrates an Z-plane dimensions are untouched.
+        :param factor: Number by which to scale the object.
+        :type factor: float
+        :return: None
+        :rtype: NOne
+        """
+
+        # Drills
+        for drill in self.drills:
+            drill.point = affinity.scale(drill.point, factor, factor, origin=(0, 0))
+
+    def convert_units(self, units):
+        factor = Geometry.convert_units(self, units)
+
+        # Tools
+        for tname in self.tools:
+            self.tools[tname] *= factor
+
+        return factor
+
 
 class CNCjob(Geometry):
+    """
+    Represents work to be done by a CNC machine.
+
+    *ATTRIBUTES*
+
+    * ``gcode_parsed`` (list): Each is a dictionary:
+
+    =====================  =========================================
+    Key                    Value
+    =====================  =========================================
+    geom                   (Shapely.LineString) Tool path (XY plane)
+    kind                   (string) "AB", A is "T" (travel) or
+                           "C" (cut). B is "F" (fast) or "S" (slow).
+    =====================  =========================================
+    """
     def __init__(self, units="in", kind="generic", z_move=0.1,
                  feedrate=3.0, z_cut=-0.002, tooldia=0.0):
-        """
 
-            @param units:
-            @param kind:
-            @param z_move:
-            @param feedrate:
-            @param z_cut:
-            @param tooldia:
-            """
         Geometry.__init__(self)
         self.kind = kind
         self.units = units
@@ -358,17 +584,18 @@ class CNCjob(Geometry):
         self.z_move = z_move
         self.feedrate = feedrate
         self.tooldia = tooldia
-        self.unitcode = {"in": "G20", "mm": "G21"}
+        self.unitcode = {"IN": "G20", "MM": "G21"}
         self.pausecode = "G04 P1"
         self.feedminutecode = "G94"
         self.absolutecode = "G90"
         self.gcode = ""
         self.input_geometry_bounds = None
         self.gcode_parsed = None
+        self.steps_per_circ = 20  # Used when parsing G-code arcs
         
     def generate_from_excellon(self, exobj):
         """
-        Generates G-code for drilling from excellon text.
+        Generates G-code for drilling from Excellon object.
         self.gcode becomes a list, each element is a
         different job for each tool in the excellon code.
         """
@@ -387,7 +614,7 @@ class CNCjob(Geometry):
                 if drill['tool'] == tool:
                     points.append(drill['point'])
             
-            gcode = self.unitcode[self.units] + "\n"
+            gcode = self.unitcode[self.units.upper()] + "\n"
             gcode += self.absolutecode + "\n"
             gcode += self.feedminutecode + "\n"
             gcode += "F%.2f\n" % self.feedrate
@@ -435,7 +662,7 @@ class CNCjob(Geometry):
         down = "G01 Z%.4f\n" % self.z_cut
         up = "G01 Z%.4f\n" % self.z_move
 
-        gcode = self.unitcode[self.units] + "\n"
+        gcode = self.unitcode[self.units.upper()] + "\n"
         gcode += self.absolutecode + "\n"
         gcode += self.feedminutecode + "\n"
         gcode += "F%.2f\n" % self.feedrate
@@ -465,7 +692,7 @@ class CNCjob(Geometry):
         if not append:
             self.gcode = ""
 
-        self.gcode = self.unitcode[self.units] + "\n"
+        self.gcode = self.unitcode[self.units.upper()] + "\n"
         self.gcode += self.absolutecode + "\n"
         self.gcode += self.feedminutecode + "\n"
         self.gcode += "F%.2f\n" % self.feedrate
@@ -497,7 +724,63 @@ class CNCjob(Geometry):
         self.gcode += "G00 Z%.4f\n" % self.z_move  # Stop cutting
         self.gcode += "G00 X0Y0\n"
         self.gcode += "M05\n"  # Spindle stop
-    
+
+    def pre_parse(self, gtext):
+        """
+        gtext is a single string with g-code
+        """
+
+        # Units: G20-inches, G21-mm
+        units_re = re.compile(r'^G2([01])')
+
+        # TODO: This has to be re-done
+        gcmds = []
+        lines = gtext.split("\n")  # TODO: This is probably a lot of work!
+        for line in lines:
+            # Clean up
+            line = line.strip()
+
+            # Remove comments
+            # NOTE: Limited to 1 bracket pair
+            op = line.find("(")
+            cl = line.find(")")
+            if op > -1 and  cl > op:
+                #comment = line[op+1:cl]
+                line = line[:op] + line[(cl+1):]
+
+            # Units
+            match = units_re.match(line)
+            if match:
+                self.units = {'0': "IN", '1': "MM"}[match.group(1)]
+
+            # Parse GCode
+            # 0   4       12
+            # G01 X-0.007 Y-0.057
+            # --> codes_idx = [0, 4, 12]
+            codes = "NMGXYZIJFP"
+            codes_idx = []
+            i = 0
+            for ch in line:
+                if ch in codes:
+                    codes_idx.append(i)
+                i += 1
+            n_codes = len(codes_idx)
+            if n_codes == 0:
+                continue
+
+            # Separate codes in line
+            parts = []
+            for p in range(n_codes-1):
+                parts.append(line[codes_idx[p]:codes_idx[p+1]].strip())
+            parts.append(line[codes_idx[-1]:].strip())
+
+            # Separate codes from values
+            cmds = {}
+            for part in parts:
+                cmds[part[0]] = float(part[1:])
+            gcmds.append(cmds)
+        return gcmds
+
     def gcode_parse(self):
         """
         G-Code parser (from self.gcode). Generates dictionary with
@@ -505,14 +788,11 @@ class CNCjob(Geometry):
         fast or feedrate speed.
         """
 
-        # TODO: Make this a parameter
-        steps_per_circ = 20
-
         # Results go here
         geometry = []        
         
-        # TODO: ???? bring this into the class??
-        gobjs = gparse1b(self.gcode)
+        # TODO: Merge into single parser?
+        gobjs = self.pre_parse(self.gcode)
         
         # Last known instruction
         current = {'X': 0.0, 'Y': 0.0, 'Z': 0.0, 'G': 0}
@@ -549,7 +829,7 @@ class CNCjob(Geometry):
                     kind[1] = 'S'
                    
                 arcdir = [None, None, "cw", "ccw"]
-                if current['G'] in [0, 1]: # line
+                if current['G'] in [0, 1]:  # line
                     geometry.append({'geom': LineString([(current['X'], current['Y']),
                                                         (x, y)]), 'kind': kind})
                 if current['G'] in [2, 3]:  # arc
@@ -559,7 +839,7 @@ class CNCjob(Geometry):
                     stop = arctan2(-center[1]+y, -center[0]+x)
                     geometry.append({'geom': arc(center, radius, start, stop,
                                                  arcdir[current['G']],
-                                                 steps_per_circ),
+                                                 self.steps_per_circ),
                                      'kind': kind})
 
             # Update current instruction
@@ -676,51 +956,28 @@ class CNCjob(Geometry):
         gcode += "G01 Z%.4f\n" % self.z_cut       # Start cutting
         gcode += "G00 Z%.4f\n" % self.z_move      # Stop cutting
 
+    def scale(self, factor):
+        """
+        Scales all the geometry on the XY plane in the object by the
+        given factor. Tool sizes, feedrates, or Z-axis dimensions are
+        not altered.
+        :param factor: Number by which to scale the object.
+        :type factor: float
+        :return: None
+        :rtype: None
+        """
+        for g in self.gcode_parsed:
+            g['geom'] = affinity.scale(g['geom'], factor, factor, origin=(0, 0))
 
-def gparse1b(gtext):
-    """
-    gtext is a single string with g-code
-    """
-    gcmds = []
-    lines = gtext.split("\n")  # TODO: This is probably a lot of work!
-    for line in lines:
-        line = line.strip()
-        
-        # Remove comments
-        # NOTE: Limited to 1 bracket pair
-        op = line.find("(")
-        cl = line.find(")")
-        if  op > -1 and  cl > op:
-            #comment = line[op+1:cl]
-            line = line[:op] + line[(cl+1):]
-        
-        # Parse GCode
-        # 0   4       12 
-        # G01 X-0.007 Y-0.057
-        # --> codes_idx = [0, 4, 12]
-        codes = "NMGXYZIJFP"
-        codes_idx = []
-        i = 0
-        for ch in line:
-            if ch in codes:
-                codes_idx.append(i)
-            i += 1
-        n_codes = len(codes_idx)
-        if n_codes == 0:
-            continue
-        
-        # Separate codes in line
-        parts = []
-        for p in range(n_codes-1):
-            parts.append(line[codes_idx[p]:codes_idx[p+1]].strip())
-        parts.append(line[codes_idx[-1]:].strip())
-        
-        # Separate codes from values
-        cmds = {}
-        for part in parts:
-            cmds[part[0]] = float(part[1:])
-        gcmds.append(cmds)
-    return gcmds
+    def convert_units(self, units):
+        factor = Geometry.convert_units(self, units)
+
+        self.z_move *= factor
+        self.z_cut *= factor
+        self.feedrate *= factor
+        self.tooldia *= factor
+
+        return factor
 
 
 def get_bounds(geometry_set):

+ 98 - 25
cirkuix.py

@@ -54,14 +54,14 @@ class CirkuixObj:
             print "Clearing Axes"
             self.axes.cla()
 
-        self.axes.set_frame_on(False)
-        self.axes.set_xticks([])
-        self.axes.set_yticks([])
+        # Remove all decoration. The app's axes will have
+        # the ticks and grid.
+        self.axes.set_frame_on(False)  # No frame
+        self.axes.set_xticks([])  # No tick
+        self.axes.set_yticks([])  # No ticks
         self.axes.patch.set_visible(False)  # No background
         self.axes.set_aspect(1)
 
-        #return self.axes
-
     def set_options(self, options):
         for name in options:
             self.options[name] = options[name]
@@ -183,7 +183,7 @@ class CirkuixGerber(CirkuixObj, Gerber):
 
         self.kind = "gerber"
 
-        # The 'name' is already in self.options
+        # The 'name' is already in self.options from CirkuixObj
         self.options.update({
             "plot": True,
             "mergepolys": True,
@@ -198,7 +198,7 @@ class CirkuixGerber(CirkuixObj, Gerber):
             "bboxrounded": False
         })
 
-        # The 'name' is already in self.form_kinds
+        # The 'name' is already in self.form_kinds from CirkuixObj
         self.form_kinds.update({
             "plot": "cb",
             "mergepolys": "cb",
@@ -216,20 +216,27 @@ class CirkuixGerber(CirkuixObj, Gerber):
         self.radios = {"gaps": {"rb_2tb": "tb", "rb_2lr": "lr", "rb_4": "4"}}
         self.radios_inv = {"gaps": {"tb": "rb_2tb", "lr": "rb_2lr", "4": "rb_4"}}
 
+    def convert_units(self, units):
+        factor = Gerber.convert_units(self, units)
+
+        self.options['isotooldia'] *= factor
+        self.options['cutoutmargin'] *= factor
+        self.options['cutoutgapsize'] *= factor
+        self.options['noncoppermargin'] *= factor
+        self.options['bboxmargin'] *= factor
+
     def plot(self, figure):
         CirkuixObj.plot(self, figure)
 
         self.create_geometry()
 
-        geometry = None  # TODO: Test if needed
         if self.options["mergepolys"]:
             geometry = self.solid_geometry
         else:
             geometry = self.buffered_paths + \
-                        [poly['polygon'] for poly in self.regions] + \
-                        self.flash_geometry
+                       [poly['polygon'] for poly in self.regions] + \
+                       self.flash_geometry
 
-        linespec = None  # TODO: Test if needed
         if self.options["multicolored"]:
             linespec = '-'
         else:
@@ -242,6 +249,8 @@ class CirkuixGerber(CirkuixObj, Gerber):
                 x, y = ints.coords.xy
                 self.axes.plot(x, y, linespec)
 
+        self.app.canvas.queue_draw()
+
     def serialize(self):
         return {
             "options": self.options,
@@ -282,8 +291,16 @@ class CirkuixExcellon(CirkuixObj, Excellon):
 
         self.tool_cbs = {}
 
+    def convert_units(self, units):
+        factor = Excellon.convert_units(self, units)
+
+        self.options['drillz'] *= factor
+        self.options['travelz'] *= factor
+        self.options['feedrate'] *= factor
+
     def plot(self, figure):
-        self.setup_axes(figure)
+        CirkuixObj.plot(self, figure)
+        #self.setup_axes(figure)
         self.create_geometry()
 
         # Plot excellon
@@ -294,6 +311,9 @@ class CirkuixExcellon(CirkuixObj, Excellon):
                 x, y = ints.coords.xy
                 self.axes.plot(x, y, 'g-')
 
+        self.app.on_zoom_fit(None)
+        self.app.canvas.queue_draw()
+
     def show_tool_chooser(self):
         win = Gtk.Window()
         box = Gtk.Box(spacing=2)
@@ -318,6 +338,10 @@ class CirkuixExcellon(CirkuixObj, Excellon):
         button.connect("activate", on_accept)
         button.connect("clicked", on_accept)
 
+    # def parse_lines(self, elines):
+    #     Excellon.parse_lines(self, elines)
+    #     self.options["units"] = self.units
+
 
 class CirkuixCNCjob(CirkuixObj, CNCjob):
     """
@@ -346,9 +370,11 @@ class CirkuixCNCjob(CirkuixObj, CNCjob):
         })
 
     def plot(self, figure):
-        self.setup_axes(figure)
+        CirkuixObj.plot(self, figure)
+        #self.setup_axes(figure)
         self.plot2(self.axes, tooldia=self.options["tooldia"])
-        app.canvas.queue_draw()
+        self.app.on_zoom_fit(None)
+        self.app.canvas.queue_draw()
 
 
 class CirkuixGeometry(CirkuixObj, Geometry):
@@ -359,6 +385,7 @@ class CirkuixGeometry(CirkuixObj, Geometry):
 
     def __init__(self, name):
         CirkuixObj.__init__(self, name)
+        Geometry.__init__(self)
 
         self.kind = "geometry"
 
@@ -388,8 +415,32 @@ class CirkuixGeometry(CirkuixObj, Geometry):
             "paintmargin": "entry_eval"
         })
 
+    # def convert_units(self, units):
+    #     factor = Geometry.convert_units(self, units)
+
+    def scale(self, factor):
+        if type(self.solid_geometry) == list:
+            self.solid_geometry = [affinity.scale(g, factor, factor, origin=(0, 0))
+                                   for g in self.solid_geometry]
+        else:
+            self.solid_geometry = affinity.scale(self.solid_geometry, factor, factor,
+                                                 origin=(0, 0))
+
+    def convert_units(self, units):
+        factor = Geometry.convert_units(self, units)
+
+        self.options['cutz'] *= factor
+        self.options['travelz'] *= factor
+        self.options['feedrate'] *= factor
+        self.options['cnctooldia'] *= factor
+        self.options['painttooldia'] *= factor
+        self.options['paintmargin'] *= factor
+
+        return factor
+
     def plot(self, figure):
-        self.setup_axes(figure)
+        CirkuixObj.plot(self, figure)
+        #self.setup_axes(figure)
 
         try:
             _ = iter(self.solid_geometry)
@@ -422,6 +473,9 @@ class CirkuixGeometry(CirkuixObj, Geometry):
 
             print "WARNING: Did not plot:", str(type(geo))
 
+        self.app.on_zoom_fit(None)
+        self.app.canvas.queue_draw()
+
 
 ########################################
 ##                App                 ##
@@ -499,7 +553,6 @@ class App:
         ########################################
         self.window.set_default_size(900, 600)
         self.window.show_all()
-        #Gtk.main()
         
     def setup_plot(self):
         """
@@ -722,18 +775,23 @@ class App:
         """
         Creates a new specalized CirkuixObj and attaches it to the application,
         this is, updates the GUI accordingly, any other records and plots it.
-        @param kind: Knd of object to create.
-        @param name: Name for the object.
-        @param initilize: Function to run after the
-            object has been created but before attacing it
-            to the application. Takes the new object and the
-            app as parameters.
-        @return: The object requested
-        @rtype : CirkuixObj extended
+
+        :param kind: The kind of object to create. One of 'gerber',
+         'excellon', 'cncjob' and 'geometry'.
+        :type kind: str
+        :param name: Name for the object.
+        :type name: str
+        :param initialize: Function to run after creation of the object
+         but before it is attached to the application. The function is
+         called with 2 parameters: the new object and the App instance.
+        :type initialize: function
+        :return: None
+        :rtype: None
         """
 
         # Check for existing name
         if name in self.stuff:
+            self.info("Rename " + name + " in project first.")
             return None
 
         # Create object
@@ -751,6 +809,11 @@ class App:
         # have been invoked in a separate thread.
         initialize(obj, self)
 
+        # Check units and convert if necessary
+        if self.options["units"].upper() != obj.units.upper():
+            GLib.idle_add(lambda: self.info("Converting units to " + self.options["units"] + "."))
+            obj.convert_units(self.options["units"])
+
         # Add to our records
         self.stuff[name] = obj
 
@@ -845,6 +908,13 @@ class App:
     ##         EVENT HANDLERS             ##
     ########################################
 
+    def on_scale_object(self, widget):
+        obj = self.get_current()
+        factor = self.get_eval("entry_eval_" + obj.kind + "_scalefactor")
+        obj.scale(factor)
+        obj.to_form()
+        self.on_update_plot(None)
+
     def on_canvas_configure(self, widget, event):
         print "on_canvas_configure()"
 
@@ -883,8 +953,11 @@ class App:
         #GLib.idle_add(lambda: self.set_progress_bar(0.5, "Plotting..."))
 
         def thread_func(app_obj):
+            assert isinstance(app_obj, App)
             #GLib.idle_add(lambda: app_obj.set_progress_bar(0.5, "Plotting..."))
-            GLib.idle_add(lambda: app_obj.get_current().plot(app_obj.figure))
+            #GLib.idle_add(lambda: app_obj.get_current().plot(app_obj.figure))
+            app_obj.get_current().plot(app_obj.figure)
+            GLib.idle_add(lambda: app_obj.on_zoom_fit(None))
             GLib.timeout_add(300, lambda: app_obj.set_progress_bar(0.0, ""))
 
         t = threading.Thread(target=thread_func, args=(self,))

+ 325 - 3
cirkuix.ui

@@ -243,6 +243,80 @@
                     <property name="position">9</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkLabel" id="label45">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">3</property>
+                    <property name="xalign">0</property>
+                    <property name="ypad">3</property>
+                    <property name="label" translatable="yes">Scale:</property>
+                    <attributes>
+                      <attribute name="weight" value="semibold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">10</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box13">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">3</property>
+                    <property name="margin_bottom">3</property>
+                    <property name="spacing">3</property>
+                    <child>
+                      <object class="GtkLabel" id="label46">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Factor:</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="entry_eval_cncjob_scalefactor">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">●</property>
+                        <property name="text" translatable="yes">1.0</property>
+                        <property name="invisible_char_set">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">11</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="button14">
+                    <property name="label" translatable="yes">Scale</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <signal name="activate" handler="on_scale_object" swapped="no"/>
+                    <signal name="clicked" handler="on_scale_object" swapped="no"/>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">12</property>
+                  </packing>
+                </child>
               </object>
             </child>
           </object>
@@ -589,6 +663,86 @@
                     <property name="position">9</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkLabel" id="label47">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">3</property>
+                    <property name="xalign">0</property>
+                    <property name="ypad">3</property>
+                    <property name="label" translatable="yes">Scale:</property>
+                    <attributes>
+                      <attribute name="weight" value="semibold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">10</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box14">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">3</property>
+                    <property name="margin_bottom">3</property>
+                    <property name="spacing">3</property>
+                    <child>
+                      <object class="GtkLabel" id="label48">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Factor:</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="entry_eval_excellon_scalefactor">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">●</property>
+                        <property name="text" translatable="yes">1.0</property>
+                        <property name="invisible_char_set">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">11</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="button15">
+                    <property name="label" translatable="yes">Scale</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <signal name="activate" handler="on_scale_object" swapped="no"/>
+                    <signal name="clicked" handler="on_scale_object" swapped="no"/>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">12</property>
+                  </packing>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
               </object>
             </child>
           </object>
@@ -1044,6 +1198,83 @@
                     <property name="position">12</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkLabel" id="label49">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">3</property>
+                    <property name="xalign">0</property>
+                    <property name="ypad">3</property>
+                    <property name="label" translatable="yes">Scale:</property>
+                    <attributes>
+                      <attribute name="weight" value="semibold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">13</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box15">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">3</property>
+                    <property name="margin_bottom">3</property>
+                    <property name="spacing">3</property>
+                    <child>
+                      <object class="GtkLabel" id="label50">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Factor:</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="entry_eval_geometry_scalefactor">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">●</property>
+                        <property name="text" translatable="yes">1.0</property>
+                        <property name="invisible_char_set">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">14</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="button16">
+                    <property name="label" translatable="yes">Scale</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <signal name="activate" handler="on_scale_object" swapped="no"/>
+                    <signal name="clicked" handler="on_scale_object" swapped="no"/>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">15</property>
+                  </packing>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
                 <child>
                   <placeholder/>
                 </child>
@@ -1648,6 +1879,83 @@
                     <property name="position">20</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkLabel" id="label51">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">3</property>
+                    <property name="xalign">0</property>
+                    <property name="ypad">3</property>
+                    <property name="label" translatable="yes">Scale:</property>
+                    <attributes>
+                      <attribute name="weight" value="semibold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">21</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box16">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">3</property>
+                    <property name="margin_bottom">3</property>
+                    <property name="spacing">3</property>
+                    <child>
+                      <object class="GtkLabel" id="label52">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">Factor:</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="entry_eval_gerber_scalefactor">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="invisible_char">●</property>
+                        <property name="text" translatable="yes">1.0</property>
+                        <property name="invisible_char_set">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">22</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="button17">
+                    <property name="label" translatable="yes">Scale</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <signal name="activate" handler="on_scale_object" swapped="no"/>
+                    <signal name="clicked" handler="on_scale_object" swapped="no"/>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">23</property>
+                  </packing>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
                 <child>
                   <placeholder/>
                 </child>
@@ -1977,12 +2285,12 @@
                         <property name="can_focus">False</property>
                         <property name="orientation">vertical</property>
                         <child>
-                          <object class="GtkLabel" id="label43">
+                          <object class="GtkLabel" id="label44">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
                             <property name="margin_top">5</property>
                             <property name="ypad">3</property>
-                            <property name="label" translatable="yes">APLICATION DEFAULTS</property>
+                            <property name="label" translatable="yes">PROJECT</property>
                             <attributes>
                               <attribute name="weight" value="semibold"/>
                             </attributes>
@@ -2032,7 +2340,21 @@
                           </packing>
                         </child>
                         <child>
-                          <placeholder/>
+                          <object class="GtkLabel" id="label43">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="margin_top">5</property>
+                            <property name="ypad">3</property>
+                            <property name="label" translatable="yes">APLICATION</property>
+                            <attributes>
+                              <attribute name="weight" value="semibold"/>
+                            </attributes>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">2</property>
+                          </packing>
                         </child>
                         <child>
                           <placeholder/>

+ 177 - 0
doc/Makefile

@@ -0,0 +1,177 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = build
+
+# User-friendly check for sphinx-build
+ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
+$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
+endif
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html       to make standalone HTML files"
+	@echo "  dirhtml    to make HTML files named index.html in directories"
+	@echo "  singlehtml to make a single large HTML file"
+	@echo "  pickle     to make pickle files"
+	@echo "  json       to make JSON files"
+	@echo "  htmlhelp   to make HTML files and a HTML help project"
+	@echo "  qthelp     to make HTML files and a qthelp project"
+	@echo "  devhelp    to make HTML files and a Devhelp project"
+	@echo "  epub       to make an epub"
+	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+	@echo "  latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
+	@echo "  text       to make text files"
+	@echo "  man        to make manual pages"
+	@echo "  texinfo    to make Texinfo files"
+	@echo "  info       to make Texinfo files and run them through makeinfo"
+	@echo "  gettext    to make PO message catalogs"
+	@echo "  changes    to make an overview of all changed/added/deprecated items"
+	@echo "  xml        to make Docutils-native XML files"
+	@echo "  pseudoxml  to make pseudoxml-XML files for display purposes"
+	@echo "  linkcheck  to check all external links for integrity"
+	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+	rm -rf $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+	@echo
+	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Cirkuix.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Cirkuix.qhc"
+
+devhelp:
+	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+	@echo
+	@echo "Build finished."
+	@echo "To view the help file:"
+	@echo "# mkdir -p $$HOME/.local/share/devhelp/Cirkuix"
+	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Cirkuix"
+	@echo "# devhelp"
+
+epub:
+	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+	@echo
+	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make' in that directory to run these through (pdf)latex" \
+	      "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo "Running LaTeX files through pdflatex..."
+	$(MAKE) -C $(BUILDDIR)/latex all-pdf
+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+latexpdfja:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo "Running LaTeX files through platex and dvipdfmx..."
+	$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+	@echo
+	@echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+	@echo
+	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+	@echo
+	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+	@echo "Run \`make' in that directory to run these through makeinfo" \
+	      "(use \`make info' here to do that automatically)."
+
+info:
+	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+	@echo "Running Texinfo files through makeinfo..."
+	make -C $(BUILDDIR)/texinfo info
+	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+	@echo
+	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."
+
+xml:
+	$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
+	@echo
+	@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
+
+pseudoxml:
+	$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
+	@echo
+	@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."

+ 4 - 0
doc/build/.buildinfo

@@ -0,0 +1,4 @@
+# Sphinx build info version 1
+# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
+config: 5d14861db364fd07def06ca8fd4c733a
+tags: 645f666f9bcd5a90fca523b33c5a78b7

BIN
doc/build/.doctrees/camlib.doctree


BIN
doc/build/.doctrees/environment.pickle


BIN
doc/build/.doctrees/index.doctree


+ 4 - 0
doc/build/_sources/camlib.txt

@@ -0,0 +1,4 @@
+This is the main file for camlib
+=================================
+
+Some text.

+ 55 - 0
doc/build/_sources/index.txt

@@ -0,0 +1,55 @@
+.. Cirkuix documentation master file, created by
+   sphinx-quickstart on Fri Jan 24 22:13:35 2014.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+
+
+Welcome to Cirkuix's documentation!
+===================================
+
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+.. automodule:: cirkuix
+
+.. autoclass:: App
+    :members:
+
+.. autoclass:: Geometry
+    :members:
+
+.. autoclass:: Gerber(Geometry)
+    :members:
+
+.. autoclass:: Excellon
+    :members:
+
+.. autoclass:: CNCjob
+    :members:
+
+.. autoclass:: CirkuixObj
+    :members:
+
+.. autoclass:: CirkuixGerber
+    :members:
+
+.. autoclass:: CirkuixExcellon
+    :members:
+
+.. autoclass:: CirkuixCNCjob
+    :members:
+
+.. autoclass:: CirkuixGeometry
+    :members:
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+

BIN
doc/build/_static/ajax-loader.gif


+ 536 - 0
doc/build/_static/basic.css

@@ -0,0 +1,536 @@
+/*
+ * basic.css
+ * ~~~~~~~~~
+ *
+ * Sphinx stylesheet -- basic theme.
+ *
+ * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/* -- main layout ----------------------------------------------------------- */
+
+div.clearer {
+    clear: both;
+}
+
+/* -- relbar ---------------------------------------------------------------- */
+
+div.related {
+    width: 100%;
+    font-size: 90%;
+}
+
+div.related h3 {
+    display: none;
+}
+
+div.related ul {
+    margin: 0;
+    padding: 0 0 0 10px;
+    list-style: none;
+}
+
+div.related li {
+    display: inline;
+}
+
+div.related li.right {
+    float: right;
+    margin-right: 5px;
+}
+
+/* -- sidebar --------------------------------------------------------------- */
+
+div.sphinxsidebarwrapper {
+    padding: 10px 5px 0 10px;
+}
+
+div.sphinxsidebar {
+    float: left;
+    width: 230px;
+    margin-left: -100%;
+    font-size: 90%;
+}
+
+div.sphinxsidebar ul {
+    list-style: none;
+}
+
+div.sphinxsidebar ul ul,
+div.sphinxsidebar ul.want-points {
+    margin-left: 20px;
+    list-style: square;
+}
+
+div.sphinxsidebar ul ul {
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+div.sphinxsidebar form {
+    margin-top: 10px;
+}
+
+div.sphinxsidebar input {
+    border: 1px solid #98dbcc;
+    font-family: sans-serif;
+    font-size: 1em;
+}
+
+div.sphinxsidebar #searchbox input[type="text"] {
+    width: 170px;
+}
+
+div.sphinxsidebar #searchbox input[type="submit"] {
+    width: 30px;
+}
+
+img {
+    border: 0;
+}
+
+/* -- search page ----------------------------------------------------------- */
+
+ul.search {
+    margin: 10px 0 0 20px;
+    padding: 0;
+}
+
+ul.search li {
+    padding: 5px 0 5px 20px;
+    background-image: url(file.png);
+    background-repeat: no-repeat;
+    background-position: 0 7px;
+}
+
+ul.search li a {
+    font-weight: bold;
+}
+
+ul.search li div.context {
+    color: #888;
+    margin: 2px 0 0 30px;
+    text-align: left;
+}
+
+ul.keywordmatches li.goodmatch a {
+    font-weight: bold;
+}
+
+/* -- index page ------------------------------------------------------------ */
+
+table.contentstable {
+    width: 90%;
+}
+
+table.contentstable p.biglink {
+    line-height: 150%;
+}
+
+a.biglink {
+    font-size: 1.3em;
+}
+
+span.linkdescr {
+    font-style: italic;
+    padding-top: 5px;
+    font-size: 90%;
+}
+
+/* -- general index --------------------------------------------------------- */
+
+table.indextable {
+    width: 100%;
+}
+
+table.indextable td {
+    text-align: left;
+    vertical-align: top;
+}
+
+table.indextable dl, table.indextable dd {
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+table.indextable tr.pcap {
+    height: 10px;
+}
+
+table.indextable tr.cap {
+    margin-top: 10px;
+    background-color: #f2f2f2;
+}
+
+img.toggler {
+    margin-right: 3px;
+    margin-top: 3px;
+    cursor: pointer;
+}
+
+div.modindex-jumpbox {
+    border-top: 1px solid #ddd;
+    border-bottom: 1px solid #ddd;
+    margin: 1em 0 1em 0;
+    padding: 0.4em;
+}
+
+div.genindex-jumpbox {
+    border-top: 1px solid #ddd;
+    border-bottom: 1px solid #ddd;
+    margin: 1em 0 1em 0;
+    padding: 0.4em;
+}
+
+/* -- general body styles --------------------------------------------------- */
+
+a.headerlink {
+    visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink {
+    visibility: visible;
+}
+
+div.body p.caption {
+    text-align: inherit;
+}
+
+div.body td {
+    text-align: left;
+}
+
+.field-list ul {
+    padding-left: 1em;
+}
+
+.first {
+    margin-top: 0 !important;
+}
+
+p.rubric {
+    margin-top: 30px;
+    font-weight: bold;
+}
+
+img.align-left, .figure.align-left, object.align-left {
+    clear: left;
+    float: left;
+    margin-right: 1em;
+}
+
+img.align-right, .figure.align-right, object.align-right {
+    clear: right;
+    float: right;
+    margin-left: 1em;
+}
+
+img.align-center, .figure.align-center, object.align-center {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+.align-left {
+    text-align: left;
+}
+
+.align-center {
+    text-align: center;
+}
+
+.align-right {
+    text-align: right;
+}
+
+/* -- sidebars -------------------------------------------------------------- */
+
+div.sidebar {
+    margin: 0 0 0.5em 1em;
+    border: 1px solid #ddb;
+    padding: 7px 7px 0 7px;
+    background-color: #ffe;
+    width: 40%;
+    float: right;
+}
+
+p.sidebar-title {
+    font-weight: bold;
+}
+
+/* -- topics ---------------------------------------------------------------- */
+
+div.topic {
+    border: 1px solid #ccc;
+    padding: 7px 7px 0 7px;
+    margin: 10px 0 10px 0;
+}
+
+p.topic-title {
+    font-size: 1.1em;
+    font-weight: bold;
+    margin-top: 10px;
+}
+
+/* -- admonitions ----------------------------------------------------------- */
+
+div.admonition {
+    margin-top: 10px;
+    margin-bottom: 10px;
+    padding: 7px;
+}
+
+div.admonition dt {
+    font-weight: bold;
+}
+
+div.admonition dl {
+    margin-bottom: 0;
+}
+
+p.admonition-title {
+    margin: 0px 10px 5px 0px;
+    font-weight: bold;
+}
+
+div.body p.centered {
+    text-align: center;
+    margin-top: 25px;
+}
+
+/* -- tables ---------------------------------------------------------------- */
+
+table.docutils {
+    border: 0;
+    border-collapse: collapse;
+}
+
+table.docutils td, table.docutils th {
+    padding: 1px 8px 1px 5px;
+    border-top: 0;
+    border-left: 0;
+    border-right: 0;
+    border-bottom: 1px solid #aaa;
+}
+
+table.field-list td, table.field-list th {
+    border: 0 !important;
+}
+
+table.footnote td, table.footnote th {
+    border: 0 !important;
+}
+
+th {
+    text-align: left;
+    padding-right: 5px;
+}
+
+table.citation {
+    border-left: solid 1px gray;
+    margin-left: 1px;
+}
+
+table.citation td {
+    border-bottom: none;
+}
+
+/* -- other body styles ----------------------------------------------------- */
+
+ol.arabic {
+    list-style: decimal;
+}
+
+ol.loweralpha {
+    list-style: lower-alpha;
+}
+
+ol.upperalpha {
+    list-style: upper-alpha;
+}
+
+ol.lowerroman {
+    list-style: lower-roman;
+}
+
+ol.upperroman {
+    list-style: upper-roman;
+}
+
+dl {
+    margin-bottom: 15px;
+}
+
+dd p {
+    margin-top: 0px;
+}
+
+dd ul, dd table {
+    margin-bottom: 10px;
+}
+
+dd {
+    margin-top: 3px;
+    margin-bottom: 10px;
+    margin-left: 30px;
+}
+
+dt:target, .highlighted {
+    background-color: #fbe54e;
+}
+
+dl.glossary dt {
+    font-weight: bold;
+    font-size: 1.1em;
+}
+
+.field-list ul {
+    margin: 0;
+    padding-left: 1em;
+}
+
+.field-list p {
+    margin: 0;
+}
+
+.optional {
+    font-size: 1.3em;
+}
+
+.versionmodified {
+    font-style: italic;
+}
+
+.system-message {
+    background-color: #fda;
+    padding: 5px;
+    border: 3px solid red;
+}
+
+.footnote:target  {
+    background-color: #ffa;
+}
+
+.line-block {
+    display: block;
+    margin-top: 1em;
+    margin-bottom: 1em;
+}
+
+.line-block .line-block {
+    margin-top: 0;
+    margin-bottom: 0;
+    margin-left: 1.5em;
+}
+
+.guilabel, .menuselection {
+    font-family: sans-serif;
+}
+
+.accelerator {
+    text-decoration: underline;
+}
+
+.classifier {
+    font-style: oblique;
+}
+
+abbr, acronym {
+    border-bottom: dotted 1px;
+    cursor: help;
+}
+
+/* -- code displays --------------------------------------------------------- */
+
+pre {
+    overflow: auto;
+    overflow-y: hidden;  /* fixes display issues on Chrome browsers */
+}
+
+td.linenos pre {
+    padding: 5px 0px;
+    border: 0;
+    background-color: transparent;
+    color: #aaa;
+}
+
+table.highlighttable {
+    margin-left: 0.5em;
+}
+
+table.highlighttable td {
+    padding: 0 0.5em 0 0.5em;
+}
+
+tt.descname {
+    background-color: transparent;
+    font-weight: bold;
+    font-size: 1.2em;
+}
+
+tt.descclassname {
+    background-color: transparent;
+}
+
+tt.xref, a tt {
+    background-color: transparent;
+    font-weight: bold;
+}
+
+h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
+    background-color: transparent;
+}
+
+.viewcode-link {
+    float: right;
+}
+
+.viewcode-back {
+    float: right;
+    font-family: sans-serif;
+}
+
+div.viewcode-block:target {
+    margin: -1px -10px;
+    padding: 0 10px;
+}
+
+/* -- math display ---------------------------------------------------------- */
+
+img.math {
+    vertical-align: middle;
+}
+
+div.body div.math p {
+    text-align: center;
+}
+
+span.eqno {
+    float: right;
+}
+
+/* -- printout stylesheet --------------------------------------------------- */
+
+@media print {
+    div.document,
+    div.documentwrapper,
+    div.bodywrapper {
+        margin: 0 !important;
+        width: 100%;
+    }
+
+    div.sphinxsidebar,
+    div.related,
+    div.footer,
+    #top-link {
+        display: none;
+    }
+}

BIN
doc/build/_static/comment-bright.png


BIN
doc/build/_static/comment-close.png


BIN
doc/build/_static/comment.png


BIN
doc/build/_static/contents.png


Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
doc/build/_static/css/badge_only.css


Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
doc/build/_static/css/theme.css


+ 256 - 0
doc/build/_static/default.css

@@ -0,0 +1,256 @@
+/*
+ * default.css_t
+ * ~~~~~~~~~~~~~
+ *
+ * Sphinx stylesheet -- default theme.
+ *
+ * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+@import url("basic.css");
+
+/* -- page layout ----------------------------------------------------------- */
+
+body {
+    font-family: sans-serif;
+    font-size: 100%;
+    background-color: #11303d;
+    color: #000;
+    margin: 0;
+    padding: 0;
+}
+
+div.document {
+    background-color: #1c4e63;
+}
+
+div.documentwrapper {
+    float: left;
+    width: 100%;
+}
+
+div.bodywrapper {
+    margin: 0 0 0 230px;
+}
+
+div.body {
+    background-color: #ffffff;
+    color: #000000;
+    padding: 0 20px 30px 20px;
+}
+
+div.footer {
+    color: #ffffff;
+    width: 100%;
+    padding: 9px 0 9px 0;
+    text-align: center;
+    font-size: 75%;
+}
+
+div.footer a {
+    color: #ffffff;
+    text-decoration: underline;
+}
+
+div.related {
+    background-color: #133f52;
+    line-height: 30px;
+    color: #ffffff;
+}
+
+div.related a {
+    color: #ffffff;
+}
+
+div.sphinxsidebar {
+}
+
+div.sphinxsidebar h3 {
+    font-family: 'Trebuchet MS', sans-serif;
+    color: #ffffff;
+    font-size: 1.4em;
+    font-weight: normal;
+    margin: 0;
+    padding: 0;
+}
+
+div.sphinxsidebar h3 a {
+    color: #ffffff;
+}
+
+div.sphinxsidebar h4 {
+    font-family: 'Trebuchet MS', sans-serif;
+    color: #ffffff;
+    font-size: 1.3em;
+    font-weight: normal;
+    margin: 5px 0 0 0;
+    padding: 0;
+}
+
+div.sphinxsidebar p {
+    color: #ffffff;
+}
+
+div.sphinxsidebar p.topless {
+    margin: 5px 10px 10px 10px;
+}
+
+div.sphinxsidebar ul {
+    margin: 10px;
+    padding: 0;
+    color: #ffffff;
+}
+
+div.sphinxsidebar a {
+    color: #98dbcc;
+}
+
+div.sphinxsidebar input {
+    border: 1px solid #98dbcc;
+    font-family: sans-serif;
+    font-size: 1em;
+}
+
+
+
+/* -- hyperlink styles ------------------------------------------------------ */
+
+a {
+    color: #355f7c;
+    text-decoration: none;
+}
+
+a:visited {
+    color: #355f7c;
+    text-decoration: none;
+}
+
+a:hover {
+    text-decoration: underline;
+}
+
+
+
+/* -- body styles ----------------------------------------------------------- */
+
+div.body h1,
+div.body h2,
+div.body h3,
+div.body h4,
+div.body h5,
+div.body h6 {
+    font-family: 'Trebuchet MS', sans-serif;
+    background-color: #f2f2f2;
+    font-weight: normal;
+    color: #20435c;
+    border-bottom: 1px solid #ccc;
+    margin: 20px -20px 10px -20px;
+    padding: 3px 0 3px 10px;
+}
+
+div.body h1 { margin-top: 0; font-size: 200%; }
+div.body h2 { font-size: 160%; }
+div.body h3 { font-size: 140%; }
+div.body h4 { font-size: 120%; }
+div.body h5 { font-size: 110%; }
+div.body h6 { font-size: 100%; }
+
+a.headerlink {
+    color: #c60f0f;
+    font-size: 0.8em;
+    padding: 0 4px 0 4px;
+    text-decoration: none;
+}
+
+a.headerlink:hover {
+    background-color: #c60f0f;
+    color: white;
+}
+
+div.body p, div.body dd, div.body li {
+    text-align: justify;
+    line-height: 130%;
+}
+
+div.admonition p.admonition-title + p {
+    display: inline;
+}
+
+div.admonition p {
+    margin-bottom: 5px;
+}
+
+div.admonition pre {
+    margin-bottom: 5px;
+}
+
+div.admonition ul, div.admonition ol {
+    margin-bottom: 5px;
+}
+
+div.note {
+    background-color: #eee;
+    border: 1px solid #ccc;
+}
+
+div.seealso {
+    background-color: #ffc;
+    border: 1px solid #ff6;
+}
+
+div.topic {
+    background-color: #eee;
+}
+
+div.warning {
+    background-color: #ffe4e4;
+    border: 1px solid #f66;
+}
+
+p.admonition-title {
+    display: inline;
+}
+
+p.admonition-title:after {
+    content: ":";
+}
+
+pre {
+    padding: 5px;
+    background-color: #eeffcc;
+    color: #333333;
+    line-height: 120%;
+    border: 1px solid #ac9;
+    border-left: none;
+    border-right: none;
+}
+
+tt {
+    background-color: #ecf0f3;
+    padding: 0 1px 0 1px;
+    font-size: 0.95em;
+}
+
+th {
+    background-color: #ede;
+}
+
+.warning tt {
+    background: #efc2c2;
+}
+
+.note tt {
+    background: #d6d6d6;
+}
+
+.viewcode-back {
+    font-family: sans-serif;
+}
+
+div.viewcode-block:target {
+    background-color: #f4debf;
+    border-top: 1px solid #ac9;
+    border-bottom: 1px solid #ac9;
+}

BIN
doc/build/_static/dialog-note.png


BIN
doc/build/_static/dialog-seealso.png


BIN
doc/build/_static/dialog-todo.png


BIN
doc/build/_static/dialog-topic.png


BIN
doc/build/_static/dialog-warning.png


+ 235 - 0
doc/build/_static/doctools.js

@@ -0,0 +1,235 @@
+/*
+ * doctools.js
+ * ~~~~~~~~~~~
+ *
+ * Sphinx JavaScript utilities for all documentation.
+ *
+ * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/**
+ * select a different prefix for underscore
+ */
+$u = _.noConflict();
+
+/**
+ * make the code below compatible with browsers without
+ * an installed firebug like debugger
+if (!window.console || !console.firebug) {
+  var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
+    "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
+    "profile", "profileEnd"];
+  window.console = {};
+  for (var i = 0; i < names.length; ++i)
+    window.console[names[i]] = function() {};
+}
+ */
+
+/**
+ * small helper function to urldecode strings
+ */
+jQuery.urldecode = function(x) {
+  return decodeURIComponent(x).replace(/\+/g, ' ');
+};
+
+/**
+ * small helper function to urlencode strings
+ */
+jQuery.urlencode = encodeURIComponent;
+
+/**
+ * This function returns the parsed url parameters of the
+ * current request. Multiple values per key are supported,
+ * it will always return arrays of strings for the value parts.
+ */
+jQuery.getQueryParameters = function(s) {
+  if (typeof s == 'undefined')
+    s = document.location.search;
+  var parts = s.substr(s.indexOf('?') + 1).split('&');
+  var result = {};
+  for (var i = 0; i < parts.length; i++) {
+    var tmp = parts[i].split('=', 2);
+    var key = jQuery.urldecode(tmp[0]);
+    var value = jQuery.urldecode(tmp[1]);
+    if (key in result)
+      result[key].push(value);
+    else
+      result[key] = [value];
+  }
+  return result;
+};
+
+/**
+ * highlight a given string on a jquery object by wrapping it in
+ * span elements with the given class name.
+ */
+jQuery.fn.highlightText = function(text, className) {
+  function highlight(node) {
+    if (node.nodeType == 3) {
+      var val = node.nodeValue;
+      var pos = val.toLowerCase().indexOf(text);
+      if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {
+        var span = document.createElement("span");
+        span.className = className;
+        span.appendChild(document.createTextNode(val.substr(pos, text.length)));
+        node.parentNode.insertBefore(span, node.parentNode.insertBefore(
+          document.createTextNode(val.substr(pos + text.length)),
+          node.nextSibling));
+        node.nodeValue = val.substr(0, pos);
+      }
+    }
+    else if (!jQuery(node).is("button, select, textarea")) {
+      jQuery.each(node.childNodes, function() {
+        highlight(this);
+      });
+    }
+  }
+  return this.each(function() {
+    highlight(this);
+  });
+};
+
+/**
+ * Small JavaScript module for the documentation.
+ */
+var Documentation = {
+
+  init : function() {
+    this.fixFirefoxAnchorBug();
+    this.highlightSearchWords();
+    this.initIndexTable();
+  },
+
+  /**
+   * i18n support
+   */
+  TRANSLATIONS : {},
+  PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
+  LOCALE : 'unknown',
+
+  // gettext and ngettext don't access this so that the functions
+  // can safely bound to a different name (_ = Documentation.gettext)
+  gettext : function(string) {
+    var translated = Documentation.TRANSLATIONS[string];
+    if (typeof translated == 'undefined')
+      return string;
+    return (typeof translated == 'string') ? translated : translated[0];
+  },
+
+  ngettext : function(singular, plural, n) {
+    var translated = Documentation.TRANSLATIONS[singular];
+    if (typeof translated == 'undefined')
+      return (n == 1) ? singular : plural;
+    return translated[Documentation.PLURALEXPR(n)];
+  },
+
+  addTranslations : function(catalog) {
+    for (var key in catalog.messages)
+      this.TRANSLATIONS[key] = catalog.messages[key];
+    this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
+    this.LOCALE = catalog.locale;
+  },
+
+  /**
+   * add context elements like header anchor links
+   */
+  addContextElements : function() {
+    $('div[id] > :header:first').each(function() {
+      $('<a class="headerlink">\u00B6</a>').
+      attr('href', '#' + this.id).
+      attr('title', _('Permalink to this headline')).
+      appendTo(this);
+    });
+    $('dt[id]').each(function() {
+      $('<a class="headerlink">\u00B6</a>').
+      attr('href', '#' + this.id).
+      attr('title', _('Permalink to this definition')).
+      appendTo(this);
+    });
+  },
+
+  /**
+   * workaround a firefox stupidity
+   */
+  fixFirefoxAnchorBug : function() {
+    if (document.location.hash && $.browser.mozilla)
+      window.setTimeout(function() {
+        document.location.href += '';
+      }, 10);
+  },
+
+  /**
+   * highlight the search words provided in the url in the text
+   */
+  highlightSearchWords : function() {
+    var params = $.getQueryParameters();
+    var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
+    if (terms.length) {
+      var body = $('div.body');
+      window.setTimeout(function() {
+        $.each(terms, function() {
+          body.highlightText(this.toLowerCase(), 'highlighted');
+        });
+      }, 10);
+      $('<p class="highlight-link"><a href="javascript:Documentation.' +
+        'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
+          .appendTo($('#searchbox'));
+    }
+  },
+
+  /**
+   * init the domain index toggle buttons
+   */
+  initIndexTable : function() {
+    var togglers = $('img.toggler').click(function() {
+      var src = $(this).attr('src');
+      var idnum = $(this).attr('id').substr(7);
+      $('tr.cg-' + idnum).toggle();
+      if (src.substr(-9) == 'minus.png')
+        $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
+      else
+        $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
+    }).css('display', '');
+    if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
+        togglers.click();
+    }
+  },
+
+  /**
+   * helper function to hide the search marks again
+   */
+  hideSearchWords : function() {
+    $('#searchbox .highlight-link').fadeOut(300);
+    $('span.highlighted').removeClass('highlighted');
+  },
+
+  /**
+   * make the url absolute
+   */
+  makeURL : function(relativeURL) {
+    return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
+  },
+
+  /**
+   * get the current relative url
+   */
+  getCurrentURL : function() {
+    var path = document.location.pathname;
+    var parts = path.split(/\//);
+    $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
+      if (this == '..')
+        parts.pop();
+    });
+    var url = parts.join('/');
+    return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
+  }
+};
+
+// quick alias for translations
+_ = Documentation.gettext;
+
+$(document).ready(function() {
+  Documentation.init();
+});

BIN
doc/build/_static/down-pressed.png


BIN
doc/build/_static/down.png


+ 310 - 0
doc/build/_static/epub.css

@@ -0,0 +1,310 @@
+/*
+ * default.css_t
+ * ~~~~~~~~~~~~~
+ *
+ * Sphinx stylesheet -- default theme.
+ *
+ * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+@import url("basic.css");
+
+/* -- page layout ----------------------------------------------------------- */
+
+body {
+    font-family: {{ theme_bodyfont }};
+    font-size: 100%;
+    background-color: {{ theme_footerbgcolor }};
+    color: #000;
+    margin: 0;
+    padding: 0;
+}
+
+div.document {
+    background-color: {{ theme_sidebarbgcolor }};
+}
+
+div.documentwrapper {
+    float: left;
+    width: 100%;
+}
+
+div.bodywrapper {
+    margin: 0 0 0 230px;
+}
+
+div.body {
+    background-color: {{ theme_bgcolor }};
+    color: {{ theme_textcolor }};
+    padding: 0 20px 30px 20px;
+}
+
+{%- if theme_rightsidebar|tobool %}
+div.bodywrapper {
+    margin: 0 230px 0 0;
+}
+{%- endif %}
+
+div.footer {
+    color: {{ theme_footertextcolor }};
+    width: 100%;
+    padding: 9px 0 9px 0;
+    text-align: center;
+    font-size: 75%;
+}
+
+div.footer a {
+    color: {{ theme_footertextcolor }};
+    text-decoration: underline;
+}
+
+div.related {
+    background-color: {{ theme_relbarbgcolor }};
+    line-height: 30px;
+    color: {{ theme_relbartextcolor }};
+}
+
+div.related a {
+    color: {{ theme_relbarlinkcolor }};
+}
+
+div.sphinxsidebar {
+    {%- if theme_stickysidebar|tobool %}
+    top: 30px;
+    bottom: 0;
+    margin: 0;
+    position: fixed;
+    overflow: auto;
+    height: auto;
+    {%- endif %}
+    {%- if theme_rightsidebar|tobool %}
+    float: right;
+    {%- if theme_stickysidebar|tobool %}
+    right: 0;
+    {%- endif %}
+    {%- endif %}
+}
+
+{%- if theme_stickysidebar|tobool %}
+/* this is nice, but it it leads to hidden headings when jumping
+   to an anchor */
+/*
+div.related {
+    position: fixed;
+}
+
+div.documentwrapper {
+    margin-top: 30px;
+}
+*/
+{%- endif %}
+
+div.sphinxsidebar h3 {
+    font-family: {{ theme_headfont }};
+    color: {{ theme_sidebartextcolor }};
+    font-size: 1.4em;
+    font-weight: normal;
+    margin: 0;
+    padding: 0;
+}
+
+div.sphinxsidebar h3 a {
+    color: {{ theme_sidebartextcolor }};
+}
+
+div.sphinxsidebar h4 {
+    font-family: {{ theme_headfont }};
+    color: {{ theme_sidebartextcolor }};
+    font-size: 1.3em;
+    font-weight: normal;
+    margin: 5px 0 0 0;
+    padding: 0;
+}
+
+div.sphinxsidebar p {
+    color: {{ theme_sidebartextcolor }};
+}
+
+div.sphinxsidebar p.topless {
+    margin: 5px 10px 10px 10px;
+}
+
+div.sphinxsidebar ul {
+    margin: 10px;
+    padding: 0;
+    color: {{ theme_sidebartextcolor }};
+}
+
+div.sphinxsidebar a {
+    color: {{ theme_sidebarlinkcolor }};
+}
+
+div.sphinxsidebar input {
+    border: 1px solid {{ theme_sidebarlinkcolor }};
+    font-family: sans-serif;
+    font-size: 1em;
+}
+
+{% if theme_collapsiblesidebar|tobool %}
+/* for collapsible sidebar */
+div#sidebarbutton {
+    background-color: {{ theme_sidebarbtncolor }};
+}
+{% endif %}
+
+/* -- hyperlink styles ------------------------------------------------------ */
+
+a {
+    color: {{ theme_linkcolor }};
+    text-decoration: none;
+}
+
+a:visited {
+    color: {{ theme_visitedlinkcolor }};
+    text-decoration: none;
+}
+
+a:hover {
+    text-decoration: underline;
+}
+
+{% if theme_externalrefs|tobool %}
+a.external {
+   text-decoration: none;
+   border-bottom: 1px dashed {{ theme_linkcolor }};
+}
+
+a.external:hover {
+   text-decoration: none;
+   border-bottom: none;
+}
+
+a.external:visited {
+    text-decoration: none;
+    border-bottom: 1px dashed {{ theme_visitedlinkcolor }};
+}
+{% endif %}
+
+/* -- body styles ----------------------------------------------------------- */
+
+div.body h1,
+div.body h2,
+div.body h3,
+div.body h4,
+div.body h5,
+div.body h6 {
+    font-family: {{ theme_headfont }};
+    background-color: {{ theme_headbgcolor }};
+    font-weight: normal;
+    color: {{ theme_headtextcolor }};
+    border-bottom: 1px solid #ccc;
+    margin: 20px -20px 10px -20px;
+    padding: 3px 0 3px 10px;
+}
+
+div.body h1 { margin-top: 0; font-size: 200%; }
+div.body h2 { font-size: 160%; }
+div.body h3 { font-size: 140%; }
+div.body h4 { font-size: 120%; }
+div.body h5 { font-size: 110%; }
+div.body h6 { font-size: 100%; }
+
+a.headerlink {
+    color: {{ theme_headlinkcolor }};
+    font-size: 0.8em;
+    padding: 0 4px 0 4px;
+    text-decoration: none;
+}
+
+a.headerlink:hover {
+    background-color: {{ theme_headlinkcolor }};
+    color: white;
+}
+
+div.body p, div.body dd, div.body li {
+    text-align: justify;
+    line-height: 130%;
+}
+
+div.admonition p.admonition-title + p {
+    display: inline;
+}
+
+div.admonition p {
+    margin-bottom: 5px;
+}
+
+div.admonition pre {
+    margin-bottom: 5px;
+}
+
+div.admonition ul, div.admonition ol {
+    margin-bottom: 5px;
+}
+
+div.note {
+    background-color: #eee;
+    border: 1px solid #ccc;
+}
+
+div.seealso {
+    background-color: #ffc;
+    border: 1px solid #ff6;
+}
+
+div.topic {
+    background-color: #eee;
+}
+
+div.warning {
+    background-color: #ffe4e4;
+    border: 1px solid #f66;
+}
+
+p.admonition-title {
+    display: inline;
+}
+
+p.admonition-title:after {
+    content: ":";
+}
+
+pre {
+    padding: 5px;
+    background-color: {{ theme_codebgcolor }};
+    color: {{ theme_codetextcolor }};
+    line-height: 120%;
+    border: 1px solid #ac9;
+    border-left: none;
+    border-right: none;
+}
+
+tt {
+    background-color: #ecf0f3;
+    padding: 0 1px 0 1px;
+    font-size: 0.95em;
+}
+
+th {
+    background-color: #ede;
+}
+
+.warning tt {
+    background: #efc2c2;
+}
+
+.note tt {
+    background: #d6d6d6;
+}
+
+.viewcode-back {
+    font-family: {{ theme_bodyfont }};
+}
+
+div.viewcode-block:target {
+    background-color: #f4debf;
+    border-top: 1px solid #ac9;
+    border-bottom: 1px solid #ac9;
+}

BIN
doc/build/_static/file.png


BIN
doc/build/_static/font/fontawesome_webfont.eot


Dosya farkı çok büyük olduğundan ihmal edildi
+ 195 - 0
doc/build/_static/font/fontawesome_webfont.svg


BIN
doc/build/_static/font/fontawesome_webfont.ttf


BIN
doc/build/_static/font/fontawesome_webfont.woff


BIN
doc/build/_static/footerbg.png


BIN
doc/build/_static/headerbg.png


+ 7 - 0
doc/build/_static/ie6.css

@@ -0,0 +1,7 @@
+* html img,
+* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none",
+this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')",
+this.src = "_static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''),
+this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')",
+this.runtimeStyle.backgroundImage = "none")),this.pngSet=true)
+);}

Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
doc/build/_static/jquery.js


+ 47 - 0
doc/build/_static/js/theme.js

@@ -0,0 +1,47 @@
+$( document ).ready(function() {
+    // Shift nav in mobile when clicking the menu.
+    $(document).on('click', "[data-toggle='wy-nav-top']", function() {
+      $("[data-toggle='wy-nav-shift']").toggleClass("shift");
+      $("[data-toggle='rst-versions']").toggleClass("shift");
+    });
+    // Close menu when you click a link.
+    $(document).on('click', ".wy-menu-vertical .current ul li a", function() {
+      $("[data-toggle='wy-nav-shift']").removeClass("shift");
+      $("[data-toggle='rst-versions']").toggleClass("shift");
+    });
+    $(document).on('click', "[data-toggle='rst-current-version']", function() {
+      $("[data-toggle='rst-versions']").toggleClass("shift-up");
+    });  
+    // Make tables responsive
+    $("table.docutils:not(.field-list)").wrap("<div class='wy-table-responsive'></div>");
+});
+
+window.SphinxRtdTheme = (function (jquery) {
+    var stickyNav = (function () {
+        var navBar,
+            win,
+            stickyNavCssClass = 'stickynav',
+            applyStickNav = function () {
+                if (navBar.height() <= win.height()) {
+                    navBar.addClass(stickyNavCssClass);
+                } else {
+                    navBar.removeClass(stickyNavCssClass);
+                }
+            },
+            enable = function () {
+                applyStickNav();
+                win.on('resize', applyStickNav);
+            },
+            init = function () {
+                navBar = jquery('nav.wy-nav-side:first');
+                win    = jquery(window);
+            };
+        jquery(init);
+        return {
+            enable : enable
+        };
+    }());
+    return {
+        StickyNav : stickyNav
+    };
+}($));

BIN
doc/build/_static/middlebg.png


BIN
doc/build/_static/minus.png


BIN
doc/build/_static/navigation.png


BIN
doc/build/_static/plus.png


+ 62 - 0
doc/build/_static/pygments.css

@@ -0,0 +1,62 @@
+.highlight .hll { background-color: #ffffcc }
+.highlight  { background: #eeffcc; }
+.highlight .c { color: #408090; font-style: italic } /* Comment */
+.highlight .err { border: 1px solid #FF0000 } /* Error */
+.highlight .k { color: #007020; font-weight: bold } /* Keyword */
+.highlight .o { color: #666666 } /* Operator */
+.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #007020 } /* Comment.Preproc */
+.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
+.highlight .gd { color: #A00000 } /* Generic.Deleted */
+.highlight .ge { font-style: italic } /* Generic.Emph */
+.highlight .gr { color: #FF0000 } /* Generic.Error */
+.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.highlight .gi { color: #00A000 } /* Generic.Inserted */
+.highlight .go { color: #333333 } /* Generic.Output */
+.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
+.highlight .gs { font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.highlight .gt { color: #0044DD } /* Generic.Traceback */
+.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
+.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
+.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
+.highlight .kp { color: #007020 } /* Keyword.Pseudo */
+.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #902000 } /* Keyword.Type */
+.highlight .m { color: #208050 } /* Literal.Number */
+.highlight .s { color: #4070a0 } /* Literal.String */
+.highlight .na { color: #4070a0 } /* Name.Attribute */
+.highlight .nb { color: #007020 } /* Name.Builtin */
+.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
+.highlight .no { color: #60add5 } /* Name.Constant */
+.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
+.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
+.highlight .ne { color: #007020 } /* Name.Exception */
+.highlight .nf { color: #06287e } /* Name.Function */
+.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
+.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
+.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
+.highlight .nv { color: #bb60d5 } /* Name.Variable */
+.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
+.highlight .w { color: #bbbbbb } /* Text.Whitespace */
+.highlight .mf { color: #208050 } /* Literal.Number.Float */
+.highlight .mh { color: #208050 } /* Literal.Number.Hex */
+.highlight .mi { color: #208050 } /* Literal.Number.Integer */
+.highlight .mo { color: #208050 } /* Literal.Number.Oct */
+.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
+.highlight .sc { color: #4070a0 } /* Literal.String.Char */
+.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
+.highlight .s2 { color: #4070a0 } /* Literal.String.Double */
+.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
+.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
+.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
+.highlight .sx { color: #c65d09 } /* Literal.String.Other */
+.highlight .sr { color: #235388 } /* Literal.String.Regex */
+.highlight .s1 { color: #4070a0 } /* Literal.String.Single */
+.highlight .ss { color: #517918 } /* Literal.String.Symbol */
+.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
+.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
+.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
+.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
+.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */

+ 342 - 0
doc/build/_static/pyramid.css

@@ -0,0 +1,342 @@
+/*
+ * pyramid.css_t
+ * ~~~~~~~~~~~~
+ *
+ * Sphinx stylesheet -- pylons theme.
+ *
+ * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+ 
+@import url("basic.css");
+ 
+/* -- page layout ----------------------------------------------------------- */
+ 
+body {
+    font-family: "Nobile", sans-serif;
+    font-size: 100%;
+    background-color: #393939;
+    color: #ffffff;
+    margin: 0;
+    padding: 0;
+}
+
+div.documentwrapper {
+    float: left;
+    width: 100%;
+}
+
+div.bodywrapper {
+    margin: 0 0 0 230px;
+}
+
+hr {
+    border: 1px solid #B1B4B6;
+}
+ 
+div.document {
+    background-color: #eee;
+}
+
+div.header {
+    width:100%;
+    background: #f4ad32 url(headerbg.png) repeat-x 0 top;
+    border-bottom: 2px solid #ffffff;
+}
+
+div.logo {
+    text-align: center;
+    padding-top: 10px;
+}
+
+div.body {
+    background-color: #ffffff;
+    color: #3E4349;
+    padding: 0 30px 30px 30px;
+    font-size: 1em;
+    border: 2px solid #ddd;
+    border-right-style: none;
+    overflow: auto;
+}
+ 
+div.footer {
+    color: #ffffff;
+    width: 100%;
+    padding: 13px 0;
+    text-align: center;
+    font-size: 75%;
+    background: transparent;
+    clear:both;
+}
+ 
+div.footer a {
+    color: #ffffff;
+    text-decoration: none;
+}
+
+div.footer a:hover {
+    color: #e88f00;
+    text-decoration: underline;
+}
+ 
+div.related {
+    line-height: 30px;
+    color: #373839;
+    font-size: 0.8em;
+    background-color: #eee;
+}
+ 
+div.related a {
+    color: #1b61d6;
+}
+
+div.related ul {
+    padding-left: 240px;
+}
+ 
+div.sphinxsidebar {
+    font-size: 0.75em;
+    line-height: 1.5em;
+}
+
+div.sphinxsidebarwrapper{
+    padding: 10px 0;
+}
+ 
+div.sphinxsidebar h3,
+div.sphinxsidebar h4 {
+    font-family: "Neuton", sans-serif;
+    color: #373839;
+    font-size: 1.4em;
+    font-weight: normal;
+    margin: 0;
+    padding: 5px 10px;
+    border-bottom: 2px solid #ddd;
+}
+
+div.sphinxsidebar h4{
+    font-size: 1.3em;
+}
+ 
+div.sphinxsidebar h3 a {
+    color: #000000;
+}
+ 
+ 
+div.sphinxsidebar p {
+    color: #888;
+    padding: 5px 20px;
+}
+ 
+div.sphinxsidebar p.topless {
+}
+ 
+div.sphinxsidebar ul {
+    margin: 10px 20px;
+    padding: 0;
+    color: #373839;
+}
+ 
+div.sphinxsidebar a {
+    color: #444;
+}
+ 
+div.sphinxsidebar input {
+    border: 1px solid #ccc;
+    font-family: sans-serif;
+    font-size: 1em;
+}
+
+div.sphinxsidebar input[type=text]{
+    margin-left: 20px;
+}
+
+/* -- sidebars -------------------------------------------------------------- */
+
+div.sidebar {
+    margin: 0 0 0.5em 1em;
+    border: 2px solid #c6d880;
+    background-color: #e6efc2;
+    width: 40%;
+    float: right;
+    border-right-style: none;
+    border-left-style: none;
+    padding: 10px 20px;
+}
+
+p.sidebar-title {
+    font-weight: bold;
+}
+
+/* -- body styles ----------------------------------------------------------- */
+ 
+a, a .pre {
+    color: #1b61d6;
+    text-decoration: none;
+}
+ 
+a:hover, a:hover .pre {
+    text-decoration: underline;
+}
+ 
+div.body h1,
+div.body h2,
+div.body h3,
+div.body h4,
+div.body h5,
+div.body h6 {
+    font-family: "Neuton", sans-serif;
+    background-color: #ffffff;
+    font-weight: normal;
+    color: #373839;
+    margin: 30px 0px 10px 0px;
+    padding: 5px 0;
+}
+ 
+div.body h1 { border-top: 20px solid white; margin-top: 0; font-size: 200%; }
+div.body h2 { font-size: 150%; background-color: #ffffff; }
+div.body h3 { font-size: 120%; background-color: #ffffff; }
+div.body h4 { font-size: 110%; background-color: #ffffff; }
+div.body h5 { font-size: 100%; background-color: #ffffff; }
+div.body h6 { font-size: 100%; background-color: #ffffff; }
+ 
+a.headerlink {
+    color: #1b61d6;
+    font-size: 0.8em;
+    padding: 0 4px 0 4px;
+    text-decoration: none;
+}
+ 
+a.headerlink:hover {
+    text-decoration: underline;
+}
+ 
+div.body p, div.body dd, div.body li {
+    line-height: 1.5em;
+}
+ 
+div.admonition p.admonition-title + p {
+    display: inline;
+}
+
+div.admonition {
+    background: #eeeeec;
+    border: 2px solid #babdb6;
+    border-right-style: none;
+    border-left-style: none;
+    padding: 10px 20px 10px 60px;
+}
+
+div.highlight{
+    background-color: white;
+}
+
+div.note {
+    border: 2px solid #7a9eec;
+    border-right-style: none;
+    border-left-style: none;
+    padding: 10px 20px 10px 60px;
+    background: #e1ecfe url(dialog-note.png) no-repeat 10px 8px;
+}
+ 
+div.seealso {
+    background: #fff6bf url(dialog-seealso.png) no-repeat 10px 8px;
+    border: 2px solid #ffd324;
+    border-left-style: none;
+    border-right-style: none;
+    padding: 10px 20px 10px 60px;
+}
+ 
+div.topic {
+    background: #eeeeee;
+    border: 2px solid #C6C9CB;
+    padding: 10px 20px;
+    border-right-style: none;
+    border-left-style: none;
+}
+ 
+div.warning {
+    background: #fbe3e4 url(dialog-warning.png) no-repeat 10px 8px;
+    border: 2px solid #fbc2c4;
+    border-right-style: none;
+    border-left-style: none;
+    padding: 10px 20px 10px 60px;
+}
+
+div.admonition-todo {
+    background: #f2d9b4 url(dialog-todo.png) no-repeat 10px 8px;
+    border: 2px solid #e9b96e;
+    border-right-style: none;
+    border-left-style: none;
+    padding: 10px 20px 10px 60px;
+}
+ 
+div.note p.admonition-title,
+div.warning p.admonition-title,
+div.seealso p.admonition-title,
+div.admonition-todo p.admonition-title {
+    display: none;
+}
+ 
+p.admonition-title:after {
+    content: ":";
+}
+ 
+pre {
+    padding: 10px;
+    background-color: #fafafa;
+    color: #222;
+    line-height: 1.2em;
+    border: 2px solid #C6C9CB;
+    font-size: 1.1em;
+    margin: 1.5em 0 1.5em 0;
+    border-right-style: none;
+    border-left-style: none;
+}
+ 
+tt {
+    background-color: transparent;
+    color: #222;
+    font-size: 1.1em;
+    font-family: monospace;
+}
+
+.viewcode-back {
+    font-family: "Nobile", sans-serif;
+}
+
+div.viewcode-block:target {
+    background-color: #fff6bf;
+    border: 2px solid #ffd324;
+    border-left-style: none;
+    border-right-style: none;
+    padding: 10px 20px;
+}
+
+table.highlighttable {
+    width: 100%;
+}
+
+table.highlighttable td {
+    padding: 0;
+}
+
+a em.std-term {
+   color: #007f00;
+}
+
+a:hover em.std-term {
+    text-decoration: underline;
+}
+
+.download {
+    font-family: "Nobile", sans-serif;
+    font-weight: normal;
+    font-style: normal;
+}
+
+tt.xref {
+    font-weight: normal;
+    font-style: normal;
+}

+ 622 - 0
doc/build/_static/searchtools.js

@@ -0,0 +1,622 @@
+/*
+ * searchtools.js_t
+ * ~~~~~~~~~~~~~~~~
+ *
+ * Sphinx JavaScript utilties for the full-text search.
+ *
+ * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+
+/**
+ * Porter Stemmer
+ */
+var Stemmer = function() {
+
+  var step2list = {
+    ational: 'ate',
+    tional: 'tion',
+    enci: 'ence',
+    anci: 'ance',
+    izer: 'ize',
+    bli: 'ble',
+    alli: 'al',
+    entli: 'ent',
+    eli: 'e',
+    ousli: 'ous',
+    ization: 'ize',
+    ation: 'ate',
+    ator: 'ate',
+    alism: 'al',
+    iveness: 'ive',
+    fulness: 'ful',
+    ousness: 'ous',
+    aliti: 'al',
+    iviti: 'ive',
+    biliti: 'ble',
+    logi: 'log'
+  };
+
+  var step3list = {
+    icate: 'ic',
+    ative: '',
+    alize: 'al',
+    iciti: 'ic',
+    ical: 'ic',
+    ful: '',
+    ness: ''
+  };
+
+  var c = "[^aeiou]";          // consonant
+  var v = "[aeiouy]";          // vowel
+  var C = c + "[^aeiouy]*";    // consonant sequence
+  var V = v + "[aeiou]*";      // vowel sequence
+
+  var mgr0 = "^(" + C + ")?" + V + C;                      // [C]VC... is m>0
+  var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$";    // [C]VC[V] is m=1
+  var mgr1 = "^(" + C + ")?" + V + C + V + C;              // [C]VCVC... is m>1
+  var s_v   = "^(" + C + ")?" + v;                         // vowel in stem
+
+  this.stemWord = function (w) {
+    var stem;
+    var suffix;
+    var firstch;
+    var origword = w;
+
+    if (w.length < 3)
+      return w;
+
+    var re;
+    var re2;
+    var re3;
+    var re4;
+
+    firstch = w.substr(0,1);
+    if (firstch == "y")
+      w = firstch.toUpperCase() + w.substr(1);
+
+    // Step 1a
+    re = /^(.+?)(ss|i)es$/;
+    re2 = /^(.+?)([^s])s$/;
+
+    if (re.test(w))
+      w = w.replace(re,"$1$2");
+    else if (re2.test(w))
+      w = w.replace(re2,"$1$2");
+
+    // Step 1b
+    re = /^(.+?)eed$/;
+    re2 = /^(.+?)(ed|ing)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      re = new RegExp(mgr0);
+      if (re.test(fp[1])) {
+        re = /.$/;
+        w = w.replace(re,"");
+      }
+    }
+    else if (re2.test(w)) {
+      var fp = re2.exec(w);
+      stem = fp[1];
+      re2 = new RegExp(s_v);
+      if (re2.test(stem)) {
+        w = stem;
+        re2 = /(at|bl|iz)$/;
+        re3 = new RegExp("([^aeiouylsz])\\1$");
+        re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+        if (re2.test(w))
+          w = w + "e";
+        else if (re3.test(w)) {
+          re = /.$/;
+          w = w.replace(re,"");
+        }
+        else if (re4.test(w))
+          w = w + "e";
+      }
+    }
+
+    // Step 1c
+    re = /^(.+?)y$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      re = new RegExp(s_v);
+      if (re.test(stem))
+        w = stem + "i";
+    }
+
+    // Step 2
+    re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      suffix = fp[2];
+      re = new RegExp(mgr0);
+      if (re.test(stem))
+        w = stem + step2list[suffix];
+    }
+
+    // Step 3
+    re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      suffix = fp[2];
+      re = new RegExp(mgr0);
+      if (re.test(stem))
+        w = stem + step3list[suffix];
+    }
+
+    // Step 4
+    re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
+    re2 = /^(.+?)(s|t)(ion)$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      re = new RegExp(mgr1);
+      if (re.test(stem))
+        w = stem;
+    }
+    else if (re2.test(w)) {
+      var fp = re2.exec(w);
+      stem = fp[1] + fp[2];
+      re2 = new RegExp(mgr1);
+      if (re2.test(stem))
+        w = stem;
+    }
+
+    // Step 5
+    re = /^(.+?)e$/;
+    if (re.test(w)) {
+      var fp = re.exec(w);
+      stem = fp[1];
+      re = new RegExp(mgr1);
+      re2 = new RegExp(meq1);
+      re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+      if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
+        w = stem;
+    }
+    re = /ll$/;
+    re2 = new RegExp(mgr1);
+    if (re.test(w) && re2.test(w)) {
+      re = /.$/;
+      w = w.replace(re,"");
+    }
+
+    // and turn initial Y back to y
+    if (firstch == "y")
+      w = firstch.toLowerCase() + w.substr(1);
+    return w;
+  }
+}
+
+
+
+/**
+ * Simple result scoring code.
+ */
+var Scorer = {
+  // Implement the following function to further tweak the score for each result
+  // The function takes a result array [filename, title, anchor, descr, score]
+  // and returns the new score.
+  /*
+  score: function(result) {
+    return result[4];
+  },
+  */
+
+  // query matches the full name of an object
+  objNameMatch: 11,
+  // or matches in the last dotted part of the object name
+  objPartialMatch: 6,
+  // Additive scores depending on the priority of the object
+  objPrio: {0:  15,   // used to be importantResults
+            1:  5,   // used to be objectResults
+            2: -5},  // used to be unimportantResults
+  //  Used when the priority is not in the mapping.
+  objPrioDefault: 0,
+
+  // query found in title
+  title: 15,
+  // query found in terms
+  term: 5
+};
+
+
+/**
+ * Search Module
+ */
+var Search = {
+
+  _index : null,
+  _queued_query : null,
+  _pulse_status : -1,
+
+  init : function() {
+      var params = $.getQueryParameters();
+      if (params.q) {
+          var query = params.q[0];
+          $('input[name="q"]')[0].value = query;
+          this.performSearch(query);
+      }
+  },
+
+  loadIndex : function(url) {
+    $.ajax({type: "GET", url: url, data: null,
+            dataType: "script", cache: true,
+            complete: function(jqxhr, textstatus) {
+              if (textstatus != "success") {
+                document.getElementById("searchindexloader").src = url;
+              }
+            }});
+  },
+
+  setIndex : function(index) {
+    var q;
+    this._index = index;
+    if ((q = this._queued_query) !== null) {
+      this._queued_query = null;
+      Search.query(q);
+    }
+  },
+
+  hasIndex : function() {
+      return this._index !== null;
+  },
+
+  deferQuery : function(query) {
+      this._queued_query = query;
+  },
+
+  stopPulse : function() {
+      this._pulse_status = 0;
+  },
+
+  startPulse : function() {
+    if (this._pulse_status >= 0)
+        return;
+    function pulse() {
+      var i;
+      Search._pulse_status = (Search._pulse_status + 1) % 4;
+      var dotString = '';
+      for (i = 0; i < Search._pulse_status; i++)
+        dotString += '.';
+      Search.dots.text(dotString);
+      if (Search._pulse_status > -1)
+        window.setTimeout(pulse, 500);
+    }
+    pulse();
+  },
+
+  /**
+   * perform a search for something (or wait until index is loaded)
+   */
+  performSearch : function(query) {
+    // create the required interface elements
+    this.out = $('#search-results');
+    this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
+    this.dots = $('<span></span>').appendTo(this.title);
+    this.status = $('<p style="display: none"></p>').appendTo(this.out);
+    this.output = $('<ul class="search"/>').appendTo(this.out);
+
+    $('#search-progress').text(_('Preparing search...'));
+    this.startPulse();
+
+    // index already loaded, the browser was quick!
+    if (this.hasIndex())
+      this.query(query);
+    else
+      this.deferQuery(query);
+  },
+
+  /**
+   * execute search (requires search index to be loaded)
+   */
+  query : function(query) {
+    var i;
+    var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
+
+    // stem the searchterms and add them to the correct list
+    var stemmer = new Stemmer();
+    var searchterms = [];
+    var excluded = [];
+    var hlterms = [];
+    var tmp = query.split(/\s+/);
+    var objectterms = [];
+    for (i = 0; i < tmp.length; i++) {
+      if (tmp[i] !== "") {
+          objectterms.push(tmp[i].toLowerCase());
+      }
+
+      if ($u.indexOf(stopwords, tmp[i]) != -1 || tmp[i].match(/^\d+$/) ||
+          tmp[i] === "") {
+        // skip this "word"
+        continue;
+      }
+      // stem the word
+      var word = stemmer.stemWord(tmp[i]).toLowerCase();
+      var toAppend;
+      // select the correct list
+      if (word[0] == '-') {
+        toAppend = excluded;
+        word = word.substr(1);
+      }
+      else {
+        toAppend = searchterms;
+        hlterms.push(tmp[i].toLowerCase());
+      }
+      // only add if not already in the list
+      if (!$u.contains(toAppend, word))
+        toAppend.push(word);
+    }
+    var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
+
+    // console.debug('SEARCH: searching for:');
+    // console.info('required: ', searchterms);
+    // console.info('excluded: ', excluded);
+
+    // prepare search
+    var terms = this._index.terms;
+    var titleterms = this._index.titleterms;
+
+    // array of [filename, title, anchor, descr, score]
+    var results = [];
+    $('#search-progress').empty();
+
+    // lookup as object
+    for (i = 0; i < objectterms.length; i++) {
+      var others = [].concat(objectterms.slice(0, i),
+                             objectterms.slice(i+1, objectterms.length));
+      results = results.concat(this.performObjectSearch(objectterms[i], others));
+    }
+
+    // lookup as search terms in fulltext
+    results = results.concat(this.performTermsSearch(searchterms, excluded, terms, Scorer.term))
+                     .concat(this.performTermsSearch(searchterms, excluded, titleterms, Scorer.title));
+
+    // let the scorer override scores with a custom scoring function
+    if (Scorer.score) {
+      for (i = 0; i < results.length; i++)
+        results[i][4] = Scorer.score(results[i]);
+    }
+
+    // now sort the results by score (in opposite order of appearance, since the
+    // display function below uses pop() to retrieve items) and then
+    // alphabetically
+    results.sort(function(a, b) {
+      var left = a[4];
+      var right = b[4];
+      if (left > right) {
+        return 1;
+      } else if (left < right) {
+        return -1;
+      } else {
+        // same score: sort alphabetically
+        left = a[1].toLowerCase();
+        right = b[1].toLowerCase();
+        return (left > right) ? -1 : ((left < right) ? 1 : 0);
+      }
+    });
+
+    // for debugging
+    //Search.lastresults = results.slice();  // a copy
+    //console.info('search results:', Search.lastresults);
+
+    // print the results
+    var resultCount = results.length;
+    function displayNextItem() {
+      // results left, load the summary and display it
+      if (results.length) {
+        var item = results.pop();
+        var listItem = $('<li style="display:none"></li>');
+        if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') {
+          // dirhtml builder
+          var dirname = item[0] + '/';
+          if (dirname.match(/\/index\/$/)) {
+            dirname = dirname.substring(0, dirname.length-6);
+          } else if (dirname == 'index/') {
+            dirname = '';
+          }
+          listItem.append($('<a/>').attr('href',
+            DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
+            highlightstring + item[2]).html(item[1]));
+        } else {
+          // normal html builders
+          listItem.append($('<a/>').attr('href',
+            item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
+            highlightstring + item[2]).html(item[1]));
+        }
+        if (item[3]) {
+          listItem.append($('<span> (' + item[3] + ')</span>'));
+          Search.output.append(listItem);
+          listItem.slideDown(5, function() {
+            displayNextItem();
+          });
+        } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
+          $.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[0] + '.txt',
+                  dataType: "text",
+                  complete: function(jqxhr, textstatus) {
+                    var data = jqxhr.responseText;
+                    if (data !== '') {
+                      listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));
+                    }
+                    Search.output.append(listItem);
+                    listItem.slideDown(5, function() {
+                      displayNextItem();
+                    });
+                  }});
+        } else {
+          // no source available, just display title
+          Search.output.append(listItem);
+          listItem.slideDown(5, function() {
+            displayNextItem();
+          });
+        }
+      }
+      // search finished, update title and status message
+      else {
+        Search.stopPulse();
+        Search.title.text(_('Search Results'));
+        if (!resultCount)
+          Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
+        else
+            Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
+        Search.status.fadeIn(500);
+      }
+    }
+    displayNextItem();
+  },
+
+  /**
+   * search for object names
+   */
+  performObjectSearch : function(object, otherterms) {
+    var filenames = this._index.filenames;
+    var objects = this._index.objects;
+    var objnames = this._index.objnames;
+    var titles = this._index.titles;
+
+    var i;
+    var results = [];
+
+    for (var prefix in objects) {
+      for (var name in objects[prefix]) {
+        var fullname = (prefix ? prefix + '.' : '') + name;
+        if (fullname.toLowerCase().indexOf(object) > -1) {
+          var score = 0;
+          var parts = fullname.split('.');
+          // check for different match types: exact matches of full name or
+          // "last name" (i.e. last dotted part)
+          if (fullname == object || parts[parts.length - 1] == object) {
+            score += Scorer.objNameMatch;
+          // matches in last name
+          } else if (parts[parts.length - 1].indexOf(object) > -1) {
+            score += Scorer.objPartialMatch;
+          }
+          var match = objects[prefix][name];
+          var objname = objnames[match[1]][2];
+          var title = titles[match[0]];
+          // If more than one term searched for, we require other words to be
+          // found in the name/title/description
+          if (otherterms.length > 0) {
+            var haystack = (prefix + ' ' + name + ' ' +
+                            objname + ' ' + title).toLowerCase();
+            var allfound = true;
+            for (i = 0; i < otherterms.length; i++) {
+              if (haystack.indexOf(otherterms[i]) == -1) {
+                allfound = false;
+                break;
+              }
+            }
+            if (!allfound) {
+              continue;
+            }
+          }
+          var descr = objname + _(', in ') + title;
+
+          var anchor = match[3];
+          if (anchor === '')
+            anchor = fullname;
+          else if (anchor == '-')
+            anchor = objnames[match[1]][1] + '-' + fullname;
+          // add custom score for some objects according to scorer
+          if (Scorer.objPrio.hasOwnProperty(match[2])) {
+            score += Scorer.objPrio[match[2]];
+          } else {
+            score += Scorer.objPrioDefault;
+          }
+          results.push([filenames[match[0]], fullname, '#'+anchor, descr, score]);
+        }
+      }
+    }
+
+    return results;
+  },
+
+  /**
+   * search for full-text terms in the index
+   */
+  performTermsSearch : function(searchterms, excluded, terms, score) {
+    var filenames = this._index.filenames;
+    var titles = this._index.titles;
+
+    var i, j, file, files;
+    var fileMap = {};
+    var results = [];
+
+    // perform the search on the required terms
+    for (i = 0; i < searchterms.length; i++) {
+      var word = searchterms[i];
+      // no match but word was a required one
+      if ((files = terms[word]) === undefined)
+        break;
+      if (files.length === undefined) {
+        files = [files];
+      }
+      // create the mapping
+      for (j = 0; j < files.length; j++) {
+        file = files[j];
+        if (file in fileMap)
+          fileMap[file].push(word);
+        else
+          fileMap[file] = [word];
+      }
+    }
+
+    // now check if the files don't contain excluded terms
+    for (file in fileMap) {
+      var valid = true;
+
+      // check if all requirements are matched
+      if (fileMap[file].length != searchterms.length)
+          continue;
+
+      // ensure that none of the excluded terms is in the search result
+      for (i = 0; i < excluded.length; i++) {
+        if (terms[excluded[i]] == file ||
+          $u.contains(terms[excluded[i]] || [], file)) {
+          valid = false;
+          break;
+        }
+      }
+
+      // if we have still a valid result we can add it to the result list
+      if (valid) {
+        results.push([filenames[file], titles[file], '', null, score]);
+      }
+    }
+    return results;
+  },
+
+  /**
+   * helper function to return a node containing the
+   * search summary for a given text. keywords is a list
+   * of stemmed words, hlwords is the list of normal, unstemmed
+   * words. the first one is used to find the occurance, the
+   * latter for highlighting it.
+   */
+  makeSearchSummary : function(text, keywords, hlwords) {
+    var textLower = text.toLowerCase();
+    var start = 0;
+    $.each(keywords, function() {
+      var i = textLower.indexOf(this.toLowerCase());
+      if (i > -1)
+        start = i;
+    });
+    start = Math.max(start - 120, 0);
+    var excerpt = ((start > 0) ? '...' : '') +
+      $.trim(text.substr(start, 240)) +
+      ((start + 240 - text.length) ? '...' : '');
+    var rv = $('<div class="context"></div>').text(excerpt);
+    $.each(hlwords, function() {
+      rv = rv.highlightText(this, 'highlighted');
+    });
+    return rv;
+  }
+};
+
+$(document).ready(function() {
+  Search.init();
+});

+ 159 - 0
doc/build/_static/sidebar.js

@@ -0,0 +1,159 @@
+/*
+ * sidebar.js
+ * ~~~~~~~~~~
+ *
+ * This script makes the Sphinx sidebar collapsible.
+ *
+ * .sphinxsidebar contains .sphinxsidebarwrapper.  This script adds
+ * in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton
+ * used to collapse and expand the sidebar.
+ *
+ * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden
+ * and the width of the sidebar and the margin-left of the document
+ * are decreased. When the sidebar is expanded the opposite happens.
+ * This script saves a per-browser/per-session cookie used to
+ * remember the position of the sidebar among the pages.
+ * Once the browser is closed the cookie is deleted and the position
+ * reset to the default (expanded).
+ *
+ * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+$(function() {
+  
+  
+  
+  
+  
+  
+  
+
+  // global elements used by the functions.
+  // the 'sidebarbutton' element is defined as global after its
+  // creation, in the add_sidebar_button function
+  var bodywrapper = $('.bodywrapper');
+  var sidebar = $('.sphinxsidebar');
+  var sidebarwrapper = $('.sphinxsidebarwrapper');
+
+  // for some reason, the document has no sidebar; do not run into errors
+  if (!sidebar.length) return;
+
+  // original margin-left of the bodywrapper and width of the sidebar
+  // with the sidebar expanded
+  var bw_margin_expanded = bodywrapper.css('margin-left');
+  var ssb_width_expanded = sidebar.width();
+
+  // margin-left of the bodywrapper and width of the sidebar
+  // with the sidebar collapsed
+  var bw_margin_collapsed = '.8em';
+  var ssb_width_collapsed = '.8em';
+
+  // colors used by the current theme
+  var dark_color = $('.related').css('background-color');
+  var light_color = $('.document').css('background-color');
+
+  function sidebar_is_collapsed() {
+    return sidebarwrapper.is(':not(:visible)');
+  }
+
+  function toggle_sidebar() {
+    if (sidebar_is_collapsed())
+      expand_sidebar();
+    else
+      collapse_sidebar();
+  }
+
+  function collapse_sidebar() {
+    sidebarwrapper.hide();
+    sidebar.css('width', ssb_width_collapsed);
+    bodywrapper.css('margin-left', bw_margin_collapsed);
+    sidebarbutton.css({
+        'margin-left': '0',
+        'height': bodywrapper.height()
+    });
+    sidebarbutton.find('span').text('»');
+    sidebarbutton.attr('title', _('Expand sidebar'));
+    document.cookie = 'sidebar=collapsed';
+  }
+
+  function expand_sidebar() {
+    bodywrapper.css('margin-left', bw_margin_expanded);
+    sidebar.css('width', ssb_width_expanded);
+    sidebarwrapper.show();
+    sidebarbutton.css({
+        'margin-left': ssb_width_expanded-12,
+        'height': bodywrapper.height()
+    });
+    sidebarbutton.find('span').text('«');
+    sidebarbutton.attr('title', _('Collapse sidebar'));
+    document.cookie = 'sidebar=expanded';
+  }
+
+  function add_sidebar_button() {
+    sidebarwrapper.css({
+        'float': 'left',
+        'margin-right': '0',
+        'width': ssb_width_expanded - 28
+    });
+    // create the button
+    sidebar.append(
+        '<div id="sidebarbutton"><span>&laquo;</span></div>'
+    );
+    var sidebarbutton = $('#sidebarbutton');
+    light_color = sidebarbutton.css('background-color');
+    // find the height of the viewport to center the '<<' in the page
+    var viewport_height;
+    if (window.innerHeight)
+ 	  viewport_height = window.innerHeight;
+    else
+	  viewport_height = $(window).height();
+    sidebarbutton.find('span').css({
+        'display': 'block',
+        'margin-top': (viewport_height - sidebar.position().top - 20) / 2
+    });
+
+    sidebarbutton.click(toggle_sidebar);
+    sidebarbutton.attr('title', _('Collapse sidebar'));
+    sidebarbutton.css({
+        'color': '#FFFFFF',
+        'border-left': '1px solid ' + dark_color,
+        'font-size': '1.2em',
+        'cursor': 'pointer',
+        'height': bodywrapper.height(),
+        'padding-top': '1px',
+        'margin-left': ssb_width_expanded - 12
+    });
+
+    sidebarbutton.hover(
+      function () {
+          $(this).css('background-color', dark_color);
+      },
+      function () {
+          $(this).css('background-color', light_color);
+      }
+    );
+  }
+
+  function set_position_from_cookie() {
+    if (!document.cookie)
+      return;
+    var items = document.cookie.split(';');
+    for(var k=0; k<items.length; k++) {
+      var key_val = items[k].split('=');
+      var key = key_val[0].replace(/ /, "");  // strip leading spaces
+      if (key == 'sidebar') {
+        var value = key_val[1];
+        if ((value == 'collapsed') && (!sidebar_is_collapsed()))
+          collapse_sidebar();
+        else if ((value == 'expanded') && (sidebar_is_collapsed()))
+          expand_sidebar();
+      }
+    }
+  }
+
+  add_sidebar_button();
+  var sidebarbutton = $('#sidebarbutton');
+  set_position_from_cookie();
+});

+ 339 - 0
doc/build/_static/sphinxdoc.css

@@ -0,0 +1,339 @@
+/*
+ * sphinxdoc.css_t
+ * ~~~~~~~~~~~~~~~
+ *
+ * Sphinx stylesheet -- sphinxdoc theme.  Originally created by
+ * Armin Ronacher for Werkzeug.
+ *
+ * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+@import url("basic.css");
+
+/* -- page layout ----------------------------------------------------------- */
+
+body {
+    font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva',
+                 'Verdana', sans-serif;
+    font-size: 14px;
+    letter-spacing: -0.01em;
+    line-height: 150%;
+    text-align: center;
+    background-color: #BFD1D4;
+    color: black;
+    padding: 0;
+    border: 1px solid #aaa;
+
+    margin: 0px 80px 0px 80px;
+    min-width: 740px;
+}
+
+div.document {
+    background-color: white;
+    text-align: left;
+    background-image: url(contents.png);
+    background-repeat: repeat-x;
+}
+
+div.bodywrapper {
+    margin: 0 240px 0 0;
+    border-right: 1px solid #ccc;
+}
+
+div.body {
+    margin: 0;
+    padding: 0.5em 20px 20px 20px;
+}
+
+div.related {
+    font-size: 1em;
+}
+
+div.related ul {
+    background-image: url(navigation.png);
+    height: 2em;
+    border-top: 1px solid #ddd;
+    border-bottom: 1px solid #ddd;
+}
+
+div.related ul li {
+    margin: 0;
+    padding: 0;
+    height: 2em;
+    float: left;
+}
+
+div.related ul li.right {
+    float: right;
+    margin-right: 5px;
+}
+
+div.related ul li a {
+    margin: 0;
+    padding: 0 5px 0 5px;
+    line-height: 1.75em;
+    color: #EE9816;
+}
+
+div.related ul li a:hover {
+    color: #3CA8E7;
+}
+
+div.sphinxsidebarwrapper {
+    padding: 0;
+}
+
+div.sphinxsidebar {
+    margin: 0;
+    padding: 0.5em 15px 15px 0;
+    width: 210px;
+    float: right;
+    font-size: 1em;
+    text-align: left;
+}
+
+div.sphinxsidebar h3, div.sphinxsidebar h4 {
+    margin: 1em 0 0.5em 0;
+    font-size: 1em;
+    padding: 0.1em 0 0.1em 0.5em;
+    color: white;
+    border: 1px solid #86989B;
+    background-color: #AFC1C4;
+}
+
+div.sphinxsidebar h3 a {
+    color: white;
+}
+
+div.sphinxsidebar ul {
+    padding-left: 1.5em;
+    margin-top: 7px;
+    padding: 0;
+    line-height: 130%;
+}
+
+div.sphinxsidebar ul ul {
+    margin-left: 20px;
+}
+
+div.footer {
+    background-color: #E3EFF1;
+    color: #86989B;
+    padding: 3px 8px 3px 0;
+    clear: both;
+    font-size: 0.8em;
+    text-align: right;
+}
+
+div.footer a {
+    color: #86989B;
+    text-decoration: underline;
+}
+
+/* -- body styles ----------------------------------------------------------- */
+
+p {    
+    margin: 0.8em 0 0.5em 0;
+}
+
+a {
+    color: #CA7900;
+    text-decoration: none;
+}
+
+a:hover {
+    color: #2491CF;
+}
+
+div.body a {
+    text-decoration: underline;
+}
+
+h1 {
+    margin: 0;
+    padding: 0.7em 0 0.3em 0;
+    font-size: 1.5em;
+    color: #11557C;
+}
+
+h2 {
+    margin: 1.3em 0 0.2em 0;
+    font-size: 1.35em;
+    padding: 0;
+}
+
+h3 {
+    margin: 1em 0 -0.3em 0;
+    font-size: 1.2em;
+}
+
+div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a {
+    color: black!important;
+}
+
+h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor {
+    display: none;
+    margin: 0 0 0 0.3em;
+    padding: 0 0.2em 0 0.2em;
+    color: #aaa!important;
+}
+
+h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor,
+h5:hover a.anchor, h6:hover a.anchor {
+    display: inline;
+}
+
+h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover,
+h5 a.anchor:hover, h6 a.anchor:hover {
+    color: #777;
+    background-color: #eee;
+}
+
+a.headerlink {
+    color: #c60f0f!important;
+    font-size: 1em;
+    margin-left: 6px;
+    padding: 0 4px 0 4px;
+    text-decoration: none!important;
+}
+
+a.headerlink:hover {
+    background-color: #ccc;
+    color: white!important;
+}
+
+cite, code, tt {
+    font-family: 'Consolas', 'Deja Vu Sans Mono',
+                 'Bitstream Vera Sans Mono', monospace;
+    font-size: 0.95em;
+    letter-spacing: 0.01em;
+}
+
+tt {
+    background-color: #f2f2f2;
+    border-bottom: 1px solid #ddd;
+    color: #333;
+}
+
+tt.descname, tt.descclassname, tt.xref {
+    border: 0;
+}
+
+hr {
+    border: 1px solid #abc;
+    margin: 2em;
+}
+
+a tt {
+    border: 0;
+    color: #CA7900;
+}
+
+a tt:hover {
+    color: #2491CF;
+}
+
+pre {
+    font-family: 'Consolas', 'Deja Vu Sans Mono',
+                 'Bitstream Vera Sans Mono', monospace;
+    font-size: 0.95em;
+    letter-spacing: 0.015em;
+    line-height: 120%;
+    padding: 0.5em;
+    border: 1px solid #ccc;
+    background-color: #f8f8f8;
+}
+
+pre a {
+    color: inherit;
+    text-decoration: underline;
+}
+
+td.linenos pre {
+    padding: 0.5em 0;
+}
+
+div.quotebar {
+    background-color: #f8f8f8;
+    max-width: 250px;
+    float: right;
+    padding: 2px 7px;
+    border: 1px solid #ccc;
+}
+
+div.topic {
+    background-color: #f8f8f8;
+}
+
+table {
+    border-collapse: collapse;
+    margin: 0 -0.5em 0 -0.5em;
+}
+
+table td, table th {
+    padding: 0.2em 0.5em 0.2em 0.5em;
+}
+
+div.admonition, div.warning {
+    font-size: 0.9em;
+    margin: 1em 0 1em 0;
+    border: 1px solid #86989B;
+    background-color: #f7f7f7;
+    padding: 0;
+}
+
+div.admonition p, div.warning p {
+    margin: 0.5em 1em 0.5em 1em;
+    padding: 0;
+}
+
+div.admonition pre, div.warning pre {
+    margin: 0.4em 1em 0.4em 1em;
+}
+
+div.admonition p.admonition-title,
+div.warning p.admonition-title {
+    margin: 0;
+    padding: 0.1em 0 0.1em 0.5em;
+    color: white;
+    border-bottom: 1px solid #86989B;
+    font-weight: bold;
+    background-color: #AFC1C4;
+}
+
+div.warning {
+    border: 1px solid #940000;
+}
+
+div.warning p.admonition-title {
+    background-color: #CF0000;
+    border-bottom-color: #940000;
+}
+
+div.admonition ul, div.admonition ol,
+div.warning ul, div.warning ol {
+    margin: 0.1em 0.5em 0.5em 3em;
+    padding: 0;
+}
+
+div.versioninfo {
+    margin: 1em 0 0 0;
+    border: 1px solid #ccc;
+    background-color: #DDEAF0;
+    padding: 8px;
+    line-height: 1.3em;
+    font-size: 0.9em;
+}
+
+.viewcode-back {
+    font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva',
+                 'Verdana', sans-serif;
+}
+
+div.viewcode-block:target {
+    background-color: #f4debf;
+    border-top: 1px solid #ac9;
+    border-bottom: 1px solid #ac9;
+}

BIN
doc/build/_static/transparent.gif


+ 31 - 0
doc/build/_static/underscore.js

@@ -0,0 +1,31 @@
+// Underscore.js 1.3.1
+// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
+// Underscore is freely distributable under the MIT license.
+// Portions of Underscore are inspired or borrowed from Prototype,
+// Oliver Steele's Functional, and John Resig's Micro-Templating.
+// For all details and documentation:
+// http://documentcloud.github.com/underscore
+(function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
+c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,
+h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each=
+b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===n)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===n)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(x&&a.map===x)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a==
+null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=
+function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e=
+e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
+function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,computed:b})});
+return e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){f==0?b[0]=a:(d=Math.floor(Math.random()*(f+1)),b[f]=b[d],b[d]=a)});return b};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,g){return{value:a,criteria:c.call(d,a,b,g)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,
+c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:a.toArray?a.toArray():b.isArray(a)?i.call(a):b.isArguments(a)?i.call(a):b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=
+b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(0==h||(c===true?b.last(d)!=g:!b.include(d,g)))d[d.length]=g,e[e.length]=a[h];return d},[]);
+return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,
+d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(p&&a.indexOf===p)return a.indexOf(c);for(d=0,e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(D&&a.lastIndexOf===D)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};
+var F=function(){};b.bind=function(a,c){var d,e;if(a.bind===s&&s)return s.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));F.prototype=a.prototype;var b=new F,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,
+c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;var b;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);i()},c));g?h=true:
+a.apply(d,e);i();g=true}};b.debounce=function(a,b){var d;return function(){var e=this,f=arguments;clearTimeout(d);d=setTimeout(function(){d=null;a.apply(e,f)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};
+b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments,
+1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};
+b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};
+b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;")};b.mixin=function(a){j(b.functions(a),
+function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+
+u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]=
+function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=
+true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);

BIN
doc/build/_static/up-pressed.png


BIN
doc/build/_static/up.png


+ 808 - 0
doc/build/_static/websupport.js

@@ -0,0 +1,808 @@
+/*
+ * websupport.js
+ * ~~~~~~~~~~~~~
+ *
+ * sphinx.websupport utilties for all documentation.
+ *
+ * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+(function($) {
+  $.fn.autogrow = function() {
+    return this.each(function() {
+    var textarea = this;
+
+    $.fn.autogrow.resize(textarea);
+
+    $(textarea)
+      .focus(function() {
+        textarea.interval = setInterval(function() {
+          $.fn.autogrow.resize(textarea);
+        }, 500);
+      })
+      .blur(function() {
+        clearInterval(textarea.interval);
+      });
+    });
+  };
+
+  $.fn.autogrow.resize = function(textarea) {
+    var lineHeight = parseInt($(textarea).css('line-height'), 10);
+    var lines = textarea.value.split('\n');
+    var columns = textarea.cols;
+    var lineCount = 0;
+    $.each(lines, function() {
+      lineCount += Math.ceil(this.length / columns) || 1;
+    });
+    var height = lineHeight * (lineCount + 1);
+    $(textarea).css('height', height);
+  };
+})(jQuery);
+
+(function($) {
+  var comp, by;
+
+  function init() {
+    initEvents();
+    initComparator();
+  }
+
+  function initEvents() {
+    $('a.comment-close').live("click", function(event) {
+      event.preventDefault();
+      hide($(this).attr('id').substring(2));
+    });
+    $('a.vote').live("click", function(event) {
+      event.preventDefault();
+      handleVote($(this));
+    });
+    $('a.reply').live("click", function(event) {
+      event.preventDefault();
+      openReply($(this).attr('id').substring(2));
+    });
+    $('a.close-reply').live("click", function(event) {
+      event.preventDefault();
+      closeReply($(this).attr('id').substring(2));
+    });
+    $('a.sort-option').live("click", function(event) {
+      event.preventDefault();
+      handleReSort($(this));
+    });
+    $('a.show-proposal').live("click", function(event) {
+      event.preventDefault();
+      showProposal($(this).attr('id').substring(2));
+    });
+    $('a.hide-proposal').live("click", function(event) {
+      event.preventDefault();
+      hideProposal($(this).attr('id').substring(2));
+    });
+    $('a.show-propose-change').live("click", function(event) {
+      event.preventDefault();
+      showProposeChange($(this).attr('id').substring(2));
+    });
+    $('a.hide-propose-change').live("click", function(event) {
+      event.preventDefault();
+      hideProposeChange($(this).attr('id').substring(2));
+    });
+    $('a.accept-comment').live("click", function(event) {
+      event.preventDefault();
+      acceptComment($(this).attr('id').substring(2));
+    });
+    $('a.delete-comment').live("click", function(event) {
+      event.preventDefault();
+      deleteComment($(this).attr('id').substring(2));
+    });
+    $('a.comment-markup').live("click", function(event) {
+      event.preventDefault();
+      toggleCommentMarkupBox($(this).attr('id').substring(2));
+    });
+  }
+
+  /**
+   * Set comp, which is a comparator function used for sorting and
+   * inserting comments into the list.
+   */
+  function setComparator() {
+    // If the first three letters are "asc", sort in ascending order
+    // and remove the prefix.
+    if (by.substring(0,3) == 'asc') {
+      var i = by.substring(3);
+      comp = function(a, b) { return a[i] - b[i]; };
+    } else {
+      // Otherwise sort in descending order.
+      comp = function(a, b) { return b[by] - a[by]; };
+    }
+
+    // Reset link styles and format the selected sort option.
+    $('a.sel').attr('href', '#').removeClass('sel');
+    $('a.by' + by).removeAttr('href').addClass('sel');
+  }
+
+  /**
+   * Create a comp function. If the user has preferences stored in
+   * the sortBy cookie, use those, otherwise use the default.
+   */
+  function initComparator() {
+    by = 'rating'; // Default to sort by rating.
+    // If the sortBy cookie is set, use that instead.
+    if (document.cookie.length > 0) {
+      var start = document.cookie.indexOf('sortBy=');
+      if (start != -1) {
+        start = start + 7;
+        var end = document.cookie.indexOf(";", start);
+        if (end == -1) {
+          end = document.cookie.length;
+          by = unescape(document.cookie.substring(start, end));
+        }
+      }
+    }
+    setComparator();
+  }
+
+  /**
+   * Show a comment div.
+   */
+  function show(id) {
+    $('#ao' + id).hide();
+    $('#ah' + id).show();
+    var context = $.extend({id: id}, opts);
+    var popup = $(renderTemplate(popupTemplate, context)).hide();
+    popup.find('textarea[name="proposal"]').hide();
+    popup.find('a.by' + by).addClass('sel');
+    var form = popup.find('#cf' + id);
+    form.submit(function(event) {
+      event.preventDefault();
+      addComment(form);
+    });
+    $('#s' + id).after(popup);
+    popup.slideDown('fast', function() {
+      getComments(id);
+    });
+  }
+
+  /**
+   * Hide a comment div.
+   */
+  function hide(id) {
+    $('#ah' + id).hide();
+    $('#ao' + id).show();
+    var div = $('#sc' + id);
+    div.slideUp('fast', function() {
+      div.remove();
+    });
+  }
+
+  /**
+   * Perform an ajax request to get comments for a node
+   * and insert the comments into the comments tree.
+   */
+  function getComments(id) {
+    $.ajax({
+     type: 'GET',
+     url: opts.getCommentsURL,
+     data: {node: id},
+     success: function(data, textStatus, request) {
+       var ul = $('#cl' + id);
+       var speed = 100;
+       $('#cf' + id)
+         .find('textarea[name="proposal"]')
+         .data('source', data.source);
+
+       if (data.comments.length === 0) {
+         ul.html('<li>No comments yet.</li>');
+         ul.data('empty', true);
+       } else {
+         // If there are comments, sort them and put them in the list.
+         var comments = sortComments(data.comments);
+         speed = data.comments.length * 100;
+         appendComments(comments, ul);
+         ul.data('empty', false);
+       }
+       $('#cn' + id).slideUp(speed + 200);
+       ul.slideDown(speed);
+     },
+     error: function(request, textStatus, error) {
+       showError('Oops, there was a problem retrieving the comments.');
+     },
+     dataType: 'json'
+    });
+  }
+
+  /**
+   * Add a comment via ajax and insert the comment into the comment tree.
+   */
+  function addComment(form) {
+    var node_id = form.find('input[name="node"]').val();
+    var parent_id = form.find('input[name="parent"]').val();
+    var text = form.find('textarea[name="comment"]').val();
+    var proposal = form.find('textarea[name="proposal"]').val();
+
+    if (text == '') {
+      showError('Please enter a comment.');
+      return;
+    }
+
+    // Disable the form that is being submitted.
+    form.find('textarea,input').attr('disabled', 'disabled');
+
+    // Send the comment to the server.
+    $.ajax({
+      type: "POST",
+      url: opts.addCommentURL,
+      dataType: 'json',
+      data: {
+        node: node_id,
+        parent: parent_id,
+        text: text,
+        proposal: proposal
+      },
+      success: function(data, textStatus, error) {
+        // Reset the form.
+        if (node_id) {
+          hideProposeChange(node_id);
+        }
+        form.find('textarea')
+          .val('')
+          .add(form.find('input'))
+          .removeAttr('disabled');
+	var ul = $('#cl' + (node_id || parent_id));
+        if (ul.data('empty')) {
+          $(ul).empty();
+          ul.data('empty', false);
+        }
+        insertComment(data.comment);
+        var ao = $('#ao' + node_id);
+        ao.find('img').attr({'src': opts.commentBrightImage});
+        if (node_id) {
+          // if this was a "root" comment, remove the commenting box
+          // (the user can get it back by reopening the comment popup)
+          $('#ca' + node_id).slideUp();
+        }
+      },
+      error: function(request, textStatus, error) {
+        form.find('textarea,input').removeAttr('disabled');
+        showError('Oops, there was a problem adding the comment.');
+      }
+    });
+  }
+
+  /**
+   * Recursively append comments to the main comment list and children
+   * lists, creating the comment tree.
+   */
+  function appendComments(comments, ul) {
+    $.each(comments, function() {
+      var div = createCommentDiv(this);
+      ul.append($(document.createElement('li')).html(div));
+      appendComments(this.children, div.find('ul.comment-children'));
+      // To avoid stagnating data, don't store the comments children in data.
+      this.children = null;
+      div.data('comment', this);
+    });
+  }
+
+  /**
+   * After adding a new comment, it must be inserted in the correct
+   * location in the comment tree.
+   */
+  function insertComment(comment) {
+    var div = createCommentDiv(comment);
+
+    // To avoid stagnating data, don't store the comments children in data.
+    comment.children = null;
+    div.data('comment', comment);
+
+    var ul = $('#cl' + (comment.node || comment.parent));
+    var siblings = getChildren(ul);
+
+    var li = $(document.createElement('li'));
+    li.hide();
+
+    // Determine where in the parents children list to insert this comment.
+    for(i=0; i < siblings.length; i++) {
+      if (comp(comment, siblings[i]) <= 0) {
+        $('#cd' + siblings[i].id)
+          .parent()
+          .before(li.html(div));
+        li.slideDown('fast');
+        return;
+      }
+    }
+
+    // If we get here, this comment rates lower than all the others,
+    // or it is the only comment in the list.
+    ul.append(li.html(div));
+    li.slideDown('fast');
+  }
+
+  function acceptComment(id) {
+    $.ajax({
+      type: 'POST',
+      url: opts.acceptCommentURL,
+      data: {id: id},
+      success: function(data, textStatus, request) {
+        $('#cm' + id).fadeOut('fast');
+        $('#cd' + id).removeClass('moderate');
+      },
+      error: function(request, textStatus, error) {
+        showError('Oops, there was a problem accepting the comment.');
+      }
+    });
+  }
+
+  function deleteComment(id) {
+    $.ajax({
+      type: 'POST',
+      url: opts.deleteCommentURL,
+      data: {id: id},
+      success: function(data, textStatus, request) {
+        var div = $('#cd' + id);
+        if (data == 'delete') {
+          // Moderator mode: remove the comment and all children immediately
+          div.slideUp('fast', function() {
+            div.remove();
+          });
+          return;
+        }
+        // User mode: only mark the comment as deleted
+        div
+          .find('span.user-id:first')
+          .text('[deleted]').end()
+          .find('div.comment-text:first')
+          .text('[deleted]').end()
+          .find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id +
+                ', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id)
+          .remove();
+        var comment = div.data('comment');
+        comment.username = '[deleted]';
+        comment.text = '[deleted]';
+        div.data('comment', comment);
+      },
+      error: function(request, textStatus, error) {
+        showError('Oops, there was a problem deleting the comment.');
+      }
+    });
+  }
+
+  function showProposal(id) {
+    $('#sp' + id).hide();
+    $('#hp' + id).show();
+    $('#pr' + id).slideDown('fast');
+  }
+
+  function hideProposal(id) {
+    $('#hp' + id).hide();
+    $('#sp' + id).show();
+    $('#pr' + id).slideUp('fast');
+  }
+
+  function showProposeChange(id) {
+    $('#pc' + id).hide();
+    $('#hc' + id).show();
+    var textarea = $('#pt' + id);
+    textarea.val(textarea.data('source'));
+    $.fn.autogrow.resize(textarea[0]);
+    textarea.slideDown('fast');
+  }
+
+  function hideProposeChange(id) {
+    $('#hc' + id).hide();
+    $('#pc' + id).show();
+    var textarea = $('#pt' + id);
+    textarea.val('').removeAttr('disabled');
+    textarea.slideUp('fast');
+  }
+
+  function toggleCommentMarkupBox(id) {
+    $('#mb' + id).toggle();
+  }
+
+  /** Handle when the user clicks on a sort by link. */
+  function handleReSort(link) {
+    var classes = link.attr('class').split(/\s+/);
+    for (var i=0; i<classes.length; i++) {
+      if (classes[i] != 'sort-option') {
+	by = classes[i].substring(2);
+      }
+    }
+    setComparator();
+    // Save/update the sortBy cookie.
+    var expiration = new Date();
+    expiration.setDate(expiration.getDate() + 365);
+    document.cookie= 'sortBy=' + escape(by) +
+                     ';expires=' + expiration.toUTCString();
+    $('ul.comment-ul').each(function(index, ul) {
+      var comments = getChildren($(ul), true);
+      comments = sortComments(comments);
+      appendComments(comments, $(ul).empty());
+    });
+  }
+
+  /**
+   * Function to process a vote when a user clicks an arrow.
+   */
+  function handleVote(link) {
+    if (!opts.voting) {
+      showError("You'll need to login to vote.");
+      return;
+    }
+
+    var id = link.attr('id');
+    if (!id) {
+      // Didn't click on one of the voting arrows.
+      return;
+    }
+    // If it is an unvote, the new vote value is 0,
+    // Otherwise it's 1 for an upvote, or -1 for a downvote.
+    var value = 0;
+    if (id.charAt(1) != 'u') {
+      value = id.charAt(0) == 'u' ? 1 : -1;
+    }
+    // The data to be sent to the server.
+    var d = {
+      comment_id: id.substring(2),
+      value: value
+    };
+
+    // Swap the vote and unvote links.
+    link.hide();
+    $('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id)
+      .show();
+
+    // The div the comment is displayed in.
+    var div = $('div#cd' + d.comment_id);
+    var data = div.data('comment');
+
+    // If this is not an unvote, and the other vote arrow has
+    // already been pressed, unpress it.
+    if ((d.value !== 0) && (data.vote === d.value * -1)) {
+      $('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide();
+      $('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show();
+    }
+
+    // Update the comments rating in the local data.
+    data.rating += (data.vote === 0) ? d.value : (d.value - data.vote);
+    data.vote = d.value;
+    div.data('comment', data);
+
+    // Change the rating text.
+    div.find('.rating:first')
+      .text(data.rating + ' point' + (data.rating == 1 ? '' : 's'));
+
+    // Send the vote information to the server.
+    $.ajax({
+      type: "POST",
+      url: opts.processVoteURL,
+      data: d,
+      error: function(request, textStatus, error) {
+        showError('Oops, there was a problem casting that vote.');
+      }
+    });
+  }
+
+  /**
+   * Open a reply form used to reply to an existing comment.
+   */
+  function openReply(id) {
+    // Swap out the reply link for the hide link
+    $('#rl' + id).hide();
+    $('#cr' + id).show();
+
+    // Add the reply li to the children ul.
+    var div = $(renderTemplate(replyTemplate, {id: id})).hide();
+    $('#cl' + id)
+      .prepend(div)
+      // Setup the submit handler for the reply form.
+      .find('#rf' + id)
+      .submit(function(event) {
+        event.preventDefault();
+        addComment($('#rf' + id));
+        closeReply(id);
+      })
+      .find('input[type=button]')
+      .click(function() {
+        closeReply(id);
+      });
+    div.slideDown('fast', function() {
+      $('#rf' + id).find('textarea').focus();
+    });
+  }
+
+  /**
+   * Close the reply form opened with openReply.
+   */
+  function closeReply(id) {
+    // Remove the reply div from the DOM.
+    $('#rd' + id).slideUp('fast', function() {
+      $(this).remove();
+    });
+
+    // Swap out the hide link for the reply link
+    $('#cr' + id).hide();
+    $('#rl' + id).show();
+  }
+
+  /**
+   * Recursively sort a tree of comments using the comp comparator.
+   */
+  function sortComments(comments) {
+    comments.sort(comp);
+    $.each(comments, function() {
+      this.children = sortComments(this.children);
+    });
+    return comments;
+  }
+
+  /**
+   * Get the children comments from a ul. If recursive is true,
+   * recursively include childrens' children.
+   */
+  function getChildren(ul, recursive) {
+    var children = [];
+    ul.children().children("[id^='cd']")
+      .each(function() {
+        var comment = $(this).data('comment');
+        if (recursive)
+          comment.children = getChildren($(this).find('#cl' + comment.id), true);
+        children.push(comment);
+      });
+    return children;
+  }
+
+  /** Create a div to display a comment in. */
+  function createCommentDiv(comment) {
+    if (!comment.displayed && !opts.moderator) {
+      return $('<div class="moderate">Thank you!  Your comment will show up '
+               + 'once it is has been approved by a moderator.</div>');
+    }
+    // Prettify the comment rating.
+    comment.pretty_rating = comment.rating + ' point' +
+      (comment.rating == 1 ? '' : 's');
+    // Make a class (for displaying not yet moderated comments differently)
+    comment.css_class = comment.displayed ? '' : ' moderate';
+    // Create a div for this comment.
+    var context = $.extend({}, opts, comment);
+    var div = $(renderTemplate(commentTemplate, context));
+
+    // If the user has voted on this comment, highlight the correct arrow.
+    if (comment.vote) {
+      var direction = (comment.vote == 1) ? 'u' : 'd';
+      div.find('#' + direction + 'v' + comment.id).hide();
+      div.find('#' + direction + 'u' + comment.id).show();
+    }
+
+    if (opts.moderator || comment.text != '[deleted]') {
+      div.find('a.reply').show();
+      if (comment.proposal_diff)
+        div.find('#sp' + comment.id).show();
+      if (opts.moderator && !comment.displayed)
+        div.find('#cm' + comment.id).show();
+      if (opts.moderator || (opts.username == comment.username))
+        div.find('#dc' + comment.id).show();
+    }
+    return div;
+  }
+
+  /**
+   * A simple template renderer. Placeholders such as <%id%> are replaced
+   * by context['id'] with items being escaped. Placeholders such as <#id#>
+   * are not escaped.
+   */
+  function renderTemplate(template, context) {
+    var esc = $(document.createElement('div'));
+
+    function handle(ph, escape) {
+      var cur = context;
+      $.each(ph.split('.'), function() {
+        cur = cur[this];
+      });
+      return escape ? esc.text(cur || "").html() : cur;
+    }
+
+    return template.replace(/<([%#])([\w\.]*)\1>/g, function() {
+      return handle(arguments[2], arguments[1] == '%' ? true : false);
+    });
+  }
+
+  /** Flash an error message briefly. */
+  function showError(message) {
+    $(document.createElement('div')).attr({'class': 'popup-error'})
+      .append($(document.createElement('div'))
+               .attr({'class': 'error-message'}).text(message))
+      .appendTo('body')
+      .fadeIn("slow")
+      .delay(2000)
+      .fadeOut("slow");
+  }
+
+  /** Add a link the user uses to open the comments popup. */
+  $.fn.comment = function() {
+    return this.each(function() {
+      var id = $(this).attr('id').substring(1);
+      var count = COMMENT_METADATA[id];
+      var title = count + ' comment' + (count == 1 ? '' : 's');
+      var image = count > 0 ? opts.commentBrightImage : opts.commentImage;
+      var addcls = count == 0 ? ' nocomment' : '';
+      $(this)
+        .append(
+          $(document.createElement('a')).attr({
+            href: '#',
+            'class': 'sphinx-comment-open' + addcls,
+            id: 'ao' + id
+          })
+            .append($(document.createElement('img')).attr({
+              src: image,
+              alt: 'comment',
+              title: title
+            }))
+            .click(function(event) {
+              event.preventDefault();
+              show($(this).attr('id').substring(2));
+            })
+        )
+        .append(
+          $(document.createElement('a')).attr({
+            href: '#',
+            'class': 'sphinx-comment-close hidden',
+            id: 'ah' + id
+          })
+            .append($(document.createElement('img')).attr({
+              src: opts.closeCommentImage,
+              alt: 'close',
+              title: 'close'
+            }))
+            .click(function(event) {
+              event.preventDefault();
+              hide($(this).attr('id').substring(2));
+            })
+        );
+    });
+  };
+
+  var opts = {
+    processVoteURL: '/_process_vote',
+    addCommentURL: '/_add_comment',
+    getCommentsURL: '/_get_comments',
+    acceptCommentURL: '/_accept_comment',
+    deleteCommentURL: '/_delete_comment',
+    commentImage: '/static/_static/comment.png',
+    closeCommentImage: '/static/_static/comment-close.png',
+    loadingImage: '/static/_static/ajax-loader.gif',
+    commentBrightImage: '/static/_static/comment-bright.png',
+    upArrow: '/static/_static/up.png',
+    downArrow: '/static/_static/down.png',
+    upArrowPressed: '/static/_static/up-pressed.png',
+    downArrowPressed: '/static/_static/down-pressed.png',
+    voting: false,
+    moderator: false
+  };
+
+  if (typeof COMMENT_OPTIONS != "undefined") {
+    opts = jQuery.extend(opts, COMMENT_OPTIONS);
+  }
+
+  var popupTemplate = '\
+    <div class="sphinx-comments" id="sc<%id%>">\
+      <p class="sort-options">\
+        Sort by:\
+        <a href="#" class="sort-option byrating">best rated</a>\
+        <a href="#" class="sort-option byascage">newest</a>\
+        <a href="#" class="sort-option byage">oldest</a>\
+      </p>\
+      <div class="comment-header">Comments</div>\
+      <div class="comment-loading" id="cn<%id%>">\
+        loading comments... <img src="<%loadingImage%>" alt="" /></div>\
+      <ul id="cl<%id%>" class="comment-ul"></ul>\
+      <div id="ca<%id%>">\
+      <p class="add-a-comment">Add a comment\
+        (<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\
+      <div class="comment-markup-box" id="mb<%id%>">\
+        reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \
+        <tt>``code``</tt>, \
+        code blocks: <tt>::</tt> and an indented block after blank line</div>\
+      <form method="post" id="cf<%id%>" class="comment-form" action="">\
+        <textarea name="comment" cols="80"></textarea>\
+        <p class="propose-button">\
+          <a href="#" id="pc<%id%>" class="show-propose-change">\
+            Propose a change &#9657;\
+          </a>\
+          <a href="#" id="hc<%id%>" class="hide-propose-change">\
+            Propose a change &#9663;\
+          </a>\
+        </p>\
+        <textarea name="proposal" id="pt<%id%>" cols="80"\
+                  spellcheck="false"></textarea>\
+        <input type="submit" value="Add comment" />\
+        <input type="hidden" name="node" value="<%id%>" />\
+        <input type="hidden" name="parent" value="" />\
+      </form>\
+      </div>\
+    </div>';
+
+  var commentTemplate = '\
+    <div id="cd<%id%>" class="sphinx-comment<%css_class%>">\
+      <div class="vote">\
+        <div class="arrow">\
+          <a href="#" id="uv<%id%>" class="vote" title="vote up">\
+            <img src="<%upArrow%>" />\
+          </a>\
+          <a href="#" id="uu<%id%>" class="un vote" title="vote up">\
+            <img src="<%upArrowPressed%>" />\
+          </a>\
+        </div>\
+        <div class="arrow">\
+          <a href="#" id="dv<%id%>" class="vote" title="vote down">\
+            <img src="<%downArrow%>" id="da<%id%>" />\
+          </a>\
+          <a href="#" id="du<%id%>" class="un vote" title="vote down">\
+            <img src="<%downArrowPressed%>" />\
+          </a>\
+        </div>\
+      </div>\
+      <div class="comment-content">\
+        <p class="tagline comment">\
+          <span class="user-id"><%username%></span>\
+          <span class="rating"><%pretty_rating%></span>\
+          <span class="delta"><%time.delta%></span>\
+        </p>\
+        <div class="comment-text comment"><#text#></div>\
+        <p class="comment-opts comment">\
+          <a href="#" class="reply hidden" id="rl<%id%>">reply &#9657;</a>\
+          <a href="#" class="close-reply" id="cr<%id%>">reply &#9663;</a>\
+          <a href="#" id="sp<%id%>" class="show-proposal">proposal &#9657;</a>\
+          <a href="#" id="hp<%id%>" class="hide-proposal">proposal &#9663;</a>\
+          <a href="#" id="dc<%id%>" class="delete-comment hidden">delete</a>\
+          <span id="cm<%id%>" class="moderation hidden">\
+            <a href="#" id="ac<%id%>" class="accept-comment">accept</a>\
+          </span>\
+        </p>\
+        <pre class="proposal" id="pr<%id%>">\
+<#proposal_diff#>\
+        </pre>\
+          <ul class="comment-children" id="cl<%id%>"></ul>\
+        </div>\
+        <div class="clearleft"></div>\
+      </div>\
+    </div>';
+
+  var replyTemplate = '\
+    <li>\
+      <div class="reply-div" id="rd<%id%>">\
+        <form id="rf<%id%>">\
+          <textarea name="comment" cols="80"></textarea>\
+          <input type="submit" value="Add reply" />\
+          <input type="button" value="Cancel" />\
+          <input type="hidden" name="parent" value="<%id%>" />\
+          <input type="hidden" name="node" value="" />\
+        </form>\
+      </div>\
+    </li>';
+
+  $(document).ready(function() {
+    init();
+  });
+})(jQuery);
+
+$(document).ready(function() {
+  // add comment anchors for all paragraphs that are commentable
+  $('.sphinx-has-comment').comment();
+
+  // highlight search words in search results
+  $("div.context").each(function() {
+    var params = $.getQueryParameters();
+    var terms = (params.q) ? params.q[0].split(/\s+/) : [];
+    var result = $(this);
+    $.each(terms, function() {
+      result.highlightText(this.toLowerCase(), 'highlighted');
+    });
+  });
+
+  // directly open comment window if requested
+  var anchor = document.location.hash;
+  if (anchor.substring(0, 9) == '#comment-') {
+    $('#ao' + anchor.substring(9)).click();
+    document.location.hash = '#s' + anchor.substring(9);
+  }
+});

+ 147 - 0
doc/build/camlib.html

@@ -0,0 +1,147 @@
+
+
+<!DOCTYPE html>
+<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
+<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  
+  <title>This is the main file for camlib &mdash; Cirkuix 0.5 documentation</title>
+  
+
+  
+  
+
+  
+  <link href='https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700' rel='stylesheet' type='text/css'>
+
+  
+  
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:'./',
+        VERSION:'0.5',
+        COLLAPSE_INDEX:false,
+        FILE_SUFFIX:'.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+      <script type="text/javascript" src="_static/jquery.js"></script>
+      <script type="text/javascript" src="_static/underscore.js"></script>
+      <script type="text/javascript" src="_static/doctools.js"></script>
+
+    
+
+  
+
+  
+  
+    <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
+    <script type="text/javascript" src="_static/js/theme.js"></script>
+  
+
+  
+  
+    <script type="text/javascript">
+        jQuery(function () {
+            SphinxRtdTheme.StickyNav.enable();
+        });
+    </script>
+  
+
+  
+    <link rel="top" title="Cirkuix 0.5 documentation" href="index.html"/> 
+
+  <script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script>
+
+</head>
+
+<body class="wy-body-for-nav" role="document">
+
+  <div class="wy-grid-for-nav">
+
+    
+    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
+      <div class="wy-side-nav-search">
+        <a href="index.html" class="icon icon-home"> Cirkuix</a>
+        <div role="search">
+  <form id ="rtd-search-form" class="wy-form" action="search.html" method="get">
+    <input type="text" name="q" placeholder="Search docs" />
+    <input type="hidden" name="check_keywords" value="yes" />
+    <input type="hidden" name="area" value="default" />
+  </form>
+</div>
+      </div>
+
+      <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
+        
+        
+            <!-- Local TOC -->
+            <div class="local-toc"><ul>
+<li><a class="reference internal" href="#">This is the main file for camlib</a></li>
+</ul>
+</div>
+        
+      </div>
+      &nbsp;
+    </nav>
+
+    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
+
+      
+      <nav class="wy-nav-top" role="navigation" aria-label="top navigation">
+        <i data-toggle="wy-nav-top" class="icon icon-reorder"></i>
+        <a href="index.html">Cirkuix</a>
+      </nav>
+
+
+      
+      <div class="wy-nav-content">
+        <div class="rst-content">
+          <div role="navigation" aria-label="breadcrumbs navigation">
+  <ul class="wy-breadcrumbs">
+    <li><a href="index.html">Docs</a> &raquo;</li>
+      
+    <li>This is the main file for camlib</li>
+      <li class="wy-breadcrumbs-aside">
+        
+          <a href="_sources/camlib.txt" rel="nofollow"> View page source</a>
+        
+      </li>
+  </ul>
+  <hr/>
+</div>
+          <div role="main">
+            
+  <div class="section" id="this-is-the-main-file-for-camlib">
+<h1>This is the main file for camlib<a class="headerlink" href="#this-is-the-main-file-for-camlib" title="Permalink to this headline">¶</a></h1>
+<p>Some text.</p>
+</div>
+
+
+          </div>
+          <footer>
+  
+
+  <hr/>
+
+  <div role="contentinfo">
+    <p>
+        &copy; Copyright 2014, Juan Pablo Caram.
+    </p>
+  </div>
+
+  <a href="https://github.com/snide/sphinx_rtd_theme">Sphinx theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>
+</footer>
+        </div>
+      </div>
+
+    </section>
+
+  </div>
+  
+
+</body>
+</html>

+ 554 - 0
doc/build/genindex.html

@@ -0,0 +1,554 @@
+
+
+
+<!DOCTYPE html>
+<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
+<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  
+  <title>Index &mdash; Cirkuix 0.5 documentation</title>
+  
+
+  
+  
+
+  
+  <link href='https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700' rel='stylesheet' type='text/css'>
+
+  
+  
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:'./',
+        VERSION:'0.5',
+        COLLAPSE_INDEX:false,
+        FILE_SUFFIX:'.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+      <script type="text/javascript" src="_static/jquery.js"></script>
+      <script type="text/javascript" src="_static/underscore.js"></script>
+      <script type="text/javascript" src="_static/doctools.js"></script>
+
+    
+
+  
+
+  
+  
+    <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
+    <script type="text/javascript" src="_static/js/theme.js"></script>
+  
+
+  
+  
+    <script type="text/javascript">
+        jQuery(function () {
+            SphinxRtdTheme.StickyNav.enable();
+        });
+    </script>
+  
+
+  
+    <link rel="top" title="Cirkuix 0.5 documentation" href="index.html"/> 
+
+  <script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script>
+
+</head>
+
+<body class="wy-body-for-nav" role="document">
+
+  <div class="wy-grid-for-nav">
+
+    
+    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
+      <div class="wy-side-nav-search">
+        <a href="index.html" class="icon icon-home"> Cirkuix</a>
+        <div role="search">
+  <form id ="rtd-search-form" class="wy-form" action="search.html" method="get">
+    <input type="text" name="q" placeholder="Search docs" />
+    <input type="hidden" name="check_keywords" value="yes" />
+    <input type="hidden" name="area" value="default" />
+  </form>
+</div>
+      </div>
+
+      <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
+        
+        
+            <ul class="simple">
+</ul>
+
+        
+      </div>
+      &nbsp;
+    </nav>
+
+    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
+
+      
+      <nav class="wy-nav-top" role="navigation" aria-label="top navigation">
+        <i data-toggle="wy-nav-top" class="icon icon-reorder"></i>
+        <a href="index.html">Cirkuix</a>
+      </nav>
+
+
+      
+      <div class="wy-nav-content">
+        <div class="rst-content">
+          <div role="navigation" aria-label="breadcrumbs navigation">
+  <ul class="wy-breadcrumbs">
+    <li><a href="index.html">Docs</a> &raquo;</li>
+      
+    <li></li>
+      <li class="wy-breadcrumbs-aside">
+        
+      </li>
+  </ul>
+  <hr/>
+</div>
+          <div role="main">
+            
+
+<h1 id="index">Index</h1>
+
+<div class="genindex-jumpbox">
+ <a href="#A"><strong>A</strong></a>
+ | <a href="#B"><strong>B</strong></a>
+ | <a href="#C"><strong>C</strong></a>
+ | <a href="#D"><strong>D</strong></a>
+ | <a href="#E"><strong>E</strong></a>
+ | <a href="#F"><strong>F</strong></a>
+ | <a href="#G"><strong>G</strong></a>
+ | <a href="#I"><strong>I</strong></a>
+ | <a href="#N"><strong>N</strong></a>
+ | <a href="#O"><strong>O</strong></a>
+ | <a href="#P"><strong>P</strong></a>
+ | <a href="#R"><strong>R</strong></a>
+ | <a href="#S"><strong>S</strong></a>
+ | <a href="#Z"><strong>Z</strong></a>
+ 
+</div>
+<h2 id="A">A</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.Gerber.aperture_parse">aperture_parse() (cirkuix.Gerber method)</a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.App">App (class in cirkuix)</a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="B">B</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.Geometry.bounds">bounds() (cirkuix.Geometry method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.App.build_list">build_list() (cirkuix.App method)</a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.CirkuixObj.build_ui">build_ui() (cirkuix.CirkuixObj method)</a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="C">C</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#module-cirkuix">cirkuix (module)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.CirkuixCNCjob">CirkuixCNCjob (class in cirkuix)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.CirkuixExcellon">CirkuixExcellon (class in cirkuix)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.CirkuixGeometry">CirkuixGeometry (class in cirkuix)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.CirkuixGerber">CirkuixGerber (class in cirkuix)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.CirkuixObj">CirkuixObj (class in cirkuix)</a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.App.clear_plots">clear_plots() (cirkuix.App method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.Geometry.clear_polygon">clear_polygon() (cirkuix.Geometry method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.CNCjob">CNCjob (class in cirkuix)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.Geometry.convert_units">convert_units() (cirkuix.Geometry method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.Gerber.create_geometry">create_geometry() (cirkuix.Gerber method)</a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="D">D</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.CirkuixObj.deserialize">deserialize() (cirkuix.CirkuixObj method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.Gerber.digits">digits (cirkuix.Gerber attribute)</a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.Gerber.do_flashes">do_flashes() (cirkuix.Gerber method)</a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="E">E</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.Excellon">Excellon (class in cirkuix)</a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="F">F</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.App.file_chooser_action">file_chooser_action() (cirkuix.App method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.App.file_chooser_save_action">file_chooser_save_action() (cirkuix.App method)</a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.Gerber.fix_regions">fix_regions() (cirkuix.Gerber method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.Gerber.fraction">fraction (cirkuix.Gerber attribute)</a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="G">G</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.CNCjob.gcode_parse">gcode_parse() (cirkuix.CNCjob method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.CNCjob.generate_from_excellon">generate_from_excellon() (cirkuix.CNCjob method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.CNCjob.generate_from_excellon_by_tool">generate_from_excellon_by_tool() (cirkuix.CNCjob method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.CNCjob.generate_from_geometry">generate_from_geometry() (cirkuix.CNCjob method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.Geometry">Geometry (class in cirkuix)</a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.Gerber">Gerber (class in cirkuix)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.App.get_current">get_current() (cirkuix.App method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.Geometry.get_empty_area">get_empty_area() (cirkuix.Geometry method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.App.get_eval">get_eval() (cirkuix.App method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.App.get_radio_value">get_radio_value() (cirkuix.App method)</a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="I">I</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.App.info">info() (cirkuix.App method)</a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.Geometry.isolation_geometry">isolation_geometry() (cirkuix.Geometry method)</a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="N">N</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.App.new_object">new_object() (cirkuix.App method)</a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="O">O</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.App.on_activate_name">on_activate_name() (cirkuix.App method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.App.on_delete">on_delete() (cirkuix.App method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.App.on_eval_update">on_eval_update() (cirkuix.App method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.App.on_excellon_tool_choose">on_excellon_tool_choose() (cirkuix.App method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.App.on_generate_cncjob">on_generate_cncjob() (cirkuix.App method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.App.on_generate_excellon_cncjob">on_generate_excellon_cncjob() (cirkuix.App method)</a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.App.on_generate_isolation">on_generate_isolation() (cirkuix.App method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.App.on_generate_paintarea">on_generate_paintarea() (cirkuix.App method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.App.on_gerber_generate_cutout">on_gerber_generate_cutout() (cirkuix.App method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.App.on_gerber_generate_noncopper">on_gerber_generate_noncopper() (cirkuix.App method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.App.on_tree_selection_changed">on_tree_selection_changed() (cirkuix.App method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.App.on_update_plot">on_update_plot() (cirkuix.App method)</a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="P">P</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.Gerber.parse_file">parse_file() (cirkuix.Gerber method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.Excellon.parse_lines">parse_lines() (cirkuix.Excellon method)</a>
+  </dt>
+
+      <dd><dl>
+        
+  <dt><a href="index.html#cirkuix.Gerber.parse_lines">(cirkuix.Gerber method)</a>
+  </dt>
+
+      </dl></dd>
+      
+  <dt><a href="index.html#cirkuix.CirkuixObj.plot">plot() (cirkuix.CirkuixObj method)</a>
+  </dt>
+
+      <dd><dl>
+        
+  <dt><a href="index.html#cirkuix.CNCjob.plot">(cirkuix.CNCjob method)</a>
+  </dt>
+
+      </dl></dd>
+      
+  <dt><a href="index.html#cirkuix.CNCjob.plot2">plot2() (cirkuix.CNCjob method)</a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.App.plot_all">plot_all() (cirkuix.App method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.CNCjob.polygon2gcode">polygon2gcode() (cirkuix.CNCjob method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.CNCjob.pre_parse">pre_parse() (cirkuix.CNCjob method)</a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="R">R</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.CirkuixObj.read_form">read_form() (cirkuix.CirkuixObj method)</a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="S">S</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.CNCjob.scale">scale() (cirkuix.CNCjob method)</a>
+  </dt>
+
+      <dd><dl>
+        
+  <dt><a href="index.html#cirkuix.Excellon.scale">(cirkuix.Excellon method)</a>
+  </dt>
+
+        
+  <dt><a href="index.html#cirkuix.Geometry.scale">(cirkuix.Geometry method)</a>
+  </dt>
+
+        
+  <dt><a href="index.html#cirkuix.Gerber.scale">(cirkuix.Gerber method)</a>
+  </dt>
+
+      </dl></dd>
+      
+  <dt><a href="index.html#cirkuix.CirkuixObj.serialize">serialize() (cirkuix.CirkuixObj method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.App.set_list_selection">set_list_selection() (cirkuix.App method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.CirkuixObj.setup_axes">setup_axes() (cirkuix.CirkuixObj method)</a>
+  </dt>
+
+  </dl></td>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.App.setup_component_editor">setup_component_editor() (cirkuix.App method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.App.setup_component_viewer">setup_component_viewer() (cirkuix.App method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.App.setup_plot">setup_plot() (cirkuix.App method)</a>
+  </dt>
+
+      
+  <dt><a href="index.html#cirkuix.Geometry.size">size() (cirkuix.Geometry method)</a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+<h2 id="Z">Z</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%" valign="top"><dl>
+      
+  <dt><a href="index.html#cirkuix.App.zoom">zoom() (cirkuix.App method)</a>
+  </dt>
+
+  </dl></td>
+</tr></table>
+
+
+
+          </div>
+          <footer>
+  
+
+  <hr/>
+
+  <div role="contentinfo">
+    <p>
+        &copy; Copyright 2014, Juan Pablo Caram.
+    </p>
+  </div>
+
+  <a href="https://github.com/snide/sphinx_rtd_theme">Sphinx theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>
+</footer>
+        </div>
+      </div>
+
+    </section>
+
+  </div>
+  
+
+</body>
+</html>

+ 905 - 0
doc/build/index.html

@@ -0,0 +1,905 @@
+
+
+<!DOCTYPE html>
+<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
+<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  
+  <title>Welcome to Cirkuix’s documentation! &mdash; Cirkuix 0.5 documentation</title>
+  
+
+  
+  
+
+  
+  <link href='https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700' rel='stylesheet' type='text/css'>
+
+  
+  
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:'./',
+        VERSION:'0.5',
+        COLLAPSE_INDEX:false,
+        FILE_SUFFIX:'.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+      <script type="text/javascript" src="_static/jquery.js"></script>
+      <script type="text/javascript" src="_static/underscore.js"></script>
+      <script type="text/javascript" src="_static/doctools.js"></script>
+
+    
+
+  
+
+  
+  
+    <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
+    <script type="text/javascript" src="_static/js/theme.js"></script>
+  
+
+  
+  
+    <script type="text/javascript">
+        jQuery(function () {
+            SphinxRtdTheme.StickyNav.enable();
+        });
+    </script>
+  
+
+  
+    <link rel="top" title="Cirkuix 0.5 documentation" href="#"/> 
+
+  <script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script>
+
+</head>
+
+<body class="wy-body-for-nav" role="document">
+
+  <div class="wy-grid-for-nav">
+
+    
+    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
+      <div class="wy-side-nav-search">
+        <a href="#" class="icon icon-home"> Cirkuix</a>
+        <div role="search">
+  <form id ="rtd-search-form" class="wy-form" action="search.html" method="get">
+    <input type="text" name="q" placeholder="Search docs" />
+    <input type="hidden" name="check_keywords" value="yes" />
+    <input type="hidden" name="area" value="default" />
+  </form>
+</div>
+      </div>
+
+      <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
+        
+        
+            <ul class="simple">
+</ul>
+
+        
+      </div>
+      &nbsp;
+    </nav>
+
+    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
+
+      
+      <nav class="wy-nav-top" role="navigation" aria-label="top navigation">
+        <i data-toggle="wy-nav-top" class="icon icon-reorder"></i>
+        <a href="#">Cirkuix</a>
+      </nav>
+
+
+      
+      <div class="wy-nav-content">
+        <div class="rst-content">
+          <div role="navigation" aria-label="breadcrumbs navigation">
+  <ul class="wy-breadcrumbs">
+    <li><a href="#">Docs</a> &raquo;</li>
+      
+    <li>Welcome to Cirkuix&#8217;s documentation!</li>
+      <li class="wy-breadcrumbs-aside">
+        
+          <a href="_sources/index.txt" rel="nofollow"> View page source</a>
+        
+      </li>
+  </ul>
+  <hr/>
+</div>
+          <div role="main">
+            
+  <div class="section" id="welcome-to-cirkuix-s-documentation">
+<h1>Welcome to Cirkuix&#8217;s documentation!<a class="headerlink" href="#welcome-to-cirkuix-s-documentation" title="Permalink to this headline">¶</a></h1>
+<p>Contents:</p>
+<div class="toctree-wrapper compound">
+<ul class="simple">
+</ul>
+</div>
+<span class="target" id="module-cirkuix"></span><dl class="class">
+<dt id="cirkuix.App">
+<em class="property">class </em><tt class="descclassname">cirkuix.</tt><tt class="descname">App</tt><a class="headerlink" href="#cirkuix.App" title="Permalink to this definition">¶</a></dt>
+<dd><p>The main application class. The constructor starts the GUI.</p>
+<dl class="method">
+<dt id="cirkuix.App.build_list">
+<tt class="descname">build_list</tt><big>(</big><big>)</big><a class="headerlink" href="#cirkuix.App.build_list" title="Permalink to this definition">¶</a></dt>
+<dd><p>Clears and re-populates the list of objects in currently
+in the project.
+&#64;return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.clear_plots">
+<tt class="descname">clear_plots</tt><big>(</big><big>)</big><a class="headerlink" href="#cirkuix.App.clear_plots" title="Permalink to this definition">¶</a></dt>
+<dd><p>Clears self.axes and self.figure.
+&#64;return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.file_chooser_action">
+<tt class="descname">file_chooser_action</tt><big>(</big><em>on_success</em><big>)</big><a class="headerlink" href="#cirkuix.App.file_chooser_action" title="Permalink to this definition">¶</a></dt>
+<dd><p>Opens the file chooser and runs on_success on a separate thread
+upon completion of valid file choice.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.file_chooser_save_action">
+<tt class="descname">file_chooser_save_action</tt><big>(</big><em>on_success</em><big>)</big><a class="headerlink" href="#cirkuix.App.file_chooser_save_action" title="Permalink to this definition">¶</a></dt>
+<dd><p>Opens the file chooser and runs on_success
+upon completion of valid file choice.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.get_current">
+<tt class="descname">get_current</tt><big>(</big><big>)</big><a class="headerlink" href="#cirkuix.App.get_current" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns the currently selected CirkuixObj in the application.
+&#64;return: Currently selected CirkuixObj in the application.
+&#64;rtype: CirkuixObj</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.get_eval">
+<tt class="descname">get_eval</tt><big>(</big><em>widget_name</em><big>)</big><a class="headerlink" href="#cirkuix.App.get_eval" title="Permalink to this definition">¶</a></dt>
+<dd><p>Runs eval() on the on the text entry of name &#8216;widget_name&#8217;
+and returns the results.
+&#64;param widget_name: Name of Gtk.Entry
+&#64;return: Depends on contents of the entry text.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.get_radio_value">
+<tt class="descname">get_radio_value</tt><big>(</big><em>radio_set</em><big>)</big><a class="headerlink" href="#cirkuix.App.get_radio_value" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns the radio_set[key] if the radiobutton
+whose name is key is active.
+&#64;return: radio_set[key]</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.info">
+<tt class="descname">info</tt><big>(</big><em>text</em><big>)</big><a class="headerlink" href="#cirkuix.App.info" title="Permalink to this definition">¶</a></dt>
+<dd><p>Show text on the status bar.
+&#64;return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.new_object">
+<tt class="descname">new_object</tt><big>(</big><em>kind</em>, <em>name</em>, <em>initialize</em><big>)</big><a class="headerlink" href="#cirkuix.App.new_object" title="Permalink to this definition">¶</a></dt>
+<dd><p>Creates a new specalized CirkuixObj and attaches it to the application,
+this is, updates the GUI accordingly, any other records and plots it.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>kind</strong> (<em>str</em>) &#8211; The kind of object to create. One of &#8216;gerber&#8217;,
+&#8216;excellon&#8217;, &#8216;cncjob&#8217; and &#8216;geometry&#8217;.</li>
+<li><strong>name</strong> (<em>str</em>) &#8211; Name for the object.</li>
+<li><strong>initialize</strong> (<em>function</em>) &#8211; Function to run after creation of the object
+but before it is attached to the application. The function is
+called with 2 parameters: the new object and the App instance.</li>
+</ul>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first">None</p>
+</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">None</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.on_activate_name">
+<tt class="descname">on_activate_name</tt><big>(</big><em>entry</em><big>)</big><a class="headerlink" href="#cirkuix.App.on_activate_name" title="Permalink to this definition">¶</a></dt>
+<dd><p>Hitting &#8216;Enter&#8217; after changing the name of an item
+updates the item dictionary and re-builds the item list.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.on_delete">
+<tt class="descname">on_delete</tt><big>(</big><em>widget</em><big>)</big><a class="headerlink" href="#cirkuix.App.on_delete" title="Permalink to this definition">¶</a></dt>
+<dd><p>Delete the currently selected CirkuixObj.
+&#64;param widget: The widget from which this was called.
+&#64;return:</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.on_eval_update">
+<tt class="descname">on_eval_update</tt><big>(</big><em>widget</em><big>)</big><a class="headerlink" href="#cirkuix.App.on_eval_update" title="Permalink to this definition">¶</a></dt>
+<dd><p>Modifies the content of a Gtk.Entry by running
+eval() on its contents and puting it back as a
+string.
+&#64;param widget: The widget from which this was called.
+&#64;return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.on_excellon_tool_choose">
+<tt class="descname">on_excellon_tool_choose</tt><big>(</big><em>widget</em><big>)</big><a class="headerlink" href="#cirkuix.App.on_excellon_tool_choose" title="Permalink to this definition">¶</a></dt>
+<dd><p>Callback for button on Excellon form to open up a window for
+selecting tools.
+&#64;param widget: The widget from which this was called.
+&#64;return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.on_generate_cncjob">
+<tt class="descname">on_generate_cncjob</tt><big>(</big><em>widget</em><big>)</big><a class="headerlink" href="#cirkuix.App.on_generate_cncjob" title="Permalink to this definition">¶</a></dt>
+<dd><p>Callback for button on geometry form to generate CNC job.
+&#64;param widget: The widget from which this was called.
+&#64;return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.on_generate_excellon_cncjob">
+<tt class="descname">on_generate_excellon_cncjob</tt><big>(</big><em>widget</em><big>)</big><a class="headerlink" href="#cirkuix.App.on_generate_excellon_cncjob" title="Permalink to this definition">¶</a></dt>
+<dd><p>Callback for button active/click on Excellon form to
+create a CNC Job for the Excellon file.
+&#64;param widget: The widget from which this was called.
+&#64;return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.on_generate_isolation">
+<tt class="descname">on_generate_isolation</tt><big>(</big><em>widget</em><big>)</big><a class="headerlink" href="#cirkuix.App.on_generate_isolation" title="Permalink to this definition">¶</a></dt>
+<dd><p>Callback for button on Gerber form to create isolation routing geometry.
+&#64;param widget: The widget from which this was called.
+&#64;return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.on_generate_paintarea">
+<tt class="descname">on_generate_paintarea</tt><big>(</big><em>widget</em><big>)</big><a class="headerlink" href="#cirkuix.App.on_generate_paintarea" title="Permalink to this definition">¶</a></dt>
+<dd><p>Callback for button on geometry form.
+Subscribes to the &#8220;Click on plot&#8221; event and continues
+after the click. Finds the polygon containing
+the clicked point and runs clear_poly() on it, resulting
+in a new CirkuixGeometry object.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.on_gerber_generate_cutout">
+<tt class="descname">on_gerber_generate_cutout</tt><big>(</big><em>widget</em><big>)</big><a class="headerlink" href="#cirkuix.App.on_gerber_generate_cutout" title="Permalink to this definition">¶</a></dt>
+<dd><p>Callback for button on Gerber form to create geometry with lines
+for cutting off the board.
+&#64;param widget: The widget from which this was called.
+&#64;return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.on_gerber_generate_noncopper">
+<tt class="descname">on_gerber_generate_noncopper</tt><big>(</big><em>widget</em><big>)</big><a class="headerlink" href="#cirkuix.App.on_gerber_generate_noncopper" title="Permalink to this definition">¶</a></dt>
+<dd><p>Callback for button on Gerber form to create a geometry object
+with polygons covering the area without copper or negative of the
+Gerber.
+&#64;param widget: The widget from which this was called.
+&#64;return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.on_tree_selection_changed">
+<tt class="descname">on_tree_selection_changed</tt><big>(</big><em>selection</em><big>)</big><a class="headerlink" href="#cirkuix.App.on_tree_selection_changed" title="Permalink to this definition">¶</a></dt>
+<dd><p>Callback for selection change in the project list. This changes
+the currently selected CirkuixObj.
+&#64;param selection: Selection associated to the project tree or list
+&#64;type selection: Gtk.TreeSelection
+&#64;return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.on_update_plot">
+<tt class="descname">on_update_plot</tt><big>(</big><em>widget</em><big>)</big><a class="headerlink" href="#cirkuix.App.on_update_plot" title="Permalink to this definition">¶</a></dt>
+<dd><p>Callback for button on form for all kinds of objects.
+Re-plot the current object only.
+&#64;param widget: The widget from which this was called.
+&#64;return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.plot_all">
+<tt class="descname">plot_all</tt><big>(</big><big>)</big><a class="headerlink" href="#cirkuix.App.plot_all" title="Permalink to this definition">¶</a></dt>
+<dd><p>Re-generates all plots from all objects.
+&#64;return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.set_list_selection">
+<tt class="descname">set_list_selection</tt><big>(</big><em>name</em><big>)</big><a class="headerlink" href="#cirkuix.App.set_list_selection" title="Permalink to this definition">¶</a></dt>
+<dd><p>Marks a given object as selected in the list ob objects
+in the GUI. This selection will in turn trigger
+self.on_tree_selection_changed().
+&#64;param name: Name of the object.
+&#64;return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.setup_component_editor">
+<tt class="descname">setup_component_editor</tt><big>(</big><big>)</big><a class="headerlink" href="#cirkuix.App.setup_component_editor" title="Permalink to this definition">¶</a></dt>
+<dd><p>Initial configuration of the component editor. Creates
+a page titled &#8220;Selection&#8221; on the notebook on the left
+side of the main window.
+&#64;return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.setup_component_viewer">
+<tt class="descname">setup_component_viewer</tt><big>(</big><big>)</big><a class="headerlink" href="#cirkuix.App.setup_component_viewer" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sets up list or Tree where whatever has been loaded or created is
+displayed.
+&#64;return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.setup_plot">
+<tt class="descname">setup_plot</tt><big>(</big><big>)</big><a class="headerlink" href="#cirkuix.App.setup_plot" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sets up the main plotting area by creating a matplotlib
+figure in self.canvas, adding axes and configuring them.
+These axes should not be ploted on and are just there to
+display the axes ticks and grid.
+&#64;return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.App.zoom">
+<tt class="descname">zoom</tt><big>(</big><em>factor</em>, <em>center=None</em><big>)</big><a class="headerlink" href="#cirkuix.App.zoom" title="Permalink to this definition">¶</a></dt>
+<dd><p>Zooms the plot by factor around a given
+center point. Takes care of re-drawing.
+&#64;return: None</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="cirkuix.Geometry">
+<em class="property">class </em><tt class="descclassname">cirkuix.</tt><tt class="descname">Geometry</tt><a class="headerlink" href="#cirkuix.Geometry" title="Permalink to this definition">¶</a></dt>
+<dd><dl class="method">
+<dt id="cirkuix.Geometry.bounds">
+<tt class="descname">bounds</tt><big>(</big><big>)</big><a class="headerlink" href="#cirkuix.Geometry.bounds" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns coordinates of rectangular bounds
+of geometry: (xmin, ymin, xmax, ymax).</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.Geometry.clear_polygon">
+<tt class="descname">clear_polygon</tt><big>(</big><em>polygon</em>, <em>tooldia</em>, <em>overlap=0.15</em><big>)</big><a class="headerlink" href="#cirkuix.Geometry.clear_polygon" title="Permalink to this definition">¶</a></dt>
+<dd><p>Creates geometry inside a polygon for a tool to cover
+the whole area.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.Geometry.convert_units">
+<tt class="descname">convert_units</tt><big>(</big><em>units</em><big>)</big><a class="headerlink" href="#cirkuix.Geometry.convert_units" title="Permalink to this definition">¶</a></dt>
+<dd><p>Converts the units of the object to <tt class="docutils literal"><span class="pre">units</span></tt> by scaling all
+the geometry appropriately.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>units</strong> (<em>str</em>) &#8211; &#8220;IN&#8221; or &#8220;MM&#8221;</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">Scaling factor resulting from unit change.</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">float</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.Geometry.get_empty_area">
+<tt class="descname">get_empty_area</tt><big>(</big><em>boundary=None</em><big>)</big><a class="headerlink" href="#cirkuix.Geometry.get_empty_area" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns the complement of self.solid_geometry within
+the given boundary polygon. If not specified, it defaults to
+the rectangular bounding box of self.solid_geometry.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.Geometry.isolation_geometry">
+<tt class="descname">isolation_geometry</tt><big>(</big><em>offset</em><big>)</big><a class="headerlink" href="#cirkuix.Geometry.isolation_geometry" title="Permalink to this definition">¶</a></dt>
+<dd><p>Creates contours around geometry at a given
+offset distance.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.Geometry.scale">
+<tt class="descname">scale</tt><big>(</big><em>factor</em><big>)</big><a class="headerlink" href="#cirkuix.Geometry.scale" title="Permalink to this definition">¶</a></dt>
+<dd><p>Scales all of the object&#8217;s geometry by a given factor. Override
+this method.
+:param factor: Number by which to scale.
+:type factor: float
+:return: None
+:rtype: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.Geometry.size">
+<tt class="descname">size</tt><big>(</big><big>)</big><a class="headerlink" href="#cirkuix.Geometry.size" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns (width, height) of rectangular
+bounds of geometry.</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="cirkuix.Gerber">
+<em class="property">class </em><tt class="descclassname">cirkuix.</tt><tt class="descname">Gerber</tt><big>(</big><em>Geometry</em><big>)</big><a class="headerlink" href="#cirkuix.Gerber" title="Permalink to this definition">¶</a></dt>
+<dd><p><strong>ATTRIBUTES</strong></p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">apertures</span></tt> (dict): The keys are names/identifiers of each aperture.
+The values are dictionaries key/value pairs which describe the aperture. The
+type key is always present and the rest depend on the key:</li>
+</ul>
+<table border="1" class="docutils">
+<colgroup>
+<col width="24%" />
+<col width="76%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Key</th>
+<th class="head">Value</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>type</td>
+<td>(str) &#8220;C&#8221;, &#8220;R&#8221;, or &#8220;O&#8221;</td>
+</tr>
+<tr class="row-odd"><td>others</td>
+<td>Depend on <tt class="docutils literal"><span class="pre">type</span></tt></td>
+</tr>
+</tbody>
+</table>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">paths</span></tt> (list): A path is described by a line an aperture that follows that
+line. Each paths[i] is a dictionary:</li>
+</ul>
+<table border="1" class="docutils">
+<colgroup>
+<col width="20%" />
+<col width="80%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Key</th>
+<th class="head">Value</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>linestring</td>
+<td>(Shapely.LineString) The actual path.</td>
+</tr>
+<tr class="row-odd"><td>aperture</td>
+<td>(str) The key for an aperture in apertures.</td>
+</tr>
+</tbody>
+</table>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">flashes</span></tt> (list): Flashes are single-point strokes of an aperture. Each
+is a dictionary:</li>
+</ul>
+<table border="1" class="docutils">
+<colgroup>
+<col width="20%" />
+<col width="80%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Key</th>
+<th class="head">Value</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>loc</td>
+<td>(list) [x (float), y (float)] coordinates.</td>
+</tr>
+<tr class="row-odd"><td>aperture</td>
+<td>(str) The key for an aperture in apertures.</td>
+</tr>
+</tbody>
+</table>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">regions</span></tt> (list): Are surfaces defined by a polygon (Shapely.Polygon),
+which have an exterior and zero or more interiors. An aperture is also
+associated with a region. Each is a dictionary:</li>
+</ul>
+<table border="1" class="docutils">
+<colgroup>
+<col width="18%" />
+<col width="82%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Key</th>
+<th class="head">Value</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>polygon</td>
+<td>(Shapely.Polygon) The polygon defining the region.</td>
+</tr>
+<tr class="row-odd"><td>aperture</td>
+<td>(str) The key for an aperture in apertures.</td>
+</tr>
+</tbody>
+</table>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">flash_geometry</span></tt> (list): List of (Shapely) geometric object resulting
+from <tt class="docutils literal"><span class="pre">flashes</span></tt>. These are generated from <tt class="docutils literal"><span class="pre">flashes</span></tt> in <tt class="docutils literal"><span class="pre">do_flashes()</span></tt>.</li>
+<li><tt class="docutils literal"><span class="pre">buffered_paths</span></tt> (list): List of (Shapely) polygons resulting from
+<em>buffering</em> (or thickening) the <tt class="docutils literal"><span class="pre">paths</span></tt> with the aperture. These are
+generated from <tt class="docutils literal"><span class="pre">paths</span></tt> in <tt class="docutils literal"><span class="pre">buffer_paths()</span></tt>.</li>
+</ul>
+<dl class="method">
+<dt id="cirkuix.Gerber.aperture_parse">
+<tt class="descname">aperture_parse</tt><big>(</big><em>gline</em><big>)</big><a class="headerlink" href="#cirkuix.Gerber.aperture_parse" title="Permalink to this definition">¶</a></dt>
+<dd><p>Parse gerber aperture definition into dictionary of apertures.
+The following kinds and their attributes are supported:</p>
+<ul class="simple">
+<li><em>Circular (C)</em>: size (float)</li>
+<li><em>Rectangle (R)</em>: width (float), height (float)</li>
+<li><em>Obround (O)</em>: width (float), height (float). NOTE: This can
+be parsed, but it is not supported further yet.</li>
+</ul>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.Gerber.create_geometry">
+<tt class="descname">create_geometry</tt><big>(</big><big>)</big><a class="headerlink" href="#cirkuix.Gerber.create_geometry" title="Permalink to this definition">¶</a></dt>
+<dd><p>Geometry from a Gerber file is made up entirely of polygons.
+Every stroke (linear or circular) has an aperture which gives
+it thickness. Additionally, aperture strokes have non-zero area,
+and regions naturally do as well.
+:rtype : None
+&#64;return: None</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="cirkuix.Gerber.digits">
+<tt class="descname">digits</tt><em class="property"> = None</em><a class="headerlink" href="#cirkuix.Gerber.digits" title="Permalink to this definition">¶</a></dt>
+<dd><p>Number of integer digits in Gerber numbers. Used during parsing.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.Gerber.do_flashes">
+<tt class="descname">do_flashes</tt><big>(</big><big>)</big><a class="headerlink" href="#cirkuix.Gerber.do_flashes" title="Permalink to this definition">¶</a></dt>
+<dd><p>Creates geometry for Gerber flashes (aperture on a single point).</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.Gerber.fix_regions">
+<tt class="descname">fix_regions</tt><big>(</big><big>)</big><a class="headerlink" href="#cirkuix.Gerber.fix_regions" title="Permalink to this definition">¶</a></dt>
+<dd><p>Overwrites the region polygons with fixed
+versions if found to be invalid (according to Shapely).</p>
+</dd></dl>
+
+<dl class="attribute">
+<dt id="cirkuix.Gerber.fraction">
+<tt class="descname">fraction</tt><em class="property"> = None</em><a class="headerlink" href="#cirkuix.Gerber.fraction" title="Permalink to this definition">¶</a></dt>
+<dd><p>Number of fraction digits in Gerber numbers. Used during parsing.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.Gerber.parse_file">
+<tt class="descname">parse_file</tt><big>(</big><em>filename</em><big>)</big><a class="headerlink" href="#cirkuix.Gerber.parse_file" title="Permalink to this definition">¶</a></dt>
+<dd><p>Calls Gerber.parse_lines() with array of lines
+read from the given file.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.Gerber.parse_lines">
+<tt class="descname">parse_lines</tt><big>(</big><em>glines</em><big>)</big><a class="headerlink" href="#cirkuix.Gerber.parse_lines" title="Permalink to this definition">¶</a></dt>
+<dd><p>Main Gerber parser.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.Gerber.scale">
+<tt class="descname">scale</tt><big>(</big><em>factor</em><big>)</big><a class="headerlink" href="#cirkuix.Gerber.scale" title="Permalink to this definition">¶</a></dt>
+<dd><p>Scales the objects&#8217; geometry on the XY plane by a given factor.
+These are:</p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">apertures</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">paths</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">regions</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">flashes</span></tt></li>
+</ul>
+<p>Then <tt class="docutils literal"><span class="pre">buffered_paths</span></tt>, <tt class="docutils literal"><span class="pre">flash_geometry</span></tt> and <tt class="docutils literal"><span class="pre">solid_geometry</span></tt>
+are re-created with <tt class="docutils literal"><span class="pre">self.create_geometry()</span></tt>.
+:param factor: Number by which to scale.
+:type factor: float
+:rtype : None</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="cirkuix.Excellon">
+<em class="property">class </em><tt class="descclassname">cirkuix.</tt><tt class="descname">Excellon</tt><a class="headerlink" href="#cirkuix.Excellon" title="Permalink to this definition">¶</a></dt>
+<dd><p><em>ATTRIBUTES</em></p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">tools</span></tt> (dict): The key is the tool name and the value is
+the size (diameter).</li>
+<li><tt class="docutils literal"><span class="pre">drills</span></tt> (list): Each is a dictionary:</li>
+</ul>
+<table border="1" class="docutils">
+<colgroup>
+<col width="31%" />
+<col width="69%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Key</th>
+<th class="head">Value</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>point</td>
+<td>(Shapely.Point) Where to drill</td>
+</tr>
+<tr class="row-odd"><td>tool</td>
+<td>(str) A key in <tt class="docutils literal"><span class="pre">tools</span></tt></td>
+</tr>
+</tbody>
+</table>
+<dl class="method">
+<dt id="cirkuix.Excellon.parse_lines">
+<tt class="descname">parse_lines</tt><big>(</big><em>elines</em><big>)</big><a class="headerlink" href="#cirkuix.Excellon.parse_lines" title="Permalink to this definition">¶</a></dt>
+<dd><p>Main Excellon parser.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.Excellon.scale">
+<tt class="descname">scale</tt><big>(</big><em>factor</em><big>)</big><a class="headerlink" href="#cirkuix.Excellon.scale" title="Permalink to this definition">¶</a></dt>
+<dd><p>Scales geometry on the XY plane in the object by a given factor.
+Tool sizes, feedrates an Z-plane dimensions are untouched.
+:param factor: Number by which to scale the object.
+:type factor: float
+:return: None
+:rtype: NOne</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="cirkuix.CNCjob">
+<em class="property">class </em><tt class="descclassname">cirkuix.</tt><tt class="descname">CNCjob</tt><big>(</big><em>units='in'</em>, <em>kind='generic'</em>, <em>z_move=0.1</em>, <em>feedrate=3.0</em>, <em>z_cut=-0.002</em>, <em>tooldia=0.0</em><big>)</big><a class="headerlink" href="#cirkuix.CNCjob" title="Permalink to this definition">¶</a></dt>
+<dd><p>Represents work to be done by a CNC machine.</p>
+<p><em>ATTRIBUTES</em></p>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">gcode_parsed</span></tt> (list): Each is a dictionary:</li>
+</ul>
+<table border="1" class="docutils">
+<colgroup>
+<col width="34%" />
+<col width="66%" />
+</colgroup>
+<thead valign="bottom">
+<tr class="row-odd"><th class="head">Key</th>
+<th class="head">Value</th>
+</tr>
+</thead>
+<tbody valign="top">
+<tr class="row-even"><td>geom</td>
+<td>(Shapely.LineString) Tool path (XY plane)</td>
+</tr>
+<tr class="row-odd"><td>kind</td>
+<td>(string) &#8220;AB&#8221;, A is &#8220;T&#8221; (travel) or
+&#8220;C&#8221; (cut). B is &#8220;F&#8221; (fast) or &#8220;S&#8221; (slow).</td>
+</tr>
+</tbody>
+</table>
+<dl class="method">
+<dt id="cirkuix.CNCjob.gcode_parse">
+<tt class="descname">gcode_parse</tt><big>(</big><big>)</big><a class="headerlink" href="#cirkuix.CNCjob.gcode_parse" title="Permalink to this definition">¶</a></dt>
+<dd><p>G-Code parser (from self.gcode). Generates dictionary with
+single-segment LineString&#8217;s and &#8220;kind&#8221; indicating cut or travel,
+fast or feedrate speed.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.CNCjob.generate_from_excellon">
+<tt class="descname">generate_from_excellon</tt><big>(</big><em>exobj</em><big>)</big><a class="headerlink" href="#cirkuix.CNCjob.generate_from_excellon" title="Permalink to this definition">¶</a></dt>
+<dd><p>Generates G-code for drilling from Excellon object.
+self.gcode becomes a list, each element is a
+different job for each tool in the excellon code.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.CNCjob.generate_from_excellon_by_tool">
+<tt class="descname">generate_from_excellon_by_tool</tt><big>(</big><em>exobj</em>, <em>tools='all'</em><big>)</big><a class="headerlink" href="#cirkuix.CNCjob.generate_from_excellon_by_tool" title="Permalink to this definition">¶</a></dt>
+<dd><p>Creates gcode for this object from an Excellon object
+for the specified tools.
+&#64;param exobj: Excellon object to process
+&#64;type exobj: Excellon
+&#64;param tools: Comma separated tool names
+&#64;type: tools: str
+&#64;return: None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.CNCjob.generate_from_geometry">
+<tt class="descname">generate_from_geometry</tt><big>(</big><em>geometry</em>, <em>append=True</em>, <em>tooldia=None</em><big>)</big><a class="headerlink" href="#cirkuix.CNCjob.generate_from_geometry" title="Permalink to this definition">¶</a></dt>
+<dd><p>Generates G-Code from a Geometry object.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.CNCjob.plot">
+<tt class="descname">plot</tt><big>(</big><em>tooldia=None, dpi=75, margin=0.1, color={'C': ['#5E6CFF', '#4650BD'], 'T': ['#F0E24D', '#B5AB3A']}, alpha={'C': 1.0, 'T': 0.3}</em><big>)</big><a class="headerlink" href="#cirkuix.CNCjob.plot" title="Permalink to this definition">¶</a></dt>
+<dd><p>Creates a Matplotlib figure with a plot of the
+G-code job.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.CNCjob.plot2">
+<tt class="descname">plot2</tt><big>(</big><em>axes, tooldia=None, dpi=75, margin=0.1, color={'C': ['#5E6CFF', '#4650BD'], 'T': ['#F0E24D', '#B5AB3A']}, alpha={'C': 1.0, 'T': 0.3}</em><big>)</big><a class="headerlink" href="#cirkuix.CNCjob.plot2" title="Permalink to this definition">¶</a></dt>
+<dd><p>Plots the G-code job onto the given axes.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.CNCjob.polygon2gcode">
+<tt class="descname">polygon2gcode</tt><big>(</big><em>polygon</em><big>)</big><a class="headerlink" href="#cirkuix.CNCjob.polygon2gcode" title="Permalink to this definition">¶</a></dt>
+<dd><p>Creates G-Code for the exterior and all interior paths
+of a polygon.
+&#64;param polygon: A Shapely.Polygon
+&#64;type polygon: Shapely.Polygon</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.CNCjob.pre_parse">
+<tt class="descname">pre_parse</tt><big>(</big><em>gtext</em><big>)</big><a class="headerlink" href="#cirkuix.CNCjob.pre_parse" title="Permalink to this definition">¶</a></dt>
+<dd><p>gtext is a single string with g-code</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.CNCjob.scale">
+<tt class="descname">scale</tt><big>(</big><em>factor</em><big>)</big><a class="headerlink" href="#cirkuix.CNCjob.scale" title="Permalink to this definition">¶</a></dt>
+<dd><p>Scales all the geometry on the XY plane in the object by the
+given factor. Tool sizes, feedrates, or Z-axis dimensions are
+not altered.
+:param factor: Number by which to scale the object.
+:type factor: float
+:return: None
+:rtype: None</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="cirkuix.CirkuixObj">
+<em class="property">class </em><tt class="descclassname">cirkuix.</tt><tt class="descname">CirkuixObj</tt><big>(</big><em>name</em><big>)</big><a class="headerlink" href="#cirkuix.CirkuixObj" title="Permalink to this definition">¶</a></dt>
+<dd><p>Base type of objects handled in Cirkuix. These become interactive
+in the GUI, can be plotted, and their options can be modified
+by the user in their respective forms.</p>
+<dl class="method">
+<dt id="cirkuix.CirkuixObj.build_ui">
+<tt class="descname">build_ui</tt><big>(</big><big>)</big><a class="headerlink" href="#cirkuix.CirkuixObj.build_ui" title="Permalink to this definition">¶</a></dt>
+<dd><p>Sets up the UI/form for this object.
+&#64;return: None
+&#64;rtype : None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.CirkuixObj.deserialize">
+<tt class="descname">deserialize</tt><big>(</big><em>obj_dict</em><big>)</big><a class="headerlink" href="#cirkuix.CirkuixObj.deserialize" title="Permalink to this definition">¶</a></dt>
+<dd><p>Re-builds an object from its serialized version.
+&#64;param obj_dict: Dictionary representing a CirkuixObj
+&#64;type obj_dict: dict
+&#64;return None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.CirkuixObj.plot">
+<tt class="descname">plot</tt><big>(</big><em>figure</em><big>)</big><a class="headerlink" href="#cirkuix.CirkuixObj.plot" title="Permalink to this definition">¶</a></dt>
+<dd><p>Extend this method! Sets up axes if needed and
+clears them. Descendants must do the actual plotting.</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.CirkuixObj.read_form">
+<tt class="descname">read_form</tt><big>(</big><big>)</big><a class="headerlink" href="#cirkuix.CirkuixObj.read_form" title="Permalink to this definition">¶</a></dt>
+<dd><p>Reads form into self.options
+&#64;rtype : None</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.CirkuixObj.serialize">
+<tt class="descname">serialize</tt><big>(</big><big>)</big><a class="headerlink" href="#cirkuix.CirkuixObj.serialize" title="Permalink to this definition">¶</a></dt>
+<dd><p>Returns a representation of the object as a dictionary so
+it can be later exported as JSON. Override this method.
+&#64;return: Dictionary representing the object
+&#64;rtype: dict</p>
+</dd></dl>
+
+<dl class="method">
+<dt id="cirkuix.CirkuixObj.setup_axes">
+<tt class="descname">setup_axes</tt><big>(</big><em>figure</em><big>)</big><a class="headerlink" href="#cirkuix.CirkuixObj.setup_axes" title="Permalink to this definition">¶</a></dt>
+<dd><p>1) Creates axes if they don&#8217;t exist. 2) Clears axes. 3) Attaches
+them to figure if not part of the figure. 4) Sets transparent
+background. 5) Sets 1:1 scale aspect ratio.
+&#64;param figure: A Matplotlib.Figure on which to add/configure axes.
+&#64;type figure: matplotlib.figure.Figure
+&#64;return: None</p>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="cirkuix.CirkuixGerber">
+<em class="property">class </em><tt class="descclassname">cirkuix.</tt><tt class="descname">CirkuixGerber</tt><big>(</big><em>name</em><big>)</big><a class="headerlink" href="#cirkuix.CirkuixGerber" title="Permalink to this definition">¶</a></dt>
+<dd><p>Represents Gerber code.</p>
+</dd></dl>
+
+<dl class="class">
+<dt id="cirkuix.CirkuixExcellon">
+<em class="property">class </em><tt class="descclassname">cirkuix.</tt><tt class="descname">CirkuixExcellon</tt><big>(</big><em>name</em><big>)</big><a class="headerlink" href="#cirkuix.CirkuixExcellon" title="Permalink to this definition">¶</a></dt>
+<dd><p>Represents Excellon code.</p>
+</dd></dl>
+
+<dl class="class">
+<dt id="cirkuix.CirkuixCNCjob">
+<em class="property">class </em><tt class="descclassname">cirkuix.</tt><tt class="descname">CirkuixCNCjob</tt><big>(</big><em>name</em>, <em>units='in'</em>, <em>kind='generic'</em>, <em>z_move=0.1</em>, <em>feedrate=3.0</em>, <em>z_cut=-0.002</em>, <em>tooldia=0.0</em><big>)</big><a class="headerlink" href="#cirkuix.CirkuixCNCjob" title="Permalink to this definition">¶</a></dt>
+<dd><p>Represents G-Code.</p>
+</dd></dl>
+
+<dl class="class">
+<dt id="cirkuix.CirkuixGeometry">
+<em class="property">class </em><tt class="descclassname">cirkuix.</tt><tt class="descname">CirkuixGeometry</tt><big>(</big><em>name</em><big>)</big><a class="headerlink" href="#cirkuix.CirkuixGeometry" title="Permalink to this definition">¶</a></dt>
+<dd><p>Geometric object not associated with a specific
+format.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="indices-and-tables">
+<h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline">¶</a></h1>
+<ul class="simple">
+<li><a class="reference internal" href="genindex.html"><em>Index</em></a></li>
+<li><a class="reference internal" href="py-modindex.html"><em>Module Index</em></a></li>
+<li><a class="reference internal" href="search.html"><em>Search Page</em></a></li>
+</ul>
+</div>
+
+
+          </div>
+          <footer>
+  
+
+  <hr/>
+
+  <div role="contentinfo">
+    <p>
+        &copy; Copyright 2014, Juan Pablo Caram.
+    </p>
+  </div>
+
+  <a href="https://github.com/snide/sphinx_rtd_theme">Sphinx theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>
+</footer>
+        </div>
+      </div>
+
+    </section>
+
+  </div>
+  
+
+</body>
+</html>

BIN
doc/build/objects.inv


+ 163 - 0
doc/build/py-modindex.html

@@ -0,0 +1,163 @@
+
+
+<!DOCTYPE html>
+<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
+<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  
+  <title>Python Module Index &mdash; Cirkuix 0.5 documentation</title>
+  
+
+  
+  
+
+  
+  <link href='https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700' rel='stylesheet' type='text/css'>
+
+  
+  
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:'./',
+        VERSION:'0.5',
+        COLLAPSE_INDEX:false,
+        FILE_SUFFIX:'.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+      <script type="text/javascript" src="_static/jquery.js"></script>
+      <script type="text/javascript" src="_static/underscore.js"></script>
+      <script type="text/javascript" src="_static/doctools.js"></script>
+
+    
+
+  
+
+  
+  
+    <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
+    <script type="text/javascript" src="_static/js/theme.js"></script>
+  
+
+  
+  
+    <script type="text/javascript">
+        jQuery(function () {
+            SphinxRtdTheme.StickyNav.enable();
+        });
+    </script>
+  
+
+  
+    <link rel="top" title="Cirkuix 0.5 documentation" href="index.html"/>
+ 
+
+    <script type="text/javascript">
+      DOCUMENTATION_OPTIONS.COLLAPSE_INDEX = true;
+    </script>
+
+
+
+  <script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script>
+
+</head>
+
+<body class="wy-body-for-nav" role="document">
+
+  <div class="wy-grid-for-nav">
+
+    
+    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
+      <div class="wy-side-nav-search">
+        <a href="index.html" class="icon icon-home"> Cirkuix</a>
+        <div role="search">
+  <form id ="rtd-search-form" class="wy-form" action="search.html" method="get">
+    <input type="text" name="q" placeholder="Search docs" />
+    <input type="hidden" name="check_keywords" value="yes" />
+    <input type="hidden" name="area" value="default" />
+  </form>
+</div>
+      </div>
+
+      <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
+        
+        
+            <ul class="simple">
+</ul>
+
+        
+      </div>
+      &nbsp;
+    </nav>
+
+    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
+
+      
+      <nav class="wy-nav-top" role="navigation" aria-label="top navigation">
+        <i data-toggle="wy-nav-top" class="icon icon-reorder"></i>
+        <a href="index.html">Cirkuix</a>
+      </nav>
+
+
+      
+      <div class="wy-nav-content">
+        <div class="rst-content">
+          <div role="navigation" aria-label="breadcrumbs navigation">
+  <ul class="wy-breadcrumbs">
+    <li><a href="index.html">Docs</a> &raquo;</li>
+      
+    <li></li>
+      <li class="wy-breadcrumbs-aside">
+        
+      </li>
+  </ul>
+  <hr/>
+</div>
+          <div role="main">
+            
+
+   <h1>Python Module Index</h1>
+
+   <div class="modindex-jumpbox">
+   <a href="#cap-c"><strong>c</strong></a>
+   </div>
+
+   <table class="indextable modindextable" cellspacing="0" cellpadding="2">
+     <tr class="pcap"><td></td><td>&nbsp;</td><td></td></tr>
+     <tr class="cap" id="cap-c"><td></td><td>
+       <strong>c</strong></td><td></td></tr>
+     <tr>
+       <td></td>
+       <td>
+       <a href="index.html#module-cirkuix"><tt class="xref">cirkuix</tt></a></td><td>
+       <em></em></td></tr>
+   </table>
+
+
+          </div>
+          <footer>
+  
+
+  <hr/>
+
+  <div role="contentinfo">
+    <p>
+        &copy; Copyright 2014, Juan Pablo Caram.
+    </p>
+  </div>
+
+  <a href="https://github.com/snide/sphinx_rtd_theme">Sphinx theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>
+</footer>
+        </div>
+      </div>
+
+    </section>
+
+  </div>
+  
+
+</body>
+</html>

+ 159 - 0
doc/build/search.html

@@ -0,0 +1,159 @@
+
+
+<!DOCTYPE html>
+<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
+<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  
+  <title>Search &mdash; Cirkuix 0.5 documentation</title>
+  
+
+  
+  
+
+  
+  <link href='https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700' rel='stylesheet' type='text/css'>
+
+  
+  
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:'./',
+        VERSION:'0.5',
+        COLLAPSE_INDEX:false,
+        FILE_SUFFIX:'.html',
+        HAS_SOURCE:  true
+      };
+    </script>
+      <script type="text/javascript" src="_static/jquery.js"></script>
+      <script type="text/javascript" src="_static/underscore.js"></script>
+      <script type="text/javascript" src="_static/doctools.js"></script>
+      <script type="text/javascript" src="_static/searchtools.js"></script>
+
+    
+
+  
+
+  
+  
+    <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
+    <script type="text/javascript" src="_static/js/theme.js"></script>
+  
+
+  
+  
+    <script type="text/javascript">
+        jQuery(function () {
+            SphinxRtdTheme.StickyNav.enable();
+        });
+    </script>
+  
+
+  
+    <link rel="top" title="Cirkuix 0.5 documentation" href="index.html"/>
+  <script type="text/javascript">
+    jQuery(function() { Search.loadIndex("searchindex.js"); });
+  </script>
+  
+  <script type="text/javascript" id="searchindexloader"></script>
+   
+
+
+  <script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script>
+
+</head>
+
+<body class="wy-body-for-nav" role="document">
+
+  <div class="wy-grid-for-nav">
+
+    
+    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
+      <div class="wy-side-nav-search">
+        <a href="index.html" class="icon icon-home"> Cirkuix</a>
+        <div role="search">
+  <form id ="rtd-search-form" class="wy-form" action="#" method="get">
+    <input type="text" name="q" placeholder="Search docs" />
+    <input type="hidden" name="check_keywords" value="yes" />
+    <input type="hidden" name="area" value="default" />
+  </form>
+</div>
+      </div>
+
+      <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
+        
+        
+            <ul class="simple">
+</ul>
+
+        
+      </div>
+      &nbsp;
+    </nav>
+
+    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
+
+      
+      <nav class="wy-nav-top" role="navigation" aria-label="top navigation">
+        <i data-toggle="wy-nav-top" class="icon icon-reorder"></i>
+        <a href="index.html">Cirkuix</a>
+      </nav>
+
+
+      
+      <div class="wy-nav-content">
+        <div class="rst-content">
+          <div role="navigation" aria-label="breadcrumbs navigation">
+  <ul class="wy-breadcrumbs">
+    <li><a href="index.html">Docs</a> &raquo;</li>
+      
+    <li></li>
+      <li class="wy-breadcrumbs-aside">
+        
+      </li>
+  </ul>
+  <hr/>
+</div>
+          <div role="main">
+            
+  <noscript>
+  <div id="fallback" class="admonition warning">
+    <p class="last">
+      Please activate JavaScript to enable the search
+      functionality.
+    </p>
+  </div>
+  </noscript>
+
+  
+  <div id="search-results">
+  
+  </div>
+
+          </div>
+          <footer>
+  
+
+  <hr/>
+
+  <div role="contentinfo">
+    <p>
+        &copy; Copyright 2014, Juan Pablo Caram.
+    </p>
+  </div>
+
+  <a href="https://github.com/snide/sphinx_rtd_theme">Sphinx theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>
+</footer>
+        </div>
+      </div>
+
+    </section>
+
+  </div>
+  
+
+</body>
+</html>

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
doc/build/searchindex.js


+ 242 - 0
doc/make.bat

@@ -0,0 +1,242 @@
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+	set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
+set I18NSPHINXOPTS=%SPHINXOPTS% source
+if NOT "%PAPER%" == "" (
+	set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+	set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+	:help
+	echo.Please use `make ^<target^>` where ^<target^> is one of
+	echo.  html       to make standalone HTML files
+	echo.  dirhtml    to make HTML files named index.html in directories
+	echo.  singlehtml to make a single large HTML file
+	echo.  pickle     to make pickle files
+	echo.  json       to make JSON files
+	echo.  htmlhelp   to make HTML files and a HTML help project
+	echo.  qthelp     to make HTML files and a qthelp project
+	echo.  devhelp    to make HTML files and a Devhelp project
+	echo.  epub       to make an epub
+	echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+	echo.  text       to make text files
+	echo.  man        to make manual pages
+	echo.  texinfo    to make Texinfo files
+	echo.  gettext    to make PO message catalogs
+	echo.  changes    to make an overview over all changed/added/deprecated items
+	echo.  xml        to make Docutils-native XML files
+	echo.  pseudoxml  to make pseudoxml-XML files for display purposes
+	echo.  linkcheck  to check all external links for integrity
+	echo.  doctest    to run all doctests embedded in the documentation if enabled
+	goto end
+)
+
+if "%1" == "clean" (
+	for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+	del /q /s %BUILDDIR%\*
+	goto end
+)
+
+
+%SPHINXBUILD% 2> nul
+if errorlevel 9009 (
+	echo.
+	echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+	echo.installed, then set the SPHINXBUILD environment variable to point
+	echo.to the full path of the 'sphinx-build' executable. Alternatively you
+	echo.may add the Sphinx directory to PATH.
+	echo.
+	echo.If you don't have Sphinx installed, grab it from
+	echo.http://sphinx-doc.org/
+	exit /b 1
+)
+
+if "%1" == "html" (
+	%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+	goto end
+)
+
+if "%1" == "dirhtml" (
+	%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+	goto end
+)
+
+if "%1" == "singlehtml" (
+	%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+	goto end
+)
+
+if "%1" == "pickle" (
+	%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can process the pickle files.
+	goto end
+)
+
+if "%1" == "json" (
+	%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can process the JSON files.
+	goto end
+)
+
+if "%1" == "htmlhelp" (
+	%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+	goto end
+)
+
+if "%1" == "qthelp" (
+	%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+	echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Cirkuix.qhcp
+	echo.To view the help file:
+	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Cirkuix.ghc
+	goto end
+)
+
+if "%1" == "devhelp" (
+	%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished.
+	goto end
+)
+
+if "%1" == "epub" (
+	%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The epub file is in %BUILDDIR%/epub.
+	goto end
+)
+
+if "%1" == "latex" (
+	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+	goto end
+)
+
+if "%1" == "latexpdf" (
+	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+	cd %BUILDDIR%/latex
+	make all-pdf
+	cd %BUILDDIR%/..
+	echo.
+	echo.Build finished; the PDF files are in %BUILDDIR%/latex.
+	goto end
+)
+
+if "%1" == "latexpdfja" (
+	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+	cd %BUILDDIR%/latex
+	make all-pdf-ja
+	cd %BUILDDIR%/..
+	echo.
+	echo.Build finished; the PDF files are in %BUILDDIR%/latex.
+	goto end
+)
+
+if "%1" == "text" (
+	%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The text files are in %BUILDDIR%/text.
+	goto end
+)
+
+if "%1" == "man" (
+	%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The manual pages are in %BUILDDIR%/man.
+	goto end
+)
+
+if "%1" == "texinfo" (
+	%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
+	goto end
+)
+
+if "%1" == "gettext" (
+	%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
+	goto end
+)
+
+if "%1" == "changes" (
+	%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.The overview file is in %BUILDDIR%/changes.
+	goto end
+)
+
+if "%1" == "linkcheck" (
+	%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+	goto end
+)
+
+if "%1" == "doctest" (
+	%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+	goto end
+)
+
+if "%1" == "xml" (
+	%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The XML files are in %BUILDDIR%/xml.
+	goto end
+)
+
+if "%1" == "pseudoxml" (
+	%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
+	if errorlevel 1 exit /b 1
+	echo.
+	echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
+	goto end
+)
+
+:end

+ 17 - 0
doc/source/_theme/__init__.py

@@ -0,0 +1,17 @@
+"""Sphinx ReadTheDocs theme.
+
+From https://github.com/ryan-roemer/sphinx-bootstrap-theme.
+
+"""
+import os
+
+VERSION = (0, 1, 5)
+
+__version__ = ".".join(str(v) for v in VERSION)
+__version_full__ = __version__
+
+
+def get_html_theme_path():
+    """Return list of HTML theme paths."""
+    cur_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
+    return cur_dir

+ 19 - 0
doc/source/_theme/breadcrumbs.html

@@ -0,0 +1,19 @@
+<div role="navigation" aria-label="breadcrumbs navigation">
+  <ul class="wy-breadcrumbs">
+    <li><a href="{{ pathto(master_doc) }}">Docs</a> &raquo;</li>
+      {% for doc in parents %}
+          <li><a href="{{ doc.link|e }}">{{ doc.title }}</a> &raquo;</li>
+      {% endfor %}
+    <li>{{ title }}</li>
+      <li class="wy-breadcrumbs-aside">
+        {% if display_github %}
+          <a href="https://github.com/{{ github_user }}/{{ github_repo }}/blob/{{ github_version }}{{ conf_py_path }}{{ pagename }}.rst" class="icon icon-github"> Edit on GitHub</a>
+        {% elif display_bitbucket %}
+          <a href="https://bitbucket.org/{{ bitbucket_user }}/{{ bitbucket_repo }}/src/{{ bitbucket_version}}{{ conf_py_path }}{{ pagename }}.rst" class="icon icon-bitbucket"> Edit on Bitbucket</a>
+        {% elif show_source and has_source and sourcename %}
+          <a href="{{ pathto('_sources/' + sourcename, true)|e }}" rel="nofollow"> View page source</a>
+        {% endif %}
+      </li>
+  </ul>
+  <hr/>
+</div>

+ 32 - 0
doc/source/_theme/footer.html

@@ -0,0 +1,32 @@
+<footer>
+  {% if next or prev %}
+    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
+      {% if next %}
+        <a href="{{ next.link|e }}" class="btn btn-neutral float-right" title="{{ next.title|striptags|e }}"/>Next <span class="icon icon-circle-arrow-right"></span></a>
+      {% endif %}
+      {% if prev %}
+        <a href="{{ prev.link|e }}" class="btn btn-neutral" title="{{ prev.title|striptags|e }}"><span class="icon icon-circle-arrow-left"></span> Previous</a>
+      {% endif %}
+    </div>
+  {% endif %}
+
+  <hr/>
+
+  <div role="contentinfo">
+    <p>
+    {%- if show_copyright %}
+      {%- if hasdoc('copyright') %}
+        {% trans path=pathto('copyright'), copyright=copyright|e %}&copy; <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
+      {%- else %}
+        {% trans copyright=copyright|e %}&copy; Copyright {{ copyright }}.{% endtrans %}
+      {%- endif %}
+    {%- endif %}
+
+    {%- if last_updated %}
+      {% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
+    {%- endif %}
+    </p>
+  </div>
+
+  {% trans %}<a href="https://github.com/snide/sphinx_rtd_theme">Sphinx theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>{% endtrans %}
+</footer>

+ 149 - 0
doc/source/_theme/layout.html

@@ -0,0 +1,149 @@
+{# TEMPLATE VAR SETTINGS #}
+{%- set url_root = pathto('', 1) %}
+{%- if url_root == '#' %}{% set url_root = '' %}{% endif %}
+{%- if not embedded and docstitle %}
+  {%- set titlesuffix = " &mdash; "|safe + docstitle|e %}
+{%- else %}
+  {%- set titlesuffix = "" %}
+{%- endif %}
+
+<!DOCTYPE html>
+<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
+<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  {% block htmltitle %}
+  <title>{{ title|striptags|e }}{{ titlesuffix }}</title>
+  {% endblock %}
+
+  {# FAVICON #}
+  {% if favicon %}
+    <link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
+  {% endif %}
+
+  {# CSS #}
+  <link href='https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700' rel='stylesheet' type='text/css'>
+
+  {# JS #}
+  {% if not embedded %}
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:'{{ url_root }}',
+        VERSION:'{{ release|e }}',
+        COLLAPSE_INDEX:false,
+        FILE_SUFFIX:'{{ '' if no_search_suffix else file_suffix }}',
+        HAS_SOURCE:  {{ has_source|lower }}
+      };
+    </script>
+    {%- for scriptfile in script_files %}
+      <script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
+    {%- endfor %}
+
+    {% if use_opensearch %}
+      <link rel="search" type="application/opensearchdescription+xml" title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}" href="{{ pathto('_static/opensearch.xml', 1) }}"/>
+    {% endif %}
+
+  {% endif %}
+
+  {# RTD hosts these file themselves, so just load on non RTD builds #}
+  {% if not READTHEDOCS %}
+    <link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
+    <script type="text/javascript" src="{{ pathto('_static/js/theme.js', 1) }}"></script>
+  {% endif %}
+
+  {# STICKY NAVIGATION #}
+  {% if theme_sticky_navigation %}
+    <script type="text/javascript">
+        jQuery(function () {
+            SphinxRtdTheme.StickyNav.enable();
+        });
+    </script>
+  {% endif %}
+
+  {% for cssfile in css_files %}
+    <link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" />
+  {% endfor %}
+
+  {%- block linktags %}
+    {%- if hasdoc('about') %}
+        <link rel="author" title="{{ _('About these documents') }}"
+              href="{{ pathto('about') }}"/>
+    {%- endif %}
+    {%- if hasdoc('genindex') %}
+        <link rel="index" title="{{ _('Index') }}"
+              href="{{ pathto('genindex') }}"/>
+    {%- endif %}
+    {%- if hasdoc('search') %}
+        <link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}"/>
+    {%- endif %}
+    {%- if hasdoc('copyright') %}
+        <link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}"/>
+    {%- endif %}
+    <link rel="top" title="{{ docstitle|e }}" href="{{ pathto('index') }}"/>
+    {%- if parents %}
+        <link rel="up" title="{{ parents[-1].title|striptags|e }}" href="{{ parents[-1].link|e }}"/>
+    {%- endif %}
+    {%- if next %}
+        <link rel="next" title="{{ next.title|striptags|e }}" href="{{ next.link|e }}"/>
+    {%- endif %}
+    {%- if prev %}
+        <link rel="prev" title="{{ prev.title|striptags|e }}" href="{{ prev.link|e }}"/>
+    {%- endif %}
+  {%- endblock %}
+  {%- block extrahead %} {% endblock %}
+
+  <script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script>
+
+</head>
+
+<body class="wy-body-for-nav" role="document">
+
+  <div class="wy-grid-for-nav">
+
+    {# SIDE NAV, TOGGLES ON MOBILE #}
+    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
+      <div class="wy-side-nav-search">
+        <a href="{{ pathto(master_doc) }}" class="icon icon-home"> {{ project }}</a>
+        {% include "searchbox.html" %}
+      </div>
+
+      <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
+        {% set toctree = toctree(maxdepth=2, collapse=False, includehidden=True) %}
+        {% if toctree %}
+            {{ toctree }}
+        {% else %}
+            <!-- Local TOC -->
+            <div class="local-toc">{{ toc }}</div>
+        {% endif %}
+      </div>
+      &nbsp;
+    </nav>
+
+    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
+
+      {# MOBILE NAV, TRIGGLES SIDE NAV ON TOGGLE #}
+      <nav class="wy-nav-top" role="navigation" aria-label="top navigation">
+        <i data-toggle="wy-nav-top" class="icon icon-reorder"></i>
+        <a href="{{ pathto(master_doc) }}">{{ project }}</a>
+      </nav>
+
+
+      {# PAGE CONTENT #}
+      <div class="wy-nav-content">
+        <div class="rst-content">
+          {% include "breadcrumbs.html" %}
+          <div role="main">
+            {% block body %}{% endblock %}
+          </div>
+          {% include "footer.html" %}
+        </div>
+      </div>
+
+    </section>
+
+  </div>
+  {% include "versions.html" %}
+</body>
+</html>

+ 205 - 0
doc/source/_theme/layout_old.html

@@ -0,0 +1,205 @@
+{#
+    basic/layout.html
+    ~~~~~~~~~~~~~~~~~
+
+    Master layout template for Sphinx themes.
+
+    :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+#}
+{%- block doctype -%}
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+{%- endblock %}
+{%- set reldelim1 = reldelim1 is not defined and ' &raquo;' or reldelim1 %}
+{%- set reldelim2 = reldelim2 is not defined and ' |' or reldelim2 %}
+{%- set render_sidebar = (not embedded) and (not theme_nosidebar|tobool) and
+                         (sidebars != []) %}
+{%- set url_root = pathto('', 1) %}
+{# XXX necessary? #}
+{%- if url_root == '#' %}{% set url_root = '' %}{% endif %}
+{%- if not embedded and docstitle %}
+  {%- set titlesuffix = " &mdash; "|safe + docstitle|e %}
+{%- else %}
+  {%- set titlesuffix = "" %}
+{%- endif %}
+
+{%- macro relbar() %}
+    <div class="related">
+      <h3>{{ _('Navigation') }}</h3>
+      <ul>
+        {%- for rellink in rellinks %}
+        <li class="right" {% if loop.first %}style="margin-right: 10px"{% endif %}>
+          <a href="{{ pathto(rellink[0]) }}" title="{{ rellink[1]|striptags|e }}"
+             {{ accesskey(rellink[2]) }}>{{ rellink[3] }}</a>
+          {%- if not loop.first %}{{ reldelim2 }}{% endif %}</li>
+        {%- endfor %}
+        {%- block rootrellink %}
+        <li><a href="{{ pathto(master_doc) }}">{{ shorttitle|e }}</a>{{ reldelim1 }}</li>
+        {%- endblock %}
+        {%- for parent in parents %}
+          <li><a href="{{ parent.link|e }}" {% if loop.last %}{{ accesskey("U") }}{% endif %}>{{ parent.title }}</a>{{ reldelim1 }}</li>
+        {%- endfor %}
+        {%- block relbaritems %} {% endblock %}
+      </ul>
+    </div>
+{%- endmacro %}
+
+{%- macro sidebar() %}
+      {%- if render_sidebar %}
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+          {%- block sidebarlogo %}
+          {%- if logo %}
+            <p class="logo"><a href="{{ pathto(master_doc) }}">
+              <img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/>
+            </a></p>
+          {%- endif %}
+          {%- endblock %}
+          {%- if sidebars != None %}
+            {#- new style sidebar: explicitly include/exclude templates #}
+            {%- for sidebartemplate in sidebars %}
+            {%- include sidebartemplate %}
+            {%- endfor %}
+          {%- else %}
+            {#- old style sidebars: using blocks -- should be deprecated #}
+            {%- block sidebartoc %}
+            {%- include "localtoc.html" %}
+            {%- endblock %}
+            {%- block sidebarrel %}
+            {%- include "relations.html" %}
+            {%- endblock %}
+            {%- block sidebarsourcelink %}
+            {%- include "sourcelink.html" %}
+            {%- endblock %}
+            {%- if customsidebar %}
+            {%- include customsidebar %}
+            {%- endif %}
+            {%- block sidebarsearch %}
+            {%- include "searchbox.html" %}
+            {%- endblock %}
+          {%- endif %}
+        </div>
+      </div>
+      {%- endif %}
+{%- endmacro %}
+
+{%- macro script() %}
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '{{ url_root }}',
+        VERSION:     '{{ release|e }}',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '{{ '' if no_search_suffix else file_suffix }}',
+        HAS_SOURCE:  {{ has_source|lower }}
+      };
+    </script>
+    {%- for scriptfile in script_files %}
+    <script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
+    {%- endfor %}
+{%- endmacro %}
+
+{%- macro css() %}
+    <link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
+    <link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
+    {%- for cssfile in css_files %}
+    <link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" />
+    {%- endfor %}
+{%- endmacro %}
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset={{ encoding }}" />
+    {{ metatags }}
+    {%- block htmltitle %}
+    <title>{{ title|striptags|e }}{{ titlesuffix }}</title>
+    {%- endblock %}
+    {{ css() }}
+    {%- if not embedded %}
+    {{ script() }}
+    {%- if use_opensearch %}
+    <link rel="search" type="application/opensearchdescription+xml"
+          title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}"
+          href="{{ pathto('_static/opensearch.xml', 1) }}"/>
+    {%- endif %}
+    {%- if favicon %}
+    <link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
+    {%- endif %}
+    {%- endif %}
+{%- block linktags %}
+    {%- if hasdoc('about') %}
+    <link rel="author" title="{{ _('About these documents') }}" href="{{ pathto('about') }}" />
+    {%- endif %}
+    {%- if hasdoc('genindex') %}
+    <link rel="index" title="{{ _('Index') }}" href="{{ pathto('genindex') }}" />
+    {%- endif %}
+    {%- if hasdoc('search') %}
+    <link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}" />
+    {%- endif %}
+    {%- if hasdoc('copyright') %}
+    <link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}" />
+    {%- endif %}
+    <link rel="top" title="{{ docstitle|e }}" href="{{ pathto('index') }}" />
+    {%- if parents %}
+    <link rel="up" title="{{ parents[-1].title|striptags|e }}" href="{{ parents[-1].link|e }}" />
+    {%- endif %}
+    {%- if next %}
+    <link rel="next" title="{{ next.title|striptags|e }}" href="{{ next.link|e }}" />
+    {%- endif %}
+    {%- if prev %}
+    <link rel="prev" title="{{ prev.title|striptags|e }}" href="{{ prev.link|e }}" />
+    {%- endif %}
+{%- endblock %}
+{%- block extrahead %} {% endblock %}
+  </head>
+  <body>
+{%- block header %}{% endblock %}
+
+{%- block relbar1 %}{{ relbar() }}{% endblock %}
+
+{%- block content %}
+  {%- block sidebar1 %} {# possible location for sidebar #} {% endblock %}
+
+    <div class="document">
+  {%- block document %}
+      <div class="documentwrapper">
+      {%- if render_sidebar %}
+        <div class="bodywrapper">
+      {%- endif %}
+          <div class="body">
+            {% block body %} {% endblock %}
+          </div>
+      {%- if render_sidebar %}
+        </div>
+      {%- endif %}
+      </div>
+  {%- endblock %}
+
+  {%- block sidebar2 %}{{ sidebar() }}{% endblock %}
+      <div class="clearer"></div>
+    </div>
+{%- endblock %}
+
+{%- block relbar2 %}{{ relbar() }}{% endblock %}
+
+{%- block footer %}
+    <div class="footer">
+    {%- if show_copyright %}
+      {%- if hasdoc('copyright') %}
+        {% trans path=pathto('copyright'), copyright=copyright|e %}&copy; <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
+      {%- else %}
+        {% trans copyright=copyright|e %}&copy; Copyright {{ copyright }}.{% endtrans %}
+      {%- endif %}
+    {%- endif %}
+    {%- if last_updated %}
+      {% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
+    {%- endif %}
+    {%- if show_sphinx %}
+      {% trans sphinx_version=sphinx_version|e %}Created using <a href="http://sphinx-doc.org/">Sphinx</a> {{ sphinx_version }}.{% endtrans %}
+    {%- endif %}
+    </div>
+    <p>asdf asdf asdf asdf 22</p>
+{%- endblock %}
+  </body>
+</html>
+

+ 50 - 0
doc/source/_theme/search.html

@@ -0,0 +1,50 @@
+{#
+    basic/search.html
+    ~~~~~~~~~~~~~~~~~
+
+    Template for the search page.
+
+    :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+#}
+{%- extends "layout.html" %}
+{% set title = _('Search') %}
+{% set script_files = script_files + ['_static/searchtools.js'] %}
+{% block extrahead %}
+  <script type="text/javascript">
+    jQuery(function() { Search.loadIndex("{{ pathto('searchindex.js', 1) }}"); });
+  </script>
+  {# this is used when loading the search index using $.ajax fails,
+     such as on Chrome for documents on localhost #}
+  <script type="text/javascript" id="searchindexloader"></script>
+  {{ super() }}
+{% endblock %}
+{% block body %}
+  <noscript>
+  <div id="fallback" class="admonition warning">
+    <p class="last">
+      {% trans %}Please activate JavaScript to enable the search
+      functionality.{% endtrans %}
+    </p>
+  </div>
+  </noscript>
+
+  {% if search_performed %}
+    <h2>{{ _('Search Results') }}</h2>
+    {% if not search_results %}
+      <p>{{ _('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.') }}</p>
+    {% endif %}
+  {% endif %}
+  <div id="search-results">
+  {% if search_results %}
+    <ul>
+    {% for href, caption, context in search_results %}
+      <li>
+        <a href="{{ pathto(item.href) }}">{{ caption }}</a>
+        <p class="context">{{ context|e }}</p>
+      </li>
+    {% endfor %}
+    </ul>
+  {% endif %}
+  </div>
+{% endblock %}

+ 7 - 0
doc/source/_theme/searchbox.html

@@ -0,0 +1,7 @@
+<div role="search">
+  <form id ="rtd-search-form" class="wy-form" action="{{ pathto('search') }}" method="get">
+    <input type="text" name="q" placeholder="Search docs" />
+    <input type="hidden" name="check_keywords" value="yes" />
+    <input type="hidden" name="area" value="default" />
+  </form>
+</div>

+ 17 - 0
doc/source/_theme/sphinx_rtd_theme/__init__.py

@@ -0,0 +1,17 @@
+"""Sphinx ReadTheDocs theme.
+
+From https://github.com/ryan-roemer/sphinx-bootstrap-theme.
+
+"""
+import os
+
+VERSION = (0, 1, 5)
+
+__version__ = ".".join(str(v) for v in VERSION)
+__version_full__ = __version__
+
+
+def get_html_theme_path():
+    """Return list of HTML theme paths."""
+    cur_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
+    return cur_dir

+ 19 - 0
doc/source/_theme/sphinx_rtd_theme/breadcrumbs.html

@@ -0,0 +1,19 @@
+<div role="navigation" aria-label="breadcrumbs navigation">
+  <ul class="wy-breadcrumbs">
+    <li><a href="{{ pathto(master_doc) }}">Docs</a> &raquo;</li>
+      {% for doc in parents %}
+          <li><a href="{{ doc.link|e }}">{{ doc.title }}</a> &raquo;</li>
+      {% endfor %}
+    <li>{{ title }}</li>
+      <li class="wy-breadcrumbs-aside">
+        {% if display_github %}
+          <a href="https://github.com/{{ github_user }}/{{ github_repo }}/blob/{{ github_version }}{{ conf_py_path }}{{ pagename }}.rst" class="icon icon-github"> Edit on GitHub</a>
+        {% elif display_bitbucket %}
+          <a href="https://bitbucket.org/{{ bitbucket_user }}/{{ bitbucket_repo }}/src/{{ bitbucket_version}}{{ conf_py_path }}{{ pagename }}.rst" class="icon icon-bitbucket"> Edit on Bitbucket</a>
+        {% elif show_source and has_source and sourcename %}
+          <a href="{{ pathto('_sources/' + sourcename, true)|e }}" rel="nofollow"> View page source</a>
+        {% endif %}
+      </li>
+  </ul>
+  <hr/>
+</div>

+ 32 - 0
doc/source/_theme/sphinx_rtd_theme/footer.html

@@ -0,0 +1,32 @@
+<footer>
+  {% if next or prev %}
+    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
+      {% if next %}
+        <a href="{{ next.link|e }}" class="btn btn-neutral float-right" title="{{ next.title|striptags|e }}"/>Next <span class="icon icon-circle-arrow-right"></span></a>
+      {% endif %}
+      {% if prev %}
+        <a href="{{ prev.link|e }}" class="btn btn-neutral" title="{{ prev.title|striptags|e }}"><span class="icon icon-circle-arrow-left"></span> Previous</a>
+      {% endif %}
+    </div>
+  {% endif %}
+
+  <hr/>
+
+  <div role="contentinfo">
+    <p>
+    {%- if show_copyright %}
+      {%- if hasdoc('copyright') %}
+        {% trans path=pathto('copyright'), copyright=copyright|e %}&copy; <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
+      {%- else %}
+        {% trans copyright=copyright|e %}&copy; Copyright {{ copyright }}.{% endtrans %}
+      {%- endif %}
+    {%- endif %}
+
+    {%- if last_updated %}
+      {% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
+    {%- endif %}
+    </p>
+  </div>
+
+  {% trans %}<a href="https://github.com/snide/sphinx_rtd_theme">Sphinx theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>{% endtrans %}
+</footer>

+ 149 - 0
doc/source/_theme/sphinx_rtd_theme/layout.html

@@ -0,0 +1,149 @@
+{# TEMPLATE VAR SETTINGS #}
+{%- set url_root = pathto('', 1) %}
+{%- if url_root == '#' %}{% set url_root = '' %}{% endif %}
+{%- if not embedded and docstitle %}
+  {%- set titlesuffix = " &mdash; "|safe + docstitle|e %}
+{%- else %}
+  {%- set titlesuffix = "" %}
+{%- endif %}
+
+<!DOCTYPE html>
+<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
+<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  {% block htmltitle %}
+  <title>{{ title|striptags|e }}{{ titlesuffix }}</title>
+  {% endblock %}
+
+  {# FAVICON #}
+  {% if favicon %}
+    <link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
+  {% endif %}
+
+  {# CSS #}
+  <link href='https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700' rel='stylesheet' type='text/css'>
+
+  {# JS #}
+  {% if not embedded %}
+
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:'{{ url_root }}',
+        VERSION:'{{ release|e }}',
+        COLLAPSE_INDEX:false,
+        FILE_SUFFIX:'{{ '' if no_search_suffix else file_suffix }}',
+        HAS_SOURCE:  {{ has_source|lower }}
+      };
+    </script>
+    {%- for scriptfile in script_files %}
+      <script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
+    {%- endfor %}
+
+    {% if use_opensearch %}
+      <link rel="search" type="application/opensearchdescription+xml" title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}" href="{{ pathto('_static/opensearch.xml', 1) }}"/>
+    {% endif %}
+
+  {% endif %}
+
+  {# RTD hosts these file themselves, so just load on non RTD builds #}
+  {% if not READTHEDOCS %}
+    <link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
+    <script type="text/javascript" src="{{ pathto('_static/js/theme.js', 1) }}"></script>
+  {% endif %}
+
+  {# STICKY NAVIGATION #}
+  {% if theme_sticky_navigation %}
+    <script type="text/javascript">
+        jQuery(function () {
+            SphinxRtdTheme.StickyNav.enable();
+        });
+    </script>
+  {% endif %}
+
+  {% for cssfile in css_files %}
+    <link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" />
+  {% endfor %}
+
+  {%- block linktags %}
+    {%- if hasdoc('about') %}
+        <link rel="author" title="{{ _('About these documents') }}"
+              href="{{ pathto('about') }}"/>
+    {%- endif %}
+    {%- if hasdoc('genindex') %}
+        <link rel="index" title="{{ _('Index') }}"
+              href="{{ pathto('genindex') }}"/>
+    {%- endif %}
+    {%- if hasdoc('search') %}
+        <link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}"/>
+    {%- endif %}
+    {%- if hasdoc('copyright') %}
+        <link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}"/>
+    {%- endif %}
+    <link rel="top" title="{{ docstitle|e }}" href="{{ pathto('index') }}"/>
+    {%- if parents %}
+        <link rel="up" title="{{ parents[-1].title|striptags|e }}" href="{{ parents[-1].link|e }}"/>
+    {%- endif %}
+    {%- if next %}
+        <link rel="next" title="{{ next.title|striptags|e }}" href="{{ next.link|e }}"/>
+    {%- endif %}
+    {%- if prev %}
+        <link rel="prev" title="{{ prev.title|striptags|e }}" href="{{ prev.link|e }}"/>
+    {%- endif %}
+  {%- endblock %}
+  {%- block extrahead %} {% endblock %}
+
+  <script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script>
+
+</head>
+
+<body class="wy-body-for-nav" role="document">
+
+  <div class="wy-grid-for-nav">
+
+    {# SIDE NAV, TOGGLES ON MOBILE #}
+    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
+      <div class="wy-side-nav-search">
+        <a href="{{ pathto(master_doc) }}" class="icon icon-home"> {{ project }}</a>
+        {% include "searchbox.html" %}
+      </div>
+
+      <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
+        {% set toctree = toctree(maxdepth=2, collapse=False, includehidden=True) %}
+        {% if toctree %}
+            {{ toctree }}
+        {% else %}
+            <!-- Local TOC -->
+            <div class="local-toc">{{ toc }}</div>
+        {% endif %}
+      </div>
+      &nbsp;
+    </nav>
+
+    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
+
+      {# MOBILE NAV, TRIGGLES SIDE NAV ON TOGGLE #}
+      <nav class="wy-nav-top" role="navigation" aria-label="top navigation">
+        <i data-toggle="wy-nav-top" class="icon icon-reorder"></i>
+        <a href="{{ pathto(master_doc) }}">{{ project }}</a>
+      </nav>
+
+
+      {# PAGE CONTENT #}
+      <div class="wy-nav-content">
+        <div class="rst-content">
+          {% include "breadcrumbs.html" %}
+          <div role="main">
+            {% block body %}{% endblock %}
+          </div>
+          {% include "footer.html" %}
+        </div>
+      </div>
+
+    </section>
+
+  </div>
+  {% include "versions.html" %}
+</body>
+</html>

+ 205 - 0
doc/source/_theme/sphinx_rtd_theme/layout_old.html

@@ -0,0 +1,205 @@
+{#
+    basic/layout.html
+    ~~~~~~~~~~~~~~~~~
+
+    Master layout template for Sphinx themes.
+
+    :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+#}
+{%- block doctype -%}
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+{%- endblock %}
+{%- set reldelim1 = reldelim1 is not defined and ' &raquo;' or reldelim1 %}
+{%- set reldelim2 = reldelim2 is not defined and ' |' or reldelim2 %}
+{%- set render_sidebar = (not embedded) and (not theme_nosidebar|tobool) and
+                         (sidebars != []) %}
+{%- set url_root = pathto('', 1) %}
+{# XXX necessary? #}
+{%- if url_root == '#' %}{% set url_root = '' %}{% endif %}
+{%- if not embedded and docstitle %}
+  {%- set titlesuffix = " &mdash; "|safe + docstitle|e %}
+{%- else %}
+  {%- set titlesuffix = "" %}
+{%- endif %}
+
+{%- macro relbar() %}
+    <div class="related">
+      <h3>{{ _('Navigation') }}</h3>
+      <ul>
+        {%- for rellink in rellinks %}
+        <li class="right" {% if loop.first %}style="margin-right: 10px"{% endif %}>
+          <a href="{{ pathto(rellink[0]) }}" title="{{ rellink[1]|striptags|e }}"
+             {{ accesskey(rellink[2]) }}>{{ rellink[3] }}</a>
+          {%- if not loop.first %}{{ reldelim2 }}{% endif %}</li>
+        {%- endfor %}
+        {%- block rootrellink %}
+        <li><a href="{{ pathto(master_doc) }}">{{ shorttitle|e }}</a>{{ reldelim1 }}</li>
+        {%- endblock %}
+        {%- for parent in parents %}
+          <li><a href="{{ parent.link|e }}" {% if loop.last %}{{ accesskey("U") }}{% endif %}>{{ parent.title }}</a>{{ reldelim1 }}</li>
+        {%- endfor %}
+        {%- block relbaritems %} {% endblock %}
+      </ul>
+    </div>
+{%- endmacro %}
+
+{%- macro sidebar() %}
+      {%- if render_sidebar %}
+      <div class="sphinxsidebar">
+        <div class="sphinxsidebarwrapper">
+          {%- block sidebarlogo %}
+          {%- if logo %}
+            <p class="logo"><a href="{{ pathto(master_doc) }}">
+              <img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/>
+            </a></p>
+          {%- endif %}
+          {%- endblock %}
+          {%- if sidebars != None %}
+            {#- new style sidebar: explicitly include/exclude templates #}
+            {%- for sidebartemplate in sidebars %}
+            {%- include sidebartemplate %}
+            {%- endfor %}
+          {%- else %}
+            {#- old style sidebars: using blocks -- should be deprecated #}
+            {%- block sidebartoc %}
+            {%- include "localtoc.html" %}
+            {%- endblock %}
+            {%- block sidebarrel %}
+            {%- include "relations.html" %}
+            {%- endblock %}
+            {%- block sidebarsourcelink %}
+            {%- include "sourcelink.html" %}
+            {%- endblock %}
+            {%- if customsidebar %}
+            {%- include customsidebar %}
+            {%- endif %}
+            {%- block sidebarsearch %}
+            {%- include "searchbox.html" %}
+            {%- endblock %}
+          {%- endif %}
+        </div>
+      </div>
+      {%- endif %}
+{%- endmacro %}
+
+{%- macro script() %}
+    <script type="text/javascript">
+      var DOCUMENTATION_OPTIONS = {
+        URL_ROOT:    '{{ url_root }}',
+        VERSION:     '{{ release|e }}',
+        COLLAPSE_INDEX: false,
+        FILE_SUFFIX: '{{ '' if no_search_suffix else file_suffix }}',
+        HAS_SOURCE:  {{ has_source|lower }}
+      };
+    </script>
+    {%- for scriptfile in script_files %}
+    <script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
+    {%- endfor %}
+{%- endmacro %}
+
+{%- macro css() %}
+    <link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
+    <link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
+    {%- for cssfile in css_files %}
+    <link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" />
+    {%- endfor %}
+{%- endmacro %}
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset={{ encoding }}" />
+    {{ metatags }}
+    {%- block htmltitle %}
+    <title>{{ title|striptags|e }}{{ titlesuffix }}</title>
+    {%- endblock %}
+    {{ css() }}
+    {%- if not embedded %}
+    {{ script() }}
+    {%- if use_opensearch %}
+    <link rel="search" type="application/opensearchdescription+xml"
+          title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}"
+          href="{{ pathto('_static/opensearch.xml', 1) }}"/>
+    {%- endif %}
+    {%- if favicon %}
+    <link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
+    {%- endif %}
+    {%- endif %}
+{%- block linktags %}
+    {%- if hasdoc('about') %}
+    <link rel="author" title="{{ _('About these documents') }}" href="{{ pathto('about') }}" />
+    {%- endif %}
+    {%- if hasdoc('genindex') %}
+    <link rel="index" title="{{ _('Index') }}" href="{{ pathto('genindex') }}" />
+    {%- endif %}
+    {%- if hasdoc('search') %}
+    <link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}" />
+    {%- endif %}
+    {%- if hasdoc('copyright') %}
+    <link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}" />
+    {%- endif %}
+    <link rel="top" title="{{ docstitle|e }}" href="{{ pathto('index') }}" />
+    {%- if parents %}
+    <link rel="up" title="{{ parents[-1].title|striptags|e }}" href="{{ parents[-1].link|e }}" />
+    {%- endif %}
+    {%- if next %}
+    <link rel="next" title="{{ next.title|striptags|e }}" href="{{ next.link|e }}" />
+    {%- endif %}
+    {%- if prev %}
+    <link rel="prev" title="{{ prev.title|striptags|e }}" href="{{ prev.link|e }}" />
+    {%- endif %}
+{%- endblock %}
+{%- block extrahead %} {% endblock %}
+  </head>
+  <body>
+{%- block header %}{% endblock %}
+
+{%- block relbar1 %}{{ relbar() }}{% endblock %}
+
+{%- block content %}
+  {%- block sidebar1 %} {# possible location for sidebar #} {% endblock %}
+
+    <div class="document">
+  {%- block document %}
+      <div class="documentwrapper">
+      {%- if render_sidebar %}
+        <div class="bodywrapper">
+      {%- endif %}
+          <div class="body">
+            {% block body %} {% endblock %}
+          </div>
+      {%- if render_sidebar %}
+        </div>
+      {%- endif %}
+      </div>
+  {%- endblock %}
+
+  {%- block sidebar2 %}{{ sidebar() }}{% endblock %}
+      <div class="clearer"></div>
+    </div>
+{%- endblock %}
+
+{%- block relbar2 %}{{ relbar() }}{% endblock %}
+
+{%- block footer %}
+    <div class="footer">
+    {%- if show_copyright %}
+      {%- if hasdoc('copyright') %}
+        {% trans path=pathto('copyright'), copyright=copyright|e %}&copy; <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
+      {%- else %}
+        {% trans copyright=copyright|e %}&copy; Copyright {{ copyright }}.{% endtrans %}
+      {%- endif %}
+    {%- endif %}
+    {%- if last_updated %}
+      {% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
+    {%- endif %}
+    {%- if show_sphinx %}
+      {% trans sphinx_version=sphinx_version|e %}Created using <a href="http://sphinx-doc.org/">Sphinx</a> {{ sphinx_version }}.{% endtrans %}
+    {%- endif %}
+    </div>
+    <p>asdf asdf asdf asdf 22</p>
+{%- endblock %}
+  </body>
+</html>
+

+ 50 - 0
doc/source/_theme/sphinx_rtd_theme/search.html

@@ -0,0 +1,50 @@
+{#
+    basic/search.html
+    ~~~~~~~~~~~~~~~~~
+
+    Template for the search page.
+
+    :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+#}
+{%- extends "layout.html" %}
+{% set title = _('Search') %}
+{% set script_files = script_files + ['_static/searchtools.js'] %}
+{% block extrahead %}
+  <script type="text/javascript">
+    jQuery(function() { Search.loadIndex("{{ pathto('searchindex.js', 1) }}"); });
+  </script>
+  {# this is used when loading the search index using $.ajax fails,
+     such as on Chrome for documents on localhost #}
+  <script type="text/javascript" id="searchindexloader"></script>
+  {{ super() }}
+{% endblock %}
+{% block body %}
+  <noscript>
+  <div id="fallback" class="admonition warning">
+    <p class="last">
+      {% trans %}Please activate JavaScript to enable the search
+      functionality.{% endtrans %}
+    </p>
+  </div>
+  </noscript>
+
+  {% if search_performed %}
+    <h2>{{ _('Search Results') }}</h2>
+    {% if not search_results %}
+      <p>{{ _('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.') }}</p>
+    {% endif %}
+  {% endif %}
+  <div id="search-results">
+  {% if search_results %}
+    <ul>
+    {% for href, caption, context in search_results %}
+      <li>
+        <a href="{{ pathto(item.href) }}">{{ caption }}</a>
+        <p class="context">{{ context|e }}</p>
+      </li>
+    {% endfor %}
+    </ul>
+  {% endif %}
+  </div>
+{% endblock %}

+ 7 - 0
doc/source/_theme/sphinx_rtd_theme/searchbox.html

@@ -0,0 +1,7 @@
+<div role="search">
+  <form id ="rtd-search-form" class="wy-form" action="{{ pathto('search') }}" method="get">
+    <input type="text" name="q" placeholder="Search docs" />
+    <input type="hidden" name="check_keywords" value="yes" />
+    <input type="hidden" name="area" value="default" />
+  </form>
+</div>

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
doc/source/_theme/sphinx_rtd_theme/static/css/badge_only.css


Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
doc/source/_theme/sphinx_rtd_theme/static/css/theme.css


BIN
doc/source/_theme/sphinx_rtd_theme/static/font/fontawesome_webfont.eot


Dosya farkı çok büyük olduğundan ihmal edildi
+ 195 - 0
doc/source/_theme/sphinx_rtd_theme/static/font/fontawesome_webfont.svg


BIN
doc/source/_theme/sphinx_rtd_theme/static/font/fontawesome_webfont.ttf


BIN
doc/source/_theme/sphinx_rtd_theme/static/font/fontawesome_webfont.woff


+ 47 - 0
doc/source/_theme/sphinx_rtd_theme/static/js/theme.js

@@ -0,0 +1,47 @@
+$( document ).ready(function() {
+    // Shift nav in mobile when clicking the menu.
+    $(document).on('click', "[data-toggle='wy-nav-top']", function() {
+      $("[data-toggle='wy-nav-shift']").toggleClass("shift");
+      $("[data-toggle='rst-versions']").toggleClass("shift");
+    });
+    // Close menu when you click a link.
+    $(document).on('click', ".wy-menu-vertical .current ul li a", function() {
+      $("[data-toggle='wy-nav-shift']").removeClass("shift");
+      $("[data-toggle='rst-versions']").toggleClass("shift");
+    });
+    $(document).on('click', "[data-toggle='rst-current-version']", function() {
+      $("[data-toggle='rst-versions']").toggleClass("shift-up");
+    });  
+    // Make tables responsive
+    $("table.docutils:not(.field-list)").wrap("<div class='wy-table-responsive'></div>");
+});
+
+window.SphinxRtdTheme = (function (jquery) {
+    var stickyNav = (function () {
+        var navBar,
+            win,
+            stickyNavCssClass = 'stickynav',
+            applyStickNav = function () {
+                if (navBar.height() <= win.height()) {
+                    navBar.addClass(stickyNavCssClass);
+                } else {
+                    navBar.removeClass(stickyNavCssClass);
+                }
+            },
+            enable = function () {
+                applyStickNav();
+                win.on('resize', applyStickNav);
+            },
+            init = function () {
+                navBar = jquery('nav.wy-nav-side:first');
+                win    = jquery(window);
+            };
+        jquery(init);
+        return {
+            enable : enable
+        };
+    }());
+    return {
+        StickyNav : stickyNav
+    };
+}($));

+ 8 - 0
doc/source/_theme/sphinx_rtd_theme/theme.conf

@@ -0,0 +1,8 @@
+[theme]
+inherit = basic
+stylesheet = css/theme.css
+
+[options]
+typekit_id = hiw1hhg
+analytics_id = 
+sticky_navigation = False

+ 37 - 0
doc/source/_theme/sphinx_rtd_theme/versions.html

@@ -0,0 +1,37 @@
+{% if READTHEDOCS %}
+{# Add rst-badge after rst-versions for small badge style. #}
+  <div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions">
+    <span class="rst-current-version" data-toggle="rst-current-version">
+      <span class="icon icon-book"> Read the Docs</span>
+      v: {{ current_version }} 
+      <span class="icon icon-caret-down"></span>
+    </span>
+    <div class="rst-other-versions">
+      <dl>
+        <dt>Versions</dt>
+        {% for slug, url in versions %}
+          <dd><a href="{{ url }}">{{ slug }}</a></dd>
+        {% endfor %}
+      </dl>
+      <dl>
+        <dt>Downloads</dt>
+        {% for type, url in downloads %}
+          <dd><a href="{{ url }}">{{ type }}</a></dd>
+        {% endfor %}
+      </dl>
+      <dl>
+        <dt>On Read the Docs</dt>
+          <dd>
+            <a href="//{{ PRODUCTION_DOMAIN }}/projects/{{ slug }}/?fromdocs={{ slug }}">Project Home</a>
+          </dd>
+          <dd>
+            <a href="//{{ PRODUCTION_DOMAIN }}/builds/{{ slug }}/?fromdocs={{ slug }}">Builds</a>
+          </dd>
+      </dl>
+      <hr/>
+      Free document hosting provided by <a href="http://www.readthedocs.org">Read the Docs</a>.
+
+    </div>
+  </div>
+{% endif %}
+

Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
doc/source/_theme/static/css/badge_only.css


Dosya farkı çok büyük olduğundan ihmal edildi
+ 0 - 0
doc/source/_theme/static/css/theme.css


BIN
doc/source/_theme/static/font/fontawesome_webfont.eot


Dosya farkı çok büyük olduğundan ihmal edildi
+ 195 - 0
doc/source/_theme/static/font/fontawesome_webfont.svg


BIN
doc/source/_theme/static/font/fontawesome_webfont.ttf


BIN
doc/source/_theme/static/font/fontawesome_webfont.woff


+ 47 - 0
doc/source/_theme/static/js/theme.js

@@ -0,0 +1,47 @@
+$( document ).ready(function() {
+    // Shift nav in mobile when clicking the menu.
+    $(document).on('click', "[data-toggle='wy-nav-top']", function() {
+      $("[data-toggle='wy-nav-shift']").toggleClass("shift");
+      $("[data-toggle='rst-versions']").toggleClass("shift");
+    });
+    // Close menu when you click a link.
+    $(document).on('click', ".wy-menu-vertical .current ul li a", function() {
+      $("[data-toggle='wy-nav-shift']").removeClass("shift");
+      $("[data-toggle='rst-versions']").toggleClass("shift");
+    });
+    $(document).on('click', "[data-toggle='rst-current-version']", function() {
+      $("[data-toggle='rst-versions']").toggleClass("shift-up");
+    });  
+    // Make tables responsive
+    $("table.docutils:not(.field-list)").wrap("<div class='wy-table-responsive'></div>");
+});
+
+window.SphinxRtdTheme = (function (jquery) {
+    var stickyNav = (function () {
+        var navBar,
+            win,
+            stickyNavCssClass = 'stickynav',
+            applyStickNav = function () {
+                if (navBar.height() <= win.height()) {
+                    navBar.addClass(stickyNavCssClass);
+                } else {
+                    navBar.removeClass(stickyNavCssClass);
+                }
+            },
+            enable = function () {
+                applyStickNav();
+                win.on('resize', applyStickNav);
+            },
+            init = function () {
+                navBar = jquery('nav.wy-nav-side:first');
+                win    = jquery(window);
+            };
+        jquery(init);
+        return {
+            enable : enable
+        };
+    }());
+    return {
+        StickyNav : stickyNav
+    };
+}($));

+ 8 - 0
doc/source/_theme/theme.conf

@@ -0,0 +1,8 @@
+[theme]
+inherit = basic
+stylesheet = css/theme.css
+
+[options]
+typekit_id = hiw1hhg
+analytics_id = 
+sticky_navigation = False

+ 37 - 0
doc/source/_theme/versions.html

@@ -0,0 +1,37 @@
+{% if READTHEDOCS %}
+{# Add rst-badge after rst-versions for small badge style. #}
+  <div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions">
+    <span class="rst-current-version" data-toggle="rst-current-version">
+      <span class="icon icon-book"> Read the Docs</span>
+      v: {{ current_version }} 
+      <span class="icon icon-caret-down"></span>
+    </span>
+    <div class="rst-other-versions">
+      <dl>
+        <dt>Versions</dt>
+        {% for slug, url in versions %}
+          <dd><a href="{{ url }}">{{ slug }}</a></dd>
+        {% endfor %}
+      </dl>
+      <dl>
+        <dt>Downloads</dt>
+        {% for type, url in downloads %}
+          <dd><a href="{{ url }}">{{ type }}</a></dd>
+        {% endfor %}
+      </dl>
+      <dl>
+        <dt>On Read the Docs</dt>
+          <dd>
+            <a href="//{{ PRODUCTION_DOMAIN }}/projects/{{ slug }}/?fromdocs={{ slug }}">Project Home</a>
+          </dd>
+          <dd>
+            <a href="//{{ PRODUCTION_DOMAIN }}/builds/{{ slug }}/?fromdocs={{ slug }}">Builds</a>
+          </dd>
+      </dl>
+      <hr/>
+      Free document hosting provided by <a href="http://www.readthedocs.org">Read the Docs</a>.
+
+    </div>
+  </div>
+{% endif %}
+

+ 4 - 0
doc/source/camlib.rst

@@ -0,0 +1,4 @@
+This is the main file for camlib
+=================================
+
+Some text.

+ 265 - 0
doc/source/conf.py

@@ -0,0 +1,265 @@
+# -*- coding: utf-8 -*-
+#
+# Cirkuix documentation build configuration file, created by
+# sphinx-quickstart on Fri Jan 24 22:13:35 2014.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys
+import os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+    'sphinx.ext.autodoc',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'Cirkuix'
+copyright = u'2014, Juan Pablo Caram'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '0.5'
+# The full version, including alpha/beta/rc tags.
+release = '0.5'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = []
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+#keep_warnings = False
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+#html_theme = 'default'
+#html_theme = 'sphinxdoc'
+
+html_theme_path = ["_theme/"]
+html_theme = "sphinx_rtd_theme"
+
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+#html_extra_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'Cirkuixdoc'
+
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+#  author, documentclass [howto, manual, or own class]).
+latex_documents = [
+  ('index', 'Cirkuix.tex', u'Cirkuix Documentation',
+   u'Juan Pablo Caram', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('index', 'cirkuix', u'Cirkuix Documentation',
+     [u'Juan Pablo Caram'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+#  dir menu entry, description, category)
+texinfo_documents = [
+  ('index', 'Cirkuix', u'Cirkuix Documentation',
+   u'Juan Pablo Caram', 'Cirkuix', 'One line description of project.',
+   'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+#texinfo_no_detailmenu = False

+ 55 - 0
doc/source/index.rst

@@ -0,0 +1,55 @@
+.. Cirkuix documentation master file, created by
+   sphinx-quickstart on Fri Jan 24 22:13:35 2014.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+
+
+Welcome to Cirkuix's documentation!
+===================================
+
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+.. automodule:: cirkuix
+
+.. autoclass:: App
+    :members:
+
+.. autoclass:: Geometry
+    :members:
+
+.. autoclass:: Gerber(Geometry)
+    :members:
+
+.. autoclass:: Excellon
+    :members:
+
+.. autoclass:: CNCjob
+    :members:
+
+.. autoclass:: CirkuixObj
+    :members:
+
+.. autoclass:: CirkuixGerber
+    :members:
+
+.. autoclass:: CirkuixExcellon
+    :members:
+
+.. autoclass:: CirkuixCNCjob
+    :members:
+
+.. autoclass:: CirkuixGeometry
+    :members:
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor